aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106
diff options
context:
space:
mode:
authorTrent Piepho <xyzzy@speakeasy.org>2007-07-25 12:39:59 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:57:58 -0400
commit485100706b4b397f8072c756839878f634e21f85 (patch)
treefa17ce759c9a6d7108523006747af252e15f6b12 /sound/pci/ca0106
parentbddcf5411ffd17bfb86c2baed4a1b859c7071c98 (diff)
[ALSA] ca0106: power down SPI DAC channels when not in use
For cards with an SPI DAC (SB Live 24-bit / Audigy SE), power down channels 0-2 when not in use. They are powered up on PCM open and down again on PCM close. Channel 4 (== Front) is not powered down, as it is used for capture feedback. Powering it down would effectively kill line in pass-through. Signed-off-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/ca0106')
-rw-r--r--sound/pci/ca0106/ca0106.h2
-rw-r--r--sound/pci/ca0106/ca0106_main.c37
2 files changed, 36 insertions, 3 deletions
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 7ad03c6afd42..47d923821403 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -587,7 +587,7 @@
587#define SPI_DACD0_BIT 1 587#define SPI_DACD0_BIT 1
588#define SPI_DACD1_BIT 2 588#define SPI_DACD1_BIT 2
589#define SPI_DACD2_BIT 3 589#define SPI_DACD2_BIT 3
590#define SPI_DACD4_BIT 1 590#define SPI_DACD4_BIT 0 /* datasheet error says it's 1 */
591 591
592#define SPI_PWRDNALL_REG 10 /* power down everything */ 592#define SPI_PWRDNALL_REG 10 /* power down everything */
593#define SPI_PWRDNALL_BIT 4 593#define SPI_PWRDNALL_BIT 4
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 512fda946c66..36b7cdda7c41 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> 2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit 3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.24 4 * Version: 0.0.25
5 * 5 *
6 * FEATURES currently supported: 6 * FEATURES currently supported:
7 * Front, Rear and Center/LFE. 7 * Front, Rear and Center/LFE.
@@ -81,6 +81,8 @@
81 * Implement support for Line-in capture on SB Live 24bit. 81 * Implement support for Line-in capture on SB Live 24bit.
82 * 0.0.24 82 * 0.0.24
83 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) 83 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
84 * 0.0.25
85 * Powerdown SPI DAC channels when not in use
84 * 86 *
85 * BUGS: 87 * BUGS:
86 * Some stability problems when unloading the snd-ca0106 kernel module. 88 * Some stability problems when unloading the snd-ca0106 kernel module.
@@ -458,6 +460,19 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
458 kfree(runtime->private_data); 460 kfree(runtime->private_data);
459} 461}
460 462
463static const int spi_dacd_reg[] = {
464 [PCM_FRONT_CHANNEL] = SPI_DACD4_REG,
465 [PCM_REAR_CHANNEL] = SPI_DACD0_REG,
466 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG,
467 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG,
468};
469static const int spi_dacd_bit[] = {
470 [PCM_FRONT_CHANNEL] = 1<<SPI_DACD4_BIT,
471 [PCM_REAR_CHANNEL] = 1<<SPI_DACD0_BIT,
472 [PCM_CENTER_LFE_CHANNEL]= 1<<SPI_DACD2_BIT,
473 [PCM_UNKNOWN_CHANNEL] = 1<<SPI_DACD1_BIT,
474};
475
461/* open_playback callback */ 476/* open_playback callback */
462static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 477static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
463 int channel_id) 478 int channel_id)
@@ -492,6 +507,16 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
492 return err; 507 return err;
493 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) 508 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
494 return err; 509 return err;
510
511 if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) {
512 const int reg = spi_dacd_reg[channel_id];
513
514 /* Power up dac */
515 chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
516 err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
517 if (err < 0)
518 return err;
519 }
495 return 0; 520 return 0;
496} 521}
497 522
@@ -502,6 +527,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
502 struct snd_pcm_runtime *runtime = substream->runtime; 527 struct snd_pcm_runtime *runtime = substream->runtime;
503 struct snd_ca0106_pcm *epcm = runtime->private_data; 528 struct snd_ca0106_pcm *epcm = runtime->private_data;
504 chip->playback_channels[epcm->channel_id].use = 0; 529 chip->playback_channels[epcm->channel_id].use = 0;
530
531 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
532 const int reg = spi_dacd_reg[epcm->channel_id];
533
534 /* Power down DAC */
535 chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id];
536 snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
537 }
505 /* FIXME: maybe zero others */ 538 /* FIXME: maybe zero others */
506 return 0; 539 return 0;
507} 540}
@@ -1246,7 +1279,7 @@ static unsigned int spi_dac_init[] = {
1246 0x0530, 1279 0x0530,
1247 0x0602, 1280 0x0602,
1248 0x0622, 1281 0x0622,
1249 0x1400, 1282 0x140e,
1250}; 1283};
1251 1284
1252static unsigned int i2c_adc_init[][2] = { 1285static unsigned int i2c_adc_init[][2] = {