diff --git a/asoc/sa8155.c b/asoc/sa8155.c index fbd96ecca74b..3d8b4605abb0 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -148,6 +148,10 @@ static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios", "qcom,hsif2-tdm-gpios", }; +static const char *const mclk_gpio_phandle[] = { "qcom,internal-mclk1-gpios" }; + +static bool mclk_enable_status = false; + enum { TDM_0 = 0, TDM_1, @@ -176,6 +180,11 @@ enum { TDM_INTERFACE_MAX, }; +enum { + MCLK1 = 0, + MCLK_MAX, +}; + struct tdm_port { u32 mode; u32 channel; @@ -937,6 +946,17 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static struct afe_clk_set internal_mclk[MCLK_MAX] = { + { + AFE_API_VERSION_CLOCK_SET_V2, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 1, + } +}; + static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, @@ -983,6 +1003,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { struct msm_asoc_mach_data { struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX]; + struct msm_pinctrl_info mclk_pinctrl_info[MCLK_MAX]; struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX]; }; @@ -5201,6 +5222,92 @@ err: return -EINVAL; } +static int msm_pinctrl_mclk_enable(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl = NULL; + int pinctrl_num; + int i, j; + struct device_node *np = NULL; + struct platform_device *pdev_np = NULL; + int ret = 0; + + pinctrl_num = MCLK_MAX; + for (i = 0; i < pinctrl_num; i++) { + + np = of_parse_phandle(pdev->dev.of_node, mclk_gpio_phandle[i], 0); + if (!np) { + pr_err("%s: device node %s is null\n", __func__, mclk_gpio_phandle[i]); + continue; + } + pdev_np = of_find_device_by_node(np); + if (!pdev_np) { + pr_err("%s: platform device not found\n", __func__); + continue; + } + + pinctrl_info = &pdata->mclk_pinctrl_info[i]; + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl info is null\n", __func__); + continue; + } + + pinctrl = devm_pinctrl_get(&pdev_np->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: fail to get pinctrl handle\n", __func__); + goto err; + } + pinctrl_info->pinctrl = pinctrl; + /* get all the states handles from Device Tree */ + pinctrl_info->sleep = pinctrl_lookup_state(pinctrl, + "sleep"); + if (IS_ERR(pinctrl_info->sleep)) { + pr_err("%s: could not get sleep pin state\n", __func__); + goto err; + } + pinctrl_info->active = pinctrl_lookup_state(pinctrl, + "default"); + if (IS_ERR(pinctrl_info->active)) { + pr_err("%s: could not get active pin state\n", __func__); + goto err; + } + + /* Reset the mclk pins to a active state */ + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START, + &internal_mclk[i]); + if (ret < 0) { + pr_err("%s: afe lpass clock failed to enable clock, err:%d\n", + __func__, ret); + ret = -EIO; + goto err; + } + mclk_enable_status = true; + ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->active); + if (ret != 0) { + pr_err("%s: set pin state to active failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_ACTIVE; + } + return 0; + +err: + for (j = i; j >= 0; j--) { + pinctrl_info = &pdata->mclk_pinctrl_info[i]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } + } + return -EINVAL; +} + static int msm_tdm_get_intf_idx(u16 id) { switch (id) { @@ -10568,6 +10675,7 @@ static int sa8155_ssr_enable(struct device *dev, void *data) struct platform_device *pdev = to_platform_device(dev); struct snd_soc_card *card = platform_get_drvdata(pdev); int ret = 0; + int i; if (!card) { dev_err(dev, "%s: card is NULL\n", __func__); @@ -10575,6 +10683,19 @@ static int sa8155_ssr_enable(struct device *dev, void *data) goto err; } + if (mclk_enable_status == true) { + for (i = 0; i < MCLK_MAX; i++) { + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START, + &internal_mclk[i]); + if (ret < 0) { + pr_err("%s: afe lpass clock failed to enable clock, err:%d\n", + __func__, ret); + ret = -EIO; + goto err; + } + } + } + dev_info(dev, "%s: setting snd_card to ONLINE\n", __func__); #if IS_ENABLED(CONFIG_AUDIO_QGKI) snd_soc_card_change_online_state(card, 1); @@ -10644,6 +10765,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) int ret; enum apr_subsys_state q6_state; static int first_probe = 1; + const struct of_device_id *match; if (first_probe) { place_marker("M - DRIVER Audio Init"); @@ -10725,6 +10847,24 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) ret = 0; } + match = of_match_node(sa8155_asoc_machine_of_match, pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: No DT match found for sound card\n", __func__); + return -EINVAL; + } + if (strstr(match->compatible, "sa8295")) { + /* enable mclk pinctrl info from devicetree */ + ret = msm_pinctrl_mclk_enable(pdev); + if (!ret) { + pr_debug("%s: pinctrl mclk parsing successful\n", __func__); + } else { + dev_err(&pdev->dev, + "%s: pinctrl mclk parsing failed with %d\n", + __func__, ret); + ret = 0; + } + } + msm_i2s_auxpcm_init(pdev); ret = msm_audio_ssr_register(&pdev->dev);