aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106/ca0106_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ca0106/ca0106_main.c')
-rw-r--r--sound/pci/ca0106/ca0106_main.c74
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
1500static int __init alsa_card_ca0106_init(void) 1491static 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