[alsa-devel] [PATCH v2 00/10] ASoC: twl6040: Cleanups and fixes
Hello,
Changes since v1 [1]: - Left out patches already applied by Mark - Description on patch 01 changed to describe more precisely the need to lower the chip default gains after power on. - Extended the commit message for patch 02 to explain the change. - Added Acked-by from Liam to the patches.
Short summary for v2 series: Code cleanup, and fixes for the twl6040 codec driver. Main changes: - codec initialization changes - Correction for the Earphone path - AUX L/R output support - Headset/Handsfree control name changes - Headset DC offset workaround
The series has been created on top of: git://opensource.wolfsonmicro.com/linux-2.6-asoc for-3.2 branch + OMAP McPDM changes [2]
[1] first series: http://mailman.alsa-project.org/pipermail/alsa-devel/2011-September/043847.h...
[2] OMAP McPDM changes: http://mailman.alsa-project.org/pipermail/alsa-devel/2011-September/044172.h...
Regards, Peter --- Peter Ujfalusi (10): ASoC: twl6040: Lower the power on gain values at startup ASoC: twl6040: Fix comments for register names ASoC: twl6040: Remove strings "NULL" from DAPM route ASoC: twl6040: Introduce SW only shadow register ASoC: twl6040: Earphone path correction ASoC: twl6040: Use consistent names for Handsfree path ASoC: twl6040: Use consistent names for Headset path ASoC: twl6040: Support for AUX L/R output ASoC: twl6040/sdp4430: Change legacy DAI name ASoC/MFD: twl6040: Combine bit definitions for Headset control registers
include/linux/mfd/twl6040.h | 13 +-- sound/soc/codecs/twl6040.c | 223 ++++++++++++++++++++++++++----------------- sound/soc/omap/sdp4430.c | 2 +- 3 files changed, 140 insertions(+), 98 deletions(-)
The default gains on outputs/inputs are set to 0dB. This is fixing the pop noise issue at the first playback, which caused by the wrong starting point of the ramp code. The ramp code for the outputs expects the gains to be in their lowest configuration in order to be effective. After the playback stops, the ramp code takes care of ramping down the gains to their minimum.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 81645c6..0694d65 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -269,6 +269,17 @@ static void twl6040_init_chip(struct snd_soc_codec *codec) /* No imput selected for microphone amplifiers */ twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18); twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18); + + /* + * We need to lower the default gain values, so the ramp code + * can work correctly for the first playback. + * This reduces the pop noise heard at the first playback. + */ + twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff); + twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e); + twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d); + twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d); + twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0); }
static void twl6040_restore_regs(struct snd_soc_codec *codec)
Change the register name strings in the comments for the twl6040_reg table, so it is easier to search for specific register.
This is cosmetic change.
Before we had for example: TWL6040_REG_HSLCTL as register definition.
At the register table we had: TWL6040_HSLCTL
Searching for TWL6040_HSLCTL resulted no hits.
While if we look for REG_HSLCTL, we can find the places the register has been used.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 94 ++++++++++++++++++++++---------------------- 1 files changed, 47 insertions(+), 47 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 0694d65..6f6b180 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -106,53 +106,53 @@ struct twl6040_data { * twl6040 register cache & default register settings */ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { - 0x00, /* not used 0x00 */ - 0x4B, /* TWL6040_ASICID (ro) 0x01 */ - 0x00, /* TWL6040_ASICREV (ro) 0x02 */ - 0x00, /* TWL6040_INTID 0x03 */ - 0x00, /* TWL6040_INTMR 0x04 */ - 0x00, /* TWL6040_NCPCTRL 0x05 */ - 0x00, /* TWL6040_LDOCTL 0x06 */ - 0x60, /* TWL6040_HPPLLCTL 0x07 */ - 0x00, /* TWL6040_LPPLLCTL 0x08 */ - 0x4A, /* TWL6040_LPPLLDIV 0x09 */ - 0x00, /* TWL6040_AMICBCTL 0x0A */ - 0x00, /* TWL6040_DMICBCTL 0x0B */ - 0x00, /* TWL6040_MICLCTL 0x0C */ - 0x00, /* TWL6040_MICRCTL 0x0D */ - 0x00, /* TWL6040_MICGAIN 0x0E */ - 0x1B, /* TWL6040_LINEGAIN 0x0F */ - 0x00, /* TWL6040_HSLCTL 0x10 */ - 0x00, /* TWL6040_HSRCTL 0x11 */ - 0x00, /* TWL6040_HSGAIN 0x12 */ - 0x00, /* TWL6040_EARCTL 0x13 */ - 0x00, /* TWL6040_HFLCTL 0x14 */ - 0x00, /* TWL6040_HFLGAIN 0x15 */ - 0x00, /* TWL6040_HFRCTL 0x16 */ - 0x00, /* TWL6040_HFRGAIN 0x17 */ - 0x00, /* TWL6040_VIBCTLL 0x18 */ - 0x00, /* TWL6040_VIBDATL 0x19 */ - 0x00, /* TWL6040_VIBCTLR 0x1A */ - 0x00, /* TWL6040_VIBDATR 0x1B */ - 0x00, /* TWL6040_HKCTL1 0x1C */ - 0x00, /* TWL6040_HKCTL2 0x1D */ - 0x00, /* TWL6040_GPOCTL 0x1E */ - 0x00, /* TWL6040_ALB 0x1F */ - 0x00, /* TWL6040_DLB 0x20 */ - 0x00, /* not used 0x21 */ - 0x00, /* not used 0x22 */ - 0x00, /* not used 0x23 */ - 0x00, /* not used 0x24 */ - 0x00, /* not used 0x25 */ - 0x00, /* not used 0x26 */ - 0x00, /* not used 0x27 */ - 0x00, /* TWL6040_TRIM1 0x28 */ - 0x00, /* TWL6040_TRIM2 0x29 */ - 0x00, /* TWL6040_TRIM3 0x2A */ - 0x00, /* TWL6040_HSOTRIM 0x2B */ - 0x00, /* TWL6040_HFOTRIM 0x2C */ - 0x09, /* TWL6040_ACCCTL 0x2D */ - 0x00, /* TWL6040_STATUS (ro) 0x2E */ + 0x00, /* not used 0x00 */ + 0x4B, /* REG_ASICID 0x01 (ro) */ + 0x00, /* REG_ASICREV 0x02 (ro) */ + 0x00, /* REG_INTID 0x03 */ + 0x00, /* REG_INTMR 0x04 */ + 0x00, /* REG_NCPCTRL 0x05 */ + 0x00, /* REG_LDOCTL 0x06 */ + 0x60, /* REG_HPPLLCTL 0x07 */ + 0x00, /* REG_LPPLLCTL 0x08 */ + 0x4A, /* REG_LPPLLDIV 0x09 */ + 0x00, /* REG_AMICBCTL 0x0A */ + 0x00, /* REG_DMICBCTL 0x0B */ + 0x00, /* REG_MICLCTL 0x0C */ + 0x00, /* REG_MICRCTL 0x0D */ + 0x00, /* REG_MICGAIN 0x0E */ + 0x1B, /* REG_LINEGAIN 0x0F */ + 0x00, /* REG_HSLCTL 0x10 */ + 0x00, /* REG_HSRCTL 0x11 */ + 0x00, /* REG_HSGAIN 0x12 */ + 0x00, /* REG_EARCTL 0x13 */ + 0x00, /* REG_HFLCTL 0x14 */ + 0x00, /* REG_HFLGAIN 0x15 */ + 0x00, /* REG_HFRCTL 0x16 */ + 0x00, /* REG_HFRGAIN 0x17 */ + 0x00, /* REG_VIBCTLL 0x18 */ + 0x00, /* REG_VIBDATL 0x19 */ + 0x00, /* REG_VIBCTLR 0x1A */ + 0x00, /* REG_VIBDATR 0x1B */ + 0x00, /* REG_HKCTL1 0x1C */ + 0x00, /* REG_HKCTL2 0x1D */ + 0x00, /* REG_GPOCTL 0x1E */ + 0x00, /* REG_ALB 0x1F */ + 0x00, /* REG_DLB 0x20 */ + 0x00, /* not used 0x21 */ + 0x00, /* not used 0x22 */ + 0x00, /* not used 0x23 */ + 0x00, /* not used 0x24 */ + 0x00, /* not used 0x25 */ + 0x00, /* not used 0x26 */ + 0x00, /* not used 0x27 */ + 0x00, /* REG_TRIM1 0x28 */ + 0x00, /* REG_TRIM2 0x29 */ + 0x00, /* REG_TRIM3 0x2A */ + 0x00, /* REG_HSOTRIM 0x2B */ + 0x00, /* REG_HFOTRIM 0x2C */ + 0x09, /* REG_ACCCTL 0x2D */ + 0x00, /* REG_STATUS 0x2E (ro) */ };
/* List of registers to be restored after power up */
Replace the string with plain NULL.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 6f6b180..9fbfe0e 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1199,8 +1199,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"ADC Right", NULL, "MicAmpR"},
/* AFM path */ - {"AFMAmpL", "NULL", "AFML"}, - {"AFMAmpR", "NULL", "AFMR"}, + {"AFMAmpL", NULL, "AFML"}, + {"AFMAmpR", NULL, "AFMR"},
{"HS Left Playback", "HS DAC", "HSDAC Left"}, {"HS Left Playback", "Line-In amp", "AFMAmpL"}, @@ -1208,8 +1208,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HS Right Playback", "HS DAC", "HSDAC Right"}, {"HS Right Playback", "Line-In amp", "AFMAmpR"},
- {"Headset Left Driver", "NULL", "HS Left Playback"}, - {"Headset Right Driver", "NULL", "HS Right Playback"}, + {"Headset Left Driver", NULL, "HS Left Playback"}, + {"Headset Right Driver", NULL, "HS Right Playback"},
{"HSOL", NULL, "Headset Left Driver"}, {"HSOR", NULL, "Headset Right Driver"},
Software only shadow register to be used by the driver. For example Earpiece path will need this shadow register.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- include/linux/mfd/twl6040.h | 2 -- sound/soc/codecs/twl6040.c | 19 ++++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index ec1ec79..47470ca 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -68,8 +68,6 @@ #define TWL6040_REG_ACCCTL 0x2D #define TWL6040_REG_STATUS 0x2E
-#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1) - /* INTID (0x03) fields */
#define TWL6040_THINT 0x01 diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 9fbfe0e..9635466 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -57,6 +57,10 @@ #define TWL6040_HF_VOL_MASK 0x1F #define TWL6040_HF_VOL_SHIFT 0
+/* Shadow register used by the driver */ +#define TWL6040_REG_SW_SHADOW 0x2F +#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1) + struct twl6040_output { u16 active; u16 left_vol; @@ -153,6 +157,8 @@ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { 0x00, /* REG_HFOTRIM 0x2C */ 0x09, /* REG_ACCCTL 0x2D */ 0x00, /* REG_STATUS 0x2E (ro) */ + + 0x00, /* REG_SW_SHADOW 0x2F - Shadow, non HW register */ };
/* List of registers to be restored after power up */ @@ -236,8 +242,12 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, if (reg >= TWL6040_CACHEREGNUM) return -EIO;
- value = twl6040_reg_read(twl6040, reg); - twl6040_write_reg_cache(codec, reg, value); + if (likely(reg < TWL6040_REG_SW_SHADOW)) { + value = twl6040_reg_read(twl6040, reg); + twl6040_write_reg_cache(codec, reg, value); + } else { + value = twl6040_read_reg_cache(codec, reg); + }
return value; } @@ -254,7 +264,10 @@ static int twl6040_write(struct snd_soc_codec *codec, return -EIO;
twl6040_write_reg_cache(codec, reg, value); - return twl6040_reg_write(twl6040, reg, value); + if (likely(reg < TWL6040_REG_SW_SHADOW)) + return twl6040_reg_write(twl6040, reg, value); + else + return 0; }
static void twl6040_init_chip(struct snd_soc_codec *codec)
Fix the DAPM routing for the earphone path. Convert the DAPM_SWITCH_E to DAPM_OUT_DRV_E, so we can have correct power up, and down sequence for EP. Introduce mute control (Earphone Playback Switch) for users to enable/disable the EP path. Note: the EP does not have it's own dedicated DAC. EP is connected to HSL DAC.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 9635466..3450b11 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -61,6 +61,9 @@ #define TWL6040_REG_SW_SHADOW 0x2F #define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
+/* TWL6040_REG_SW_SHADOW (0x2F) fields */ +#define TWL6040_EAR_PATH_ENABLE 0x01 + struct twl6040_output { u16 active; u16 left_vol; @@ -991,8 +994,8 @@ static const struct snd_kcontrol_new hfl_mux_controls = static const struct snd_kcontrol_new hfr_mux_controls = SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
-static const struct snd_kcontrol_new ep_driver_switch_controls = - SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); +static const struct snd_kcontrol_new ep_path_enable_control = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0);
/* Headset power mode */ static const char *twl6040_power_mode_texts[] = { @@ -1165,6 +1168,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_MUX("HS Right Playback", SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
+ SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, + &ep_path_enable_control), + /* Analog playback drivers */ SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", TWL6040_REG_HFLCTL, 4, 0, NULL, 0, @@ -1182,8 +1188,8 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { TWL6040_REG_HSRCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_SWITCH_E("Earphone Driver", - SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, + SND_SOC_DAPM_OUT_DRV_E("Earphone Driver", + TWL6040_REG_EARCTL, 0, 0, NULL, 0, twl6040_power_mode_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -1228,7 +1234,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HSOR", NULL, "Headset Right Driver"},
/* Earphone playback path */ - {"Earphone Driver", "Switch", "HSDAC Left"}, + {"Earphone Playback", "Switch", "HSDAC Left"}, + {"Earphone Driver", NULL, "Earphone Playback"}, {"EP", NULL, "Earphone Driver"},
{"HF Left Playback", "HF DAC", "HFDAC Left"},
Use "Handsfree XYZ" for user visible controls, while the internal DAPM widgets can use "HF XYZ". In this way we can group the Handsfree related controls in UI (alsamixer for example).
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 32 ++++++++++++++++---------------- 1 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 3450b11..10f292d 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1158,9 +1158,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { twl6040_power_mode_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MUX("HF Left Playback", + SND_SOC_DAPM_MUX("Handsfree Left Playback", SND_SOC_NOPM, 0, 0, &hfl_mux_controls), - SND_SOC_DAPM_MUX("HF Right Playback", + SND_SOC_DAPM_MUX("Handsfree Right Playback", SND_SOC_NOPM, 0, 0, &hfr_mux_controls), /* Analog playback Muxes */ SND_SOC_DAPM_MUX("HS Left Playback", @@ -1172,11 +1172,11 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { &ep_path_enable_control),
/* Analog playback drivers */ - SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", + SND_SOC_DAPM_OUT_DRV_E("HF Left Driver", TWL6040_REG_HFLCTL, 4, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", + SND_SOC_DAPM_OUT_DRV_E("HF Right Driver", TWL6040_REG_HFRCTL, 4, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1194,9 +1194,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* Analog playback PGAs */ - SND_SOC_DAPM_PGA("HFDAC Left PGA", + SND_SOC_DAPM_PGA("HF Left PGA", TWL6040_REG_HFLCTL, 1, 0, NULL, 0), - SND_SOC_DAPM_PGA("HFDAC Right PGA", + SND_SOC_DAPM_PGA("HF Right PGA", TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
}; @@ -1238,20 +1238,20 @@ static const struct snd_soc_dapm_route intercon[] = { {"Earphone Driver", NULL, "Earphone Playback"}, {"EP", NULL, "Earphone Driver"},
- {"HF Left Playback", "HF DAC", "HFDAC Left"}, - {"HF Left Playback", "Line-In amp", "AFMAmpL"}, + {"Handsfree Left Playback", "HF DAC", "HFDAC Left"}, + {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"},
- {"HF Right Playback", "HF DAC", "HFDAC Right"}, - {"HF Right Playback", "Line-In amp", "AFMAmpR"}, + {"Handsfree Right Playback", "HF DAC", "HFDAC Right"}, + {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"},
- {"HFDAC Left PGA", NULL, "HF Left Playback"}, - {"HFDAC Right PGA", NULL, "HF Right Playback"}, + {"HF Left PGA", NULL, "Handsfree Left Playback"}, + {"HF Right PGA", NULL, "Handsfree Right Playback"},
- {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, - {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, + {"HF Left Driver", NULL, "HF Left PGA"}, + {"HF Right Driver", NULL, "HF Right PGA"},
- {"HFL", NULL, "Handsfree Left Driver"}, - {"HFR", NULL, "Handsfree Right Driver"}, + {"HFL", NULL, "HF Left Driver"}, + {"HFR", NULL, "HF Right Driver"}, };
static int twl6040_add_widgets(struct snd_soc_codec *codec)
Use "Headset XYZ" for user visible controls, while the internal DAPM widgets can use "HS XYZ". In this way we can group the Headset related controls in UI (alsamixer for example).
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 24 ++++++++++++------------ 1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 10f292d..fffd7ff 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1163,9 +1163,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_MUX("Handsfree Right Playback", SND_SOC_NOPM, 0, 0, &hfr_mux_controls), /* Analog playback Muxes */ - SND_SOC_DAPM_MUX("HS Left Playback", + SND_SOC_DAPM_MUX("Headset Left Playback", SND_SOC_NOPM, 0, 0, &hsl_mux_controls), - SND_SOC_DAPM_MUX("HS Right Playback", + SND_SOC_DAPM_MUX("Headset Right Playback", SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, @@ -1180,11 +1180,11 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { TWL6040_REG_HFRCTL, 4, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", + SND_SOC_DAPM_OUT_DRV_E("HS Left Driver", TWL6040_REG_HSLCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", + SND_SOC_DAPM_OUT_DRV_E("HS Right Driver", TWL6040_REG_HSRCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1221,17 +1221,17 @@ static const struct snd_soc_dapm_route intercon[] = { {"AFMAmpL", NULL, "AFML"}, {"AFMAmpR", NULL, "AFMR"},
- {"HS Left Playback", "HS DAC", "HSDAC Left"}, - {"HS Left Playback", "Line-In amp", "AFMAmpL"}, + {"Headset Left Playback", "HS DAC", "HSDAC Left"}, + {"Headset Left Playback", "Line-In amp", "AFMAmpL"},
- {"HS Right Playback", "HS DAC", "HSDAC Right"}, - {"HS Right Playback", "Line-In amp", "AFMAmpR"}, + {"Headset Right Playback", "HS DAC", "HSDAC Right"}, + {"Headset Right Playback", "Line-In amp", "AFMAmpR"},
- {"Headset Left Driver", NULL, "HS Left Playback"}, - {"Headset Right Driver", NULL, "HS Right Playback"}, + {"HS Left Driver", NULL, "Headset Left Playback"}, + {"HS Right Driver", NULL, "Headset Right Playback"},
- {"HSOL", NULL, "Headset Left Driver"}, - {"HSOR", NULL, "Headset Right Driver"}, + {"HSOL", NULL, "HS Left Driver"}, + {"HSOR", NULL, "HS Right Driver"},
/* Earphone playback path */ {"Earphone Playback", "Switch", "HSDAC Left"},
AUX L/R outputs can be driver from the Handsfree PGA output.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index fffd7ff..3908b88 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -997,6 +997,12 @@ static const struct snd_kcontrol_new hfr_mux_controls = static const struct snd_kcontrol_new ep_path_enable_control = SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0);
+static const struct snd_kcontrol_new auxl_switch_control = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0); + +static const struct snd_kcontrol_new auxr_switch_control = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0); + /* Headset power mode */ static const char *twl6040_power_mode_texts[] = { "Low-Power", "High-Perfomance", @@ -1105,6 +1111,8 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HFL"), SND_SOC_DAPM_OUTPUT("HFR"), SND_SOC_DAPM_OUTPUT("EP"), + SND_SOC_DAPM_OUTPUT("AUXL"), + SND_SOC_DAPM_OUTPUT("AUXR"),
/* Analog input muxes for the capture amplifiers */ SND_SOC_DAPM_MUX("Analog Left Capture Route", @@ -1170,6 +1178,10 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, &ep_path_enable_control), + SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0, + &auxl_switch_control), + SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0, + &auxr_switch_control),
/* Analog playback drivers */ SND_SOC_DAPM_OUT_DRV_E("HF Left Driver", @@ -1252,6 +1264,12 @@ static const struct snd_soc_dapm_route intercon[] = {
{"HFL", NULL, "HF Left Driver"}, {"HFR", NULL, "HF Right Driver"}, + + {"AUXL Playback", "Switch", "HF Left PGA"}, + {"AUXR Playback", "Switch", "HF Right PGA"}, + + {"AUXL", NULL, "AUXL Playback"}, + {"AUXR", NULL, "AUXR Playback"}, };
static int twl6040_add_widgets(struct snd_soc_codec *codec)
Change the legacy DAI name from "twl6040-hifi" to "twl6040-legacy" to be more intuitive.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- sound/soc/codecs/twl6040.c | 2 +- sound/soc/omap/sdp4430.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 3908b88..760701e 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1444,7 +1444,7 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
static struct snd_soc_dai_driver twl6040_dai[] = { { - .name = "twl6040-hifi", + .name = "twl6040-legacy", .playback = { .stream_name = "Playback", .channels_min = 1, diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index a951774..4200eb4 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -166,7 +166,7 @@ static struct snd_soc_dai_link sdp4430_dai = { .name = "TWL6040", .stream_name = "TWL6040", .cpu_dai_name = "omap-mcpdm", - .codec_dai_name = "twl6040-hifi", + .codec_dai_name = "twl6040-legacy", .platform_name = "omap-pcm-audio", .codec_name = "twl6040-codec", .init = sdp4430_twl6040_init,
Use one set of defines for the HS bits, since they are identical in both control register.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Acked-by: Liam Girdwood lrg@ti.com --- include/linux/mfd/twl6040.h | 11 +++-------- sound/soc/codecs/twl6040.c | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 47470ca..d9e05ea 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -120,15 +120,10 @@ #define TWL6040_LPLLFIN 0x08 #define TWL6040_HPLLSEL 0x10
-/* HSLCTL (0x10) fields */ +/* HSLCTL/R (0x10/0x11) fields */
-#define TWL6040_HSDACMODEL 0x02 -#define TWL6040_HSDRVMODEL 0x08 - -/* HSRCTL (0x11) fields */ - -#define TWL6040_HSDACMODER 0x02 -#define TWL6040_HSDRVMODER 0x08 +#define TWL6040_HSDACMODE (1 << 1) +#define TWL6040_HSDRVMODE (1 << 3)
/* VIBCTLL (0x18) fields */
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 760701e..68e52c9 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -642,7 +642,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) { int hslctl, hsrctl; - int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL; + int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
participants (2)
-
Mark Brown
-
Peter Ujfalusi