Loading arch/arm/boot/dts/qcom/msm8998-audio.dtsi +20 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ "AIF4 VI", "MCLK", "RX_BIAS", "MCLK", "MADINPUT", "MCLK", "hifi amp", "LINEOUT1", "hifi amp", "LINEOUT2", "AMIC2", "MIC BIAS2", "MIC BIAS2", "Headset Mic", "AMIC3", "MIC BIAS2", Loading Loading @@ -81,6 +83,8 @@ qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,us-euro-gpios = <&wcd_us_euro_gpio>; qcom,hph-en0-gpio = <&hph_en0_gpio>; qcom,hph-en1-gpio = <&hph_en1_gpio>; qcom,tasha-mclk-clk-freq = <9600000>; asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, <&loopback>, <&compress>, <&hostless>, Loading Loading @@ -142,6 +146,20 @@ <&wsa881x_213>, <&wsa881x_214>; qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", "SpkrLeft", "SpkrRight"; hph_en0_gpio: msm_cdc_pinctrl@67 { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&hph_en0_active>; pinctrl-1 = <&hph_en0_idle>; }; hph_en1_gpio: msm_cdc_pinctrl@68 { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&hph_en1_active>; pinctrl-1 = <&hph_en1_idle>; }; }; sound-tavil { Loading @@ -165,6 +183,8 @@ qcom,audio-routing = "RX_BIAS", "MCLK", "MADINPUT", "MCLK", "hifi amp", "LINEOUT1", "hifi amp", "LINEOUT2", "AMIC2", "MIC BIAS2", "MIC BIAS2", "Headset Mic", "AMIC3", "MIC BIAS2", Loading arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +54 −0 Original line number Diff line number Diff line Loading @@ -587,6 +587,60 @@ }; }; hph_en0_ctrl { hph_en0_idle: hph_en0_idle { mux { pins = "gpio67"; function = "gpio"; }; config { pins = "gpio67"; drive-strength = <2>; bias-pull-down; output-low; }; }; hph_en0_active: hph_en0_active { mux { pins = "gpio67"; function = "gpio"; }; config { pins = "gpio67"; drive-strength = <2>; bias-disable; output-high; }; }; }; hph_en1_ctrl { hph_en1_idle: hph_en1_idle { mux { pins = "gpio68"; function = "gpio"; }; config { pins = "gpio68"; drive-strength = <2>; bias-pull-down; output-low; }; }; hph_en1_active: hph_en1_active { mux { pins = "gpio68"; function = "gpio"; }; config { pins = "gpio68"; drive-strength = <2>; bias-disable; output-high; }; }; }; wcd_gnd_mic_swap { wcd_gnd_mic_swap_idle: wcd_gnd_mic_swap_idle { mux { Loading sound/soc/msm/msm8998.c +114 −95 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/switch.h> #include <linux/input.h> #include <linux/of_device.h> #include <linux/mfd/msm-cdc-pinctrl.h> #include <sound/core.h> #include <sound/soc.h> Loading Loading @@ -74,6 +75,8 @@ #define TDM_CHANNEL_MAX 8 #define TDM_SLOT_OFFSET_MAX 8 #define MSM_HIFI_ON 1 enum { SLIM_RX_0 = 0, SLIM_RX_1, Loading Loading @@ -158,8 +161,6 @@ struct msm_wsa881x_dev_info { struct msm_asoc_mach_data { u32 mclk_freq; int hph_en1_gpio; int hph_en0_gpio; int us_euro_gpio; /* used by gpio driver API */ struct device_node *us_euro_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ Loading Loading @@ -415,6 +416,7 @@ static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static const char *const hifi_text[] = {"Off", "On"}; static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); Loading Loading @@ -474,8 +476,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); static struct platform_device *spdev; static int msm_hifi_control; static bool is_initial_boot; static bool codec_reg_done; Loading Loading @@ -2340,6 +2344,56 @@ static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } static int msm_hifi_ctrl(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en1_gpio_p) { pr_err("%s: hph_en1_gpio is invalid\n", __func__); return -EINVAL; } if (msm_hifi_control == MSM_HIFI_ON) { msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); /* 5msec delay needed as per HW requirement */ usleep_range(5000, 5010); } else { msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); } snd_soc_dapm_sync(dapm); return 0; } static int msm_hifi_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); ucontrol->value.integer.value[0] = msm_hifi_control; return 0; } static int msm_hifi_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); msm_hifi_control = ucontrol->value.integer.value[0]; msm_hifi_ctrl(codec); return 0; } static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, msm_slim_rx_ch_get, msm_slim_rx_ch_put), Loading Loading @@ -2542,6 +2596,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, msm_hifi_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, Loading Loading @@ -2608,6 +2664,39 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, return 0; } static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en0_gpio_p) { pr_err("%s: hph_en0_gpio is invalid\n", __func__); return -EINVAL; } if (msm_hifi_control != MSM_HIFI_ON) { pr_debug("%s: HiFi mixer control is not set\n", __func__); return 0; } switch (event) { case SND_SOC_DAPM_POST_PMU: msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); break; case SND_SOC_DAPM_PRE_PMD: msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); break; } return 0; } static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, Loading @@ -2621,6 +2710,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), SND_SOC_DAPM_MIC("Handset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), Loading Loading @@ -3207,28 +3297,6 @@ static struct notifier_block service_nb = { .priority = -INT_MAX, }; static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) { struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata; int val; if (!card) return 0; pdata = snd_soc_card_get_drvdata(card); if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) return 0; val = gpio_get_value_cansleep(pdata->hph_en0_gpio); if ((!!val) == high) return 0; gpio_direction_output(pdata->hph_en0_gpio, (int)high); return 1; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; Loading Loading @@ -5800,8 +5868,6 @@ static int msm_snd_card_late_probe(struct snd_soc_card *card) goto err_pcm_runtime; } tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); mbhc_calibration = def_tasha_mbhc_cal(); if (!mbhc_calibration) { ret = -ENOMEM; Loading Loading @@ -5976,37 +6042,6 @@ static int msm_prepare_us_euro(struct snd_soc_card *card) return ret; } static int msm_prepare_hifi(struct snd_soc_card *card) { struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int ret = 0; if (gpio_is_valid(pdata->hph_en1_gpio)) { dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__, pdata->hph_en1_gpio); ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); if (ret) { dev_err(card->dev, "%s: hph_en1_gpio request failed, ret:%d\n", __func__, ret); goto err; } } if (gpio_is_valid(pdata->hph_en0_gpio)) { dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__, pdata->hph_en0_gpio); ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); if (ret) dev_err(card->dev, "%s: hph_en0_gpio request failed, ret:%d\n", __func__, ret); } err: return ret; } static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; Loading Loading @@ -6666,30 +6701,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (ret) goto err; pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio)) pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); } pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!gpio_is_valid(pdata->hph_en0_gpio)) pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); } ret = msm_prepare_hifi(card); if (ret) dev_dbg(&pdev->dev, "msm_prepare_hifi failed (%d)\n", ret); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret == -EPROBE_DEFER) { if (codec_reg_done) Loading @@ -6703,6 +6714,28 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (ret) { dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", __func__, ret); } else { pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!pdata->hph_en1_gpio_p) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); } pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!pdata->hph_en0_gpio_p) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); } } ret = of_property_read_string(pdev->dev.of_node, "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); if (ret) { Loading Loading @@ -6761,18 +6794,6 @@ err: gpio_free(pdata->us_euro_gpio); pdata->us_euro_gpio = 0; } if (pdata->hph_en1_gpio > 0) { dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", __func__, pdata->hph_en1_gpio); gpio_free(pdata->hph_en1_gpio); pdata->hph_en1_gpio = 0; } if (pdata->hph_en0_gpio > 0) { dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", __func__, pdata->hph_en0_gpio); gpio_free(pdata->hph_en0_gpio); pdata->hph_en0_gpio = 0; } devm_kfree(&pdev->dev, pdata); return ret; } Loading @@ -6784,8 +6805,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) snd_soc_card_get_drvdata(card); gpio_free(pdata->us_euro_gpio); gpio_free(pdata->hph_en1_gpio); gpio_free(pdata->hph_en0_gpio); i2s_auxpcm_deinit(); snd_soc_unregister_card(card); Loading Loading
arch/arm/boot/dts/qcom/msm8998-audio.dtsi +20 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ "AIF4 VI", "MCLK", "RX_BIAS", "MCLK", "MADINPUT", "MCLK", "hifi amp", "LINEOUT1", "hifi amp", "LINEOUT2", "AMIC2", "MIC BIAS2", "MIC BIAS2", "Headset Mic", "AMIC3", "MIC BIAS2", Loading Loading @@ -81,6 +83,8 @@ qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,us-euro-gpios = <&wcd_us_euro_gpio>; qcom,hph-en0-gpio = <&hph_en0_gpio>; qcom,hph-en1-gpio = <&hph_en1_gpio>; qcom,tasha-mclk-clk-freq = <9600000>; asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, <&loopback>, <&compress>, <&hostless>, Loading Loading @@ -142,6 +146,20 @@ <&wsa881x_213>, <&wsa881x_214>; qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", "SpkrLeft", "SpkrRight"; hph_en0_gpio: msm_cdc_pinctrl@67 { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&hph_en0_active>; pinctrl-1 = <&hph_en0_idle>; }; hph_en1_gpio: msm_cdc_pinctrl@68 { compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&hph_en1_active>; pinctrl-1 = <&hph_en1_idle>; }; }; sound-tavil { Loading @@ -165,6 +183,8 @@ qcom,audio-routing = "RX_BIAS", "MCLK", "MADINPUT", "MCLK", "hifi amp", "LINEOUT1", "hifi amp", "LINEOUT2", "AMIC2", "MIC BIAS2", "MIC BIAS2", "Headset Mic", "AMIC3", "MIC BIAS2", Loading
arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +54 −0 Original line number Diff line number Diff line Loading @@ -587,6 +587,60 @@ }; }; hph_en0_ctrl { hph_en0_idle: hph_en0_idle { mux { pins = "gpio67"; function = "gpio"; }; config { pins = "gpio67"; drive-strength = <2>; bias-pull-down; output-low; }; }; hph_en0_active: hph_en0_active { mux { pins = "gpio67"; function = "gpio"; }; config { pins = "gpio67"; drive-strength = <2>; bias-disable; output-high; }; }; }; hph_en1_ctrl { hph_en1_idle: hph_en1_idle { mux { pins = "gpio68"; function = "gpio"; }; config { pins = "gpio68"; drive-strength = <2>; bias-pull-down; output-low; }; }; hph_en1_active: hph_en1_active { mux { pins = "gpio68"; function = "gpio"; }; config { pins = "gpio68"; drive-strength = <2>; bias-disable; output-high; }; }; }; wcd_gnd_mic_swap { wcd_gnd_mic_swap_idle: wcd_gnd_mic_swap_idle { mux { Loading
sound/soc/msm/msm8998.c +114 −95 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/switch.h> #include <linux/input.h> #include <linux/of_device.h> #include <linux/mfd/msm-cdc-pinctrl.h> #include <sound/core.h> #include <sound/soc.h> Loading Loading @@ -74,6 +75,8 @@ #define TDM_CHANNEL_MAX 8 #define TDM_SLOT_OFFSET_MAX 8 #define MSM_HIFI_ON 1 enum { SLIM_RX_0 = 0, SLIM_RX_1, Loading Loading @@ -158,8 +161,6 @@ struct msm_wsa881x_dev_info { struct msm_asoc_mach_data { u32 mclk_freq; int hph_en1_gpio; int hph_en0_gpio; int us_euro_gpio; /* used by gpio driver API */ struct device_node *us_euro_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ Loading Loading @@ -415,6 +416,7 @@ static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static const char *const hifi_text[] = {"Off", "On"}; static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); Loading Loading @@ -474,8 +476,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); static struct platform_device *spdev; static int msm_hifi_control; static bool is_initial_boot; static bool codec_reg_done; Loading Loading @@ -2340,6 +2344,56 @@ static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } static int msm_hifi_ctrl(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en1_gpio_p) { pr_err("%s: hph_en1_gpio is invalid\n", __func__); return -EINVAL; } if (msm_hifi_control == MSM_HIFI_ON) { msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); /* 5msec delay needed as per HW requirement */ usleep_range(5000, 5010); } else { msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); } snd_soc_dapm_sync(dapm); return 0; } static int msm_hifi_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); ucontrol->value.integer.value[0] = msm_hifi_control; return 0; } static int msm_hifi_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); msm_hifi_control = ucontrol->value.integer.value[0]; msm_hifi_ctrl(codec); return 0; } static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, msm_slim_rx_ch_get, msm_slim_rx_ch_put), Loading Loading @@ -2542,6 +2596,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, msm_hifi_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, Loading Loading @@ -2608,6 +2664,39 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, return 0; } static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en0_gpio_p) { pr_err("%s: hph_en0_gpio is invalid\n", __func__); return -EINVAL; } if (msm_hifi_control != MSM_HIFI_ON) { pr_debug("%s: HiFi mixer control is not set\n", __func__); return 0; } switch (event) { case SND_SOC_DAPM_POST_PMU: msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); break; case SND_SOC_DAPM_PRE_PMD: msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); break; } return 0; } static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, Loading @@ -2621,6 +2710,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), SND_SOC_DAPM_MIC("Handset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), Loading Loading @@ -3207,28 +3297,6 @@ static struct notifier_block service_nb = { .priority = -INT_MAX, }; static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) { struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata; int val; if (!card) return 0; pdata = snd_soc_card_get_drvdata(card); if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) return 0; val = gpio_get_value_cansleep(pdata->hph_en0_gpio); if ((!!val) == high) return 0; gpio_direction_output(pdata->hph_en0_gpio, (int)high); return 1; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; Loading Loading @@ -5800,8 +5868,6 @@ static int msm_snd_card_late_probe(struct snd_soc_card *card) goto err_pcm_runtime; } tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); mbhc_calibration = def_tasha_mbhc_cal(); if (!mbhc_calibration) { ret = -ENOMEM; Loading Loading @@ -5976,37 +6042,6 @@ static int msm_prepare_us_euro(struct snd_soc_card *card) return ret; } static int msm_prepare_hifi(struct snd_soc_card *card) { struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int ret = 0; if (gpio_is_valid(pdata->hph_en1_gpio)) { dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__, pdata->hph_en1_gpio); ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); if (ret) { dev_err(card->dev, "%s: hph_en1_gpio request failed, ret:%d\n", __func__, ret); goto err; } } if (gpio_is_valid(pdata->hph_en0_gpio)) { dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__, pdata->hph_en0_gpio); ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); if (ret) dev_err(card->dev, "%s: hph_en0_gpio request failed, ret:%d\n", __func__, ret); } err: return ret; } static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; Loading Loading @@ -6666,30 +6701,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (ret) goto err; pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio)) pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); } pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!gpio_is_valid(pdata->hph_en0_gpio)) pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); } ret = msm_prepare_hifi(card); if (ret) dev_dbg(&pdev->dev, "msm_prepare_hifi failed (%d)\n", ret); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret == -EPROBE_DEFER) { if (codec_reg_done) Loading @@ -6703,6 +6714,28 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (ret) { dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", __func__, ret); } else { pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!pdata->hph_en1_gpio_p) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); } pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); if (!pdata->hph_en0_gpio_p) { dev_dbg(&pdev->dev, "property %s not detected in node %s", "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); } } ret = of_property_read_string(pdev->dev.of_node, "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); if (ret) { Loading Loading @@ -6761,18 +6794,6 @@ err: gpio_free(pdata->us_euro_gpio); pdata->us_euro_gpio = 0; } if (pdata->hph_en1_gpio > 0) { dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", __func__, pdata->hph_en1_gpio); gpio_free(pdata->hph_en1_gpio); pdata->hph_en1_gpio = 0; } if (pdata->hph_en0_gpio > 0) { dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", __func__, pdata->hph_en0_gpio); gpio_free(pdata->hph_en0_gpio); pdata->hph_en0_gpio = 0; } devm_kfree(&pdev->dev, pdata); return ret; } Loading @@ -6784,8 +6805,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) snd_soc_card_get_drvdata(card); gpio_free(pdata->us_euro_gpio); gpio_free(pdata->hph_en1_gpio); gpio_free(pdata->hph_en0_gpio); i2s_auxpcm_deinit(); snd_soc_unregister_card(card); Loading