Merge remote-tracking branches 'asoc/topic/kcontrol', 'asoc/topic/max98357a' and 'asoc/topic/mtk' into asoc-next
This commit is contained in:
Коммит
9451a46928
|
@ -92,8 +92,10 @@ struct snd_soc_tplg_kcontrol_ops {
|
||||||
/* Bytes ext operations, for TLV byte controls */
|
/* Bytes ext operations, for TLV byte controls */
|
||||||
struct snd_soc_tplg_bytes_ext_ops {
|
struct snd_soc_tplg_bytes_ext_ops {
|
||||||
u32 id;
|
u32 id;
|
||||||
int (*get)(unsigned int __user *bytes, unsigned int size);
|
int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes,
|
||||||
int (*put)(const unsigned int __user *bytes, unsigned int size);
|
unsigned int size);
|
||||||
|
int (*put)(struct snd_kcontrol *kcontrol,
|
||||||
|
const unsigned int __user *bytes, unsigned int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1250,8 +1250,10 @@ struct soc_bytes_ext {
|
||||||
struct snd_soc_dobj dobj;
|
struct snd_soc_dobj dobj;
|
||||||
|
|
||||||
/* used for TLV byte control */
|
/* used for TLV byte control */
|
||||||
int (*get)(unsigned int __user *bytes, unsigned int size);
|
int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes,
|
||||||
int (*put)(const unsigned int __user *bytes, unsigned int size);
|
unsigned int size);
|
||||||
|
int (*put)(struct snd_kcontrol *kcontrol, const unsigned int __user *bytes,
|
||||||
|
unsigned int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* multi register control */
|
/* multi register control */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
* max98357a.c -- MAX98357A ALSA SoC Codec driver
|
* max98357a.c -- MAX98357A ALSA SoC Codec driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
@ -123,10 +124,19 @@ static const struct of_device_id max98357a_device_id[] = {
|
||||||
MODULE_DEVICE_TABLE(of, max98357a_device_id);
|
MODULE_DEVICE_TABLE(of, max98357a_device_id);
|
||||||
#endif
|
#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 = {
|
static struct platform_driver max98357a_platform_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "max98357a",
|
.name = "max98357a",
|
||||||
.of_match_table = of_match_ptr(max98357a_device_id),
|
.of_match_table = of_match_ptr(max98357a_device_id),
|
||||||
|
.acpi_match_table = ACPI_PTR(max98357a_acpi_match),
|
||||||
},
|
},
|
||||||
.probe = max98357a_platform_probe,
|
.probe = max98357a_platform_probe,
|
||||||
.remove = max98357a_platform_remove,
|
.remove = max98357a_platform_remove,
|
||||||
|
|
|
@ -92,7 +92,6 @@ struct mtk_afe_memif_data {
|
||||||
struct mtk_afe_memif {
|
struct mtk_afe_memif {
|
||||||
unsigned int phys_buf_addr;
|
unsigned int phys_buf_addr;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
unsigned int hw_ptr; /* Previous IRQ's HW ptr */
|
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
const struct mtk_afe_memif_data *data;
|
const struct mtk_afe_memif_data *data;
|
||||||
const struct mtk_afe_irq_data *irqdata;
|
const struct mtk_afe_irq_data *irqdata;
|
||||||
|
|
|
@ -175,8 +175,17 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
|
struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
|
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 = {
|
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");
|
dev_err(afe->dev, "Failed to enable m_ck\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
|
|
||||||
AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_ck) {
|
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,
|
static void mtk_afe_dais_disable_clks(struct mtk_afe *afe,
|
||||||
struct clk *m_ck, struct clk *b_ck)
|
struct clk *m_ck, struct clk *b_ck)
|
||||||
{
|
{
|
||||||
if (m_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);
|
|
||||||
clk_disable_unprepare(m_ck);
|
clk_disable_unprepare(m_ck);
|
||||||
}
|
|
||||||
if (b_ck)
|
if (b_ck)
|
||||||
clk_disable_unprepare(b_ck);
|
clk_disable_unprepare(b_ck);
|
||||||
}
|
}
|
||||||
|
@ -360,6 +363,8 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,10 +378,10 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mtk_afe_set_i2s_enable(afe, false);
|
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);
|
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,
|
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],
|
mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M],
|
||||||
afe->clocks[MTK_CLK_I2S3_B]);
|
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,
|
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->phys_buf_addr = substream->runtime->dma_addr;
|
||||||
memif->buffer_size = substream->runtime->dma_bytes;
|
memif->buffer_size = substream->runtime->dma_bytes;
|
||||||
memif->hw_ptr = 0;
|
|
||||||
|
|
||||||
/* start */
|
/* start */
|
||||||
regmap_write(afe->regmap,
|
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);
|
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,
|
static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
struct snd_soc_dai *dai)
|
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 */
|
/* and clear pending IRQ */
|
||||||
regmap_write(afe->regmap, AFE_IRQ_CLR,
|
regmap_write(afe->regmap, AFE_IRQ_CLR,
|
||||||
1 << memif->data->irq_clr_shift);
|
1 << memif->data->irq_clr_shift);
|
||||||
memif->hw_ptr = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -751,7 +740,6 @@ static const struct snd_soc_dai_ops mtk_afe_dai_ops = {
|
||||||
.shutdown = mtk_afe_dais_shutdown,
|
.shutdown = mtk_afe_dais_shutdown,
|
||||||
.hw_params = mtk_afe_dais_hw_params,
|
.hw_params = mtk_afe_dais_hw_params,
|
||||||
.hw_free = mtk_afe_dais_hw_free,
|
.hw_free = mtk_afe_dais_hw_free,
|
||||||
.prepare = mtk_afe_dais_prepare,
|
|
||||||
.trigger = mtk_afe_dais_trigger,
|
.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)
|
static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct mtk_afe *afe = dev_id;
|
struct mtk_afe *afe = dev_id;
|
||||||
unsigned int reg_value, hw_ptr;
|
unsigned int reg_value;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, ®_value);
|
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)))
|
if (!(reg_value & (1 << memif->data->irq_clr_shift)))
|
||||||
continue;
|
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);
|
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);
|
struct mtk_afe *afe = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
/* disable AFE */
|
||||||
|
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
|
||||||
|
|
||||||
/* disable AFE clk */
|
/* disable AFE clk */
|
||||||
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
|
regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
|
||||||
AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
|
AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
|
||||||
|
@ -1165,6 +1149,9 @@ static int mtk_afe_runtime_resume(struct device *dev)
|
||||||
|
|
||||||
/* unmask all IRQs */
|
/* unmask all IRQs */
|
||||||
regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff);
|
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;
|
return 0;
|
||||||
|
|
||||||
err_bck0:
|
err_bck0:
|
||||||
|
|
|
@ -779,11 +779,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
|
||||||
switch (op_flag) {
|
switch (op_flag) {
|
||||||
case SNDRV_CTL_TLV_OP_READ:
|
case SNDRV_CTL_TLV_OP_READ:
|
||||||
if (params->get)
|
if (params->get)
|
||||||
ret = params->get(tlv, count);
|
ret = params->get(kcontrol, tlv, count);
|
||||||
break;
|
break;
|
||||||
case SNDRV_CTL_TLV_OP_WRITE:
|
case SNDRV_CTL_TLV_OP_WRITE:
|
||||||
if (params->put)
|
if (params->put)
|
||||||
ret = params->put(tlv, count);
|
ret = params->put(kcontrol, tlv, count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче