diff options
-rw-r--r-- | include/linux/mfd/twl6040.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/twl6040.c | 36 |
2 files changed, 29 insertions, 8 deletions
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 87a4778ed4b..2463c261959 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h | |||
@@ -122,6 +122,7 @@ | |||
122 | 122 | ||
123 | /* HSLCTL/R (0x10/0x11) fields */ | 123 | /* HSLCTL/R (0x10/0x11) fields */ |
124 | 124 | ||
125 | #define TWL6040_HSDACENA (1 << 0) | ||
125 | #define TWL6040_HSDACMODE (1 << 1) | 126 | #define TWL6040_HSDACMODE (1 << 1) |
126 | #define TWL6040_HSDRVMODE (1 << 3) | 127 | #define TWL6040_HSDRVMODE (1 << 3) |
127 | 128 | ||
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 864849838f4..636923051ad 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -654,6 +654,26 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) | |||
654 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, | 654 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, |
655 | struct snd_kcontrol *kcontrol, int event) | 655 | struct snd_kcontrol *kcontrol, int event) |
656 | { | 656 | { |
657 | struct snd_soc_codec *codec = w->codec; | ||
658 | u8 hslctl, hsrctl; | ||
659 | |||
660 | /* | ||
661 | * Workaround for Headset DC offset caused pop noise: | ||
662 | * Both HS DAC need to be turned on (before the HS driver) and off at | ||
663 | * the same time. | ||
664 | */ | ||
665 | hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); | ||
666 | hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); | ||
667 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
668 | hslctl |= TWL6040_HSDACENA; | ||
669 | hsrctl |= TWL6040_HSDACENA; | ||
670 | } else { | ||
671 | hslctl &= ~TWL6040_HSDACENA; | ||
672 | hsrctl &= ~TWL6040_HSDACENA; | ||
673 | } | ||
674 | twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl); | ||
675 | twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl); | ||
676 | |||
657 | msleep(1); | 677 | msleep(1); |
658 | return 0; | 678 | return 0; |
659 | } | 679 | } |
@@ -1103,14 +1123,8 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
1103 | TWL6040_REG_DMICBCTL, 4, 0), | 1123 | TWL6040_REG_DMICBCTL, 4, 0), |
1104 | 1124 | ||
1105 | /* DACs */ | 1125 | /* DACs */ |
1106 | SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback", | 1126 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), |
1107 | TWL6040_REG_HSLCTL, 0, 0, | 1127 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0), |
1108 | twl6040_hs_dac_event, | ||
1109 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1110 | SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback", | ||
1111 | TWL6040_REG_HSRCTL, 0, 0, | ||
1112 | twl6040_hs_dac_event, | ||
1113 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1114 | SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", | 1128 | SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", |
1115 | TWL6040_REG_HFLCTL, 0, 0, | 1129 | TWL6040_REG_HFLCTL, 0, 0, |
1116 | twl6040_power_mode_event, | 1130 | twl6040_power_mode_event, |
@@ -1175,6 +1189,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
1175 | NULL, 0), | 1189 | NULL, 0), |
1176 | SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0, | 1190 | SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0, |
1177 | NULL, 0), | 1191 | NULL, 0), |
1192 | SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0, | ||
1193 | twl6040_hs_dac_event, | ||
1194 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1178 | 1195 | ||
1179 | /* Analog playback PGAs */ | 1196 | /* Analog playback PGAs */ |
1180 | SND_SOC_DAPM_PGA("HF Left PGA", | 1197 | SND_SOC_DAPM_PGA("HF Left PGA", |
@@ -1204,6 +1221,9 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1204 | {"AFMAmpL", NULL, "AFML"}, | 1221 | {"AFMAmpL", NULL, "AFML"}, |
1205 | {"AFMAmpR", NULL, "AFMR"}, | 1222 | {"AFMAmpR", NULL, "AFMR"}, |
1206 | 1223 | ||
1224 | {"HSDAC Left", NULL, "HSDAC Power"}, | ||
1225 | {"HSDAC Right", NULL, "HSDAC Power"}, | ||
1226 | |||
1207 | {"Headset Left Playback", "HS DAC", "HSDAC Left"}, | 1227 | {"Headset Left Playback", "HS DAC", "HSDAC Left"}, |
1208 | {"Headset Left Playback", "Line-In amp", "AFMAmpL"}, | 1228 | {"Headset Left Playback", "Line-In amp", "AFMAmpL"}, |
1209 | 1229 | ||