ASoC: wcd938x: enable t14s audio headset
authorMark Brown <broonie@kernel.org>
Tue, 8 Apr 2025 09:25:20 +0000 (10:25 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 8 Apr 2025 09:25:20 +0000 (10:25 +0100)
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.

1  2 
sound/soc/codecs/wcd938x.c
sound/soc/codecs/wcd939x.c

index 955a0d3a77d7cb45932faa0c7a6f5060232d33b4,585a92772c2acbdfe8c7bc390418b4f2db5d7850..b72dcd9d01720f44550d6e438498a2e7eab6dc1a
@@@ -170,8 -172,10 +171,10 @@@ struct wcd938x_priv 
        int flyback_cur_det_disable;
        int ear_rx_path;
        int variant;
 -      int reset_gpio;
 +      struct gpio_desc *reset_gpio;
        struct gpio_desc *us_euro_gpio;
+       struct mux_control *us_euro_mux;
+       unsigned int mux_state;
        u32 micb1_mv;
        u32 micb2_mv;
        u32 micb3_mv;
@@@ -3250,16 -3266,31 +3265,31 @@@ static int wcd938x_populate_dt_data(str
        struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg;
        int ret;
  
 -      wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
 -      if (wcd938x->reset_gpio < 0)
 -              return dev_err_probe(dev, wcd938x->reset_gpio,
 +      wcd938x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
 +      if (IS_ERR(wcd938x->reset_gpio))
 +              return dev_err_probe(dev, PTR_ERR(wcd938x->reset_gpio),
                                     "Failed to get reset gpio\n");
  
-       wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro",
-                                               GPIOD_OUT_LOW);
-       if (IS_ERR(wcd938x->us_euro_gpio))
-               return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio),
-                                    "us-euro swap Control GPIO not found\n");
+       wcd938x->us_euro_mux = devm_mux_control_get(dev, NULL);
+       if (IS_ERR(wcd938x->us_euro_mux)) {
+               if (PTR_ERR(wcd938x->us_euro_mux) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               /* mux is optional and now fallback to using gpio */
+               wcd938x->us_euro_mux = NULL;
+               wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", GPIOD_OUT_LOW);
+               if (IS_ERR(wcd938x->us_euro_gpio))
+                       return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio),
+                                            "us-euro swap Control GPIO not found\n");
+       } else {
+               ret = mux_control_try_select(wcd938x->us_euro_mux, wcd938x->mux_state);
+               if (ret) {
+                       dev_err(dev, "Error (%d) Unable to select us/euro mux state\n", ret);
+                       wcd938x->mux_setup_done = false;
+                       return ret;
+               }
+               wcd938x->mux_setup_done = true;
+       }
  
        cfg->swap_gnd_mic = wcd938x_swap_gnd_mic;
  
Simple merge