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:
Mark Brown 2017-10-26 09:45:46 +02:00
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
10 changed files with 51 additions and 85 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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*/

View File

@ -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__ */

View File

@ -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 },

View File

@ -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" },

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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;