mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
Merge remote-tracking branches 'asoc/fix/rt5514', 'asoc/fix/rt5616', 'asoc/fix/rt5659', 'asoc/fix/rt5663', 'asoc/fix/samsung' and 'asoc/fix/stm32' into asoc-linus
This commit is contained in:
commit
b64395f189
@ -145,9 +145,8 @@ done:
|
|||||||
mutex_unlock(&rt5514_dsp->dma_lock);
|
mutex_unlock(&rt5514_dsp->dma_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t rt5514_spi_irq(int irq, void *data)
|
static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
|
||||||
{
|
{
|
||||||
struct rt5514_dsp *rt5514_dsp = data;
|
|
||||||
u8 buf[8];
|
u8 buf[8];
|
||||||
|
|
||||||
rt5514_dsp->get_size = 0;
|
rt5514_dsp->get_size = 0;
|
||||||
@ -180,6 +179,13 @@ static irqreturn_t rt5514_spi_irq(int irq, void *data)
|
|||||||
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
|
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
|
||||||
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
|
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
|
||||||
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
|
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t rt5514_spi_irq(int irq, void *data)
|
||||||
|
{
|
||||||
|
struct rt5514_dsp *rt5514_dsp = data;
|
||||||
|
|
||||||
|
rt5514_schedule_copy(rt5514_dsp);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -199,12 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
|
|||||||
struct rt5514_dsp *rt5514_dsp =
|
struct rt5514_dsp *rt5514_dsp =
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
int ret;
|
int ret;
|
||||||
|
u8 buf[8];
|
||||||
|
|
||||||
mutex_lock(&rt5514_dsp->dma_lock);
|
mutex_lock(&rt5514_dsp->dma_lock);
|
||||||
ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
|
ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
|
||||||
params_buffer_bytes(hw_params));
|
params_buffer_bytes(hw_params));
|
||||||
rt5514_dsp->substream = substream;
|
rt5514_dsp->substream = substream;
|
||||||
rt5514_dsp->dma_offset = 0;
|
rt5514_dsp->dma_offset = 0;
|
||||||
|
|
||||||
|
/* Read IRQ status and schedule copy accordingly. */
|
||||||
|
rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
|
||||||
|
if (buf[0] & RT5514_IRQ_STATUS_BIT)
|
||||||
|
rt5514_schedule_copy(rt5514_dsp);
|
||||||
|
|
||||||
mutex_unlock(&rt5514_dsp->dma_lock);
|
mutex_unlock(&rt5514_dsp->dma_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#define RT5514_BUFFER_VOICE_BASE 0x18000200
|
#define RT5514_BUFFER_VOICE_BASE 0x18000200
|
||||||
#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
|
#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
|
||||||
#define RT5514_BUFFER_VOICE_WP 0x1800020c
|
#define RT5514_BUFFER_VOICE_WP 0x1800020c
|
||||||
|
#define RT5514_IRQ_CTRL 0x18002094
|
||||||
|
|
||||||
|
#define RT5514_IRQ_STATUS_BIT (0x1 << 5)
|
||||||
|
|
||||||
/* SPI Command */
|
/* SPI Command */
|
||||||
enum {
|
enum {
|
||||||
|
@ -338,39 +338,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
|
|||||||
fw = NULL;
|
fw = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt5514->model_buf && rt5514->model_len) {
|
|
||||||
#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = rt5514_spi_burst_write(0x4ff80000,
|
|
||||||
rt5514->model_buf,
|
|
||||||
((rt5514->model_len / 8) + 1) * 8);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(codec->dev,
|
|
||||||
"Model load failed %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
dev_err(codec->dev,
|
|
||||||
"No SPI driver for loading firmware\n");
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
request_firmware(&fw, RT5514_FIRMWARE3,
|
|
||||||
codec->dev);
|
|
||||||
if (fw) {
|
|
||||||
#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
|
|
||||||
rt5514_spi_burst_write(0x4ff80000,
|
|
||||||
fw->data,
|
|
||||||
((fw->size/8)+1)*8);
|
|
||||||
#else
|
|
||||||
dev_err(codec->dev,
|
|
||||||
"No SPI driver to load fw\n");
|
|
||||||
#endif
|
|
||||||
release_firmware(fw);
|
|
||||||
fw = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DSP run */
|
/* DSP run */
|
||||||
regmap_write(rt5514->i2c_regmap, 0x18002f00,
|
regmap_write(rt5514->i2c_regmap, 0x18002f00,
|
||||||
0x00055148);
|
0x00055148);
|
||||||
@ -385,34 +352,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt5514_hotword_model_put(struct snd_kcontrol *kcontrol,
|
|
||||||
const unsigned int __user *bytes, unsigned int size)
|
|
||||||
{
|
|
||||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
|
|
||||||
struct snd_soc_codec *codec = rt5514->codec;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (rt5514->model_buf || rt5514->model_len < size) {
|
|
||||||
if (rt5514->model_buf)
|
|
||||||
devm_kfree(codec->dev, rt5514->model_buf);
|
|
||||||
rt5514->model_buf = devm_kmalloc(codec->dev, size, GFP_KERNEL);
|
|
||||||
if (!rt5514->model_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skips the TLV header. */
|
|
||||||
bytes += 2;
|
|
||||||
|
|
||||||
if (copy_from_user(rt5514->model_buf, bytes, size))
|
|
||||||
ret = -EFAULT;
|
|
||||||
done:
|
|
||||||
rt5514->model_len = (ret ? 0 : size);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct snd_kcontrol_new rt5514_snd_controls[] = {
|
static const struct snd_kcontrol_new rt5514_snd_controls[] = {
|
||||||
SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
|
SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
|
||||||
RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
|
RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
|
||||||
@ -424,8 +363,6 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
|
|||||||
adc_vol_tlv),
|
adc_vol_tlv),
|
||||||
SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
|
SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
|
||||||
rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
|
rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
|
||||||
SND_SOC_BYTES_TLV("Hotword Model", 0x8504,
|
|
||||||
NULL, rt5514_hotword_model_put),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ADC Mixer*/
|
/* ADC Mixer*/
|
||||||
|
@ -255,7 +255,6 @@
|
|||||||
|
|
||||||
#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
|
#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
|
||||||
#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
|
#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
|
||||||
#define RT5514_FIRMWARE3 "rt5514_dsp_fw3.bin"
|
|
||||||
|
|
||||||
/* System Clock Source */
|
/* System Clock Source */
|
||||||
enum {
|
enum {
|
||||||
@ -282,8 +281,6 @@ struct rt5514_priv {
|
|||||||
int pll_in;
|
int pll_in;
|
||||||
int pll_out;
|
int pll_out;
|
||||||
int dsp_enabled;
|
int dsp_enabled;
|
||||||
u8 *model_buf;
|
|
||||||
unsigned int model_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __RT5514_H__ */
|
#endif /* __RT5514_H__ */
|
||||||
|
@ -98,7 +98,7 @@ static const struct reg_default rt5616_reg[] = {
|
|||||||
{ 0x8e, 0x0004 },
|
{ 0x8e, 0x0004 },
|
||||||
{ 0x8f, 0x1100 },
|
{ 0x8f, 0x1100 },
|
||||||
{ 0x90, 0x0000 },
|
{ 0x90, 0x0000 },
|
||||||
{ 0x91, 0x0000 },
|
{ 0x91, 0x0c00 },
|
||||||
{ 0x92, 0x0000 },
|
{ 0x92, 0x0000 },
|
||||||
{ 0x93, 0x2000 },
|
{ 0x93, 0x2000 },
|
||||||
{ 0x94, 0x0200 },
|
{ 0x94, 0x0200 },
|
||||||
|
@ -2744,7 +2744,8 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_PRE_PMU),
|
SND_SOC_DAPM_PRE_PMU),
|
||||||
SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
|
SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
|
||||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||||
SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
|
SND_SOC_DAPM_PGA_S("LOUT Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_LM_BIT,
|
||||||
|
0, NULL, 0),
|
||||||
|
|
||||||
SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
|
||||||
rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
|
rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
|
||||||
@ -3208,6 +3209,7 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
|
|||||||
{ "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
|
{ "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
|
||||||
{ "LOUT Amp", NULL, "LOUT L MIX" },
|
{ "LOUT Amp", NULL, "LOUT L MIX" },
|
||||||
{ "LOUT Amp", NULL, "LOUT R MIX" },
|
{ "LOUT Amp", NULL, "LOUT R MIX" },
|
||||||
|
{ "LOUT Amp", NULL, "Charge Pump" },
|
||||||
{ "LOUT Amp", NULL, "SYS CLK DET" },
|
{ "LOUT Amp", NULL, "SYS CLK DET" },
|
||||||
{ "LOUT L Playback", "Switch", "LOUT Amp" },
|
{ "LOUT L Playback", "Switch", "LOUT Amp" },
|
||||||
{ "LOUT R Playback", "Switch", "LOUT Amp" },
|
{ "LOUT R Playback", "Switch", "LOUT Amp" },
|
||||||
|
@ -1639,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
|
|||||||
{
|
{
|
||||||
struct rt5663_priv *rt5663 = data;
|
struct rt5663_priv *rt5663 = data;
|
||||||
|
|
||||||
dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__);
|
dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n",
|
||||||
|
__func__);
|
||||||
|
|
||||||
queue_delayed_work(system_wq, &rt5663->jack_detect_work,
|
queue_delayed_work(system_wq, &rt5663->jack_detect_work,
|
||||||
msecs_to_jiffies(250));
|
msecs_to_jiffies(250));
|
||||||
|
@ -552,8 +552,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(i2s->op_clk);
|
ret = clk_prepare_enable(i2s->op_clk);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
clk_put(i2s->op_clk);
|
||||||
|
i2s->op_clk = NULL;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
|
i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
|
||||||
|
|
||||||
/* Over-ride the other's */
|
/* Over-ride the other's */
|
||||||
@ -1285,6 +1288,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
|
pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* reset */
|
/* reset */
|
||||||
rst = reset_control_get_exclusive(&pdev->dev, NULL);
|
rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||||
if (!IS_ERR(rst)) {
|
if (!IS_ERR(rst)) {
|
||||||
reset_control_assert(rst);
|
reset_control_assert(rst);
|
||||||
udelay(2);
|
udelay(2);
|
||||||
|
@ -184,7 +184,6 @@ static const struct regmap_config stm32_sai_sub_regmap_config_h7 = {
|
|||||||
static irqreturn_t stm32_sai_isr(int irq, void *devid)
|
static irqreturn_t stm32_sai_isr(int irq, void *devid)
|
||||||
{
|
{
|
||||||
struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
|
struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
|
||||||
struct snd_pcm_substream *substream = sai->substream;
|
|
||||||
struct platform_device *pdev = sai->pdev;
|
struct platform_device *pdev = sai->pdev;
|
||||||
unsigned int sr, imr, flags;
|
unsigned int sr, imr, flags;
|
||||||
snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
|
snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
|
||||||
@ -199,6 +198,11 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
|
|||||||
regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
|
regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
|
||||||
SAI_XCLRFR_MASK);
|
SAI_XCLRFR_MASK);
|
||||||
|
|
||||||
|
if (!sai->substream) {
|
||||||
|
dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & SAI_XIMR_OVRUDRIE) {
|
if (flags & SAI_XIMR_OVRUDRIE) {
|
||||||
dev_err(&pdev->dev, "IRQ %s\n",
|
dev_err(&pdev->dev, "IRQ %s\n",
|
||||||
STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
|
STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
|
||||||
@ -227,9 +231,9 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status != SNDRV_PCM_STATE_RUNNING) {
|
if (status != SNDRV_PCM_STATE_RUNNING) {
|
||||||
snd_pcm_stream_lock(substream);
|
snd_pcm_stream_lock(sai->substream);
|
||||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
snd_pcm_stop(sai->substream, SNDRV_PCM_STATE_XRUN);
|
||||||
snd_pcm_stream_unlock(substream);
|
snd_pcm_stream_unlock(sai->substream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
@ -442,12 +446,16 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
|
|||||||
{
|
{
|
||||||
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||||
int cr1, cr1_mask, ret;
|
int cr1, cr1_mask, ret;
|
||||||
int fth = STM_SAI_FIFO_TH_HALF;
|
|
||||||
|
|
||||||
/* FIFO config */
|
/*
|
||||||
|
* DMA bursts increment is set to 4 words.
|
||||||
|
* SAI fifo threshold is set to half fifo, to keep enough space
|
||||||
|
* for DMA incoming bursts.
|
||||||
|
*/
|
||||||
regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
|
regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
|
||||||
SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
|
SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
|
||||||
SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));
|
SAI_XCR2_FFLUSH |
|
||||||
|
SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
|
||||||
|
|
||||||
/* Mode, data format and channel config */
|
/* Mode, data format and channel config */
|
||||||
cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
|
cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
|
||||||
@ -481,10 +489,6 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DMA config */
|
|
||||||
sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
|
|
||||||
snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +731,12 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
|||||||
struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
|
struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
|
||||||
|
|
||||||
sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
|
sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
|
||||||
sai->dma_params.maxburst = 1;
|
/*
|
||||||
|
* DMA supports 4, 8 or 16 burst sizes. Burst size 4 is the best choice,
|
||||||
|
* as it allows bytes, half-word and words transfers. (See DMA fifos
|
||||||
|
* constraints).
|
||||||
|
*/
|
||||||
|
sai->dma_params.maxburst = 4;
|
||||||
/* Buswidth will be set by framework at runtime */
|
/* Buswidth will be set by framework at runtime */
|
||||||
sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user