mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
ASoC: codecs: wcd938x: add mux control support for hp audio mux
On some platforms to minimise pop and click during switching between CTIA and OMTP headset an additional HiFi mux is used. Most common case is that this switch is switched on by default, but on some platforms this needs a regulator enable. move to using mux control to enable both regulator and handle gpios, deprecate the usage of gpio. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Tested-by: Christopher Obbard <christopher.obbard@linaro.org> Tested-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20250327100633.11530-6-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
fe19245d3e
commit
eec611d26f
2 changed files with 45 additions and 11 deletions
|
@ -2239,6 +2239,7 @@ config SND_SOC_WCD938X
|
|||
tristate
|
||||
depends on SOUNDWIRE || !SOUNDWIRE
|
||||
select SND_SOC_WCD_CLASSH
|
||||
select MULTIPLEXER
|
||||
|
||||
config SND_SOC_WCD938X_SDW
|
||||
tristate "WCD9380/WCD9385 Codec - SDW"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <linux/mux/consumer.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "wcd-clsh-v2.h"
|
||||
|
@ -173,6 +174,8 @@ struct wcd938x_priv {
|
|||
int variant;
|
||||
int 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;
|
||||
|
@ -183,6 +186,7 @@ struct wcd938x_priv {
|
|||
bool comp1_enable;
|
||||
bool comp2_enable;
|
||||
bool ldoh;
|
||||
bool mux_setup_done;
|
||||
};
|
||||
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
|
||||
|
@ -3232,15 +3236,26 @@ static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_pri
|
|||
|
||||
static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component)
|
||||
{
|
||||
int value;
|
||||
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||
struct device *dev = component->dev;
|
||||
int ret;
|
||||
|
||||
struct wcd938x_priv *wcd938x;
|
||||
if (wcd938x->us_euro_mux) {
|
||||
if (wcd938x->mux_setup_done)
|
||||
mux_control_deselect(wcd938x->us_euro_mux);
|
||||
|
||||
wcd938x = snd_soc_component_get_drvdata(component);
|
||||
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 false;
|
||||
}
|
||||
wcd938x->mux_setup_done = true;
|
||||
} else {
|
||||
gpiod_set_value(wcd938x->us_euro_gpio, !wcd938x->mux_state);
|
||||
}
|
||||
|
||||
value = gpiod_get_value(wcd938x->us_euro_gpio);
|
||||
|
||||
gpiod_set_value(wcd938x->us_euro_gpio, !value);
|
||||
wcd938x->mux_state = !wcd938x->mux_state;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3256,11 +3271,26 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
|
|||
return dev_err_probe(dev, wcd938x->reset_gpio,
|
||||
"Failed to get reset gpio\n");
|
||||
|
||||
wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro",
|
||||
GPIOD_OUT_LOW);
|
||||
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;
|
||||
|
||||
|
@ -3576,6 +3606,9 @@ static void wcd938x_remove(struct platform_device *pdev)
|
|||
pm_runtime_set_suspended(dev);
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
|
||||
if (wcd938x->us_euro_mux && wcd938x->mux_setup_done)
|
||||
mux_control_deselect(wcd938x->us_euro_mux);
|
||||
|
||||
regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
|
||||
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue