Loading sound/soc/codecs/audio-ext-clk.c +83 −24 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ struct audio_ext_ap_clk2 { struct audio_ext_lpass_mclk { struct pinctrl_info pnctrl_info; struct clk c; u32 lpass_clock; void __iomem *lpass_csr_gpio_mux_spkrctl_vaddr; }; static struct afe_clk_set clk2_config = { Loading Loading @@ -87,6 +89,15 @@ static struct afe_clk_set lpass_default2 = { 0, }; static struct afe_clk_set digital_cdc_core_clk = { Q6AFE_LPASS_CLK_CONFIG_API_VERSION, Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, }; static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk) { return container_of(clk, struct audio_ext_ap_clk, c); Loading Loading @@ -163,7 +174,7 @@ static int audio_ext_lpass_mclk_prepare(struct clk *clk) struct audio_ext_lpass_mclk *audio_lpass_mclk; struct pinctrl_info *pnctrl_info; struct afe_clk_cfg *lpass_clk = NULL; int ret; int ret, val = 0; audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c); pnctrl_info = &audio_lpass_mclk->pnctrl_info; Loading @@ -179,21 +190,41 @@ static int audio_ext_lpass_mclk_prepare(struct clk *clk) pr_err("%s: active state select failed with %d\n", __func__, ret); ret = -EIO; goto err; goto done; } } if (!audio_lpass_mclk->lpass_clock) { memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg)); lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ; lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); if (ret < 0) { pr_err("%s afe_set_lpass_clock failed, ret = %d\n", __func__, ret); kfree(lpass_clk); return -EINVAL; } err: } else { if (audio_lpass_mclk->lpass_csr_gpio_mux_spkrctl_vaddr) { val = ioread32(audio_lpass_mclk-> lpass_csr_gpio_mux_spkrctl_vaddr); val = val | 0x00000002; iowrite32(val, audio_lpass_mclk-> lpass_csr_gpio_mux_spkrctl_vaddr); } digital_cdc_core_clk.enable = 1; ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &digital_cdc_core_clk); if (ret < 0) { pr_err("%s afe_set_digital_codec_core_clock failed\n", __func__); kfree(lpass_clk); return ret; } } done: kfree(lpass_clk); return 0; } Loading @@ -214,7 +245,7 @@ static void audio_ext_lpass_mclk_unprepare(struct clk *clk) if (pnctrl_info->pinctrl) { ret = pinctrl_select_state(pnctrl_info->pinctrl, pnctrl_info->active); pnctrl_info->sleep); if (ret) { pr_err("%s: active state select failed with %d\n", __func__, ret); Loading @@ -222,14 +253,24 @@ static void audio_ext_lpass_mclk_unprepare(struct clk *clk) goto err; } } if (!audio_lpass_mclk->lpass_clock) { memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg)); lpass_clk->clk_val2 = 0; lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); if (ret < 0) pr_err("%s: afe_set_lpass_clock failed, ret = %d\n", __func__, ret); } else { digital_cdc_core_clk.enable = 0; ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &digital_cdc_core_clk); if (ret < 0) pr_err("%s: afe_set_digital_codec_core_clock failed, ret = %d\n", __func__, ret); } err: kfree(lpass_clk); } Loading Loading @@ -437,11 +478,26 @@ static int audio_ref_clk_probe(struct platform_device *pdev) u32 mclk_freq; const char *mclk_id = "qcom,lpass-mclk-id"; const char *mclk_str = NULL; u32 lpass_csr_gpio_mux_spkrctl_reg = 0; ret = of_property_read_u32(pdev->dev.of_node, "qcom,lpass-clock", &audio_lpass_mclk.lpass_clock); if (ret) dev_dbg(&pdev->dev, "%s: qcom,lpass-clock is undefined\n", __func__); ret = of_property_read_u32(pdev->dev.of_node, "qcom,codec-mclk-clk-freq", &mclk_freq); if (!ret && mclk_freq == 12288000) { if (!ret && (mclk_freq == 12288000 || audio_lpass_mclk.lpass_clock)) { ret = of_property_read_u32(pdev->dev.of_node, "reg", &lpass_csr_gpio_mux_spkrctl_reg); if (!ret) { audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr = ioremap(lpass_csr_gpio_mux_spkrctl_reg, 4); } ret = audio_get_pinctrl(pdev, LPASS_MCLK); if (ret) dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n", Loading Loading @@ -548,6 +604,9 @@ static int audio_ref_clk_remove(struct platform_device *pdev) pnctrl_info->pinctrl = NULL; } if (audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr) iounmap(audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr); return 0; } Loading sound/soc/msm/apq8009-i2s-ext-codec.c +112 −48 Original line number Diff line number Diff line Loading @@ -164,23 +164,21 @@ static void *def_tasha_mbhc_cal(void) return tasha_wcd_cal; } static struct afe_clk_cfg mi2s_rx_clk = { static struct afe_clk_set mi2s_tx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, Q6AFE_LPASS_CLK_SRC_INTERNAL, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, Q6AFE_LPASS_MODE_CLK1_VALID, 0, }; static struct afe_clk_cfg mi2s_tx_clk = { static struct afe_clk_set mi2s_rx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, Q6AFE_LPASS_CLK_SRC_INTERNAL, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, Q6AFE_LPASS_MODE_CLK1_VALID, 0, }; Loading Loading @@ -541,20 +539,88 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, u16 port_id) static int apq8009_get_port_id(int be_id) { switch (be_id) { case MSM_BACKEND_DAI_PRI_MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: return AFE_PORT_ID_SECONDARY_MI2S_RX; case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: return AFE_PORT_ID_TERTIARY_MI2S_TX; case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: return AFE_PORT_ID_QUATERNARY_MI2S_RX; case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: return AFE_PORT_ID_QUATERNARY_MI2S_TX; case MSM_BACKEND_DAI_QUINARY_MI2S_RX: return AFE_PORT_ID_QUINARY_MI2S_RX; case MSM_BACKEND_DAI_QUINARY_MI2S_TX: return AFE_PORT_ID_QUINARY_MI2S_TX; case MSM_BACKEND_DAI_SENARY_MI2S_TX: return AFE_PORT_ID_SENARY_MI2S_TX; default: pr_err("%s: Invalid be_id: %d\n", __func__, be_id); return -EINVAL; } } static int apq8009_get_clk_id(int port_id) { switch (port_id) { case AFE_PORT_ID_PRIMARY_MI2S_RX: return Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT; case AFE_PORT_ID_SECONDARY_MI2S_RX: return Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT; case AFE_PORT_ID_TERTIARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT; case AFE_PORT_ID_QUATERNARY_MI2S_RX: case AFE_PORT_ID_QUATERNARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT; case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT; case AFE_PORT_ID_SENARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT; default: pr_err("%s: invalid port_id: 0x%x\n", __func__, port_id); return -EINVAL; } } static uint32_t get_mi2s_rx_clk_val(void) { uint32_t clk_val; clk_val = pri_rx_sample_rate * bits_per_sample * 2; return clk_val; } static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; u32 clk_val; int port_id = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; port_id = apq8009_get_port_id(rtd->dai_link->be_id); if (port_id < 0) { pr_err("%s: Invalid port_id\n", __func__); return -EINVAL; } if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { clk_val = pri_rx_sample_rate * bits_per_sample * 2; mi2s_rx_clk.clk_val1 = clk_val; ret = afe_set_lpass_clock(port_id, &mi2s_rx_clk); mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_rx_clk.clk_freq_in_hz = get_mi2s_rx_clk_val(); ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(port_id, &mi2s_tx_clk); mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_tx_clk.clk_freq_in_hz = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); } else pr_err("%s:Not valid substream.\n", __func__); Loading @@ -563,11 +629,15 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, __func__, ret); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(port_id, &mi2s_rx_clk); mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_rx_clk.clk_freq_in_hz = 0; ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(port_id, &mi2s_tx_clk); mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_tx_clk.clk_freq_in_hz = 0; ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); } else pr_err("%s:Not valid substream %d\n", __func__, substream->stream); Loading Loading @@ -699,12 +769,11 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) val = val|0x2020002; iowrite32(val, vaddr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_QUATERNARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s: failed to enable sclk\n", __func__); return ret; } ret = msm_gpioset_activate(CLIENT_WCD_EXT, "quat_i2s"); if (ret < 0) { Loading @@ -720,8 +789,7 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) } return ret; err: ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); return ret; Loading @@ -734,12 +802,11 @@ static void msm_quat_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); atomic_dec_return(&quat_mi2s_clk_ref); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s: failed to disable sclk\n", __func__); ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "quat_i2s"); if (ret < 0) pr_err("%s: gpio set cannot be de-activated %sd", Loading Loading @@ -768,12 +835,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) val = val | 0x00000002; iowrite32(val, vaddr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_PRIMARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s: failed to enable sclk\n", __func__); return ret; } ret = msm_gpioset_activate(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) { Loading @@ -790,8 +856,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) } return ret; err: ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); return ret; Loading @@ -804,12 +869,11 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); atomic_dec_return(&pri_mi2s_clk_ref); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s: failed to enable sclk\n", __func__); ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) pr_err("%s: gpio set cannot be de-activated %sd", Loading sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +18 −0 Original line number Diff line number Diff line Loading @@ -6327,6 +6327,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "TERT_MI2S")) { *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; } else if (!strcmp(kcontrol->id.name + strlen(prefix), "QUATERNARY_MI2S")) { *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); Loading Loading @@ -6531,6 +6534,21 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Sound Focus Audio Tx QUATERNARY_MI2S", .info = msm_sound_focus_info, .get = msm_audio_sound_focus_get, .put = msm_audio_sound_focus_put, }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Source Tracking Audio Tx QUATERNARY_MI2S", .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, Loading Loading
sound/soc/codecs/audio-ext-clk.c +83 −24 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ struct audio_ext_ap_clk2 { struct audio_ext_lpass_mclk { struct pinctrl_info pnctrl_info; struct clk c; u32 lpass_clock; void __iomem *lpass_csr_gpio_mux_spkrctl_vaddr; }; static struct afe_clk_set clk2_config = { Loading Loading @@ -87,6 +89,15 @@ static struct afe_clk_set lpass_default2 = { 0, }; static struct afe_clk_set digital_cdc_core_clk = { Q6AFE_LPASS_CLK_CONFIG_API_VERSION, Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, }; static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk) { return container_of(clk, struct audio_ext_ap_clk, c); Loading Loading @@ -163,7 +174,7 @@ static int audio_ext_lpass_mclk_prepare(struct clk *clk) struct audio_ext_lpass_mclk *audio_lpass_mclk; struct pinctrl_info *pnctrl_info; struct afe_clk_cfg *lpass_clk = NULL; int ret; int ret, val = 0; audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c); pnctrl_info = &audio_lpass_mclk->pnctrl_info; Loading @@ -179,21 +190,41 @@ static int audio_ext_lpass_mclk_prepare(struct clk *clk) pr_err("%s: active state select failed with %d\n", __func__, ret); ret = -EIO; goto err; goto done; } } if (!audio_lpass_mclk->lpass_clock) { memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg)); lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ; lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); if (ret < 0) { pr_err("%s afe_set_lpass_clock failed, ret = %d\n", __func__, ret); kfree(lpass_clk); return -EINVAL; } err: } else { if (audio_lpass_mclk->lpass_csr_gpio_mux_spkrctl_vaddr) { val = ioread32(audio_lpass_mclk-> lpass_csr_gpio_mux_spkrctl_vaddr); val = val | 0x00000002; iowrite32(val, audio_lpass_mclk-> lpass_csr_gpio_mux_spkrctl_vaddr); } digital_cdc_core_clk.enable = 1; ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &digital_cdc_core_clk); if (ret < 0) { pr_err("%s afe_set_digital_codec_core_clock failed\n", __func__); kfree(lpass_clk); return ret; } } done: kfree(lpass_clk); return 0; } Loading @@ -214,7 +245,7 @@ static void audio_ext_lpass_mclk_unprepare(struct clk *clk) if (pnctrl_info->pinctrl) { ret = pinctrl_select_state(pnctrl_info->pinctrl, pnctrl_info->active); pnctrl_info->sleep); if (ret) { pr_err("%s: active state select failed with %d\n", __func__, ret); Loading @@ -222,14 +253,24 @@ static void audio_ext_lpass_mclk_unprepare(struct clk *clk) goto err; } } if (!audio_lpass_mclk->lpass_clock) { memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg)); lpass_clk->clk_val2 = 0; lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, lpass_clk); if (ret < 0) pr_err("%s: afe_set_lpass_clock failed, ret = %d\n", __func__, ret); } else { digital_cdc_core_clk.enable = 0; ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &digital_cdc_core_clk); if (ret < 0) pr_err("%s: afe_set_digital_codec_core_clock failed, ret = %d\n", __func__, ret); } err: kfree(lpass_clk); } Loading Loading @@ -437,11 +478,26 @@ static int audio_ref_clk_probe(struct platform_device *pdev) u32 mclk_freq; const char *mclk_id = "qcom,lpass-mclk-id"; const char *mclk_str = NULL; u32 lpass_csr_gpio_mux_spkrctl_reg = 0; ret = of_property_read_u32(pdev->dev.of_node, "qcom,lpass-clock", &audio_lpass_mclk.lpass_clock); if (ret) dev_dbg(&pdev->dev, "%s: qcom,lpass-clock is undefined\n", __func__); ret = of_property_read_u32(pdev->dev.of_node, "qcom,codec-mclk-clk-freq", &mclk_freq); if (!ret && mclk_freq == 12288000) { if (!ret && (mclk_freq == 12288000 || audio_lpass_mclk.lpass_clock)) { ret = of_property_read_u32(pdev->dev.of_node, "reg", &lpass_csr_gpio_mux_spkrctl_reg); if (!ret) { audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr = ioremap(lpass_csr_gpio_mux_spkrctl_reg, 4); } ret = audio_get_pinctrl(pdev, LPASS_MCLK); if (ret) dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n", Loading Loading @@ -548,6 +604,9 @@ static int audio_ref_clk_remove(struct platform_device *pdev) pnctrl_info->pinctrl = NULL; } if (audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr) iounmap(audio_lpass_mclk.lpass_csr_gpio_mux_spkrctl_vaddr); return 0; } Loading
sound/soc/msm/apq8009-i2s-ext-codec.c +112 −48 Original line number Diff line number Diff line Loading @@ -164,23 +164,21 @@ static void *def_tasha_mbhc_cal(void) return tasha_wcd_cal; } static struct afe_clk_cfg mi2s_rx_clk = { static struct afe_clk_set mi2s_tx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, Q6AFE_LPASS_CLK_SRC_INTERNAL, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, Q6AFE_LPASS_MODE_CLK1_VALID, 0, }; static struct afe_clk_cfg mi2s_tx_clk = { static struct afe_clk_set mi2s_rx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, Q6AFE_LPASS_CLK_SRC_INTERNAL, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, Q6AFE_LPASS_MODE_CLK1_VALID, 0, }; Loading Loading @@ -541,20 +539,88 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, u16 port_id) static int apq8009_get_port_id(int be_id) { switch (be_id) { case MSM_BACKEND_DAI_PRI_MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: return AFE_PORT_ID_SECONDARY_MI2S_RX; case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: return AFE_PORT_ID_TERTIARY_MI2S_TX; case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: return AFE_PORT_ID_QUATERNARY_MI2S_RX; case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: return AFE_PORT_ID_QUATERNARY_MI2S_TX; case MSM_BACKEND_DAI_QUINARY_MI2S_RX: return AFE_PORT_ID_QUINARY_MI2S_RX; case MSM_BACKEND_DAI_QUINARY_MI2S_TX: return AFE_PORT_ID_QUINARY_MI2S_TX; case MSM_BACKEND_DAI_SENARY_MI2S_TX: return AFE_PORT_ID_SENARY_MI2S_TX; default: pr_err("%s: Invalid be_id: %d\n", __func__, be_id); return -EINVAL; } } static int apq8009_get_clk_id(int port_id) { switch (port_id) { case AFE_PORT_ID_PRIMARY_MI2S_RX: return Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT; case AFE_PORT_ID_SECONDARY_MI2S_RX: return Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT; case AFE_PORT_ID_TERTIARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT; case AFE_PORT_ID_QUATERNARY_MI2S_RX: case AFE_PORT_ID_QUATERNARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT; case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT; case AFE_PORT_ID_SENARY_MI2S_TX: return Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT; default: pr_err("%s: invalid port_id: 0x%x\n", __func__, port_id); return -EINVAL; } } static uint32_t get_mi2s_rx_clk_val(void) { uint32_t clk_val; clk_val = pri_rx_sample_rate * bits_per_sample * 2; return clk_val; } static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; u32 clk_val; int port_id = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; port_id = apq8009_get_port_id(rtd->dai_link->be_id); if (port_id < 0) { pr_err("%s: Invalid port_id\n", __func__); return -EINVAL; } if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { clk_val = pri_rx_sample_rate * bits_per_sample * 2; mi2s_rx_clk.clk_val1 = clk_val; ret = afe_set_lpass_clock(port_id, &mi2s_rx_clk); mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_rx_clk.clk_freq_in_hz = get_mi2s_rx_clk_val(); ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(port_id, &mi2s_tx_clk); mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_tx_clk.clk_freq_in_hz = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); } else pr_err("%s:Not valid substream.\n", __func__); Loading @@ -563,11 +629,15 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, __func__, ret); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(port_id, &mi2s_rx_clk); mi2s_rx_clk.enable = enable; mi2s_rx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_rx_clk.clk_freq_in_hz = 0; ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(port_id, &mi2s_tx_clk); mi2s_tx_clk.enable = enable; mi2s_tx_clk.clk_id = apq8009_get_clk_id(port_id); mi2s_tx_clk.clk_freq_in_hz = 0; ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); } else pr_err("%s:Not valid substream %d\n", __func__, substream->stream); Loading Loading @@ -699,12 +769,11 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) val = val|0x2020002; iowrite32(val, vaddr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_QUATERNARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s: failed to enable sclk\n", __func__); return ret; } ret = msm_gpioset_activate(CLIENT_WCD_EXT, "quat_i2s"); if (ret < 0) { Loading @@ -720,8 +789,7 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) } return ret; err: ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); return ret; Loading @@ -734,12 +802,11 @@ static void msm_quat_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); atomic_dec_return(&quat_mi2s_clk_ref); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_QUATERNARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s: failed to disable sclk\n", __func__); ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "quat_i2s"); if (ret < 0) pr_err("%s: gpio set cannot be de-activated %sd", Loading Loading @@ -768,12 +835,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) val = val | 0x00000002; iowrite32(val, vaddr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_PRIMARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = ext_mi2s_clk_ctl(substream, true, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { pr_err("%s: failed to enable sclk\n", __func__); return ret; } ret = msm_gpioset_activate(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) { Loading @@ -790,8 +856,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) } return ret; err: ret = ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("failed to disable sclk\n"); return ret; Loading @@ -804,12 +869,11 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); atomic_dec_return(&pri_mi2s_clk_ref); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_RX); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ext_mi2s_clk_ctl(substream, false, AFE_PORT_ID_PRIMARY_MI2S_TX); ret = ext_mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s: failed to enable sclk\n", __func__); ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) pr_err("%s: gpio set cannot be de-activated %sd", Loading
sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +18 −0 Original line number Diff line number Diff line Loading @@ -6327,6 +6327,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "TERT_MI2S")) { *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; } else if (!strcmp(kcontrol->id.name + strlen(prefix), "QUATERNARY_MI2S")) { *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); Loading Loading @@ -6531,6 +6534,21 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Sound Focus Audio Tx QUATERNARY_MI2S", .info = msm_sound_focus_info, .get = msm_audio_sound_focus_get, .put = msm_audio_sound_focus_put, }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Source Tracking Audio Tx QUATERNARY_MI2S", .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, Loading