Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: wcd938x: enable t14s audio headset

Merge series from srinivas.kandagatla@linaro.org:

On Lenovo ThinkPad T14s, the headset is connected via a HiFi Switch to
support CTIA and OMTP headsets. This switch is used to minimise pop and
click during headset type switching.

This patchset adds required bindings and changes to codec and dts to
tnable the regulator required to power this switch along with wiring up
gpio that control the headset switching.

Without this patchset, there will be lots of noise on headset and mic
will not we functional.

+56 -16
+6
Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
··· 23 23 - qcom,wcd9380-codec 24 24 - qcom,wcd9385-codec 25 25 26 + mux-controls: 27 + description: A reference to the audio mux switch for 28 + switching CTIA/OMTP Headset types 29 + maxItems: 1 30 + 26 31 us-euro-gpios: 27 32 description: GPIO spec for swapping gnd and mic segments 28 33 maxItems: 1 34 + deprecated: true 29 35 30 36 required: 31 37 - compatible
+1
sound/soc/codecs/Kconfig
··· 2239 2239 tristate 2240 2240 depends on SOUNDWIRE || !SOUNDWIRE 2241 2241 select SND_SOC_WCD_CLASSH 2242 + select MULTIPLEXER 2242 2243 2243 2244 config SND_SOC_WCD938X_SDW 2244 2245 tristate "WCD9380/WCD9385 Codec - SDW"
+1 -1
sound/soc/codecs/wcd-mbhc-v2.c
··· 1260 1260 if (pt_gnd_mic_swap_cnt == mbhc->swap_thr) { 1261 1261 /* US_EU gpio present, flip switch */ 1262 1262 if (mbhc->cfg->swap_gnd_mic) { 1263 - if (mbhc->cfg->swap_gnd_mic(component, true)) 1263 + if (mbhc->cfg->swap_gnd_mic(component)) 1264 1264 continue; 1265 1265 } 1266 1266 }
+1 -1
sound/soc/codecs/wcd-mbhc-v2.h
··· 194 194 int num_btn; 195 195 bool mono_stero_detection; 196 196 bool typec_analog_mux; 197 - bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active); 197 + bool (*swap_gnd_mic)(struct snd_soc_component *component); 198 198 bool hs_ext_micbias; 199 199 bool gnd_det_en; 200 200 uint32_t linein_th;
+1 -1
sound/soc/codecs/wcd937x.c
··· 2656 2656 dev_warn(dev, "Micbias3 DT property not found\n"); 2657 2657 } 2658 2658 2659 - static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component, bool active) 2659 + static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component) 2660 2660 { 2661 2661 int value; 2662 2662 struct wcd937x_priv *wcd937x;
+45 -12
sound/soc/codecs/wcd938x.c
··· 18 18 #include <linux/regmap.h> 19 19 #include <sound/soc.h> 20 20 #include <sound/soc-dapm.h> 21 + #include <linux/mux/consumer.h> 21 22 #include <linux/regulator/consumer.h> 22 23 23 24 #include "wcd-clsh-v2.h" ··· 173 172 int variant; 174 173 struct gpio_desc *reset_gpio; 175 174 struct gpio_desc *us_euro_gpio; 175 + struct mux_control *us_euro_mux; 176 + unsigned int mux_state; 176 177 u32 micb1_mv; 177 178 u32 micb2_mv; 178 179 u32 micb3_mv; ··· 185 182 bool comp1_enable; 186 183 bool comp2_enable; 187 184 bool ldoh; 185 + bool mux_setup_done; 188 186 }; 189 187 190 188 static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); ··· 3233 3229 dev_info(dev, "%s: Micbias4 DT property not found\n", __func__); 3234 3230 } 3235 3231 3236 - static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active) 3232 + static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component) 3237 3233 { 3238 - int value; 3234 + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); 3235 + struct device *dev = component->dev; 3236 + int ret; 3239 3237 3240 - struct wcd938x_priv *wcd938x; 3238 + if (wcd938x->us_euro_mux) { 3239 + if (wcd938x->mux_setup_done) 3240 + mux_control_deselect(wcd938x->us_euro_mux); 3241 3241 3242 - wcd938x = snd_soc_component_get_drvdata(component); 3242 + ret = mux_control_try_select(wcd938x->us_euro_mux, !wcd938x->mux_state); 3243 + if (ret) { 3244 + dev_err(dev, "Error (%d) Unable to select us/euro mux state\n", ret); 3245 + wcd938x->mux_setup_done = false; 3246 + return false; 3247 + } 3248 + wcd938x->mux_setup_done = true; 3249 + } else { 3250 + gpiod_set_value(wcd938x->us_euro_gpio, !wcd938x->mux_state); 3251 + } 3243 3252 3244 - value = gpiod_get_value(wcd938x->us_euro_gpio); 3245 - 3246 - gpiod_set_value(wcd938x->us_euro_gpio, !value); 3253 + wcd938x->mux_state = !wcd938x->mux_state; 3247 3254 3248 3255 return true; 3249 3256 } ··· 3270 3255 return dev_err_probe(dev, PTR_ERR(wcd938x->reset_gpio), 3271 3256 "Failed to get reset gpio\n"); 3272 3257 3273 - wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", 3274 - GPIOD_OUT_LOW); 3275 - if (IS_ERR(wcd938x->us_euro_gpio)) 3276 - return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), 3277 - "us-euro swap Control GPIO not found\n"); 3258 + wcd938x->us_euro_mux = devm_mux_control_get(dev, NULL); 3259 + if (IS_ERR(wcd938x->us_euro_mux)) { 3260 + if (PTR_ERR(wcd938x->us_euro_mux) == -EPROBE_DEFER) 3261 + return -EPROBE_DEFER; 3262 + 3263 + /* mux is optional and now fallback to using gpio */ 3264 + wcd938x->us_euro_mux = NULL; 3265 + wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", GPIOD_OUT_LOW); 3266 + if (IS_ERR(wcd938x->us_euro_gpio)) 3267 + return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), 3268 + "us-euro swap Control GPIO not found\n"); 3269 + } else { 3270 + ret = mux_control_try_select(wcd938x->us_euro_mux, wcd938x->mux_state); 3271 + if (ret) { 3272 + dev_err(dev, "Error (%d) Unable to select us/euro mux state\n", ret); 3273 + wcd938x->mux_setup_done = false; 3274 + return ret; 3275 + } 3276 + wcd938x->mux_setup_done = true; 3277 + } 3278 3278 3279 3279 cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; 3280 3280 ··· 3604 3574 pm_runtime_disable(dev); 3605 3575 pm_runtime_set_suspended(dev); 3606 3576 pm_runtime_dont_use_autosuspend(dev); 3577 + 3578 + if (wcd938x->us_euro_mux && wcd938x->mux_setup_done) 3579 + mux_control_deselect(wcd938x->us_euro_mux); 3607 3580 3608 3581 regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); 3609 3582 regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
+1 -1
sound/soc/codecs/wcd939x.c
··· 3214 3214 } 3215 3215 3216 3216 #if IS_ENABLED(CONFIG_TYPEC) 3217 - static bool wcd939x_swap_gnd_mic(struct snd_soc_component *component, bool active) 3217 + static bool wcd939x_swap_gnd_mic(struct snd_soc_component *component) 3218 3218 { 3219 3219 struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 3220 3220