Loading Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +17 −4 Original line number Diff line number Diff line Loading @@ -504,9 +504,17 @@ normally open. switch type on target typically the switch type will be normally open or normally close, value for this property 0 for normally close and 1 for normally open. - pinctrl-names : Pincntrl entries to configure the PDM gpio lines accordingly - pinctrl-0 : This exoplains the active state of the PDM gpio lines - pinctrl-1 : This exoplains the suspend state of the PDM gpio lines - pinctrl-names : Pincntrl entries to configure the PDM gpio lines and cross connection switch gpio accordingly - pinctrl-0 : This explains the active state of the PDM gpio lines - pinctrl-1 : This explains the suspend state of the PDM gpio lines - pinctrl-2 : This explains the active state of the cross connection gpio lines - pinctrl-3 : This explains the suspend state of the cross connection gpio lines Optional Properties: - qcom,us-euro-gpios : GPIO on which gnd/mic swap signal is coming. Example: Loading @@ -517,6 +525,7 @@ Example: qcom,msm-codec-type = "internal"; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,cdc-us-euro-gpios = <&msmgpio 120 0>; qcom,audio-routing = "RX_BIAS", "MCLK", "INT_LDO_H", "MCLK", Loading @@ -527,9 +536,13 @@ Example: "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS External"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus"; "cdc_pdm_lines_sus", "cross_conn_det_act", "cross_conn_det_sus"; pinctrl-0 = <&cdc_pdm_lines_act>; pinctrl-1 = <&cdc_pdm_lines_sus>; pinctrl-2 = <&cross_conn_det_act>; pinctrl-3 = <&cross_conn_det_sus>; }; * MSM8974 ASoC Machine driver Loading sound/soc/codecs/msm8x16-wcd.h +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ struct msm8x16_wcd_regulator { struct msm8916_asoc_mach_data { int codec_type; int us_euro_gpio; atomic_t mclk_rsc_ref; atomic_t dis_work_mclk; struct mutex cdc_mclk_mutex; Loading sound/soc/codecs/wcd-mbhc-v2.c +20 −0 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) if (!result1 && !(swap_res & 0x04)) { plug_type = PLUG_TYPE_GND_MIC_SWAP; pr_debug("%s: Cross connection identified", __func__); goto eu_us_switch; } else { pr_debug("%s: No Cross connection found", __func__); } Loading Loading @@ -468,6 +469,25 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) goto exit; } } eu_us_switch: if (plug_type == PLUG_TYPE_GND_MIC_SWAP) { pr_debug("%s: cross connection found\n", __func__); if (mbhc->mbhc_cfg->swap_gnd_mic) { pr_debug("%s: US_EU gpio present, flip switch\n", __func__); if (mbhc->mbhc_cfg->swap_gnd_mic(codec)) plug_type = PLUG_TYPE_HEADSET; } /* Disable micbias and schmitt trigger */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x6, 0x0); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x80, 0x00); } pr_debug("%s: Valid plug found, plug type is %d\n", __func__, plug_type); wcd_mbhc_find_plug_and_report(mbhc, plug_type); Loading sound/soc/codecs/wcd-mbhc-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct wcd_mbhc_config { void *calibration; bool detect_extn_cable; bool mono_stero_detection; bool (*swap_gnd_mic) (struct snd_soc_codec *codec); }; struct wcd_mbhc_intr { Loading sound/soc/msm/msm8x16.c +71 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ static struct wcd_mbhc_config mbhc_cfg = { .calibration = NULL, .detect_extn_cable = true, .mono_stero_detection = false, .swap_gnd_mic = NULL, }; static struct afe_clk_cfg mi2s_rx_clk = { Loading @@ -82,6 +83,8 @@ struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_pdm_sus; struct pinctrl_state *cdc_pdm_act; struct pinctrl_state *cross_conn_det_sus; struct pinctrl_state *cross_conn_det_act; }; static struct cdc_pdm_pinctrl_info pinctrl_info; Loading Loading @@ -970,7 +973,29 @@ static int cdc_pdm_get_pinctrl(struct platform_device *pdev) pr_err("%s: Failed to disable the TLMM pins\n", __func__); return -EIO; } /* get pinctrl handle for cross det pin*/ pinctrl_info.cross_conn_det_sus = pinctrl_lookup_state(pinctrl, "cross_conn_det_sus"); if (IS_ERR(pinctrl_info.cross_conn_det_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cross_conn_det_act = pinctrl_lookup_state(pinctrl, "cross_conn_det_act"); if (IS_ERR(pinctrl_info.cross_conn_det_act)) { pr_err("%s: Unable to get pinctrl active state handle\n", __func__); return -EINVAL; } /* Reset cross conn det pins to default state*/ ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_sus); if (ret != 0) { pr_err("%s: Failed to disable cross conn det pins\n", __func__); return -EIO; } return 0; } Loading Loading @@ -998,6 +1023,50 @@ void enable_mclk(struct work_struct *work) mutex_unlock(&pdata->cdc_mclk_mutex); } static bool msm8x16_swap_gnd_mic(struct snd_soc_codec *codec) { struct snd_soc_card *card = codec->card; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int value, ret; if (!gpio_is_valid(pdata->us_euro_gpio)) { pr_debug("%s: Invalid gpio: %d", __func__, pdata->us_euro_gpio); return false; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_act); if (ret < 0) { pr_err("failed to configure the gpio\n"); return ret; } value = gpio_get_value_cansleep(pdata->us_euro_gpio); gpio_direction_output(pdata->us_euro_gpio, !value); pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_sus); if (ret < 0) { pr_err("failed to configure the gpio\n"); return ret; } return true; } static void msm8x16_setup_hs_jack(struct platform_device *pdev, struct msm8916_asoc_mach_data *pdata) { pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,cdc-us-euro-gpios", 0); if (pdata->us_euro_gpio < 0) { dev_dbg(&pdev->dev, "property %s in node %s not found %d\n", "qcom,cdc-us-euro-gpios", pdev->dev.of_node->full_name, pdata->us_euro_gpio); } else { mbhc_cfg.swap_gnd_mic = msm8x16_swap_gnd_mic; } } static int msm8x16_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; Loading Loading @@ -1065,6 +1134,8 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) } card = &bear_cards[pdev->id]; msm8x16_setup_hs_jack(pdev, pdata); card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, pdata); Loading Loading
Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +17 −4 Original line number Diff line number Diff line Loading @@ -504,9 +504,17 @@ normally open. switch type on target typically the switch type will be normally open or normally close, value for this property 0 for normally close and 1 for normally open. - pinctrl-names : Pincntrl entries to configure the PDM gpio lines accordingly - pinctrl-0 : This exoplains the active state of the PDM gpio lines - pinctrl-1 : This exoplains the suspend state of the PDM gpio lines - pinctrl-names : Pincntrl entries to configure the PDM gpio lines and cross connection switch gpio accordingly - pinctrl-0 : This explains the active state of the PDM gpio lines - pinctrl-1 : This explains the suspend state of the PDM gpio lines - pinctrl-2 : This explains the active state of the cross connection gpio lines - pinctrl-3 : This explains the suspend state of the cross connection gpio lines Optional Properties: - qcom,us-euro-gpios : GPIO on which gnd/mic swap signal is coming. Example: Loading @@ -517,6 +525,7 @@ Example: qcom,msm-codec-type = "internal"; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,cdc-us-euro-gpios = <&msmgpio 120 0>; qcom,audio-routing = "RX_BIAS", "MCLK", "INT_LDO_H", "MCLK", Loading @@ -527,9 +536,13 @@ Example: "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS External"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus"; "cdc_pdm_lines_sus", "cross_conn_det_act", "cross_conn_det_sus"; pinctrl-0 = <&cdc_pdm_lines_act>; pinctrl-1 = <&cdc_pdm_lines_sus>; pinctrl-2 = <&cross_conn_det_act>; pinctrl-3 = <&cross_conn_det_sus>; }; * MSM8974 ASoC Machine driver Loading
sound/soc/codecs/msm8x16-wcd.h +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ struct msm8x16_wcd_regulator { struct msm8916_asoc_mach_data { int codec_type; int us_euro_gpio; atomic_t mclk_rsc_ref; atomic_t dis_work_mclk; struct mutex cdc_mclk_mutex; Loading
sound/soc/codecs/wcd-mbhc-v2.c +20 −0 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) if (!result1 && !(swap_res & 0x04)) { plug_type = PLUG_TYPE_GND_MIC_SWAP; pr_debug("%s: Cross connection identified", __func__); goto eu_us_switch; } else { pr_debug("%s: No Cross connection found", __func__); } Loading Loading @@ -468,6 +469,25 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) goto exit; } } eu_us_switch: if (plug_type == PLUG_TYPE_GND_MIC_SWAP) { pr_debug("%s: cross connection found\n", __func__); if (mbhc->mbhc_cfg->swap_gnd_mic) { pr_debug("%s: US_EU gpio present, flip switch\n", __func__); if (mbhc->mbhc_cfg->swap_gnd_mic(codec)) plug_type = PLUG_TYPE_HEADSET; } /* Disable micbias and schmitt trigger */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x6, 0x0); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x80, 0x00); } pr_debug("%s: Valid plug found, plug type is %d\n", __func__, plug_type); wcd_mbhc_find_plug_and_report(mbhc, plug_type); Loading
sound/soc/codecs/wcd-mbhc-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct wcd_mbhc_config { void *calibration; bool detect_extn_cable; bool mono_stero_detection; bool (*swap_gnd_mic) (struct snd_soc_codec *codec); }; struct wcd_mbhc_intr { Loading
sound/soc/msm/msm8x16.c +71 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ static struct wcd_mbhc_config mbhc_cfg = { .calibration = NULL, .detect_extn_cable = true, .mono_stero_detection = false, .swap_gnd_mic = NULL, }; static struct afe_clk_cfg mi2s_rx_clk = { Loading @@ -82,6 +83,8 @@ struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_pdm_sus; struct pinctrl_state *cdc_pdm_act; struct pinctrl_state *cross_conn_det_sus; struct pinctrl_state *cross_conn_det_act; }; static struct cdc_pdm_pinctrl_info pinctrl_info; Loading Loading @@ -970,7 +973,29 @@ static int cdc_pdm_get_pinctrl(struct platform_device *pdev) pr_err("%s: Failed to disable the TLMM pins\n", __func__); return -EIO; } /* get pinctrl handle for cross det pin*/ pinctrl_info.cross_conn_det_sus = pinctrl_lookup_state(pinctrl, "cross_conn_det_sus"); if (IS_ERR(pinctrl_info.cross_conn_det_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cross_conn_det_act = pinctrl_lookup_state(pinctrl, "cross_conn_det_act"); if (IS_ERR(pinctrl_info.cross_conn_det_act)) { pr_err("%s: Unable to get pinctrl active state handle\n", __func__); return -EINVAL; } /* Reset cross conn det pins to default state*/ ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_sus); if (ret != 0) { pr_err("%s: Failed to disable cross conn det pins\n", __func__); return -EIO; } return 0; } Loading Loading @@ -998,6 +1023,50 @@ void enable_mclk(struct work_struct *work) mutex_unlock(&pdata->cdc_mclk_mutex); } static bool msm8x16_swap_gnd_mic(struct snd_soc_codec *codec) { struct snd_soc_card *card = codec->card; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int value, ret; if (!gpio_is_valid(pdata->us_euro_gpio)) { pr_debug("%s: Invalid gpio: %d", __func__, pdata->us_euro_gpio); return false; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_act); if (ret < 0) { pr_err("failed to configure the gpio\n"); return ret; } value = gpio_get_value_cansleep(pdata->us_euro_gpio); gpio_direction_output(pdata->us_euro_gpio, !value); pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cross_conn_det_sus); if (ret < 0) { pr_err("failed to configure the gpio\n"); return ret; } return true; } static void msm8x16_setup_hs_jack(struct platform_device *pdev, struct msm8916_asoc_mach_data *pdata) { pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,cdc-us-euro-gpios", 0); if (pdata->us_euro_gpio < 0) { dev_dbg(&pdev->dev, "property %s in node %s not found %d\n", "qcom,cdc-us-euro-gpios", pdev->dev.of_node->full_name, pdata->us_euro_gpio); } else { mbhc_cfg.swap_gnd_mic = msm8x16_swap_gnd_mic; } } static int msm8x16_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; Loading Loading @@ -1065,6 +1134,8 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) } card = &bear_cards[pdev->id]; msm8x16_setup_hs_jack(pdev, pdata); card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, pdata); Loading