Merge "ASoC: wcd9335: Add counter to maintain count of functions voting for max bw"

This commit is contained in:
Linux Build Service Account 2017-07-04 01:21:00 -07:00 committed by Gerrit - the friendly Code Review server
commit 8661bf1cf3

View file

@ -352,7 +352,6 @@ enum {
AUDIO_NOMINAL, AUDIO_NOMINAL,
CPE_NOMINAL, CPE_NOMINAL,
HPH_PA_DELAY, HPH_PA_DELAY,
SB_CLK_GEAR,
ANC_MIC_AMIC1, ANC_MIC_AMIC1,
ANC_MIC_AMIC2, ANC_MIC_AMIC2,
ANC_MIC_AMIC3, ANC_MIC_AMIC3,
@ -854,7 +853,10 @@ struct tasha_priv {
int rx_8_count; int rx_8_count;
bool clk_mode; bool clk_mode;
bool clk_internal; bool clk_internal;
/* Lock to prevent multiple functions voting at same time */
struct mutex sb_clk_gear_lock;
/* Count for functions voting or un-voting */
u32 ref_count;
/* Lock to protect mclk enablement */ /* Lock to protect mclk enablement */
struct mutex mclk_lock; struct mutex mclk_lock;
}; };
@ -3153,10 +3155,7 @@ static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
&dai->grph); &dai->grph);
break; break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
if (!test_bit(SB_CLK_GEAR, &tasha_p->status_mask)) { tasha_codec_vote_max_bw(codec, true);
tasha_codec_vote_max_bw(codec, true);
set_bit(SB_CLK_GEAR, &tasha_p->status_mask);
}
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
@ -5468,10 +5467,7 @@ static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
if (!test_bit(SB_CLK_GEAR, &tasha->status_mask)) { tasha_codec_vote_max_bw(codec, true);
tasha_codec_vote_max_bw(codec, true);
set_bit(SB_CLK_GEAR, &tasha->status_mask);
}
/* Reset if needed */ /* Reset if needed */
tasha_codec_enable_prim_interpolator(codec, reg, event); tasha_codec_enable_prim_interpolator(codec, reg, event);
break; break;
@ -11332,11 +11328,8 @@ static void tasha_shutdown(struct snd_pcm_substream *substream,
if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
return; return;
if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
tasha_codec_vote_max_bw(dai->codec, false); tasha_codec_vote_max_bw(dai->codec, false);
clear_bit(SB_CLK_GEAR, &tasha->status_mask);
}
} }
static int tasha_set_decimator_rate(struct snd_soc_dai *dai, static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
@ -11571,15 +11564,11 @@ prim_rate:
static int tasha_prepare(struct snd_pcm_substream *substream, static int tasha_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
pr_debug("%s(): substream = %s stream = %d\n" , __func__, pr_debug("%s(): substream = %s stream = %d\n" , __func__,
substream->name, substream->stream); substream->name, substream->stream);
if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
test_bit(SB_CLK_GEAR, &tasha->status_mask)) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
tasha_codec_vote_max_bw(dai->codec, false); tasha_codec_vote_max_bw(dai->codec, false);
clear_bit(SB_CLK_GEAR, &tasha->status_mask);
}
return 0; return 0;
} }
@ -13287,13 +13276,29 @@ static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
return 0; return 0;
if (vote) mutex_lock(&tasha->sb_clk_gear_lock);
bw_ops = SLIM_BW_CLK_GEAR_9; if (vote) {
else tasha->ref_count++;
bw_ops = SLIM_BW_UNVOTE; if (tasha->ref_count == 1) {
bw_ops = SLIM_BW_CLK_GEAR_9;
tasha_codec_slim_reserve_bw(codec,
bw_ops, true);
}
} else if (!vote && tasha->ref_count > 0) {
tasha->ref_count--;
if (tasha->ref_count == 0) {
bw_ops = SLIM_BW_UNVOTE;
tasha_codec_slim_reserve_bw(codec,
bw_ops, true);
}
};
return tasha_codec_slim_reserve_bw(codec, dev_dbg(codec->dev, "%s Value of counter after vote or un-vote is %d\n",
bw_ops, true); __func__, tasha->ref_count);
mutex_unlock(&tasha->sb_clk_gear_lock);
return 0;
} }
static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec, static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
@ -13476,6 +13481,8 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
if (IS_ERR_VALUE(ret)) if (IS_ERR_VALUE(ret))
dev_err(codec->dev, "%s: invalid pdata\n", __func__); dev_err(codec->dev, "%s: invalid pdata\n", __func__);
/* Reset reference counter for voting for max bw */
tasha->ref_count = 0;
/* MBHC Init */ /* MBHC Init */
wcd_mbhc_deinit(&tasha->mbhc); wcd_mbhc_deinit(&tasha->mbhc);
tasha->mbhc_started = false; tasha->mbhc_started = false;
@ -14262,6 +14269,7 @@ static int tasha_probe(struct platform_device *pdev)
mutex_init(&tasha->swr_read_lock); mutex_init(&tasha->swr_read_lock);
mutex_init(&tasha->swr_write_lock); mutex_init(&tasha->swr_write_lock);
mutex_init(&tasha->swr_clk_lock); mutex_init(&tasha->swr_clk_lock);
mutex_init(&tasha->sb_clk_gear_lock);
mutex_init(&tasha->mclk_lock); mutex_init(&tasha->mclk_lock);
cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
@ -14366,6 +14374,7 @@ static int tasha_remove(struct platform_device *pdev)
mutex_destroy(&tasha->mclk_lock); mutex_destroy(&tasha->mclk_lock);
devm_kfree(&pdev->dev, tasha); devm_kfree(&pdev->dev, tasha);
snd_soc_unregister_codec(&pdev->dev); snd_soc_unregister_codec(&pdev->dev);
mutex_destroy(&tasha->sb_clk_gear_lock);
return 0; return 0;
} }