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.c136
1 files changed, 93 insertions, 43 deletions
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 0a3d3d6e77b4..d2d12c08f937 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -227,7 +227,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
227 .name = "Audigy SE [SB0570]", 227 .name = "Audigy SE [SB0570]",
228 .gpio_type = 1, 228 .gpio_type = 1,
229 .i2c_adc = 1, 229 .i2c_adc = 1,
230 .spi_dac = 1 } , 230 .spi_dac = 0x4021 } ,
231 /* New Audigy LS. Has a different DAC. */ 231 /* New Audigy LS. Has a different DAC. */
232 /* SB0570: 232 /* SB0570:
233 * CTRL:CA0106-DAT 233 * CTRL:CA0106-DAT
@@ -238,7 +238,17 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
238 .name = "Audigy SE OEM [SB0570a]", 238 .name = "Audigy SE OEM [SB0570a]",
239 .gpio_type = 1, 239 .gpio_type = 1,
240 .i2c_adc = 1, 240 .i2c_adc = 1,
241 .spi_dac = 1 } , 241 .spi_dac = 0x4021 } ,
242 /* Sound Blaster 5.1vx
243 * Tested: Playback on front, rear, center/lfe speakers
244 * Not-Tested: Capture
245 */
246 { .serial = 0x10041102,
247 .name = "Sound Blaster 5.1vx [SB1070]",
248 .gpio_type = 1,
249 .i2c_adc = 0,
250 .spi_dac = 0x0124
251 } ,
242 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 252 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
243 /* SB0438 253 /* SB0438
244 * CTRL:CA0106-DAT 254 * CTRL:CA0106-DAT
@@ -254,7 +264,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 264 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 265 .gpio_type = 2,
256 .i2c_adc = 1, 266 .i2c_adc = 1,
257 .spi_dac = 1 } , 267 .spi_dac = 0x4021 } ,
258 /* Giga-byte GA-G1975X mobo 268 /* Giga-byte GA-G1975X mobo
259 * Novell bnc#395807 269 * Novell bnc#395807
260 */ 270 */
@@ -483,16 +493,18 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
483} 493}
484 494
485static const int spi_dacd_reg[] = { 495static const int spi_dacd_reg[] = {
486 [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, 496 SPI_DACD0_REG,
487 [PCM_REAR_CHANNEL] = SPI_DACD0_REG, 497 SPI_DACD1_REG,
488 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, 498 SPI_DACD2_REG,
489 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, 499 0,
500 SPI_DACD4_REG,
490}; 501};
491static const int spi_dacd_bit[] = { 502static const int spi_dacd_bit[] = {
492 [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT, 503 SPI_DACD0_BIT,
493 [PCM_REAR_CHANNEL] = SPI_DACD0_BIT, 504 SPI_DACD1_BIT,
494 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT, 505 SPI_DACD2_BIT,
495 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 506 0,
507 SPI_DACD4_BIT,
496}; 508};
497 509
498static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) 510static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
@@ -504,6 +516,45 @@ static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
504 } 516 }
505} 517}
506 518
519static int snd_ca0106_channel_dac(struct snd_ca0106_details *details,
520 int channel_id)
521{
522 switch (channel_id) {
523 case PCM_FRONT_CHANNEL:
524 return (details->spi_dac & 0xf000) >> (4 * 3);
525 case PCM_REAR_CHANNEL:
526 return (details->spi_dac & 0x0f00) >> (4 * 2);
527 case PCM_CENTER_LFE_CHANNEL:
528 return (details->spi_dac & 0x00f0) >> (4 * 1);
529 case PCM_UNKNOWN_CHANNEL:
530 return (details->spi_dac & 0x000f) >> (4 * 0);
531 default:
532 snd_printk(KERN_DEBUG "ca0106: unknown channel_id %d\n",
533 channel_id);
534 }
535 return 0;
536}
537
538static int snd_ca0106_pcm_power_dac(struct snd_ca0106 *chip, int channel_id,
539 int power)
540{
541 if (chip->details->spi_dac) {
542 const int dac = snd_ca0106_channel_dac(chip->details,
543 channel_id);
544 const int reg = spi_dacd_reg[dac];
545 const int bit = spi_dacd_bit[dac];
546
547 if (power)
548 /* Power up */
549 chip->spi_dac_reg[reg] &= ~bit;
550 else
551 /* Power down */
552 chip->spi_dac_reg[reg] |= bit;
553 return snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
554 }
555 return 0;
556}
557
507/* open_playback callback */ 558/* open_playback callback */
508static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 559static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
509 int channel_id) 560 int channel_id)
@@ -543,12 +594,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
543 return err; 594 return err;
544 snd_pcm_set_sync(substream); 595 snd_pcm_set_sync(substream);
545 596
546 if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { 597 /* Front channel dac should already be on */
547 const int reg = spi_dacd_reg[channel_id]; 598 if (channel_id != PCM_FRONT_CHANNEL) {
548 599 err = snd_ca0106_pcm_power_dac(chip, channel_id, 1);
549 /* Power up dac */
550 chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
551 err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
552 if (err < 0) 600 if (err < 0)
553 return err; 601 return err;
554 } 602 }
@@ -568,13 +616,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
568 616
569 restore_spdif_bits(chip, epcm->channel_id); 617 restore_spdif_bits(chip, epcm->channel_id);
570 618
571 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 619 /* Front channel dac should stay on */
572 const int reg = spi_dacd_reg[epcm->channel_id]; 620 if (epcm->channel_id != PCM_FRONT_CHANNEL) {
573 621 int err;
574 /* Power down DAC */ 622 err = snd_ca0106_pcm_power_dac(chip, epcm->channel_id, 0);
575 chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; 623 if (err < 0)
576 snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); 624 return err;
577 } 625 }
626
578 /* FIXME: maybe zero others */ 627 /* FIXME: maybe zero others */
579 return 0; 628 return 0;
580} 629}
@@ -1002,29 +1051,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
1002 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); 1051 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
1003 struct snd_pcm_runtime *runtime = substream->runtime; 1052 struct snd_pcm_runtime *runtime = substream->runtime;
1004 struct snd_ca0106_pcm *epcm = runtime->private_data; 1053 struct snd_ca0106_pcm *epcm = runtime->private_data;
1005 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; 1054 unsigned int ptr, prev_ptr;
1006 int channel = epcm->channel_id; 1055 int channel = epcm->channel_id;
1056 int timeout = 10;
1007 1057
1008 if (!epcm->running) 1058 if (!epcm->running)
1009 return 0; 1059 return 0;
1010 1060
1011 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1061 prev_ptr = -1;
1012 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1062 do {
1013 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1063 ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
1014 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1064 ptr = (ptr >> 3) * runtime->period_size;
1015 ptr2 = bytes_to_frames(runtime, ptr1); 1065 ptr += bytes_to_frames(runtime,
1016 ptr2+= (ptr4 >> 3) * runtime->period_size; 1066 snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
1017 ptr=ptr2; 1067 if (ptr >= runtime->buffer_size)
1018 if (ptr >= runtime->buffer_size) 1068 ptr -= runtime->buffer_size;
1019 ptr -= runtime->buffer_size; 1069 if (prev_ptr == ptr)
1020 /* 1070 return ptr;
1021 printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " 1071 prev_ptr = ptr;
1022 "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", 1072 } while (--timeout);
1023 ptr1, ptr2, ptr, (int)runtime->buffer_size, 1073 snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
1024 (int)runtime->period_size, (int)runtime->frame_bits, 1074 return 0;
1025 (int)runtime->rate);
1026 */
1027 return ptr;
1028} 1075}
1029 1076
1030/* pointer_capture callback */ 1077/* pointer_capture callback */
@@ -1362,7 +1409,7 @@ static unsigned int spi_dac_init[] = {
1362 SPI_REG(12, 0x00), 1409 SPI_REG(12, 0x00),
1363 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), 1410 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB),
1364 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), 1411 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE),
1365 SPI_REG(SPI_DACD4_REG, 0x00), 1412 SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT),
1366}; 1413};
1367 1414
1368static unsigned int i2c_adc_init[][2] = { 1415static unsigned int i2c_adc_init[][2] = {
@@ -1541,7 +1588,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1541 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */ 1588 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1542 } 1589 }
1543 1590
1544 if (chip->details->spi_dac == 1) { 1591 if (chip->details->spi_dac) {
1545 /* The SB0570 use SPI to control DAC. */ 1592 /* The SB0570 use SPI to control DAC. */
1546 int size, n; 1593 int size, n;
1547 1594
@@ -1553,6 +1600,9 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1553 if (reg < ARRAY_SIZE(chip->spi_dac_reg)) 1600 if (reg < ARRAY_SIZE(chip->spi_dac_reg))
1554 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1601 chip->spi_dac_reg[reg] = spi_dac_init[n];
1555 } 1602 }
1603
1604 /* Enable front dac only */
1605 snd_ca0106_pcm_power_dac(chip, PCM_FRONT_CHANNEL, 1);
1556 } 1606 }
1557} 1607}
1558 1608