Loading Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +6 −2 Original line number Diff line number Diff line Loading @@ -524,8 +524,12 @@ Required properties: - qcom,msm-hs-micbias-type : This property is used to recognize the headset micbias type, internal or external. - qcom,msm-ext-pa : This property is used to inform machine driver about the connection of external PA over secondary MI2S interface, val 0 external PA is not there, Val 1 external PA is connected. the connection of external PA over available MI2S interfaces, following values can be given to this property. primary -> Primary MI2S interface secondary -> Secondary MI2S interface tertiary -> Tertiary MI2S interface quaternary -> Quaternary MI2S interface - qcom,msm-mclk-freq : This property is used to inform machine driver about mclk frequency needs to be configured for internal and external PA. - qcom,msm-mbhc-hphl-swh: This property is used to distinguish headset HPHL Loading arch/arm/boot/dts/qcom/msm8916-cdp.dtsi +9 −7 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ qcom,model = "msm8x16-snd-card"; qcom,msm-snd-card-id = <0>; qcom,msm-codec-type = "internal"; qcom,msm-ext-pa = <0>; qcom,msm-ext-pa = "primary"; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,msm-mclk-freq = <9600000>; Loading @@ -215,14 +215,16 @@ "AMIC1", "MIC BIAS Internal1", "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS Internal3"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus", "cdc_ext_pa_act", "cdc_ext_pa_sus"; pinctrl-names = "cdc_lines_act", "cdc_lines_sus", "cdc_lines_sec_ext_act", "cdc_lines_sec_ext_sus"; pinctrl-0 = <&cdc_pdm_lines_act>; pinctrl-1 = <&cdc_pdm_lines_sus>; pinctrl-2 = <&cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; pinctrl-2 = <&cdc_pdm_lines_act &cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_pdm_lines_sus &cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; }; sound-9306 { Loading arch/arm/boot/dts/qcom/msm8916-mtp.dtsi +11 −5 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ qcom,model = "msm8x16-snd-card-mtp"; qcom,msm-snd-card-id = <0>; qcom,msm-codec-type = "internal"; qcom,msm-ext-pa = <0>; qcom,msm-ext-pa = "primary"; qcom,msm-mclk-freq = <9600000>; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; Loading @@ -146,14 +146,20 @@ "AMIC1", "MIC BIAS External", "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS External"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus", pinctrl-names = "cdc_lines_act", "cdc_lines_sus", "cdc_lines_sec_ext_act", "cdc_lines_sec_ext_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>; pinctrl-2 = <&cdc_pdm_lines_act &cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_pdm_lines_sus &cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; pinctrl-4 = <&cross_conn_det_act>; pinctrl-5 = <&cross_conn_det_sus>; qcom,cdc-us-euro-gpios = <&msm_gpio 120 0>; }; }; Loading sound/soc/msm/msm8x16.c +280 −106 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ #define BTSCO_RATE_16KHZ 16000 #define MAX_SND_CARDS 3 #define PRI_MI2S_ID (1 << 0) #define SEC_MI2S_ID (1 << 1) #define TER_MI2S_ID (1 << 2) #define QUAT_MI2S_ID (1 << 3) #define LPASS_CSR_GP_IO_MUX_MIC_CTL 0x07702000 #define LPASS_CSR_GP_IO_MUX_SPKR_CTL 0x07702004 Loading Loading @@ -189,12 +194,10 @@ static struct afe_clk_cfg mi2s_tx_clk = { struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_pdm_sus; struct pinctrl_state *cdc_pdm_act; struct pinctrl_state *cdc_lines_sus; struct pinctrl_state *cdc_lines_act; struct pinctrl_state *cross_conn_det_sus; struct pinctrl_state *cross_conn_det_act; struct pinctrl_state *ext_pa_sus; struct pinctrl_state *ext_pa_act; }; struct ext_cdc_tlmm_pinctrl_info { Loading Loading @@ -467,6 +470,40 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } return ret; } static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; Loading Loading @@ -577,10 +614,8 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, atomic_set(&pdata->dis_work_mclk, true); } mutex_unlock(&pdata->cdc_mclk_mutex); msm8x16_wcd_mclk_enable(codec, 1, dapm); } } else { msm8x16_wcd_mclk_enable(codec, 0, dapm); mutex_lock(&pdata->cdc_mclk_mutex); atomic_set(&pdata->mclk_rsc_ref, 0); cancel_delayed_work_sync(&pdata->enable_mclk_work); Loading Loading @@ -659,6 +694,7 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct msm8916_asoc_mach_data *pdata = NULL; int ret = 0; pdata = snd_soc_card_get_drvdata(w->codec->card); pr_debug("%s: event = %d\n", __func__, event); Loading @@ -669,9 +705,14 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, if (!pdata->codec_type) { if (atomic_read(&pdata->mclk_rsc_ref) == 0) { pr_debug("%s: disabling MCLK\n", __func__); /* disable the codec mclk config*/ msm8x16_wcd_mclk_enable(w->codec, 0, true); msm8x16_enable_codec_ext_clk(w->codec, 0, true); pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_sus); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_lines_sus); if (ret < 0) pr_err("%s: error during pinctrl state select\n", __func__); } } break; Loading Loading @@ -722,16 +763,14 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) } } static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) static int conf_int_codec_mux_sec(struct msm8916_asoc_mach_data *pdata) { int ret = 0; int val = 0; void __iomem *vaddr = NULL; /* *configure the Primary, Sec and Tert mux for Mi2S interface * slave select to invalid state, for machine mode this * should move to HW, I do not like to do it here * Configure the secondary MI2S to TLMM. */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { Loading @@ -740,20 +779,127 @@ static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00030300; if (pdata->ext_pa) { /* enable sec MI2S interface to TLMM GPIO */ val = val | 0x0004007E; pr_debug("%s: mux configuration = %x\n", __func__, val); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.ext_pa_act); pr_debug("%s: Sec mux configuration = %x\n", __func__, val); iowrite32(val, vaddr); iounmap(vaddr); vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_MIC_CTL); return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00200000; iowrite32(val, vaddr); iounmap(vaddr); return ret; } static int msm_sec_mi2s_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { pr_info("%s: Secondary Mi2s does not support capture\n", __func__); return 0; } if (!pdata->codec_type && ((pdata->ext_pa & SEC_MI2S_ID) == SEC_MI2S_ID)) { ret = conf_int_codec_mux_sec(pdata); if (ret < 0) { pr_err("%s: Failed to configure the ext pa gpio's\n", pr_err("%s: failed to conf internal codec mux\n", __func__); iounmap(vaddr); return ret; } ret = msm8x16_enable_codec_ext_clk(codec, 1, true); if (ret < 0) { pr_err("failed to enable mclk\n"); return ret; } ret = sec_mi2s_sclk_ctl(substream, true); if (ret < 0) { pr_err("failed to enable sclk\n"); goto err; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_lines_act); if (ret < 0) { pr_err("failed to enable codec gpios\n"); goto err1; } } else { pr_err("%s: error codec type\n", __func__); } ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) pr_debug("%s: set fmt cpu dai failed\n", __func__); return ret; err1: ret = sec_mi2s_sclk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); err: ret = msm8x16_enable_codec_ext_clk(codec, 0, true); if (ret < 0) pr_err("failed to disable mclk\n"); return ret; } static void msm_sec_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if ((!pdata->codec_type) && ((pdata->ext_pa & SEC_MI2S_ID) == SEC_MI2S_ID)) { ret = sec_mi2s_sclk_ctl(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); if (atomic_read(&pdata->mclk_rsc_ref) > 0) { atomic_dec(&pdata->mclk_rsc_ref); pr_debug("%s: decrementing mclk_res_ref %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref)); } } } static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) { int ret = 0; int val = 0; void __iomem *vaddr = NULL; /* *configure the Primary, Sec and Tert mux for Mi2S interface * slave select to invalid state, for machine mode this * should move to HW, I do not like to do it here */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00030300; iowrite32(val, vaddr); iounmap(vaddr); vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); Loading @@ -763,13 +909,18 @@ static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00200000; val = val | 0x00220002; vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_MIC_CTL); return -ENOMEM; } iowrite32(val, vaddr); iounmap(vaddr); return ret; } static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; Loading Loading @@ -802,13 +953,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) pr_err("failed to enable mclk\n"); return ret; } /* Reset the CDC PDM TLMM pins to a default state */ /* Enable the codec mclk config */ msm8x16_wcd_mclk_enable(codec, 1, true); ret = mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s failed to enable the sclk %x\n", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_act); if (ret != 0) { pr_err("%s: Failed to enable CDC PDM pins %d\n", __func__, ret); return ret; pinctrl_info.cdc_lines_act); if (ret < 0) { pr_err("%s: failed to active cdc gpio's\n", __func__); return -EINVAL; } } else { /* configure Quatarnary Mi2S interface SCLK, WS, Data 0 Loading @@ -817,8 +976,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { pr_err("%s: ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); pr_err("%s ioremap failure for addr %x\n", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } val = ioread32(vaddr); Loading Loading @@ -962,6 +1122,12 @@ static int msm_audrx_init_wcd(struct snd_soc_pcm_runtime *rtd) return ret; } static struct snd_soc_ops msm8x16_sec_mi2s_be_ops = { .startup = msm_sec_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, .shutdown = msm_sec_mi2s_snd_shutdown, }; static struct snd_soc_ops msm8x16_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, Loading Loading @@ -1424,13 +1590,12 @@ static struct snd_soc_dai_link msm8x16_dai[] = { .stream_name = "Secondary MI2S Playback", .cpu_dai_name = "msm-dai-q6-mi2s.1", .platform_name = "msm-pcm-routing", .codec_name = MSM8X16_CODEC_NAME, .codec_dai_name = "msm8x16_wcd_i2s_rx1", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, .init = &msm_audrx_init, .be_hw_params_fixup = msm_be_hw_params_fixup, .ops = &msm8x16_mi2s_be_ops, .ops = &msm8x16_sec_mi2s_be_ops, .ignore_suspend = 1, }, { Loading Loading @@ -1617,37 +1782,6 @@ static struct snd_soc_card bear_cards[MAX_SND_CARDS] = { }, }; static int cdc_pdm_get_pinctrl(struct platform_device *pdev) { struct pinctrl *pinctrl; int ret; pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(pinctrl)) { pr_err("%s: Unable to get pinctrl handle\n", __func__); return -EINVAL; } pinctrl_info.pinctrl = pinctrl; /* get all the states handles from Device Tree*/ pinctrl_info.cdc_pdm_sus = pinctrl_lookup_state(pinctrl, "cdc_pdm_lines_sus"); pinctrl_info.cdc_pdm_act = pinctrl_lookup_state(pinctrl, "cdc_pdm_lines_act"); if (IS_ERR(pinctrl_info.cdc_pdm_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } /* Reset the CDC PDM TLMM pins to a default state */ ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_sus); if (ret != 0) { pr_err("%s: Failed to disable the TLMM pins\n", __func__); return -EIO; } return 0; } void enable_mclk(struct work_struct *work) { struct msm8916_asoc_mach_data *pdata = NULL; Loading Loading @@ -1745,7 +1879,48 @@ static int msm8x16_setup_hs_jack(struct platform_device *pdev, return 0; } static int populate_ext_snd_card_dt_data(struct platform_device *pdev) int get_cdc_gpio_lines(struct pinctrl *pinctrl, int ext_pa) { pr_debug("%s\n", __func__); switch (ext_pa & SEC_MI2S_ID) { case SEC_MI2S_ID: pinctrl_info.cdc_lines_sus = pinctrl_lookup_state(pinctrl, "cdc_lines_sec_ext_sus"); if (IS_ERR(pinctrl_info.cdc_lines_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cdc_lines_act = pinctrl_lookup_state(pinctrl, "cdc_lines_sec_ext_act"); if (IS_ERR(pinctrl_info.cdc_lines_act)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } break; default: pinctrl_info.cdc_lines_sus = pinctrl_lookup_state(pinctrl, "cdc_lines_sus"); if (IS_ERR(pinctrl_info.cdc_lines_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cdc_lines_act = pinctrl_lookup_state(pinctrl, "cdc_lines_act"); if (IS_ERR(pinctrl_info.cdc_lines_act)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pr_debug("%s: no external PA connected %d\n", __func__, ext_pa); break; } return 0; } int populate_ext_snd_card_dt_data(struct platform_device *pdev) { struct pinctrl *pinctrl; int ret; Loading Loading @@ -1818,7 +1993,9 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) const char *mclk = "qcom,msm-mclk-freq"; const char *ptr = NULL; const char *type = NULL; int ret, id; const char *ext_pa_str = NULL; int num_strings; int ret, id, i; pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm8916_asoc_mach_data), GFP_KERNEL); Loading Loading @@ -1882,24 +2059,37 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) bear_cards[pdev->id].name = dev_name(&pdev->dev); card = &bear_cards[pdev->id]; } else { ret = cdc_pdm_get_pinctrl(pdev); if (ret < 0) { pr_err("failed to get the pdm gpios; ret=%d\n", ret); goto err; } card = &bear_cards[pdev->id]; bear_cards[pdev->id].name = dev_name(&pdev->dev); card = &bear_cards[pdev->id]; dev_info(&pdev->dev, "default codec configured\n"); pdata->codec_type = 0; ret = of_property_read_u32(pdev->dev.of_node, ext_pa, &id); if (ret) { num_strings = of_property_count_strings(pdev->dev.of_node, ext_pa); if (num_strings < 0) { dev_err(&pdev->dev, "%s: missing %s in dt node\n", "%s: missing %s in dt node or length is incorrect\n", __func__, ext_pa); goto err; } pdata->ext_pa = id; if (pdata->ext_pa) { for (i = 0; i < num_strings; i++) { ret = of_property_read_string_index(pdev->dev.of_node, ext_pa, i, &ext_pa_str); if (ret) { dev_err(&pdev->dev, "%s:of read string %s i %d error %d\n", __func__, ext_pa, i, ret); goto err; } if (!strcmp(ext_pa_str, "primary")) pdata->ext_pa = (pdata->ext_pa | PRI_MI2S_ID); else if (!strcmp(ext_pa_str, "secondary")) pdata->ext_pa = (pdata->ext_pa | SEC_MI2S_ID); else if (!strcmp(ext_pa_str, "tertiary")) pdata->ext_pa = (pdata->ext_pa | TER_MI2S_ID); else if (!strcmp(ext_pa_str, "quaternary")) pdata->ext_pa = (pdata->ext_pa | QUAT_MI2S_ID); } pr_debug("%s: ext_pa = %d\n", __func__, pdata->ext_pa); pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(pinctrl)) { pr_err("%s: Unable to get pinctrl handle\n", Loading @@ -1907,22 +2097,11 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) return -EINVAL; } pinctrl_info.pinctrl = pinctrl; /* get pinctrl handle for ext_pa */ pinctrl_info.ext_pa_sus = pinctrl_lookup_state(pinctrl, "cdc_ext_pa_sus"); if (IS_ERR(pinctrl_info.ext_pa_sus)) { pr_err("%s: Unable to get pinctrl disable handle\n", __func__); return -EINVAL; } /* get pinctrl handle for ext_pa */ pinctrl_info.ext_pa_act = pinctrl_lookup_state(pinctrl, "cdc_ext_pa_act"); if (IS_ERR(pinctrl_info.ext_pa_act)) { pr_err("%s: Unable to get pinctrl disable handle\n", __func__); return -EINVAL; } ret = get_cdc_gpio_lines(pinctrl, pdata->ext_pa); if (ret < 0) { pr_err("%s: failed to ger the codec gpio's %d\n", __func__, ret); goto err; } } Loading @@ -1947,11 +2126,6 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) pdata->digital_cdc_clk.clk_val = pdata->mclk_freq; pdata->digital_cdc_clk.clk_root = 5; pdata->digital_cdc_clk.reserved = 0; ret = cdc_pdm_get_pinctrl(pdev); if (ret < 0) { pr_err("failed to get the pdm gpios\n"); goto err; } msm8x16_setup_hs_jack(pdev, pdata); Loading Loading
Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +6 −2 Original line number Diff line number Diff line Loading @@ -524,8 +524,12 @@ Required properties: - qcom,msm-hs-micbias-type : This property is used to recognize the headset micbias type, internal or external. - qcom,msm-ext-pa : This property is used to inform machine driver about the connection of external PA over secondary MI2S interface, val 0 external PA is not there, Val 1 external PA is connected. the connection of external PA over available MI2S interfaces, following values can be given to this property. primary -> Primary MI2S interface secondary -> Secondary MI2S interface tertiary -> Tertiary MI2S interface quaternary -> Quaternary MI2S interface - qcom,msm-mclk-freq : This property is used to inform machine driver about mclk frequency needs to be configured for internal and external PA. - qcom,msm-mbhc-hphl-swh: This property is used to distinguish headset HPHL Loading
arch/arm/boot/dts/qcom/msm8916-cdp.dtsi +9 −7 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ qcom,model = "msm8x16-snd-card"; qcom,msm-snd-card-id = <0>; qcom,msm-codec-type = "internal"; qcom,msm-ext-pa = <0>; qcom,msm-ext-pa = "primary"; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,msm-mclk-freq = <9600000>; Loading @@ -215,14 +215,16 @@ "AMIC1", "MIC BIAS Internal1", "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS Internal3"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus", "cdc_ext_pa_act", "cdc_ext_pa_sus"; pinctrl-names = "cdc_lines_act", "cdc_lines_sus", "cdc_lines_sec_ext_act", "cdc_lines_sec_ext_sus"; pinctrl-0 = <&cdc_pdm_lines_act>; pinctrl-1 = <&cdc_pdm_lines_sus>; pinctrl-2 = <&cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; pinctrl-2 = <&cdc_pdm_lines_act &cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_pdm_lines_sus &cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; }; sound-9306 { Loading
arch/arm/boot/dts/qcom/msm8916-mtp.dtsi +11 −5 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ qcom,model = "msm8x16-snd-card-mtp"; qcom,msm-snd-card-id = <0>; qcom,msm-codec-type = "internal"; qcom,msm-ext-pa = <0>; qcom,msm-ext-pa = "primary"; qcom,msm-mclk-freq = <9600000>; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; Loading @@ -146,14 +146,20 @@ "AMIC1", "MIC BIAS External", "AMIC2", "MIC BIAS Internal2", "AMIC3", "MIC BIAS External"; pinctrl-names = "cdc_pdm_lines_act", "cdc_pdm_lines_sus", pinctrl-names = "cdc_lines_act", "cdc_lines_sus", "cdc_lines_sec_ext_act", "cdc_lines_sec_ext_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>; pinctrl-2 = <&cdc_pdm_lines_act &cdc_ext_pa_act &cdc_ext_pa_ws_act>; pinctrl-3 = <&cdc_pdm_lines_sus &cdc_ext_pa_sus &cdc_ext_pa_ws_sus>; pinctrl-4 = <&cross_conn_det_act>; pinctrl-5 = <&cross_conn_det_sus>; qcom,cdc-us-euro-gpios = <&msm_gpio 120 0>; }; }; Loading
sound/soc/msm/msm8x16.c +280 −106 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ #define BTSCO_RATE_16KHZ 16000 #define MAX_SND_CARDS 3 #define PRI_MI2S_ID (1 << 0) #define SEC_MI2S_ID (1 << 1) #define TER_MI2S_ID (1 << 2) #define QUAT_MI2S_ID (1 << 3) #define LPASS_CSR_GP_IO_MUX_MIC_CTL 0x07702000 #define LPASS_CSR_GP_IO_MUX_SPKR_CTL 0x07702004 Loading Loading @@ -189,12 +194,10 @@ static struct afe_clk_cfg mi2s_tx_clk = { struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_pdm_sus; struct pinctrl_state *cdc_pdm_act; struct pinctrl_state *cdc_lines_sus; struct pinctrl_state *cdc_lines_act; struct pinctrl_state *cross_conn_det_sus; struct pinctrl_state *cross_conn_det_act; struct pinctrl_state *ext_pa_sus; struct pinctrl_state *ext_pa_act; }; struct ext_cdc_tlmm_pinctrl_info { Loading Loading @@ -467,6 +470,40 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } return ret; } static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; Loading Loading @@ -577,10 +614,8 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, atomic_set(&pdata->dis_work_mclk, true); } mutex_unlock(&pdata->cdc_mclk_mutex); msm8x16_wcd_mclk_enable(codec, 1, dapm); } } else { msm8x16_wcd_mclk_enable(codec, 0, dapm); mutex_lock(&pdata->cdc_mclk_mutex); atomic_set(&pdata->mclk_rsc_ref, 0); cancel_delayed_work_sync(&pdata->enable_mclk_work); Loading Loading @@ -659,6 +694,7 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct msm8916_asoc_mach_data *pdata = NULL; int ret = 0; pdata = snd_soc_card_get_drvdata(w->codec->card); pr_debug("%s: event = %d\n", __func__, event); Loading @@ -669,9 +705,14 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, if (!pdata->codec_type) { if (atomic_read(&pdata->mclk_rsc_ref) == 0) { pr_debug("%s: disabling MCLK\n", __func__); /* disable the codec mclk config*/ msm8x16_wcd_mclk_enable(w->codec, 0, true); msm8x16_enable_codec_ext_clk(w->codec, 0, true); pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_sus); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_lines_sus); if (ret < 0) pr_err("%s: error during pinctrl state select\n", __func__); } } break; Loading Loading @@ -722,16 +763,14 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) } } static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) static int conf_int_codec_mux_sec(struct msm8916_asoc_mach_data *pdata) { int ret = 0; int val = 0; void __iomem *vaddr = NULL; /* *configure the Primary, Sec and Tert mux for Mi2S interface * slave select to invalid state, for machine mode this * should move to HW, I do not like to do it here * Configure the secondary MI2S to TLMM. */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { Loading @@ -740,20 +779,127 @@ static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00030300; if (pdata->ext_pa) { /* enable sec MI2S interface to TLMM GPIO */ val = val | 0x0004007E; pr_debug("%s: mux configuration = %x\n", __func__, val); ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.ext_pa_act); pr_debug("%s: Sec mux configuration = %x\n", __func__, val); iowrite32(val, vaddr); iounmap(vaddr); vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_MIC_CTL); return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00200000; iowrite32(val, vaddr); iounmap(vaddr); return ret; } static int msm_sec_mi2s_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { pr_info("%s: Secondary Mi2s does not support capture\n", __func__); return 0; } if (!pdata->codec_type && ((pdata->ext_pa & SEC_MI2S_ID) == SEC_MI2S_ID)) { ret = conf_int_codec_mux_sec(pdata); if (ret < 0) { pr_err("%s: Failed to configure the ext pa gpio's\n", pr_err("%s: failed to conf internal codec mux\n", __func__); iounmap(vaddr); return ret; } ret = msm8x16_enable_codec_ext_clk(codec, 1, true); if (ret < 0) { pr_err("failed to enable mclk\n"); return ret; } ret = sec_mi2s_sclk_ctl(substream, true); if (ret < 0) { pr_err("failed to enable sclk\n"); goto err; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_lines_act); if (ret < 0) { pr_err("failed to enable codec gpios\n"); goto err1; } } else { pr_err("%s: error codec type\n", __func__); } ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) pr_debug("%s: set fmt cpu dai failed\n", __func__); return ret; err1: ret = sec_mi2s_sclk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); err: ret = msm8x16_enable_codec_ext_clk(codec, 0, true); if (ret < 0) pr_err("failed to disable mclk\n"); return ret; } static void msm_sec_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if ((!pdata->codec_type) && ((pdata->ext_pa & SEC_MI2S_ID) == SEC_MI2S_ID)) { ret = sec_mi2s_sclk_ctl(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); if (atomic_read(&pdata->mclk_rsc_ref) > 0) { atomic_dec(&pdata->mclk_rsc_ref); pr_debug("%s: decrementing mclk_res_ref %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref)); } } } static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) { int ret = 0; int val = 0; void __iomem *vaddr = NULL; /* *configure the Primary, Sec and Tert mux for Mi2S interface * slave select to invalid state, for machine mode this * should move to HW, I do not like to do it here */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00030300; iowrite32(val, vaddr); iounmap(vaddr); vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); Loading @@ -763,13 +909,18 @@ static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata) return -ENOMEM; } val = ioread32(vaddr); val = val | 0x00200000; val = val | 0x00220002; vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4); if (!vaddr) { pr_err("%s ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_MIC_CTL); return -ENOMEM; } iowrite32(val, vaddr); iounmap(vaddr); return ret; } static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; Loading Loading @@ -802,13 +953,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) pr_err("failed to enable mclk\n"); return ret; } /* Reset the CDC PDM TLMM pins to a default state */ /* Enable the codec mclk config */ msm8x16_wcd_mclk_enable(codec, 1, true); ret = mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s failed to enable the sclk %x\n", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_act); if (ret != 0) { pr_err("%s: Failed to enable CDC PDM pins %d\n", __func__, ret); return ret; pinctrl_info.cdc_lines_act); if (ret < 0) { pr_err("%s: failed to active cdc gpio's\n", __func__); return -EINVAL; } } else { /* configure Quatarnary Mi2S interface SCLK, WS, Data 0 Loading @@ -817,8 +976,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) */ vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); if (!vaddr) { pr_err("%s: ioremap failure for addr %x", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); pr_err("%s ioremap failure for addr %x\n", __func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL); return -ENOMEM; } val = ioread32(vaddr); Loading Loading @@ -962,6 +1122,12 @@ static int msm_audrx_init_wcd(struct snd_soc_pcm_runtime *rtd) return ret; } static struct snd_soc_ops msm8x16_sec_mi2s_be_ops = { .startup = msm_sec_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, .shutdown = msm_sec_mi2s_snd_shutdown, }; static struct snd_soc_ops msm8x16_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, Loading Loading @@ -1424,13 +1590,12 @@ static struct snd_soc_dai_link msm8x16_dai[] = { .stream_name = "Secondary MI2S Playback", .cpu_dai_name = "msm-dai-q6-mi2s.1", .platform_name = "msm-pcm-routing", .codec_name = MSM8X16_CODEC_NAME, .codec_dai_name = "msm8x16_wcd_i2s_rx1", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, .init = &msm_audrx_init, .be_hw_params_fixup = msm_be_hw_params_fixup, .ops = &msm8x16_mi2s_be_ops, .ops = &msm8x16_sec_mi2s_be_ops, .ignore_suspend = 1, }, { Loading Loading @@ -1617,37 +1782,6 @@ static struct snd_soc_card bear_cards[MAX_SND_CARDS] = { }, }; static int cdc_pdm_get_pinctrl(struct platform_device *pdev) { struct pinctrl *pinctrl; int ret; pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(pinctrl)) { pr_err("%s: Unable to get pinctrl handle\n", __func__); return -EINVAL; } pinctrl_info.pinctrl = pinctrl; /* get all the states handles from Device Tree*/ pinctrl_info.cdc_pdm_sus = pinctrl_lookup_state(pinctrl, "cdc_pdm_lines_sus"); pinctrl_info.cdc_pdm_act = pinctrl_lookup_state(pinctrl, "cdc_pdm_lines_act"); if (IS_ERR(pinctrl_info.cdc_pdm_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } /* Reset the CDC PDM TLMM pins to a default state */ ret = pinctrl_select_state(pinctrl_info.pinctrl, pinctrl_info.cdc_pdm_sus); if (ret != 0) { pr_err("%s: Failed to disable the TLMM pins\n", __func__); return -EIO; } return 0; } void enable_mclk(struct work_struct *work) { struct msm8916_asoc_mach_data *pdata = NULL; Loading Loading @@ -1745,7 +1879,48 @@ static int msm8x16_setup_hs_jack(struct platform_device *pdev, return 0; } static int populate_ext_snd_card_dt_data(struct platform_device *pdev) int get_cdc_gpio_lines(struct pinctrl *pinctrl, int ext_pa) { pr_debug("%s\n", __func__); switch (ext_pa & SEC_MI2S_ID) { case SEC_MI2S_ID: pinctrl_info.cdc_lines_sus = pinctrl_lookup_state(pinctrl, "cdc_lines_sec_ext_sus"); if (IS_ERR(pinctrl_info.cdc_lines_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cdc_lines_act = pinctrl_lookup_state(pinctrl, "cdc_lines_sec_ext_act"); if (IS_ERR(pinctrl_info.cdc_lines_act)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } break; default: pinctrl_info.cdc_lines_sus = pinctrl_lookup_state(pinctrl, "cdc_lines_sus"); if (IS_ERR(pinctrl_info.cdc_lines_sus)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pinctrl_info.cdc_lines_act = pinctrl_lookup_state(pinctrl, "cdc_lines_act"); if (IS_ERR(pinctrl_info.cdc_lines_act)) { pr_err("%s: Unable to get pinctrl disable state handle\n", __func__); return -EINVAL; } pr_debug("%s: no external PA connected %d\n", __func__, ext_pa); break; } return 0; } int populate_ext_snd_card_dt_data(struct platform_device *pdev) { struct pinctrl *pinctrl; int ret; Loading Loading @@ -1818,7 +1993,9 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) const char *mclk = "qcom,msm-mclk-freq"; const char *ptr = NULL; const char *type = NULL; int ret, id; const char *ext_pa_str = NULL; int num_strings; int ret, id, i; pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm8916_asoc_mach_data), GFP_KERNEL); Loading Loading @@ -1882,24 +2059,37 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) bear_cards[pdev->id].name = dev_name(&pdev->dev); card = &bear_cards[pdev->id]; } else { ret = cdc_pdm_get_pinctrl(pdev); if (ret < 0) { pr_err("failed to get the pdm gpios; ret=%d\n", ret); goto err; } card = &bear_cards[pdev->id]; bear_cards[pdev->id].name = dev_name(&pdev->dev); card = &bear_cards[pdev->id]; dev_info(&pdev->dev, "default codec configured\n"); pdata->codec_type = 0; ret = of_property_read_u32(pdev->dev.of_node, ext_pa, &id); if (ret) { num_strings = of_property_count_strings(pdev->dev.of_node, ext_pa); if (num_strings < 0) { dev_err(&pdev->dev, "%s: missing %s in dt node\n", "%s: missing %s in dt node or length is incorrect\n", __func__, ext_pa); goto err; } pdata->ext_pa = id; if (pdata->ext_pa) { for (i = 0; i < num_strings; i++) { ret = of_property_read_string_index(pdev->dev.of_node, ext_pa, i, &ext_pa_str); if (ret) { dev_err(&pdev->dev, "%s:of read string %s i %d error %d\n", __func__, ext_pa, i, ret); goto err; } if (!strcmp(ext_pa_str, "primary")) pdata->ext_pa = (pdata->ext_pa | PRI_MI2S_ID); else if (!strcmp(ext_pa_str, "secondary")) pdata->ext_pa = (pdata->ext_pa | SEC_MI2S_ID); else if (!strcmp(ext_pa_str, "tertiary")) pdata->ext_pa = (pdata->ext_pa | TER_MI2S_ID); else if (!strcmp(ext_pa_str, "quaternary")) pdata->ext_pa = (pdata->ext_pa | QUAT_MI2S_ID); } pr_debug("%s: ext_pa = %d\n", __func__, pdata->ext_pa); pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(pinctrl)) { pr_err("%s: Unable to get pinctrl handle\n", Loading @@ -1907,22 +2097,11 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) return -EINVAL; } pinctrl_info.pinctrl = pinctrl; /* get pinctrl handle for ext_pa */ pinctrl_info.ext_pa_sus = pinctrl_lookup_state(pinctrl, "cdc_ext_pa_sus"); if (IS_ERR(pinctrl_info.ext_pa_sus)) { pr_err("%s: Unable to get pinctrl disable handle\n", __func__); return -EINVAL; } /* get pinctrl handle for ext_pa */ pinctrl_info.ext_pa_act = pinctrl_lookup_state(pinctrl, "cdc_ext_pa_act"); if (IS_ERR(pinctrl_info.ext_pa_act)) { pr_err("%s: Unable to get pinctrl disable handle\n", __func__); return -EINVAL; } ret = get_cdc_gpio_lines(pinctrl, pdata->ext_pa); if (ret < 0) { pr_err("%s: failed to ger the codec gpio's %d\n", __func__, ret); goto err; } } Loading @@ -1947,11 +2126,6 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) pdata->digital_cdc_clk.clk_val = pdata->mclk_freq; pdata->digital_cdc_clk.clk_root = 5; pdata->digital_cdc_clk.reserved = 0; ret = cdc_pdm_get_pinctrl(pdev); if (ret < 0) { pr_err("failed to get the pdm gpios\n"); goto err; } msm8x16_setup_hs_jack(pdev, pdata); Loading