Loading asoc/sdm660-common.c +112 −12 Original line number Diff line number Diff line Loading @@ -2824,15 +2824,105 @@ 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 (!mbhc_cfg.enable_usbc_analog) { if (pdata->us_euro_gpio_p) { value = msm_cdc_pinctrl_get_state(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); Loading @@ -2843,8 +2933,14 @@ static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) 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); return true; 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_populate_dai_link_component_of_node( Loading Loading @@ -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), Loading Loading @@ -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", Loading asoc/sdm660-common.h +3 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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 Loading
asoc/sdm660-common.c +112 −12 Original line number Diff line number Diff line Loading @@ -2824,15 +2824,105 @@ 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 (!mbhc_cfg.enable_usbc_analog) { if (pdata->us_euro_gpio_p) { value = msm_cdc_pinctrl_get_state(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); Loading @@ -2843,8 +2933,14 @@ static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) 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); return true; 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_populate_dai_link_component_of_node( Loading Loading @@ -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), Loading Loading @@ -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", Loading
asoc/sdm660-common.h +3 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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