diff options
author | Trent Piepho <xyzzy@speakeasy.org> | 2007-07-25 12:39:59 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:57:58 -0400 |
commit | 485100706b4b397f8072c756839878f634e21f85 (patch) | |
tree | fa17ce759c9a6d7108523006747af252e15f6b12 /sound/pci/ca0106 | |
parent | bddcf5411ffd17bfb86c2baed4a1b859c7071c98 (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.h | 2 | ||||
-rw-r--r-- | sound/pci/ca0106/ca0106_main.c | 37 |
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 | ||
463 | static 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 | }; | ||
469 | static 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 */ |
462 | static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, | 477 | static 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 | ||
1252 | static unsigned int i2c_adc_init[][2] = { | 1285 | static unsigned int i2c_adc_init[][2] = { |