aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/rt5514-spi.c17
-rw-r--r--sound/soc/codecs/rt5514-spi.h3
-rw-r--r--sound/soc/codecs/rt5514.c63
-rw-r--r--sound/soc/codecs/rt5514.h3
-rw-r--r--sound/soc/codecs/rt5616.c2
-rw-r--r--sound/soc/codecs/rt5659.c4
-rw-r--r--sound/soc/codecs/rt5663.c3
-rw-r--r--sound/soc/samsung/i2s.c6
-rw-r--r--sound/soc/stm/stm32_sai.c2
-rw-r--r--sound/soc/stm/stm32_sai_sub.c33
10 files changed, 51 insertions, 85 deletions
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index ed6e5373916c..12f2ecf3a4fe 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -145,9 +145,8 @@ done:
145 mutex_unlock(&rt5514_dsp->dma_lock); 145 mutex_unlock(&rt5514_dsp->dma_lock);
146} 146}
147 147
148static irqreturn_t rt5514_spi_irq(int irq, void *data) 148static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
149{ 149{
150 struct rt5514_dsp *rt5514_dsp = data;
151 u8 buf[8]; 150 u8 buf[8];
152 151
153 rt5514_dsp->get_size = 0; 152 rt5514_dsp->get_size = 0;
@@ -180,6 +179,13 @@ static irqreturn_t rt5514_spi_irq(int irq, void *data)
180 if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && 179 if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
181 rt5514_dsp->buf_rp && rt5514_dsp->buf_size) 180 rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
182 schedule_delayed_work(&rt5514_dsp->copy_work, 0); 181 schedule_delayed_work(&rt5514_dsp->copy_work, 0);
182}
183
184static irqreturn_t rt5514_spi_irq(int irq, void *data)
185{
186 struct rt5514_dsp *rt5514_dsp = data;
187
188 rt5514_schedule_copy(rt5514_dsp);
183 189
184 return IRQ_HANDLED; 190 return IRQ_HANDLED;
185} 191}
@@ -199,12 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
199 struct rt5514_dsp *rt5514_dsp = 205 struct rt5514_dsp *rt5514_dsp =
200 snd_soc_platform_get_drvdata(rtd->platform); 206 snd_soc_platform_get_drvdata(rtd->platform);
201 int ret; 207 int ret;
208 u8 buf[8];
202 209
203 mutex_lock(&rt5514_dsp->dma_lock); 210 mutex_lock(&rt5514_dsp->dma_lock);
204 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, 211 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
205 params_buffer_bytes(hw_params)); 212 params_buffer_bytes(hw_params));
206 rt5514_dsp->substream = substream; 213 rt5514_dsp->substream = substream;
207 rt5514_dsp->dma_offset = 0; 214 rt5514_dsp->dma_offset = 0;
215
216 /* Read IRQ status and schedule copy accordingly. */
217 rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
218 if (buf[0] & RT5514_IRQ_STATUS_BIT)
219 rt5514_schedule_copy(rt5514_dsp);
220
208 mutex_unlock(&rt5514_dsp->dma_lock); 221 mutex_unlock(&rt5514_dsp->dma_lock);
209 222
210 return ret; 223 return ret;
diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h
index a6434ee6ff03..c1a36647c119 100644
--- a/sound/soc/codecs/rt5514-spi.h
+++ b/sound/soc/codecs/rt5514-spi.h
@@ -20,6 +20,9 @@
20#define RT5514_BUFFER_VOICE_BASE 0x18000200 20#define RT5514_BUFFER_VOICE_BASE 0x18000200
21#define RT5514_BUFFER_VOICE_LIMIT 0x18000204 21#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
22#define RT5514_BUFFER_VOICE_WP 0x1800020c 22#define RT5514_BUFFER_VOICE_WP 0x1800020c
23#define RT5514_IRQ_CTRL 0x18002094
24
25#define RT5514_IRQ_STATUS_BIT (0x1 << 5)
23 26
24/* SPI Command */ 27/* SPI Command */
25enum { 28enum {
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 0945d212b8dc..d7956ababd11 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -338,39 +338,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
338 fw = NULL; 338 fw = NULL;
339 } 339 }
340 340
341 if (rt5514->model_buf && rt5514->model_len) {
342#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
343 int ret;
344
345 ret = rt5514_spi_burst_write(0x4ff80000,
346 rt5514->model_buf,
347 ((rt5514->model_len / 8) + 1) * 8);
348 if (ret) {
349 dev_err(codec->dev,
350 "Model load failed %d\n", ret);
351 return ret;
352 }
353#else
354 dev_err(codec->dev,
355 "No SPI driver for loading firmware\n");
356#endif
357 } else {
358 request_firmware(&fw, RT5514_FIRMWARE3,
359 codec->dev);
360 if (fw) {
361#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
362 rt5514_spi_burst_write(0x4ff80000,
363 fw->data,
364 ((fw->size/8)+1)*8);
365#else
366 dev_err(codec->dev,
367 "No SPI driver to load fw\n");
368#endif
369 release_firmware(fw);
370 fw = NULL;
371 }
372 }
373
374 /* DSP run */ 341 /* DSP run */
375 regmap_write(rt5514->i2c_regmap, 0x18002f00, 342 regmap_write(rt5514->i2c_regmap, 0x18002f00,
376 0x00055148); 343 0x00055148);
@@ -385,34 +352,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
385 return 0; 352 return 0;
386} 353}
387 354
388static int rt5514_hotword_model_put(struct snd_kcontrol *kcontrol,
389 const unsigned int __user *bytes, unsigned int size)
390{
391 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
392 struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
393 struct snd_soc_codec *codec = rt5514->codec;
394 int ret = 0;
395
396 if (rt5514->model_buf || rt5514->model_len < size) {
397 if (rt5514->model_buf)
398 devm_kfree(codec->dev, rt5514->model_buf);
399 rt5514->model_buf = devm_kmalloc(codec->dev, size, GFP_KERNEL);
400 if (!rt5514->model_buf) {
401 ret = -ENOMEM;
402 goto done;
403 }
404 }
405
406 /* Skips the TLV header. */
407 bytes += 2;
408
409 if (copy_from_user(rt5514->model_buf, bytes, size))
410 ret = -EFAULT;
411done:
412 rt5514->model_len = (ret ? 0 : size);
413 return ret;
414}
415
416static const struct snd_kcontrol_new rt5514_snd_controls[] = { 355static const struct snd_kcontrol_new rt5514_snd_controls[] = {
417 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, 356 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
418 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), 357 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[] = {
424 adc_vol_tlv), 363 adc_vol_tlv),
425 SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, 364 SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
426 rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), 365 rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
427 SND_SOC_BYTES_TLV("Hotword Model", 0x8504,
428 NULL, rt5514_hotword_model_put),
429}; 366};
430 367
431/* ADC Mixer*/ 368/* ADC Mixer*/
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
index 803311cb7e2a..2dc40e6d8b3f 100644
--- a/sound/soc/codecs/rt5514.h
+++ b/sound/soc/codecs/rt5514.h
@@ -255,7 +255,6 @@
255 255
256#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin" 256#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
257#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin" 257#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
258#define RT5514_FIRMWARE3 "rt5514_dsp_fw3.bin"
259 258
260/* System Clock Source */ 259/* System Clock Source */
261enum { 260enum {
@@ -282,8 +281,6 @@ struct rt5514_priv {
282 int pll_in; 281 int pll_in;
283 int pll_out; 282 int pll_out;
284 int dsp_enabled; 283 int dsp_enabled;
285 u8 *model_buf;
286 unsigned int model_len;
287}; 284};
288 285
289#endif /* __RT5514_H__ */ 286#endif /* __RT5514_H__ */
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
index c94e94fe8297..0e5f54a9bc7e 100644
--- a/sound/soc/codecs/rt5616.c
+++ b/sound/soc/codecs/rt5616.c
@@ -98,7 +98,7 @@ static const struct reg_default rt5616_reg[] = {
98 { 0x8e, 0x0004 }, 98 { 0x8e, 0x0004 },
99 { 0x8f, 0x1100 }, 99 { 0x8f, 0x1100 },
100 { 0x90, 0x0000 }, 100 { 0x90, 0x0000 },
101 { 0x91, 0x0000 }, 101 { 0x91, 0x0c00 },
102 { 0x92, 0x0000 }, 102 { 0x92, 0x0000 },
103 { 0x93, 0x2000 }, 103 { 0x93, 0x2000 },
104 { 0x94, 0x0200 }, 104 { 0x94, 0x0200 },
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 71216db15eab..fa66b11df8d4 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -2744,7 +2744,8 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
2744 SND_SOC_DAPM_PRE_PMU), 2744 SND_SOC_DAPM_PRE_PMU),
2745 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event, 2745 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
2746 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 2746 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
2747 SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0), 2747 SND_SOC_DAPM_PGA_S("LOUT Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_LM_BIT,
2748 0, NULL, 0),
2748 2749
2749 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, 2750 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
2750 rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU | 2751 rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
@@ -3208,6 +3209,7 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
3208 { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" }, 3209 { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
3209 { "LOUT Amp", NULL, "LOUT L MIX" }, 3210 { "LOUT Amp", NULL, "LOUT L MIX" },
3210 { "LOUT Amp", NULL, "LOUT R MIX" }, 3211 { "LOUT Amp", NULL, "LOUT R MIX" },
3212 { "LOUT Amp", NULL, "Charge Pump" },
3211 { "LOUT Amp", NULL, "SYS CLK DET" }, 3213 { "LOUT Amp", NULL, "SYS CLK DET" },
3212 { "LOUT L Playback", "Switch", "LOUT Amp" }, 3214 { "LOUT L Playback", "Switch", "LOUT Amp" },
3213 { "LOUT R Playback", "Switch", "LOUT Amp" }, 3215 { "LOUT R Playback", "Switch", "LOUT Amp" },
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index ab9e0ebff5a7..e45b895d8279 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -1639,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
1639{ 1639{
1640 struct rt5663_priv *rt5663 = data; 1640 struct rt5663_priv *rt5663 = data;
1641 1641
1642 dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__); 1642 dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n",
1643 __func__);
1643 1644
1644 queue_delayed_work(system_wq, &rt5663->jack_detect_work, 1645 queue_delayed_work(system_wq, &rt5663->jack_detect_work,
1645 msecs_to_jiffies(250)); 1646 msecs_to_jiffies(250));
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 10a4da06c0a1..de783c6d2a70 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -552,8 +552,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
552 } 552 }
553 553
554 ret = clk_prepare_enable(i2s->op_clk); 554 ret = clk_prepare_enable(i2s->op_clk);
555 if (ret) 555 if (ret) {
556 clk_put(i2s->op_clk);
557 i2s->op_clk = NULL;
556 goto err; 558 goto err;
559 }
557 i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); 560 i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
558 561
559 /* Over-ride the other's */ 562 /* Over-ride the other's */
@@ -1285,6 +1288,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1285 } 1288 }
1286 } 1289 }
1287 } 1290 }
1291 quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
1288 1292
1289 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1293 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1290 pri_dai->addr = devm_ioremap_resource(&pdev->dev, res); 1294 pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index 1258bef4dcb3..5fe878ace605 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev)
85 } 85 }
86 86
87 /* reset */ 87 /* reset */
88 rst = reset_control_get_exclusive(&pdev->dev, NULL); 88 rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
89 if (!IS_ERR(rst)) { 89 if (!IS_ERR(rst)) {
90 reset_control_assert(rst); 90 reset_control_assert(rst);
91 udelay(2); 91 udelay(2);
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 90d439613899..dde8ddf9e777 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -184,7 +184,6 @@ static const struct regmap_config stm32_sai_sub_regmap_config_h7 = {
184static irqreturn_t stm32_sai_isr(int irq, void *devid) 184static irqreturn_t stm32_sai_isr(int irq, void *devid)
185{ 185{
186 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid; 186 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
187 struct snd_pcm_substream *substream = sai->substream;
188 struct platform_device *pdev = sai->pdev; 187 struct platform_device *pdev = sai->pdev;
189 unsigned int sr, imr, flags; 188 unsigned int sr, imr, flags;
190 snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING; 189 snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
@@ -199,6 +198,11 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
199 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, 198 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
200 SAI_XCLRFR_MASK); 199 SAI_XCLRFR_MASK);
201 200
201 if (!sai->substream) {
202 dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
203 return IRQ_NONE;
204 }
205
202 if (flags & SAI_XIMR_OVRUDRIE) { 206 if (flags & SAI_XIMR_OVRUDRIE) {
203 dev_err(&pdev->dev, "IRQ %s\n", 207 dev_err(&pdev->dev, "IRQ %s\n",
204 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun"); 208 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
@@ -227,9 +231,9 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
227 } 231 }
228 232
229 if (status != SNDRV_PCM_STATE_RUNNING) { 233 if (status != SNDRV_PCM_STATE_RUNNING) {
230 snd_pcm_stream_lock(substream); 234 snd_pcm_stream_lock(sai->substream);
231 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 235 snd_pcm_stop(sai->substream, SNDRV_PCM_STATE_XRUN);
232 snd_pcm_stream_unlock(substream); 236 snd_pcm_stream_unlock(sai->substream);
233 } 237 }
234 238
235 return IRQ_HANDLED; 239 return IRQ_HANDLED;
@@ -442,12 +446,16 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
442{ 446{
443 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); 447 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
444 int cr1, cr1_mask, ret; 448 int cr1, cr1_mask, ret;
445 int fth = STM_SAI_FIFO_TH_HALF;
446 449
447 /* FIFO config */ 450 /*
451 * DMA bursts increment is set to 4 words.
452 * SAI fifo threshold is set to half fifo, to keep enough space
453 * for DMA incoming bursts.
454 */
448 regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX, 455 regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
449 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK, 456 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
450 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth)); 457 SAI_XCR2_FFLUSH |
458 SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
451 459
452 /* Mode, data format and channel config */ 460 /* Mode, data format and channel config */
453 cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL); 461 cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
@@ -481,10 +489,6 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
481 return ret; 489 return ret;
482 } 490 }
483 491
484 /* DMA config */
485 sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
486 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
487
488 return 0; 492 return 0;
489} 493}
490 494
@@ -727,7 +731,12 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
727 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); 731 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
728 732
729 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX); 733 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
730 sai->dma_params.maxburst = 1; 734 /*
735 * DMA supports 4, 8 or 16 burst sizes. Burst size 4 is the best choice,
736 * as it allows bytes, half-word and words transfers. (See DMA fifos
737 * constraints).
738 */
739 sai->dma_params.maxburst = 4;
731 /* Buswidth will be set by framework at runtime */ 740 /* Buswidth will be set by framework at runtime */
732 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED; 741 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
733 742