[alsa-devel] [PATCH 0/4] ASoC: TWL4030: Gain control updates, adding pre-DAC routing controls
Hello,
This series adds 'proper' gain controls for: Per-DAC common gain controls. There are three gain controls asspciated wit a DAC in TWL, There are four DAC can be used (in OPT_MODE=1). Digital fine gain, Digital coarse gain, Analog gain.
Every output, except the HandsFree has their own gain controls per channel (L/R)
Pre-DAC routings: Digital input namings: SDRL1: TDM #1 SDRR1: TDM #2 SDRL2: TDM #3, I2S Left SDRR2: TDM #4, I2S Right
Mono mixing: SDRM1: mixed SDRL1 and SDRR1 SDRM2: mixed SDRL2 and SDRR2
The possible mux settings for the DAC inputs: DACL1 <- SDRL1, SDRM1, SDRM2, SDRL2 DACR1 <- SDRR1, SDRM1, SDRM2, SDRR2 DACL2 <- SDRL2, SDRM2 DACR2 <- SDRR2, SDRM2
--- Peter Ujfalusi (4): ASoC: TWL4030: Change the capture volume control to TLV ASoC: TWL4030: Change the common playback volume controls ASoC: TWL4030: Add volume controls for outputs ASoC: TWL4030: Add pre-DAC digital mux controls
sound/soc/codecs/twl4030.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 59 insertions(+), 0 deletions(-)
The digital Capture gain control has a range: 0 to 31 dB in 1 dB steps.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 4136231..ffc9401 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -360,6 +360,12 @@ static DECLARE_TLV_DB_SCALE(master_tlv, -6300, 100, 1); */ static DECLARE_TLV_DB_SCALE(master_coarse_tlv, 0, 600, 0);
+/* + * Capture gain after the ADCs + * from 0 dB to 31 dB in 1 dB steps + */ +static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0); + static const struct snd_kcontrol_new twl4030_snd_controls[] = { SOC_DOUBLE_R_TLV("Master Playback Volume", TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, @@ -367,9 +373,11 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { SOC_DOUBLE_R_TLV("Master PCM Playback Volume", TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, 6, 0x2, 0, master_coarse_tlv), - SOC_DOUBLE_R("Capture Volume", - TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA, - 0, 0x1f, 0), + + /* Common capture gain controls */ + SOC_DOUBLE_R_TLV("Capture Volume", + TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA, + 0, 0x1f, 0, digital_capture_tlv), };
/* add non dapm controls */
Add Playback volume controls for all four DACs. All four paths has three levels of volume controls: Digital Fine gain, Digital Coarse gain, Analog gain.
The controls are named to reflect their connection to the DACs. Per DAC volume can be performed, if needed: amixer sset 'DAC1 Analog' 5,10 DACL1 analog gain to 5 DACR1 analog gain to 10
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 37 +++++++++++++++++++++++++++++-------- 1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index ffc9401..849ad4b 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -351,14 +351,20 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, * FGAIN volume control: * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB) */ -static DECLARE_TLV_DB_SCALE(master_tlv, -6300, 100, 1); +static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
/* * CGAIN volume control: * 0 dB to 12 dB in 6 dB steps * value 2 and 3 means 12 dB */ -static DECLARE_TLV_DB_SCALE(master_coarse_tlv, 0, 600, 0); +static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0); + +/* + * Analog playback gain + * -24 dB to 12 dB in 2 dB steps + */ +static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
/* * Capture gain after the ADCs @@ -367,12 +373,27 @@ static DECLARE_TLV_DB_SCALE(master_coarse_tlv, 0, 600, 0); static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
static const struct snd_kcontrol_new twl4030_snd_controls[] = { - SOC_DOUBLE_R_TLV("Master Playback Volume", - TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, - 0, 0x3f, 0, master_tlv), - SOC_DOUBLE_R_TLV("Master PCM Playback Volume", - TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, - 6, 0x2, 0, master_coarse_tlv), + /* Common playback gain controls */ + SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", + TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA, + 0, 0x3f, 0, digital_fine_tlv), + SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume", + TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, + 0, 0x3f, 0, digital_fine_tlv), + + SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume", + TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA, + 6, 0x2, 0, digital_coarse_tlv), + SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume", + TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, + 6, 0x2, 0, digital_coarse_tlv), + + SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume", + TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL, + 3, 0x12, 1, analog_tlv), + SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume", + TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, + 3, 0x12, 1, analog_tlv),
/* Common capture gain controls */ SOC_DOUBLE_R_TLV("Capture Volume",
All outputs have dedicated gain controls except the HandsFree output.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 849ad4b..bd236b2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -367,6 +367,12 @@ static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0); static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
/* + * Gain controls tied to outputs + * -6 dB to 6 dB in 6 dB steps (mute instead of -12) + */ +static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1); + +/* * Capture gain after the ADCs * from 0 dB to 31 dB in 1 dB steps */ @@ -395,6 +401,21 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, 3, 0x12, 1, analog_tlv),
+ /* Separate output gain controls */ + SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", + TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, + 4, 3, 0, output_tvl), + + SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume", + TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl), + + SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume", + TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, + 4, 3, 0, output_tvl), + + SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume", + TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl), + /* Common capture gain controls */ SOC_DOUBLE_R_TLV("Capture Volume", TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
Controls for selecting the digital inputs for the four DAC. Digital input namings: SDRL1: TDM #1 SDRR1: TDM #2 SDRL2: TDM #3, I2S Left SDRR2: TDM #4, I2S Right
Mono mixing: SDRM1: mixed SDRL1 and SDRR1 SDRM2: mixed SDRL2 and SDRR2
The possible mux settings for the DAC inputs: DACL1 <- SDRL1, SDRM1, SDRM2, SDRL2 DACR1 <- SDRR1, SDRM1, SDRM2, SDRR2 DACL2 <- SDRL2, SDRM2 DACR2 <- SDRR2, SDRM2
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index bd236b2..fd9d47e 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -190,6 +190,38 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
}
+static const char *twl4030_predacl1_texts[] = + {"SDRL1", "SDRM1", "SRDL2", "SDRM2"}; + +static const char *twl4030_predacr1_texts[] = + {"SDRR1", "SDRM1", "SRDR2", "SDRM2"}; + +static const char *twl4030_predacl2_texts[] = + {"SDRL2", "SDRM2"}; + +static const char *twl4030_predacr2_texts[] = + {"SDRR2", "SDRM2"}; + +static const struct soc_enum twl4030_predacl1_enum = + SOC_ENUM_SINGLE(TWL4030_REG_RX_PATH_SEL, 2, + ARRAY_SIZE(twl4030_predacl1_texts), + twl4030_predacl1_texts); + +static const struct soc_enum twl4030_predacr1_enum = + SOC_ENUM_SINGLE(TWL4030_REG_RX_PATH_SEL, 0, + ARRAY_SIZE(twl4030_predacr1_texts), + twl4030_predacr1_texts); + +static const struct soc_enum twl4030_predacl2_enum = + SOC_ENUM_SINGLE(TWL4030_REG_RX_PATH_SEL, 5, + ARRAY_SIZE(twl4030_predacl2_texts), + twl4030_predacl2_texts); + +static const struct soc_enum twl4030_predacr2_enum = + SOC_ENUM_SINGLE(TWL4030_REG_RX_PATH_SEL, 4, + ARRAY_SIZE(twl4030_predacr2_texts), + twl4030_predacr2_texts); + /* * Some of the gain controls in TWL (mostly those which are associated with * the outputs) are implemented in an interesting way: @@ -420,6 +452,12 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { SOC_DOUBLE_R_TLV("Capture Volume", TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA, 0, 0x1f, 0, digital_capture_tlv), + + /* Mux controls before the DACs */ + SOC_ENUM("DACL1 Playback Mux", twl4030_predacl1_enum), + SOC_ENUM("DACR1 Playback Mux", twl4030_predacr1_enum), + SOC_ENUM("DACL2 Playback Mux", twl4030_predacl2_enum), + SOC_ENUM("DACR2 Playback Mux", twl4030_predacr2_enum), };
/* add non dapm controls */
On Mon, Dec 01, 2008 at 10:03:48AM +0200, Peter Ujfalusi wrote:
Controls for selecting the digital inputs for the four DAC.
How often is this feature used at the minute? While I've got no problem with the code per se there's currently no framework in ASoC for handling digital routing which means that having the flexibility creates problems with DAPM (which isn't implemented yet for this codec). There's no real issue merging it, but it might make life easier to leave it for now.
Implementing digial routing support is on my radar but it's firmly below the V2 merge.
Hello Mark,
On Monday 01 December 2008 13:43:48 ext Mark Brown wrote:
On Mon, Dec 01, 2008 at 10:03:48AM +0200, Peter Ujfalusi wrote:
Controls for selecting the digital inputs for the four DAC.
How often is this feature used at the minute? While I've got no problem with the code per se there's currently no framework in ASoC for handling digital routing which means that having the flexibility creates problems with DAPM (which isn't implemented yet for this codec). There's no real issue merging it, but it might make life easier to leave it for now.
Well, I'm not sure how often this can be used. I was reading the wm* codec drivers as you suggested a while ago. Those also implement the digital routing outside of DAPM. So I thought why not. Most of the times these routings are static, so one can set these from the actual board file, it is kind of hackish, but could do it: codec->write(codec, TWL4030_REG_RX_PATH_SEL, _something_); I don't see to much harm on having it as runtime configurable. As I said I think it is good to have 'full control' over things.
About the DAPM things: Now I'm in the process of adding the DAPM mappings for TWL (the Earpiece out now works with DAPM). Altrough there are some obstacles on the road, but slowly and steadily I'm getting there.
One more thing: I have asked around the availability of technical documentation for TWL. My copy has the big sign: Sigend NDA is required for Distribution... But, the TPS65950 (also from TI) has the very same audio block as the TWL and the TRM is publically available here: http://focus.ti.com/docs/prod/folders/print/tps65950.html
Implementing digial routing support is on my radar but it's firmly below the V2 merge.
You obviously know about ASoCv2... Do you have some pointers on what is coming and when?
On Mon, Dec 01, 2008 at 02:09:40PM +0200, Peter Ujfalusi wrote:
Well, I'm not sure how often this can be used. I was reading the wm* codec drivers as you suggested a while ago. Those also implement the digital routing outside of DAPM. So I thought why not.
Right, this is one reason I know it can cause issues. For the Wolfson codecs it's mostly sidetone paths that are implemented which tends to work OK since it's relatively rare to want to run a digital sidetone without also doing a record and playback. It's when you start implementing DAC source and ADC output selection that things can get tricky - DAPM needs to have a method for figuring out which DACs and ADCs to power up and currently that's done by hard coding.
Most of the times these routings are static, so one can set these from the actual board file, it is kind of hackish, but could do it: codec->write(codec, TWL4030_REG_RX_PATH_SEL, _something_); I don't see to much harm on having it as runtime configurable. As I said I think it is good to have 'full control' over things.
There are definitely use cases for having the control, it's just the problem with working out what's actually active that means it's safer to let people make local modifications to the driver for now. Having parts of the chip you're trying to use fail to power on doesn't tend to work so well.
Implementing digial routing support is on my radar but it's firmly below the V2 merge.
You obviously know about ASoCv2... Do you have some pointers on what is coming and when?
The main outstanding bit is the ability to probe machine, codec and platform drivers independently. The asoc-v2-dev branch of git://opensource.wolfsonmicro.com/linux-2.6-asoc has the model for where we're heading, but there are likely to be some differences due to merge and review. The for-tiwai branch will have whatever backports have not yet been submitted to Takashi.
BTW, there seems to be some problem with your mail client - many of your lines are over 80 characters, making it hard to read your mails. It looks awfully like it's wrapping at ~90 characters or something;
Hello,
On Monday 01 December 2008 14:46:06 ext Mark Brown wrote:
On Mon, Dec 01, 2008 at 02:09:40PM +0200, Peter Ujfalusi wrote:
Well, I'm not sure how often this can be used. I was reading the wm* codec drivers as you suggested a while ago. Those also implement the digital routing outside of DAPM. So I thought why not.
Right, this is one reason I know it can cause issues. For the Wolfson codecs it's mostly sidetone paths that are implemented which tends to work OK since it's relatively rare to want to run a digital sidetone without also doing a record and playback. It's when you start implementing DAC source and ADC output selection that things can get tricky - DAPM needs to have a method for figuring out which DACs and ADCs to power up and currently that's done by hard coding.
In respect of PM, there is no power control before the DACs in TWL. A simple chain looks like this (I2S stereo playback to HeadSet): For the left channel:
SDRL2 -> MUX (Left/Mono) -> Digital PGA -> DACL2 -> APGA -> HSOL MUX: SDRL2 or SDRM2, no power control Digital PGA: FGAIN, CGAIN, no power control DACL2: On/Off APGA: Power, Analog Gain HSOL: MUX, Gain
What I'm trying to do with the DAPM at the moment: Have the MUX settings tied to the outputs. Based on the selected input (to the output), connect it to the correct APGA with power switch. APGA connects to the corresponding DAC with power switch. It Should be fine. Probably I need to introduce some 'ghost APGA outputs' in order to really control the APGA power switch, but this is just a small detail...
Most of the times these routings are static, so one can set these from the actual board file, it is kind of hackish, but could do it: codec->write(codec, TWL4030_REG_RX_PATH_SEL, _something_); I don't see to much harm on having it as runtime configurable. As I said I think it is good to have 'full control' over things.
There are definitely use cases for having the control, it's just the problem with working out what's actually active that means it's safer to let people make local modifications to the driver for now. Having parts of the chip you're trying to use fail to power on doesn't tend to work so well.
Ok, I agree. If someone needs to modify the routing, than it can be done in the board/platform file.
Implementing digial routing support is on my radar but it's firmly below the V2 merge.
You obviously know about ASoCv2... Do you have some pointers on what is coming and when?
The main outstanding bit is the ability to probe machine, codec and platform drivers independently. The asoc-v2-dev branch of git://opensource.wolfsonmicro.com/linux-2.6-asoc has the model for where we're heading, but there are likely to be some differences due to merge and review. The for-tiwai branch will have whatever backports have not yet been submitted to Takashi.
Thanks, I'll take a look there! How it will affect the existing codec drivers?
BTW, there seems to be some problem with your mail client - many of your lines are over 80 characters, making it hard to read your mails. It looks awfully like it's wrapping at ~90 characters or something;
Hmm, sorry about it. Using kmail... Should be fine now (set to wrap at 78 characters)
On Mon, Dec 01, 2008 at 03:25:12PM +0200, Peter Ujfalusi wrote:
In respect of PM, there is no power control before the DACs in TWL. A simple chain looks like this (I2S stereo playback to HeadSet):
It's not just the DACs themselves, it's everything after the DACs too. If DAPM thinks a DAC is powered off it won't power anything that has inputs connected only to that DAC up.
What I'm trying to do with the DAPM at the moment: Have the MUX settings tied to the outputs. Based on the selected input (to the output), connect it to the correct APGA with power switch. APGA connects to the corresponding DAC with power switch.
In general you should only have user-visible switches for things that are conditionally connected. If the APGA can only source input from a single DAC then let DAPM figure out if it needs to be turned on based on the inputs and outputs. This is often important for amplifiers which may pass signals through unexpectedly when powered down.
How it will affect the existing codec drivers?
The changes are all on the device registration side so for the stuff you're doing there should be no substantial effect - the other parts have already been merged.
Hello,
On Monday 01 December 2008 13:43:48 ext Mark Brown wrote:
On Mon, Dec 01, 2008 at 10:03:48AM +0200, Peter Ujfalusi wrote:
Controls for selecting the digital inputs for the four DAC.
How often is this feature used at the minute? While I've got no problem with the code per se there's currently no framework in ASoC for handling digital routing which means that having the flexibility creates problems with DAPM (which isn't implemented yet for this codec). There's no real issue merging it, but it might make life easier to leave it for now.
One thing came to my mind for the use of this: In theory, if the TWL is running in TDM (4 channel audio mode), your board file sets the initial routing for all four channel. But at some point you want to route mono audio to the earpiece out from the SDRL2 and SDRR2, leaving the SDRL1 and SDRR1 routings same... Or something like this. I'm not a good 'let's define some good use case scenario' type of guy...
Implementing digial routing support is on my radar but it's firmly below the V2 merge.
On Mon, Dec 01, 2008 at 10:03:47AM +0200, Peter Ujfalusi wrote:
All outputs have dedicated gain controls except the HandsFree output.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com
Applied, thanks.
On Mon, Dec 01, 2008 at 10:03:46AM +0200, Peter Ujfalusi wrote:
Add Playback volume controls for all four DACs. All four paths has three levels of volume controls: Digital Fine gain, Digital Coarse gain, Analog gain.
Applied, thanks.
On Mon, Dec 01, 2008 at 10:03:45AM +0200, Peter Ujfalusi wrote:
The digital Capture gain control has a range: 0 to 31 dB in 1 dB steps.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com
Applied, thanks.
participants (2)
-
Mark Brown
-
Peter Ujfalusi