From 7bb78319e0f8705b1a0e1016aaf5421e22e59192 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 18 Jun 2019 00:36:55 -0700 Subject: [PATCH] ASoC: msm: enable tdm pinctrl config on 6155 machine Enable dynamic TDM pinctrl configuration based on CPU DAI activity on auto 6155 machine drv. Change-Id: I4550b0e098d450d3ac29c162630c2450d42ac384 Signed-off-by: Derek Chen --- asoc/sa6155.c | 485 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 319 insertions(+), 166 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 2e243e8577d5..ab4e8428451c 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -128,26 +128,24 @@ enum { }; enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ + STATE_SLEEP = 0, /* All pins are in sleep state */ + STATE_ACTIVE, /* TDM = active */ }; struct msm_pinctrl_info { struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; + struct pinctrl_state *sleep; + struct pinctrl_state *active; enum pinctrl_pin_state curr_state; }; -struct msm_asoc_mach_data { - struct msm_pinctrl_info pinctrl_info; -}; +static const char *const pin_states[] = {"sleep", "active"}; -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; +static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios", + "qcom,sec-tdm-gpios", + "qcom,tert-tdm-gpios", + "qcom,quat-tdm-gpios", + "qcom,quin-tdm-gpios"}; enum { TDM_0 = 0, @@ -175,6 +173,11 @@ struct tdm_port { u32 channel; }; +struct tdm_conf { + struct mutex lock; + u32 ref_cnt; +}; + /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -743,7 +746,11 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { }; -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +struct msm_asoc_mach_data { + struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX]; + struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX]; +}; static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3735,7 +3742,6 @@ err: return ret; } -#ifdef ENABLE_PINCTRL static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, enum pinctrl_pin_state new_state) { @@ -3743,13 +3749,13 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, int curr_state = 0; if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); + pr_err("%s: pinctrl info is NULL\n", __func__); ret = -EINVAL; goto err; } if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + pr_err("%s: pinctrl handle is NULL\n", __func__); ret = -EINVAL; goto err; } @@ -3760,55 +3766,40 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, pin_states[curr_state], pin_states[pinctrl_info->curr_state]); if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); + pr_debug("%s: pin already in same state\n", __func__); goto err; } - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); + if (curr_state != STATE_SLEEP && + pinctrl_info->curr_state != STATE_SLEEP) { + pr_debug("%s: pin state is already active, cannot switch\n", __func__); ret = -EIO; goto err; } switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: + case STATE_ACTIVE: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); + pinctrl_info->active); if (ret) { - pr_err("%s: MI2S state select failed with %d\n", + pr_err("%s: state select to active failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; - case STATE_TDM_ACTIVE: + case STATE_SLEEP: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); + pinctrl_info->sleep); if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } - if (ret) { - pr_err("%s: state disable failed with %d\n", + pr_err("%s: state select to sleep failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; default: - pr_err("%s: TLMM pin state is invalid\n", __func__); + pr_err("%s: pin state is invalid\n", __func__); return -EINVAL; } @@ -3820,11 +3811,17 @@ static void msm_release_pinctrl(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 = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + int i; - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } } } @@ -3833,85 +3830,173 @@ static int msm_get_pinctrl(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; + struct pinctrl *pinctrl = NULL; + int i, j; + struct device_node *np = NULL; + struct platform_device *pdev_np = NULL; int ret = 0; - pinctrl_info = &pdata->pinctrl_info; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + np = of_parse_phandle(pdev->dev.of_node, + tdm_gpio_phandle[i], 0); + if (!np) { + pr_debug("%s: device node %s is null\n", + __func__, tdm_gpio_phandle[i]); + continue; + } - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } + pdev_np = of_find_device_by_node(np); + if (!pdev_np) { + pr_err("%s: platform device not found\n", __func__); + continue; + } - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl info is null\n", __func__); + continue; + } - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat_mi2s_disable"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat_mi2s_enable"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat_tdm_disable"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat_tdm_enable"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; + 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 TLMM pins to a sleep state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->sleep); + if (ret != 0) { + pr_err("%s: set pin state to sleep failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_SLEEP; + } return 0; err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; + for (j = i; j >= 0; j--) { + pinctrl_info = &pdata->pinctrl_info[j]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } + } return -EINVAL; } -#else -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - return 0; -} -static void msm_release_pinctrl(struct platform_device *pdev) +static int msm_tdm_get_intf_idx(u16 id) { - return; + switch (id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return TDM_PRI; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return TDM_SEC; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return TDM_TERT; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return TDM_QUAT; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return TDM_QUIN; + default: return -EINVAL; + } } -static int msm_get_pinctrl(struct platform_device *pdev) -{ - return 0; -} -#endif - static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -4661,37 +4746,76 @@ static int sa6155_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + pr_debug("%s: substream = %s, stream = %d, dai name = %s, dai id = %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + ret = -EINVAL; + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; } + /* + * Mutex protection in case the same TDM + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + mutex_unlock(&intf_conf->lock); + +err: return ret; } static void sa6155_tdm_snd_shutdown(struct snd_pcm_substream *substream) { - int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + pr_debug("%s: substream = %s, stream = %d\n", __func__, + substream->name, substream->stream); + + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + return; } + + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops sa6155_tdm_be_ops = { @@ -4733,7 +4857,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; dev_dbg(rtd->card->dev, @@ -4753,10 +4878,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) * interface using for both TX and RX so * that the same clock won't be enable twice. */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + if (!intf_conf->msm_is_mi2s_master) { mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; fmt = SND_SOC_DAIFMT_CBM_CFM; } @@ -4774,21 +4900,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } clk_off: if (ret < 0) msm_mi2s_set_sclk(substream, false); clean_up: if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); + intf_conf->ref_cnt--; + mutex_unlock(&intf_conf->lock); err: return ret; } @@ -4800,7 +4926,8 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -4810,21 +4937,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) return; } - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } - mutex_unlock(&mi2s_intf_conf[index].lock); + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops msm_mi2s_be_ops = { @@ -7087,19 +7215,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) /***************************************************************************** * TO BE UPDATED: Codec/Platform specific tdm slot and offset table selection *****************************************************************************/ -static int msm_tdm_init(struct device *dev) +static int msm_tdm_init(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); const struct of_device_id *match; + int count; - match = of_match_node(sa6155_asoc_machine_of_match, dev->of_node); + match = of_match_node(sa6155_asoc_machine_of_match, pdev->dev.of_node); if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", + dev_err(&pdev->dev, "%s: No DT match found for sound card\n", __func__); return -EINVAL; } if (!strcmp(match->data, "custom_codec")) { - dev_dbg(dev, "%s: custom tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: custom tdm configuration\n", __func__); memcpy(tdm_rx_slot_offset, tdm_rx_slot_offset_custom, @@ -7111,21 +7242,40 @@ static int msm_tdm_init(struct device *dev) tdm_slot_custom, sizeof(tdm_slot_custom)); } else { - dev_dbg(dev, "%s: default tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: default tdm configuration\n", __func__); + } + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_init(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; } return 0; } +static void msm_tdm_deinit(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); + int count; + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_destroy(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; + } +} + static void msm_i2s_auxpcm_init(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); int count; u32 mi2s_master_slave[MI2S_MAX]; int ret; for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; + mutex_init(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; } ret = of_property_read_u32_array(pdev->dev.of_node, @@ -7136,20 +7286,22 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev) __func__); } else { for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = mi2s_master_slave[count]; } } } -static void msm_i2s_auxpcm_deinit(void) +static void msm_i2s_auxpcm_deinit(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); int count; for (count = 0; count < MI2S_MAX; count++) { - mutex_destroy(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - mi2s_intf_conf[count].msm_is_mi2s_master = 0; + mutex_destroy(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } @@ -7275,7 +7427,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) card->controls = msm_snd_controls; card->num_controls = ARRAY_SIZE(msm_snd_controls); - ret = msm_tdm_init(&pdev->dev); + ret = msm_tdm_init(pdev); if (ret) { ret = -EPROBE_DEFER; goto err; @@ -7297,7 +7449,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pr_debug("%s: pinctrl parsing successful\n", __func__); } else { dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + "%s: pinctrl parsing failed with %d\n", __func__, ret); ret = 0; } @@ -7318,7 +7470,8 @@ err: static int msm_asoc_machine_remove(struct platform_device *pdev) { - msm_i2s_auxpcm_deinit(); + msm_i2s_auxpcm_deinit(pdev); + msm_tdm_deinit(pdev); msm_release_pinctrl(pdev); return 0;