diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 04:40:18 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:17:01 -0500 |
commit | 95a98265eb7b112b3268761053d643635171e219 (patch) | |
tree | daf88b4858b1ba856609c2a3138522ea4a2b6269 /sound/pci/ca0106 | |
parent | 954bea35571461b083390a82b03f077f901fe678 (diff) |
[ALSA] ca0106 - Code clean up
Modules: CA0106 driver
Clean up snd-ca0106 driver code:
- Fix spaces and indents
- Remove unnecessary spinlocks
- Clean up the mixer callbacks using private_value
- Clean up mixer constructors using an array
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ca0106')
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 74 | ||||
-rw-r--r-- | sound/pci/ca0106/ca0106_mixer.c | 417 |
2 files changed, 131 insertions, 360 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index a89eed255098..0120c4683c79 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -207,7 +207,8 @@ static snd_pcm_hardware_t snd_ca0106_playback_hw = { | |||
207 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 207 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
208 | SNDRV_PCM_INFO_MMAP_VALID), | 208 | SNDRV_PCM_INFO_MMAP_VALID), |
209 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, | 209 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, |
210 | .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, | 210 | .rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | |
211 | SNDRV_PCM_RATE_192000), | ||
211 | .rate_min = 48000, | 212 | .rate_min = 48000, |
212 | .rate_max = 192000, | 213 | .rate_max = 192000, |
213 | .channels_min = 2, //1, | 214 | .channels_min = 2, //1, |
@@ -226,7 +227,8 @@ static snd_pcm_hardware_t snd_ca0106_capture_hw = { | |||
226 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 227 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
227 | SNDRV_PCM_INFO_MMAP_VALID), | 228 | SNDRV_PCM_INFO_MMAP_VALID), |
228 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, | 229 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, |
229 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, | 230 | .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | |
231 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000), | ||
230 | .rate_min = 44100, | 232 | .rate_min = 44100, |
231 | .rate_max = 192000, | 233 | .rate_max = 192000, |
232 | .channels_min = 2, | 234 | .channels_min = 2, |
@@ -276,11 +278,10 @@ int snd_ca0106_i2c_write(ca0106_t *emu, | |||
276 | u32 value) | 278 | u32 value) |
277 | { | 279 | { |
278 | u32 tmp; | 280 | u32 tmp; |
279 | int timeout=0; | 281 | int timeout = 0; |
280 | int status; | 282 | int status; |
281 | int retry; | 283 | int retry; |
282 | if ((reg > 0x7f) || (value > 0x1ff)) | 284 | if ((reg > 0x7f) || (value > 0x1ff)) { |
283 | { | ||
284 | snd_printk(KERN_ERR "i2c_write: invalid values.\n"); | 285 | snd_printk(KERN_ERR "i2c_write: invalid values.\n"); |
285 | return -EINVAL; | 286 | return -EINVAL; |
286 | } | 287 | } |
@@ -292,8 +293,7 @@ int snd_ca0106_i2c_write(ca0106_t *emu, | |||
292 | /* This controls the I2C connected to the WM8775 ADC Codec */ | 293 | /* This controls the I2C connected to the WM8775 ADC Codec */ |
293 | snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp); | 294 | snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp); |
294 | 295 | ||
295 | for(retry=0;retry<10;retry++) | 296 | for (retry = 0; retry < 10; retry++) { |
296 | { | ||
297 | /* Send the data to i2c */ | 297 | /* Send the data to i2c */ |
298 | tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); | 298 | tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); |
299 | tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); | 299 | tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); |
@@ -301,24 +301,22 @@ int snd_ca0106_i2c_write(ca0106_t *emu, | |||
301 | snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); | 301 | snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); |
302 | 302 | ||
303 | /* Wait till the transaction ends */ | 303 | /* Wait till the transaction ends */ |
304 | while(1) | 304 | while (1) { |
305 | { | ||
306 | status = snd_ca0106_ptr_read(emu, I2C_A, 0); | 305 | status = snd_ca0106_ptr_read(emu, I2C_A, 0); |
307 | //snd_printk("I2C:status=0x%x\n", status); | 306 | //snd_printk("I2C:status=0x%x\n", status); |
308 | timeout++; | 307 | timeout++; |
309 | if((status & I2C_A_ADC_START)==0) | 308 | if ((status & I2C_A_ADC_START) == 0) |
310 | break; | 309 | break; |
311 | 310 | ||
312 | if(timeout>1000) | 311 | if (timeout > 1000) |
313 | break; | 312 | break; |
314 | } | 313 | } |
315 | //Read back and see if the transaction is successful | 314 | //Read back and see if the transaction is successful |
316 | if((status & I2C_A_ADC_ABORT)==0) | 315 | if ((status & I2C_A_ADC_ABORT) == 0) |
317 | break; | 316 | break; |
318 | } | 317 | } |
319 | 318 | ||
320 | if(retry==10) | 319 | if (retry == 10) { |
321 | { | ||
322 | snd_printk(KERN_ERR "Writing to ADC failed!\n"); | 320 | snd_printk(KERN_ERR "Writing to ADC failed!\n"); |
323 | return -EINVAL; | 321 | return -EINVAL; |
324 | } | 322 | } |
@@ -380,10 +378,10 @@ static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, | |||
380 | channel->emu = chip; | 378 | channel->emu = chip; |
381 | channel->number = channel_id; | 379 | channel->number = channel_id; |
382 | 380 | ||
383 | channel->use=1; | 381 | channel->use = 1; |
384 | //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); | 382 | //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); |
385 | //channel->interrupt = snd_ca0106_pcm_channel_interrupt; | 383 | //channel->interrupt = snd_ca0106_pcm_channel_interrupt; |
386 | channel->epcm=epcm; | 384 | channel->epcm = epcm; |
387 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 385 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
388 | return err; | 386 | return err; |
389 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) | 387 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) |
@@ -448,10 +446,10 @@ static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, i | |||
448 | channel->emu = chip; | 446 | channel->emu = chip; |
449 | channel->number = channel_id; | 447 | channel->number = channel_id; |
450 | 448 | ||
451 | channel->use=1; | 449 | channel->use = 1; |
452 | //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); | 450 | //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); |
453 | //channel->interrupt = snd_ca0106_pcm_channel_interrupt; | 451 | //channel->interrupt = snd_ca0106_pcm_channel_interrupt; |
454 | channel->epcm=epcm; | 452 | channel->epcm = epcm; |
455 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 453 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
456 | return err; | 454 | return err; |
457 | //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes); | 455 | //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes); |
@@ -593,8 +591,8 @@ static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream) | |||
593 | 591 | ||
594 | /* FIXME: Check emu->buffer.size before actually writing to it. */ | 592 | /* FIXME: Check emu->buffer.size before actually writing to it. */ |
595 | for(i=0; i < runtime->periods; i++) { | 593 | for(i=0; i < runtime->periods; i++) { |
596 | table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); | 594 | table_base[i*2] = runtime->dma_addr + (i * period_size_bytes); |
597 | table_base[(i*2)+1]=period_size_bytes<<16; | 595 | table_base[i*2+1] = period_size_bytes << 16; |
598 | } | 596 | } |
599 | 597 | ||
600 | snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel)); | 598 | snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel)); |
@@ -1008,13 +1006,8 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1008 | unsigned int stat76; | 1006 | unsigned int stat76; |
1009 | ca0106_channel_t *pchannel; | 1007 | ca0106_channel_t *pchannel; |
1010 | 1008 | ||
1011 | spin_lock(&chip->emu_lock); | ||
1012 | |||
1013 | status = inl(chip->port + IPR); | 1009 | status = inl(chip->port + IPR); |
1014 | 1010 | ||
1015 | // call updater, unlock before it | ||
1016 | spin_unlock(&chip->emu_lock); | ||
1017 | |||
1018 | if (! status) | 1011 | if (! status) |
1019 | return IRQ_NONE; | 1012 | return IRQ_NONE; |
1020 | 1013 | ||
@@ -1024,11 +1017,11 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1024 | mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */ | 1017 | mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */ |
1025 | for(i = 0; i < 4; i++) { | 1018 | for(i = 0; i < 4; i++) { |
1026 | pchannel = &(chip->playback_channels[i]); | 1019 | pchannel = &(chip->playback_channels[i]); |
1027 | if(stat76 & mask) { | 1020 | if (stat76 & mask) { |
1028 | /* FIXME: Select the correct substream for period elapsed */ | 1021 | /* FIXME: Select the correct substream for period elapsed */ |
1029 | if(pchannel->use) { | 1022 | if(pchannel->use) { |
1030 | snd_pcm_period_elapsed(pchannel->epcm->substream); | 1023 | snd_pcm_period_elapsed(pchannel->epcm->substream); |
1031 | //printk(KERN_INFO "interrupt [%d] used\n", i); | 1024 | //printk(KERN_INFO "interrupt [%d] used\n", i); |
1032 | } | 1025 | } |
1033 | } | 1026 | } |
1034 | //printk(KERN_INFO "channel=%p\n",pchannel); | 1027 | //printk(KERN_INFO "channel=%p\n",pchannel); |
@@ -1038,11 +1031,11 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1038 | mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */ | 1031 | mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */ |
1039 | for(i = 0; i < 4; i++) { | 1032 | for(i = 0; i < 4; i++) { |
1040 | pchannel = &(chip->capture_channels[i]); | 1033 | pchannel = &(chip->capture_channels[i]); |
1041 | if(stat76 & mask) { | 1034 | if (stat76 & mask) { |
1042 | /* FIXME: Select the correct substream for period elapsed */ | 1035 | /* FIXME: Select the correct substream for period elapsed */ |
1043 | if(pchannel->use) { | 1036 | if(pchannel->use) { |
1044 | snd_pcm_period_elapsed(pchannel->epcm->substream); | 1037 | snd_pcm_period_elapsed(pchannel->epcm->substream); |
1045 | //printk(KERN_INFO "interrupt [%d] used\n", i); | 1038 | //printk(KERN_INFO "interrupt [%d] used\n", i); |
1046 | } | 1039 | } |
1047 | } | 1040 | } |
1048 | //printk(KERN_INFO "channel=%p\n",pchannel); | 1041 | //printk(KERN_INFO "channel=%p\n",pchannel); |
@@ -1051,10 +1044,9 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1051 | } | 1044 | } |
1052 | 1045 | ||
1053 | snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76); | 1046 | snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76); |
1054 | spin_lock(&chip->emu_lock); | ||
1055 | 1047 | ||
1056 | if (chip->midi.dev_id && | 1048 | if (chip->midi.dev_id && |
1057 | (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) { | 1049 | (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) { |
1058 | if (chip->midi.interrupt) | 1050 | if (chip->midi.interrupt) |
1059 | chip->midi.interrupt(&chip->midi, status); | 1051 | chip->midi.interrupt(&chip->midi, status); |
1060 | else | 1052 | else |
@@ -1064,8 +1056,6 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, | |||
1064 | // acknowledge the interrupt if necessary | 1056 | // acknowledge the interrupt if necessary |
1065 | outl(status, chip->port+IPR); | 1057 | outl(status, chip->port+IPR); |
1066 | 1058 | ||
1067 | spin_unlock(&chip->emu_lock); | ||
1068 | |||
1069 | return IRQ_HANDLED; | 1059 | return IRQ_HANDLED; |
1070 | } | 1060 | } |
1071 | 1061 | ||
@@ -1202,8 +1192,9 @@ static int __devinit snd_ca0106_create(snd_card_t *card, | |||
1202 | strcpy(card->driver, "CA0106"); | 1192 | strcpy(card->driver, "CA0106"); |
1203 | strcpy(card->shortname, "CA0106"); | 1193 | strcpy(card->shortname, "CA0106"); |
1204 | 1194 | ||
1205 | for (c=ca0106_chip_details; c->serial; c++) { | 1195 | for (c = ca0106_chip_details; c->serial; c++) { |
1206 | if (c->serial == chip->serial) break; | 1196 | if (c->serial == chip->serial) |
1197 | break; | ||
1207 | } | 1198 | } |
1208 | chip->details = c; | 1199 | chip->details = c; |
1209 | sprintf(card->longname, "%s at 0x%lx irq %i", | 1200 | sprintf(card->longname, "%s at 0x%lx irq %i", |
@@ -1359,7 +1350,7 @@ static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel) | |||
1359 | char *name; | 1350 | char *name; |
1360 | int err; | 1351 | int err; |
1361 | 1352 | ||
1362 | if(channel==CA0106_MIDI_CHAN_B) { | 1353 | if (channel == CA0106_MIDI_CHAN_B) { |
1363 | name = "CA0106 MPU-401 (UART) B"; | 1354 | name = "CA0106 MPU-401 (UART) B"; |
1364 | midi = &chip->midi2; | 1355 | midi = &chip->midi2; |
1365 | midi->tx_enable = INTE_MIDI_TX_B; | 1356 | midi->tx_enable = INTE_MIDI_TX_B; |
@@ -1499,12 +1490,7 @@ static struct pci_driver driver = { | |||
1499 | // initialization of the module | 1490 | // initialization of the module |
1500 | static int __init alsa_card_ca0106_init(void) | 1491 | static int __init alsa_card_ca0106_init(void) |
1501 | { | 1492 | { |
1502 | int err; | 1493 | return pci_register_driver(&driver); |
1503 | |||
1504 | if ((err = pci_register_driver(&driver)) > 0) | ||
1505 | return err; | ||
1506 | |||
1507 | return 0; | ||
1508 | } | 1494 | } |
1509 | 1495 | ||
1510 | // clean up the module | 1496 | // clean up the module |
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index c10e4a54301b..0730dc7c66e5 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -125,18 +125,11 @@ static int snd_ca0106_shared_spdif_put(snd_kcontrol_t * kcontrol, | |||
125 | return change; | 125 | return change; |
126 | } | 126 | } |
127 | 127 | ||
128 | static snd_kcontrol_new_t snd_ca0106_shared_spdif __devinitdata = | ||
129 | { | ||
130 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
131 | .name = "SPDIF Out", | ||
132 | .info = snd_ca0106_shared_spdif_info, | ||
133 | .get = snd_ca0106_shared_spdif_get, | ||
134 | .put = snd_ca0106_shared_spdif_put | ||
135 | }; | ||
136 | |||
137 | static int snd_ca0106_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | 128 | static int snd_ca0106_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) |
138 | { | 129 | { |
139 | static char *texts[6] = { "SPDIF out", "i2s mixer out", "SPDIF in", "i2s in", "AC97 in", "SRC out" }; | 130 | static char *texts[6] = { |
131 | "SPDIF out", "i2s mixer out", "SPDIF in", "i2s in", "AC97 in", "SRC out" | ||
132 | }; | ||
140 | 133 | ||
141 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 134 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
142 | uinfo->count = 1; | 135 | uinfo->count = 1; |
@@ -176,15 +169,6 @@ static int snd_ca0106_capture_source_put(snd_kcontrol_t * kcontrol, | |||
176 | return change; | 169 | return change; |
177 | } | 170 | } |
178 | 171 | ||
179 | static snd_kcontrol_new_t snd_ca0106_capture_source __devinitdata = | ||
180 | { | ||
181 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
182 | .name = "Capture Source", | ||
183 | .info = snd_ca0106_capture_source_info, | ||
184 | .get = snd_ca0106_capture_source_get, | ||
185 | .put = snd_ca0106_capture_source_put | ||
186 | }; | ||
187 | |||
188 | static int snd_ca0106_capture_mic_line_in_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | 172 | static int snd_ca0106_capture_mic_line_in_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) |
189 | { | 173 | { |
190 | static char *texts[2] = { "Line in", "Mic in" }; | 174 | static char *texts[2] = { "Line in", "Mic in" }; |
@@ -294,26 +278,6 @@ static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol, | |||
294 | return change; | 278 | return change; |
295 | } | 279 | } |
296 | 280 | ||
297 | static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = | ||
298 | { | ||
299 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
300 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
301 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | ||
302 | .count = 4, | ||
303 | .info = snd_ca0106_spdif_info, | ||
304 | .get = snd_ca0106_spdif_get_mask | ||
305 | }; | ||
306 | |||
307 | static snd_kcontrol_new_t snd_ca0106_spdif_control = | ||
308 | { | ||
309 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
310 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | ||
311 | .count = 4, | ||
312 | .info = snd_ca0106_spdif_info, | ||
313 | .get = snd_ca0106_spdif_get, | ||
314 | .put = snd_ca0106_spdif_put | ||
315 | }; | ||
316 | |||
317 | static int snd_ca0106_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | 281 | static int snd_ca0106_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) |
318 | { | 282 | { |
319 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 283 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
@@ -324,10 +288,14 @@ static int snd_ca0106_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t | |||
324 | } | 288 | } |
325 | 289 | ||
326 | static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol, | 290 | static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol, |
327 | snd_ctl_elem_value_t * ucontrol, int reg, int channel_id) | 291 | snd_ctl_elem_value_t * ucontrol) |
328 | { | 292 | { |
329 | ca0106_t *emu = snd_kcontrol_chip(kcontrol); | 293 | ca0106_t *emu = snd_kcontrol_chip(kcontrol); |
330 | unsigned int value; | 294 | unsigned int value; |
295 | int channel_id, reg; | ||
296 | |||
297 | channel_id = (kcontrol->private_value >> 8) & 0xff; | ||
298 | reg = kcontrol->private_value & 0xff; | ||
331 | 299 | ||
332 | value = snd_ca0106_ptr_read(emu, reg, channel_id); | 300 | value = snd_ca0106_ptr_read(emu, reg, channel_id); |
333 | ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */ | 301 | ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */ |
@@ -335,226 +303,92 @@ static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol, | |||
335 | return 0; | 303 | return 0; |
336 | } | 304 | } |
337 | 305 | ||
338 | static int snd_ca0106_volume_get_spdif_front(snd_kcontrol_t * kcontrol, | ||
339 | snd_ctl_elem_value_t * ucontrol) | ||
340 | { | ||
341 | int channel_id = CONTROL_FRONT_CHANNEL; | ||
342 | int reg = PLAYBACK_VOLUME1; | ||
343 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
344 | } | ||
345 | |||
346 | static int snd_ca0106_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol, | ||
347 | snd_ctl_elem_value_t * ucontrol) | ||
348 | { | ||
349 | int channel_id = CONTROL_CENTER_LFE_CHANNEL; | ||
350 | int reg = PLAYBACK_VOLUME1; | ||
351 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
352 | } | ||
353 | static int snd_ca0106_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol, | ||
354 | snd_ctl_elem_value_t * ucontrol) | ||
355 | { | ||
356 | int channel_id = CONTROL_UNKNOWN_CHANNEL; | ||
357 | int reg = PLAYBACK_VOLUME1; | ||
358 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
359 | } | ||
360 | static int snd_ca0106_volume_get_spdif_rear(snd_kcontrol_t * kcontrol, | ||
361 | snd_ctl_elem_value_t * ucontrol) | ||
362 | { | ||
363 | int channel_id = CONTROL_REAR_CHANNEL; | ||
364 | int reg = PLAYBACK_VOLUME1; | ||
365 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
366 | } | ||
367 | static int snd_ca0106_volume_get_analog_front(snd_kcontrol_t * kcontrol, | ||
368 | snd_ctl_elem_value_t * ucontrol) | ||
369 | { | ||
370 | int channel_id = CONTROL_FRONT_CHANNEL; | ||
371 | int reg = PLAYBACK_VOLUME2; | ||
372 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
373 | } | ||
374 | |||
375 | static int snd_ca0106_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol, | ||
376 | snd_ctl_elem_value_t * ucontrol) | ||
377 | { | ||
378 | int channel_id = CONTROL_CENTER_LFE_CHANNEL; | ||
379 | int reg = PLAYBACK_VOLUME2; | ||
380 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
381 | } | ||
382 | static int snd_ca0106_volume_get_analog_unknown(snd_kcontrol_t * kcontrol, | ||
383 | snd_ctl_elem_value_t * ucontrol) | ||
384 | { | ||
385 | int channel_id = CONTROL_UNKNOWN_CHANNEL; | ||
386 | int reg = PLAYBACK_VOLUME2; | ||
387 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
388 | } | ||
389 | static int snd_ca0106_volume_get_analog_rear(snd_kcontrol_t * kcontrol, | ||
390 | snd_ctl_elem_value_t * ucontrol) | ||
391 | { | ||
392 | int channel_id = CONTROL_REAR_CHANNEL; | ||
393 | int reg = PLAYBACK_VOLUME2; | ||
394 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
395 | } | ||
396 | |||
397 | static int snd_ca0106_volume_get_feedback(snd_kcontrol_t * kcontrol, | ||
398 | snd_ctl_elem_value_t * ucontrol) | ||
399 | { | ||
400 | int channel_id = 1; | ||
401 | int reg = CAPTURE_CONTROL; | ||
402 | return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id); | ||
403 | } | ||
404 | |||
405 | static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol, | 306 | static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol, |
406 | snd_ctl_elem_value_t * ucontrol, int reg, int channel_id) | 307 | snd_ctl_elem_value_t * ucontrol) |
407 | { | 308 | { |
408 | ca0106_t *emu = snd_kcontrol_chip(kcontrol); | 309 | ca0106_t *emu = snd_kcontrol_chip(kcontrol); |
409 | unsigned int value; | 310 | unsigned int oval, nval; |
410 | //value = snd_ca0106_ptr_read(emu, reg, channel_id); | 311 | int channel_id, reg; |
411 | //value = value & 0xffff; | 312 | |
412 | value = ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16); | 313 | channel_id = (kcontrol->private_value >> 8) & 0xff; |
413 | value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) ); | 314 | reg = kcontrol->private_value & 0xff; |
414 | snd_ca0106_ptr_write(emu, reg, channel_id, value); | 315 | |
415 | return 1; | 316 | oval = snd_ca0106_ptr_read(emu, reg, channel_id); |
416 | } | 317 | nval = ((0xff - ucontrol->value.integer.value[0]) << 24) | |
417 | static int snd_ca0106_volume_put_spdif_front(snd_kcontrol_t * kcontrol, | 318 | ((0xff - ucontrol->value.integer.value[1]) << 16); |
418 | snd_ctl_elem_value_t * ucontrol) | 319 | nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) | |
419 | { | 320 | ((0xff - ucontrol->value.integer.value[1]) ); |
420 | int channel_id = CONTROL_FRONT_CHANNEL; | 321 | if (oval == nval) |
421 | int reg = PLAYBACK_VOLUME1; | 322 | return 0; |
422 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 323 | snd_ca0106_ptr_write(emu, reg, channel_id, nval); |
423 | } | 324 | return 1; |
424 | static int snd_ca0106_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol, | 325 | } |
425 | snd_ctl_elem_value_t * ucontrol) | 326 | |
426 | { | 327 | #define CA_VOLUME(xname,chid,reg) \ |
427 | int channel_id = CONTROL_CENTER_LFE_CHANNEL; | 328 | { \ |
428 | int reg = PLAYBACK_VOLUME1; | 329 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
429 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 330 | .info = snd_ca0106_volume_info, \ |
430 | } | 331 | .get = snd_ca0106_volume_get, \ |
431 | static int snd_ca0106_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol, | 332 | .put = snd_ca0106_volume_put, \ |
432 | snd_ctl_elem_value_t * ucontrol) | 333 | .private_value = ((chid) << 8) | (reg) \ |
433 | { | 334 | } |
434 | int channel_id = CONTROL_UNKNOWN_CHANNEL; | 335 | |
435 | int reg = PLAYBACK_VOLUME1; | 336 | |
436 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 337 | static snd_kcontrol_new_t snd_ca0106_volume_ctls[] __devinitdata = { |
437 | } | 338 | CA_VOLUME("Analog Front Playback Volume", |
438 | static int snd_ca0106_volume_put_spdif_rear(snd_kcontrol_t * kcontrol, | 339 | CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2), |
439 | snd_ctl_elem_value_t * ucontrol) | 340 | CA_VOLUME("Analog Rear Playback Volume", |
440 | { | 341 | CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2), |
441 | int channel_id = CONTROL_REAR_CHANNEL; | 342 | CA_VOLUME("Analog Center/LFE Playback Volume", |
442 | int reg = PLAYBACK_VOLUME1; | 343 | CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2), |
443 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 344 | CA_VOLUME("Analog Side Playback Volume", |
444 | } | 345 | CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2), |
445 | static int snd_ca0106_volume_put_analog_front(snd_kcontrol_t * kcontrol, | 346 | |
446 | snd_ctl_elem_value_t * ucontrol) | 347 | CA_VOLUME("SPDIF Front Playback Volume", |
447 | { | 348 | CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1), |
448 | int channel_id = CONTROL_FRONT_CHANNEL; | 349 | CA_VOLUME("SPDIF Rear Playback Volume", |
449 | int reg = PLAYBACK_VOLUME2; | 350 | CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1), |
450 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 351 | CA_VOLUME("SPDIF Center/LFE Playback Volume", |
451 | } | 352 | CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1), |
452 | static int snd_ca0106_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol, | 353 | CA_VOLUME("SPDIF Unknown Playback Volume", |
453 | snd_ctl_elem_value_t * ucontrol) | 354 | CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1), |
454 | { | 355 | |
455 | int channel_id = CONTROL_CENTER_LFE_CHANNEL; | 356 | CA_VOLUME("CAPTURE feedback Playback Volume", |
456 | int reg = PLAYBACK_VOLUME2; | 357 | 1, CAPTURE_CONTROL), |
457 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 358 | |
458 | } | 359 | { |
459 | static int snd_ca0106_volume_put_analog_unknown(snd_kcontrol_t * kcontrol, | 360 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
460 | snd_ctl_elem_value_t * ucontrol) | 361 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
461 | { | 362 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
462 | int channel_id = CONTROL_UNKNOWN_CHANNEL; | 363 | .count = 4, |
463 | int reg = PLAYBACK_VOLUME2; | 364 | .info = snd_ca0106_spdif_info, |
464 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 365 | .get = snd_ca0106_spdif_get_mask |
465 | } | 366 | }, |
466 | static int snd_ca0106_volume_put_analog_rear(snd_kcontrol_t * kcontrol, | 367 | { |
467 | snd_ctl_elem_value_t * ucontrol) | 368 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
468 | { | 369 | .name = "SPDIF Out", |
469 | int channel_id = CONTROL_REAR_CHANNEL; | 370 | .info = snd_ca0106_shared_spdif_info, |
470 | int reg = PLAYBACK_VOLUME2; | 371 | .get = snd_ca0106_shared_spdif_get, |
471 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 372 | .put = snd_ca0106_shared_spdif_put |
472 | } | 373 | }, |
473 | 374 | { | |
474 | static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol, | 375 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
475 | snd_ctl_elem_value_t * ucontrol) | 376 | .name = "Capture Source", |
476 | { | 377 | .info = snd_ca0106_capture_source_info, |
477 | int channel_id = 1; | 378 | .get = snd_ca0106_capture_source_get, |
478 | int reg = CAPTURE_CONTROL; | 379 | .put = snd_ca0106_capture_source_put |
479 | return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id); | 380 | }, |
480 | } | 381 | { |
481 | 382 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
482 | static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front = | 383 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
483 | { | 384 | .count = 4, |
484 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 385 | .info = snd_ca0106_spdif_info, |
485 | .name = "Analog Front Playback Volume", | 386 | .get = snd_ca0106_spdif_get, |
486 | .info = snd_ca0106_volume_info, | 387 | .put = snd_ca0106_spdif_put |
487 | .get = snd_ca0106_volume_get_analog_front, | 388 | }, |
488 | .put = snd_ca0106_volume_put_analog_front | ||
489 | }; | ||
490 | static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe = | ||
491 | { | ||
492 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
493 | .name = "Analog Center/LFE Playback Volume", | ||
494 | .info = snd_ca0106_volume_info, | ||
495 | .get = snd_ca0106_volume_get_analog_center_lfe, | ||
496 | .put = snd_ca0106_volume_put_analog_center_lfe | ||
497 | }; | ||
498 | static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown = | ||
499 | { | ||
500 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
501 | .name = "Analog Side Playback Volume", | ||
502 | .info = snd_ca0106_volume_info, | ||
503 | .get = snd_ca0106_volume_get_analog_unknown, | ||
504 | .put = snd_ca0106_volume_put_analog_unknown | ||
505 | }; | ||
506 | static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear = | ||
507 | { | ||
508 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
509 | .name = "Analog Rear Playback Volume", | ||
510 | .info = snd_ca0106_volume_info, | ||
511 | .get = snd_ca0106_volume_get_analog_rear, | ||
512 | .put = snd_ca0106_volume_put_analog_rear | ||
513 | }; | ||
514 | static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front = | ||
515 | { | ||
516 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
517 | .name = "SPDIF Front Playback Volume", | ||
518 | .info = snd_ca0106_volume_info, | ||
519 | .get = snd_ca0106_volume_get_spdif_front, | ||
520 | .put = snd_ca0106_volume_put_spdif_front | ||
521 | }; | ||
522 | static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe = | ||
523 | { | ||
524 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
525 | .name = "SPDIF Center/LFE Playback Volume", | ||
526 | .info = snd_ca0106_volume_info, | ||
527 | .get = snd_ca0106_volume_get_spdif_center_lfe, | ||
528 | .put = snd_ca0106_volume_put_spdif_center_lfe | ||
529 | }; | ||
530 | static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown = | ||
531 | { | ||
532 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
533 | .name = "SPDIF Unknown Playback Volume", | ||
534 | .info = snd_ca0106_volume_info, | ||
535 | .get = snd_ca0106_volume_get_spdif_unknown, | ||
536 | .put = snd_ca0106_volume_put_spdif_unknown | ||
537 | }; | ||
538 | static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear = | ||
539 | { | ||
540 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
541 | .name = "SPDIF Rear Playback Volume", | ||
542 | .info = snd_ca0106_volume_info, | ||
543 | .get = snd_ca0106_volume_get_spdif_rear, | ||
544 | .put = snd_ca0106_volume_put_spdif_rear | ||
545 | }; | ||
546 | |||
547 | static snd_kcontrol_new_t snd_ca0106_volume_control_feedback = | ||
548 | { | ||
549 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
550 | .name = "CAPTURE feedback Playback Volume", | ||
551 | .info = snd_ca0106_volume_info, | ||
552 | .get = snd_ca0106_volume_get_feedback, | ||
553 | .put = snd_ca0106_volume_put_feedback | ||
554 | }; | 389 | }; |
555 | 390 | ||
556 | 391 | static int __devinit remove_ctl(snd_card_t *card, const char *name) | |
557 | static int remove_ctl(snd_card_t *card, const char *name) | ||
558 | { | 392 | { |
559 | snd_ctl_elem_id_t id; | 393 | snd_ctl_elem_id_t id; |
560 | memset(&id, 0, sizeof(id)); | 394 | memset(&id, 0, sizeof(id)); |
@@ -563,7 +397,7 @@ static int remove_ctl(snd_card_t *card, const char *name) | |||
563 | return snd_ctl_remove_id(card, &id); | 397 | return snd_ctl_remove_id(card, &id); |
564 | } | 398 | } |
565 | 399 | ||
566 | static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name) | 400 | static snd_kcontrol_t __devinit *ctl_find(snd_card_t *card, const char *name) |
567 | { | 401 | { |
568 | snd_ctl_elem_id_t sid; | 402 | snd_ctl_elem_id_t sid; |
569 | memset(&sid, 0, sizeof(sid)); | 403 | memset(&sid, 0, sizeof(sid)); |
@@ -573,7 +407,7 @@ static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name) | |||
573 | return snd_ctl_find_id(card, &sid); | 407 | return snd_ctl_find_id(card, &sid); |
574 | } | 408 | } |
575 | 409 | ||
576 | static int rename_ctl(snd_card_t *card, const char *src, const char *dst) | 410 | static int __devinit rename_ctl(snd_card_t *card, const char *src, const char *dst) |
577 | { | 411 | { |
578 | snd_kcontrol_t *kctl = ctl_find(card, src); | 412 | snd_kcontrol_t *kctl = ctl_find(card, src); |
579 | if (kctl) { | 413 | if (kctl) { |
@@ -585,8 +419,7 @@ static int rename_ctl(snd_card_t *card, const char *src, const char *dst) | |||
585 | 419 | ||
586 | int __devinit snd_ca0106_mixer(ca0106_t *emu) | 420 | int __devinit snd_ca0106_mixer(ca0106_t *emu) |
587 | { | 421 | { |
588 | int err; | 422 | int i, err; |
589 | snd_kcontrol_t *kctl; | ||
590 | snd_card_t *card = emu->card; | 423 | snd_card_t *card = emu->card; |
591 | char **c; | 424 | char **c; |
592 | static char *ca0106_remove_ctls[] = { | 425 | static char *ca0106_remove_ctls[] = { |
@@ -627,70 +460,22 @@ int __devinit snd_ca0106_mixer(ca0106_t *emu) | |||
627 | NULL | 460 | NULL |
628 | }; | 461 | }; |
629 | #if 1 | 462 | #if 1 |
630 | for (c=ca0106_remove_ctls; *c; c++) | 463 | for (c = ca0106_remove_ctls; *c; c++) |
631 | remove_ctl(card, *c); | 464 | remove_ctl(card, *c); |
632 | for (c=ca0106_rename_ctls; *c; c += 2) | 465 | for (c = ca0106_rename_ctls; *c; c += 2) |
633 | rename_ctl(card, c[0], c[1]); | 466 | rename_ctl(card, c[0], c[1]); |
634 | #endif | 467 | #endif |
635 | 468 | ||
636 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_front, emu)) == NULL) | 469 | for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_ctls); i++) { |
637 | return -ENOMEM; | 470 | err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_ctls[i], emu)); |
638 | if ((err = snd_ctl_add(card, kctl))) | 471 | if (err < 0) |
639 | return err; | 472 | return err; |
640 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_rear, emu)) == NULL) | 473 | } |
641 | return -ENOMEM; | ||
642 | if ((err = snd_ctl_add(card, kctl))) | ||
643 | return err; | ||
644 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_center_lfe, emu)) == NULL) | ||
645 | return -ENOMEM; | ||
646 | if ((err = snd_ctl_add(card, kctl))) | ||
647 | return err; | ||
648 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_unknown, emu)) == NULL) | ||
649 | return -ENOMEM; | ||
650 | if ((err = snd_ctl_add(card, kctl))) | ||
651 | return err; | ||
652 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_front, emu)) == NULL) | ||
653 | return -ENOMEM; | ||
654 | if ((err = snd_ctl_add(card, kctl))) | ||
655 | return err; | ||
656 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_rear, emu)) == NULL) | ||
657 | return -ENOMEM; | ||
658 | if ((err = snd_ctl_add(card, kctl))) | ||
659 | return err; | ||
660 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_center_lfe, emu)) == NULL) | ||
661 | return -ENOMEM; | ||
662 | if ((err = snd_ctl_add(card, kctl))) | ||
663 | return err; | ||
664 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_unknown, emu)) == NULL) | ||
665 | return -ENOMEM; | ||
666 | if ((err = snd_ctl_add(card, kctl))) | ||
667 | return err; | ||
668 | if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_feedback, emu)) == NULL) | ||
669 | return -ENOMEM; | ||
670 | if ((err = snd_ctl_add(card, kctl))) | ||
671 | return err; | ||
672 | if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_mask_control, emu)) == NULL) | ||
673 | return -ENOMEM; | ||
674 | if ((err = snd_ctl_add(card, kctl))) | ||
675 | return err; | ||
676 | if ((kctl = snd_ctl_new1(&snd_ca0106_shared_spdif, emu)) == NULL) | ||
677 | return -ENOMEM; | ||
678 | if ((err = snd_ctl_add(card, kctl))) | ||
679 | return err; | ||
680 | if ((kctl = snd_ctl_new1(&snd_ca0106_capture_source, emu)) == NULL) | ||
681 | return -ENOMEM; | ||
682 | if ((err = snd_ctl_add(card, kctl))) | ||
683 | return err; | ||
684 | if (emu->details->i2c_adc == 1) { | 474 | if (emu->details->i2c_adc == 1) { |
685 | if ((kctl = snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)) == NULL) | 475 | err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); |
686 | return -ENOMEM; | 476 | if (err < 0) |
687 | if ((err = snd_ctl_add(card, kctl))) | ||
688 | return err; | 477 | return err; |
689 | } | 478 | } |
690 | if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL) | ||
691 | return -ENOMEM; | ||
692 | if ((err = snd_ctl_add(card, kctl))) | ||
693 | return err; | ||
694 | return 0; | 479 | return 0; |
695 | } | 480 | } |
696 | 481 | ||