diff options
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 74 |
1 files changed, 30 insertions, 44 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 |