diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h index 086cd7ff6ddc..5b68e3f5aa85 100644 --- a/include/sound/soc-topology.h +++ b/include/sound/soc-topology.h @@ -92,8 +92,10 @@ struct snd_soc_tplg_kcontrol_ops { /* Bytes ext operations, for TLV byte controls */ struct snd_soc_tplg_bytes_ext_ops { u32 id; - int (*get)(unsigned int __user *bytes, unsigned int size); - int (*put)(const unsigned int __user *bytes, unsigned int size); + int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes, + unsigned int size); + int (*put)(struct snd_kcontrol *kcontrol, + const unsigned int __user *bytes, unsigned int size); }; /* diff --git a/include/sound/soc.h b/include/sound/soc.h index ea443239cc6d..a2deeb954c21 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1250,8 +1250,10 @@ struct soc_bytes_ext { struct snd_soc_dobj dobj; /* used for TLV byte control */ - int (*get)(unsigned int __user *bytes, unsigned int size); - int (*put)(const unsigned int __user *bytes, unsigned int size); + int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes, + unsigned int size); + int (*put)(struct snd_kcontrol *kcontrol, const unsigned int __user *bytes, + unsigned int size); }; /* multi register control */ diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index f5e3dce2633a..5b1dfb1518fb 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -12,6 +12,7 @@ * max98357a.c -- MAX98357A ALSA SoC Codec driver */ +#include #include #include #include @@ -123,10 +124,19 @@ static const struct of_device_id max98357a_device_id[] = { MODULE_DEVICE_TABLE(of, max98357a_device_id); #endif +#ifdef CONFIG_ACPI +static const struct acpi_device_id max98357a_acpi_match[] = { + { "MX98357A", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, max98357a_acpi_match); +#endif + static struct platform_driver max98357a_platform_driver = { .driver = { .name = "max98357a", .of_match_table = of_match_ptr(max98357a_device_id), + .acpi_match_table = ACPI_PTR(max98357a_acpi_match), }, .probe = max98357a_platform_probe, .remove = max98357a_platform_remove, diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h index cc4393cb1130..9b1af1a70874 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 f5baf3c38863..08af9f5dc4ab 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 = &afe->memif[rtd->cpu_dai->id]; + unsigned int hw_ptr; + int ret; - return bytes_to_frames(substream->runtime, memif->hw_ptr); + ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, &hw_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, + hw_ptr - memif->phys_buf_addr); } static const struct snd_pcm_ops mtk_afe_pcm_ops = { @@ -299,8 +308,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 +347,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 +363,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,10 +378,10 @@ 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 */ - regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); } static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, @@ -425,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, @@ -603,7 +605,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, @@ -672,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) { @@ -738,7 +728,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; @@ -751,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, }; @@ -1082,7 +1070,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); @@ -1098,13 +1086,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, - &hw_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); } @@ -1119,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); @@ -1165,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: diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 2f67ba6d7a8f..a513a34a51d2 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -779,11 +779,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, switch (op_flag) { case SNDRV_CTL_TLV_OP_READ: if (params->get) - ret = params->get(tlv, count); + ret = params->get(kcontrol, tlv, count); break; case SNDRV_CTL_TLV_OP_WRITE: if (params->put) - ret = params->put(tlv, count); + ret = params->put(kcontrol, tlv, count); break; } return ret;