Commit 48510070 authored by Trent Piepho's avatar Trent Piepho Committed by Jaroslav Kysela

[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: default avatarTrent Piepho <xyzzy@speakeasy.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent bddcf541
...@@ -587,7 +587,7 @@ ...@@ -587,7 +587,7 @@
#define SPI_DACD0_BIT 1 #define SPI_DACD0_BIT 1
#define SPI_DACD1_BIT 2 #define SPI_DACD1_BIT 2
#define SPI_DACD2_BIT 3 #define SPI_DACD2_BIT 3
#define SPI_DACD4_BIT 1 #define SPI_DACD4_BIT 0 /* datasheet error says it's 1 */
#define SPI_PWRDNALL_REG 10 /* power down everything */ #define SPI_PWRDNALL_REG 10 /* power down everything */
#define SPI_PWRDNALL_BIT 4 #define SPI_PWRDNALL_BIT 4
......
/* /*
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
* Version: 0.0.24 * Version: 0.0.25
* *
* FEATURES currently supported: * FEATURES currently supported:
* Front, Rear and Center/LFE. * Front, Rear and Center/LFE.
...@@ -81,6 +81,8 @@ ...@@ -81,6 +81,8 @@
* Implement support for Line-in capture on SB Live 24bit. * Implement support for Line-in capture on SB Live 24bit.
* 0.0.24 * 0.0.24
* Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
* 0.0.25
* Powerdown SPI DAC channels when not in use
* *
* BUGS: * BUGS:
* Some stability problems when unloading the snd-ca0106 kernel module. * 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,6 +460,19 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
kfree(runtime->private_data); kfree(runtime->private_data);
} }
static const int spi_dacd_reg[] = {
[PCM_FRONT_CHANNEL] = SPI_DACD4_REG,
[PCM_REAR_CHANNEL] = SPI_DACD0_REG,
[PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG,
[PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG,
};
static const int spi_dacd_bit[] = {
[PCM_FRONT_CHANNEL] = 1<<SPI_DACD4_BIT,
[PCM_REAR_CHANNEL] = 1<<SPI_DACD0_BIT,
[PCM_CENTER_LFE_CHANNEL]= 1<<SPI_DACD2_BIT,
[PCM_UNKNOWN_CHANNEL] = 1<<SPI_DACD1_BIT,
};
/* open_playback callback */ /* open_playback callback */
static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
int channel_id) int channel_id)
...@@ -492,6 +507,16 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr ...@@ -492,6 +507,16 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
return err; return err;
if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
return err; return err;
if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) {
const int reg = spi_dacd_reg[channel_id];
/* Power up dac */
chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
if (err < 0)
return err;
}
return 0; return 0;
} }
...@@ -502,6 +527,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream) ...@@ -502,6 +527,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ca0106_pcm *epcm = runtime->private_data; struct snd_ca0106_pcm *epcm = runtime->private_data;
chip->playback_channels[epcm->channel_id].use = 0; chip->playback_channels[epcm->channel_id].use = 0;
if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
const int reg = spi_dacd_reg[epcm->channel_id];
/* Power down DAC */
chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id];
snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
}
/* FIXME: maybe zero others */ /* FIXME: maybe zero others */
return 0; return 0;
} }
...@@ -1246,7 +1279,7 @@ static unsigned int spi_dac_init[] = { ...@@ -1246,7 +1279,7 @@ static unsigned int spi_dac_init[] = {
0x0530, 0x0530,
0x0602, 0x0602,
0x0622, 0x0622,
0x1400, 0x140e,
}; };
static unsigned int i2c_adc_init[][2] = { static unsigned int i2c_adc_init[][2] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment