Merge "ARM: dts: msm: Add EN2 gpio for mic/gnd swap for SDM845 QRD target"
This commit is contained in:
commit
db727b2695
|
@ -2256,8 +2256,8 @@ Optional properties:
|
|||
- qcom,wcn-btfm : Property to specify if WCN BT/FM chip is used for the target
|
||||
- qcom,msm-mbhc-usbc-audio-supported : Property to specify if analog audio feature is
|
||||
enabled or not.
|
||||
- qcom,usbc-analog-en1_gpio : EN1 GPIO to enable USB type-C analog audio
|
||||
- qcom,usbc-analog-en2_n_gpio : EN2 GPIO to enable USB type-C analog audio
|
||||
- qcom,usbc-analog-en1-gpio : EN1 GPIO to enable USB type-C analog audio
|
||||
- qcom,usbc-analog-en2-gpio : EN2 GPIO to enable USB type-C analog audio
|
||||
- qcom,usbc-analog-force_detect_gpio : Force detect GPIO to enable USB type-C analog audio
|
||||
|
||||
Example:
|
||||
|
@ -2333,8 +2333,8 @@ Example:
|
|||
qcom,wsa-aux-dev-prefix = "SpkrRight", "SpkrLeft",
|
||||
"SpkrRight", "SpkrLeft";
|
||||
qcom,msm-mbhc-usbc-audio-supported = <1>;
|
||||
qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>;
|
||||
qcom,usbc-analog-en2_n_gpio = <&wcd_usbc_analog_en2n_gpio>;
|
||||
qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>;
|
||||
qcom,usbc-analog-en2-gpio = <&tlmm 51 0>;
|
||||
qcom,usbc-analog-force_detect_gpio = <&wcd_usbc_analog_f_gpio>;
|
||||
};
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
qcom,hph-en0-gpio = <&tavil_hph_en0>;
|
||||
qcom,hph-en1-gpio = <&tavil_hph_en1>;
|
||||
qcom,tavil-mclk-clk-freq = <9600000>;
|
||||
|
||||
qcom,usbc-analog-en1-gpio = <&wcd_usbc_analog_en1_gpio>;
|
||||
|
||||
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
|
||||
<&loopback>, <&compress>, <&hostless>,
|
||||
<&afe>, <&lsm>, <&routing>, <&compr>,
|
||||
|
@ -136,6 +139,18 @@
|
|||
<&wsa881x_0213>, <&wsa881x_0214>;
|
||||
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
|
||||
"SpkrLeft", "SpkrRight";
|
||||
|
||||
qcom,usbc-analog-en2-gpio = <&tlmm 51 0>;
|
||||
pinctrl-names = "aud_active", "aud_sleep";
|
||||
pinctrl-0 = <&wcd_usbc_analog_en2_active>;
|
||||
pinctrl-1 = <&wcd_usbc_analog_en2_idle>;
|
||||
};
|
||||
|
||||
wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl@49 {
|
||||
compatible = "qcom,msm-cdc-pinctrl";
|
||||
pinctrl-names = "aud_active", "aud_sleep";
|
||||
pinctrl-0 = <&wcd_usbc_analog_en1_active>;
|
||||
pinctrl-1 = <&wcd_usbc_analog_en1_idle>;
|
||||
};
|
||||
|
||||
wcd9xxx_intc: wcd9xxx-irq {
|
||||
|
|
|
@ -299,6 +299,63 @@
|
|||
};
|
||||
};
|
||||
|
||||
/* USB C analog configuration */
|
||||
wcd_usbc_analog_en1 {
|
||||
wcd_usbc_analog_en1_idle: wcd_usbc_ana_en1_idle {
|
||||
mux {
|
||||
pins = "gpio49";
|
||||
function = "gpio";
|
||||
};
|
||||
config {
|
||||
pins = "gpio49";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
wcd_usbc_analog_en1_active: wcd_usbc_ana_en1_active {
|
||||
mux {
|
||||
pins = "gpio49";
|
||||
function = "gpio";
|
||||
};
|
||||
config {
|
||||
pins = "gpio49";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
wcd_usbc_analog_en2 {
|
||||
wcd_usbc_analog_en2_idle: wcd_usbc_ana_en2_idle {
|
||||
mux {
|
||||
pins = "gpio51";
|
||||
function = "gpio";
|
||||
};
|
||||
config {
|
||||
pins = "gpio51";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
wcd_usbc_analog_en2_active: wcd_usbc_ana_en2_active {
|
||||
mux {
|
||||
pins = "gpio51";
|
||||
function = "gpio";
|
||||
};
|
||||
config {
|
||||
pins = "gpio51";
|
||||
drive-strength = <2>;
|
||||
bias-disable;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pri_aux_pcm_clk {
|
||||
pri_aux_pcm_clk_sleep: pri_aux_pcm_clk_sleep {
|
||||
mux {
|
||||
|
|
|
@ -105,6 +105,41 @@
|
|||
qcom,wsa-max-devs = <1>;
|
||||
qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>;
|
||||
qcom,wsa-aux-dev-prefix = "SpkrRight", "SpkrRight";
|
||||
|
||||
qcom,msm-mbhc-usbc-audio-supported = <1>;
|
||||
|
||||
qcom,usbc-analog-en2-gpio = <&tlmm 51 0>;
|
||||
pinctrl-names = "aud_active", "aud_sleep";
|
||||
pinctrl-0 = <&wcd_usbc_analog_en2_active>;
|
||||
pinctrl-1 = <&wcd_usbc_analog_en2_idle>;
|
||||
};
|
||||
};
|
||||
|
||||
&wcd934x_cdc {
|
||||
wcd: wcd_pinctrl@5 {
|
||||
us_euro_sw_wcd_active: us_euro_sw_wcd_active {
|
||||
mux {
|
||||
pins = "gpio1";
|
||||
};
|
||||
|
||||
config {
|
||||
pins = "gpio1";
|
||||
/delete-property/ output-high;
|
||||
bias-high-impedance;
|
||||
};
|
||||
};
|
||||
|
||||
us_euro_sw_wcd_sleep: us_euro_sw_wcd_sleep {
|
||||
mux {
|
||||
pins = "gpio1";
|
||||
};
|
||||
|
||||
config {
|
||||
pins = "gpio1";
|
||||
/delete-property/ output-low;
|
||||
bias-high-impedance;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -729,7 +729,8 @@ correct_plug_type:
|
|||
* otherwise report unsupported plug
|
||||
*/
|
||||
if (mbhc->mbhc_cfg->swap_gnd_mic &&
|
||||
mbhc->mbhc_cfg->swap_gnd_mic(codec)) {
|
||||
mbhc->mbhc_cfg->swap_gnd_mic(codec,
|
||||
true)) {
|
||||
pr_debug("%s: US_EU gpio present,flip switch\n"
|
||||
, __func__);
|
||||
continue;
|
||||
|
|
|
@ -633,7 +633,8 @@ correct_plug_type:
|
|||
* otherwise report unsupported plug
|
||||
*/
|
||||
if (mbhc->mbhc_cfg->swap_gnd_mic &&
|
||||
mbhc->mbhc_cfg->swap_gnd_mic(codec)) {
|
||||
mbhc->mbhc_cfg->swap_gnd_mic(codec,
|
||||
true)) {
|
||||
pr_debug("%s: US_EU gpio present,flip switch\n"
|
||||
, __func__);
|
||||
continue;
|
||||
|
|
|
@ -1460,18 +1460,12 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc,
|
|||
if (config->usbc_en1_gpio_p)
|
||||
rc = msm_cdc_pinctrl_select_active_state(
|
||||
config->usbc_en1_gpio_p);
|
||||
if (rc == 0 && config->usbc_en2n_gpio_p)
|
||||
rc = msm_cdc_pinctrl_select_active_state(
|
||||
config->usbc_en2n_gpio_p);
|
||||
if (rc == 0 && config->usbc_force_gpio_p)
|
||||
rc = msm_cdc_pinctrl_select_active_state(
|
||||
config->usbc_force_gpio_p);
|
||||
mbhc->usbc_mode = POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER;
|
||||
} else {
|
||||
/* no delay is required when disabling GPIOs */
|
||||
if (config->usbc_en2n_gpio_p)
|
||||
msm_cdc_pinctrl_select_sleep_state(
|
||||
config->usbc_en2n_gpio_p);
|
||||
if (config->usbc_en1_gpio_p)
|
||||
msm_cdc_pinctrl_select_sleep_state(
|
||||
config->usbc_en1_gpio_p);
|
||||
|
@ -1490,6 +1484,8 @@ static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc,
|
|||
}
|
||||
|
||||
mbhc->usbc_mode = POWER_SUPPLY_TYPEC_NONE;
|
||||
if (mbhc->mbhc_cfg->swap_gnd_mic)
|
||||
mbhc->mbhc_cfg->swap_gnd_mic(mbhc->codec, false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -1675,19 +1671,12 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg)
|
|||
dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n",
|
||||
__func__);
|
||||
rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg,
|
||||
"qcom,usbc-analog-en1_gpio",
|
||||
"qcom,usbc-analog-en1-gpio",
|
||||
&config->usbc_en1_gpio,
|
||||
&config->usbc_en1_gpio_p);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg,
|
||||
"qcom,usbc-analog-en2_n_gpio",
|
||||
&config->usbc_en2n_gpio,
|
||||
&config->usbc_en2n_gpio_p);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
if (of_find_property(card->dev->of_node,
|
||||
"qcom,usbc-analog-force_detect_gpio",
|
||||
NULL)) {
|
||||
|
@ -1734,12 +1723,6 @@ err:
|
|||
gpio_free(config->usbc_en1_gpio);
|
||||
config->usbc_en1_gpio = 0;
|
||||
}
|
||||
if (config->usbc_en2n_gpio > 0) {
|
||||
dev_dbg(card->dev, "%s free usb_en2 gpio %d\n",
|
||||
__func__, config->usbc_en2n_gpio);
|
||||
gpio_free(config->usbc_en2n_gpio);
|
||||
config->usbc_en2n_gpio = 0;
|
||||
}
|
||||
if (config->usbc_force_gpio > 0) {
|
||||
dev_dbg(card->dev, "%s free usb_force gpio %d\n",
|
||||
__func__, config->usbc_force_gpio);
|
||||
|
@ -1748,8 +1731,6 @@ err:
|
|||
}
|
||||
if (config->usbc_en1_gpio_p)
|
||||
of_node_put(config->usbc_en1_gpio_p);
|
||||
if (config->usbc_en2n_gpio_p)
|
||||
of_node_put(config->usbc_en2n_gpio_p);
|
||||
if (config->usbc_force_gpio_p)
|
||||
of_node_put(config->usbc_force_gpio_p);
|
||||
dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc);
|
||||
|
@ -1790,15 +1771,11 @@ void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
|
|||
/* free GPIOs */
|
||||
if (config->usbc_en1_gpio > 0)
|
||||
gpio_free(config->usbc_en1_gpio);
|
||||
if (config->usbc_en2n_gpio > 0)
|
||||
gpio_free(config->usbc_en2n_gpio);
|
||||
if (config->usbc_force_gpio)
|
||||
gpio_free(config->usbc_force_gpio);
|
||||
|
||||
if (config->usbc_en1_gpio_p)
|
||||
of_node_put(config->usbc_en1_gpio_p);
|
||||
if (config->usbc_en2n_gpio_p)
|
||||
of_node_put(config->usbc_en2n_gpio_p);
|
||||
if (config->usbc_force_gpio_p)
|
||||
of_node_put(config->usbc_force_gpio_p);
|
||||
}
|
||||
|
|
|
@ -404,10 +404,10 @@ enum mbhc_moisture_rref {
|
|||
|
||||
struct usbc_ana_audio_config {
|
||||
int usbc_en1_gpio;
|
||||
int usbc_en2n_gpio;
|
||||
int usbc_en2_gpio;
|
||||
int usbc_force_gpio;
|
||||
struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *usbc_en2n_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *usbc_en2_gpio_p; /* used by pinctrl API */
|
||||
struct device_node *usbc_force_gpio_p; /* used by pinctrl API */
|
||||
};
|
||||
|
||||
|
@ -416,7 +416,7 @@ struct wcd_mbhc_config {
|
|||
void *calibration;
|
||||
bool detect_extn_cable;
|
||||
bool mono_stero_detection;
|
||||
bool (*swap_gnd_mic)(struct snd_soc_codec *codec);
|
||||
bool (*swap_gnd_mic)(struct snd_soc_codec *codec, bool active);
|
||||
bool hs_ext_micbias;
|
||||
bool gnd_det_en;
|
||||
int key_code[WCD_MBHC_KEYCODE_NUM];
|
||||
|
|
|
@ -173,7 +173,9 @@ struct msm_pinctrl_info {
|
|||
struct msm_asoc_mach_data {
|
||||
u32 mclk_freq;
|
||||
int us_euro_gpio; /* used by gpio driver API */
|
||||
int usbc_en2_gpio; /* used by gpio driver API */
|
||||
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 snd_info_entry *codec_root;
|
||||
|
@ -3106,27 +3108,126 @@ done:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static bool msm_swap_gnd_mic(struct snd_soc_codec *codec)
|
||||
static bool msm_usbc_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;
|
||||
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->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(
|
||||
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);
|
||||
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;
|
||||
}
|
||||
pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
|
||||
return true;
|
||||
|
||||
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",
|
||||
__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)
|
||||
{
|
||||
int value = 0;
|
||||
int ret = 0;
|
||||
struct snd_soc_card *card = codec->component.card;
|
||||
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
||||
|
||||
if (!pdata)
|
||||
return false;
|
||||
|
||||
if (!wcd_mbhc_cfg.enable_usbc_analog) {
|
||||
/* if usbc is not defined, swap using us_euro_gpio_p */
|
||||
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(
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_afe_set_config(struct snd_soc_codec *codec)
|
||||
|
@ -6454,6 +6555,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
char *mclk_freq_prop_name;
|
||||
const struct of_device_id *match;
|
||||
int ret;
|
||||
const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported";
|
||||
|
||||
if (!pdev->dev.of_node) {
|
||||
dev_err(&pdev->dev, "No platform supplied from device tree\n");
|
||||
|
@ -6601,6 +6703,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
|
||||
}
|
||||
|
||||
if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL))
|
||||
wcd_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",
|
||||
|
|
Loading…
Reference in New Issue