Messages in this thread | | | Subject | Re: [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer | From | Ajit Pandey <> | Date | Sat, 25 Apr 2020 19:41:58 +0530 |
| |
On 4/16/2020 1:26 PM, Srinivas Kandagatla wrote: > > > On 11/04/2020 09:02, Ajit Pandey wrote: >> lpass_dai will store clocks related to respective dai's and it will >> be initialized during probe based on variant clock names. >> >> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org> > > I dont understand why do we need this change? What is the advantage of > doing this way vs the existing one? > > > --srini > > Actually I've kept this in chain to add dai modes properties later in > chain in this struct but with adoption of Stephen patch now , i guess > we don't have any significant advantage now. I'll probably drop this > patch during v2 submission. --Ajit >> --- >> sound/soc/qcom/lpass-cpu.c | 89 >> ++++++++++++++++++++++++++-------------------- >> sound/soc/qcom/lpass.h | 18 +++++----- >> 2 files changed, 61 insertions(+), 46 deletions(-) >> >> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c >> index dbce7e9..492f27b 100644 >> --- a/sound/soc/qcom/lpass-cpu.c >> +++ b/sound/soc/qcom/lpass-cpu.c >> @@ -23,13 +23,15 @@ static int lpass_cpu_daiops_set_sysclk(struct >> snd_soc_dai *dai, int clk_id, >> unsigned int freq, int dir) >> { >> struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); >> - int ret; >> - >> - ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq); >> - if (ret) >> - dev_err(dai->dev, "error setting mi2s osrclk to %u: %d\n", >> - freq, ret); >> + struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id]; >> + int ret = 0; >> + if (dai_data->osr_clk != NULL) { >> + ret = clk_set_rate(dai_data->osr_clk, freq); >> + if (ret) >> + dev_err(dai->dev, "error setting mi2s osrclk to %u:%d\n", >> + freq, ret); >> + } >> return ret; >> } >> @@ -37,18 +39,22 @@ static int lpass_cpu_daiops_startup(struct >> snd_pcm_substream *substream, >> struct snd_soc_dai *dai) >> { >> struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); >> + struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id]; >> int ret; >> - ret = clk_prepare_enable(drvdata->mi2s_osr_clk[dai->driver->id]); >> - if (ret) { >> - dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret); >> - return ret; >> + if (dai_data->osr_clk != NULL) { >> + ret = clk_prepare_enable(dai_data->osr_clk); >> + if (ret) { >> + dev_err(dai->dev, >> + "error in enabling mi2s osr clk: %d\n", ret); >> + return ret; >> + } >> } >> - ret = clk_prepare_enable(drvdata->mi2s_bit_clk[dai->driver->id]); >> + ret = clk_prepare_enable(dai_data->bit_clk); >> if (ret) { >> dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", >> ret); >> - clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); >> + clk_disable_unprepare(dai_data->osr_clk); >> return ret; >> } >> @@ -59,16 +65,18 @@ static void lpass_cpu_daiops_shutdown(struct >> snd_pcm_substream *substream, >> struct snd_soc_dai *dai) >> { >> struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); >> + struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id]; >> - clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]); >> + clk_disable_unprepare(dai_data->bit_clk); >> - clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); >> + clk_disable_unprepare(dai_data->osr_clk); >> } >> static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream >> *substream, >> struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) >> { >> struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); >> + struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id]; >> snd_pcm_format_t format = params_format(params); >> unsigned int channels = params_channels(params); >> unsigned int rate = params_rate(params); >> @@ -163,8 +171,7 @@ static int lpass_cpu_daiops_hw_params(struct >> snd_pcm_substream *substream, >> return ret; >> } >> - ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id], >> - rate * bitwidth * 2); >> + ret = clk_set_rate(dai_data->bit_clk, rate * bitwidth * 2); >> if (ret) { >> dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n", >> rate * bitwidth * 2, ret); >> @@ -413,6 +420,25 @@ static bool lpass_cpu_regmap_volatile(struct >> device *dev, unsigned int reg) >> .cache_type = REGCACHE_FLAT, >> }; >> +static int lpass_init_dai_clocks(struct device *dev, >> + struct lpass_data *drvdata) >> +{ >> + struct lpass_dai *dai; >> + struct lpass_variant *v = drvdata->variant; >> + int i; >> + >> + for (i = 0; i < v->num_dai; i++) { >> + >> + dai = drvdata->dai_priv[i]; >> + >> + dai->osr_clk = devm_clk_get_optional(dev, >> + v->dai_osr_clk_names[i]); >> + dai->bit_clk = devm_clk_get(dev, v->dai_bit_clk_names[i]); >> + } >> + >> + return 0; >> +} >> + >> int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) >> { >> struct lpass_data *drvdata; >> @@ -421,7 +447,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct >> platform_device *pdev) >> struct lpass_variant *variant; >> struct device *dev = &pdev->dev; >> const struct of_device_id *match; >> - int ret, i, dai_id; >> + int ret, i; >> dsp_of_node = of_parse_phandle(pdev->dev.of_node, >> "qcom,adsp", 0); >> if (dsp_of_node) { >> @@ -467,28 +493,15 @@ int asoc_qcom_lpass_cpu_platform_probe(struct >> platform_device *pdev) >> variant->init(pdev); >> for (i = 0; i < variant->num_dai; i++) { >> - dai_id = variant->dai_driver[i].id; >> - drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev, >> - variant->dai_osr_clk_names[i]); >> - if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) { >> - dev_warn(&pdev->dev, >> - "%s() error getting optional %s: %ld\n", >> - __func__, >> - variant->dai_osr_clk_names[i], >> - PTR_ERR(drvdata->mi2s_osr_clk[dai_id])); >> - >> - drvdata->mi2s_osr_clk[dai_id] = NULL; >> - } >> + drvdata->dai_priv[i] = devm_kzalloc(dev, >> + sizeof(struct lpass_dai), >> + GFP_KERNEL); >> + } >> - drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev, >> - variant->dai_bit_clk_names[i]); >> - if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { >> - dev_err(&pdev->dev, >> - "error getting %s: %ld\n", >> - variant->dai_bit_clk_names[i], >> - PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); >> - return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); >> - } >> + ret = lpass_init_dai_clocks(dev, drvdata); >> + if (ret) { >> + dev_err(&pdev->dev, "error intializing dai clock: %d\n", ret); >> + return ret; >> } >> drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk"); >> diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h >> index 17113d3..b729686 100644 >> --- a/sound/soc/qcom/lpass.h >> +++ b/sound/soc/qcom/lpass.h >> @@ -13,9 +13,14 @@ >> #include <linux/platform_device.h> >> #include <linux/regmap.h> >> -#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 >> -#define LPASS_MAX_MI2S_PORTS (8) >> -#define LPASS_MAX_DMA_CHANNELS (8) >> +#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 >> +#define LPASS_MAX_MI2S_PORTS (8) >> +#define LPASS_MAX_DMA_CHANNELS (8) >> + >> +struct lpass_dai { >> + struct clk *osr_clk; >> + struct clk *bit_clk; >> +}; >> /* Both the CPU DAI and platform drivers will access this data */ >> struct lpass_data { >> @@ -23,11 +28,8 @@ struct lpass_data { >> /* AHB-I/X bus clocks inside the low-power audio subsystem >> (LPASS) */ >> struct clk *ahbix_clk; >> - /* MI2S system clock */ >> - struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS]; >> - >> - /* MI2S bit clock (derived from system clock by a divider */ >> - struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS]; >> + /* MI2S dai specific configuration */ >> + struct lpass_dai *dai_priv[LPASS_MAX_MI2S_PORTS]; >> /* low-power audio interface (LPAIF) registers */ >> void __iomem *lpaif; >>
| |