[PATCH] ASoC: mediatek: Turn AFE on/off in runtime resume/suspend
AFE is actually allowed to be turn on before configuration of DAIs since each DAI has its own enabling control. Turn on/off AFE in runtime resume/suspend to avoid AFE being shut down when closing a DAI while other DAIs are still active. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-pcm.c | 24 ++-- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 5399a0e..08af9f5 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -382,9 +382,6 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); - - /* disable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); } static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, @@ -433,9 +430,6 @@ static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream, mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], afe->clocks[MTK_CLK_I2S3_B]); - - /* disable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); } static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, @@ -679,17 +673,6 @@ static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream, return snd_pcm_lib_free_pages(substream); } -static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); - - /* enable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); - return 0; -} - static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -757,7 +740,6 @@ static const struct snd_soc_dai_ops mtk_afe_dai_ops = { .shutdown = mtk_afe_dais_shutdown, .hw_params = mtk_afe_dais_hw_params, .hw_free= mtk_afe_dais_hw_free, - .prepare= mtk_afe_dais_prepare, .trigger= mtk_afe_dais_trigger, }; @@ -1118,6 +1100,9 @@ static int mtk_afe_runtime_suspend(struct device *dev) { struct mtk_afe *afe = dev_get_drvdata(dev); + /* disable AFE */ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); + /* disable AFE clk */ regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); @@ -1164,6 +1149,9 @@ static int mtk_afe_runtime_resume(struct device *dev) /* unmask all IRQs */ regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff); + + /* enable AFE */ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); return 0; err_bck0: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Turn AFE on/off in runtime resume/suspend
AFE is actually allowed to be turn on before configuration of DAIs since each DAI has its own enabling control. Turn on/off AFE in runtime resume/suspend to avoid AFE being shut down when closing a DAI while other DAIs are still active. Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/mediatek/mtk-afe-pcm.c | 24 ++-- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 5399a0e..08af9f5 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -382,9 +382,6 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); - - /* disable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); } static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, @@ -433,9 +430,6 @@ static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream, mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], afe->clocks[MTK_CLK_I2S3_B]); - - /* disable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); } static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, @@ -679,17 +673,6 @@ static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream, return snd_pcm_lib_free_pages(substream); } -static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); - - /* enable AFE */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); - return 0; -} - static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -757,7 +740,6 @@ static const struct snd_soc_dai_ops mtk_afe_dai_ops = { .shutdown = mtk_afe_dais_shutdown, .hw_params = mtk_afe_dais_hw_params, .hw_free= mtk_afe_dais_hw_free, - .prepare= mtk_afe_dais_prepare, .trigger= mtk_afe_dais_trigger, }; @@ -1118,6 +1100,9 @@ static int mtk_afe_runtime_suspend(struct device *dev) { struct mtk_afe *afe = dev_get_drvdata(dev); + /* disable AFE */ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); + /* disable AFE clk */ regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); @@ -1164,6 +1149,9 @@ static int mtk_afe_runtime_resume(struct device *dev) /* unmask all IRQs */ regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff); + + /* enable AFE */ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); return 0; err_bck0: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] ASoC: dpcm: Apply symmetry for DPCM
From: PC Liao DPCM does not fully support symmetry attributes. soc_pcm_apply_symmetry() is skipped in soc_pcm_open() for DPCM, without being applied elsewhere. So HW parameters cannot be correctly limited, and user space can do playback/capture at different rates while HW actually does not support it. soc_pcm_params_symmetry() will return error and the second stream stops. This patch adds soc_pcm_apply_symmetry() for FE, BE, and codec DAIs in DPCM path that was skipped in soc_pcm_open(). Signed-off-by: PC Liao Signed-off-by: Koro Chen --- sound/soc/soc-pcm.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 67ef1a0..2a2ca22 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1614,6 +1614,56 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, snd_pcm_stream_unlock_irq(substream); } +static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, + int stream) +{ + struct snd_soc_dpcm *dpcm; + struct snd_soc_pcm_runtime *fe = fe_substream->private_data; + struct snd_soc_dai *fe_cpu_dai = fe->cpu_dai; + int err; + + /* apply symmetry for FE */ + if (soc_pcm_has_symmetry(fe_substream)) + fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; + + /* Symmetry only applies if we've got an active stream. */ + if (fe_cpu_dai->active) { + err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai); + if (err < 0) + return err; + } + + /* apply symmetry for BE */ + list_for_each_entry(dpcm, >dpcm[stream].be_clients, list_be) { + struct snd_soc_pcm_runtime *be = dpcm->be; + struct snd_pcm_substream *be_substream = + snd_soc_dpcm_get_substream(be, stream); + struct snd_soc_pcm_runtime *rtd = be_substream->private_data; + int i; + + if (soc_pcm_has_symmetry(be_substream)) + be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; + + /* Symmetry only applies if we've got an active stream. */ + if (rtd->cpu_dai->active) { + err = soc_pcm_apply_symmetry(be_substream, rtd->cpu_dai); + if (err < 0) + return err; + } + + for (i = 0; i < rtd->num_codecs; i++) { + if (rtd->codec_dais[i]->active) { + err = soc_pcm_apply_symmetry(be_substream, + rtd->codec_dais[i]); + if (err < 0) + return err; + } + } + } + + return 0; +} + static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) { struct snd_soc_pcm_runtime *fe = fe_substream->private_data; @@ -1642,6 +1692,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) dpcm_set_fe_runtime(fe_substream); snd_pcm_limit_hw_rates(runtime); + ret = dpcm_apply_symmetry(fe_substream, stream); + if (ret < 0) { + dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n", + ret); + goto unwind; + } + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] ASoC: dpcm: Apply symmetry for DPCM
From: PC Liao <pc.l...@mediatek.com> DPCM does not fully support symmetry attributes. soc_pcm_apply_symmetry() is skipped in soc_pcm_open() for DPCM, without being applied elsewhere. So HW parameters cannot be correctly limited, and user space can do playback/capture at different rates while HW actually does not support it. soc_pcm_params_symmetry() will return error and the second stream stops. This patch adds soc_pcm_apply_symmetry() for FE, BE, and codec DAIs in DPCM path that was skipped in soc_pcm_open(). Signed-off-by: PC Liao <pc.l...@mediatek.com> Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/soc-pcm.c | 57 +++ 1 file changed, 57 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 67ef1a0..2a2ca22 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1614,6 +1614,56 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, snd_pcm_stream_unlock_irq(substream); } +static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, + int stream) +{ + struct snd_soc_dpcm *dpcm; + struct snd_soc_pcm_runtime *fe = fe_substream->private_data; + struct snd_soc_dai *fe_cpu_dai = fe->cpu_dai; + int err; + + /* apply symmetry for FE */ + if (soc_pcm_has_symmetry(fe_substream)) + fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; + + /* Symmetry only applies if we've got an active stream. */ + if (fe_cpu_dai->active) { + err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai); + if (err < 0) + return err; + } + + /* apply symmetry for BE */ + list_for_each_entry(dpcm, >dpcm[stream].be_clients, list_be) { + struct snd_soc_pcm_runtime *be = dpcm->be; + struct snd_pcm_substream *be_substream = + snd_soc_dpcm_get_substream(be, stream); + struct snd_soc_pcm_runtime *rtd = be_substream->private_data; + int i; + + if (soc_pcm_has_symmetry(be_substream)) + be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; + + /* Symmetry only applies if we've got an active stream. */ + if (rtd->cpu_dai->active) { + err = soc_pcm_apply_symmetry(be_substream, rtd->cpu_dai); + if (err < 0) + return err; + } + + for (i = 0; i < rtd->num_codecs; i++) { + if (rtd->codec_dais[i]->active) { + err = soc_pcm_apply_symmetry(be_substream, + rtd->codec_dais[i]); + if (err < 0) + return err; + } + } + } + + return 0; +} + static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) { struct snd_soc_pcm_runtime *fe = fe_substream->private_data; @@ -1642,6 +1692,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) dpcm_set_fe_runtime(fe_substream); snd_pcm_limit_hw_rates(runtime); + ret = dpcm_apply_symmetry(fe_substream, stream); + if (ret < 0) { + dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n", + ret); + goto unwind; + } + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH] ASoC: mediatek: Use current HW pointer for pointer callback
On Thu, 2015-12-03 at 12:07 +0100, Takashi Iwai wrote: > On Thu, 03 Dec 2015 12:01:58 +0100, > Mark Brown wrote: > > > > On Thu, Dec 03, 2015 at 10:41:38AM +0100, Takashi Iwai wrote: > > > > > While reading this patch, I wondered how regmap can be used safely in > > > an irq-disabled context. Mark, do we have any API for that? > > > > We can use user supplied locks or spin_lock_irqsave(). > > I meant how to guarantee to make regmap_read() working in an already > spin-locked context, typically in an irq handler? regmap_read() > involves with the regcache and it may invoke kmalloc(). > Yes, we were hit by this before. When using devm_regmap_init_mmio() for regmap, it uses spin_lock_irqsave() before every read/write, and if cache type is RBTREE, then kmalloc will occur after spin_lock_irqsave() and it brings warning. That's why we changed RBTREE to NONE. Setting cache type to FLAT will also work, but we think our register accessing is fast enough without need of cache. > > Takashi > ___ > Alsa-devel mailing list > alsa-de...@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH] ASoC: mediatek: Use current HW pointer for pointer callback
On Thu, 2015-12-03 at 12:07 +0100, Takashi Iwai wrote: > On Thu, 03 Dec 2015 12:01:58 +0100, > Mark Brown wrote: > > > > On Thu, Dec 03, 2015 at 10:41:38AM +0100, Takashi Iwai wrote: > > > > > While reading this patch, I wondered how regmap can be used safely in > > > an irq-disabled context. Mark, do we have any API for that? > > > > We can use user supplied locks or spin_lock_irqsave(). > > I meant how to guarantee to make regmap_read() working in an already > spin-locked context, typically in an irq handler? regmap_read() > involves with the regcache and it may invoke kmalloc(). > Yes, we were hit by this before. When using devm_regmap_init_mmio() for regmap, it uses spin_lock_irqsave() before every read/write, and if cache type is RBTREE, then kmalloc will occur after spin_lock_irqsave() and it brings warning. That's why we changed RBTREE to NONE. Setting cache type to FLAT will also work, but we think our register accessing is fast enough without need of cache. > > Takashi > ___ > Alsa-devel mailing list > alsa-de...@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Use current HW pointer for pointer callback
Previously we recorded "last interrupt position" and used it in pointer callback. This is not correct implementation, and it causes underruns when user space monitors buffer level to decide when to send next data chunk in low latency application. Remove position recording in IRQ handler and also hw_ptr in struct mtk_afe_memif used to record that, and let pointer callback reports current HW pointer instead. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-common.h |1 - sound/soc/mediatek/mtk-afe-pcm.c| 22 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h index cc4393c..9b1af1a 100644 --- a/sound/soc/mediatek/mtk-afe-common.h +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -92,7 +92,6 @@ struct mtk_afe_memif_data { struct mtk_afe_memif { unsigned int phys_buf_addr; int buffer_size; - unsigned int hw_ptr;/* Previous IRQ's HW ptr */ struct snd_pcm_substream *substream; const struct mtk_afe_memif_data *data; const struct mtk_afe_irq_data *irqdata; diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 7f71343..5399a0e 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -175,8 +175,17 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer struct snd_soc_pcm_runtime *rtd = substream->private_data; struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); struct mtk_afe_memif *memif = >memif[rtd->cpu_dai->id]; + unsigned int hw_ptr; + int ret; + + ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, _ptr); + if (ret || hw_ptr == 0) { + dev_err(afe->dev, "%s hw_ptr err\n", __func__); + hw_ptr = memif->phys_buf_addr; + } - return bytes_to_frames(substream->runtime, memif->hw_ptr); + return bytes_to_frames(substream->runtime, + hw_ptr - memif->phys_buf_addr); } static const struct snd_pcm_ops mtk_afe_pcm_ops = { @@ -602,7 +611,6 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, memif->phys_buf_addr = substream->runtime->dma_addr; memif->buffer_size = substream->runtime->dma_bytes; - memif->hw_ptr = 0; /* start */ regmap_write(afe->regmap, @@ -737,7 +745,6 @@ static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, /* and clear pending IRQ */ regmap_write(afe->regmap, AFE_IRQ_CLR, 1 << memif->data->irq_clr_shift); - memif->hw_ptr = 0; return 0; default: return -EINVAL; @@ -1081,7 +1088,7 @@ static const struct regmap_config mtk_afe_regmap_config = { static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) { struct mtk_afe *afe = dev_id; - unsigned int reg_value, hw_ptr; + unsigned int reg_value; int i, ret; ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, _value); @@ -1097,13 +1104,6 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) if (!(reg_value & (1 << memif->data->irq_clr_shift))) continue; - ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, - _ptr); - if (ret || hw_ptr == 0) { - dev_err(afe->dev, "%s hw_ptr err\n", __func__); - hw_ptr = memif->phys_buf_addr; - } - memif->hw_ptr = hw_ptr - memif->phys_buf_addr; snd_pcm_period_elapsed(memif->substream); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Use current HW pointer for pointer callback
Previously we recorded "last interrupt position" and used it in pointer callback. This is not correct implementation, and it causes underruns when user space monitors buffer level to decide when to send next data chunk in low latency application. Remove position recording in IRQ handler and also hw_ptr in struct mtk_afe_memif used to record that, and let pointer callback reports current HW pointer instead. Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/mediatek/mtk-afe-common.h |1 - sound/soc/mediatek/mtk-afe-pcm.c| 22 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h index cc4393c..9b1af1a 100644 --- a/sound/soc/mediatek/mtk-afe-common.h +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -92,7 +92,6 @@ struct mtk_afe_memif_data { struct mtk_afe_memif { unsigned int phys_buf_addr; int buffer_size; - unsigned int hw_ptr;/* Previous IRQ's HW ptr */ struct snd_pcm_substream *substream; const struct mtk_afe_memif_data *data; const struct mtk_afe_irq_data *irqdata; diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 7f71343..5399a0e 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -175,8 +175,17 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer struct snd_soc_pcm_runtime *rtd = substream->private_data; struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); struct mtk_afe_memif *memif = >memif[rtd->cpu_dai->id]; + unsigned int hw_ptr; + int ret; + + ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, _ptr); + if (ret || hw_ptr == 0) { + dev_err(afe->dev, "%s hw_ptr err\n", __func__); + hw_ptr = memif->phys_buf_addr; + } - return bytes_to_frames(substream->runtime, memif->hw_ptr); + return bytes_to_frames(substream->runtime, + hw_ptr - memif->phys_buf_addr); } static const struct snd_pcm_ops mtk_afe_pcm_ops = { @@ -602,7 +611,6 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, memif->phys_buf_addr = substream->runtime->dma_addr; memif->buffer_size = substream->runtime->dma_bytes; - memif->hw_ptr = 0; /* start */ regmap_write(afe->regmap, @@ -737,7 +745,6 @@ static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, /* and clear pending IRQ */ regmap_write(afe->regmap, AFE_IRQ_CLR, 1 << memif->data->irq_clr_shift); - memif->hw_ptr = 0; return 0; default: return -EINVAL; @@ -1081,7 +1088,7 @@ static const struct regmap_config mtk_afe_regmap_config = { static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) { struct mtk_afe *afe = dev_id; - unsigned int reg_value, hw_ptr; + unsigned int reg_value; int i, ret; ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, _value); @@ -1097,13 +1104,6 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) if (!(reg_value & (1 << memif->data->irq_clr_shift))) continue; - ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, - _ptr); - if (ret || hw_ptr == 0) { - dev_err(afe->dev, "%s hw_ptr err\n", __func__); - hw_ptr = memif->phys_buf_addr; - } - memif->hw_ptr = hw_ptr - memif->phys_buf_addr; snd_pcm_period_elapsed(memif->substream); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Move 22M/24M clock control into I2S ops
22M/24M clocks are only required for I2S, so move the control to I2S DAI ops. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-pcm.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index f5baf3c..7f71343 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -299,8 +299,6 @@ static int mtk_afe_dais_enable_clks(struct mtk_afe *afe, dev_err(afe->dev, "Failed to enable m_ck\n"); return ret; } - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); } if (b_ck) { @@ -340,12 +338,8 @@ static int mtk_afe_dais_set_clks(struct mtk_afe *afe, static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, struct clk *m_ck, struct clk *b_ck) { - if (m_ck) { - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); + if (m_ck) clk_disable_unprepare(m_ck); - } if (b_ck) clk_disable_unprepare(b_ck); } @@ -360,6 +354,8 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream, return 0; mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); return 0; } @@ -373,6 +369,9 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, return; mtk_afe_set_i2s_enable(afe, false); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); /* disable AFE */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Move 22M/24M clock control into I2S ops
22M/24M clocks are only required for I2S, so move the control to I2S DAI ops. Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/mediatek/mtk-afe-pcm.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index f5baf3c..7f71343 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -299,8 +299,6 @@ static int mtk_afe_dais_enable_clks(struct mtk_afe *afe, dev_err(afe->dev, "Failed to enable m_ck\n"); return ret; } - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); } if (b_ck) { @@ -340,12 +338,8 @@ static int mtk_afe_dais_set_clks(struct mtk_afe *afe, static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, struct clk *m_ck, struct clk *b_ck) { - if (m_ck) { - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, - AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); + if (m_ck) clk_disable_unprepare(m_ck); - } if (b_ck) clk_disable_unprepare(b_ck); } @@ -360,6 +354,8 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream, return 0; mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); return 0; } @@ -373,6 +369,9 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, return; mtk_afe_set_i2s_enable(afe, false); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, + AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); /* disable AFE */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dpcm: Make BE prepare possible in suspend state
During suspend/resume, there is a flow that if a driver does not support SNDRV_PCM_INFO_RESUME, it will fail at snd_pcm_resume(), and user space can then issue SNDRV_PCM_IOCTL_PREPARE to let audio continue to play. However, in dpcm_be_dai_prepare() it only allows BEs to be prepared in state SND_SOC_DPCM_STATE_HW_PARAMS or SND_SOC_DPCM_STATE_STOP. The BE state will then stay in SND_SOC_DPCM_STATE_SUSPEND, consequently dpcm_be_dai_shutdown() is skipped in the end of playback and be_substream->runtime is not cleared while this runtime is actually freed by snd_pcm_detach_substream(). If another suspend comes, a NULL pointer dereference will happen in snd_pcm_suspend() when accessing BE substream's runtime. Signed-off-by: Koro Chen --- sound/soc/soc-pcm.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 3173958..5c41a58 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2117,7 +2117,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) continue; if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && - (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) continue; dev_dbg(be->dev, "ASoC: prepare BE %s\n", -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dpcm: Make BE prepare possible in suspend state
During suspend/resume, there is a flow that if a driver does not support SNDRV_PCM_INFO_RESUME, it will fail at snd_pcm_resume(), and user space can then issue SNDRV_PCM_IOCTL_PREPARE to let audio continue to play. However, in dpcm_be_dai_prepare() it only allows BEs to be prepared in state SND_SOC_DPCM_STATE_HW_PARAMS or SND_SOC_DPCM_STATE_STOP. The BE state will then stay in SND_SOC_DPCM_STATE_SUSPEND, consequently dpcm_be_dai_shutdown() is skipped in the end of playback and be_substream->runtime is not cleared while this runtime is actually freed by snd_pcm_detach_substream(). If another suspend comes, a NULL pointer dereference will happen in snd_pcm_suspend() when accessing BE substream's runtime. Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/soc-pcm.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 3173958..5c41a58 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2117,7 +2117,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) continue; if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && - (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) continue; dev_dbg(be->dev, "ASoC: prepare BE %s\n", -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Thu, 2015-10-15 at 15:26 +0200, Lars-Peter Clausen wrote: > On 10/15/2015 02:10 PM, Mark Brown wrote: > > On Wed, Oct 14, 2015 at 11:00:01AM +0200, Lars-Peter Clausen wrote: > > > >> It was never intended that it is possible to bind a component to multiple > >> cards. That it was possible was a bug that was overlooked and some people > >> tried to do it which caused apparently random crashes later on, caused by > >> the data structure corruption. This is why we added the check to catch this > >> kind of mistake early and to avoid the crashes. > > > > This is true, but I do think it's something that we should have some > > story on supporting for some of this hardware that has a bunch of > > channels in one IP block that can't really interact with each other. > > It's going to make it a lot easier for people to think about the > > hardware and how to describe it. > > I'm not saying we shouldn't support it, just that we can't support it with > the current code. And adding support for it will require a fair bit of > restructuring. > > If a hardware block as multiple independent channels the best approach in my > opinion is to register multiple components (Which we can't do at the moment, > because there can only be one component per device). From a framework point Yes... I have tried to register 2 platforms in my ASoC platform driver but alsa considered they are the same platform since they are from the same device. > of view there is no difference between a single device with multiple > independent channels and multiple independent devices with one channel each. > Both have the same logical topology. > Yes, but in my case there is only one HW, one set of registers, and one set of clocks, it should be a single device node in the device tree. > - Lars > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Thu, 2015-10-15 at 13:10 +0100, Mark Brown wrote: > On Wed, Oct 14, 2015 at 11:00:01AM +0200, Lars-Peter Clausen wrote: > > > It was never intended that it is possible to bind a component to multiple > > cards. That it was possible was a bug that was overlooked and some people > > tried to do it which caused apparently random crashes later on, caused by > > the data structure corruption. This is why we added the check to catch this > > kind of mistake early and to avoid the crashes. > > This is true, but I do think it's something that we should have some > story on supporting for some of this hardware that has a bunch of > channels in one IP block that can't really interact with each other. > It's going to make it a lot easier for people to think about the > hardware and how to describe it. Yes, and if in some cases we must use multiple cards, it seems the only option left is to separate an ASoC platform driver into multiple drivers. It does not make sense to me since there is only one HW block. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Thu, 2015-10-15 at 13:10 +0100, Mark Brown wrote: > On Wed, Oct 14, 2015 at 11:00:01AM +0200, Lars-Peter Clausen wrote: > > > It was never intended that it is possible to bind a component to multiple > > cards. That it was possible was a bug that was overlooked and some people > > tried to do it which caused apparently random crashes later on, caused by > > the data structure corruption. This is why we added the check to catch this > > kind of mistake early and to avoid the crashes. > > This is true, but I do think it's something that we should have some > story on supporting for some of this hardware that has a bunch of > channels in one IP block that can't really interact with each other. > It's going to make it a lot easier for people to think about the > hardware and how to describe it. Yes, and if in some cases we must use multiple cards, it seems the only option left is to separate an ASoC platform driver into multiple drivers. It does not make sense to me since there is only one HW block. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Thu, 2015-10-15 at 15:26 +0200, Lars-Peter Clausen wrote: > On 10/15/2015 02:10 PM, Mark Brown wrote: > > On Wed, Oct 14, 2015 at 11:00:01AM +0200, Lars-Peter Clausen wrote: > > > >> It was never intended that it is possible to bind a component to multiple > >> cards. That it was possible was a bug that was overlooked and some people > >> tried to do it which caused apparently random crashes later on, caused by > >> the data structure corruption. This is why we added the check to catch this > >> kind of mistake early and to avoid the crashes. > > > > This is true, but I do think it's something that we should have some > > story on supporting for some of this hardware that has a bunch of > > channels in one IP block that can't really interact with each other. > > It's going to make it a lot easier for people to think about the > > hardware and how to describe it. > > I'm not saying we shouldn't support it, just that we can't support it with > the current code. And adding support for it will require a fair bit of > restructuring. > > If a hardware block as multiple independent channels the best approach in my > opinion is to register multiple components (Which we can't do at the moment, > because there can only be one component per device). From a framework point Yes... I have tried to register 2 platforms in my ASoC platform driver but alsa considered they are the same platform since they are from the same device. > of view there is no difference between a single device with multiple > independent channels and multiple independent devices with one channel each. > Both have the same logical topology. > Yes, but in my case there is only one HW, one set of registers, and one set of clocks, it should be a single device node in the device tree. > - Lars > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Tue, 2015-10-13 at 16:42 +0200, Lars-Peter Clausen wrote: > On 10/13/2015 04:18 PM, Koro Chen wrote: > > On Tue, 2015-10-13 at 15:44 +0200, Lars-Peter Clausen wrote: > >> On 10/13/2015 03:37 PM, Koro Chen wrote: > >>> The patch "ASoC: Prevent components from being bound to multiple cards" > >>> adds check to prevent multiple cards from using the same component. > >>> However, snd_soc_register_platform() or snd_soc_register_codec() will > >>> also create components, and sharing the same platform by multiple cards > >>> is then refused. This happens with a platform having multiple > >>> independent DAIs that share the same DMA controller. > >>> > >>> Relax the condition by checking component->registered_as_component, > >>> which is only true in case of snd_soc_register_component() and > >>> will be false for components created by snd_soc_register_platform() > >>> or snd_soc_register_codec(). > >> > >> Binding a component to multiple cards results in internal data structure > >> corruption, regardless of whether it is a raw component, CODEC or platform, > >> which is why the check was added. So the proposed change wont work. > >> > > Thanks for your comment. Is it possible to share an example of how the > > data structure will be corrupted? So I can study into this further. > > Just look at soc_probe_component() and think about what happens if that runs > twice for two different cards. Multiple calls to list_add() on the same > list, controls are added multiple times, DAPM widgets are created multiple > times, the card field will only point to the last card. > When multiple binding happens, soc_probe_component() just returns zero without doing anything after this patch (actually it also returned zero before the patch "ASoC: Prevent components from being bound to multiple cards"). So the component still binds to the first card. For this case I think it should be fine? > > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Tue, 2015-10-13 at 15:44 +0200, Lars-Peter Clausen wrote: > On 10/13/2015 03:37 PM, Koro Chen wrote: > > The patch "ASoC: Prevent components from being bound to multiple cards" > > adds check to prevent multiple cards from using the same component. > > However, snd_soc_register_platform() or snd_soc_register_codec() will > > also create components, and sharing the same platform by multiple cards > > is then refused. This happens with a platform having multiple > > independent DAIs that share the same DMA controller. > > > > Relax the condition by checking component->registered_as_component, > > which is only true in case of snd_soc_register_component() and > > will be false for components created by snd_soc_register_platform() > > or snd_soc_register_codec(). > > Binding a component to multiple cards results in internal data structure > corruption, regardless of whether it is a raw component, CODEC or platform, > which is why the check was added. So the proposed change wont work. > Thanks for your comment. Is it possible to share an example of how the data structure will be corrupted? So I can study into this further. > > > > Signed-off-by: Koro Chen > > --- > > sound/soc/soc-core.c |3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c > > index 42575b0..eca169a 100644 > > --- a/sound/soc/soc-core.c > > +++ b/sound/soc/soc-core.c > > @@ -1106,7 +1106,8 @@ static int soc_probe_component(struct snd_soc_card > > *card, > > return 0; > > > > if (component->card) { > > - if (component->card != card) { > > + if (component->card != card && > > + component->registered_as_component) { > > dev_err(component->dev, > > "Trying to bind component to card \"%s\" but is > > already bound to card \"%s\"\n", > > card->name, component->card->name); > > > > ___ > Alsa-devel mailing list > alsa-de...@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] ASoC: Modify check condition of multiple bindings of components
The patch "ASoC: Prevent components from being bound to multiple cards" adds check to prevent multiple cards from using the same component. However, snd_soc_register_platform() or snd_soc_register_codec() will also create components, and sharing the same platform by multiple cards is then refused. This happens with a platform having multiple independent DAIs that share the same DMA controller. Relax the condition by checking component->registered_as_component, which is only true in case of snd_soc_register_component() and will be false for components created by snd_soc_register_platform() or snd_soc_register_codec(). Signed-off-by: Koro Chen --- sound/soc/soc-core.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 42575b0..eca169a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1106,7 +1106,8 @@ static int soc_probe_component(struct snd_soc_card *card, return 0; if (component->card) { - if (component->card != card) { + if (component->card != card && + component->registered_as_component) { dev_err(component->dev, "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n", card->name, component->card->name); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] ASoC: Modify check condition of multiple bindings of components
The patch "ASoC: Prevent components from being bound to multiple cards" adds check to prevent multiple cards from using the same component. However, snd_soc_register_platform() or snd_soc_register_codec() will also create components, and sharing the same platform by multiple cards is then refused. This happens with a platform having multiple independent DAIs that share the same DMA controller. Relax the condition by checking component->registered_as_component, which is only true in case of snd_soc_register_component() and will be false for components created by snd_soc_register_platform() or snd_soc_register_codec(). Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/soc-core.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 42575b0..eca169a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1106,7 +1106,8 @@ static int soc_probe_component(struct snd_soc_card *card, return 0; if (component->card) { - if (component->card != card) { + if (component->card != card && + component->registered_as_component) { dev_err(component->dev, "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n", card->name, component->card->name); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Tue, 2015-10-13 at 15:44 +0200, Lars-Peter Clausen wrote: > On 10/13/2015 03:37 PM, Koro Chen wrote: > > The patch "ASoC: Prevent components from being bound to multiple cards" > > adds check to prevent multiple cards from using the same component. > > However, snd_soc_register_platform() or snd_soc_register_codec() will > > also create components, and sharing the same platform by multiple cards > > is then refused. This happens with a platform having multiple > > independent DAIs that share the same DMA controller. > > > > Relax the condition by checking component->registered_as_component, > > which is only true in case of snd_soc_register_component() and > > will be false for components created by snd_soc_register_platform() > > or snd_soc_register_codec(). > > Binding a component to multiple cards results in internal data structure > corruption, regardless of whether it is a raw component, CODEC or platform, > which is why the check was added. So the proposed change wont work. > Thanks for your comment. Is it possible to share an example of how the data structure will be corrupted? So I can study into this further. > > > > Signed-off-by: Koro Chen <koro.c...@mediatek.com> > > --- > > sound/soc/soc-core.c |3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c > > index 42575b0..eca169a 100644 > > --- a/sound/soc/soc-core.c > > +++ b/sound/soc/soc-core.c > > @@ -1106,7 +1106,8 @@ static int soc_probe_component(struct snd_soc_card > > *card, > > return 0; > > > > if (component->card) { > > - if (component->card != card) { > > + if (component->card != card && > > + component->registered_as_component) { > > dev_err(component->dev, > > "Trying to bind component to card \"%s\" but is > > already bound to card \"%s\"\n", > > card->name, component->card->name); > > > > ___ > Alsa-devel mailing list > alsa-de...@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [RFC PATCH] ASoC: Modify check condition of multiple bindings of components
On Tue, 2015-10-13 at 16:42 +0200, Lars-Peter Clausen wrote: > On 10/13/2015 04:18 PM, Koro Chen wrote: > > On Tue, 2015-10-13 at 15:44 +0200, Lars-Peter Clausen wrote: > >> On 10/13/2015 03:37 PM, Koro Chen wrote: > >>> The patch "ASoC: Prevent components from being bound to multiple cards" > >>> adds check to prevent multiple cards from using the same component. > >>> However, snd_soc_register_platform() or snd_soc_register_codec() will > >>> also create components, and sharing the same platform by multiple cards > >>> is then refused. This happens with a platform having multiple > >>> independent DAIs that share the same DMA controller. > >>> > >>> Relax the condition by checking component->registered_as_component, > >>> which is only true in case of snd_soc_register_component() and > >>> will be false for components created by snd_soc_register_platform() > >>> or snd_soc_register_codec(). > >> > >> Binding a component to multiple cards results in internal data structure > >> corruption, regardless of whether it is a raw component, CODEC or platform, > >> which is why the check was added. So the proposed change wont work. > >> > > Thanks for your comment. Is it possible to share an example of how the > > data structure will be corrupted? So I can study into this further. > > Just look at soc_probe_component() and think about what happens if that runs > twice for two different cards. Multiple calls to list_add() on the same > list, controls are added multiple times, DAPM widgets are created multiple > times, the card field will only point to the last card. > When multiple binding happens, soc_probe_component() just returns zero without doing anything after this patch (actually it also returned zero before the patch "ASoC: Prevent components from being bound to multiple cards"). So the component still binds to the first card. For this case I think it should be fine? > > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ASoC: mediatek: Increase periods_min in capture
On Wed, 2015-09-23 at 09:12 -0700, Mark Brown wrote: > On Wed, Sep 23, 2015 at 06:03:19PM +0800, Koro Chen wrote: > > Any suggestion for this patch? > > > > On Mon, 2015-09-14 at 14:51 +0800, Koro Chen wrote: > > > In capture, there is chance that hw_ptr reported at IRQ is > > > a little smaller than period_size due to internal AFE buffer. > > > In the case of ping-pong buffer: > > Please don't top post or send content free pings. I'm not entirely sure > what you're asking for here - the patch has been applied, what further > suggestions were you looking for? I am sorry about the top posting ping... will never do this again. OK thank you, now I see the patch is already in the tree, but I am sure I didn't get the mail titled "Applied xxx to the asoc tree", so I didn't know the patch status. Maybe something was wrong with the mail system? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ASoC: mediatek: Increase periods_min in capture
Any suggestion for this patch? On Mon, 2015-09-14 at 14:51 +0800, Koro Chen wrote: > In capture, there is chance that hw_ptr reported at IRQ is > a little smaller than period_size due to internal AFE buffer. > In the case of ping-pong buffer: > > |--|-| > hw_ptr < period_size > > This available buffer will not be read since its size is smaller than > avail_min (which is period_size by default), and read thread continues > to sleep. If the next hw_ptr is just a little larger than buffer_size, > overrun occurs. One more period can hold the possible unread buffer. > > Signed-off-by: Koro Chen > --- > sound/soc/mediatek/mtk-afe-pcm.c | 17 + > 1 file changed, 17 insertions(+) > > diff --git a/sound/soc/mediatek/mtk-afe-pcm.c > b/sound/soc/mediatek/mtk-afe-pcm.c > index d190fe0..f5baf3c 100644 > --- a/sound/soc/mediatek/mtk-afe-pcm.c > +++ b/sound/soc/mediatek/mtk-afe-pcm.c > @@ -549,6 +549,23 @@ static int mtk_afe_dais_startup(struct snd_pcm_substream > *substream, > memif->substream = substream; > > snd_soc_set_runtime_hwparams(substream, _afe_hardware); > + > + /* > + * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be > + * smaller than period_size due to AFE's internal buffer. > + * This easily leads to overrun when avail_min is period_size. > + * One more period can hold the possible unread buffer. > + */ > + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { > + ret = snd_pcm_hw_constraint_minmax(runtime, > +SNDRV_PCM_HW_PARAM_PERIODS, > +3, > + > mtk_afe_hardware.periods_max); > + if (ret < 0) { > + dev_err(afe->dev, "hw_constraint_minmax failed\n"); > + return ret; > + } > + } > ret = snd_pcm_hw_constraint_integer(runtime, > SNDRV_PCM_HW_PARAM_PERIODS); > if (ret < 0) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ASoC: mediatek: Increase periods_min in capture
Any suggestion for this patch? On Mon, 2015-09-14 at 14:51 +0800, Koro Chen wrote: > In capture, there is chance that hw_ptr reported at IRQ is > a little smaller than period_size due to internal AFE buffer. > In the case of ping-pong buffer: > > |--|-| > hw_ptr < period_size > > This available buffer will not be read since its size is smaller than > avail_min (which is period_size by default), and read thread continues > to sleep. If the next hw_ptr is just a little larger than buffer_size, > overrun occurs. One more period can hold the possible unread buffer. > > Signed-off-by: Koro Chen <koro.c...@mediatek.com> > --- > sound/soc/mediatek/mtk-afe-pcm.c | 17 + > 1 file changed, 17 insertions(+) > > diff --git a/sound/soc/mediatek/mtk-afe-pcm.c > b/sound/soc/mediatek/mtk-afe-pcm.c > index d190fe0..f5baf3c 100644 > --- a/sound/soc/mediatek/mtk-afe-pcm.c > +++ b/sound/soc/mediatek/mtk-afe-pcm.c > @@ -549,6 +549,23 @@ static int mtk_afe_dais_startup(struct snd_pcm_substream > *substream, > memif->substream = substream; > > snd_soc_set_runtime_hwparams(substream, _afe_hardware); > + > + /* > + * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be > + * smaller than period_size due to AFE's internal buffer. > + * This easily leads to overrun when avail_min is period_size. > + * One more period can hold the possible unread buffer. > + */ > + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { > + ret = snd_pcm_hw_constraint_minmax(runtime, > +SNDRV_PCM_HW_PARAM_PERIODS, > +3, > + > mtk_afe_hardware.periods_max); > + if (ret < 0) { > + dev_err(afe->dev, "hw_constraint_minmax failed\n"); > + return ret; > + } > + } > ret = snd_pcm_hw_constraint_integer(runtime, > SNDRV_PCM_HW_PARAM_PERIODS); > if (ret < 0) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ASoC: mediatek: Increase periods_min in capture
On Wed, 2015-09-23 at 09:12 -0700, Mark Brown wrote: > On Wed, Sep 23, 2015 at 06:03:19PM +0800, Koro Chen wrote: > > Any suggestion for this patch? > > > > On Mon, 2015-09-14 at 14:51 +0800, Koro Chen wrote: > > > In capture, there is chance that hw_ptr reported at IRQ is > > > a little smaller than period_size due to internal AFE buffer. > > > In the case of ping-pong buffer: > > Please don't top post or send content free pings. I'm not entirely sure > what you're asking for here - the patch has been applied, what further > suggestions were you looking for? I am sorry about the top posting ping... will never do this again. OK thank you, now I see the patch is already in the tree, but I am sure I didn't get the mail titled "Applied xxx to the asoc tree", so I didn't know the patch status. Maybe something was wrong with the mail system? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Increase periods_min in capture
In capture, there is chance that hw_ptr reported at IRQ is a little smaller than period_size due to internal AFE buffer. In the case of ping-pong buffer: |--|-| hw_ptr < period_size This available buffer will not be read since its size is smaller than avail_min (which is period_size by default), and read thread continues to sleep. If the next hw_ptr is just a little larger than buffer_size, overrun occurs. One more period can hold the possible unread buffer. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-pcm.c | 17 + 1 file changed, 17 insertions(+) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index d190fe0..f5baf3c 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -549,6 +549,23 @@ static int mtk_afe_dais_startup(struct snd_pcm_substream *substream, memif->substream = substream; snd_soc_set_runtime_hwparams(substream, _afe_hardware); + + /* +* Capture cannot use ping-pong buffer since hw_ptr at IRQ may be +* smaller than period_size due to AFE's internal buffer. +* This easily leads to overrun when avail_min is period_size. +* One more period can hold the possible unread buffer. +*/ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIODS, + 3, + mtk_afe_hardware.periods_max); + if (ret < 0) { + dev_err(afe->dev, "hw_constraint_minmax failed\n"); + return ret; + } + } ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Increase periods_min in capture
In capture, there is chance that hw_ptr reported at IRQ is a little smaller than period_size due to internal AFE buffer. In the case of ping-pong buffer: |--|-| hw_ptr < period_size This available buffer will not be read since its size is smaller than avail_min (which is period_size by default), and read thread continues to sleep. If the next hw_ptr is just a little larger than buffer_size, overrun occurs. One more period can hold the possible unread buffer. Signed-off-by: Koro Chen <koro.c...@mediatek.com> --- sound/soc/mediatek/mtk-afe-pcm.c | 17 + 1 file changed, 17 insertions(+) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index d190fe0..f5baf3c 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -549,6 +549,23 @@ static int mtk_afe_dais_startup(struct snd_pcm_substream *substream, memif->substream = substream; snd_soc_set_runtime_hwparams(substream, _afe_hardware); + + /* +* Capture cannot use ping-pong buffer since hw_ptr at IRQ may be +* smaller than period_size due to AFE's internal buffer. +* This easily leads to overrun when avail_min is period_size. +* One more period can hold the possible unread buffer. +*/ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIODS, + 3, + mtk_afe_hardware.periods_max); + if (ret < 0) { + dev_err(afe->dev, "hw_constraint_minmax failed\n"); + return ret; + } + } ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Remove AIF widgets for backend DAIs
DAPM core already creates widgets for DAIs. It is not necessary to declare them by SND_SOC_DAPM_AIF_IN/SND_SOC_DAPM_AIF_OUT. Furthermore, original codes use backend DAI's stream name to be the AIF widget name. It causes the same widget to be created twice, and after commit 92fa12426741 ("ASoC: dapm: Add new widgets to the end of the widget list") the first created widget (by snd_soc_dapm_new_controls) is used, not the 2nd created one (by snd_soc_dapm_new_dai_widgets), so audio path is broken. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-pcm.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 55471ee..d190fe0 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -897,10 +897,6 @@ static const struct snd_kcontrol_new mtk_afe_o10_mix[] = { }; static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = { - /* Backend DAIs */ - SND_SOC_DAPM_AIF_IN("I2S Capture", NULL, 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S Playback", NULL, 0, SND_SOC_NOPM, 0, 0), - /* inter-connections */ SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -932,11 +928,6 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = { { "O10", "I18 Switch", "I18" }, }; -static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = { - /* Backend DAIs */ - SND_SOC_DAPM_AIF_OUT("HDMIO Playback", NULL, 0, SND_SOC_NOPM, 0, 0), -}; - static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = { {"HDMIO Playback", NULL, "HDMI"}, }; @@ -951,8 +942,6 @@ static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = { static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = { .name = "mtk-afe-hdmi-dai", - .dapm_widgets = mtk_afe_hdmi_widgets, - .num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets), .dapm_routes = mtk_afe_hdmi_routes, .num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes), }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Remove AIF widgets for backend DAIs
DAPM core already creates widgets for DAIs. It is not necessary to declare them by SND_SOC_DAPM_AIF_IN/SND_SOC_DAPM_AIF_OUT. Furthermore, original codes use backend DAI's stream name to be the AIF widget name. It causes the same widget to be created twice, and after commit 92fa12426741 (ASoC: dapm: Add new widgets to the end of the widget list) the first created widget (by snd_soc_dapm_new_controls) is used, not the 2nd created one (by snd_soc_dapm_new_dai_widgets), so audio path is broken. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/mediatek/mtk-afe-pcm.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index 55471ee..d190fe0 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -897,10 +897,6 @@ static const struct snd_kcontrol_new mtk_afe_o10_mix[] = { }; static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = { - /* Backend DAIs */ - SND_SOC_DAPM_AIF_IN(I2S Capture, NULL, 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT(I2S Playback, NULL, 0, SND_SOC_NOPM, 0, 0), - /* inter-connections */ SND_SOC_DAPM_MIXER(I05, SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER(I06, SND_SOC_NOPM, 0, 0, NULL, 0), @@ -932,11 +928,6 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = { { O10, I18 Switch, I18 }, }; -static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = { - /* Backend DAIs */ - SND_SOC_DAPM_AIF_OUT(HDMIO Playback, NULL, 0, SND_SOC_NOPM, 0, 0), -}; - static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = { {HDMIO Playback, NULL, HDMI}, }; @@ -951,8 +942,6 @@ static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = { static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = { .name = mtk-afe-hdmi-dai, - .dapm_widgets = mtk_afe_hdmi_widgets, - .num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets), .dapm_routes = mtk_afe_hdmi_routes, .num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes), }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Add suspend/resume callbacks
This adds suspend/resume callbacks, which are common for each DAI. To be able to continue the last playback/capture after resume when suspend was done during a playback/capture, in the callbacks we do backup/restore of registers which were set before prepare stage. Registers to be backup/restore are defined in a backup list array. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-common.h | 8 sound/soc/mediatek/mtk-afe-pcm.c| 77 + 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h index a88b175..cc4393c 100644 --- a/sound/soc/mediatek/mtk-afe-common.h +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -98,12 +98,4 @@ struct mtk_afe_memif { const struct mtk_afe_irq_data *irqdata; }; -struct mtk_afe { - /* address for ioremap audio hardware register */ - void __iomem *base_addr; - struct device *dev; - struct regmap *regmap; - struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM]; - struct clk *clocks[MTK_CLK_NUM]; -}; #endif diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index de38d2e..55471ee 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -45,18 +45,21 @@ /* Memory interface */ #define AFE_DL1_BASE 0x0040 #define AFE_DL1_CUR0x0044 +#define AFE_DL1_END0x0048 #define AFE_DL2_BASE 0x0050 #define AFE_DL2_CUR0x0054 #define AFE_AWB_BASE 0x0070 #define AFE_AWB_CUR0x007c #define AFE_VUL_BASE 0x0080 #define AFE_VUL_CUR0x008c +#define AFE_VUL_END0x0088 #define AFE_DAI_BASE 0x0090 #define AFE_DAI_CUR0x009c #define AFE_MOD_PCM_BASE 0x0330 #define AFE_MOD_PCM_CUR0x033c #define AFE_HDMI_OUT_BASE 0x0374 #define AFE_HDMI_OUT_CUR 0x0378 +#define AFE_HDMI_OUT_END 0x037c #define AFE_ADDA2_TOP_CON0 0x0600 @@ -127,6 +130,34 @@ enum afe_tdm_ch_start { AFE_TDM_CH_ZERO, }; +static const unsigned int mtk_afe_backup_list[] = { + AUDIO_TOP_CON0, + AFE_CONN1, + AFE_CONN2, + AFE_CONN7, + AFE_CONN8, + AFE_DAC_CON1, + AFE_DL1_BASE, + AFE_DL1_END, + AFE_VUL_BASE, + AFE_VUL_END, + AFE_HDMI_OUT_BASE, + AFE_HDMI_OUT_END, + AFE_HDMI_CONN0, + AFE_DAC_CON0, +}; + +struct mtk_afe { + /* address for ioremap audio hardware register */ + void __iomem *base_addr; + struct device *dev; + struct regmap *regmap; + struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM]; + struct clk *clocks[MTK_CLK_NUM]; + unsigned int backup_regs[ARRAY_SIZE(mtk_afe_backup_list)]; + bool suspended; +}; + static const struct snd_pcm_hardware mtk_afe_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -722,11 +753,53 @@ static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = { }; +static int mtk_afe_runtime_suspend(struct device *dev); +static int mtk_afe_runtime_resume(struct device *dev); + +static int mtk_afe_dai_suspend(struct snd_soc_dai *dai) +{ + struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai); + int i; + + dev_dbg(afe->dev, "%s\n", __func__); + if (pm_runtime_status_suspended(afe->dev) || afe->suspended) + return 0; + + for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++) + regmap_read(afe->regmap, mtk_afe_backup_list[i], + >backup_regs[i]); + + afe->suspended = true; + mtk_afe_runtime_suspend(afe->dev); + return 0; +} + +static int mtk_afe_dai_resume(struct snd_soc_dai *dai) +{ + struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai); + int i = 0; + + dev_dbg(afe->dev, "%s\n", __func__); + if (pm_runtime_status_suspended(afe->dev) || !afe->suspended) + return 0; + + mtk_afe_runtime_resume(afe->dev); + + for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++) + regmap_write(afe->regmap, mtk_afe_backup_list[i], +afe->backup_regs[i]); + + afe->suspended = false; + return 0; +} + static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = { /* FE DAIs: memory intefaces to CPU */ { .name = "DL1", /* downlink 1 */ .id = MTK_AFE_MEMIF_DL1, + .suspend = mtk_afe_dai_suspend, + .resume = mtk_afe_dai_resume, .playback = { .stream_name = "DL1", .channels_min = 1, @@ -738,6 +811,8 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = { }, { .name = "VUL", /* voice
[PATCH] ASoC: mediatek: Add suspend/resume callbacks
This adds suspend/resume callbacks, which are common for each DAI. To be able to continue the last playback/capture after resume when suspend was done during a playback/capture, in the callbacks we do backup/restore of registers which were set before prepare stage. Registers to be backup/restore are defined in a backup list array. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/mediatek/mtk-afe-common.h | 8 sound/soc/mediatek/mtk-afe-pcm.c| 77 + 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h index a88b175..cc4393c 100644 --- a/sound/soc/mediatek/mtk-afe-common.h +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -98,12 +98,4 @@ struct mtk_afe_memif { const struct mtk_afe_irq_data *irqdata; }; -struct mtk_afe { - /* address for ioremap audio hardware register */ - void __iomem *base_addr; - struct device *dev; - struct regmap *regmap; - struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM]; - struct clk *clocks[MTK_CLK_NUM]; -}; #endif diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index de38d2e..55471ee 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -45,18 +45,21 @@ /* Memory interface */ #define AFE_DL1_BASE 0x0040 #define AFE_DL1_CUR0x0044 +#define AFE_DL1_END0x0048 #define AFE_DL2_BASE 0x0050 #define AFE_DL2_CUR0x0054 #define AFE_AWB_BASE 0x0070 #define AFE_AWB_CUR0x007c #define AFE_VUL_BASE 0x0080 #define AFE_VUL_CUR0x008c +#define AFE_VUL_END0x0088 #define AFE_DAI_BASE 0x0090 #define AFE_DAI_CUR0x009c #define AFE_MOD_PCM_BASE 0x0330 #define AFE_MOD_PCM_CUR0x033c #define AFE_HDMI_OUT_BASE 0x0374 #define AFE_HDMI_OUT_CUR 0x0378 +#define AFE_HDMI_OUT_END 0x037c #define AFE_ADDA2_TOP_CON0 0x0600 @@ -127,6 +130,34 @@ enum afe_tdm_ch_start { AFE_TDM_CH_ZERO, }; +static const unsigned int mtk_afe_backup_list[] = { + AUDIO_TOP_CON0, + AFE_CONN1, + AFE_CONN2, + AFE_CONN7, + AFE_CONN8, + AFE_DAC_CON1, + AFE_DL1_BASE, + AFE_DL1_END, + AFE_VUL_BASE, + AFE_VUL_END, + AFE_HDMI_OUT_BASE, + AFE_HDMI_OUT_END, + AFE_HDMI_CONN0, + AFE_DAC_CON0, +}; + +struct mtk_afe { + /* address for ioremap audio hardware register */ + void __iomem *base_addr; + struct device *dev; + struct regmap *regmap; + struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM]; + struct clk *clocks[MTK_CLK_NUM]; + unsigned int backup_regs[ARRAY_SIZE(mtk_afe_backup_list)]; + bool suspended; +}; + static const struct snd_pcm_hardware mtk_afe_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -722,11 +753,53 @@ static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = { }; +static int mtk_afe_runtime_suspend(struct device *dev); +static int mtk_afe_runtime_resume(struct device *dev); + +static int mtk_afe_dai_suspend(struct snd_soc_dai *dai) +{ + struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai); + int i; + + dev_dbg(afe-dev, %s\n, __func__); + if (pm_runtime_status_suspended(afe-dev) || afe-suspended) + return 0; + + for (i = 0; i ARRAY_SIZE(mtk_afe_backup_list); i++) + regmap_read(afe-regmap, mtk_afe_backup_list[i], + afe-backup_regs[i]); + + afe-suspended = true; + mtk_afe_runtime_suspend(afe-dev); + return 0; +} + +static int mtk_afe_dai_resume(struct snd_soc_dai *dai) +{ + struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai); + int i = 0; + + dev_dbg(afe-dev, %s\n, __func__); + if (pm_runtime_status_suspended(afe-dev) || !afe-suspended) + return 0; + + mtk_afe_runtime_resume(afe-dev); + + for (i = 0; i ARRAY_SIZE(mtk_afe_backup_list); i++) + regmap_write(afe-regmap, mtk_afe_backup_list[i], +afe-backup_regs[i]); + + afe-suspended = false; + return 0; +} + static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = { /* FE DAIs: memory intefaces to CPU */ { .name = DL1, /* downlink 1 */ .id = MTK_AFE_MEMIF_DL1, + .suspend = mtk_afe_dai_suspend, + .resume = mtk_afe_dai_resume, .playback = { .stream_name = DL1, .channels_min = 1, @@ -738,6 +811,8 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = { }, { .name = VUL, /* voice uplink */ .id = MTK_AFE_MEMIF_VUL, + .suspend = mtk_afe_dai_suspend
[PATCH v2 1/2] ASoC: rt5645: Fix missing free_irq
The driver does not free irq when snd_soc_register_codec returns error. It does not return error when request irq failed, either. Add return when request irq failed, and free_irq if snd_soc_register_codec failed. Signed-off-by: Koro Chen --- Change since v1: - use free_irq instead of devm_request_threaded_irq --- sound/soc/codecs/rt5645.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 2cedf0d..56e8c31 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3401,12 +3401,23 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5645", rt5645); - if (ret) + if (ret) { dev_err(>dev, "Failed to reguest IRQ: %d\n", ret); + return ret; + } } - return snd_soc_register_codec(>dev, _codec_dev_rt5645, - rt5645_dai, ARRAY_SIZE(rt5645_dai)); + ret = snd_soc_register_codec(>dev, _codec_dev_rt5645, +rt5645_dai, ARRAY_SIZE(rt5645_dai)); + if (ret) + goto err_irq; + + return 0; + +err_irq: + if (rt5645->i2c->irq) + free_irq(rt5645->i2c->irq, rt5645); + return ret; } static int rt5645_i2c_remove(struct i2c_client *i2c) -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/2] ASoC: rt5645: Add regulator support
This adds basic regulator support for rt5645. Signed-off-by: Koro Chen --- Change since v1: - none --- sound/soc/codecs/rt5645.c | 61 --- sound/soc/codecs/rt5645.h | 26 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 56e8c31..7a68d47 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, }; +static const char *const rt5645_supply_names[] = { + "avdd", + "cpvdd", +}; + +struct rt5645_priv { + struct snd_soc_codec *codec; + struct rt5645_platform_data pdata; + struct regmap *regmap; + struct i2c_client *i2c; + struct gpio_desc *gpiod_hp_det; + struct snd_soc_jack *hp_jack; + struct snd_soc_jack *mic_jack; + struct snd_soc_jack *btn_jack; + struct delayed_work jack_detect_work; + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; + + int codec_type; + int sysclk; + int sysclk_src; + int lrck[RT5645_AIFS]; + int bclk[RT5645_AIFS]; + int master[RT5645_AIFS]; + + int pll_src; + int pll_in; + int pll_out; + + int jack_type; + bool en_button_func; +}; + static int rt5645_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, RT5645_RESET, 0); @@ -3218,7 +3251,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, { struct rt5645_platform_data *pdata = dev_get_platdata(>dev); struct rt5645_priv *rt5645; - int ret; + int ret, i; unsigned int val; rt5645 = devm_kzalloc(>dev, sizeof(struct rt5645_priv), @@ -3252,6 +3285,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, return ret; } + for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) + rt5645->supplies[i].supply = rt5645_supply_names[i]; + + ret = devm_regulator_bulk_get(>dev, + ARRAY_SIZE(rt5645->supplies), + rt5645->supplies); + if (ret) { + dev_err(>dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(rt5645->supplies), + rt5645->supplies); + if (ret) { + dev_err(>dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, ); switch (val) { @@ -3265,7 +3316,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, dev_err(>dev, "Device with ID register %#x is not rt5645 or rt5650\n", val); - return -ENODEV; + ret = -ENODEV; + goto err_enable; } if (rt5645->codec_type == CODEC_TYPE_RT5650) { @@ -3403,7 +3455,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | IRQF_ONESHOT, "rt5645", rt5645); if (ret) { dev_err(>dev, "Failed to reguest IRQ: %d\n", ret); - return ret; + goto err_enable; } } @@ -3417,6 +3469,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, err_irq: if (rt5645->i2c->irq) free_irq(rt5645->i2c->irq, rt5645); +err_enable: + regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); return ret; } @@ -3430,6 +3484,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) cancel_delayed_work_sync(>jack_detect_work); snd_soc_unregister_codec(>dev); + regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); return 0; } diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 0353a6a..199b22f 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2177,32 +2177,6 @@ enum { int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int filter_mask, unsigned int clk_src); -struct rt5645_priv { - struct snd_soc_codec *codec; - struct rt5645_platform_data pdata; - struct regmap *regmap; - struct i2c_client *i2c; - struct gpio_desc *gpiod_hp_det; - struct snd_soc_jack *hp_jack; - struct snd_soc_jack *mic_jack; - struct snd_soc_jack *btn_jack; - struct delayed_work jack_detect_work; - - int codec_type; - int sysclk; - int sysclk_src; - int lrck[RT5645_AIFS]; -
[PATCH v2 1/2] ASoC: rt5645: Fix missing free_irq
The driver does not free irq when snd_soc_register_codec returns error. It does not return error when request irq failed, either. Add return when request irq failed, and free_irq if snd_soc_register_codec failed. Signed-off-by: Koro Chen koro.c...@mediatek.com --- Change since v1: - use free_irq instead of devm_request_threaded_irq --- sound/soc/codecs/rt5645.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 2cedf0d..56e8c31 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3401,12 +3401,23 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ret = request_threaded_irq(rt5645-i2c-irq, NULL, rt5645_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, rt5645, rt5645); - if (ret) + if (ret) { dev_err(i2c-dev, Failed to reguest IRQ: %d\n, ret); + return ret; + } } - return snd_soc_register_codec(i2c-dev, soc_codec_dev_rt5645, - rt5645_dai, ARRAY_SIZE(rt5645_dai)); + ret = snd_soc_register_codec(i2c-dev, soc_codec_dev_rt5645, +rt5645_dai, ARRAY_SIZE(rt5645_dai)); + if (ret) + goto err_irq; + + return 0; + +err_irq: + if (rt5645-i2c-irq) + free_irq(rt5645-i2c-irq, rt5645); + return ret; } static int rt5645_i2c_remove(struct i2c_client *i2c) -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/2] ASoC: rt5645: Add regulator support
This adds basic regulator support for rt5645. Signed-off-by: Koro Chen koro.c...@mediatek.com --- Change since v1: - none --- sound/soc/codecs/rt5645.c | 61 --- sound/soc/codecs/rt5645.h | 26 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 56e8c31..7a68d47 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -21,6 +21,7 @@ #include linux/gpio/consumer.h #include linux/acpi.h #include linux/dmi.h +#include linux/regulator/consumer.h #include sound/core.h #include sound/pcm.h #include sound/pcm_params.h @@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, }; +static const char *const rt5645_supply_names[] = { + avdd, + cpvdd, +}; + +struct rt5645_priv { + struct snd_soc_codec *codec; + struct rt5645_platform_data pdata; + struct regmap *regmap; + struct i2c_client *i2c; + struct gpio_desc *gpiod_hp_det; + struct snd_soc_jack *hp_jack; + struct snd_soc_jack *mic_jack; + struct snd_soc_jack *btn_jack; + struct delayed_work jack_detect_work; + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; + + int codec_type; + int sysclk; + int sysclk_src; + int lrck[RT5645_AIFS]; + int bclk[RT5645_AIFS]; + int master[RT5645_AIFS]; + + int pll_src; + int pll_in; + int pll_out; + + int jack_type; + bool en_button_func; +}; + static int rt5645_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, RT5645_RESET, 0); @@ -3218,7 +3251,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, { struct rt5645_platform_data *pdata = dev_get_platdata(i2c-dev); struct rt5645_priv *rt5645; - int ret; + int ret, i; unsigned int val; rt5645 = devm_kzalloc(i2c-dev, sizeof(struct rt5645_priv), @@ -3252,6 +3285,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, return ret; } + for (i = 0; i ARRAY_SIZE(rt5645-supplies); i++) + rt5645-supplies[i].supply = rt5645_supply_names[i]; + + ret = devm_regulator_bulk_get(i2c-dev, + ARRAY_SIZE(rt5645-supplies), + rt5645-supplies); + if (ret) { + dev_err(i2c-dev, Failed to request supplies: %d\n, ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(rt5645-supplies), + rt5645-supplies); + if (ret) { + dev_err(i2c-dev, Failed to enable supplies: %d\n, ret); + return ret; + } + regmap_read(rt5645-regmap, RT5645_VENDOR_ID2, val); switch (val) { @@ -3265,7 +3316,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, dev_err(i2c-dev, Device with ID register %#x is not rt5645 or rt5650\n, val); - return -ENODEV; + ret = -ENODEV; + goto err_enable; } if (rt5645-codec_type == CODEC_TYPE_RT5650) { @@ -3403,7 +3455,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | IRQF_ONESHOT, rt5645, rt5645); if (ret) { dev_err(i2c-dev, Failed to reguest IRQ: %d\n, ret); - return ret; + goto err_enable; } } @@ -3417,6 +3469,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, err_irq: if (rt5645-i2c-irq) free_irq(rt5645-i2c-irq, rt5645); +err_enable: + regulator_bulk_disable(ARRAY_SIZE(rt5645-supplies), rt5645-supplies); return ret; } @@ -3430,6 +3484,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) cancel_delayed_work_sync(rt5645-jack_detect_work); snd_soc_unregister_codec(i2c-dev); + regulator_bulk_disable(ARRAY_SIZE(rt5645-supplies), rt5645-supplies); return 0; } diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 0353a6a..199b22f 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2177,32 +2177,6 @@ enum { int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int filter_mask, unsigned int clk_src); -struct rt5645_priv { - struct snd_soc_codec *codec; - struct rt5645_platform_data pdata; - struct regmap *regmap; - struct i2c_client *i2c; - struct gpio_desc *gpiod_hp_det; - struct snd_soc_jack *hp_jack; - struct snd_soc_jack *mic_jack; - struct snd_soc_jack *btn_jack; - struct delayed_work jack_detect_work; - - int codec_type; - int sysclk; - int sysclk_src; - int lrck[RT5645_AIFS]; - int bclk
Re: [PATCH v2] arm64: dts: mt8173: Add afe device node
On Thu, 2015-07-09 at 18:45 +0800, Daniel Kurtz wrote: > On Thu, Jul 9, 2015 at 11:32 AM, Koro Chen wrote: > > This adds afe (audio front end) device node to the MT8173 dtsi file. > > > > Signed-off-by: Koro Chen > > Reviewed-by: Daniel Kurtz > > I believe this patch depends on the fix in: > https://patchwork.kernel.org/patch/6752521/ > > If so, I think it would have been better to upload them together and > mention the dependency in the cover letter. > However, now that they are both on the list, we just need to ensure > they are merged together. The above patch was already merged, so now it is OK to merge this one (If there is no problem for this patch, of course) > > -Dan > > > > --- > > This patch is based on Matthias's tree: > > https://github.com/mbgg/linux-mediatek > > branch: v4.2-next/arm64 > > > > Changes since v1: > > - change node name to afe: audio-controller@1122 > > --- > > arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 > > > > 1 file changed, 32 insertions(+) > > > > diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > b/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > index 0696f8f..ce9255a 100644 > > --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > @@ -14,6 +14,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include "mt8173-pinfunc.h" > > > > @@ -393,6 +394,37 @@ > > #size-cells = <0>; > > status = "disabled"; > > }; > > + > > + afe: audio-controller@1122 { > > + compatible = "mediatek,mt8173-afe-pcm"; > > + reg = <0 0x1122 0 0x1000>; > > + interrupts = ; > > + power-domains = < MT8173_POWER_DOMAIN_AUDIO>; > > + clocks = < CLK_INFRA_AUDIO>, > > +< CLK_TOP_AUDIO_SEL>, > > +< CLK_TOP_AUD_INTBUS_SEL>, > > +< CLK_TOP_APLL1_DIV0>, > > +< CLK_TOP_APLL2_DIV0>, > > +< CLK_TOP_I2S0_M_SEL>, > > +< CLK_TOP_I2S1_M_SEL>, > > +< CLK_TOP_I2S2_M_SEL>, > > +< CLK_TOP_I2S3_M_SEL>, > > +< CLK_TOP_I2S3_B_SEL>; > > + clock-names = "infra_sys_audio_clk", > > + "top_pdn_audio", > > + "top_pdn_aud_intbus", > > + "bck0", > > + "bck1", > > + "i2s0_m", > > + "i2s1_m", > > + "i2s2_m", > > + "i2s3_m", > > + "i2s3_b"; > > + assigned-clocks = < CLK_TOP_AUD_1_SEL>, > > + < CLK_TOP_AUD_2_SEL>; > > + assigned-clock-parents = < CLK_TOP_APLL1>, > > +< CLK_TOP_APLL2>; > > + }; > > }; > > }; > > > > -- > > 1.8.1.1.dirty > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] arm64: dts: mt8173: Add afe device node
On Thu, 2015-07-09 at 18:45 +0800, Daniel Kurtz wrote: On Thu, Jul 9, 2015 at 11:32 AM, Koro Chen koro.c...@mediatek.com wrote: This adds afe (audio front end) device node to the MT8173 dtsi file. Signed-off-by: Koro Chen koro.c...@mediatek.com Reviewed-by: Daniel Kurtz djku...@chromium.org I believe this patch depends on the fix in: https://patchwork.kernel.org/patch/6752521/ If so, I think it would have been better to upload them together and mention the dependency in the cover letter. However, now that they are both on the list, we just need to ensure they are merged together. The above patch was already merged, so now it is OK to merge this one (If there is no problem for this patch, of course) -Dan --- This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Changes since v1: - change node name to afe: audio-controller@1122 --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..ce9255a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include dt-bindings/clock/mt8173-clk.h #include dt-bindings/interrupt-controller/irq.h #include dt-bindings/interrupt-controller/arm-gic.h +#include dt-bindings/power/mt8173-power.h #include dt-bindings/reset-controller/mt8173-resets.h #include mt8173-pinfunc.h @@ -393,6 +394,37 @@ #size-cells = 0; status = disabled; }; + + afe: audio-controller@1122 { + compatible = mediatek,mt8173-afe-pcm; + reg = 0 0x1122 0 0x1000; + interrupts = GIC_SPI 134 IRQ_TYPE_EDGE_FALLING; + power-domains = scpsys MT8173_POWER_DOMAIN_AUDIO; + clocks = infracfg CLK_INFRA_AUDIO, +topckgen CLK_TOP_AUDIO_SEL, +topckgen CLK_TOP_AUD_INTBUS_SEL, +topckgen CLK_TOP_APLL1_DIV0, +topckgen CLK_TOP_APLL2_DIV0, +topckgen CLK_TOP_I2S0_M_SEL, +topckgen CLK_TOP_I2S1_M_SEL, +topckgen CLK_TOP_I2S2_M_SEL, +topckgen CLK_TOP_I2S3_M_SEL, +topckgen CLK_TOP_I2S3_B_SEL; + clock-names = infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + assigned-clocks = topckgen CLK_TOP_AUD_1_SEL, + topckgen CLK_TOP_AUD_2_SEL; + assigned-clock-parents = topckgen CLK_TOP_APLL1, +topckgen CLK_TOP_APLL2; + }; }; }; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] ASoC: Drop owner assignment from platform_driver
On Fri, 2015-07-10 at 14:30 +0900, Krzysztof Kozlowski wrote: > platform_driver does not need to set an owner because > platform_driver_register() will set it. > > Signed-off-by: Krzysztof Kozlowski > Acked-by: Koro Chen Thank you! -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] ASoC: Drop owner assignment from platform_driver
On Fri, 2015-07-10 at 14:30 +0900, Krzysztof Kozlowski wrote: platform_driver does not need to set an owner because platform_driver_register() will set it. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com Acked-by: Koro Chen koro.c...@mediatek.com Thank you! -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] ASoC: rt5645: Fix missing free_irq
On Thu, 2015-07-09 at 12:10 +0100, Mark Brown wrote: > On Thu, Jul 09, 2015 at 09:48:13AM +0800, Koro Chen wrote: > > > Do you think I should use devm_request_threaded_irq(), and change > > free_irq to devm_free_irq in remove? Or I should keep the original > > request_thread_irq(), and just add a free_irq() during probe failed? > > I'd just keep request_threaded_irq() and use free_irq(). OK, thanks, I will send a new patch. And about the patch 2/2 regulator support, is there any problem I should also fix? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] ASoC: rt5645: Fix missing free_irq
On Thu, 2015-07-09 at 12:10 +0100, Mark Brown wrote: On Thu, Jul 09, 2015 at 09:48:13AM +0800, Koro Chen wrote: Do you think I should use devm_request_threaded_irq(), and change free_irq to devm_free_irq in remove? Or I should keep the original request_thread_irq(), and just add a free_irq() during probe failed? I'd just keep request_threaded_irq() and use free_irq(). OK, thanks, I will send a new patch. And about the patch 2/2 regulator support, is there any problem I should also fix? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] arm64: dts: mt8173: Add afe device node
This adds afe (audio front end) device node to the MT8173 dtsi file. Signed-off-by: Koro Chen --- This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Changes since v1: - change node name to afe: audio-controller@1122 --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..ce9255a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "mt8173-pinfunc.h" @@ -393,6 +394,37 @@ #size-cells = <0>; status = "disabled"; }; + + afe: audio-controller@1122 { + compatible = "mediatek,mt8173-afe-pcm"; + reg = <0 0x1122 0 0x1000>; + interrupts = ; + power-domains = < MT8173_POWER_DOMAIN_AUDIO>; + clocks = < CLK_INFRA_AUDIO>, +< CLK_TOP_AUDIO_SEL>, +< CLK_TOP_AUD_INTBUS_SEL>, +< CLK_TOP_APLL1_DIV0>, +< CLK_TOP_APLL2_DIV0>, +< CLK_TOP_I2S0_M_SEL>, +< CLK_TOP_I2S1_M_SEL>, +< CLK_TOP_I2S2_M_SEL>, +< CLK_TOP_I2S3_M_SEL>, +< CLK_TOP_I2S3_B_SEL>; + clock-names = "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + assigned-clocks = < CLK_TOP_AUD_1_SEL>, + < CLK_TOP_AUD_2_SEL>; + assigned-clock-parents = < CLK_TOP_APLL1>, +< CLK_TOP_APLL2>; + }; }; }; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Use platform_of_node for machine drivers
This replaces the platform_name in snd_soc_dai_link by device tree node. Signed-off-by: Koro Chen --- .../devicetree/bindings/sound/mt8173-max98090.txt | 2 ++ .../bindings/sound/mt8173-rt5650-rt5676.txt | 2 ++ sound/soc/mediatek/mt8173-max98090.c | 17 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 19 +++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt index 829bd26..519e97c 100644 --- a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -3,11 +3,13 @@ MT8173 with MAX98090 CODEC Required properties: - compatible : "mediatek,mt8173-max98090" - mediatek,audio-codec: the phandle of the MAX98090 audio codec +- mediatek,platform: the phandle of MT8173 ASoC platform Example: sound { compatible = "mediatek,mt8173-max98090"; mediatek,audio-codec = <>; + mediatek,platform = <>; }; diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt index 61e98c9..f205ce9 100644 --- a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -3,11 +3,13 @@ MT8173 with RT5650 RT5676 CODECS Required properties: - compatible : "mediatek,mt8173-rt5650-rt5676" - mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs +- mediatek,platform: the phandle of MT8173 ASoC platform Example: sound { compatible = "mediatek,mt8173-rt5650-rt5676"; mediatek,audio-codec = < >; + mediatek,platform = <>; }; diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c index 4d44b58..2d2536a 100644 --- a/sound/soc/mediatek/mt8173-max98090.c +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -103,7 +103,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { .name = "MAX98090 Playback", .stream_name = "MAX98090 Playback", .cpu_dai_name = "DL1", - .platform_name = "1122.mt8173-afe-pcm", .codec_name = "snd-soc-dummy", .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -114,7 +113,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { .name = "MAX98090 Capture", .stream_name = "MAX98090 Capture", .cpu_dai_name = "VUL", - .platform_name = "1122.mt8173-afe-pcm", .codec_name = "snd-soc-dummy", .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -125,7 +123,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { { .name = "Codec", .cpu_dai_name = "I2S", - .platform_name = "1122.mt8173-afe-pcm", .no_pcm = 1, .codec_dai_name = "HiFi", .init = mt8173_max98090_init, @@ -152,9 +149,21 @@ static struct snd_soc_card mt8173_max98090_card = { static int mt8173_max98090_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card = _max98090_card; - struct device_node *codec_node; + struct device_node *codec_node, *platform_node; int ret, i; + platform_node = of_parse_phandle(pdev->dev.of_node, +"mediatek,platform", 0); + if (!platform_node) { + dev_err(>dev, "Property 'platform' missing or invalid\n"); + return -EINVAL; + } + for (i = 0; i < card->num_links; i++) { + if (mt8173_max98090_dais[i].platform_name) + continue; + mt8173_max98090_dais[i].platform_of_node = platform_node; + } + codec_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0); if (!codec_node) { diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c index 0940553..6f52eca 100644 --- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -138,7 +138,6 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { .name = "rt5650_rt5676 Playback",
Re: [PATCH 1/2] ASoC: rt5645: Fix missing free_irq
On Wed, 2015-07-08 at 12:14 +0100, Mark Brown wrote: > On Wed, Jul 08, 2015 at 04:25:50PM +0800, Koro Chen wrote: > > > The driver does not free irq if snd_soc_register_codec fails. > > It does not return error when request irq failed, either. > > Fix this by using devm_request_threaded_irq(), and returns when error. > > Unfortunately this isn't safe... > > > - if (i2c->irq) > > - free_irq(i2c->irq, rt5645); > > - > > cancel_delayed_work_sync(>jack_detect_work); > > This work item is queued up by the interrupt handler so we need to > unregister the interrupt before we cancel any pending work otherwise > it's possible that the interrupt may fire after we cancelled the work. Thank you for seeing this, I didn't notice the delayed work. Do you think I should use devm_request_threaded_irq(), and change free_irq to devm_free_irq in remove? Or I should keep the original request_thread_irq(), and just add a free_irq() during probe failed? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] ASoC: rt5645: Add regulator support
This adds basic regulator support for rt5645. Signed-off-by: Koro Chen --- sound/soc/codecs/rt5645.c | 71 +++ sound/soc/codecs/rt5645.h | 26 - 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f9f2db8..7713e2b 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, }; +static const char *const rt5645_supply_names[] = { + "avdd", + "cpvdd", +}; + +struct rt5645_priv { + struct snd_soc_codec *codec; + struct rt5645_platform_data pdata; + struct regmap *regmap; + struct i2c_client *i2c; + struct gpio_desc *gpiod_hp_det; + struct snd_soc_jack *hp_jack; + struct snd_soc_jack *mic_jack; + struct snd_soc_jack *btn_jack; + struct delayed_work jack_detect_work; + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; + + int codec_type; + int sysclk; + int sysclk_src; + int lrck[RT5645_AIFS]; + int bclk[RT5645_AIFS]; + int master[RT5645_AIFS]; + + int pll_src; + int pll_in; + int pll_out; + + int jack_type; + bool en_button_func; +}; + static int rt5645_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, RT5645_RESET, 0); @@ -3247,7 +3280,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, { struct rt5645_platform_data *pdata = dev_get_platdata(>dev); struct rt5645_priv *rt5645; - int ret; + int ret, i; unsigned int val; rt5645 = devm_kzalloc(>dev, sizeof(struct rt5645_priv), @@ -3281,6 +3314,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, return ret; } + for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) + rt5645->supplies[i].supply = rt5645_supply_names[i]; + + ret = devm_regulator_bulk_get(>dev, + ARRAY_SIZE(rt5645->supplies), + rt5645->supplies); + if (ret) { + dev_err(>dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(rt5645->supplies), + rt5645->supplies); + if (ret) { + dev_err(>dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, ); switch (val) { @@ -3294,7 +3345,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, dev_err(>dev, "Device with ID register %#x is not rt5645 or rt5650\n", val); - return -ENODEV; + ret = -ENODEV; + goto err_enable; } if (rt5645->codec_type == CODEC_TYPE_RT5650) { @@ -3434,12 +3486,20 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, IRQF_ONESHOT, "rt5645", rt5645); if (ret) { dev_err(>dev, "Failed to reguest IRQ: %d\n", ret); - return ret; + goto err_enable; } } - return snd_soc_register_codec(>dev, _codec_dev_rt5645, - rt5645_dai, ARRAY_SIZE(rt5645_dai)); + ret = snd_soc_register_codec(>dev, _codec_dev_rt5645, +rt5645_dai, ARRAY_SIZE(rt5645_dai)); + if (ret) + goto err_enable; + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); + return ret; } static int rt5645_i2c_remove(struct i2c_client *i2c) @@ -3449,6 +3509,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) cancel_delayed_work_sync(>jack_detect_work); snd_soc_unregister_codec(>dev); + regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); return 0; } diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 0353a6a..199b22f 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2177,32 +2177,6 @@ enum { int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int filter_mask, unsigned int clk_src); -struct rt5645_priv { - struct snd_soc_codec *codec; - struct rt5645_platform_data pdata; - struct regmap *regmap; - struct i2c_client *i2c; - struct gpio_desc *gpiod_hp_det; - struct snd_soc_jack *hp_jack; -
[PATCH 1/2] ASoC: rt5645: Fix missing free_irq
The driver does not free irq if snd_soc_register_codec fails. It does not return error when request irq failed, either. Fix this by using devm_request_threaded_irq(), and returns when error. Signed-off-by: Koro Chen --- sound/soc/codecs/rt5645.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 9dfa431..f9f2db8 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3427,11 +3427,15 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, INIT_DELAYED_WORK(>jack_detect_work, rt5645_jack_detect_work); if (rt5645->i2c->irq) { - ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_ONESHOT, "rt5645", rt5645); - if (ret) + ret = devm_request_threaded_irq(>dev, rt5645->i2c->irq, + NULL, rt5645_irq, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, "rt5645", rt5645); + if (ret) { dev_err(>dev, "Failed to reguest IRQ: %d\n", ret); + return ret; + } } return snd_soc_register_codec(>dev, _codec_dev_rt5645, @@ -3442,9 +3446,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) { struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c); - if (i2c->irq) - free_irq(i2c->irq, rt5645); - cancel_delayed_work_sync(>jack_detect_work); snd_soc_unregister_codec(>dev); -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] ASoC: rt5645: Fix missing free_irq
The driver does not free irq if snd_soc_register_codec fails. It does not return error when request irq failed, either. Fix this by using devm_request_threaded_irq(), and returns when error. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/codecs/rt5645.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 9dfa431..f9f2db8 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3427,11 +3427,15 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, INIT_DELAYED_WORK(rt5645-jack_detect_work, rt5645_jack_detect_work); if (rt5645-i2c-irq) { - ret = request_threaded_irq(rt5645-i2c-irq, NULL, rt5645_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_ONESHOT, rt5645, rt5645); - if (ret) + ret = devm_request_threaded_irq(i2c-dev, rt5645-i2c-irq, + NULL, rt5645_irq, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, rt5645, rt5645); + if (ret) { dev_err(i2c-dev, Failed to reguest IRQ: %d\n, ret); + return ret; + } } return snd_soc_register_codec(i2c-dev, soc_codec_dev_rt5645, @@ -3442,9 +3446,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) { struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c); - if (i2c-irq) - free_irq(i2c-irq, rt5645); - cancel_delayed_work_sync(rt5645-jack_detect_work); snd_soc_unregister_codec(i2c-dev); -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] ASoC: rt5645: Add regulator support
This adds basic regulator support for rt5645. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/codecs/rt5645.c | 71 +++ sound/soc/codecs/rt5645.h | 26 - 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f9f2db8..7713e2b 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -21,6 +21,7 @@ #include linux/gpio/consumer.h #include linux/acpi.h #include linux/dmi.h +#include linux/regulator/consumer.h #include sound/core.h #include sound/pcm.h #include sound/pcm_params.h @@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, }; +static const char *const rt5645_supply_names[] = { + avdd, + cpvdd, +}; + +struct rt5645_priv { + struct snd_soc_codec *codec; + struct rt5645_platform_data pdata; + struct regmap *regmap; + struct i2c_client *i2c; + struct gpio_desc *gpiod_hp_det; + struct snd_soc_jack *hp_jack; + struct snd_soc_jack *mic_jack; + struct snd_soc_jack *btn_jack; + struct delayed_work jack_detect_work; + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; + + int codec_type; + int sysclk; + int sysclk_src; + int lrck[RT5645_AIFS]; + int bclk[RT5645_AIFS]; + int master[RT5645_AIFS]; + + int pll_src; + int pll_in; + int pll_out; + + int jack_type; + bool en_button_func; +}; + static int rt5645_reset(struct snd_soc_codec *codec) { return snd_soc_write(codec, RT5645_RESET, 0); @@ -3247,7 +3280,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, { struct rt5645_platform_data *pdata = dev_get_platdata(i2c-dev); struct rt5645_priv *rt5645; - int ret; + int ret, i; unsigned int val; rt5645 = devm_kzalloc(i2c-dev, sizeof(struct rt5645_priv), @@ -3281,6 +3314,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, return ret; } + for (i = 0; i ARRAY_SIZE(rt5645-supplies); i++) + rt5645-supplies[i].supply = rt5645_supply_names[i]; + + ret = devm_regulator_bulk_get(i2c-dev, + ARRAY_SIZE(rt5645-supplies), + rt5645-supplies); + if (ret) { + dev_err(i2c-dev, Failed to request supplies: %d\n, ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(rt5645-supplies), + rt5645-supplies); + if (ret) { + dev_err(i2c-dev, Failed to enable supplies: %d\n, ret); + return ret; + } + regmap_read(rt5645-regmap, RT5645_VENDOR_ID2, val); switch (val) { @@ -3294,7 +3345,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, dev_err(i2c-dev, Device with ID register %#x is not rt5645 or rt5650\n, val); - return -ENODEV; + ret = -ENODEV; + goto err_enable; } if (rt5645-codec_type == CODEC_TYPE_RT5650) { @@ -3434,12 +3486,20 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, IRQF_ONESHOT, rt5645, rt5645); if (ret) { dev_err(i2c-dev, Failed to reguest IRQ: %d\n, ret); - return ret; + goto err_enable; } } - return snd_soc_register_codec(i2c-dev, soc_codec_dev_rt5645, - rt5645_dai, ARRAY_SIZE(rt5645_dai)); + ret = snd_soc_register_codec(i2c-dev, soc_codec_dev_rt5645, +rt5645_dai, ARRAY_SIZE(rt5645_dai)); + if (ret) + goto err_enable; + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(rt5645-supplies), rt5645-supplies); + return ret; } static int rt5645_i2c_remove(struct i2c_client *i2c) @@ -3449,6 +3509,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) cancel_delayed_work_sync(rt5645-jack_detect_work); snd_soc_unregister_codec(i2c-dev); + regulator_bulk_disable(ARRAY_SIZE(rt5645-supplies), rt5645-supplies); return 0; } diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 0353a6a..199b22f 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2177,32 +2177,6 @@ enum { int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int filter_mask, unsigned int clk_src); -struct rt5645_priv { - struct snd_soc_codec *codec; - struct rt5645_platform_data pdata; - struct regmap *regmap; - struct i2c_client *i2c; - struct gpio_desc *gpiod_hp_det; - struct snd_soc_jack *hp_jack
Re: [PATCH 1/2] ASoC: rt5645: Fix missing free_irq
On Wed, 2015-07-08 at 12:14 +0100, Mark Brown wrote: On Wed, Jul 08, 2015 at 04:25:50PM +0800, Koro Chen wrote: The driver does not free irq if snd_soc_register_codec fails. It does not return error when request irq failed, either. Fix this by using devm_request_threaded_irq(), and returns when error. Unfortunately this isn't safe... - if (i2c-irq) - free_irq(i2c-irq, rt5645); - cancel_delayed_work_sync(rt5645-jack_detect_work); This work item is queued up by the interrupt handler so we need to unregister the interrupt before we cancel any pending work otherwise it's possible that the interrupt may fire after we cancelled the work. Thank you for seeing this, I didn't notice the delayed work. Do you think I should use devm_request_threaded_irq(), and change free_irq to devm_free_irq in remove? Or I should keep the original request_thread_irq(), and just add a free_irq() during probe failed? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Use platform_of_node for machine drivers
This replaces the platform_name in snd_soc_dai_link by device tree node. Signed-off-by: Koro Chen koro.c...@mediatek.com --- .../devicetree/bindings/sound/mt8173-max98090.txt | 2 ++ .../bindings/sound/mt8173-rt5650-rt5676.txt | 2 ++ sound/soc/mediatek/mt8173-max98090.c | 17 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 19 +++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt index 829bd26..519e97c 100644 --- a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -3,11 +3,13 @@ MT8173 with MAX98090 CODEC Required properties: - compatible : mediatek,mt8173-max98090 - mediatek,audio-codec: the phandle of the MAX98090 audio codec +- mediatek,platform: the phandle of MT8173 ASoC platform Example: sound { compatible = mediatek,mt8173-max98090; mediatek,audio-codec = max98090; + mediatek,platform = afe; }; diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt index 61e98c9..f205ce9 100644 --- a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -3,11 +3,13 @@ MT8173 with RT5650 RT5676 CODECS Required properties: - compatible : mediatek,mt8173-rt5650-rt5676 - mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs +- mediatek,platform: the phandle of MT8173 ASoC platform Example: sound { compatible = mediatek,mt8173-rt5650-rt5676; mediatek,audio-codec = rt5650 rt5676; + mediatek,platform = afe; }; diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c index 4d44b58..2d2536a 100644 --- a/sound/soc/mediatek/mt8173-max98090.c +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -103,7 +103,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { .name = MAX98090 Playback, .stream_name = MAX98090 Playback, .cpu_dai_name = DL1, - .platform_name = 1122.mt8173-afe-pcm, .codec_name = snd-soc-dummy, .codec_dai_name = snd-soc-dummy-dai, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -114,7 +113,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { .name = MAX98090 Capture, .stream_name = MAX98090 Capture, .cpu_dai_name = VUL, - .platform_name = 1122.mt8173-afe-pcm, .codec_name = snd-soc-dummy, .codec_dai_name = snd-soc-dummy-dai, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -125,7 +123,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { { .name = Codec, .cpu_dai_name = I2S, - .platform_name = 1122.mt8173-afe-pcm, .no_pcm = 1, .codec_dai_name = HiFi, .init = mt8173_max98090_init, @@ -152,9 +149,21 @@ static struct snd_soc_card mt8173_max98090_card = { static int mt8173_max98090_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card = mt8173_max98090_card; - struct device_node *codec_node; + struct device_node *codec_node, *platform_node; int ret, i; + platform_node = of_parse_phandle(pdev-dev.of_node, +mediatek,platform, 0); + if (!platform_node) { + dev_err(pdev-dev, Property 'platform' missing or invalid\n); + return -EINVAL; + } + for (i = 0; i card-num_links; i++) { + if (mt8173_max98090_dais[i].platform_name) + continue; + mt8173_max98090_dais[i].platform_of_node = platform_node; + } + codec_node = of_parse_phandle(pdev-dev.of_node, mediatek,audio-codec, 0); if (!codec_node) { diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c index 0940553..6f52eca 100644 --- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -138,7 +138,6 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { .name = rt5650_rt5676 Playback, .stream_name = rt5650_rt5676 Playback, .cpu_dai_name = DL1, - .platform_name = 1122.mt8173-afe-pcm, .codec_name = snd-soc-dummy, .codec_dai_name = snd-soc-dummy-dai, .trigger = {SND_SOC_DPCM_TRIGGER_POST
[PATCH v2] arm64: dts: mt8173: Add afe device node
This adds afe (audio front end) device node to the MT8173 dtsi file. Signed-off-by: Koro Chen koro.c...@mediatek.com --- This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Changes since v1: - change node name to afe: audio-controller@1122 --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..ce9255a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include dt-bindings/clock/mt8173-clk.h #include dt-bindings/interrupt-controller/irq.h #include dt-bindings/interrupt-controller/arm-gic.h +#include dt-bindings/power/mt8173-power.h #include dt-bindings/reset-controller/mt8173-resets.h #include mt8173-pinfunc.h @@ -393,6 +394,37 @@ #size-cells = 0; status = disabled; }; + + afe: audio-controller@1122 { + compatible = mediatek,mt8173-afe-pcm; + reg = 0 0x1122 0 0x1000; + interrupts = GIC_SPI 134 IRQ_TYPE_EDGE_FALLING; + power-domains = scpsys MT8173_POWER_DOMAIN_AUDIO; + clocks = infracfg CLK_INFRA_AUDIO, +topckgen CLK_TOP_AUDIO_SEL, +topckgen CLK_TOP_AUD_INTBUS_SEL, +topckgen CLK_TOP_APLL1_DIV0, +topckgen CLK_TOP_APLL2_DIV0, +topckgen CLK_TOP_I2S0_M_SEL, +topckgen CLK_TOP_I2S1_M_SEL, +topckgen CLK_TOP_I2S2_M_SEL, +topckgen CLK_TOP_I2S3_M_SEL, +topckgen CLK_TOP_I2S3_B_SEL; + clock-names = infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + assigned-clocks = topckgen CLK_TOP_AUD_1_SEL, + topckgen CLK_TOP_AUD_2_SEL; + assigned-clock-parents = topckgen CLK_TOP_APLL1, +topckgen CLK_TOP_APLL2; + }; }; }; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] arm64: dts: mt8173: Add afe device node
On Tue, 2015-07-07 at 09:46 +0200, Matthias Brugger wrote: > On Monday, July 06, 2015 09:02:38 PM Daniel Kurtz wrote: > > On Mon, Jul 6, 2015 at 2:52 PM, Koro Chen wrote: > > > This adds afe (audio front end) device node to the MT8173 dtsi file. > > > > > > This patch is based on Matthias's tree: > > > https://github.com/mbgg/linux-mediatek > > > branch: v4.2-next/arm64 > > > > > > Signed-off-by: Koro Chen > > > --- > > > > > > arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 > > > 1 file changed, 32 insertions(+) > > > > > > diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > > b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..f8afab4 100644 > > > --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > > +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi > > > @@ -14,6 +14,7 @@ > > > > > > #include > > > #include > > > #include > > > > > > +#include > > > > > > #include > > > #include "mt8173-pinfunc.h" > > > > > > @@ -393,6 +394,37 @@ > > > > > > #size-cells = <0>; > > > status = "disabled"; > > > > > > }; > > > > > > + > > > + afe: mt8173-afe-pcm@1122 { > > > > I believe this should be something generic, like: > > > > afe: audio-controller@1122 > > > > Yes, please find a name that better describes the component instead of just > using the compatible string. > Thanks both, I will change the name to audio-controller. > Thanks. > > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] arm64: dts: mt8173: Add afe device node
On Tue, 2015-07-07 at 09:46 +0200, Matthias Brugger wrote: On Monday, July 06, 2015 09:02:38 PM Daniel Kurtz wrote: On Mon, Jul 6, 2015 at 2:52 PM, Koro Chen koro.c...@mediatek.com wrote: This adds afe (audio front end) device node to the MT8173 dtsi file. This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Signed-off-by: Koro Chen koro.c...@mediatek.com --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..f8afab4 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include dt-bindings/clock/mt8173-clk.h #include dt-bindings/interrupt-controller/irq.h #include dt-bindings/interrupt-controller/arm-gic.h +#include dt-bindings/power/mt8173-power.h #include dt-bindings/reset-controller/mt8173-resets.h #include mt8173-pinfunc.h @@ -393,6 +394,37 @@ #size-cells = 0; status = disabled; }; + + afe: mt8173-afe-pcm@1122 { I believe this should be something generic, like: afe: audio-controller@1122 Yes, please find a name that better describes the component instead of just using the compatible string. Thanks both, I will change the name to audio-controller. Thanks. ___ Linux-mediatek mailing list linux-media...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] arm64: dts: mt8173: Add afe device node
This adds afe (audio front end) device node to the MT8173 dtsi file. This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Signed-off-by: Koro Chen --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..f8afab4 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "mt8173-pinfunc.h" @@ -393,6 +394,37 @@ #size-cells = <0>; status = "disabled"; }; + + afe: mt8173-afe-pcm@1122 { + compatible = "mediatek,mt8173-afe-pcm"; + reg = <0 0x1122 0 0x1000>; + interrupts = ; + power-domains = < MT8173_POWER_DOMAIN_AUDIO>; + clocks = < CLK_INFRA_AUDIO>, +< CLK_TOP_AUDIO_SEL>, +< CLK_TOP_AUD_INTBUS_SEL>, +< CLK_TOP_APLL1_DIV0>, +< CLK_TOP_APLL2_DIV0>, +< CLK_TOP_I2S0_M_SEL>, +< CLK_TOP_I2S1_M_SEL>, +< CLK_TOP_I2S2_M_SEL>, +< CLK_TOP_I2S3_M_SEL>, +< CLK_TOP_I2S3_B_SEL>; + clock-names = "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + assigned-clocks = < CLK_TOP_AUD_1_SEL>, + < CLK_TOP_AUD_2_SEL>; + assigned-clock-parents = < CLK_TOP_APLL1>, +< CLK_TOP_APLL2>; + }; }; }; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] arm64: dts: mt8173: Add afe device node
This adds afe (audio front end) device node to the MT8173 dtsi file. This patch is based on Matthias's tree: https://github.com/mbgg/linux-mediatek branch: v4.2-next/arm64 Signed-off-by: Koro Chen koro.c...@mediatek.com --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 32 1 file changed, 32 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 0696f8f..f8afab4 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include dt-bindings/clock/mt8173-clk.h #include dt-bindings/interrupt-controller/irq.h #include dt-bindings/interrupt-controller/arm-gic.h +#include dt-bindings/power/mt8173-power.h #include dt-bindings/reset-controller/mt8173-resets.h #include mt8173-pinfunc.h @@ -393,6 +394,37 @@ #size-cells = 0; status = disabled; }; + + afe: mt8173-afe-pcm@1122 { + compatible = mediatek,mt8173-afe-pcm; + reg = 0 0x1122 0 0x1000; + interrupts = GIC_SPI 134 IRQ_TYPE_EDGE_FALLING; + power-domains = scpsys MT8173_POWER_DOMAIN_AUDIO; + clocks = infracfg CLK_INFRA_AUDIO, +topckgen CLK_TOP_AUDIO_SEL, +topckgen CLK_TOP_AUD_INTBUS_SEL, +topckgen CLK_TOP_APLL1_DIV0, +topckgen CLK_TOP_APLL2_DIV0, +topckgen CLK_TOP_I2S0_M_SEL, +topckgen CLK_TOP_I2S1_M_SEL, +topckgen CLK_TOP_I2S2_M_SEL, +topckgen CLK_TOP_I2S3_M_SEL, +topckgen CLK_TOP_I2S3_B_SEL; + clock-names = infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + assigned-clocks = topckgen CLK_TOP_AUD_1_SEL, + topckgen CLK_TOP_AUD_2_SEL; + assigned-clock-parents = topckgen CLK_TOP_APLL1, +topckgen CLK_TOP_APLL2; + }; }; }; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dpcm: Add checks of playback/capture before dpcm_get_be
In dpcm_get_be(), it looks for a BE rtd that has the DAI widget according to current stream type. Only playback_widgets are searched in the case of playback stream and vice versa. However, the DAI widget itself can be playback or capture. If the DAI widget is capture, but current stream type is playback, dpcm_get_be() will always fail to find a rtd, print error messages, and continue to the next DAI widget in list. We can just skip this DAI widget to further suppress error messages. This happens in a special case when 2 codecs are inter-connected, and the 1st codec's "capture" widget is used to send data to the 2nd codec during "playback": mtk-rt5650-rt5676 sound: ASoC: can't get playback BE for Sub AIF2 Capture rt5650_rt5676 Playback: ASoC: no BE found for Sub AIF2 Capture Add checks to continue to next DAI widget if current DAI widget's direction does not match the stream type. Signed-off-by: Koro Chen --- sound/soc/soc-pcm.c | 5 + 1 file changed, 5 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 256b9c9..a6d3313 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1306,7 +1306,12 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, switch (list->widgets[i]->id) { case snd_soc_dapm_dai_in: + if (stream != SNDRV_PCM_STREAM_PLAYBACK) + continue; + break; case snd_soc_dapm_dai_out: + if (stream != SNDRV_PCM_STREAM_CAPTURE) + continue; break; default: continue; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dpcm: Add checks of playback/capture before dpcm_get_be
In dpcm_get_be(), it looks for a BE rtd that has the DAI widget according to current stream type. Only playback_widgets are searched in the case of playback stream and vice versa. However, the DAI widget itself can be playback or capture. If the DAI widget is capture, but current stream type is playback, dpcm_get_be() will always fail to find a rtd, print error messages, and continue to the next DAI widget in list. We can just skip this DAI widget to further suppress error messages. This happens in a special case when 2 codecs are inter-connected, and the 1st codec's capture widget is used to send data to the 2nd codec during playback: mtk-rt5650-rt5676 sound: ASoC: can't get playback BE for Sub AIF2 Capture rt5650_rt5676 Playback: ASoC: no BE found for Sub AIF2 Capture Add checks to continue to next DAI widget if current DAI widget's direction does not match the stream type. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/soc-pcm.c | 5 + 1 file changed, 5 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 256b9c9..a6d3313 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1306,7 +1306,12 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, switch (list-widgets[i]-id) { case snd_soc_dapm_dai_in: + if (stream != SNDRV_PCM_STREAM_PLAYBACK) + continue; + break; case snd_soc_dapm_dai_out: + if (stream != SNDRV_PCM_STREAM_CAPTURE) + continue; break; default: continue; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Fix unbalanced calls to runtime suspend/resume
This adds call to runtime suspend in dev remove. It fixs the problem that suspend is not called in the case of CONFIG_PM=n. It also fixs build warning when CONFIG_PM=n. Signed-off-by: Koro Chen --- sound/soc/mediatek/mtk-afe-pcm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index cc228db..9863da7 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -1199,6 +1199,8 @@ err_pm_disable: static int mtk_afe_pcm_dev_remove(struct platform_device *pdev) { pm_runtime_disable(>dev); + if (!pm_runtime_status_suspended(>dev)) + mtk_afe_runtime_suspend(>dev); snd_soc_unregister_component(>dev); snd_soc_unregister_platform(>dev); return 0; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: mediatek: Fix unbalanced calls to runtime suspend/resume
This adds call to runtime suspend in dev remove. It fixs the problem that suspend is not called in the case of CONFIG_PM=n. It also fixs build warning when CONFIG_PM=n. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/mediatek/mtk-afe-pcm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c index cc228db..9863da7 100644 --- a/sound/soc/mediatek/mtk-afe-pcm.c +++ b/sound/soc/mediatek/mtk-afe-pcm.c @@ -1199,6 +1199,8 @@ err_pm_disable: static int mtk_afe_pcm_dev_remove(struct platform_device *pdev) { pm_runtime_disable(pdev-dev); + if (!pm_runtime_status_suspended(pdev-dev)) + mtk_afe_runtime_suspend(pdev-dev); snd_soc_unregister_component(pdev-dev); snd_soc_unregister_platform(pdev-dev); return 0; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 0/3] ASoC: Mediatek: Add support for MT8173 SOC
This adds basic support for the Mediatek AFE (Audio Front End) unit of MT8173. This patch is based on Linux 4.1-rc1 and Sascha's SCPSYS power patch [1]. The AFE unit comprises several memory interfaces that communicate with CPU, a multi input multi output digital audio interconnect, and several external interfaces (e.g. I2S). [1] https://lkml.org/lkml/2015/6/9/172 changes since v1: - change Kconfig to tristate - remove unnecessary !! in the platform driver - let MODULE_DEVICE_TABLE follow the table - remove regulators from machine drivers changes since RFC: - Use DPCM to model AFE AFE memory interfaces such as DL1, VUL are modeled as frontend DAIs, and AFE IOs such as I2S, HDMI are backend DAIs. Which memif and IO to be used can be set in the machine driver. There is no need to indicate this in dts anymore so include/dt-bindings/sound/mtk-afe.h is removed. AFE connections are represented by DAPM widgets and routes, and set connection APIs/tables are no longer required. (mtk-afe-connection.c and mtk-afe-connection.h are removed) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/3] ASoC: mediatek: Add AFE platform driver
This is the DPCM based platform driver of AFE (Audio Front End) unit. Signed-off-by: Sascha Hauer Signed-off-by: Koro Chen --- .../devicetree/bindings/sound/mtk-afe-pcm.txt | 45 + sound/soc/Kconfig |1 + sound/soc/Makefile |1 + sound/soc/mediatek/Kconfig |9 + sound/soc/mediatek/Makefile|2 + sound/soc/mediatek/mtk-afe-common.h| 109 ++ sound/soc/mediatek/mtk-afe-pcm.c | 1233 7 files changed, 1400 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt create mode 100644 sound/soc/mediatek/Kconfig create mode 100644 sound/soc/mediatek/Makefile create mode 100644 sound/soc/mediatek/mtk-afe-common.h create mode 100644 sound/soc/mediatek/mtk-afe-pcm.c diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt new file mode 100644 index 000..e302c7f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt @@ -0,0 +1,45 @@ +Mediatek AFE PCM controller + +Required properties: +- compatible = "mediatek,mt8173-afe-pcm"; +- reg: register location and size +- interrupts: Should contain AFE interrupt +- clock-names: should have these clock names: + "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + +Example: + + afe: mt8173-afe-pcm@1122 { + compatible = "mediatek,mt8173-afe-pcm"; + reg = <0 0x1122 0 0x1000>; + interrupts = ; + clocks = < INFRA_AUDIO>, + < TOP_AUDIO_SEL>, + < TOP_AUD_INTBUS_SEL>, + < TOP_APLL1_DIV0>, + < TOP_APLL2_DIV0>, + < TOP_I2S0_M_CK_SEL>, + < TOP_I2S1_M_CK_SEL>, + < TOP_I2S2_M_CK_SEL>, + < TOP_I2S3_M_CK_SEL>, + < TOP_I2S3_B_CK_SEL>; + clock-names = "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3ba52da..cc1b718 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -45,6 +45,7 @@ source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" source "sound/soc/intel/Kconfig" +source "sound/soc/mediatek/Kconfig" source "sound/soc/mxs/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/qcom/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 974ba70..e552633 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += intel/ +obj-$(CONFIG_SND_SOC) += mediatek/ obj-$(CONFIG_SND_SOC) += mxs/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig new file mode 100644 index 000..c622280 --- /dev/null +++ b/sound/soc/mediatek/Kconfig @@ -0,0 +1,9 @@ +config SND_SOC_MEDIATEK + tristate "ASoC support for Mediatek chip" + depends on ARCH_MEDIATEK + help + This adds ASoC platform driver support for Mediatek chip + that can be used with other codecs. + Select Y if you have such device. + Ex: MT8173 + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile new file mode 100644 index 000..5f27cc7 --- /dev/null +++ b/sound/soc/mediatek/Makefile @@ -0,0 +1,2 @@ +# MTK Platform Support +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h new file mode 100644 index 000..a88b175 --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -0,0 +1,109 @@ +/* + * mtk_afe_common.h -- Mediatek audio driver common definitions + * + *
[PATCH v2 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
This is the DPCM based machine driver with MAX98090 Signed-off-by: Koro Chen --- .../devicetree/bindings/sound/mt8173-max98090.txt | 13 ++ sound/soc/mediatek/Kconfig | 10 + sound/soc/mediatek/Makefile| 2 + sound/soc/mediatek/mt8173-max98090.c | 213 + 4 files changed, 238 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-max98090.txt create mode 100644 sound/soc/mediatek/mt8173-max98090.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt new file mode 100644 index 000..829bd26 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -0,0 +1,13 @@ +MT8173 with MAX98090 CODEC + +Required properties: +- compatible : "mediatek,mt8173-max98090" +- mediatek,audio-codec: the phandle of the MAX98090 audio codec + +Example: + + sound { + compatible = "mediatek,mt8173-max98090"; + mediatek,audio-codec = <>; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index c622280..0bfd2a0 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -7,3 +7,13 @@ config SND_SOC_MEDIATEK Select Y if you have such device. Ex: MT8173 +config SND_SOC_MT8173_MAX98090 + tristate "ASoC Audio driver for MT8173 with MAX98090 codec" + depends on SND_SOC_MEDIATEK + select SND_SOC_MAX98090 + help + This adds ASoC driver for Mediatek MT8173 boards + with the MAX98090 audio codec. + Select Y if you have such device. + If unsure select "N". + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 5f27cc7..08fa765 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -1,2 +1,4 @@ # MTK Platform Support obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o +# Machine support +obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c new file mode 100644 index 000..4d44b58 --- /dev/null +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -0,0 +1,213 @@ +/* + * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include "../codecs/max98090.h" + +static struct snd_soc_jack mt8173_max98090_jack; + +static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = { + { + .pin= "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin= "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8173_max98090_routes[] = { + {"Speaker", NULL, "SPKL"}, + {"Speaker", NULL, "SPKR"}, + {"DMICL", NULL, "Int Mic"}, + {"Headphone", NULL, "HPL"}, + {"Headphone", NULL, "HPR"}, + {"Headset Mic", NULL, "MICBIAS"}, + {"IN34", NULL, "Headset Mic"}, +}; + +static const struct snd_kcontrol_new mt8173_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256, + SND_SOC_CLOCK_IN); +} + +static struct snd_soc_ops mt8173_max98090_ops = { + .hw_params = mt8173_max98090_hw_params, +}; + +sta
[PATCH v2 3/3] ASoC: mediatek: Add machine driver for rt5650 rt5676 codec
This is the DPCM based machine driver with rt5650 and rt5676 Signed-off-by: Nicolas Boichat Signed-off-by: Koro Chen --- .../bindings/sound/mt8173-rt5650-rt5676.txt| 13 + sound/soc/mediatek/Kconfig | 11 + sound/soc/mediatek/Makefile| 1 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 278 + 4 files changed, 303 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt create mode 100644 sound/soc/mediatek/mt8173-rt5650-rt5676.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt new file mode 100644 index 000..61e98c9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -0,0 +1,13 @@ +MT8173 with RT5650 RT5676 CODECS + +Required properties: +- compatible : "mediatek,mt8173-rt5650-rt5676" +- mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs + +Example: + + sound { + compatible = "mediatek,mt8173-rt5650-rt5676"; + mediatek,audio-codec = < >; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 0bfd2a0..15c04e2 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -17,3 +17,14 @@ config SND_SOC_MT8173_MAX98090 Select Y if you have such device. If unsure select "N". +config SND_SOC_MT8173_RT5650_RT5676 + tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" + depends on SND_SOC_MEDIATEK + select SND_SOC_RT5645 + select SND_SOC_RT5677 + help + This adds ASoC driver for Mediatek MT8173 boards + with the RT5650 and RT5676 codecs. + Select Y if you have such device. + If unsure select "N". + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 08fa765..75effbe 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o # Machine support obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o +obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c new file mode 100644 index 000..0940553 --- /dev/null +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -0,0 +1,278 @@ +/* + * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "../codecs/rt5645.h" +#include "../codecs/rt5677.h" + +#define MCLK_FOR_CODECS12288000 + +static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { + {"Speaker", NULL, "SPOL"}, + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ + {"Sub DMIC L1", NULL, "Int Mic"}, /* DMIC from 5676 */ + {"Sub DMIC R1", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ + {"Headset Mic", NULL, "micbias1"}, + {"Headset Mic", NULL, "micbias2"}, + {"IN1P", NULL, "Headset Mic"}, + {"IN1N", NULL, "Headset Mic"}, + {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ +}; + +static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream
[PATCH v2 0/3] ASoC: Mediatek: Add support for MT8173 SOC
This adds basic support for the Mediatek AFE (Audio Front End) unit of MT8173. This patch is based on Linux 4.1-rc1 and Sascha's SCPSYS power patch [1]. The AFE unit comprises several memory interfaces that communicate with CPU, a multi input multi output digital audio interconnect, and several external interfaces (e.g. I2S). [1] https://lkml.org/lkml/2015/6/9/172 changes since v1: - change Kconfig to tristate - remove unnecessary !! in the platform driver - let MODULE_DEVICE_TABLE follow the table - remove regulators from machine drivers changes since RFC: - Use DPCM to model AFE AFE memory interfaces such as DL1, VUL are modeled as frontend DAIs, and AFE IOs such as I2S, HDMI are backend DAIs. Which memif and IO to be used can be set in the machine driver. There is no need to indicate this in dts anymore so include/dt-bindings/sound/mtk-afe.h is removed. AFE connections are represented by DAPM widgets and routes, and set connection APIs/tables are no longer required. (mtk-afe-connection.c and mtk-afe-connection.h are removed) -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/3] ASoC: mediatek: Add AFE platform driver
This is the DPCM based platform driver of AFE (Audio Front End) unit. Signed-off-by: Sascha Hauer s.ha...@pengutronix.de Signed-off-by: Koro Chen koro.c...@mediatek.com --- .../devicetree/bindings/sound/mtk-afe-pcm.txt | 45 + sound/soc/Kconfig |1 + sound/soc/Makefile |1 + sound/soc/mediatek/Kconfig |9 + sound/soc/mediatek/Makefile|2 + sound/soc/mediatek/mtk-afe-common.h| 109 ++ sound/soc/mediatek/mtk-afe-pcm.c | 1233 7 files changed, 1400 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt create mode 100644 sound/soc/mediatek/Kconfig create mode 100644 sound/soc/mediatek/Makefile create mode 100644 sound/soc/mediatek/mtk-afe-common.h create mode 100644 sound/soc/mediatek/mtk-afe-pcm.c diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt new file mode 100644 index 000..e302c7f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt @@ -0,0 +1,45 @@ +Mediatek AFE PCM controller + +Required properties: +- compatible = mediatek,mt8173-afe-pcm; +- reg: register location and size +- interrupts: Should contain AFE interrupt +- clock-names: should have these clock names: + infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + +Example: + + afe: mt8173-afe-pcm@1122 { + compatible = mediatek,mt8173-afe-pcm; + reg = 0 0x1122 0 0x1000; + interrupts = GIC_SPI 134 IRQ_TYPE_EDGE_FALLING; + clocks = infracfg INFRA_AUDIO, + topckgen TOP_AUDIO_SEL, + topckgen TOP_AUD_INTBUS_SEL, + topckgen TOP_APLL1_DIV0, + topckgen TOP_APLL2_DIV0, + topckgen TOP_I2S0_M_CK_SEL, + topckgen TOP_I2S1_M_CK_SEL, + topckgen TOP_I2S2_M_CK_SEL, + topckgen TOP_I2S3_M_CK_SEL, + topckgen TOP_I2S3_B_CK_SEL; + clock-names = infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3ba52da..cc1b718 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -45,6 +45,7 @@ source sound/soc/nuc900/Kconfig source sound/soc/omap/Kconfig source sound/soc/kirkwood/Kconfig source sound/soc/intel/Kconfig +source sound/soc/mediatek/Kconfig source sound/soc/mxs/Kconfig source sound/soc/pxa/Kconfig source sound/soc/qcom/Kconfig diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 974ba70..e552633 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += intel/ +obj-$(CONFIG_SND_SOC) += mediatek/ obj-$(CONFIG_SND_SOC) += mxs/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig new file mode 100644 index 000..c622280 --- /dev/null +++ b/sound/soc/mediatek/Kconfig @@ -0,0 +1,9 @@ +config SND_SOC_MEDIATEK + tristate ASoC support for Mediatek chip + depends on ARCH_MEDIATEK + help + This adds ASoC platform driver support for Mediatek chip + that can be used with other codecs. + Select Y if you have such device. + Ex: MT8173 + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile new file mode 100644 index 000..5f27cc7 --- /dev/null +++ b/sound/soc/mediatek/Makefile @@ -0,0 +1,2 @@ +# MTK Platform Support +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h new file mode 100644 index 000..a88b175 --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -0,0 +1,109 @@ +/* + * mtk_afe_common.h -- Mediatek audio driver common definitions + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * Sascha Hauer s.ha...@pengutronix.de + * Hidalgo Huang hidalgo.hu...@mediatek.com + * Ir Lian ir.l...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify
[PATCH v2 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
This is the DPCM based machine driver with MAX98090 Signed-off-by: Koro Chen koro.c...@mediatek.com --- .../devicetree/bindings/sound/mt8173-max98090.txt | 13 ++ sound/soc/mediatek/Kconfig | 10 + sound/soc/mediatek/Makefile| 2 + sound/soc/mediatek/mt8173-max98090.c | 213 + 4 files changed, 238 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-max98090.txt create mode 100644 sound/soc/mediatek/mt8173-max98090.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt new file mode 100644 index 000..829bd26 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -0,0 +1,13 @@ +MT8173 with MAX98090 CODEC + +Required properties: +- compatible : mediatek,mt8173-max98090 +- mediatek,audio-codec: the phandle of the MAX98090 audio codec + +Example: + + sound { + compatible = mediatek,mt8173-max98090; + mediatek,audio-codec = max98090; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index c622280..0bfd2a0 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -7,3 +7,13 @@ config SND_SOC_MEDIATEK Select Y if you have such device. Ex: MT8173 +config SND_SOC_MT8173_MAX98090 + tristate ASoC Audio driver for MT8173 with MAX98090 codec + depends on SND_SOC_MEDIATEK + select SND_SOC_MAX98090 + help + This adds ASoC driver for Mediatek MT8173 boards + with the MAX98090 audio codec. + Select Y if you have such device. + If unsure select N. + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 5f27cc7..08fa765 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -1,2 +1,4 @@ # MTK Platform Support obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o +# Machine support +obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c new file mode 100644 index 000..4d44b58 --- /dev/null +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -0,0 +1,213 @@ +/* + * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include linux/module.h +#include sound/soc.h +#include sound/jack.h +#include linux/gpio.h +#include ../codecs/max98090.h + +static struct snd_soc_jack mt8173_max98090_jack; + +static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = { + { + .pin= Headphone, + .mask = SND_JACK_HEADPHONE, + }, + { + .pin= Headset Mic, + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = { + SND_SOC_DAPM_SPK(Speaker, NULL), + SND_SOC_DAPM_MIC(Int Mic, NULL), + SND_SOC_DAPM_HP(Headphone, NULL), + SND_SOC_DAPM_MIC(Headset Mic, NULL), +}; + +static const struct snd_soc_dapm_route mt8173_max98090_routes[] = { + {Speaker, NULL, SPKL}, + {Speaker, NULL, SPKR}, + {DMICL, NULL, Int Mic}, + {Headphone, NULL, HPL}, + {Headphone, NULL, HPR}, + {Headset Mic, NULL, MICBIAS}, + {IN34, NULL, Headset Mic}, +}; + +static const struct snd_kcontrol_new mt8173_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH(Speaker), + SOC_DAPM_PIN_SWITCH(Int Mic), + SOC_DAPM_PIN_SWITCH(Headphone), + SOC_DAPM_PIN_SWITCH(Headset Mic), +}; + +static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream-private_data; + struct snd_soc_dai *codec_dai = rtd-codec_dai; + + return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256, + SND_SOC_CLOCK_IN); +} + +static struct snd_soc_ops mt8173_max98090_ops = { + .hw_params = mt8173_max98090_hw_params, +}; + +static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret; + struct snd_soc_card *card = runtime-card; + struct snd_soc_codec *codec = runtime-codec; + + /* enable jack detection */ + ret = snd_soc_card_jack_new(card, Headphone, SND_JACK_HEADPHONE
[PATCH v2 3/3] ASoC: mediatek: Add machine driver for rt5650 rt5676 codec
This is the DPCM based machine driver with rt5650 and rt5676 Signed-off-by: Nicolas Boichat drink...@chromium.org Signed-off-by: Koro Chen koro.c...@mediatek.com --- .../bindings/sound/mt8173-rt5650-rt5676.txt| 13 + sound/soc/mediatek/Kconfig | 11 + sound/soc/mediatek/Makefile| 1 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 278 + 4 files changed, 303 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt create mode 100644 sound/soc/mediatek/mt8173-rt5650-rt5676.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt new file mode 100644 index 000..61e98c9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -0,0 +1,13 @@ +MT8173 with RT5650 RT5676 CODECS + +Required properties: +- compatible : mediatek,mt8173-rt5650-rt5676 +- mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs + +Example: + + sound { + compatible = mediatek,mt8173-rt5650-rt5676; + mediatek,audio-codec = rt5650 rt5676; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 0bfd2a0..15c04e2 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -17,3 +17,14 @@ config SND_SOC_MT8173_MAX98090 Select Y if you have such device. If unsure select N. +config SND_SOC_MT8173_RT5650_RT5676 + tristate ASoC Audio driver for MT8173 with RT5650 RT5676 codecs + depends on SND_SOC_MEDIATEK + select SND_SOC_RT5645 + select SND_SOC_RT5677 + help + This adds ASoC driver for Mediatek MT8173 boards + with the RT5650 and RT5676 codecs. + Select Y if you have such device. + If unsure select N. + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 08fa765..75effbe 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o # Machine support obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o +obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c new file mode 100644 index 000..0940553 --- /dev/null +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -0,0 +1,278 @@ +/* + * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include linux/module.h +#include linux/gpio.h +#include linux/of_gpio.h +#include sound/soc.h +#include sound/jack.h +#include ../codecs/rt5645.h +#include ../codecs/rt5677.h + +#define MCLK_FOR_CODECS12288000 + +static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { + SND_SOC_DAPM_SPK(Speaker, NULL), + SND_SOC_DAPM_MIC(Int Mic, NULL), + SND_SOC_DAPM_HP(Headphone, NULL), + SND_SOC_DAPM_MIC(Headset Mic, NULL), +}; + +static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { + {Speaker, NULL, SPOL}, + {Speaker, NULL, SPOR}, + {Speaker, NULL, Sub AIF2TX}, /* IF2 ADC to 5650 */ + {Sub DMIC L1, NULL, Int Mic}, /* DMIC from 5676 */ + {Sub DMIC R1, NULL, Int Mic}, + {Headphone, NULL, HPOL}, + {Headphone, NULL, HPOR}, + {Headphone, NULL, Sub AIF2TX}, /* IF2 ADC to 5650 */ + {Headset Mic, NULL, micbias1}, + {Headset Mic, NULL, micbias2}, + {IN1P, NULL, Headset Mic}, + {IN1N, NULL, Headset Mic}, + {Sub AIF2RX, NULL, Headset Mic}, /* IF2 DAC from 5650 */ +}; + +static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { + SOC_DAPM_PIN_SWITCH(Speaker), + SOC_DAPM_PIN_SWITCH(Int Mic), + SOC_DAPM_PIN_SWITCH(Headphone), + SOC_DAPM_PIN_SWITCH(Headset Mic), +}; + +static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream-private_data; + int i, ret; + + for (i = 0; i rtd-num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd-codec_dais[i]; + + /* pll from mclk 12.288M */ + ret = snd_soc_dai_set_pll(codec_dai, 0, 0
Re: [PATCH 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
On Fri, 2015-06-12 at 14:13 +0100, Mark Brown wrote: > On Wed, Jun 10, 2015 at 10:24:35PM +0800, Koro Chen wrote: > > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt > > @@ -0,0 +1,17 @@ > > +MT8173 with MAX98090 CODEC > > + > > +Required properties: > > +- compatible : "mediatek,mt8173-max98090" > > +- mediatek,audio-codec: the phandle of the MAX98090 audio codec > > +- dvdd-supply : the phandle of regulator to supply 1.2V > > +- avdd-supply : the phandle of regulator to supply 1.8V > > Why are these supplies part of the machine driver? > These are for the codec as you said. I think I should remove all these supplies as well as codes in machine drivers, since now the regulators are configured during the board's bootloader stage. > > +config SND_SOC_MT8173_MAX98090 > > + bool "ASoC Audio driver for MT8173 with MAX98090 codec" > > Why bool? > This should be tristate as Paul mentioned before. I will fix it. > > + codec_node = of_parse_phandle(pdev->dev.of_node, > > + "mediatek,audio-codec", 0); > > + if (!codec_node) { > > + dev_err(>dev, > > + "Property 'audio-codec' missing or invalid\n"); > > + } else { > > Isn't this a fatal error? > Thank you and yes it should be fatal, I will fix it. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Fri, 2015-06-12 at 14:06 +0100, Mark Brown wrote: > On Wed, Jun 10, 2015 at 10:24:34PM +0800, Koro Chen wrote: > > This is the DPCM based platform driver of AFE (Audio Front End) unit. > > > > Signed-off-by: Koro Chen > > Signed-off-by: Sascha Hauer > > Your signoff should be last if you're the one sending the patch. > Otherwise this seems basically fine, but you said you were going to send > a new version so not applying. Thank you, I will fix this in the next version of patch along with fixups of Paul's comments. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Fri, 2015-06-12 at 14:06 +0100, Mark Brown wrote: On Wed, Jun 10, 2015 at 10:24:34PM +0800, Koro Chen wrote: This is the DPCM based platform driver of AFE (Audio Front End) unit. Signed-off-by: Koro Chen koro.c...@mediatek.com Signed-off-by: Sascha Hauer s.ha...@pengutronix.de Your signoff should be last if you're the one sending the patch. Otherwise this seems basically fine, but you said you were going to send a new version so not applying. Thank you, I will fix this in the next version of patch along with fixups of Paul's comments. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
On Fri, 2015-06-12 at 14:13 +0100, Mark Brown wrote: On Wed, Jun 10, 2015 at 10:24:35PM +0800, Koro Chen wrote: --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -0,0 +1,17 @@ +MT8173 with MAX98090 CODEC + +Required properties: +- compatible : mediatek,mt8173-max98090 +- mediatek,audio-codec: the phandle of the MAX98090 audio codec +- dvdd-supply : the phandle of regulator to supply 1.2V +- avdd-supply : the phandle of regulator to supply 1.8V Why are these supplies part of the machine driver? These are for the codec as you said. I think I should remove all these supplies as well as codes in machine drivers, since now the regulators are configured during the board's bootloader stage. +config SND_SOC_MT8173_MAX98090 + bool ASoC Audio driver for MT8173 with MAX98090 codec Why bool? This should be tristate as Paul mentioned before. I will fix it. + codec_node = of_parse_phandle(pdev-dev.of_node, + mediatek,audio-codec, 0); + if (!codec_node) { + dev_err(pdev-dev, + Property 'audio-codec' missing or invalid\n); + } else { Isn't this a fatal error? Thank you and yes it should be fatal, I will fix it. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Fri, 2015-06-12 at 09:37 +0200, Paul Bolle wrote: > On Fri, 2015-06-12 at 09:55 +0800, Koro Chen wrote: > > On Thu, 2015-06-11 at 09:03 +0200, Paul Bolle wrote: > > > (What does negating a bool twice do?) > > > > > Because bool actually can be unsigned char, although actually in this > > driver, the caller always passes "true" or "false" to this function. > > bool is _Bool in the kernel (see include/linux/types.h). So whenever you > see a bool in the kernel you can assume it's either 0 or 1. Are there > any cases where this conveniently simple rule doesn't hold? > > But here the discussion is moot, because as you say, the function will > only be passed false or true so we know "enable" is either 0 or 1 and > double negating will do nothing. > > > Do you think if this is the case, should I still need to do !!? > > So you should not, as it's confusing at best. > OK, thank you. I will drop it in the next version of patch. > Thanks, > > > Paul Bolle > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Fri, 2015-06-12 at 09:37 +0200, Paul Bolle wrote: On Fri, 2015-06-12 at 09:55 +0800, Koro Chen wrote: On Thu, 2015-06-11 at 09:03 +0200, Paul Bolle wrote: (What does negating a bool twice do?) Because bool actually can be unsigned char, although actually in this driver, the caller always passes true or false to this function. bool is _Bool in the kernel (see include/linux/types.h). So whenever you see a bool in the kernel you can assume it's either 0 or 1. Are there any cases where this conveniently simple rule doesn't hold? But here the discussion is moot, because as you say, the function will only be passed false or true so we know enable is either 0 or 1 and double negating will do nothing. Do you think if this is the case, should I still need to do !!? So you should not, as it's confusing at best. OK, thank you. I will drop it in the next version of patch. Thanks, Paul Bolle -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Thu, 2015-06-11 at 09:03 +0200, Paul Bolle wrote: > On Wed, 2015-06-10 at 22:24 +0800, Koro Chen wrote: > > --- /dev/null > > +++ b/sound/soc/mediatek/Kconfig > > > +config SND_SOC_MEDIATEK > > + bool "ASoC support for Mediatek chip" > > + depends on ARCH_MEDIATEK > > + help > > + This adds ASoC platform driver support for Mediatek chip > > + that can be used with other codecs. > > + Select Y if you have such device. > > + Ex: MT8173 > > > --- /dev/null > > +++ b/sound/soc/mediatek/Makefile > > > +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o > > > --- /dev/null > > +++ b/sound/soc/mediatek/mtk-afe-pcm.c > > > +#include > > > +static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable) > > +{ > > + unsigned int val; > > + > > + regmap_read(afe->regmap, AFE_I2S_CON2, ); > > + if (!!(val & AFE_I2S_CON2_EN) == !!enable) > > (What does negating a bool twice do?) > Because bool actually can be unsigned char, although actually in this driver, the caller always passes "true" or "false" to this function. Do you think if this is the case, should I still need to do !!? > > + return; /* must skip soft reset */ > > + > > + /* I2S soft reset begin */ > > + regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0x4); > > + > > + /* input */ > > + regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, !!enable); > > Ditto. > > > + > > + /* output */ > > + regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, !!enable); > > Ditto. > > > + > > + /* I2S soft reset end */ > > + udelay(1); > > + regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0); > > +} > > > +static const struct of_device_id mtk_afe_pcm_dt_match[] = { > > + { .compatible = "mediatek,mt8173-afe-pcm", }, > > + { } > > +}; > > > +static struct platform_driver mtk_afe_pcm_driver = { > > + .driver = { > > + .name = "mtk-afe-pcm", > > + .owner = THIS_MODULE, > > + .of_match_table = mtk_afe_pcm_dt_match, > > + .pm = _afe_pm_ops, > > + }, > > + .probe = mtk_afe_pcm_dev_probe, > > + .remove = mtk_afe_pcm_dev_remove, > > +}; > > > +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver"); > > +MODULE_AUTHOR("Koro Chen "); > > +MODULE_LICENSE("GPL v2"); > > +MODULE_DEVICE_TABLE(of, mtk_afe_pcm_dt_match); > > (The common pattern is to have MODULE_DEVICE_TABLE() directly follow > that table.) > Thank you for mentioning this, I will fix it. > SND_SOC_MEDIATEK is a bool symbol and mtk-afe-pcm.o is built-in only. > But the code uses a few module specific constructs. I spotted > THIS_MODULE, MODULE_DESCRIPTION, MODULE_AUTHOR, MODULE_LICENSE, and > MODULE_DEVICE_TABLE. > > Is SND_SOC_MEDIATEK perhaps meant to be bool? > > Likewise for SND_SOC_MT8173_MAX98090 (in 2/3) and > SND_SOC_MT8173_RT5650_RT5676 (in 3/3). > OK, yes, I think I should replace it by tristate, thank you! > Thanks, > > > Paul Bolle > > ___ > Alsa-devel mailing list > alsa-de...@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [alsa-devel] [PATCH 1/3] ASoC: mediatek: Add AFE platform driver
On Thu, 2015-06-11 at 09:03 +0200, Paul Bolle wrote: On Wed, 2015-06-10 at 22:24 +0800, Koro Chen wrote: --- /dev/null +++ b/sound/soc/mediatek/Kconfig +config SND_SOC_MEDIATEK + bool ASoC support for Mediatek chip + depends on ARCH_MEDIATEK + help + This adds ASoC platform driver support for Mediatek chip + that can be used with other codecs. + Select Y if you have such device. + Ex: MT8173 --- /dev/null +++ b/sound/soc/mediatek/Makefile +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-pcm.c +#include linux/module.h +static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable) +{ + unsigned int val; + + regmap_read(afe-regmap, AFE_I2S_CON2, val); + if (!!(val AFE_I2S_CON2_EN) == !!enable) (What does negating a bool twice do?) Because bool actually can be unsigned char, although actually in this driver, the caller always passes true or false to this function. Do you think if this is the case, should I still need to do !!? + return; /* must skip soft reset */ + + /* I2S soft reset begin */ + regmap_update_bits(afe-regmap, AUDIO_TOP_CON1, 0x4, 0x4); + + /* input */ + regmap_update_bits(afe-regmap, AFE_I2S_CON2, 0x1, !!enable); Ditto. + + /* output */ + regmap_update_bits(afe-regmap, AFE_I2S_CON1, 0x1, !!enable); Ditto. + + /* I2S soft reset end */ + udelay(1); + regmap_update_bits(afe-regmap, AUDIO_TOP_CON1, 0x4, 0); +} +static const struct of_device_id mtk_afe_pcm_dt_match[] = { + { .compatible = mediatek,mt8173-afe-pcm, }, + { } +}; +static struct platform_driver mtk_afe_pcm_driver = { + .driver = { + .name = mtk-afe-pcm, + .owner = THIS_MODULE, + .of_match_table = mtk_afe_pcm_dt_match, + .pm = mtk_afe_pm_ops, + }, + .probe = mtk_afe_pcm_dev_probe, + .remove = mtk_afe_pcm_dev_remove, +}; +MODULE_DESCRIPTION(Mediatek ALSA SoC AFE platform driver); +MODULE_AUTHOR(Koro Chen koro.c...@mediatek.com); +MODULE_LICENSE(GPL v2); +MODULE_DEVICE_TABLE(of, mtk_afe_pcm_dt_match); (The common pattern is to have MODULE_DEVICE_TABLE() directly follow that table.) Thank you for mentioning this, I will fix it. SND_SOC_MEDIATEK is a bool symbol and mtk-afe-pcm.o is built-in only. But the code uses a few module specific constructs. I spotted THIS_MODULE, MODULE_DESCRIPTION, MODULE_AUTHOR, MODULE_LICENSE, and MODULE_DEVICE_TABLE. Is SND_SOC_MEDIATEK perhaps meant to be bool? Likewise for SND_SOC_MT8173_MAX98090 (in 2/3) and SND_SOC_MT8173_RT5650_RT5676 (in 3/3). OK, yes, I think I should replace it by tristate, thank you! Thanks, Paul Bolle ___ Alsa-devel mailing list alsa-de...@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] ASoC: mediatek: Add machine driver for rt5650 rt5676 codec
This is the DPCM based machine driver with rt5650 and rt5676 Signed-off-by: Koro Chen Signed-off-by: Nicolas Boichat --- .../bindings/sound/mt8173-rt5650-rt5676.txt| 15 ++ sound/soc/mediatek/Kconfig | 12 + sound/soc/mediatek/Makefile| 1 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 300 + 4 files changed, 328 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt create mode 100644 sound/soc/mediatek/mt8173-rt5650-rt5676.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt new file mode 100644 index 000..5fbdf39 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -0,0 +1,15 @@ +MT8173 with RT5650 RT5676 CODECS + +Required properties: +- compatible : "mediatek,mt8173-rt5650-rt5676" +- mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs +- avdd-supply : the phandle of regulator to supply 1.8V + +Example: + + sound { + compatible = "mediatek,mt8173-rt5650-rt5676"; + mediatek,audio-codec = < >; + avdd-supply = <_vgp1_reg>; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 6fb337e..6f03e26 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -18,3 +18,15 @@ config SND_SOC_MT8173_MAX98090 Select Y if you have such device. If unsure select "N". +config SND_SOC_MT8173_RT5650_RT5676 + bool "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + select SND_SOC_RT5645 + select SND_SOC_RT5677 + help + This adds ASoC driver for Mediatek MT8173 boards + with the RT5650 and RT5676 codecs. + Select Y if you have such device. + If unsure select "N". + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 08fa765..75effbe 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o # Machine support obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o +obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c new file mode 100644 index 000..ceff158 --- /dev/null +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -0,0 +1,300 @@ +/* + * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "../codecs/rt5645.h" +#include "../codecs/rt5677.h" + +#define MCLK_FOR_CODECS12288000 + +static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { + {"Speaker", NULL, "SPOL"}, + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ + {"Sub DMIC L1", NULL, "Int Mic"}, /* DMIC from 5676 */ + {"Sub DMIC R1", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ + {"Headset Mic", NULL, "micbias1"}, + {"Headset Mic", NULL, "micbias2"}, + {"IN1P", NULL, "Headset Mic"}, + {"IN1N", NULL, "Headset Mic"}, + {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ +}; + +static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITC
[PATCH 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
This is the DPCM based machine driver with MAX98090 Signed-off-by: Koro Chen --- .../devicetree/bindings/sound/mt8173-max98090.txt | 17 ++ sound/soc/mediatek/Kconfig | 11 + sound/soc/mediatek/Makefile| 2 + sound/soc/mediatek/mt8173-max98090.c | 260 + 4 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-max98090.txt create mode 100644 sound/soc/mediatek/mt8173-max98090.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt new file mode 100644 index 000..8d6b84c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -0,0 +1,17 @@ +MT8173 with MAX98090 CODEC + +Required properties: +- compatible : "mediatek,mt8173-max98090" +- mediatek,audio-codec: the phandle of the MAX98090 audio codec +- dvdd-supply : the phandle of regulator to supply 1.2V +- avdd-supply : the phandle of regulator to supply 1.8V + +Example: + + sound { + compatible = "mediatek,mt8173-max98090"; + mediatek,audio-codec = <>; + dvdd-supply = <_vgp1_reg>; + avdd-supply = <_vgp4_reg>; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 38630d4..6fb337e 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -7,3 +7,14 @@ config SND_SOC_MEDIATEK Select Y if you have such device. Ex: MT8173 +config SND_SOC_MT8173_MAX98090 + bool "ASoC Audio driver for MT8173 with MAX98090 codec" + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + select SND_SOC_MAX98090 + help + This adds ASoC driver for Mediatek MT8173 boards + with the MAX98090 audio codec. + Select Y if you have such device. + If unsure select "N". + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 5f27cc7..08fa765 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -1,2 +1,4 @@ # MTK Platform Support obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o +# Machine support +obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c new file mode 100644 index 000..5cb782a --- /dev/null +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -0,0 +1,260 @@ +/* + * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "../codecs/max98090.h" + +static struct snd_soc_jack mt8173_max98090_jack; + +static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = { + { + .pin= "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin= "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8173_max98090_routes[] = { + {"Speaker", NULL, "SPKL"}, + {"Speaker", NULL, "SPKR"}, + {"DMICL", NULL, "Int Mic"}, + {"Headphone", NULL, "HPL"}, + {"Headphone", NULL, "HPR"}, + {"Headset Mic", NULL, "MICBIAS"}, + {"IN34", NULL, "Headset Mic"}, +}; + +static const struct snd_kcontrol_new mt8173_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_syscl
[PATCH 1/3] ASoC: mediatek: Add AFE platform driver
This is the DPCM based platform driver of AFE (Audio Front End) unit. Signed-off-by: Koro Chen Signed-off-by: Sascha Hauer --- .../devicetree/bindings/sound/mtk-afe-pcm.txt | 45 + sound/soc/Kconfig |1 + sound/soc/Makefile |1 + sound/soc/mediatek/Kconfig |9 + sound/soc/mediatek/Makefile|2 + sound/soc/mediatek/mtk-afe-common.h| 109 ++ sound/soc/mediatek/mtk-afe-pcm.c | 1233 7 files changed, 1400 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt create mode 100644 sound/soc/mediatek/Kconfig create mode 100644 sound/soc/mediatek/Makefile create mode 100644 sound/soc/mediatek/mtk-afe-common.h create mode 100644 sound/soc/mediatek/mtk-afe-pcm.c diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt new file mode 100644 index 000..e302c7f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt @@ -0,0 +1,45 @@ +Mediatek AFE PCM controller + +Required properties: +- compatible = "mediatek,mt8173-afe-pcm"; +- reg: register location and size +- interrupts: Should contain AFE interrupt +- clock-names: should have these clock names: + "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + +Example: + + afe: mt8173-afe-pcm@1122 { + compatible = "mediatek,mt8173-afe-pcm"; + reg = <0 0x1122 0 0x1000>; + interrupts = ; + clocks = < INFRA_AUDIO>, + < TOP_AUDIO_SEL>, + < TOP_AUD_INTBUS_SEL>, + < TOP_APLL1_DIV0>, + < TOP_APLL2_DIV0>, + < TOP_I2S0_M_CK_SEL>, + < TOP_I2S1_M_CK_SEL>, + < TOP_I2S2_M_CK_SEL>, + < TOP_I2S3_M_CK_SEL>, + < TOP_I2S3_B_CK_SEL>; + clock-names = "infra_sys_audio_clk", + "top_pdn_audio", + "top_pdn_aud_intbus", + "bck0", + "bck1", + "i2s0_m", + "i2s1_m", + "i2s2_m", + "i2s3_m", + "i2s3_b"; + }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3ba52da..cc1b718 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -45,6 +45,7 @@ source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" source "sound/soc/intel/Kconfig" +source "sound/soc/mediatek/Kconfig" source "sound/soc/mxs/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/qcom/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 974ba70..e552633 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += intel/ +obj-$(CONFIG_SND_SOC) += mediatek/ obj-$(CONFIG_SND_SOC) += mxs/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig new file mode 100644 index 000..38630d4 --- /dev/null +++ b/sound/soc/mediatek/Kconfig @@ -0,0 +1,9 @@ +config SND_SOC_MEDIATEK + bool "ASoC support for Mediatek chip" + depends on ARCH_MEDIATEK + help + This adds ASoC platform driver support for Mediatek chip + that can be used with other codecs. + Select Y if you have such device. + Ex: MT8173 + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile new file mode 100644 index 000..5f27cc7 --- /dev/null +++ b/sound/soc/mediatek/Makefile @@ -0,0 +1,2 @@ +# MTK Platform Support +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h new file mode 100644 index 000..a88b175 --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -0,0 +1,109 @@ +/* + * mtk_afe_common.h -- Mediatek audio driver common definitions + * + *
[PATCH 0/3] ASoC: Mediatek: Add support for MT8173 SoC
This adds basic support for the Mediatek AFE (Audio Front End) unit for MT8173. This patch is based on Linux 4.1-rc1 and Sascha's SCPSYS power patch [1]. The AFE unit comprises several memory interfaces that communicate with CPU, a multi input multi output digital audio interconnect, and several external interfaces (e.g. I2S). [1] https://lkml.org/lkml/2015/6/9/172 changes since RFC: - Use DPCM to model AFE AFE memory interfaces such as DL1, VUL are modeled as frontend DAIs, and AFE IOs such as I2S, HDMI are backend DAIs. Which memif and IO to be used can be set in the machine driver. There is no need to indicate this in dts anymore so include/dt-bindings/sound/mtk-afe.h is removed. AFE connections are represented by DAPM widgets and routes, and set connection APIs/tables are no longer required. (mtk-afe-connection.c and mtk-afe-connection.h are removed) Instead, mixer controls are used to do connection/disconnection. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/3] ASoC: Mediatek: Add support for MT8173 SoC
This adds basic support for the Mediatek AFE (Audio Front End) unit for MT8173. This patch is based on Linux 4.1-rc1 and Sascha's SCPSYS power patch [1]. The AFE unit comprises several memory interfaces that communicate with CPU, a multi input multi output digital audio interconnect, and several external interfaces (e.g. I2S). [1] https://lkml.org/lkml/2015/6/9/172 changes since RFC: - Use DPCM to model AFE AFE memory interfaces such as DL1, VUL are modeled as frontend DAIs, and AFE IOs such as I2S, HDMI are backend DAIs. Which memif and IO to be used can be set in the machine driver. There is no need to indicate this in dts anymore so include/dt-bindings/sound/mtk-afe.h is removed. AFE connections are represented by DAPM widgets and routes, and set connection APIs/tables are no longer required. (mtk-afe-connection.c and mtk-afe-connection.h are removed) Instead, mixer controls are used to do connection/disconnection. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] ASoC: mediatek: Add machine driver for MAX98090 codec
This is the DPCM based machine driver with MAX98090 Signed-off-by: Koro Chen koro.c...@mediatek.com --- .../devicetree/bindings/sound/mt8173-max98090.txt | 17 ++ sound/soc/mediatek/Kconfig | 11 + sound/soc/mediatek/Makefile| 2 + sound/soc/mediatek/mt8173-max98090.c | 260 + 4 files changed, 290 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-max98090.txt create mode 100644 sound/soc/mediatek/mt8173-max98090.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt new file mode 100644 index 000..8d6b84c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt @@ -0,0 +1,17 @@ +MT8173 with MAX98090 CODEC + +Required properties: +- compatible : mediatek,mt8173-max98090 +- mediatek,audio-codec: the phandle of the MAX98090 audio codec +- dvdd-supply : the phandle of regulator to supply 1.2V +- avdd-supply : the phandle of regulator to supply 1.8V + +Example: + + sound { + compatible = mediatek,mt8173-max98090; + mediatek,audio-codec = max98090; + dvdd-supply = mt6397_vgp1_reg; + avdd-supply = mt6397_vgp4_reg; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 38630d4..6fb337e 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -7,3 +7,14 @@ config SND_SOC_MEDIATEK Select Y if you have such device. Ex: MT8173 +config SND_SOC_MT8173_MAX98090 + bool ASoC Audio driver for MT8173 with MAX98090 codec + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + select SND_SOC_MAX98090 + help + This adds ASoC driver for Mediatek MT8173 boards + with the MAX98090 audio codec. + Select Y if you have such device. + If unsure select N. + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 5f27cc7..08fa765 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -1,2 +1,4 @@ # MTK Platform Support obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o +# Machine support +obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c new file mode 100644 index 000..5cb782a --- /dev/null +++ b/sound/soc/mediatek/mt8173-max98090.c @@ -0,0 +1,260 @@ +/* + * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include linux/module.h +#include sound/soc.h +#include sound/jack.h +#include linux/gpio.h +#include linux/regulator/consumer.h +#include ../codecs/max98090.h + +static struct snd_soc_jack mt8173_max98090_jack; + +static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = { + { + .pin= Headphone, + .mask = SND_JACK_HEADPHONE, + }, + { + .pin= Headset Mic, + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = { + SND_SOC_DAPM_SPK(Speaker, NULL), + SND_SOC_DAPM_MIC(Int Mic, NULL), + SND_SOC_DAPM_HP(Headphone, NULL), + SND_SOC_DAPM_MIC(Headset Mic, NULL), +}; + +static const struct snd_soc_dapm_route mt8173_max98090_routes[] = { + {Speaker, NULL, SPKL}, + {Speaker, NULL, SPKR}, + {DMICL, NULL, Int Mic}, + {Headphone, NULL, HPL}, + {Headphone, NULL, HPR}, + {Headset Mic, NULL, MICBIAS}, + {IN34, NULL, Headset Mic}, +}; + +static const struct snd_kcontrol_new mt8173_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH(Speaker), + SOC_DAPM_PIN_SWITCH(Int Mic), + SOC_DAPM_PIN_SWITCH(Headphone), + SOC_DAPM_PIN_SWITCH(Headset Mic), +}; + +static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream-private_data; + struct snd_soc_dai *codec_dai = rtd-codec_dai; + + return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256, + SND_SOC_CLOCK_IN); +} + +static struct snd_soc_ops mt8173_max98090_ops = { + .hw_params = mt8173_max98090_hw_params, +}; + +static int mt8173_max98090_init(struct
[PATCH 1/3] ASoC: mediatek: Add AFE platform driver
This is the DPCM based platform driver of AFE (Audio Front End) unit. Signed-off-by: Koro Chen koro.c...@mediatek.com Signed-off-by: Sascha Hauer s.ha...@pengutronix.de --- .../devicetree/bindings/sound/mtk-afe-pcm.txt | 45 + sound/soc/Kconfig |1 + sound/soc/Makefile |1 + sound/soc/mediatek/Kconfig |9 + sound/soc/mediatek/Makefile|2 + sound/soc/mediatek/mtk-afe-common.h| 109 ++ sound/soc/mediatek/mtk-afe-pcm.c | 1233 7 files changed, 1400 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt create mode 100644 sound/soc/mediatek/Kconfig create mode 100644 sound/soc/mediatek/Makefile create mode 100644 sound/soc/mediatek/mtk-afe-common.h create mode 100644 sound/soc/mediatek/mtk-afe-pcm.c diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt new file mode 100644 index 000..e302c7f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt @@ -0,0 +1,45 @@ +Mediatek AFE PCM controller + +Required properties: +- compatible = mediatek,mt8173-afe-pcm; +- reg: register location and size +- interrupts: Should contain AFE interrupt +- clock-names: should have these clock names: + infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + +Example: + + afe: mt8173-afe-pcm@1122 { + compatible = mediatek,mt8173-afe-pcm; + reg = 0 0x1122 0 0x1000; + interrupts = GIC_SPI 134 IRQ_TYPE_EDGE_FALLING; + clocks = infracfg INFRA_AUDIO, + topckgen TOP_AUDIO_SEL, + topckgen TOP_AUD_INTBUS_SEL, + topckgen TOP_APLL1_DIV0, + topckgen TOP_APLL2_DIV0, + topckgen TOP_I2S0_M_CK_SEL, + topckgen TOP_I2S1_M_CK_SEL, + topckgen TOP_I2S2_M_CK_SEL, + topckgen TOP_I2S3_M_CK_SEL, + topckgen TOP_I2S3_B_CK_SEL; + clock-names = infra_sys_audio_clk, + top_pdn_audio, + top_pdn_aud_intbus, + bck0, + bck1, + i2s0_m, + i2s1_m, + i2s2_m, + i2s3_m, + i2s3_b; + }; diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3ba52da..cc1b718 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -45,6 +45,7 @@ source sound/soc/nuc900/Kconfig source sound/soc/omap/Kconfig source sound/soc/kirkwood/Kconfig source sound/soc/intel/Kconfig +source sound/soc/mediatek/Kconfig source sound/soc/mxs/Kconfig source sound/soc/pxa/Kconfig source sound/soc/qcom/Kconfig diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 974ba70..e552633 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ obj-$(CONFIG_SND_SOC) += intel/ +obj-$(CONFIG_SND_SOC) += mediatek/ obj-$(CONFIG_SND_SOC) += mxs/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig new file mode 100644 index 000..38630d4 --- /dev/null +++ b/sound/soc/mediatek/Kconfig @@ -0,0 +1,9 @@ +config SND_SOC_MEDIATEK + bool ASoC support for Mediatek chip + depends on ARCH_MEDIATEK + help + This adds ASoC platform driver support for Mediatek chip + that can be used with other codecs. + Select Y if you have such device. + Ex: MT8173 + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile new file mode 100644 index 000..5f27cc7 --- /dev/null +++ b/sound/soc/mediatek/Makefile @@ -0,0 +1,2 @@ +# MTK Platform Support +obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h new file mode 100644 index 000..a88b175 --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-common.h @@ -0,0 +1,109 @@ +/* + * mtk_afe_common.h -- Mediatek audio driver common definitions + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * Sascha Hauer s.ha...@pengutronix.de + * Hidalgo Huang hidalgo.hu...@mediatek.com + * Ir Lian ir.l...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify
[PATCH 3/3] ASoC: mediatek: Add machine driver for rt5650 rt5676 codec
This is the DPCM based machine driver with rt5650 and rt5676 Signed-off-by: Koro Chen koro.c...@mediatek.com Signed-off-by: Nicolas Boichat drink...@chromium.org --- .../bindings/sound/mt8173-rt5650-rt5676.txt| 15 ++ sound/soc/mediatek/Kconfig | 12 + sound/soc/mediatek/Makefile| 1 + sound/soc/mediatek/mt8173-rt5650-rt5676.c | 300 + 4 files changed, 328 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt create mode 100644 sound/soc/mediatek/mt8173-rt5650-rt5676.c diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt new file mode 100644 index 000..5fbdf39 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt @@ -0,0 +1,15 @@ +MT8173 with RT5650 RT5676 CODECS + +Required properties: +- compatible : mediatek,mt8173-rt5650-rt5676 +- mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs +- avdd-supply : the phandle of regulator to supply 1.8V + +Example: + + sound { + compatible = mediatek,mt8173-rt5650-rt5676; + mediatek,audio-codec = rt5650 rt5676; + avdd-supply = mt6397_vgp1_reg; + }; + diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 6fb337e..6f03e26 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -18,3 +18,15 @@ config SND_SOC_MT8173_MAX98090 Select Y if you have such device. If unsure select N. +config SND_SOC_MT8173_RT5650_RT5676 + bool ASoC Audio driver for MT8173 with RT5650 RT5676 codecs + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + select SND_SOC_RT5645 + select SND_SOC_RT5677 + help + This adds ASoC driver for Mediatek MT8173 boards + with the RT5650 and RT5676 codecs. + Select Y if you have such device. + If unsure select N. + diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 08fa765..75effbe 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o # Machine support obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o +obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c new file mode 100644 index 000..ceff158 --- /dev/null +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c @@ -0,0 +1,300 @@ +/* + * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs + * + * Copyright (c) 2015 MediaTek Inc. + * Author: Koro Chen koro.c...@mediatek.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include linux/module.h +#include linux/gpio.h +#include linux/of_gpio.h +#include linux/regulator/consumer.h +#include sound/soc.h +#include sound/jack.h +#include ../codecs/rt5645.h +#include ../codecs/rt5677.h + +#define MCLK_FOR_CODECS12288000 + +static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { + SND_SOC_DAPM_SPK(Speaker, NULL), + SND_SOC_DAPM_MIC(Int Mic, NULL), + SND_SOC_DAPM_HP(Headphone, NULL), + SND_SOC_DAPM_MIC(Headset Mic, NULL), +}; + +static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { + {Speaker, NULL, SPOL}, + {Speaker, NULL, SPOR}, + {Speaker, NULL, Sub AIF2TX}, /* IF2 ADC to 5650 */ + {Sub DMIC L1, NULL, Int Mic}, /* DMIC from 5676 */ + {Sub DMIC R1, NULL, Int Mic}, + {Headphone, NULL, HPOL}, + {Headphone, NULL, HPOR}, + {Headphone, NULL, Sub AIF2TX}, /* IF2 ADC to 5650 */ + {Headset Mic, NULL, micbias1}, + {Headset Mic, NULL, micbias2}, + {IN1P, NULL, Headset Mic}, + {IN1N, NULL, Headset Mic}, + {Sub AIF2RX, NULL, Headset Mic}, /* IF2 DAC from 5650 */ +}; + +static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { + SOC_DAPM_PIN_SWITCH(Speaker), + SOC_DAPM_PIN_SWITCH(Int Mic), + SOC_DAPM_PIN_SWITCH(Headphone), + SOC_DAPM_PIN_SWITCH(Headset Mic), +}; + +static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream-private_data; + int i, ret; + + for (i = 0; i rtd-num_codecs; i
[RFC PATCH] ALSA: pcm: Modify double acknowledged interrupts check condition
Currently in snd_pcm_update_hw_ptr0 during interrupt, we consider there were double acknowledged interrupts when: 1. HW reported pointer is smaller than expected, and 2. Time from last update time (hdelta) is over half a buffer time. However, when HW reported pointer is only a few bytes smaller than expected, and when hdelta is just a little larger than half a buffer time (e.g. ping-pong buffer), it wrongly treats this IRQ as double acknowledged. The condition #2 uses jiffies, but jiffies is not high resolution since it is integer. We should consider jiffies inaccuracy. Signed-off-by: Koro Chen --- sound/core/pcm_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ac6b33f..7d45645 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -339,7 +339,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (delta > new_hw_ptr) { /* check for double acknowledged interrupts */ hdelta = curr_jiffies - runtime->hw_ptr_jiffies; - if (hdelta > runtime->hw_ptr_buffer_jiffies/2) { + if (hdelta > runtime->hw_ptr_buffer_jiffies/2 + 1) { hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) { hw_base = 0; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH] ALSA: pcm: Modify double acknowledged interrupts check condition
Currently in snd_pcm_update_hw_ptr0 during interrupt, we consider there were double acknowledged interrupts when: 1. HW reported pointer is smaller than expected, and 2. Time from last update time (hdelta) is over half a buffer time. However, when HW reported pointer is only a few bytes smaller than expected, and when hdelta is just a little larger than half a buffer time (e.g. ping-pong buffer), it wrongly treats this IRQ as double acknowledged. The condition #2 uses jiffies, but jiffies is not high resolution since it is integer. We should consider jiffies inaccuracy. Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/core/pcm_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ac6b33f..7d45645 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -339,7 +339,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (delta new_hw_ptr) { /* check for double acknowledged interrupts */ hdelta = curr_jiffies - runtime-hw_ptr_jiffies; - if (hdelta runtime-hw_ptr_buffer_jiffies/2) { + if (hdelta runtime-hw_ptr_buffer_jiffies/2 + 1) { hw_base += runtime-buffer_size; if (hw_base = runtime-boundary) { hw_base = 0; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dapm: Modify widget stream name according to prefix
When there is prefix specified, currently we will add this prefix in widget->name, but not in widget->sname. it causes failure at snd_soc_dapm_link_dai_widgets: if (!w->sname || !strstr(w->sname, dai_w->name)) because dai_w->name has prefix added, but w->sname does not. We should also add prefix for stream name Signed-off-by: Koro Chen --- sound/soc/soc-dapm.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index defe0f0..158204d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3100,11 +3100,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } prefix = soc_dapm_prefix(dapm); - if (prefix) + if (prefix) { w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name); - else + if (widget->sname) + w->sname = kasprintf(GFP_KERNEL, "%s %s", prefix, +widget->sname); + } else { w->name = kasprintf(GFP_KERNEL, "%s", widget->name); - + if (widget->sname) + w->sname = kasprintf(GFP_KERNEL, "%s", widget->sname); + } if (w->name == NULL) { kfree(w); return NULL; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ASoC: dapm: Modify widget stream name according to prefix
When there is prefix specified, currently we will add this prefix in widget-name, but not in widget-sname. it causes failure at snd_soc_dapm_link_dai_widgets: if (!w-sname || !strstr(w-sname, dai_w-name)) because dai_w-name has prefix added, but w-sname does not. We should also add prefix for stream name Signed-off-by: Koro Chen koro.c...@mediatek.com --- sound/soc/soc-dapm.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index defe0f0..158204d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3100,11 +3100,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } prefix = soc_dapm_prefix(dapm); - if (prefix) + if (prefix) { w-name = kasprintf(GFP_KERNEL, %s %s, prefix, widget-name); - else + if (widget-sname) + w-sname = kasprintf(GFP_KERNEL, %s %s, prefix, +widget-sname); + } else { w-name = kasprintf(GFP_KERNEL, %s, widget-name); - + if (widget-sname) + w-sname = kasprintf(GFP_KERNEL, %s, widget-sname); + } if (w-name == NULL) { kfree(w); return NULL; -- 1.8.1.1.dirty -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Thu, 2015-04-30 at 21:12 +0100, Mark Brown wrote: > On Wed, Apr 22, 2015 at 11:17:20AM +0800, Koro Chen wrote: > > > If using DPCM, it seems the most suitable FE DAIs will be memif, and > > external interface like I2S should be BE DAIs. Do you think it is > > suitable for our memif to be FE DAIs? Then which memif to used can be > > described in a machine driver's FE DAIs. But I think this has a problem > > that our memif is one-direction, playback or capture. So the binded pcm > > device cannot have playback and capture capability together. May it > > cause trouble for user space apps that assumes there will be pcmC0D0p, > > pcmC0D0c? > > I think the only userspace application you really have to worry about > here is PulseAudio which (at least with UCM) should be able to cope > since it needs to handle things like USB microphones. I think > everything else I can think of can either cope or has to handle the same > use cases as PulseAudio does so should have support. Thank you very much for the feedback, I will try DPCM. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Thu, 2015-04-30 at 21:12 +0100, Mark Brown wrote: On Wed, Apr 22, 2015 at 11:17:20AM +0800, Koro Chen wrote: If using DPCM, it seems the most suitable FE DAIs will be memif, and external interface like I2S should be BE DAIs. Do you think it is suitable for our memif to be FE DAIs? Then which memif to used can be described in a machine driver's FE DAIs. But I think this has a problem that our memif is one-direction, playback or capture. So the binded pcm device cannot have playback and capture capability together. May it cause trouble for user space apps that assumes there will be pcmC0D0p, pcmC0D0c? I think the only userspace application you really have to worry about here is PulseAudio which (at least with UCM) should be able to cope since it needs to handle things like USB microphones. I think everything else I can think of can either cope or has to handle the same use cases as PulseAudio does so should have support. Thank you very much for the feedback, I will try DPCM. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Mon, 2015-04-20 at 21:48 +0100, Mark Brown wrote: > On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote: > > On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote: > > > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote: > > > > > +Each external interface (called "IO" in this driver) is presented as a > > > > +DAI to ASoC. An IO must be connected via the interconnect to a memif. > > > > +The connection paths are configured through the device tree. > > > > Why are these connection paths configured via device tree? I would > > > expect that either there would be runtime configurability of these > > > things (particularly if loopback configurations within the hardware are > > > possible) or we'd just allocate memory interfaces to DAIs automatically > > > as DAIs come into use. > > > There is a crossbar switch between the memory interfaces and the DAIs. > > Not every connection is possible, so not every memory interface can be > > used for every DAI. An algorithm choosing a suitable memory interface > > must be quite clever, complicated and also SoC dependent (the same but > > different hardware is used on MT8135 aswell), so I thought offering a > > static configuration via device tree is a good start. Should there be > > runtime configuration possible later the device tree settings could > > provide a good default. > > What exactly do the restrictions look like and how often do they vary in > practice (can we get away with just doing a single static setup in the > driver)? I'd have thought it should be fairly straightforward to have a > table of valid mappings and just pick the first free memory interface? > I'd rather not get stuck with the tables in the DT. It's partly to > avoid setting bad precendents, we really don't want everyone coming > along hard coding this stuff, and partly because the hardware you > described didn't seem that hard to handle. > If using DPCM, it seems the most suitable FE DAIs will be memif, and external interface like I2S should be BE DAIs. Do you think it is suitable for our memif to be FE DAIs? Then which memif to used can be described in a machine driver's FE DAIs. But I think this has a problem that our memif is one-direction, playback or capture. So the binded pcm device cannot have playback and capture capability together. May it cause trouble for user space apps that assumes there will be pcmC0D0p, pcmC0D0c? > > > > +- mem-interface-playback: > > > > + mem-interface-capture: property of memif, format is: > > > use_sram>; > > > > +memif: which memif to be used > > > > + (defined in > > > > include/dt-bindings/sound/mtk-afe.h) > > > > +irq: which irq to be used > > > > + (defined in > > > > include/dt-bindings/sound/mtk-afe.h) > > > > +use_sram: 1 is yes, 0 is no > > > > Again, this looks like stuff we should be able to figure out at runtime > > > - the use of SRAM in particular looks like something we might want to > > > change depending on use case. Assuming it adds buffering then for a > > > VoIP application we might not want to use SRAM to minimize latency but > > > during music playback we might want to enable SRAM to minimize power > > > consumption. > > > That's exactly the usecase. How could such a runtime configurability > > look like? sysfs? Or something based on the buffer sizes? > > Yeah, one of those :) but probably an ALSA control is going to be the > easiest for applications. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Tue, 2015-04-21 at 11:49 +0200, Sascha Hauer wrote: > On Mon, Apr 20, 2015 at 09:48:49PM +0100, Mark Brown wrote: > > On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote: > > > On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote: > > > > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote: > > > > > > > +Each external interface (called "IO" in this driver) is presented as > > > > > a > > > > > +DAI to ASoC. An IO must be connected via the interconnect to a memif. > > > > > +The connection paths are configured through the device tree. > > > > > > Why are these connection paths configured via device tree? I would > > > > expect that either there would be runtime configurability of these > > > > things (particularly if loopback configurations within the hardware are > > > > possible) or we'd just allocate memory interfaces to DAIs automatically > > > > as DAIs come into use. > > > > > There is a crossbar switch between the memory interfaces and the DAIs. > > > Not every connection is possible, so not every memory interface can be > > > used for every DAI. An algorithm choosing a suitable memory interface > > > must be quite clever, complicated and also SoC dependent (the same but > > > different hardware is used on MT8135 aswell), so I thought offering a > > > static configuration via device tree is a good start. Should there be > > > runtime configuration possible later the device tree settings could > > > provide a good default. > > > > What exactly do the restrictions look like and how often do they vary in > > practice (can we get away with just doing a single static setup in the > > driver)? I'd have thought it should be fairly straightforward to have a > > table of valid mappings and just pick the first free memory interface? > > I think this could be done. I checked the possible connections in the > crossbar switch and it seems all memory interfaces can be connected with > all relevant external interfaces. So indeed the memory interfaces could > be dynamically allocated instead of statically associated to an > external interface. There are two problems I see: Some memory interfaces > are limited in the rates they support, they can only do 8k/16k/32k (for > speech). How can we know such memory interface should be used? Also The 2 memif are "DAI" and "MOD_DAI", designed for speech cases, and they should be only connected to corresponding external interface "DAI/BT" and "modem", respectively. We don't need to put them into dynamic allocation. > there are two programmable hardware gain blocks which can be inserted to > the digital audio path using the crossbar switch. There must be some > mechanism to configure them into different places. Maybe in DPCM, they can be "widgets", and we can define "routes" and corresponding controls for them. > > Sascha > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Tue, 2015-04-21 at 11:49 +0200, Sascha Hauer wrote: On Mon, Apr 20, 2015 at 09:48:49PM +0100, Mark Brown wrote: On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote: On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote: On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote: +Each external interface (called IO in this driver) is presented as a +DAI to ASoC. An IO must be connected via the interconnect to a memif. +The connection paths are configured through the device tree. Why are these connection paths configured via device tree? I would expect that either there would be runtime configurability of these things (particularly if loopback configurations within the hardware are possible) or we'd just allocate memory interfaces to DAIs automatically as DAIs come into use. There is a crossbar switch between the memory interfaces and the DAIs. Not every connection is possible, so not every memory interface can be used for every DAI. An algorithm choosing a suitable memory interface must be quite clever, complicated and also SoC dependent (the same but different hardware is used on MT8135 aswell), so I thought offering a static configuration via device tree is a good start. Should there be runtime configuration possible later the device tree settings could provide a good default. What exactly do the restrictions look like and how often do they vary in practice (can we get away with just doing a single static setup in the driver)? I'd have thought it should be fairly straightforward to have a table of valid mappings and just pick the first free memory interface? I think this could be done. I checked the possible connections in the crossbar switch and it seems all memory interfaces can be connected with all relevant external interfaces. So indeed the memory interfaces could be dynamically allocated instead of statically associated to an external interface. There are two problems I see: Some memory interfaces are limited in the rates they support, they can only do 8k/16k/32k (for speech). How can we know such memory interface should be used? Also The 2 memif are DAI and MOD_DAI, designed for speech cases, and they should be only connected to corresponding external interface DAI/BT and modem, respectively. We don't need to put them into dynamic allocation. there are two programmable hardware gain blocks which can be inserted to the digital audio path using the crossbar switch. There must be some mechanism to configure them into different places. Maybe in DPCM, they can be widgets, and we can define routes and corresponding controls for them. Sascha -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 1/3] ASoC: mediatek: Add binding support for AFE driver
On Mon, 2015-04-20 at 21:48 +0100, Mark Brown wrote: On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote: On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote: On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote: +Each external interface (called IO in this driver) is presented as a +DAI to ASoC. An IO must be connected via the interconnect to a memif. +The connection paths are configured through the device tree. Why are these connection paths configured via device tree? I would expect that either there would be runtime configurability of these things (particularly if loopback configurations within the hardware are possible) or we'd just allocate memory interfaces to DAIs automatically as DAIs come into use. There is a crossbar switch between the memory interfaces and the DAIs. Not every connection is possible, so not every memory interface can be used for every DAI. An algorithm choosing a suitable memory interface must be quite clever, complicated and also SoC dependent (the same but different hardware is used on MT8135 aswell), so I thought offering a static configuration via device tree is a good start. Should there be runtime configuration possible later the device tree settings could provide a good default. What exactly do the restrictions look like and how often do they vary in practice (can we get away with just doing a single static setup in the driver)? I'd have thought it should be fairly straightforward to have a table of valid mappings and just pick the first free memory interface? I'd rather not get stuck with the tables in the DT. It's partly to avoid setting bad precendents, we really don't want everyone coming along hard coding this stuff, and partly because the hardware you described didn't seem that hard to handle. If using DPCM, it seems the most suitable FE DAIs will be memif, and external interface like I2S should be BE DAIs. Do you think it is suitable for our memif to be FE DAIs? Then which memif to used can be described in a machine driver's FE DAIs. But I think this has a problem that our memif is one-direction, playback or capture. So the binded pcm device cannot have playback and capture capability together. May it cause trouble for user space apps that assumes there will be pcmC0D0p, pcmC0D0c? +- mem-interface-playback: + mem-interface-capture: property of memif, format is: memif irq use_sram; +memif: which memif to be used + (defined in include/dt-bindings/sound/mtk-afe.h) +irq: which irq to be used + (defined in include/dt-bindings/sound/mtk-afe.h) +use_sram: 1 is yes, 0 is no Again, this looks like stuff we should be able to figure out at runtime - the use of SRAM in particular looks like something we might want to change depending on use case. Assuming it adds buffering then for a VoIP application we might not want to use SRAM to minimize latency but during music playback we might want to enable SRAM to minimize power consumption. That's exactly the usecase. How could such a runtime configurability look like? sysfs? Or something based on the buffer sizes? Yeah, one of those :) but probably an ALSA control is going to be the easiest for applications. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 3/3] ASoC: mediatek: Add AFE platform driver
On Mon, 2015-04-20 at 21:55 +0100, Mark Brown wrote: > On Mon, Apr 20, 2015 at 02:22:24PM +0800, Koro Chen wrote: > > On Sat, 2015-04-18 at 18:51 +0100, Mark Brown wrote: > > > On Fri, Apr 10, 2015 at 04:14:09PM +0800, Koro Chen wrote: > > > > Ah, so the SRAM is directly memory mappable. Nice. But we have a > > > limited amount of it so need to allocate it to a device somehow based on > > > some factor I guess? > > > Yes, actually SRAM is only used for the main playback path (which is > > memif "DL1") to achieve low power in real use case. Maybe you think it's > > better to not describe this in the device tree, but to choose SRAM > > automatically if memif "DL1" is chosen? > > Since it's directly memory mappable is there actually any cost in > latency terms from using the SRAM in low latency cases (or did I misread > what the code was doing there)? If it can only be used with one > interface and there's no downside from using it... The SRAM size to be used is defined by params_buffer_bytes(params), not fixed (of course limited by the actual available SRAM size on HW), so the latency should be the same compared to a DRAM having the same size. The SRAM can be used by any memif, and that's why the plan was let DT make the decision. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 3/3] ASoC: mediatek: Add AFE platform driver
On Sat, 2015-04-18 at 18:51 +0100, Mark Brown wrote: > On Fri, Apr 10, 2015 at 04:14:09PM +0800, Koro Chen wrote: > > > + if (memif->use_sram) { > > + struct snd_dma_buffer *dma_buf = >dma_buffer; > > + int size = params_buffer_bytes(params); > > + > > + memif->buffer_size = size; > > + memif->phys_buf_addr = afe->sram_phy_address; > > + > > + dma_buf->bytes = size; > > + dma_buf->area = (unsigned char *)afe->sram_address; > > + dma_buf->addr = afe->sram_phy_address; > > + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; > > + dma_buf->dev.dev = substream->pcm->card->dev; > > + snd_pcm_set_runtime_buffer(substream, dma_buf); > > + } else { > > + ret = snd_pcm_lib_malloc_pages(substream, > > + params_buffer_bytes(params)); > > + if (ret < 0) > > + return ret; > > + > > + memif->phys_buf_addr = substream->runtime->dma_addr; > > + memif->buffer_size = substream->runtime->dma_bytes; > > + } > > Ah, so the SRAM is directly memory mappable. Nice. But we have a > limited amount of it so need to allocate it to a device somehow based on > some factor I guess? Yes, actually SRAM is only used for the main playback path (which is memif "DL1") to achieve low power in real use case. Maybe you think it's better to not describe this in the device tree, but to choose SRAM automatically if memif "DL1" is chosen? > > > +static int mtk_afe_set_adda_dac_out(struct mtk_afe *afe, uint32_t rate) > > +{ > > + u32 audio_i2s_dac = 0; > > + u32 con0, con1; > > + > > + /* set dl src2 */ > > + con0 = (mtk_afe_adda_fs(rate) << 28) | (0x03 << 24) | (0x03 << 11); > > + > > + /* 8k or 16k voice mode */ > > + if (con0 == 0 || con0 == 3) > > + con0 |= 0x01 << 5; > > This all looks a bit magic, some defines would not go amiss here. > > > + /* SA suggests to apply -0.3db to audio/speech path */ > > + con0 = con0 | (0x01 << 1); > > + con1 = 0xf74f; > > More magic numbers! This also suggests that there is a volume control > lurking in here which could usefully be exposed to applications? > Sorry, I will fix these magic numbers. It is actually not a real volume control and not that suitable for application control because it cannot be changed in runtime; its value is fixed and was decided off-lined by experiment that can have best audio quality when using with our proprietary codec (not for I2S) > > +static void mtk_afe_pmic_shutdown(struct mtk_afe *afe, > > + struct snd_pcm_substream *substream) > > +{ > > + /* output */ > > + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 1, 0); > > + regmap_update_bits(afe->regmap, AFE_I2S_CON1, 1, 0); > > + > > + /* input */ > > + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 1, 0); > > + /* disable ADDA */ > > + regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0, 1, false); > > +} > > This is looking like exposing the routing and using DAPM might save a > bunch of code? Overall my main thought looking at the code here and > what the hardware was described as doing is that it'd all be simpler if > it were a DPCM based thing using DAPM for power. I think I'd like to > see a strong reason for not using at least DPCM. Thank you very much for mentioning the DPCM. I didn't know much about DPCM and I will definitely study and check if it is suitable for our HW. > > > + if (rate == MTK_AFE_I2S_RATE_8K) > > + voice_mode = 0; > > + else if (rate == MTK_AFE_I2S_RATE_16K) > > + voice_mode = 1; > > + else if (rate == MTK_AFE_I2S_RATE_32K) > > + voice_mode = 2; > > + else if (rate == MTK_AFE_I2S_RATE_48K) > > + voice_mode = 3; > > This should be a switch statement. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 3/3] ASoC: mediatek: Add AFE platform driver
On Mon, 2015-04-20 at 21:55 +0100, Mark Brown wrote: On Mon, Apr 20, 2015 at 02:22:24PM +0800, Koro Chen wrote: On Sat, 2015-04-18 at 18:51 +0100, Mark Brown wrote: On Fri, Apr 10, 2015 at 04:14:09PM +0800, Koro Chen wrote: Ah, so the SRAM is directly memory mappable. Nice. But we have a limited amount of it so need to allocate it to a device somehow based on some factor I guess? Yes, actually SRAM is only used for the main playback path (which is memif DL1) to achieve low power in real use case. Maybe you think it's better to not describe this in the device tree, but to choose SRAM automatically if memif DL1 is chosen? Since it's directly memory mappable is there actually any cost in latency terms from using the SRAM in low latency cases (or did I misread what the code was doing there)? If it can only be used with one interface and there's no downside from using it... The SRAM size to be used is defined by params_buffer_bytes(params), not fixed (of course limited by the actual available SRAM size on HW), so the latency should be the same compared to a DRAM having the same size. The SRAM can be used by any memif, and that's why the plan was let DT make the decision. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RESEND RFC PATCH 3/3] ASoC: mediatek: Add AFE platform driver
On Sat, 2015-04-18 at 18:51 +0100, Mark Brown wrote: On Fri, Apr 10, 2015 at 04:14:09PM +0800, Koro Chen wrote: + if (memif-use_sram) { + struct snd_dma_buffer *dma_buf = substream-dma_buffer; + int size = params_buffer_bytes(params); + + memif-buffer_size = size; + memif-phys_buf_addr = afe-sram_phy_address; + + dma_buf-bytes = size; + dma_buf-area = (unsigned char *)afe-sram_address; + dma_buf-addr = afe-sram_phy_address; + dma_buf-dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf-dev.dev = substream-pcm-card-dev; + snd_pcm_set_runtime_buffer(substream, dma_buf); + } else { + ret = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(params)); + if (ret 0) + return ret; + + memif-phys_buf_addr = substream-runtime-dma_addr; + memif-buffer_size = substream-runtime-dma_bytes; + } Ah, so the SRAM is directly memory mappable. Nice. But we have a limited amount of it so need to allocate it to a device somehow based on some factor I guess? Yes, actually SRAM is only used for the main playback path (which is memif DL1) to achieve low power in real use case. Maybe you think it's better to not describe this in the device tree, but to choose SRAM automatically if memif DL1 is chosen? +static int mtk_afe_set_adda_dac_out(struct mtk_afe *afe, uint32_t rate) +{ + u32 audio_i2s_dac = 0; + u32 con0, con1; + + /* set dl src2 */ + con0 = (mtk_afe_adda_fs(rate) 28) | (0x03 24) | (0x03 11); + + /* 8k or 16k voice mode */ + if (con0 == 0 || con0 == 3) + con0 |= 0x01 5; This all looks a bit magic, some defines would not go amiss here. + /* SA suggests to apply -0.3db to audio/speech path */ + con0 = con0 | (0x01 1); + con1 = 0xf74f; More magic numbers! This also suggests that there is a volume control lurking in here which could usefully be exposed to applications? Sorry, I will fix these magic numbers. It is actually not a real volume control and not that suitable for application control because it cannot be changed in runtime; its value is fixed and was decided off-lined by experiment that can have best audio quality when using with our proprietary codec (not for I2S) +static void mtk_afe_pmic_shutdown(struct mtk_afe *afe, + struct snd_pcm_substream *substream) +{ + /* output */ + regmap_update_bits(afe-regmap, AFE_ADDA_DL_SRC2_CON0, 1, 0); + regmap_update_bits(afe-regmap, AFE_I2S_CON1, 1, 0); + + /* input */ + regmap_update_bits(afe-regmap, AFE_ADDA_UL_SRC_CON0, 1, 0); + /* disable ADDA */ + regmap_update_bits(afe-regmap, AFE_ADDA_UL_DL_CON0, 1, false); +} This is looking like exposing the routing and using DAPM might save a bunch of code? Overall my main thought looking at the code here and what the hardware was described as doing is that it'd all be simpler if it were a DPCM based thing using DAPM for power. I think I'd like to see a strong reason for not using at least DPCM. Thank you very much for mentioning the DPCM. I didn't know much about DPCM and I will definitely study and check if it is suitable for our HW. + if (rate == MTK_AFE_I2S_RATE_8K) + voice_mode = 0; + else if (rate == MTK_AFE_I2S_RATE_16K) + voice_mode = 1; + else if (rate == MTK_AFE_I2S_RATE_32K) + voice_mode = 2; + else if (rate == MTK_AFE_I2S_RATE_48K) + voice_mode = 3; This should be a switch statement. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/