diff options
Diffstat (limited to 'sound/pci/cmipci.c')
| -rw-r--r-- | sound/pci/cmipci.c | 366 |
1 files changed, 215 insertions, 151 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 6832649879c..12c318e175f 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -20,7 +20,6 @@ /* Does not work. Warning may block system in capture mode */ /* #define USE_VAR48KRATE */ -#include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> #include <linux/interrupt.h> @@ -28,7 +27,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/gameport.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <linux/mutex.h> #include <sound/core.h> #include <sound/info.h> @@ -55,10 +54,10 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static long mpu_port[SNDRV_CARDS]; static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; -static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; +static bool soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; #ifdef SUPPORT_JOYSTICK static int joystick_port[SNDRV_CARDS]; #endif @@ -74,7 +73,7 @@ MODULE_PARM_DESC(mpu_port, "MPU-401 port."); module_param_array(fm_port, long, NULL, 0444); MODULE_PARM_DESC(fm_port, "FM port."); module_param_array(soft_ac3, bool, NULL, 0444); -MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only)."); +MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only)."); #ifdef SUPPORT_JOYSTICK module_param_array(joystick_port, int, NULL, 0444); MODULE_PARM_DESC(joystick_port, "Joystick port address."); @@ -150,6 +149,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_CH0_SRATE_176K 0x00000200 #define CM_CH0_SRATE_96K 0x00000200 /* model 055? */ #define CM_CH0_SRATE_88K 0x00000100 +#define CM_CH0_SRATE_128K 0x00000300 +#define CM_CH0_SRATE_MASK 0x00000300 #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ #define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */ @@ -246,10 +247,9 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */ #define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */ #define CM_ENCENTER 0x00000080 -#define CM_FLINKON 0x00000080 /* force modem link detection on, model 037 */ +#define CM_FLINKON 0x00000040 /* force modem link detection on, model 037 */ #define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */ -#define CM_FLINKOFF 0x00000040 /* force modem link detection off, model 037 */ -#define CM_UNKNOWN_18_5 0x00000020 /* ? */ +#define CM_FLINKOFF 0x00000020 /* force modem link detection off, model 037 */ #define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */ #define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */ #define CM_UPDDMA_2048 0x00000000 @@ -474,6 +474,7 @@ struct cmipci { unsigned int can_ac3_sw: 1; unsigned int can_ac3_hw: 1; unsigned int can_multi_ch: 1; + unsigned int can_96k: 1; /* samplerate above 48k */ unsigned int do_soft_ac3: 1; unsigned int spdif_playback_avail: 1; /* spdif ready? */ @@ -503,7 +504,7 @@ struct cmipci { spinlock_t reg_lock; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP unsigned int saved_regs[0x20]; unsigned char saved_mixers[0x20]; #endif @@ -604,8 +605,6 @@ static unsigned int snd_cmipci_rate_freq(unsigned int rate) { unsigned int i; - if (rate > 48000) - rate /= 2; for (i = 0; i < ARRAY_SIZE(rates); i++) { if (rates[i] == rate) return i; @@ -657,8 +656,8 @@ out: } /* - * Program pll register bits, I assume that the 8 registers 0xf8 upto 0xff - * are mapped onto the 8 ADC/DAC sampling frequency which can be choosen + * Program pll register bits, I assume that the 8 registers 0xf8 up to 0xff + * are mapped onto the 8 ADC/DAC sampling frequency which can be chosen * at the register CM_REG_FUNCTRL1 (0x04). * Problem: other ways are also possible (any information about that?) */ @@ -667,7 +666,7 @@ static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned in unsigned int reg = CM_REG_PLL + slot; /* * Guess that this programs at reg. 0x04 the pos 15:13/12:10 - * for DSFC/ASFC (000 upto 111). + * for DSFC/ASFC (000 up to 111). */ /* FIXME: Init (Do we've to set an other register first before programming?) */ @@ -783,7 +782,7 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, struct snd_pcm_substream *substream) { - unsigned int reg, freq, val; + unsigned int reg, freq, freq_ext, val; unsigned int period_size; struct snd_pcm_runtime *runtime = substream->runtime; @@ -797,7 +796,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, if (runtime->channels > 1) rec->fmt |= 0x01; if (rec->is_dac && set_dac_channels(cm, rec, runtime->channels) < 0) { - snd_printd("cannot set dac channels\n"); + dev_dbg(cm->card->dev, "cannot set dac channels\n"); return -EINVAL; } @@ -828,10 +827,20 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, else cm->ctrl |= val; snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl); - //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl); + /* dev_dbg(cm->card->dev, "functrl0 = %08x\n", cm->ctrl); */ /* set sample rate */ - freq = snd_cmipci_rate_freq(runtime->rate); + freq = 0; + freq_ext = 0; + if (runtime->rate > 48000) + switch (runtime->rate) { + case 88200: freq_ext = CM_CH0_SRATE_88K; break; + case 96000: freq_ext = CM_CH0_SRATE_96K; break; + case 128000: freq_ext = CM_CH0_SRATE_128K; break; + default: snd_BUG(); break; + } + else + freq = snd_cmipci_rate_freq(runtime->rate); val = snd_cmipci_read(cm, CM_REG_FUNCTRL1); if (rec->ch) { val &= ~CM_DSFC_MASK; @@ -841,7 +850,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK; } snd_cmipci_write(cm, CM_REG_FUNCTRL1, val); - //snd_printd("cmipci: functrl1 = %08x\n", val); + dev_dbg(cm->card->dev, "functrl1 = %08x\n", val); /* set format */ val = snd_cmipci_read(cm, CM_REG_CHFORMAT); @@ -852,18 +861,19 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, val &= ~CM_CH0FMT_MASK; val |= rec->fmt << CM_CH0FMT_SHIFT; } - if (cm->chip_version == 68) { - if (runtime->rate == 88200) - val |= CM_CH0_SRATE_88K << (rec->ch * 2); - else - val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); - if (runtime->rate == 96000) - val |= CM_CH0_SRATE_96K << (rec->ch * 2); - else - val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); + if (cm->can_96k) { + val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2)); + val |= freq_ext << (rec->ch * 2); } snd_cmipci_write(cm, CM_REG_CHFORMAT, val); - //snd_printd("cmipci: chformat = %08x\n", val); + dev_dbg(cm->card->dev, "chformat = %08x\n", val); + + if (!rec->is_dac && cm->chip_version) { + if (runtime->rate > 44100) + snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K); + else + snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K); + } rec->running = 0; spin_unlock_irq(&cm->reg_lock); @@ -894,7 +904,7 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec, cm->ctrl |= chen; /* enable channel */ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl); - //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl); + dev_dbg(cm->card->dev, "functrl0 = %08x\n", cm->ctrl); break; case SNDRV_PCM_TRIGGER_STOP: rec->running = 0; @@ -931,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci struct snd_pcm_substream *substream) { size_t ptr; - unsigned int reg; + unsigned int reg, rem, tries; + if (!rec->running) return 0; #if 1 // this seems better.. reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; - ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); - ptr >>= rec->shift; + for (tries = 0; tries < 3; tries++) { + rem = snd_cmipci_read_w(cm, reg); + if (rem < rec->dma_size) + goto ok; + } + dev_err(cm->card->dev, "invalid PCM pointer: %#x\n", rem); + return SNDRV_PCM_POS_XRUN; +ok: + ptr = (rec->dma_size - (rem + 1)) >> rec->shift; #else reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; ptr = snd_cmipci_read(cm, reg) - rec->offset; @@ -1027,7 +1045,7 @@ static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new snd_cmipci_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_cmipci_spdif_default = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1054,7 +1072,7 @@ static int snd_cmipci_spdif_mask_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new snd_cmipci_spdif_mask __devinitdata = +static struct snd_kcontrol_new snd_cmipci_spdif_mask = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1101,7 +1119,7 @@ static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new snd_cmipci_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_cmipci_spdif_stream = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1281,7 +1299,7 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream) int rate = substream->runtime->rate; int err, do_spdif, do_ac3 = 0; - do_spdif = (rate >= 44100 && + do_spdif = (rate >= 44100 && rate <= 96000 && substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && substream->runtime->channels == 2); if (do_spdif && cm->can_ac3_hw) @@ -1337,10 +1355,8 @@ static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec) val = snd_cmipci_read(cm, CM_REG_CHFORMAT); val &= ~(CM_CH0FMT_MASK << (rec->ch * 2)); val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2); - if (cm->chip_version == 68) { - val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); - val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); - } + if (cm->can_96k) + val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2)); snd_cmipci_write(cm, CM_REG_CHFORMAT, val); /* start stream (we don't need interrupts) */ @@ -1392,6 +1408,17 @@ static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream) spin_lock_irq(&cm->reg_lock); snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); + if (cm->can_96k) { + if (substream->runtime->rate > 48000) + snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); + else + snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); + } + if (snd_pcm_format_width(substream->runtime->format) > 16) + snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); + else + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); + spin_unlock_irq(&cm->reg_lock); return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream); @@ -1403,6 +1430,7 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs) spin_lock_irq(&cm->reg_lock); snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); spin_unlock_irq(&cm->reg_lock); return snd_cmipci_hw_free(subs); @@ -1554,7 +1582,8 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, .rate_min = 44100, .rate_max = 48000, @@ -1568,6 +1597,14 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif = .fifo_size = 0, }; +static unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050, + 32000, 44100, 48000, 88200, 96000, 128000 }; +static struct snd_pcm_hw_constraint_list hw_constraints_rates = { + .count = ARRAY_SIZE(rate_constraints), + .list = rate_constraints, + .mask = 0, +}; + /* * check device open/close */ @@ -1637,6 +1674,13 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream) runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; + } else if (cm->chip_version == 55) { + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); + if (err < 0) + return err; + runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; + runtime->hw.rate_max = 128000; } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); cm->dig_pcm_status = cm->dig_status; @@ -1655,6 +1699,13 @@ static int snd_cmipci_capture_open(struct snd_pcm_substream *substream) if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording runtime->hw.rate_min = 41000; runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; + } else if (cm->chip_version == 55) { + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); + if (err < 0) + return err; + runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; + runtime->hw.rate_max = 128000; } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); return 0; @@ -1686,6 +1737,13 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; + } else if (cm->chip_version == 55) { + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); + if (err < 0) + return err; + runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; + runtime->hw.rate_max = 128000; } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); return 0; @@ -1705,7 +1763,7 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream) runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); } - if (cm->chip_version == 68) { + if (cm->can_96k) { runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; @@ -1727,6 +1785,11 @@ static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream) if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */ return err; runtime->hw = snd_cmipci_capture_spdif; + if (cm->can_96k && !(cm->chip_version == 68)) { + runtime->hw.rates |= SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000; + runtime->hw.rate_max = 96000; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000); return 0; } @@ -1834,7 +1897,7 @@ static struct snd_pcm_ops snd_cmipci_capture_spdif_ops = { /* */ -static int __devinit snd_cmipci_pcm_new(struct cmipci *cm, int device) +static int snd_cmipci_pcm_new(struct cmipci *cm, int device) { struct snd_pcm *pcm; int err; @@ -1857,7 +1920,7 @@ static int __devinit snd_cmipci_pcm_new(struct cmipci *cm, int device) return 0; } -static int __devinit snd_cmipci_pcm2_new(struct cmipci *cm, int device) +static int snd_cmipci_pcm2_new(struct cmipci *cm, int device) { struct snd_pcm *pcm; int err; @@ -1879,7 +1942,7 @@ static int __devinit snd_cmipci_pcm2_new(struct cmipci *cm, int device) return 0; } -static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device) +static int snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device) { struct snd_pcm *pcm; int err; @@ -1899,6 +1962,12 @@ static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(cm->pci), 64*1024, 128*1024); + err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + snd_pcm_alt_chmaps, cm->max_channels, 0, + NULL); + if (err < 0) + return err; + return 0; } @@ -2221,7 +2290,7 @@ static int snd_cmipci_put_native_mixer_sensitive(struct snd_kcontrol *kcontrol, } -static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = { +static struct snd_kcontrol_new snd_cmipci_mixers[] = { CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31), CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0), CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31), @@ -2247,7 +2316,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = { CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), CMIPCI_SB_SW_MONO("Mic Playback Switch", 0), CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0), - CMIPCI_SB_VOL_MONO("PC Speaker Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3), + CMIPCI_SB_VOL_MONO("Beep Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3), CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), @@ -2255,7 +2324,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = { CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), - CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), + CMIPCI_DOUBLE("Beep Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), }; @@ -2302,7 +2371,8 @@ static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol, { struct cmipci_switch_args *args; args = (struct cmipci_switch_args *)kcontrol->private_value; - snd_assert(args != NULL, return -EINVAL); + if (snd_BUG_ON(!args)) + return -EINVAL; return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args); } @@ -2346,7 +2416,8 @@ static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol, { struct cmipci_switch_args *args; args = (struct cmipci_switch_args *)kcontrol->private_value; - snd_assert(args != NULL, return -EINVAL); + if (snd_BUG_ON(!args)) + return -EINVAL; return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args); } @@ -2442,14 +2513,12 @@ static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct cmipci *cm = snd_kcontrol_chip(kcontrol); - static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char *const texts[3] = { + "Line-In", "Rear Output", "Bass Output" + }; + + return snd_ctl_enum_info(uinfo, 1, + cm->chip_version >= 39 ? 3 : 2, texts); } static inline unsigned int get_line_in_mode(struct cmipci *cm) @@ -2499,14 +2568,9 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol, static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "Mic-In", "Center/LFE Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char *const texts[2] = { "Mic-In", "Center/LFE Output" }; + + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, @@ -2537,7 +2601,7 @@ static int snd_cmipci_mic_in_mode_put(struct snd_kcontrol *kcontrol, } /* both for CM8338/8738 */ -static struct snd_kcontrol_new snd_cmipci_mixer_switches[] __devinitdata = { +static struct snd_kcontrol_new snd_cmipci_mixer_switches[] = { DEFINE_MIXER_SWITCH("Four Channel Mode", fourch), { .name = "Line-In Mode", @@ -2549,11 +2613,11 @@ static struct snd_kcontrol_new snd_cmipci_mixer_switches[] __devinitdata = { }; /* for non-multichannel chips */ -static struct snd_kcontrol_new snd_cmipci_nomulti_switch __devinitdata = +static struct snd_kcontrol_new snd_cmipci_nomulti_switch = DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac); /* only for CM8738 */ -static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] __devinitdata = { +static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] = { #if 0 /* controlled in pcm device */ DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in), DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out), @@ -2575,14 +2639,14 @@ static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] __devinitdata = }; /* only for model 033/037 */ -static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] __devinitdata = { +static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] = { DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out), DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase), DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1), }; /* only for model 039 or later */ -static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = { +static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] = { DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2), DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2), { @@ -2595,13 +2659,11 @@ static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = }; /* card control switches */ -static struct snd_kcontrol_new snd_cmipci_control_switches[] __devinitdata = { - // DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */ - DEFINE_CARD_SWITCH("Modem", modem), -}; +static struct snd_kcontrol_new snd_cmipci_modem_switch = +DEFINE_CARD_SWITCH("Modem", modem); -static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device) +static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device) { struct snd_card *card; struct snd_kcontrol_new *sw; @@ -2609,7 +2671,8 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic unsigned int idx; int err; - snd_assert(cm != NULL && cm->card != NULL, return -EINVAL); + if (snd_BUG_ON(!cm || !cm->card)) + return -EINVAL; card = cm->card; @@ -2679,20 +2742,25 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic } /* card switches */ - sw = snd_cmipci_control_switches; - for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_control_switches); idx++, sw++) { - err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm)); + /* + * newer chips don't have the register bits to force modem link + * detection; the bit that was FLINKON now mutes CH1 + */ + if (cm->chip_version < 39) { + err = snd_ctl_add(cm->card, + snd_ctl_new1(&snd_cmipci_modem_switch, cm)); if (err < 0) return err; } for (idx = 0; idx < CM_SAVED_MIXERS; idx++) { - struct snd_ctl_elem_id id; + struct snd_ctl_elem_id elem_id; struct snd_kcontrol *ctl; - memset(&id, 0, sizeof(id)); - id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(id.name, cm_saved_mixer[idx].name); - if ((ctl = snd_ctl_find_id(cm->card, &id)) != NULL) + memset(&elem_id, 0, sizeof(elem_id)); + elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + strcpy(elem_id.name, cm_saved_mixer[idx].name); + ctl = snd_ctl_find_id(cm->card, &elem_id); + if (ctl) cm->mixer_res_ctl[idx] = ctl; } @@ -2723,7 +2791,7 @@ static void snd_cmipci_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, "\n"); } -static void __devinit snd_cmipci_proc_init(struct cmipci *cm) +static void snd_cmipci_proc_init(struct cmipci *cm) { struct snd_info_entry *entry; @@ -2735,12 +2803,12 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {} #endif -static struct pci_device_id snd_cmipci_ids[] = { - {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_AL, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = { + {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, + {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, + {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, + {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B), 0}, + {PCI_VDEVICE(AL, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, {0,}, }; @@ -2749,7 +2817,7 @@ static struct pci_device_id snd_cmipci_ids[] = { * check chip version and capabilities * driver name is modified according to the chip model */ -static void __devinit query_chip(struct cmipci *cm) +static void query_chip(struct cmipci *cm) { unsigned int detect; @@ -2786,9 +2854,11 @@ static void __devinit query_chip(struct cmipci *cm) } else if (detect & CM_CHIP_8768) { cm->chip_version = 68; cm->max_channels = 8; + cm->can_96k = 1; } else { cm->chip_version = 55; cm->max_channels = 6; + cm->can_96k = 1; } cm->can_ac3_hw = 1; cm->can_multi_ch = 1; @@ -2796,7 +2866,7 @@ static void __devinit query_chip(struct cmipci *cm) } #ifdef SUPPORT_JOYSTICK -static int __devinit snd_cmipci_create_gameport(struct cmipci *cm, int dev) +static int snd_cmipci_create_gameport(struct cmipci *cm, int dev) { static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */ struct gameport *gp; @@ -2819,13 +2889,13 @@ static int __devinit snd_cmipci_create_gameport(struct cmipci *cm, int dev) } if (!r) { - printk(KERN_WARNING "cmipci: cannot reserve joystick ports\n"); + dev_warn(cm->card->dev, "cannot reserve joystick ports\n"); return -EBUSY; } cm->gameport = gp = gameport_allocate_port(); if (!gp) { - printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n"); + dev_err(cm->card->dev, "cannot allocate memory for gameport\n"); release_and_free_resource(r); return -ENOMEM; } @@ -2873,8 +2943,6 @@ static int snd_cmipci_free(struct cmipci *cm) /* reset mixer */ snd_cmipci_mixer_write(cm, 0, 0); - synchronize_irq(cm->irq); - free_irq(cm->irq, cm); } @@ -2891,7 +2959,7 @@ static int snd_cmipci_dev_free(struct snd_device *device) return snd_cmipci_free(cm); } -static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port) +static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port) { long iosynth; unsigned int val; @@ -2927,13 +2995,14 @@ static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port) if (snd_opl3_create(cm->card, iosynth, iosynth + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { - printk(KERN_ERR "cmipci: no OPL device at %#lx, " - "skipping...\n", iosynth); + dev_err(cm->card->dev, + "no OPL device at %#lx, skipping...\n", + iosynth); goto disable_fm; } } if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { - printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n"); + dev_err(cm->card->dev, "cannot create OPL3 hwdep\n"); return err; } return 0; @@ -2944,8 +3013,8 @@ static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port) return 0; } -static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pci, - int dev, struct cmipci **rcmipci) +static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci, + int dev, struct cmipci **rcmipci) { struct cmipci *cm; int err; @@ -2953,11 +3022,11 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc .dev_free = snd_cmipci_dev_free, }; unsigned int val; - long iomidi; + long iomidi = 0; int integrated_midi = 0; char modelstr[16]; int pcm_index, pcm_spdif_index; - static struct pci_device_id intel_82437vx[] = { + static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, { }, }; @@ -2991,8 +3060,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc cm->iobase = pci_resource_start(pci, 0); if (request_irq(pci->irq, snd_cmipci_interrupt, - IRQF_SHARED, card->driver, cm)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + IRQF_SHARED, KBUILD_MODNAME, cm)) { + dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); snd_cmipci_free(cm); return -EBUSY; } @@ -3124,8 +3193,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc /* enable UART */ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN); if (inb(iomidi + 1) == 0xff) { - snd_printk(KERN_ERR "cannot enable MPU-401 port" - " at %#lx\n", iomidi); + dev_err(cm->card->dev, + "cannot enable MPU-401 port at %#lx\n", + iomidi); snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN); iomidi = 0; @@ -3166,9 +3236,11 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, iomidi, (integrated_midi ? - MPU401_INFO_INTEGRATED : 0), - cm->irq, 0, &cm->rmidi)) < 0) { - printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); + MPU401_INFO_INTEGRATED : 0) | + MPU401_INFO_IRQ_HOOK, + -1, &cm->rmidi)) < 0) { + dev_err(cm->card->dev, + "no UART401 device at 0x%lx\n", iomidi); } } @@ -3185,8 +3257,6 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc if (snd_cmipci_create_gameport(cm, dev) < 0) snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); - snd_card_set_dev(card, &pci->dev); - *rcmipci = cm; return 0; } @@ -3196,8 +3266,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc MODULE_DEVICE_TABLE(pci, snd_cmipci_ids); -static int __devinit snd_cmipci_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int snd_cmipci_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; @@ -3211,9 +3281,10 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci, return -ENOENT; } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + 0, &card); + if (err < 0) + return err; switch (pci->device) { case PCI_DEVICE_ID_CMEDIA_CM8738: @@ -3245,14 +3316,13 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci, } -static void __devexit snd_cmipci_remove(struct pci_dev *pci) +static void snd_cmipci_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP /* * power management */ @@ -3275,9 +3345,10 @@ static unsigned char saved_mixers[] = { SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, }; -static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state) +static int snd_cmipci_suspend(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + struct pci_dev *pci = to_pci_dev(dev); + struct snd_card *card = dev_get_drvdata(dev); struct cmipci *cm = card->private_data; int i; @@ -3298,21 +3369,21 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state) pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); + pci_set_power_state(pci, PCI_D3hot); return 0; } -static int snd_cmipci_resume(struct pci_dev *pci) +static int snd_cmipci_resume(struct device *dev) { - struct snd_card *card = pci_get_drvdata(pci); + struct pci_dev *pci = to_pci_dev(dev); + struct snd_card *card = dev_get_drvdata(dev); struct cmipci *cm = card->private_data; int i; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "cmipci: pci_enable_device failed, " - "disabling device\n"); + dev_err(dev, "pci_enable_device failed, disabling device\n"); snd_card_disconnect(card); return -EIO; } @@ -3333,28 +3404,21 @@ static int snd_cmipci_resume(struct pci_dev *pci) snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -#endif /* CONFIG_PM */ -static struct pci_driver driver = { - .name = "C-Media PCI", +static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume); +#define SND_CMIPCI_PM_OPS &snd_cmipci_pm +#else +#define SND_CMIPCI_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver cmipci_driver = { + .name = KBUILD_MODNAME, .id_table = snd_cmipci_ids, .probe = snd_cmipci_probe, - .remove = __devexit_p(snd_cmipci_remove), -#ifdef CONFIG_PM - .suspend = snd_cmipci_suspend, - .resume = snd_cmipci_resume, -#endif + .remove = snd_cmipci_remove, + .driver = { + .pm = SND_CMIPCI_PM_OPS, + }, }; -static int __init alsa_card_cmipci_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_cmipci_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_cmipci_init) -module_exit(alsa_card_cmipci_exit) +module_pci_driver(cmipci_driver); |
