diff options
Diffstat (limited to 'sound/soc/codecs/wcd938x.c')
-rw-r--r-- | sound/soc/codecs/wcd938x.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index 9ae65cbabb1a..898b2887fa63 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -6,6 +6,7 @@ #include <linux/platform_device.h> #include <linux/device.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/pm_runtime.h> #include <linux/component.h> @@ -194,6 +195,7 @@ struct wcd938x_priv { int ear_rx_path; int variant; int reset_gpio; + struct gpio_desc *us_euro_gpio; u32 micb1_mv; u32 micb2_mv; u32 micb3_mv; @@ -4199,6 +4201,22 @@ static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_pri dev_info(dev, "%s: Micbias4 DT property not found\n", __func__); } +static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active) +{ + int value; + + struct wcd938x_priv *wcd938x; + + wcd938x = snd_soc_component_get_drvdata(component); + + value = gpiod_get_value(wcd938x->us_euro_gpio); + + gpiod_set_value(wcd938x->us_euro_gpio, !value); + + return true; +} + + static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device *dev) { struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg; @@ -4211,6 +4229,15 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device return wcd938x->reset_gpio; } + wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", + GPIOD_OUT_LOW); + if (IS_ERR(wcd938x->us_euro_gpio)) { + dev_err(dev, "us-euro swap Control GPIO not found\n"); + return PTR_ERR(wcd938x->us_euro_gpio); + } + + cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; + wcd938x->supplies[0].supply = "vdd-rxtx"; wcd938x->supplies[1].supply = "vdd-io"; wcd938x->supplies[2].supply = "vdd-buck"; @@ -4420,16 +4447,6 @@ static const struct component_master_ops wcd938x_comp_ops = { .unbind = wcd938x_unbind, }; -static int wcd938x_compare_of(struct device *dev, void *data) -{ - return dev->of_node == data; -} - -static void wcd938x_release_of(struct device *dev, void *data) -{ - of_node_put(data); -} - static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x, struct device *dev, struct component_match **matchptr) @@ -4445,8 +4462,8 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x, } of_node_get(wcd938x->rxnode); - component_match_add_release(dev, matchptr, wcd938x_release_of, - wcd938x_compare_of, wcd938x->rxnode); + component_match_add_release(dev, matchptr, component_release_of, + component_compare_of, wcd938x->rxnode); wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0); if (!wcd938x->txnode) { @@ -4454,8 +4471,8 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x, return -ENODEV; } of_node_get(wcd938x->txnode); - component_match_add_release(dev, matchptr, wcd938x_release_of, - wcd938x_compare_of, wcd938x->txnode); + component_match_add_release(dev, matchptr, component_release_of, + component_compare_of, wcd938x->txnode); return 0; } |