ASoC: Add Euro usb-c analog support for sdm670 internal codec
Euro usb-c analog support is not present in machine driver for sdm670. Add support for corresponding gpio so that usb-c analog headset is reported correctly. CRs-Fixed: 2164436 Change-Id: I4bf73a9f13b7b8193289706ac21f96c557503fd8 Signed-off-by: Vatsal Bucha <vbucha@codeaurora.org>
This commit is contained in:
parent
65a1efdc28
commit
a74bac9050
2 changed files with 114 additions and 12 deletions
|
@ -2824,27 +2824,123 @@ static int msm_prepare_us_euro(struct snd_soc_card *card)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
|
||||
{
|
||||
int value = 0;
|
||||
bool ret = false;
|
||||
struct snd_soc_card *card = codec->component.card;
|
||||
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
||||
struct pinctrl_state *en2_pinctrl_active;
|
||||
struct pinctrl_state *en2_pinctrl_sleep;
|
||||
|
||||
if (!pdata->usbc_en2_gpio_p) {
|
||||
if (active) {
|
||||
/* if active and usbc_en2_gpio undefined, get pin */
|
||||
pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev);
|
||||
if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) {
|
||||
dev_err(card->dev,
|
||||
"%s: Can't get EN2 gpio pinctrl:%ld\n",
|
||||
__func__,
|
||||
PTR_ERR(pdata->usbc_en2_gpio_p));
|
||||
pdata->usbc_en2_gpio_p = NULL;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* if not active and usbc_en2_gpio undefined, return */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node,
|
||||
"qcom,usbc-analog-en2-gpio", 0);
|
||||
if (!gpio_is_valid(pdata->usbc_en2_gpio)) {
|
||||
dev_err(card->dev, "%s, property %s not in node %s\n",
|
||||
__func__, "qcom,usbc-analog-en2-gpio",
|
||||
card->dev->of_node->full_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
en2_pinctrl_active = pinctrl_lookup_state(
|
||||
pdata->usbc_en2_gpio_p, "aud_active");
|
||||
if (IS_ERR_OR_NULL(en2_pinctrl_active)) {
|
||||
dev_err(card->dev,
|
||||
"%s: Cannot get aud_active pinctrl state:%ld\n",
|
||||
__func__, PTR_ERR(en2_pinctrl_active));
|
||||
ret = false;
|
||||
goto err_lookup_state;
|
||||
}
|
||||
|
||||
en2_pinctrl_sleep = pinctrl_lookup_state(
|
||||
pdata->usbc_en2_gpio_p, "aud_sleep");
|
||||
if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) {
|
||||
dev_err(card->dev,
|
||||
"%s: Cannot get aud_sleep pinctrl state:%ld\n",
|
||||
__func__, PTR_ERR(en2_pinctrl_sleep));
|
||||
ret = false;
|
||||
goto err_lookup_state;
|
||||
}
|
||||
|
||||
/* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */
|
||||
if (active) {
|
||||
dev_dbg(codec->dev, "%s: enter\n", __func__);
|
||||
if (pdata->usbc_en2_gpio_p) {
|
||||
value = gpio_get_value_cansleep(pdata->usbc_en2_gpio);
|
||||
if (value)
|
||||
pinctrl_select_state(pdata->usbc_en2_gpio_p,
|
||||
en2_pinctrl_sleep);
|
||||
else
|
||||
pinctrl_select_state(pdata->usbc_en2_gpio_p,
|
||||
en2_pinctrl_active);
|
||||
} else if (pdata->usbc_en2_gpio >= 0) {
|
||||
value = gpio_get_value_cansleep(pdata->usbc_en2_gpio);
|
||||
gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value);
|
||||
}
|
||||
pr_debug("%s: swap select switch %d to %d\n", __func__,
|
||||
value, !value);
|
||||
ret = true;
|
||||
} else {
|
||||
/* if not active, release usbc_en2_gpio_p pin */
|
||||
pinctrl_select_state(pdata->usbc_en2_gpio_p,
|
||||
en2_pinctrl_sleep);
|
||||
}
|
||||
|
||||
err_lookup_state:
|
||||
devm_pinctrl_put(pdata->usbc_en2_gpio_p);
|
||||
pdata->usbc_en2_gpio_p = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
|
||||
{
|
||||
struct snd_soc_card *card = codec->component.card;
|
||||
struct msm_asoc_mach_data *pdata =
|
||||
snd_soc_card_get_drvdata(card);
|
||||
int value = 0;
|
||||
bool ret = 0;
|
||||
|
||||
if (pdata->us_euro_gpio_p) {
|
||||
value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
|
||||
if (value)
|
||||
msm_cdc_pinctrl_select_sleep_state(
|
||||
if (!mbhc_cfg.enable_usbc_analog) {
|
||||
if (pdata->us_euro_gpio_p) {
|
||||
value = msm_cdc_pinctrl_get_state(
|
||||
pdata->us_euro_gpio_p);
|
||||
if (value)
|
||||
msm_cdc_pinctrl_select_sleep_state(
|
||||
pdata->us_euro_gpio_p);
|
||||
else
|
||||
msm_cdc_pinctrl_select_active_state(
|
||||
else
|
||||
msm_cdc_pinctrl_select_active_state(
|
||||
pdata->us_euro_gpio_p);
|
||||
} else if (pdata->us_euro_gpio >= 0) {
|
||||
value = gpio_get_value_cansleep(pdata->us_euro_gpio);
|
||||
gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
|
||||
} else if (pdata->us_euro_gpio >= 0) {
|
||||
value = gpio_get_value_cansleep(pdata->us_euro_gpio);
|
||||
gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
|
||||
}
|
||||
pr_debug("%s: swap select switch %d to %d\n",
|
||||
__func__, value, !value);
|
||||
ret = true;
|
||||
} else {
|
||||
/* if usbc is defined, swap using usbc_en2 */
|
||||
ret = msm_usbc_swap_gnd_mic(codec, active);
|
||||
}
|
||||
pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_populate_dai_link_component_of_node(
|
||||
|
@ -3256,6 +3352,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
const char *mclk = "qcom,msm-mclk-freq";
|
||||
int ret = -EINVAL, id;
|
||||
const struct of_device_id *match;
|
||||
const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported";
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct msm_asoc_mach_data),
|
||||
|
@ -3340,6 +3437,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
|
||||
}
|
||||
|
||||
if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL))
|
||||
mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
|
||||
|
||||
ret = msm_prepare_us_euro(card);
|
||||
if (ret)
|
||||
dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -93,9 +93,11 @@ enum {
|
|||
|
||||
struct msm_asoc_mach_data {
|
||||
int us_euro_gpio; /* used by gpio driver API */
|
||||
int usbc_en2_gpio; /* used by gpio driver API */
|
||||
int hph_en1_gpio;
|
||||
int hph_en0_gpio;
|
||||
struct device_node *us_euro_gpio_p; /* used by pinctrl API */
|
||||
struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *pdm_gpio_p; /* used by pinctrl API */
|
||||
|
|
Loading…
Add table
Reference in a new issue