summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-06-22 05:32:41 -0400
committerTakashi Iwai <tiwai@suse.de>2015-06-22 05:32:41 -0400
commit57fa8a1e22c5833fb2cae96af68fc39ec21cb017 (patch)
treeb0bb4e4a6e04a24119da30253add9fe9ffbc8d22 /sound
parentf267f9dff8ba00a8b11f340da3634858ad50ebab (diff)
parentc99d49a8f81fb35e67b0ffa45f320a75e0b5639d (diff)
Merge tag 'asoc-v4.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Further updates for v4.2 There's a bunch of additional updates and fixes that came in since my orignal pull request here, including DT support for rt5645 and fairly large serieses of cleanups and improvements to tas2552 and rcar.
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/Kconfig25
-rw-r--r--sound/soc/atmel/Makefile8
-rw-r--r--sound/soc/codecs/Kconfig5
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/max98090.c4
-rw-r--r--sound/soc/codecs/ml26124.c58
-rw-r--r--sound/soc/codecs/rl6347a.c128
-rw-r--r--sound/soc/codecs/rl6347a.h32
-rw-r--r--sound/soc/codecs/rt286.c97
-rw-r--r--sound/soc/codecs/rt5640.c5
-rw-r--r--sound/soc/codecs/rt5645.c111
-rw-r--r--sound/soc/codecs/rt5645.h1
-rw-r--r--sound/soc/codecs/rt5670.c5
-rw-r--r--sound/soc/codecs/tas2552.c182
-rw-r--r--sound/soc/codecs/tas2552.h61
-rw-r--r--sound/soc/codecs/wm5102.c6
-rw-r--r--sound/soc/codecs/wm5110.c14
-rw-r--r--sound/soc/codecs/wm8523.c26
-rw-r--r--sound/soc/codecs/wm8741.c61
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8995.c2
-rw-r--r--sound/soc/codecs/wm_adsp.c246
-rw-r--r--sound/soc/codecs/wm_adsp.h14
-rw-r--r--sound/soc/davinci/davinci-mcasp.c72
-rw-r--r--sound/soc/davinci/davinci-mcasp.h5
-rw-r--r--sound/soc/fsl/imx-wm8962.c2
-rw-r--r--sound/soc/generic/simple-card.c18
-rw-r--r--sound/soc/intel/Kconfig4
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c20
-rw-r--r--sound/soc/intel/atom/sst/sst.c4
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c30
-rw-r--r--sound/soc/intel/common/sst-acpi.c2
-rw-r--r--sound/soc/mediatek/Kconfig30
-rw-r--r--sound/soc/mediatek/Makefile5
-rw-r--r--sound/soc/mediatek/mt8173-max98090.c213
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5676.c278
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h109
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c1233
-rw-r--r--sound/soc/omap/rx51.c10
-rw-r--r--sound/soc/qcom/Kconfig9
-rw-r--r--sound/soc/qcom/Makefile2
-rw-r--r--sound/soc/qcom/apq8016_sbc.c198
-rw-r--r--sound/soc/qcom/storm.c26
-rw-r--r--sound/soc/sh/rcar/core.c111
-rw-r--r--sound/soc/sh/rcar/dma.c113
-rw-r--r--sound/soc/sh/rcar/dvc.c30
-rw-r--r--sound/soc/sh/rcar/rsnd.h112
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c438
-rw-r--r--sound/soc/sh/rcar/src.c121
-rw-r--r--sound/soc/sh/rcar/ssi.c96
53 files changed, 3501 insertions, 889 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index e2828e101433..2ae9619443d1 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -45,6 +45,7 @@ source "sound/soc/nuc900/Kconfig"
45source "sound/soc/omap/Kconfig" 45source "sound/soc/omap/Kconfig"
46source "sound/soc/kirkwood/Kconfig" 46source "sound/soc/kirkwood/Kconfig"
47source "sound/soc/intel/Kconfig" 47source "sound/soc/intel/Kconfig"
48source "sound/soc/mediatek/Kconfig"
48source "sound/soc/mxs/Kconfig" 49source "sound/soc/mxs/Kconfig"
49source "sound/soc/pxa/Kconfig" 50source "sound/soc/pxa/Kconfig"
50source "sound/soc/qcom/Kconfig" 51source "sound/soc/qcom/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index a0e1ee6b507d..e189903fabf4 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_SND_SOC) += dwc/
24obj-$(CONFIG_SND_SOC) += fsl/ 24obj-$(CONFIG_SND_SOC) += fsl/
25obj-$(CONFIG_SND_SOC) += jz4740/ 25obj-$(CONFIG_SND_SOC) += jz4740/
26obj-$(CONFIG_SND_SOC) += intel/ 26obj-$(CONFIG_SND_SOC) += intel/
27obj-$(CONFIG_SND_SOC) += mediatek/
27obj-$(CONFIG_SND_SOC) += mxs/ 28obj-$(CONFIG_SND_SOC) += mxs/
28obj-$(CONFIG_SND_SOC) += nuc900/ 29obj-$(CONFIG_SND_SOC) += nuc900/
29obj-$(CONFIG_SND_SOC) += omap/ 30obj-$(CONFIG_SND_SOC) += omap/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index c3152072d682..1489cd461aec 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -9,21 +9,32 @@ config SND_ATMEL_SOC
9if SND_ATMEL_SOC 9if SND_ATMEL_SOC
10 10
11config SND_ATMEL_SOC_PDC 11config SND_ATMEL_SOC_PDC
12 bool 12 tristate
13 default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m
14 default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y)
15
16config SND_ATMEL_SOC_SSC_PDC
17 tristate
13 18
14config SND_ATMEL_SOC_DMA 19config SND_ATMEL_SOC_DMA
15 bool 20 tristate
16 select SND_SOC_GENERIC_DMAENGINE_PCM 21 select SND_SOC_GENERIC_DMAENGINE_PCM
22 default m if SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=m
23 default y if SND_ATMEL_SOC_SSC_DMA=y || (SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=y)
24
25config SND_ATMEL_SOC_SSC_DMA
26 tristate
17 27
18config SND_ATMEL_SOC_SSC 28config SND_ATMEL_SOC_SSC
19 tristate 29 tristate
30 default y if SND_ATMEL_SOC_SSC_DMA=y || SND_ATMEL_SOC_SSC_PDC=y
31 default m if SND_ATMEL_SOC_SSC_DMA=m || SND_ATMEL_SOC_SSC_PDC=m
20 32
21config SND_AT91_SOC_SAM9G20_WM8731 33config SND_AT91_SOC_SAM9G20_WM8731
22 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 34 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
23 depends on ARCH_AT91 || COMPILE_TEST 35 depends on ARCH_AT91 || COMPILE_TEST
24 depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI 36 depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
25 select SND_ATMEL_SOC_PDC 37 select SND_ATMEL_SOC_SSC_PDC
26 select SND_ATMEL_SOC_SSC
27 select SND_SOC_WM8731 38 select SND_SOC_WM8731
28 help 39 help
29 Say Y if you want to add support for SoC audio on WM8731-based 40 Say Y if you want to add support for SoC audio on WM8731-based
@@ -33,8 +44,7 @@ config SND_ATMEL_SOC_WM8904
33 tristate "Atmel ASoC driver for boards using WM8904 codec" 44 tristate "Atmel ASoC driver for boards using WM8904 codec"
34 depends on ARCH_AT91 || COMPILE_TEST 45 depends on ARCH_AT91 || COMPILE_TEST
35 depends on ATMEL_SSC && I2C 46 depends on ATMEL_SSC && I2C
36 select SND_ATMEL_SOC_SSC 47 select SND_ATMEL_SOC_SSC_DMA
37 select SND_ATMEL_SOC_DMA
38 select SND_SOC_WM8904 48 select SND_SOC_WM8904
39 help 49 help
40 Say Y if you want to add support for Atmel ASoC driver for boards using 50 Say Y if you want to add support for Atmel ASoC driver for boards using
@@ -44,8 +54,7 @@ config SND_AT91_SOC_SAM9X5_WM8731
44 tristate "SoC Audio support for WM8731-based at91sam9x5 board" 54 tristate "SoC Audio support for WM8731-based at91sam9x5 board"
45 depends on ARCH_AT91 || COMPILE_TEST 55 depends on ARCH_AT91 || COMPILE_TEST
46 depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI 56 depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
47 select SND_ATMEL_SOC_SSC 57 select SND_ATMEL_SOC_SSC_DMA
48 select SND_ATMEL_SOC_DMA
49 select SND_SOC_WM8731 58 select SND_SOC_WM8731
50 help 59 help
51 Say Y if you want to add support for audio SoC on an 60 Say Y if you want to add support for audio SoC on an
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 4fa7ac91f972..b327e5cc8de3 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,8 +1,10 @@
1# AT91 Platform Support 1# AT91 Platform Support
2snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_PDC) := atmel-pcm-pdc.o 2snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
3snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_DMA) += atmel-pcm-dma.o 3snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
4snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o $(snd-soc-atmel-pcm-y) 4snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
5 5
6obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
7obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
6obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o 8obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
7 9
8# AT91 Machine Support 10# AT91 Machine Support
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9b36011a814e..efaafce8ba38 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -509,6 +509,11 @@ config SND_SOC_RL6231
509 default m if SND_SOC_RT5670=m 509 default m if SND_SOC_RT5670=m
510 default m if SND_SOC_RT5677=m 510 default m if SND_SOC_RT5677=m
511 511
512config SND_SOC_RL6347A
513 tristate
514 default y if SND_SOC_RT286=y
515 default m if SND_SOC_RT286=m
516
512config SND_SOC_RT286 517config SND_SOC_RT286
513 tristate 518 tristate
514 depends on I2C 519 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3dcf5ac85e89..cf160d972cb3 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -77,6 +77,7 @@ snd-soc-pcm512x-objs := pcm512x.o
77snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 77snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
78snd-soc-pcm512x-spi-objs := pcm512x-spi.o 78snd-soc-pcm512x-spi-objs := pcm512x-spi.o
79snd-soc-rl6231-objs := rl6231.o 79snd-soc-rl6231-objs := rl6231.o
80snd-soc-rl6347a-objs := rl6347a.o
80snd-soc-rt286-objs := rt286.o 81snd-soc-rt286-objs := rt286.o
81snd-soc-rt5631-objs := rt5631.o 82snd-soc-rt5631-objs := rt5631.o
82snd-soc-rt5640-objs := rt5640.o 83snd-soc-rt5640-objs := rt5640.o
@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
263obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 264obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
264obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 265obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
265obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o 266obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
267obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
266obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 268obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
267obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 269obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
268obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 270obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 679f0a0f7039..78268f0514e9 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -27,7 +27,7 @@
27#include "max98090.h" 27#include "max98090.h"
28 28
29/* Allows for sparsely populated register maps */ 29/* Allows for sparsely populated register maps */
30static struct reg_default max98090_reg[] = { 30static const struct reg_default max98090_reg[] = {
31 { 0x00, 0x00 }, /* 00 Software Reset */ 31 { 0x00, 0x00 }, /* 00 Software Reset */
32 { 0x03, 0x04 }, /* 03 Interrupt Masks */ 32 { 0x03, 0x04 }, /* 03 Interrupt Masks */
33 { 0x04, 0x00 }, /* 04 System Clock Quick */ 33 { 0x04, 0x00 }, /* 04 System Clock Quick */
@@ -2704,7 +2704,7 @@ static const struct of_device_id max98090_of_match[] = {
2704MODULE_DEVICE_TABLE(of, max98090_of_match); 2704MODULE_DEVICE_TABLE(of, max98090_of_match);
2705 2705
2706#ifdef CONFIG_ACPI 2706#ifdef CONFIG_ACPI
2707static struct acpi_device_id max98090_acpi_match[] = { 2707static const struct acpi_device_id max98090_acpi_match[] = {
2708 { "193C9890", MAX98090 }, 2708 { "193C9890", MAX98090 },
2709 { } 2709 { }
2710}; 2710};
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 62dda2488f14..b74118e019fb 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -341,6 +341,7 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
341 struct snd_soc_codec *codec = dai->codec; 341 struct snd_soc_codec *codec = dai->codec;
342 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec); 342 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
343 int i = get_coeff(priv->mclk, params_rate(hw_params)); 343 int i = get_coeff(priv->mclk, params_rate(hw_params));
344 int srate;
344 345
345 if (i < 0) 346 if (i < 0)
346 return i; 347 return i;
@@ -370,53 +371,16 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
370 BIT(0) | BIT(1), 0); 371 BIT(0) | BIT(1), 0);
371 } 372 }
372 373
373 switch (params_rate(hw_params)) { 374 srate = get_srate(params_rate(hw_params));
374 case 16000: 375 if (srate < 0)
375 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, 376 return srate;
376 get_srate(params_rate(hw_params))); 377
377 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, 378 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, srate);
378 coeff_div[i].pllnl); 379 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
379 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, 380 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
380 coeff_div[i].pllnh); 381 snd_soc_update_bits(codec, ML26124_PLLML, 0xff, coeff_div[i].pllml);
381 snd_soc_update_bits(codec, ML26124_PLLML, 0xff, 382 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
382 coeff_div[i].pllml); 383 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
383 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
384 coeff_div[i].pllmh);
385 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
386 coeff_div[i].plldiv);
387 break;
388 case 32000:
389 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
390 get_srate(params_rate(hw_params)));
391 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
392 coeff_div[i].pllnl);
393 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
394 coeff_div[i].pllnh);
395 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
396 coeff_div[i].pllml);
397 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
398 coeff_div[i].pllmh);
399 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
400 coeff_div[i].plldiv);
401 break;
402 case 48000:
403 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
404 get_srate(params_rate(hw_params)));
405 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
406 coeff_div[i].pllnl);
407 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
408 coeff_div[i].pllnh);
409 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
410 coeff_div[i].pllml);
411 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
412 coeff_div[i].pllmh);
413 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
414 coeff_div[i].plldiv);
415 break;
416 default:
417 pr_err("%s:this rate is no support for ml26124\n", __func__);
418 return -EINVAL;
419 }
420 384
421 return 0; 385 return 0;
422} 386}
diff --git a/sound/soc/codecs/rl6347a.c b/sound/soc/codecs/rl6347a.c
new file mode 100644
index 000000000000..91d5166bd3a1
--- /dev/null
+++ b/sound/soc/codecs/rl6347a.c
@@ -0,0 +1,128 @@
1/*
2 * rl6347a.c - RL6347A class device shared support
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 *
6 * Author: Oder Chiou <oder_chiou@realtek.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/spi/spi.h>
21#include <linux/dmi.h>
22#include <linux/acpi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <sound/jack.h>
31#include <linux/workqueue.h>
32#include <sound/hda_verbs.h>
33
34#include "rl6347a.h"
35
36int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value)
37{
38 struct i2c_client *client = context;
39 struct rl6347a_priv *rl6347a = i2c_get_clientdata(client);
40 u8 data[4];
41 int ret, i;
42
43 /* handle index registers */
44 if (reg <= 0xff) {
45 rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
46 for (i = 0; i < rl6347a->index_cache_size; i++) {
47 if (reg == rl6347a->index_cache[i].reg) {
48 rl6347a->index_cache[i].def = value;
49 break;
50 }
51
52 }
53 reg = RL6347A_PROC_COEF;
54 }
55
56 data[0] = (reg >> 24) & 0xff;
57 data[1] = (reg >> 16) & 0xff;
58 /*
59 * 4 bit VID: reg should be 0
60 * 12 bit VID: value should be 0
61 * So we use an OR operator to handle it rather than use if condition.
62 */
63 data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
64 data[3] = value & 0xff;
65
66 ret = i2c_master_send(client, data, 4);
67
68 if (ret == 4)
69 return 0;
70 else
71 pr_err("ret=%d\n", ret);
72 if (ret < 0)
73 return ret;
74 else
75 return -EIO;
76}
77EXPORT_SYMBOL_GPL(rl6347a_hw_write);
78
79int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value)
80{
81 struct i2c_client *client = context;
82 struct i2c_msg xfer[2];
83 int ret;
84 __be32 be_reg;
85 unsigned int index, vid, buf = 0x0;
86
87 /* handle index registers */
88 if (reg <= 0xff) {
89 rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
90 reg = RL6347A_PROC_COEF;
91 }
92
93 reg = reg | 0x80000;
94 vid = (reg >> 8) & 0xfff;
95
96 if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
97 index = (reg >> 8) & 0xf;
98 reg = (reg & ~0xf0f) | index;
99 }
100 be_reg = cpu_to_be32(reg);
101
102 /* Write register */
103 xfer[0].addr = client->addr;
104 xfer[0].flags = 0;
105 xfer[0].len = 4;
106 xfer[0].buf = (u8 *)&be_reg;
107
108 /* Read data */
109 xfer[1].addr = client->addr;
110 xfer[1].flags = I2C_M_RD;
111 xfer[1].len = 4;
112 xfer[1].buf = (u8 *)&buf;
113
114 ret = i2c_transfer(client->adapter, xfer, 2);
115 if (ret < 0)
116 return ret;
117 else if (ret != 2)
118 return -EIO;
119
120 *value = be32_to_cpu(buf);
121
122 return 0;
123}
124EXPORT_SYMBOL_GPL(rl6347a_hw_read);
125
126MODULE_DESCRIPTION("RL6347A class device shared support");
127MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
128MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rl6347a.h b/sound/soc/codecs/rl6347a.h
new file mode 100644
index 000000000000..1cb56e50b7f3
--- /dev/null
+++ b/sound/soc/codecs/rl6347a.h
@@ -0,0 +1,32 @@
1/*
2 * rl6347a.h - RL6347A class device shared support
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 *
6 * Author: Oder Chiou <oder_chiou@realtek.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __RL6347A_H__
13#define __RL6347A_H__
14
15#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
16
17#define RL6347A_VENDOR_REGISTERS 0x20
18
19#define RL6347A_COEF_INDEX\
20 VERB_CMD(AC_VERB_SET_COEF_INDEX, RL6347A_VENDOR_REGISTERS, 0)
21#define RL6347A_PROC_COEF\
22 VERB_CMD(AC_VERB_SET_PROC_COEF, RL6347A_VENDOR_REGISTERS, 0)
23
24struct rl6347a_priv {
25 struct reg_default *index_cache;
26 int index_cache_size;
27};
28
29int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value);
30int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value);
31
32#endif /* __RL6347A_H__ */
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index c6cca0639e0d..5c43e263b2c1 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -31,12 +31,15 @@
31#include <sound/rt286.h> 31#include <sound/rt286.h>
32#include <sound/hda_verbs.h> 32#include <sound/hda_verbs.h>
33 33
34#include "rl6347a.h"
34#include "rt286.h" 35#include "rt286.h"
35 36
36#define RT286_VENDOR_ID 0x10ec0286 37#define RT286_VENDOR_ID 0x10ec0286
37#define RT288_VENDOR_ID 0x10ec0288 38#define RT288_VENDOR_ID 0x10ec0288
38 39
39struct rt286_priv { 40struct rt286_priv {
41 struct reg_default *index_cache;
42 int index_cache_size;
40 struct regmap *regmap; 43 struct regmap *regmap;
41 struct snd_soc_codec *codec; 44 struct snd_soc_codec *codec;
42 struct rt286_platform_data pdata; 45 struct rt286_platform_data pdata;
@@ -45,7 +48,6 @@ struct rt286_priv {
45 struct delayed_work jack_detect_work; 48 struct delayed_work jack_detect_work;
46 int sys_clk; 49 int sys_clk;
47 int clk_id; 50 int clk_id;
48 struct reg_default *index_cache;
49}; 51};
50 52
51static struct reg_default rt286_index_def[] = { 53static struct reg_default rt286_index_def[] = {
@@ -185,94 +187,6 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
185 } 187 }
186} 188}
187 189
188static int rt286_hw_write(void *context, unsigned int reg, unsigned int value)
189{
190 struct i2c_client *client = context;
191 struct rt286_priv *rt286 = i2c_get_clientdata(client);
192 u8 data[4];
193 int ret, i;
194
195 /* handle index registers */
196 if (reg <= 0xff) {
197 rt286_hw_write(client, RT286_COEF_INDEX, reg);
198 for (i = 0; i < INDEX_CACHE_SIZE; i++) {
199 if (reg == rt286->index_cache[i].reg) {
200 rt286->index_cache[i].def = value;
201 break;
202 }
203
204 }
205 reg = RT286_PROC_COEF;
206 }
207
208 data[0] = (reg >> 24) & 0xff;
209 data[1] = (reg >> 16) & 0xff;
210 /*
211 * 4 bit VID: reg should be 0
212 * 12 bit VID: value should be 0
213 * So we use an OR operator to handle it rather than use if condition.
214 */
215 data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
216 data[3] = value & 0xff;
217
218 ret = i2c_master_send(client, data, 4);
219
220 if (ret == 4)
221 return 0;
222 else
223 pr_err("ret=%d\n", ret);
224 if (ret < 0)
225 return ret;
226 else
227 return -EIO;
228}
229
230static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value)
231{
232 struct i2c_client *client = context;
233 struct i2c_msg xfer[2];
234 int ret;
235 __be32 be_reg;
236 unsigned int index, vid, buf = 0x0;
237
238 /* handle index registers */
239 if (reg <= 0xff) {
240 rt286_hw_write(client, RT286_COEF_INDEX, reg);
241 reg = RT286_PROC_COEF;
242 }
243
244 reg = reg | 0x80000;
245 vid = (reg >> 8) & 0xfff;
246
247 if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
248 index = (reg >> 8) & 0xf;
249 reg = (reg & ~0xf0f) | index;
250 }
251 be_reg = cpu_to_be32(reg);
252
253 /* Write register */
254 xfer[0].addr = client->addr;
255 xfer[0].flags = 0;
256 xfer[0].len = 4;
257 xfer[0].buf = (u8 *)&be_reg;
258
259 /* Read data */
260 xfer[1].addr = client->addr;
261 xfer[1].flags = I2C_M_RD;
262 xfer[1].len = 4;
263 xfer[1].buf = (u8 *)&buf;
264
265 ret = i2c_transfer(client->adapter, xfer, 2);
266 if (ret < 0)
267 return ret;
268 else if (ret != 2)
269 return -EIO;
270
271 *value = be32_to_cpu(buf);
272
273 return 0;
274}
275
276#ifdef CONFIG_PM 190#ifdef CONFIG_PM
277static void rt286_index_sync(struct snd_soc_codec *codec) 191static void rt286_index_sync(struct snd_soc_codec *codec)
278{ 192{
@@ -1174,8 +1088,8 @@ static const struct regmap_config rt286_regmap = {
1174 .max_register = 0x02370100, 1088 .max_register = 0x02370100,
1175 .volatile_reg = rt286_volatile_register, 1089 .volatile_reg = rt286_volatile_register,
1176 .readable_reg = rt286_readable_register, 1090 .readable_reg = rt286_readable_register,
1177 .reg_write = rt286_hw_write, 1091 .reg_write = rl6347a_hw_write,
1178 .reg_read = rt286_hw_read, 1092 .reg_read = rl6347a_hw_read,
1179 .cache_type = REGCACHE_RBTREE, 1093 .cache_type = REGCACHE_RBTREE,
1180 .reg_defaults = rt286_reg, 1094 .reg_defaults = rt286_reg,
1181 .num_reg_defaults = ARRAY_SIZE(rt286_reg), 1095 .num_reg_defaults = ARRAY_SIZE(rt286_reg),
@@ -1248,6 +1162,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1248 } 1162 }
1249 1163
1250 rt286->index_cache = rt286_index_def; 1164 rt286->index_cache = rt286_index_def;
1165 rt286->index_cache_size = INDEX_CACHE_SIZE;
1251 rt286->i2c = i2c; 1166 rt286->i2c = i2c;
1252 i2c_set_clientdata(i2c, rt286); 1167 i2c_set_clientdata(i2c, rt286);
1253 1168
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index f40752a6c242..9bc78e57513d 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -51,7 +51,7 @@ static const struct regmap_range_cfg rt5640_ranges[] = {
51 .window_len = 0x1, }, 51 .window_len = 0x1, },
52}; 52};
53 53
54static struct reg_default init_list[] = { 54static const struct reg_default init_list[] = {
55 {RT5640_PR_BASE + 0x3d, 0x3600}, 55 {RT5640_PR_BASE + 0x3d, 0x3600},
56 {RT5640_PR_BASE + 0x12, 0x0aa8}, 56 {RT5640_PR_BASE + 0x12, 0x0aa8},
57 {RT5640_PR_BASE + 0x14, 0x0aaa}, 57 {RT5640_PR_BASE + 0x14, 0x0aaa},
@@ -59,7 +59,6 @@ static struct reg_default init_list[] = {
59 {RT5640_PR_BASE + 0x21, 0xe0e0}, 59 {RT5640_PR_BASE + 0x21, 0xe0e0},
60 {RT5640_PR_BASE + 0x23, 0x1804}, 60 {RT5640_PR_BASE + 0x23, 0x1804},
61}; 61};
62#define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list)
63 62
64static const struct reg_default rt5640_reg[] = { 63static const struct reg_default rt5640_reg[] = {
65 { 0x00, 0x000e }, 64 { 0x00, 0x000e },
@@ -2122,7 +2121,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match);
2122#endif 2121#endif
2123 2122
2124#ifdef CONFIG_ACPI 2123#ifdef CONFIG_ACPI
2125static struct acpi_device_id rt5640_acpi_match[] = { 2124static const struct acpi_device_id rt5640_acpi_match[] = {
2126 { "INT33CA", 0 }, 2125 { "INT33CA", 0 },
2127 { "10EC5640", 0 }, 2126 { "10EC5640", 0 },
2128 { "10EC5642", 0 }, 2127 { "10EC5642", 0 },
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index d5f0f5680d3b..9ce311e088fc 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -349,6 +349,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
349 case RT5645_TDM_CTRL_1: 349 case RT5645_TDM_CTRL_1:
350 case RT5645_TDM_CTRL_2: 350 case RT5645_TDM_CTRL_2:
351 case RT5645_TDM_CTRL_3: 351 case RT5645_TDM_CTRL_3:
352 case RT5650_TDM_CTRL_4:
352 case RT5645_GLB_CLK: 353 case RT5645_GLB_CLK:
353 case RT5645_PLL_CTRL1: 354 case RT5645_PLL_CTRL1:
354 case RT5645_PLL_CTRL2: 355 case RT5645_PLL_CTRL2:
@@ -1705,15 +1706,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
1705 SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM, 1706 SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM,
1706 0, 0, &rt5645_if1_adc_in_mux), 1707 0, 0, &rt5645_if1_adc_in_mux),
1707 1708
1708 SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM,
1709 0, 0, &rt5650_if1_adc1_in_mux),
1710 SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM,
1711 0, 0, &rt5650_if1_adc2_in_mux),
1712 SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM,
1713 0, 0, &rt5650_if1_adc3_in_mux),
1714 SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM,
1715 0, 0, &rt5650_if1_adc_in_mux),
1716
1717 SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 1709 SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM,
1718 0, 0, &rt5645_if2_adc_in_mux), 1710 0, 0, &rt5645_if2_adc_in_mux),
1719 1711
@@ -1732,14 +1724,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
1732 &rt5645_if1_dac2_tdm_sel_mux), 1724 &rt5645_if1_dac2_tdm_sel_mux),
1733 SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, 1725 SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0,
1734 &rt5645_if1_dac3_tdm_sel_mux), 1726 &rt5645_if1_dac3_tdm_sel_mux),
1735 SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0,
1736 &rt5650_if1_dac0_tdm_sel_mux),
1737 SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0,
1738 &rt5650_if1_dac1_tdm_sel_mux),
1739 SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0,
1740 &rt5650_if1_dac2_tdm_sel_mux),
1741 SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0,
1742 &rt5650_if1_dac3_tdm_sel_mux),
1743 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), 1727 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
1744 SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), 1728 SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
1745 SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), 1729 SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -1881,6 +1865,24 @@ static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
1881 0, 0, &rt5650_a_dac2_l_mux), 1865 0, 0, &rt5650_a_dac2_l_mux),
1882 SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM, 1866 SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM,
1883 0, 0, &rt5650_a_dac2_r_mux), 1867 0, 0, &rt5650_a_dac2_r_mux),
1868
1869 SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM,
1870 0, 0, &rt5650_if1_adc1_in_mux),
1871 SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM,
1872 0, 0, &rt5650_if1_adc2_in_mux),
1873 SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM,
1874 0, 0, &rt5650_if1_adc3_in_mux),
1875 SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM,
1876 0, 0, &rt5650_if1_adc_in_mux),
1877
1878 SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0,
1879 &rt5650_if1_dac0_tdm_sel_mux),
1880 SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0,
1881 &rt5650_if1_dac1_tdm_sel_mux),
1882 SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0,
1883 &rt5650_if1_dac2_tdm_sel_mux),
1884 SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0,
1885 &rt5650_if1_dac3_tdm_sel_mux),
1884}; 1886};
1885 1887
1886static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { 1888static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
@@ -2761,6 +2763,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
2761 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 2763 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2762 2764
2763 if (enable) { 2765 if (enable) {
2766 snd_soc_dapm_mutex_lock(&codec->dapm);
2764 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, 2767 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm,
2765 "ADC L power"); 2768 "ADC L power");
2766 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, 2769 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm,
@@ -2770,6 +2773,8 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
2770 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, 2773 snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm,
2771 "Mic Det Power"); 2774 "Mic Det Power");
2772 snd_soc_dapm_sync_unlocked(&codec->dapm); 2775 snd_soc_dapm_sync_unlocked(&codec->dapm);
2776 snd_soc_dapm_mutex_unlock(&codec->dapm);
2777
2773 snd_soc_update_bits(codec, 2778 snd_soc_update_bits(codec,
2774 RT5645_INT_IRQ_ST, 0x8, 0x8); 2779 RT5645_INT_IRQ_ST, 0x8, 0x8);
2775 snd_soc_update_bits(codec, 2780 snd_soc_update_bits(codec,
@@ -2780,6 +2785,8 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
2780 } else { 2785 } else {
2781 snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0); 2786 snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
2782 snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0); 2787 snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0);
2788
2789 snd_soc_dapm_mutex_lock(&codec->dapm);
2783 snd_soc_dapm_disable_pin_unlocked(&codec->dapm, 2790 snd_soc_dapm_disable_pin_unlocked(&codec->dapm,
2784 "ADC L power"); 2791 "ADC L power");
2785 snd_soc_dapm_disable_pin_unlocked(&codec->dapm, 2792 snd_soc_dapm_disable_pin_unlocked(&codec->dapm,
@@ -2790,6 +2797,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
2790 snd_soc_dapm_disable_pin_unlocked(&codec->dapm, 2797 snd_soc_dapm_disable_pin_unlocked(&codec->dapm,
2791 "Mic Det Power"); 2798 "Mic Det Power");
2792 snd_soc_dapm_sync_unlocked(&codec->dapm); 2799 snd_soc_dapm_sync_unlocked(&codec->dapm);
2800 snd_soc_dapm_mutex_unlock(&codec->dapm);
2793 } 2801 }
2794} 2802}
2795 2803
@@ -2937,17 +2945,11 @@ static int rt5645_irq_detection(struct rt5645_priv *rt5645)
2937 2945
2938 switch (rt5645->pdata.jd_mode) { 2946 switch (rt5645->pdata.jd_mode) {
2939 case 0: /* Not using rt5645 JD */ 2947 case 0: /* Not using rt5645 JD */
2940 if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { 2948 if (rt5645->gpiod_hp_det) {
2941 gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); 2949 gpio_state = gpiod_get_value(rt5645->gpiod_hp_det);
2942 dev_dbg(rt5645->codec->dev, "gpio = %d(%d)\n", 2950 dev_dbg(rt5645->codec->dev, "gpio_state = %d\n",
2943 rt5645->pdata.hp_det_gpio, gpio_state); 2951 gpio_state);
2944 } 2952 report = rt5645_jack_detect(rt5645->codec, gpio_state);
2945 if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) ||
2946 (!rt5645->pdata.gpio_hp_det_active_high &&
2947 !gpio_state)) {
2948 report = rt5645_jack_detect(rt5645->codec, 1);
2949 } else {
2950 report = rt5645_jack_detect(rt5645->codec, 0);
2951 } 2953 }
2952 snd_soc_jack_report(rt5645->hp_jack, 2954 snd_soc_jack_report(rt5645->hp_jack,
2953 report, SND_JACK_HEADPHONE); 2955 report, SND_JACK_HEADPHONE);
@@ -3230,6 +3232,20 @@ static struct dmi_system_id dmi_platform_intel_braswell[] = {
3230 { } 3232 { }
3231}; 3233};
3232 3234
3235static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3236{
3237 rt5645->pdata.in2_diff = device_property_read_bool(dev,
3238 "realtek,in2-differential");
3239 device_property_read_u32(dev,
3240 "realtek,dmic1-data-pin", &rt5645->pdata.dmic1_data_pin);
3241 device_property_read_u32(dev,
3242 "realtek,dmic2-data-pin", &rt5645->pdata.dmic2_data_pin);
3243 device_property_read_u32(dev,
3244 "realtek,jd-mode", &rt5645->pdata.jd_mode);
3245
3246 return 0;
3247}
3248
3233static int rt5645_i2c_probe(struct i2c_client *i2c, 3249static int rt5645_i2c_probe(struct i2c_client *i2c,
3234 const struct i2c_device_id *id) 3250 const struct i2c_device_id *id)
3235{ 3251{
@@ -3237,7 +3253,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3237 struct rt5645_priv *rt5645; 3253 struct rt5645_priv *rt5645;
3238 int ret; 3254 int ret;
3239 unsigned int val; 3255 unsigned int val;
3240 struct gpio_desc *gpiod;
3241 3256
3242 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), 3257 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
3243 GFP_KERNEL); 3258 GFP_KERNEL);
@@ -3247,22 +3262,19 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3247 rt5645->i2c = i2c; 3262 rt5645->i2c = i2c;
3248 i2c_set_clientdata(i2c, rt5645); 3263 i2c_set_clientdata(i2c, rt5645);
3249 3264
3250 if (pdata) { 3265 if (pdata)
3251 rt5645->pdata = *pdata; 3266 rt5645->pdata = *pdata;
3252 } else { 3267 else if (dmi_check_system(dmi_platform_intel_braswell))
3253 if (dmi_check_system(dmi_platform_intel_braswell)) { 3268 rt5645->pdata = *rt5645_pdata;
3254 rt5645->pdata = *rt5645_pdata; 3269 else
3255 gpiod = devm_gpiod_get_index(&i2c->dev, "rt5645", 0); 3270 rt5645_parse_dt(rt5645, &i2c->dev);
3256 3271
3257 if (IS_ERR(gpiod) || gpiod_direction_input(gpiod)) { 3272 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
3258 rt5645->pdata.hp_det_gpio = -1; 3273 GPIOD_IN);
3259 dev_err(&i2c->dev, "failed to initialize gpiod\n"); 3274
3260 } else { 3275 if (IS_ERR(rt5645->gpiod_hp_det)) {
3261 rt5645->pdata.hp_det_gpio = desc_to_gpio(gpiod); 3276 dev_err(&i2c->dev, "failed to initialize gpiod\n");
3262 rt5645->pdata.gpio_hp_det_active_high 3277 return PTR_ERR(rt5645->gpiod_hp_det);
3263 = !gpiod_is_active_low(gpiod);
3264 }
3265 }
3266 } 3278 }
3267 3279
3268 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap); 3280 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
@@ -3426,16 +3438,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3426 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); 3438 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
3427 } 3439 }
3428 3440
3429 if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) {
3430 ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645");
3431 if (ret)
3432 dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n");
3433
3434 ret = gpio_direction_input(rt5645->pdata.hp_det_gpio);
3435 if (ret)
3436 dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n");
3437 }
3438
3439 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, 3441 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645,
3440 rt5645_dai, ARRAY_SIZE(rt5645_dai)); 3442 rt5645_dai, ARRAY_SIZE(rt5645_dai));
3441} 3443}
@@ -3449,9 +3451,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
3449 3451
3450 cancel_delayed_work_sync(&rt5645->jack_detect_work); 3452 cancel_delayed_work_sync(&rt5645->jack_detect_work);
3451 3453
3452 if (gpio_is_valid(rt5645->pdata.hp_det_gpio))
3453 gpio_free(rt5645->pdata.hp_det_gpio);
3454
3455 snd_soc_unregister_codec(&i2c->dev); 3454 snd_soc_unregister_codec(&i2c->dev);
3456 3455
3457 return 0; 3456 return 0;
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 9ec4e899795d..0353a6a273ab 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -2182,6 +2182,7 @@ struct rt5645_priv {
2182 struct rt5645_platform_data pdata; 2182 struct rt5645_platform_data pdata;
2183 struct regmap *regmap; 2183 struct regmap *regmap;
2184 struct i2c_client *i2c; 2184 struct i2c_client *i2c;
2185 struct gpio_desc *gpiod_hp_det;
2185 struct snd_soc_jack *hp_jack; 2186 struct snd_soc_jack *hp_jack;
2186 struct snd_soc_jack *mic_jack; 2187 struct snd_soc_jack *mic_jack;
2187 struct snd_soc_jack *btn_jack; 2188 struct snd_soc_jack *btn_jack;
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 840dd6d0003a..a9123d414178 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -51,12 +51,11 @@ static const struct regmap_range_cfg rt5670_ranges[] = {
51 .window_len = 0x1, }, 51 .window_len = 0x1, },
52}; 52};
53 53
54static struct reg_default init_list[] = { 54static const struct reg_default init_list[] = {
55 { RT5670_PR_BASE + 0x14, 0x9a8a }, 55 { RT5670_PR_BASE + 0x14, 0x9a8a },
56 { RT5670_PR_BASE + 0x38, 0x3ba1 }, 56 { RT5670_PR_BASE + 0x38, 0x3ba1 },
57 { RT5670_PR_BASE + 0x3d, 0x3640 }, 57 { RT5670_PR_BASE + 0x3d, 0x3640 },
58}; 58};
59#define RT5670_INIT_REG_LEN ARRAY_SIZE(init_list)
60 59
61static const struct reg_default rt5670_reg[] = { 60static const struct reg_default rt5670_reg[] = {
62 { 0x00, 0x0000 }, 61 { 0x00, 0x0000 },
@@ -2809,7 +2808,7 @@ static const struct i2c_device_id rt5670_i2c_id[] = {
2809MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); 2808MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
2810 2809
2811#ifdef CONFIG_ACPI 2810#ifdef CONFIG_ACPI
2812static struct acpi_device_id rt5670_acpi_match[] = { 2811static const struct acpi_device_id rt5670_acpi_match[] = {
2813 { "10EC5670", 0}, 2812 { "10EC5670", 0},
2814 { }, 2813 { },
2815}; 2814};
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index 891e2c529df3..4f25a7d0efa2 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -45,7 +45,7 @@ static struct reg_default tas2552_reg_defs[] = {
45 {TAS2552_OUTPUT_DATA, 0xc0}, 45 {TAS2552_OUTPUT_DATA, 0xc0},
46 {TAS2552_PDM_CFG, 0x01}, 46 {TAS2552_PDM_CFG, 0x01},
47 {TAS2552_PGA_GAIN, 0x00}, 47 {TAS2552_PGA_GAIN, 0x00},
48 {TAS2552_BOOST_PT_CTRL, 0x0f}, 48 {TAS2552_BOOST_APT_CTRL, 0x0f},
49 {TAS2552_RESERVED_0D, 0xbe}, 49 {TAS2552_RESERVED_0D, 0xbe},
50 {TAS2552_LIMIT_RATE_HYS, 0x08}, 50 {TAS2552_LIMIT_RATE_HYS, 0x08},
51 {TAS2552_CFG_2, 0xef}, 51 {TAS2552_CFG_2, 0xef},
@@ -77,7 +77,9 @@ struct tas2552_data {
77 struct gpio_desc *enable_gpio; 77 struct gpio_desc *enable_gpio;
78 unsigned char regs[TAS2552_VBAT_DATA]; 78 unsigned char regs[TAS2552_VBAT_DATA];
79 unsigned int pll_clkin; 79 unsigned int pll_clkin;
80 int pll_clk_id;
80 unsigned int pdm_clk; 81 unsigned int pdm_clk;
82 int pdm_clk_id;
81 83
82 unsigned int dai_fmt; 84 unsigned int dai_fmt;
83 unsigned int tdm_delay; 85 unsigned int tdm_delay;
@@ -143,31 +145,105 @@ static const struct snd_soc_dapm_route tas2552_audio_map[] = {
143}; 145};
144 146
145#ifdef CONFIG_PM 147#ifdef CONFIG_PM
146static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) 148static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
147{ 149{
148 u8 cfg1_reg = 0; 150 u8 cfg1_reg = 0;
149 151
150 if (!tas_data->codec) 152 if (!tas2552->codec)
151 return; 153 return;
152 154
153 if (sw_shutdown) 155 if (sw_shutdown)
154 cfg1_reg = TAS2552_SWS; 156 cfg1_reg = TAS2552_SWS;
155 157
156 snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, TAS2552_SWS, 158 snd_soc_update_bits(tas2552->codec, TAS2552_CFG_1, TAS2552_SWS,
157 cfg1_reg); 159 cfg1_reg);
158} 160}
159#endif 161#endif
160 162
163static int tas2552_setup_pll(struct snd_soc_codec *codec,
164 struct snd_pcm_hw_params *params)
165{
166 struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
167 bool bypass_pll = false;
168 unsigned int pll_clk = params_rate(params) * 512;
169 unsigned int pll_clkin = tas2552->pll_clkin;
170 u8 pll_enable;
171
172 if (!pll_clkin) {
173 if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
174 return -EINVAL;
175
176 pll_clkin = snd_soc_params_to_bclk(params);
177 pll_clkin += tas2552->tdm_delay;
178 }
179
180 pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
181 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
182
183 if (pll_clkin == pll_clk)
184 bypass_pll = true;
185
186 if (bypass_pll) {
187 /* By pass the PLL configuration */
188 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
189 TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
190 } else {
191 /* Fill in the PLL control registers for J & D
192 * pll_clk = (.5 * pll_clkin * J.D) / 2^p
193 * Need to fill in J and D here based on incoming freq
194 */
195 unsigned int d;
196 u8 j;
197 u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
198 u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
199
200 p = (p >> 7);
201
202recalc:
203 j = (pll_clk * 2 * (1 << p)) / pll_clkin;
204 d = (pll_clk * 2 * (1 << p)) % pll_clkin;
205 d /= (pll_clkin / 10000);
206
207 if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
208 if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
209 pll_clkin = 1800000;
210 pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
211 TAS2552_PLL_SRC_MASK;
212 } else {
213 pll_clkin = snd_soc_params_to_bclk(params);
214 pll_clkin += tas2552->tdm_delay;
215 pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
216 TAS2552_PLL_SRC_MASK;
217 }
218 goto recalc;
219 }
220
221 snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
222 pll_sel);
223
224 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
225 TAS2552_PLL_J_MASK, j);
226 /* Will clear the PLL_BYPASS bit */
227 snd_soc_write(codec, TAS2552_PLL_CTRL_2,
228 TAS2552_PLL_D_UPPER(d));
229 snd_soc_write(codec, TAS2552_PLL_CTRL_3,
230 TAS2552_PLL_D_LOWER(d));
231 }
232
233 /* Restore PLL status */
234 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
235 pll_enable);
236
237 return 0;
238}
239
161static int tas2552_hw_params(struct snd_pcm_substream *substream, 240static int tas2552_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params, 241 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai) 242 struct snd_soc_dai *dai)
164{ 243{
165 struct snd_soc_codec *codec = dai->codec; 244 struct snd_soc_codec *codec = dai->codec;
166 struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); 245 struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
167 int sample_rate, pll_clk;
168 int d;
169 int cpf; 246 int cpf;
170 u8 p, j;
171 u8 ser_ctrl1_reg, wclk_rate; 247 u8 ser_ctrl1_reg, wclk_rate;
172 248
173 switch (params_width(params)) { 249 switch (params_width(params)) {
@@ -245,49 +321,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
245 snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK, 321 snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
246 wclk_rate); 322 wclk_rate);
247 323
248 if (!tas2552->pll_clkin) 324 return tas2552_setup_pll(codec, params);
249 return -EINVAL;
250
251 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
252
253 if (tas2552->pll_clkin == TAS2552_245MHZ_CLK ||
254 tas2552->pll_clkin == TAS2552_225MHZ_CLK) {
255 /* By pass the PLL configuration */
256 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
257 TAS2552_PLL_BYPASS_MASK,
258 TAS2552_PLL_BYPASS);
259 } else {
260 /* Fill in the PLL control registers for J & D
261 * PLL_CLK = (.5 * freq * J.D) / 2^p
262 * Need to fill in J and D here based on incoming freq
263 */
264 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
265 p = (p >> 7);
266 sample_rate = params_rate(params);
267
268 if (sample_rate == 48000)
269 pll_clk = TAS2552_245MHZ_CLK;
270 else if (sample_rate == 44100)
271 pll_clk = TAS2552_225MHZ_CLK;
272 else {
273 dev_vdbg(codec->dev, "Substream sample rate is not found %i\n",
274 params_rate(params));
275 return -EINVAL;
276 }
277
278 j = (pll_clk * 2 * (1 << p)) / tas2552->pll_clkin;
279 d = (pll_clk * 2 * (1 << p)) % tas2552->pll_clkin;
280
281 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
282 TAS2552_PLL_J_MASK, j);
283 snd_soc_write(codec, TAS2552_PLL_CTRL_2,
284 (d >> 7) & TAS2552_PLL_D_UPPER_MASK);
285 snd_soc_write(codec, TAS2552_PLL_CTRL_3,
286 d & TAS2552_PLL_D_LOWER_MASK);
287
288 }
289
290 return 0;
291} 325}
292 326
293#define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \ 327#define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
@@ -370,12 +404,21 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
370 404
371 switch (clk_id) { 405 switch (clk_id) {
372 case TAS2552_PLL_CLKIN_MCLK: 406 case TAS2552_PLL_CLKIN_MCLK:
373 case TAS2552_PLL_CLKIN_BCLK:
374 case TAS2552_PLL_CLKIN_IVCLKIN: 407 case TAS2552_PLL_CLKIN_IVCLKIN:
408 if (freq < 512000 || freq > 24576000) {
409 /* out of range PLL_CLKIN, fall back to use BCLK */
410 dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n",
411 freq);
412 clk_id = TAS2552_PLL_CLKIN_BCLK;
413 freq = 0;
414 }
415 /* fall through */
416 case TAS2552_PLL_CLKIN_BCLK:
375 case TAS2552_PLL_CLKIN_1_8_FIXED: 417 case TAS2552_PLL_CLKIN_1_8_FIXED:
376 mask = TAS2552_PLL_SRC_MASK; 418 mask = TAS2552_PLL_SRC_MASK;
377 val = (clk_id << 3) & mask; /* bit 4:5 in the register */ 419 val = (clk_id << 3) & mask; /* bit 4:5 in the register */
378 reg = TAS2552_CFG_1; 420 reg = TAS2552_CFG_1;
421 tas2552->pll_clk_id = clk_id;
379 tas2552->pll_clkin = freq; 422 tas2552->pll_clkin = freq;
380 break; 423 break;
381 case TAS2552_PDM_CLK_PLL: 424 case TAS2552_PDM_CLK_PLL:
@@ -385,6 +428,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
385 mask = TAS2552_PDM_CLK_SEL_MASK; 428 mask = TAS2552_PDM_CLK_SEL_MASK;
386 val = (clk_id >> 1) & mask; /* bit 0:1 in the register */ 429 val = (clk_id >> 1) & mask; /* bit 0:1 in the register */
387 reg = TAS2552_PDM_CFG; 430 reg = TAS2552_PDM_CFG;
431 tas2552->pdm_clk_id = clk_id;
388 tas2552->pdm_clk = freq; 432 tas2552->pdm_clk = freq;
389 break; 433 break;
390 default: 434 default:
@@ -509,9 +553,20 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
509 */ 553 */
510static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0); 554static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0);
511 555
556static const char * const tas2552_din_source_select[] = {
557 "Muted",
558 "Left",
559 "Right",
560 "Left + Right average",
561};
562static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum,
563 TAS2552_CFG_3, 3,
564 tas2552_din_source_select);
565
512static const struct snd_kcontrol_new tas2552_snd_controls[] = { 566static const struct snd_kcontrol_new tas2552_snd_controls[] = {
513 SOC_SINGLE_TLV("Speaker Driver Playback Volume", 567 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
514 TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv), 568 TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
569 SOC_ENUM("DIN source", tas2552_din_source_enum),
515}; 570};
516 571
517static int tas2552_codec_probe(struct snd_soc_codec *codec) 572static int tas2552_codec_probe(struct snd_soc_codec *codec)
@@ -543,13 +598,14 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec)
543 snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE); 598 snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
544 snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | 599 snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
545 TAS2552_DIN_SRC_SEL_AVG_L_R); 600 TAS2552_DIN_SRC_SEL_AVG_L_R);
546 snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I); 601 snd_soc_write(codec, TAS2552_OUTPUT_DATA,
547 snd_soc_write(codec, TAS2552_OUTPUT_DATA, TAS2552_PDM_DATA_V_I | 0x8); 602 TAS2552_PDM_DATA_SEL_V_I |
548 snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 | 603 TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
549 TAS2552_APT_THRESH_2_1_7); 604 snd_soc_write(codec, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
605 TAS2552_APT_THRESH_20_17);
550 606
551 snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | 607 snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
552 TAS2552_APT_EN | TAS2552_LIM_EN); 608 TAS2552_LIM_EN);
553 609
554 return 0; 610 return 0;
555 611
@@ -647,13 +703,10 @@ static int tas2552_probe(struct i2c_client *client,
647 if (data == NULL) 703 if (data == NULL)
648 return -ENOMEM; 704 return -ENOMEM;
649 705
650 data->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 706 data->enable_gpio = devm_gpiod_get_optional(dev, "enable",
651 if (IS_ERR(data->enable_gpio)) { 707 GPIOD_OUT_LOW);
652 if (PTR_ERR(data->enable_gpio) == -EPROBE_DEFER) 708 if (IS_ERR(data->enable_gpio))
653 return -EPROBE_DEFER; 709 return PTR_ERR(data->enable_gpio);
654
655 data->enable_gpio = NULL;;
656 }
657 710
658 data->tas2552_client = client; 711 data->tas2552_client = client;
659 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config); 712 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
@@ -695,6 +748,7 @@ static int tas2552_probe(struct i2c_client *client,
695static int tas2552_i2c_remove(struct i2c_client *client) 748static int tas2552_i2c_remove(struct i2c_client *client)
696{ 749{
697 snd_soc_unregister_codec(&client->dev); 750 snd_soc_unregister_codec(&client->dev);
751 pm_runtime_disable(&client->dev);
698 return 0; 752 return 0;
699} 753}
700 754
diff --git a/sound/soc/codecs/tas2552.h b/sound/soc/codecs/tas2552.h
index bbb820495516..5746f8fd0afd 100644
--- a/sound/soc/codecs/tas2552.h
+++ b/sound/soc/codecs/tas2552.h
@@ -19,7 +19,7 @@
19#define __TAS2552_H__ 19#define __TAS2552_H__
20 20
21/* Register Address Map */ 21/* Register Address Map */
22#define TAS2552_DEVICE_STATUS 0x00 22#define TAS2552_DEVICE_STATUS 0x00
23#define TAS2552_CFG_1 0x01 23#define TAS2552_CFG_1 0x01
24#define TAS2552_CFG_2 0x02 24#define TAS2552_CFG_2 0x02
25#define TAS2552_CFG_3 0x03 25#define TAS2552_CFG_3 0x03
@@ -33,13 +33,13 @@
33#define TAS2552_BTIP 0x0b 33#define TAS2552_BTIP 0x0b
34#define TAS2552_BTS_CTRL 0x0c 34#define TAS2552_BTS_CTRL 0x0c
35#define TAS2552_RESERVED_0D 0x0d 35#define TAS2552_RESERVED_0D 0x0d
36#define TAS2552_LIMIT_RATE_HYS 0x0e 36#define TAS2552_LIMIT_RATE_HYS 0x0e
37#define TAS2552_LIMIT_RELEASE 0x0f 37#define TAS2552_LIMIT_RELEASE 0x0f
38#define TAS2552_LIMIT_INT_COUNT 0x10 38#define TAS2552_LIMIT_INT_COUNT 0x10
39#define TAS2552_PDM_CFG 0x11 39#define TAS2552_PDM_CFG 0x11
40#define TAS2552_PGA_GAIN 0x12 40#define TAS2552_PGA_GAIN 0x12
41#define TAS2552_EDGE_RATE_CTRL 0x13 41#define TAS2552_EDGE_RATE_CTRL 0x13
42#define TAS2552_BOOST_PT_CTRL 0x14 42#define TAS2552_BOOST_APT_CTRL 0x14
43#define TAS2552_VER_NUM 0x16 43#define TAS2552_VER_NUM 0x16
44#define TAS2552_VBAT_DATA 0x19 44#define TAS2552_VBAT_DATA 0x19
45#define TAS2552_MAX_REG 0x20 45#define TAS2552_MAX_REG 0x20
@@ -103,10 +103,21 @@
103#define TAS2552_WCLKDIR (1 << 7) 103#define TAS2552_WCLKDIR (1 << 7)
104 104
105/* OUTPUT_DATA register */ 105/* OUTPUT_DATA register */
106#define TAS2552_PDM_DATA_I 0x00 106#define TAS2552_DATA_OUT_I_DATA (0x0)
107#define TAS2552_PDM_DATA_V (1 << 6) 107#define TAS2552_DATA_OUT_V_DATA (0x1)
108#define TAS2552_PDM_DATA_I_V (1 << 7) 108#define TAS2552_DATA_OUT_VBAT_DATA (0x2)
109#define TAS2552_PDM_DATA_V_I (0x11 << 6) 109#define TAS2552_DATA_OUT_VBOOST_DATA (0x3)
110#define TAS2552_DATA_OUT_PGA_GAIN (0x4)
111#define TAS2552_DATA_OUT_IV_DATA (0x5)
112#define TAS2552_DATA_OUT_VBAT_VBOOST_GAIN (0x6)
113#define TAS2552_DATA_OUT_DISABLED (0x7)
114#define TAS2552_L_DATA_OUT(x) ((x) << 0)
115#define TAS2552_R_DATA_OUT(x) ((x) << 3)
116#define TAS2552_PDM_DATA_SEL_I (0x0 << 6)
117#define TAS2552_PDM_DATA_SEL_V (0x1 << 6)
118#define TAS2552_PDM_DATA_SEL_I_V (0x2 << 6)
119#define TAS2552_PDM_DATA_SEL_V_I (0x3 << 6)
120#define TAS2552_PDM_DATA_SEL_MASK TAS2552_PDM_DATA_SEL_V_I
110 121
111/* PDM CFG Register */ 122/* PDM CFG Register */
112#define TAS2552_PDM_CLK_SEL_PLL (0x0 << 0) 123#define TAS2552_PDM_CLK_SEL_PLL (0x0 << 0)
@@ -116,24 +127,20 @@
116#define TAS2552_PDM_CLK_SEL_MASK TAS2552_PDM_CLK_SEL_MCLK 127#define TAS2552_PDM_CLK_SEL_MASK TAS2552_PDM_CLK_SEL_MCLK
117#define TAS2552_PDM_DATA_ES (1 << 2) 128#define TAS2552_PDM_DATA_ES (1 << 2)
118 129
119/* Boost pass-through register */ 130/* Boost Auto-pass through register */
120#define TAS2552_APT_DELAY_50 0x00 131#define TAS2552_APT_DELAY_50 (0x0 << 0)
121#define TAS2552_APT_DELAY_75 (1 << 1) 132#define TAS2552_APT_DELAY_75 (0x1 << 0)
122#define TAS2552_APT_DELAY_125 (1 << 2) 133#define TAS2552_APT_DELAY_125 (0x2 << 0)
123#define TAS2552_APT_DELAY_200 (1 << 3) 134#define TAS2552_APT_DELAY_200 (0x3 << 0)
124 135#define TAS2552_APT_THRESH_05_02 (0x0 << 2)
125#define TAS2552_APT_THRESH_2_5 0x00 136#define TAS2552_APT_THRESH_10_07 (0x1 << 2)
126#define TAS2552_APT_THRESH_1_7 (1 << 3) 137#define TAS2552_APT_THRESH_14_11 (0x2 << 2)
127#define TAS2552_APT_THRESH_1_4_1_1 (1 << 4) 138#define TAS2552_APT_THRESH_20_17 (0x3 << 2)
128#define TAS2552_APT_THRESH_2_1_7 (0x11 << 2)
129 139
130/* PLL Control Register */ 140/* PLL Control Register */
131#define TAS2552_245MHZ_CLK 24576000 141#define TAS2552_PLL_J_MASK 0x7f
132#define TAS2552_225MHZ_CLK 22579200 142#define TAS2552_PLL_D_UPPER(x) (((x) >> 8) & 0x3f)
133#define TAS2552_PLL_J_MASK 0x7f 143#define TAS2552_PLL_D_LOWER(x) ((x) & 0xff)
134#define TAS2552_PLL_D_UPPER_MASK 0x3f 144#define TAS2552_PLL_BYPASS (1 << 7)
135#define TAS2552_PLL_D_LOWER_MASK 0xff
136#define TAS2552_PLL_BYPASS_MASK 0x80
137#define TAS2552_PLL_BYPASS 0x80
138 145
139#endif 146#endif
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index d8959e31853d..c5ec519d34be 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1876,8 +1876,8 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1876 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); 1876 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1877 int ret; 1877 int ret;
1878 1878
1879 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); 1879 ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
1880 if (ret != 0) 1880 if (ret)
1881 return ret; 1881 return ret;
1882 1882
1883 arizona_init_spk(codec); 1883 arizona_init_spk(codec);
@@ -1894,6 +1894,8 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
1894{ 1894{
1895 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); 1895 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1896 1896
1897 wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
1898
1897 priv->core.arizona->dapm = NULL; 1899 priv->core.arizona->dapm = NULL;
1898 1900
1899 return 0; 1901 return 0;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 14a7739d6c09..5f032a37b61f 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1600,7 +1600,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
1600{ 1600{
1601 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 1601 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1602 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); 1602 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
1603 int ret; 1603 int i, ret;
1604 1604
1605 priv->core.arizona->dapm = dapm; 1605 priv->core.arizona->dapm = dapm;
1606 1606
@@ -1608,9 +1608,11 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
1608 arizona_init_gpio(codec); 1608 arizona_init_gpio(codec);
1609 arizona_init_mono(codec); 1609 arizona_init_mono(codec);
1610 1610
1611 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); 1611 for (i = 0; i < WM5110_NUM_ADSP; ++i) {
1612 if (ret != 0) 1612 ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec);
1613 return ret; 1613 if (ret)
1614 return ret;
1615 }
1614 1616
1615 snd_soc_dapm_disable_pin(dapm, "HAPTICS"); 1617 snd_soc_dapm_disable_pin(dapm, "HAPTICS");
1616 1618
@@ -1620,6 +1622,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
1620static int wm5110_codec_remove(struct snd_soc_codec *codec) 1622static int wm5110_codec_remove(struct snd_soc_codec *codec)
1621{ 1623{
1622 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); 1624 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
1625 int i;
1626
1627 for (i = 0; i < WM5110_NUM_ADSP; ++i)
1628 wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
1623 1629
1624 priv->core.arizona->dapm = NULL; 1630 priv->core.arizona->dapm = NULL;
1625 1631
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 8c5b9df3e542..43ea8ae5f871 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -113,6 +113,15 @@ static struct {
113 { 7, 1152 }, 113 { 7, 1152 },
114}; 114};
115 115
116static struct {
117 int value;
118 int ratio;
119} bclk_ratios[WM8523_NUM_RATES] = {
120 { 2, 32 },
121 { 3, 64 },
122 { 4, 128 },
123};
124
116static int wm8523_startup(struct snd_pcm_substream *substream, 125static int wm8523_startup(struct snd_pcm_substream *substream,
117 struct snd_soc_dai *dai) 126 struct snd_soc_dai *dai)
118{ 127{
@@ -162,6 +171,23 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
162 aifctrl2 &= ~WM8523_SR_MASK; 171 aifctrl2 &= ~WM8523_SR_MASK;
163 aifctrl2 |= lrclk_ratios[i].value; 172 aifctrl2 |= lrclk_ratios[i].value;
164 173
174 if (aifctrl1 & WM8523_AIF_MSTR) {
175 /* Find a fs->bclk ratio */
176 for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
177 if (params_width(params) * 2 <= bclk_ratios[i].ratio)
178 break;
179
180 if (i == ARRAY_SIZE(bclk_ratios)) {
181 dev_err(codec->dev,
182 "No matching BCLK/fs ratio for word length %d\n",
183 params_width(params));
184 return -EINVAL;
185 }
186
187 aifctrl2 &= ~WM8523_BCLKDIV_MASK;
188 aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
189 }
190
165 aifctrl1 &= ~WM8523_WL_MASK; 191 aifctrl1 &= ~WM8523_WL_MASK;
166 switch (params_width(params)) { 192 switch (params_width(params)) {
167 case 16: 193 case 16:
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 09ff01f2fc1e..b34623786e35 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -125,18 +125,6 @@ static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {
125 { "VOUTRN", NULL, "DACR" }, 125 { "VOUTRN", NULL, "DACR" },
126}; 126};
127 127
128static struct {
129 int value;
130 int ratio;
131} lrclk_ratios[WM8741_NUM_RATES] = {
132 { 1, 128 },
133 { 2, 192 },
134 { 3, 256 },
135 { 4, 384 },
136 { 5, 512 },
137 { 6, 768 },
138};
139
140static const unsigned int rates_11289[] = { 128static const unsigned int rates_11289[] = {
141 44100, 88200, 129 44100, 88200,
142}; 130};
@@ -209,25 +197,16 @@ static const struct snd_pcm_hw_constraint_list constraints_36864 = {
209 .list = rates_36864, 197 .list = rates_36864,
210}; 198};
211 199
212
213static int wm8741_startup(struct snd_pcm_substream *substream, 200static int wm8741_startup(struct snd_pcm_substream *substream,
214 struct snd_soc_dai *dai) 201 struct snd_soc_dai *dai)
215{ 202{
216 struct snd_soc_codec *codec = dai->codec; 203 struct snd_soc_codec *codec = dai->codec;
217 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 204 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
218 205
219 /* The set of sample rates that can be supported depends on the 206 if (wm8741->sysclk)
220 * MCLK supplied to the CODEC - enforce this. 207 snd_pcm_hw_constraint_list(substream->runtime, 0,
221 */ 208 SNDRV_PCM_HW_PARAM_RATE,
222 if (!wm8741->sysclk) { 209 wm8741->sysclk_constraints);
223 dev_err(codec->dev,
224 "No MCLK configured, call set_sysclk() on init\n");
225 return -EINVAL;
226 }
227
228 snd_pcm_hw_constraint_list(substream->runtime, 0,
229 SNDRV_PCM_HW_PARAM_RATE,
230 wm8741->sysclk_constraints);
231 210
232 return 0; 211 return 0;
233} 212}
@@ -241,17 +220,24 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
241 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 220 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
242 int i; 221 int i;
243 222
244 /* Find a supported LRCLK ratio */ 223 /* The set of sample rates that can be supported depends on the
245 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { 224 * MCLK supplied to the CODEC - enforce this.
246 if (wm8741->sysclk / params_rate(params) == 225 */
247 lrclk_ratios[i].ratio) 226 if (!wm8741->sysclk) {
227 dev_err(codec->dev,
228 "No MCLK configured, call set_sysclk() on init or in hw_params\n");
229 return -EINVAL;
230 }
231
232 /* Find a supported LRCLK rate */
233 for (i = 0; i < wm8741->sysclk_constraints->count; i++) {
234 if (wm8741->sysclk_constraints->list[i] == params_rate(params))
248 break; 235 break;
249 } 236 }
250 237
251 /* Should never happen, should be handled by constraints */ 238 if (i == wm8741->sysclk_constraints->count) {
252 if (i == ARRAY_SIZE(lrclk_ratios)) { 239 dev_err(codec->dev, "LRCLK %d unsupported with MCLK %d\n",
253 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n", 240 params_rate(params), wm8741->sysclk);
254 wm8741->sysclk / params_rate(params));
255 return -EINVAL; 241 return -EINVAL;
256 } 242 }
257 243
@@ -274,8 +260,8 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
274 return -EINVAL; 260 return -EINVAL;
275 } 261 }
276 262
277 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d", 263 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d, rate param = %d",
278 params_width(params)); 264 params_width(params), params_rate(params));
279 265
280 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface); 266 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
281 return 0; 267 return 0;
@@ -290,6 +276,11 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
290 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); 276 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
291 277
292 switch (freq) { 278 switch (freq) {
279 case 0:
280 wm8741->sysclk_constraints = NULL;
281 wm8741->sysclk = freq;
282 return 0;
283
293 case 11289600: 284 case 11289600:
294 wm8741->sysclk_constraints = &constraints_11289; 285 wm8741->sysclk_constraints = &constraints_11289;
295 wm8741->sysclk = freq; 286 wm8741->sysclk = freq;
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 761418f05d59..94c5c4681ce5 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -247,7 +247,7 @@ SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
247SOC_ENUM("ADC Polarity", wm8960_enum[0]), 247SOC_ENUM("ADC Polarity", wm8960_enum[0]),
248SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), 248SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
249 249
250SOC_ENUM("DAC Polarity", wm8960_enum[2]), 250SOC_ENUM("DAC Polarity", wm8960_enum[1]),
251SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, 251SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
252 wm8960_get_deemph, wm8960_put_deemph), 252 wm8960_get_deemph, wm8960_put_deemph),
253 253
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 687c4dd7ec99..505b65f5734f 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -1930,7 +1930,7 @@ static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
1930 dai->id + 1, freq); 1930 dai->id + 1, freq);
1931 break; 1931 break;
1932 case WM8995_SYSCLK_MCLK2: 1932 case WM8995_SYSCLK_MCLK2:
1933 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1; 1933 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK2;
1934 wm8995->mclk[1] = freq; 1934 wm8995->mclk[1] = freq;
1935 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", 1935 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
1936 dai->id + 1, freq); 1936 dai->id + 1, freq);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index b62ffd0c133e..f9f90b0f5db4 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include <linux/debugfs.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
@@ -248,6 +249,175 @@ struct wm_coeff_ctl {
248 unsigned int flags; 249 unsigned int flags;
249}; 250};
250 251
252#ifdef CONFIG_DEBUG_FS
253static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
254{
255 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
256
257 mutex_lock(&dsp->debugfs_lock);
258 kfree(dsp->wmfw_file_name);
259 dsp->wmfw_file_name = tmp;
260 mutex_unlock(&dsp->debugfs_lock);
261}
262
263static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
264{
265 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
266
267 mutex_lock(&dsp->debugfs_lock);
268 kfree(dsp->bin_file_name);
269 dsp->bin_file_name = tmp;
270 mutex_unlock(&dsp->debugfs_lock);
271}
272
273static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
274{
275 mutex_lock(&dsp->debugfs_lock);
276 kfree(dsp->wmfw_file_name);
277 kfree(dsp->bin_file_name);
278 dsp->wmfw_file_name = NULL;
279 dsp->bin_file_name = NULL;
280 mutex_unlock(&dsp->debugfs_lock);
281}
282
283static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
284 char __user *user_buf,
285 size_t count, loff_t *ppos)
286{
287 struct wm_adsp *dsp = file->private_data;
288 ssize_t ret;
289
290 mutex_lock(&dsp->debugfs_lock);
291
292 if (!dsp->wmfw_file_name || !dsp->running)
293 ret = 0;
294 else
295 ret = simple_read_from_buffer(user_buf, count, ppos,
296 dsp->wmfw_file_name,
297 strlen(dsp->wmfw_file_name));
298
299 mutex_unlock(&dsp->debugfs_lock);
300 return ret;
301}
302
303static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
304 char __user *user_buf,
305 size_t count, loff_t *ppos)
306{
307 struct wm_adsp *dsp = file->private_data;
308 ssize_t ret;
309
310 mutex_lock(&dsp->debugfs_lock);
311
312 if (!dsp->bin_file_name || !dsp->running)
313 ret = 0;
314 else
315 ret = simple_read_from_buffer(user_buf, count, ppos,
316 dsp->bin_file_name,
317 strlen(dsp->bin_file_name));
318
319 mutex_unlock(&dsp->debugfs_lock);
320 return ret;
321}
322
323static const struct {
324 const char *name;
325 const struct file_operations fops;
326} wm_adsp_debugfs_fops[] = {
327 {
328 .name = "wmfw_file_name",
329 .fops = {
330 .open = simple_open,
331 .read = wm_adsp_debugfs_wmfw_read,
332 },
333 },
334 {
335 .name = "bin_file_name",
336 .fops = {
337 .open = simple_open,
338 .read = wm_adsp_debugfs_bin_read,
339 },
340 },
341};
342
343static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
344 struct snd_soc_codec *codec)
345{
346 struct dentry *root = NULL;
347 char *root_name;
348 int i;
349
350 if (!codec->component.debugfs_root) {
351 adsp_err(dsp, "No codec debugfs root\n");
352 goto err;
353 }
354
355 root_name = kmalloc(PAGE_SIZE, GFP_KERNEL);
356 if (!root_name)
357 goto err;
358
359 snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
360 root = debugfs_create_dir(root_name, codec->component.debugfs_root);
361 kfree(root_name);
362
363 if (!root)
364 goto err;
365
366 if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running))
367 goto err;
368
369 if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id))
370 goto err;
371
372 if (!debugfs_create_x32("fw_version", S_IRUGO, root,
373 &dsp->fw_id_version))
374 goto err;
375
376 for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) {
377 if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name,
378 S_IRUGO, root, dsp,
379 &wm_adsp_debugfs_fops[i].fops))
380 goto err;
381 }
382
383 dsp->debugfs_root = root;
384 return;
385
386err:
387 debugfs_remove_recursive(root);
388 adsp_err(dsp, "Failed to create debugfs\n");
389}
390
391static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
392{
393 wm_adsp_debugfs_clear(dsp);
394 debugfs_remove_recursive(dsp->debugfs_root);
395}
396#else
397static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
398 struct snd_soc_codec *codec)
399{
400}
401
402static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
403{
404}
405
406static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp,
407 const char *s)
408{
409}
410
411static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp,
412 const char *s)
413{
414}
415
416static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
417{
418}
419#endif
420
251static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 421static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
252 struct snd_ctl_elem_value *ucontrol) 422 struct snd_ctl_elem_value *ucontrol)
253{ 423{
@@ -298,7 +468,6 @@ const struct snd_kcontrol_new wm_adsp1_fw_controls[] = {
298}; 468};
299EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); 469EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls);
300 470
301#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA)
302static const struct soc_enum wm_adsp2_rate_enum[] = { 471static const struct soc_enum wm_adsp2_rate_enum[] = {
303 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, 472 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
304 ARIZONA_DSP1_RATE_SHIFT, 0xf, 473 ARIZONA_DSP1_RATE_SHIFT, 0xf,
@@ -318,22 +487,28 @@ static const struct soc_enum wm_adsp2_rate_enum[] = {
318 arizona_rate_text, arizona_rate_val), 487 arizona_rate_text, arizona_rate_val),
319}; 488};
320 489
321const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { 490static const struct snd_kcontrol_new wm_adsp2_fw_controls[4][2] = {
322 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 491 {
323 wm_adsp_fw_get, wm_adsp_fw_put), 492 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
324 SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), 493 wm_adsp_fw_get, wm_adsp_fw_put),
325 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 494 SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]),
326 wm_adsp_fw_get, wm_adsp_fw_put), 495 },
327 SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), 496 {
328 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 497 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
329 wm_adsp_fw_get, wm_adsp_fw_put), 498 wm_adsp_fw_get, wm_adsp_fw_put),
330 SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), 499 SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]),
331 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 500 },
332 wm_adsp_fw_get, wm_adsp_fw_put), 501 {
333 SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), 502 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
503 wm_adsp_fw_get, wm_adsp_fw_put),
504 SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]),
505 },
506 {
507 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
508 wm_adsp_fw_get, wm_adsp_fw_put),
509 SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]),
510 },
334}; 511};
335EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls);
336#endif
337 512
338static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 513static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
339 int type) 514 int type)
@@ -1128,6 +1303,8 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1128 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 1303 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
1129 file, regions, pos - firmware->size); 1304 file, regions, pos - firmware->size);
1130 1305
1306 wm_adsp_debugfs_save_wmfwname(dsp, file);
1307
1131out_fw: 1308out_fw:
1132 regmap_async_complete(regmap); 1309 regmap_async_complete(regmap);
1133 wm_adsp_buf_free(&buf_list); 1310 wm_adsp_buf_free(&buf_list);
@@ -1345,11 +1522,12 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp)
1345 1522
1346 n_algs = be32_to_cpu(adsp2_id.n_algs); 1523 n_algs = be32_to_cpu(adsp2_id.n_algs);
1347 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); 1524 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id);
1525 dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver);
1348 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 1526 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
1349 dsp->fw_id, 1527 dsp->fw_id,
1350 (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, 1528 (dsp->fw_id_version & 0xff0000) >> 16,
1351 (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, 1529 (dsp->fw_id_version & 0xff00) >> 8,
1352 be32_to_cpu(adsp2_id.fw.ver) & 0xff, 1530 dsp->fw_id_version & 0xff,
1353 n_algs); 1531 n_algs);
1354 1532
1355 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, 1533 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM,
@@ -1625,6 +1803,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1625 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 1803 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
1626 file, blocks, pos - firmware->size); 1804 file, blocks, pos - firmware->size);
1627 1805
1806 wm_adsp_debugfs_save_binname(dsp, file);
1807
1628out_fw: 1808out_fw:
1629 regmap_async_complete(regmap); 1809 regmap_async_complete(regmap);
1630 release_firmware(firmware); 1810 release_firmware(firmware);
@@ -1638,6 +1818,9 @@ int wm_adsp1_init(struct wm_adsp *dsp)
1638{ 1818{
1639 INIT_LIST_HEAD(&dsp->alg_regions); 1819 INIT_LIST_HEAD(&dsp->alg_regions);
1640 1820
1821#ifdef CONFIG_DEBUG_FS
1822 mutex_init(&dsp->debugfs_lock);
1823#endif
1641 return 0; 1824 return 0;
1642} 1825}
1643EXPORT_SYMBOL_GPL(wm_adsp1_init); 1826EXPORT_SYMBOL_GPL(wm_adsp1_init);
@@ -1896,6 +2079,10 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1896 /* Log firmware state, it can be useful for analysis */ 2079 /* Log firmware state, it can be useful for analysis */
1897 wm_adsp2_show_fw_status(dsp); 2080 wm_adsp2_show_fw_status(dsp);
1898 2081
2082 wm_adsp_debugfs_clear(dsp);
2083
2084 dsp->fw_id = 0;
2085 dsp->fw_id_version = 0;
1899 dsp->running = false; 2086 dsp->running = false;
1900 2087
1901 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2088 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
@@ -1933,6 +2120,24 @@ err:
1933} 2120}
1934EXPORT_SYMBOL_GPL(wm_adsp2_event); 2121EXPORT_SYMBOL_GPL(wm_adsp2_event);
1935 2122
2123int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
2124{
2125 wm_adsp2_init_debugfs(dsp, codec);
2126
2127 return snd_soc_add_codec_controls(codec,
2128 wm_adsp2_fw_controls[dsp->num - 1],
2129 ARRAY_SIZE(wm_adsp2_fw_controls[0]));
2130}
2131EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe);
2132
2133int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec)
2134{
2135 wm_adsp2_cleanup_debugfs(dsp);
2136
2137 return 0;
2138}
2139EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove);
2140
1936int wm_adsp2_init(struct wm_adsp *dsp) 2141int wm_adsp2_init(struct wm_adsp *dsp)
1937{ 2142{
1938 int ret; 2143 int ret;
@@ -1952,6 +2157,9 @@ int wm_adsp2_init(struct wm_adsp *dsp)
1952 INIT_LIST_HEAD(&dsp->ctl_list); 2157 INIT_LIST_HEAD(&dsp->ctl_list);
1953 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2158 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
1954 2159
2160#ifdef CONFIG_DEBUG_FS
2161 mutex_init(&dsp->debugfs_lock);
2162#endif
1955 return 0; 2163 return 0;
1956} 2164}
1957EXPORT_SYMBOL_GPL(wm_adsp2_init); 2165EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 0e5f07c35d50..5042cbd39e54 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -46,17 +46,26 @@ struct wm_adsp {
46 struct list_head alg_regions; 46 struct list_head alg_regions;
47 47
48 int fw_id; 48 int fw_id;
49 int fw_id_version;
49 50
50 const struct wm_adsp_region *mem; 51 const struct wm_adsp_region *mem;
51 int num_mems; 52 int num_mems;
52 53
53 int fw; 54 int fw;
54 int fw_ver; 55 int fw_ver;
55 bool running; 56 u32 running;
56 57
57 struct list_head ctl_list; 58 struct list_head ctl_list;
58 59
59 struct work_struct boot_work; 60 struct work_struct boot_work;
61
62#ifdef CONFIG_DEBUG_FS
63 struct dentry *debugfs_root;
64 struct mutex debugfs_lock;
65 char *wmfw_file_name;
66 char *bin_file_name;
67#endif
68
60}; 69};
61 70
62#define WM_ADSP1(wname, num) \ 71#define WM_ADSP1(wname, num) \
@@ -75,10 +84,11 @@ struct wm_adsp {
75 WM_ADSP2_E(wname, num, wm_adsp2_early_event) 84 WM_ADSP2_E(wname, num, wm_adsp2_early_event)
76 85
77extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; 86extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
78extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
79 87
80int wm_adsp1_init(struct wm_adsp *dsp); 88int wm_adsp1_init(struct wm_adsp *dsp);
81int wm_adsp2_init(struct wm_adsp *dsp); 89int wm_adsp2_init(struct wm_adsp *dsp);
90int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec);
91int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec);
82int wm_adsp1_event(struct snd_soc_dapm_widget *w, 92int wm_adsp1_event(struct snd_soc_dapm_widget *w,
83 struct snd_kcontrol *kcontrol, int event); 93 struct snd_kcontrol *kcontrol, int event);
84int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 94int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index d79349434a9a..b960e626dad9 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -686,6 +686,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
686 if (mcasp->serial_dir[i] == TX_MODE && 686 if (mcasp->serial_dir[i] == TX_MODE &&
687 tx_ser < max_active_serializers) { 687 tx_ser < max_active_serializers) {
688 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); 688 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i));
689 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
690 DISMOD_LOW, DISMOD_MASK);
689 tx_ser++; 691 tx_ser++;
690 } else if (mcasp->serial_dir[i] == RX_MODE && 692 } else if (mcasp->serial_dir[i] == RX_MODE &&
691 rx_ser < max_active_serializers) { 693 rx_ser < max_active_serializers) {
@@ -1565,6 +1567,49 @@ static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)
1565 return ret; 1567 return ret;
1566} 1568}
1567 1569
1570enum {
1571 PCM_EDMA,
1572 PCM_SDMA,
1573};
1574static const char *sdma_prefix = "ti,omap";
1575
1576static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
1577{
1578 struct dma_chan *chan;
1579 const char *tmp;
1580 int ret = PCM_EDMA;
1581
1582 if (!mcasp->dev->of_node)
1583 return PCM_EDMA;
1584
1585 tmp = mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
1586 chan = dma_request_slave_channel_reason(mcasp->dev, tmp);
1587 if (IS_ERR(chan)) {
1588 if (PTR_ERR(chan) != -EPROBE_DEFER)
1589 dev_err(mcasp->dev,
1590 "Can't verify DMA configuration (%ld)\n",
1591 PTR_ERR(chan));
1592 return PTR_ERR(chan);
1593 }
1594 BUG_ON(!chan->device || !chan->device->dev);
1595
1596 if (chan->device->dev->of_node)
1597 ret = of_property_read_string(chan->device->dev->of_node,
1598 "compatible", &tmp);
1599 else
1600 dev_dbg(mcasp->dev, "DMA controller has no of-node\n");
1601
1602 dma_release_channel(chan);
1603 if (ret)
1604 return ret;
1605
1606 dev_dbg(mcasp->dev, "DMA controller compatible = \"%s\"\n", tmp);
1607 if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
1608 return PCM_SDMA;
1609
1610 return PCM_EDMA;
1611}
1612
1568static int davinci_mcasp_probe(struct platform_device *pdev) 1613static int davinci_mcasp_probe(struct platform_device *pdev)
1569{ 1614{
1570 struct snd_dmaengine_dai_dma_data *dma_data; 1615 struct snd_dmaengine_dai_dma_data *dma_data;
@@ -1763,27 +1808,34 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1763 if (ret != 0) 1808 if (ret != 0)
1764 goto err; 1809 goto err;
1765 1810
1766 switch (mcasp->version) { 1811 ret = davinci_mcasp_get_dma_type(mcasp);
1812 switch (ret) {
1813 case PCM_EDMA:
1767#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ 1814#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
1768 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 1815 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1769 IS_MODULE(CONFIG_SND_EDMA_SOC)) 1816 IS_MODULE(CONFIG_SND_EDMA_SOC))
1770 case MCASP_VERSION_1:
1771 case MCASP_VERSION_2:
1772 case MCASP_VERSION_3:
1773 ret = edma_pcm_platform_register(&pdev->dev); 1817 ret = edma_pcm_platform_register(&pdev->dev);
1774 break; 1818#else
1819 dev_err(&pdev->dev, "Missing SND_EDMA_SOC\n");
1820 ret = -EINVAL;
1821 goto err;
1775#endif 1822#endif
1823 break;
1824 case PCM_SDMA:
1776#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ 1825#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
1777 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 1826 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1778 IS_MODULE(CONFIG_SND_OMAP_SOC)) 1827 IS_MODULE(CONFIG_SND_OMAP_SOC))
1779 case MCASP_VERSION_4:
1780 ret = omap_pcm_platform_register(&pdev->dev); 1828 ret = omap_pcm_platform_register(&pdev->dev);
1781 break; 1829#else
1830 dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n");
1831 ret = -EINVAL;
1832 goto err;
1782#endif 1833#endif
1834 break;
1783 default: 1835 default:
1784 dev_err(&pdev->dev, "Invalid McASP version: %d\n", 1836 dev_err(&pdev->dev, "No DMA controller found (%d)\n", ret);
1785 mcasp->version); 1837 case -EPROBE_DEFER:
1786 ret = -EINVAL; 1838 goto err;
1787 break; 1839 break;
1788 } 1840 }
1789 1841
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 79dc511180bf..a3be108a8c17 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -215,7 +215,10 @@
215 * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits 215 * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
216 */ 216 */
217#define MODE(val) (val) 217#define MODE(val) (val)
218#define DISMOD (val)(val<<2) 218#define DISMOD_3STATE (0x0)
219#define DISMOD_LOW (0x2 << 2)
220#define DISMOD_HIGH (0x3 << 2)
221#define DISMOD_MASK DISMOD_HIGH
219#define TXSTATE BIT(4) 222#define TXSTATE BIT(4)
220#define RXSTATE BIT(5) 223#define RXSTATE BIT(5)
221#define SRMOD_MASK 3 224#define SRMOD_MASK 3
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index cd146d4fa805..b38b98cae855 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -190,7 +190,7 @@ static int imx_wm8962_probe(struct platform_device *pdev)
190 dev_err(&pdev->dev, "audmux internal port setup failed\n"); 190 dev_err(&pdev->dev, "audmux internal port setup failed\n");
191 return ret; 191 return ret;
192 } 192 }
193 imx_audmux_v2_configure_port(ext_port, 193 ret = imx_audmux_v2_configure_port(ext_port,
194 IMX_AUDMUX_V2_PTCR_SYN, 194 IMX_AUDMUX_V2_PTCR_SYN,
195 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 195 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
196 if (ret) { 196 if (ret) {
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index c87e58504a62..d5554939146e 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -26,6 +26,7 @@ struct simple_card_data {
26 struct simple_dai_props { 26 struct simple_dai_props {
27 struct asoc_simple_dai cpu_dai; 27 struct asoc_simple_dai cpu_dai;
28 struct asoc_simple_dai codec_dai; 28 struct asoc_simple_dai codec_dai;
29 unsigned int mclk_fs;
29 } *dai_props; 30 } *dai_props;
30 unsigned int mclk_fs; 31 unsigned int mclk_fs;
31 int gpio_hp_det; 32 int gpio_hp_det;
@@ -76,11 +77,18 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
76 struct snd_soc_pcm_runtime *rtd = substream->private_data; 77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
77 struct snd_soc_dai *codec_dai = rtd->codec_dai; 78 struct snd_soc_dai *codec_dai = rtd->codec_dai;
78 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 79 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
79 unsigned int mclk; 80 struct simple_dai_props *dai_props =
81 &priv->dai_props[rtd - rtd->card->rtd];
82 unsigned int mclk, mclk_fs = 0;
80 int ret = 0; 83 int ret = 0;
81 84
82 if (priv->mclk_fs) { 85 if (priv->mclk_fs)
83 mclk = params_rate(params) * priv->mclk_fs; 86 mclk_fs = priv->mclk_fs;
87 else if (dai_props->mclk_fs)
88 mclk_fs = dai_props->mclk_fs;
89
90 if (mclk_fs) {
91 mclk = params_rate(params) * mclk_fs;
84 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 92 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
85 SND_SOC_CLOCK_IN); 93 SND_SOC_CLOCK_IN);
86 } 94 }
@@ -313,6 +321,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
313 char prop[128]; 321 char prop[128];
314 char *prefix = ""; 322 char *prefix = "";
315 int ret, cpu_args; 323 int ret, cpu_args;
324 u32 val;
316 325
317 /* For single DAI link & old style of DT node */ 326 /* For single DAI link & old style of DT node */
318 if (is_top_level_node) 327 if (is_top_level_node)
@@ -338,6 +347,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
338 if (ret < 0) 347 if (ret < 0)
339 goto dai_link_of_err; 348 goto dai_link_of_err;
340 349
350 if (!of_property_read_u32(node, "mclk-fs", &val))
351 dai_props->mclk_fs = val;
352
341 ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, 353 ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai,
342 &dai_link->cpu_of_node, 354 &dai_link->cpu_of_node,
343 &dai_link->cpu_dai_name, 355 &dai_link->cpu_dai_name,
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 791953ffbc41..f3060a4ca040 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -112,7 +112,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
112 112
113config SND_SOC_INTEL_CHT_BSW_RT5645_MACH 113config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
114 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" 114 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
115 depends on X86_INTEL_LPSS 115 depends on X86_INTEL_LPSS && I2C
116 select SND_SOC_RT5645 116 select SND_SOC_RT5645
117 select SND_SST_MFLD_PLATFORM 117 select SND_SST_MFLD_PLATFORM
118 select SND_SST_IPC_ACPI 118 select SND_SST_IPC_ACPI
@@ -123,7 +123,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
123 123
124config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH 124config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
125 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" 125 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec"
126 depends on X86_INTEL_LPSS 126 depends on X86_INTEL_LPSS && I2C
127 select SND_SOC_MAX98090 127 select SND_SOC_MAX98090
128 select SND_SOC_TS3A227E 128 select SND_SOC_TS3A227E
129 select SND_SST_MFLD_PLATFORM 129 select SND_SST_MFLD_PLATFORM
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 61e240935451..31e9b9ecbb8a 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -1401,36 +1401,32 @@ static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w,
1401 down_read(&card->controls_rwsem); 1401 down_read(&card->controls_rwsem);
1402 1402
1403 list_for_each_entry(kctl, &card->controls, list) { 1403 list_for_each_entry(kctl, &card->controls, list) {
1404 idx = strstr(kctl->id.name, " "); 1404 idx = strchr(kctl->id.name, ' ');
1405 if (idx == NULL) 1405 if (idx == NULL)
1406 continue; 1406 continue;
1407 index = strlen(kctl->id.name) - strlen(idx); 1407 index = idx - (char*)kctl->id.name;
1408 if (strncmp(kctl->id.name, w->name, index))
1409 continue;
1408 1410
1409 if (strstr(kctl->id.name, "Volume") && 1411 if (strstr(kctl->id.name, "Volume"))
1410 !strncmp(kctl->id.name, w->name, index))
1411 ret = sst_fill_module_list(kctl, w, SST_MODULE_GAIN); 1412 ret = sst_fill_module_list(kctl, w, SST_MODULE_GAIN);
1412 1413
1413 else if (strstr(kctl->id.name, "params") && 1414 else if (strstr(kctl->id.name, "params"))
1414 !strncmp(kctl->id.name, w->name, index))
1415 ret = sst_fill_module_list(kctl, w, SST_MODULE_ALGO); 1415 ret = sst_fill_module_list(kctl, w, SST_MODULE_ALGO);
1416 1416
1417 else if (strstr(kctl->id.name, "Switch") && 1417 else if (strstr(kctl->id.name, "Switch") &&
1418 !strncmp(kctl->id.name, w->name, index) &&
1419 strstr(kctl->id.name, "Gain")) { 1418 strstr(kctl->id.name, "Gain")) {
1420 struct sst_gain_mixer_control *mc = 1419 struct sst_gain_mixer_control *mc =
1421 (void *)kctl->private_value; 1420 (void *)kctl->private_value;
1422 1421
1423 mc->w = w; 1422 mc->w = w;
1424 1423
1425 } else if (strstr(kctl->id.name, "interleaver") && 1424 } else if (strstr(kctl->id.name, "interleaver")) {
1426 !strncmp(kctl->id.name, w->name, index)) {
1427 struct sst_enum *e = (void *)kctl->private_value; 1425 struct sst_enum *e = (void *)kctl->private_value;
1428 1426
1429 e->w = w; 1427 e->w = w;
1430 1428
1431 } else if (strstr(kctl->id.name, "deinterleaver") && 1429 } else if (strstr(kctl->id.name, "deinterleaver")) {
1432 !strncmp(kctl->id.name, w->name, index)) {
1433
1434 struct sst_enum *e = (void *)kctl->private_value; 1430 struct sst_enum *e = (void *)kctl->private_value;
1435 1431
1436 e->w = w; 1432 e->w = w;
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index 96c2e420cce6..a4b458e77089 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -368,8 +368,8 @@ static inline void sst_restore_shim64(struct intel_sst_drv *ctx,
368 * initialize by FW or driver when firmware is loaded 368 * initialize by FW or driver when firmware is loaded
369 */ 369 */
370 spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); 370 spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags);
371 sst_shim_write64(shim, SST_IMRX, shim_regs->imrx), 371 sst_shim_write64(shim, SST_IMRX, shim_regs->imrx);
372 sst_shim_write64(shim, SST_CSR, shim_regs->csr), 372 sst_shim_write64(shim, SST_CSR, shim_regs->csr);
373 spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); 373 spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags);
374} 374}
375 375
diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index 7b50a9d17ec1..620da1d1b9e3 100644
--- a/sound/soc/intel/atom/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -533,7 +533,7 @@ static inline int sst_calc_tstamp(struct intel_sst_drv *ctx,
533 533
534 info->buffer_ptr = pointer_samples / substream->runtime->channels; 534 info->buffer_ptr = pointer_samples / substream->runtime->channels;
535 535
536 info->pcm_delay = delay_frames / substream->runtime->channels; 536 info->pcm_delay = delay_frames;
537 dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", 537 dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n",
538 info->buffer_ptr, info->pcm_delay); 538 info->buffer_ptr, info->pcm_delay);
539 return 0; 539 return 0;
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 1be079423d1e..d604ee80eda4 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -101,6 +101,33 @@ static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
101 return 0; 101 return 0;
102} 102}
103 103
104static int cht_ti_jack_event(struct notifier_block *nb,
105 unsigned long event, void *data)
106{
107
108 struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
109 struct snd_soc_dai *codec_dai = jack->card->rtd->codec_dai;
110 struct snd_soc_codec *codec = codec_dai->codec;
111
112 if (event & SND_JACK_MICROPHONE) {
113
114 snd_soc_dapm_force_enable_pin(&codec->dapm, "SHDN");
115 snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS");
116 snd_soc_dapm_sync(&codec->dapm);
117 } else {
118
119 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS");
120 snd_soc_dapm_disable_pin(&codec->dapm, "SHDN");
121 snd_soc_dapm_sync(&codec->dapm);
122 }
123
124 return 0;
125}
126
127static struct notifier_block cht_jack_nb = {
128 .notifier_call = cht_ti_jack_event,
129};
130
104static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) 131static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
105{ 132{
106 int ret; 133 int ret;
@@ -130,6 +157,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
130 return ret; 157 return ret;
131 } 158 }
132 159
160 if (ctx->ts3a227e_present)
161 snd_soc_jack_notifier_register(jack, &cht_jack_nb);
162
133 return ret; 163 return ret;
134} 164}
135 165
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 42f293f9c6e2..67b6d3d52f57 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -263,7 +263,7 @@ static struct sst_acpi_desc sst_acpi_baytrail_desc = {
263 .resindex_dma_base = -1, 263 .resindex_dma_base = -1,
264}; 264};
265 265
266static struct acpi_device_id sst_acpi_match[] = { 266static const struct acpi_device_id sst_acpi_match[] = {
267 { "INT33C8", (unsigned long)&sst_acpi_haswell_desc }, 267 { "INT33C8", (unsigned long)&sst_acpi_haswell_desc },
268 { "INT3438", (unsigned long)&sst_acpi_broadwell_desc }, 268 { "INT3438", (unsigned long)&sst_acpi_broadwell_desc },
269 { "80860F28", (unsigned long)&sst_acpi_baytrail_desc }, 269 { "80860F28", (unsigned long)&sst_acpi_baytrail_desc },
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
new file mode 100644
index 000000000000..15c04e2eae34
--- /dev/null
+++ b/sound/soc/mediatek/Kconfig
@@ -0,0 +1,30 @@
1config SND_SOC_MEDIATEK
2 tristate "ASoC support for Mediatek chip"
3 depends on ARCH_MEDIATEK
4 help
5 This adds ASoC platform driver support for Mediatek chip
6 that can be used with other codecs.
7 Select Y if you have such device.
8 Ex: MT8173
9
10config SND_SOC_MT8173_MAX98090
11 tristate "ASoC Audio driver for MT8173 with MAX98090 codec"
12 depends on SND_SOC_MEDIATEK
13 select SND_SOC_MAX98090
14 help
15 This adds ASoC driver for Mediatek MT8173 boards
16 with the MAX98090 audio codec.
17 Select Y if you have such device.
18 If unsure select "N".
19
20config SND_SOC_MT8173_RT5650_RT5676
21 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
22 depends on SND_SOC_MEDIATEK
23 select SND_SOC_RT5645
24 select SND_SOC_RT5677
25 help
26 This adds ASoC driver for Mediatek MT8173 boards
27 with the RT5650 and RT5676 codecs.
28 Select Y if you have such device.
29 If unsure select "N".
30
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
new file mode 100644
index 000000000000..75effbec438d
--- /dev/null
+++ b/sound/soc/mediatek/Makefile
@@ -0,0 +1,5 @@
1# MTK Platform Support
2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o
3# Machine support
4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c
new file mode 100644
index 000000000000..4d44b5803e55
--- /dev/null
+++ b/sound/soc/mediatek/mt8173-max98090.c
@@ -0,0 +1,213 @@
1/*
2 * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <sound/soc.h>
19#include <sound/jack.h>
20#include <linux/gpio.h>
21#include "../codecs/max98090.h"
22
23static struct snd_soc_jack mt8173_max98090_jack;
24
25static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = {
26 {
27 .pin = "Headphone",
28 .mask = SND_JACK_HEADPHONE,
29 },
30 {
31 .pin = "Headset Mic",
32 .mask = SND_JACK_MICROPHONE,
33 },
34};
35
36static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = {
37 SND_SOC_DAPM_SPK("Speaker", NULL),
38 SND_SOC_DAPM_MIC("Int Mic", NULL),
39 SND_SOC_DAPM_HP("Headphone", NULL),
40 SND_SOC_DAPM_MIC("Headset Mic", NULL),
41};
42
43static const struct snd_soc_dapm_route mt8173_max98090_routes[] = {
44 {"Speaker", NULL, "SPKL"},
45 {"Speaker", NULL, "SPKR"},
46 {"DMICL", NULL, "Int Mic"},
47 {"Headphone", NULL, "HPL"},
48 {"Headphone", NULL, "HPR"},
49 {"Headset Mic", NULL, "MICBIAS"},
50 {"IN34", NULL, "Headset Mic"},
51};
52
53static const struct snd_kcontrol_new mt8173_max98090_controls[] = {
54 SOC_DAPM_PIN_SWITCH("Speaker"),
55 SOC_DAPM_PIN_SWITCH("Int Mic"),
56 SOC_DAPM_PIN_SWITCH("Headphone"),
57 SOC_DAPM_PIN_SWITCH("Headset Mic"),
58};
59
60static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params)
62{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct snd_soc_dai *codec_dai = rtd->codec_dai;
65
66 return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256,
67 SND_SOC_CLOCK_IN);
68}
69
70static struct snd_soc_ops mt8173_max98090_ops = {
71 .hw_params = mt8173_max98090_hw_params,
72};
73
74static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
75{
76 int ret;
77 struct snd_soc_card *card = runtime->card;
78 struct snd_soc_codec *codec = runtime->codec;
79
80 /* enable jack detection */
81 ret = snd_soc_card_jack_new(card, "Headphone", SND_JACK_HEADPHONE,
82 &mt8173_max98090_jack, NULL, 0);
83 if (ret) {
84 dev_err(card->dev, "Can't snd_soc_jack_new %d\n", ret);
85 return ret;
86 }
87
88 ret = snd_soc_jack_add_pins(&mt8173_max98090_jack,
89 ARRAY_SIZE(mt8173_max98090_jack_pins),
90 mt8173_max98090_jack_pins);
91 if (ret) {
92 dev_err(card->dev, "Can't snd_soc_jack_add_pins %d\n", ret);
93 return ret;
94 }
95
96 return max98090_mic_detect(codec, &mt8173_max98090_jack);
97}
98
99/* Digital audio interface glue - connects codec <---> CPU */
100static struct snd_soc_dai_link mt8173_max98090_dais[] = {
101 /* Front End DAI links */
102 {
103 .name = "MAX98090 Playback",
104 .stream_name = "MAX98090 Playback",
105 .cpu_dai_name = "DL1",
106 .platform_name = "11220000.mt8173-afe-pcm",
107 .codec_name = "snd-soc-dummy",
108 .codec_dai_name = "snd-soc-dummy-dai",
109 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
110 .dynamic = 1,
111 .dpcm_playback = 1,
112 },
113 {
114 .name = "MAX98090 Capture",
115 .stream_name = "MAX98090 Capture",
116 .cpu_dai_name = "VUL",
117 .platform_name = "11220000.mt8173-afe-pcm",
118 .codec_name = "snd-soc-dummy",
119 .codec_dai_name = "snd-soc-dummy-dai",
120 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
121 .dynamic = 1,
122 .dpcm_capture = 1,
123 },
124 /* Back End DAI links */
125 {
126 .name = "Codec",
127 .cpu_dai_name = "I2S",
128 .platform_name = "11220000.mt8173-afe-pcm",
129 .no_pcm = 1,
130 .codec_dai_name = "HiFi",
131 .init = mt8173_max98090_init,
132 .ops = &mt8173_max98090_ops,
133 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
134 SND_SOC_DAIFMT_CBS_CFS,
135 .dpcm_playback = 1,
136 .dpcm_capture = 1,
137 },
138};
139
140static struct snd_soc_card mt8173_max98090_card = {
141 .name = "mt8173-max98090",
142 .dai_link = mt8173_max98090_dais,
143 .num_links = ARRAY_SIZE(mt8173_max98090_dais),
144 .controls = mt8173_max98090_controls,
145 .num_controls = ARRAY_SIZE(mt8173_max98090_controls),
146 .dapm_widgets = mt8173_max98090_widgets,
147 .num_dapm_widgets = ARRAY_SIZE(mt8173_max98090_widgets),
148 .dapm_routes = mt8173_max98090_routes,
149 .num_dapm_routes = ARRAY_SIZE(mt8173_max98090_routes),
150};
151
152static int mt8173_max98090_dev_probe(struct platform_device *pdev)
153{
154 struct snd_soc_card *card = &mt8173_max98090_card;
155 struct device_node *codec_node;
156 int ret, i;
157
158 codec_node = of_parse_phandle(pdev->dev.of_node,
159 "mediatek,audio-codec", 0);
160 if (!codec_node) {
161 dev_err(&pdev->dev,
162 "Property 'audio-codec' missing or invalid\n");
163 return -EINVAL;
164 }
165 for (i = 0; i < card->num_links; i++) {
166 if (mt8173_max98090_dais[i].codec_name)
167 continue;
168 mt8173_max98090_dais[i].codec_of_node = codec_node;
169 }
170 card->dev = &pdev->dev;
171
172 ret = snd_soc_register_card(card);
173 if (ret)
174 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
175 __func__, ret);
176 return ret;
177}
178
179static int mt8173_max98090_dev_remove(struct platform_device *pdev)
180{
181 struct snd_soc_card *card = platform_get_drvdata(pdev);
182
183 snd_soc_unregister_card(card);
184 return 0;
185}
186
187static const struct of_device_id mt8173_max98090_dt_match[] = {
188 { .compatible = "mediatek,mt8173-max98090", },
189 { }
190};
191MODULE_DEVICE_TABLE(of, mt8173_max98090_dt_match);
192
193static struct platform_driver mt8173_max98090_driver = {
194 .driver = {
195 .name = "mt8173-max98090",
196 .owner = THIS_MODULE,
197 .of_match_table = mt8173_max98090_dt_match,
198#ifdef CONFIG_PM
199 .pm = &snd_soc_pm_ops,
200#endif
201 },
202 .probe = mt8173_max98090_dev_probe,
203 .remove = mt8173_max98090_dev_remove,
204};
205
206module_platform_driver(mt8173_max98090_driver);
207
208/* Module information */
209MODULE_DESCRIPTION("MT8173 MAX98090 ALSA SoC machine driver");
210MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
211MODULE_LICENSE("GPL v2");
212MODULE_ALIAS("platform:mt8173-max98090");
213
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
new file mode 100644
index 000000000000..094055323059
--- /dev/null
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -0,0 +1,278 @@
1/*
2 * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22#include "../codecs/rt5645.h"
23#include "../codecs/rt5677.h"
24
25#define MCLK_FOR_CODECS 12288000
26
27static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = {
28 SND_SOC_DAPM_SPK("Speaker", NULL),
29 SND_SOC_DAPM_MIC("Int Mic", NULL),
30 SND_SOC_DAPM_HP("Headphone", NULL),
31 SND_SOC_DAPM_MIC("Headset Mic", NULL),
32};
33
34static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = {
35 {"Speaker", NULL, "SPOL"},
36 {"Speaker", NULL, "SPOR"},
37 {"Speaker", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */
38 {"Sub DMIC L1", NULL, "Int Mic"}, /* DMIC from 5676 */
39 {"Sub DMIC R1", NULL, "Int Mic"},
40 {"Headphone", NULL, "HPOL"},
41 {"Headphone", NULL, "HPOR"},
42 {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */
43 {"Headset Mic", NULL, "micbias1"},
44 {"Headset Mic", NULL, "micbias2"},
45 {"IN1P", NULL, "Headset Mic"},
46 {"IN1N", NULL, "Headset Mic"},
47 {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */
48};
49
50static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = {
51 SOC_DAPM_PIN_SWITCH("Speaker"),
52 SOC_DAPM_PIN_SWITCH("Int Mic"),
53 SOC_DAPM_PIN_SWITCH("Headphone"),
54 SOC_DAPM_PIN_SWITCH("Headset Mic"),
55};
56
57static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params)
59{
60 struct snd_soc_pcm_runtime *rtd = substream->private_data;
61 int i, ret;
62
63 for (i = 0; i < rtd->num_codecs; i++) {
64 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
65
66 /* pll from mclk 12.288M */
67 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
68 params_rate(params) * 512);
69 if (ret)
70 return ret;
71
72 /* sysclk from pll */
73 ret = snd_soc_dai_set_sysclk(codec_dai, 1,
74 params_rate(params) * 512,
75 SND_SOC_CLOCK_IN);
76 if (ret)
77 return ret;
78 }
79 return 0;
80}
81
82static struct snd_soc_ops mt8173_rt5650_rt5676_ops = {
83 .hw_params = mt8173_rt5650_rt5676_hw_params,
84};
85
86static struct snd_soc_jack mt8173_rt5650_rt5676_jack;
87
88static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime)
89{
90 struct snd_soc_card *card = runtime->card;
91 struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
92 struct snd_soc_codec *codec_sub = runtime->codec_dais[1]->codec;
93 int ret;
94
95 rt5645_sel_asrc_clk_src(codec,
96 RT5645_DA_STEREO_FILTER |
97 RT5645_AD_STEREO_FILTER,
98 RT5645_CLK_SEL_I2S1_ASRC);
99 rt5677_sel_asrc_clk_src(codec_sub,
100 RT5677_DA_STEREO_FILTER |
101 RT5677_AD_STEREO1_FILTER,
102 RT5677_CLK_SEL_I2S1_ASRC);
103 rt5677_sel_asrc_clk_src(codec_sub,
104 RT5677_AD_STEREO2_FILTER |
105 RT5677_I2S2_SOURCE,
106 RT5677_CLK_SEL_I2S2_ASRC);
107
108 /* enable jack detection */
109 ret = snd_soc_card_jack_new(card, "Headset Jack",
110 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
111 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
112 SND_JACK_BTN_2 | SND_JACK_BTN_3,
113 &mt8173_rt5650_rt5676_jack, NULL, 0);
114 if (ret) {
115 dev_err(card->dev, "Can't new Headset Jack %d\n", ret);
116 return ret;
117 }
118
119 return rt5645_set_jack_detect(codec,
120 &mt8173_rt5650_rt5676_jack,
121 &mt8173_rt5650_rt5676_jack,
122 &mt8173_rt5650_rt5676_jack);
123}
124
125static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = {
126 {
127 .dai_name = "rt5645-aif1",
128 },
129 {
130 .dai_name = "rt5677-aif1",
131 },
132};
133
134/* Digital audio interface glue - connects codec <---> CPU */
135static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
136 /* Front End DAI links */
137 {
138 .name = "rt5650_rt5676 Playback",
139 .stream_name = "rt5650_rt5676 Playback",
140 .cpu_dai_name = "DL1",
141 .platform_name = "11220000.mt8173-afe-pcm",
142 .codec_name = "snd-soc-dummy",
143 .codec_dai_name = "snd-soc-dummy-dai",
144 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
145 .dynamic = 1,
146 .dpcm_playback = 1,
147 },
148 {
149 .name = "rt5650_rt5676 Capture",
150 .stream_name = "rt5650_rt5676 Capture",
151 .cpu_dai_name = "VUL",
152 .platform_name = "11220000.mt8173-afe-pcm",
153 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai",
155 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
156 .dynamic = 1,
157 .dpcm_capture = 1,
158 },
159
160 /* Back End DAI links */
161 {
162 .name = "Codec",
163 .cpu_dai_name = "I2S",
164 .platform_name = "11220000.mt8173-afe-pcm",
165 .no_pcm = 1,
166 .codecs = mt8173_rt5650_rt5676_codecs,
167 .num_codecs = 2,
168 .init = mt8173_rt5650_rt5676_init,
169 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
170 SND_SOC_DAIFMT_CBS_CFS,
171 .ops = &mt8173_rt5650_rt5676_ops,
172 .ignore_pmdown_time = 1,
173 .dpcm_playback = 1,
174 .dpcm_capture = 1,
175 },
176 { /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
177 .name = "rt5650_rt5676 intercodec",
178 .stream_name = "rt5650_rt5676 intercodec",
179 .cpu_dai_name = "snd-soc-dummy-dai",
180 .platform_name = "snd-soc-dummy",
181 .no_pcm = 1,
182 .codec_dai_name = "rt5677-aif2",
183 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
184 SND_SOC_DAIFMT_CBM_CFM,
185 },
186
187};
188
189static struct snd_soc_codec_conf mt8173_rt5650_rt5676_codec_conf[] = {
190 {
191 .name_prefix = "Sub",
192 },
193};
194
195static struct snd_soc_card mt8173_rt5650_rt5676_card = {
196 .name = "mtk-rt5650-rt5676",
197 .dai_link = mt8173_rt5650_rt5676_dais,
198 .num_links = ARRAY_SIZE(mt8173_rt5650_rt5676_dais),
199 .codec_conf = mt8173_rt5650_rt5676_codec_conf,
200 .num_configs = ARRAY_SIZE(mt8173_rt5650_rt5676_codec_conf),
201 .controls = mt8173_rt5650_rt5676_controls,
202 .num_controls = ARRAY_SIZE(mt8173_rt5650_rt5676_controls),
203 .dapm_widgets = mt8173_rt5650_rt5676_widgets,
204 .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_rt5676_widgets),
205 .dapm_routes = mt8173_rt5650_rt5676_routes,
206 .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_rt5676_routes),
207};
208
209static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
210{
211 struct snd_soc_card *card = &mt8173_rt5650_rt5676_card;
212 int ret;
213
214 mt8173_rt5650_rt5676_codecs[0].of_node =
215 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
216 if (!mt8173_rt5650_rt5676_codecs[0].of_node) {
217 dev_err(&pdev->dev,
218 "Property 'audio-codec' missing or invalid\n");
219 return -EINVAL;
220 }
221 mt8173_rt5650_rt5676_codecs[1].of_node =
222 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
223 if (!mt8173_rt5650_rt5676_codecs[1].of_node) {
224 dev_err(&pdev->dev,
225 "Property 'audio-codec' missing or invalid\n");
226 return -EINVAL;
227 }
228 mt8173_rt5650_rt5676_codec_conf[0].of_node =
229 mt8173_rt5650_rt5676_codecs[1].of_node;
230
231 mt8173_rt5650_rt5676_dais[3].codec_of_node =
232 mt8173_rt5650_rt5676_codecs[1].of_node;
233
234 card->dev = &pdev->dev;
235 platform_set_drvdata(pdev, card);
236
237 ret = snd_soc_register_card(card);
238 if (ret)
239 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
240 __func__, ret);
241 return ret;
242}
243
244static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev)
245{
246 struct snd_soc_card *card = platform_get_drvdata(pdev);
247
248 snd_soc_unregister_card(card);
249 return 0;
250}
251
252static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = {
253 { .compatible = "mediatek,mt8173-rt5650-rt5676", },
254 { }
255};
256MODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5676_dt_match);
257
258static struct platform_driver mt8173_rt5650_rt5676_driver = {
259 .driver = {
260 .name = "mtk-rt5650-rt5676",
261 .owner = THIS_MODULE,
262 .of_match_table = mt8173_rt5650_rt5676_dt_match,
263#ifdef CONFIG_PM
264 .pm = &snd_soc_pm_ops,
265#endif
266 },
267 .probe = mt8173_rt5650_rt5676_dev_probe,
268 .remove = mt8173_rt5650_rt5676_dev_remove,
269};
270
271module_platform_driver(mt8173_rt5650_rt5676_driver);
272
273/* Module information */
274MODULE_DESCRIPTION("MT8173 RT5650 and RT5676 SoC machine driver");
275MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
276MODULE_LICENSE("GPL v2");
277MODULE_ALIAS("platform:mtk-rt5650-rt5676");
278
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
new file mode 100644
index 000000000000..a88b17511fdf
--- /dev/null
+++ b/sound/soc/mediatek/mtk-afe-common.h
@@ -0,0 +1,109 @@
1/*
2 * mtk_afe_common.h -- Mediatek audio driver common definitions
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#ifndef _MTK_AFE_COMMON_H_
21#define _MTK_AFE_COMMON_H_
22
23#include <linux/clk.h>
24#include <linux/regmap.h>
25
26enum {
27 MTK_AFE_MEMIF_DL1,
28 MTK_AFE_MEMIF_DL2,
29 MTK_AFE_MEMIF_VUL,
30 MTK_AFE_MEMIF_DAI,
31 MTK_AFE_MEMIF_AWB,
32 MTK_AFE_MEMIF_MOD_DAI,
33 MTK_AFE_MEMIF_HDMI,
34 MTK_AFE_MEMIF_NUM,
35 MTK_AFE_IO_MOD_PCM1 = MTK_AFE_MEMIF_NUM,
36 MTK_AFE_IO_MOD_PCM2,
37 MTK_AFE_IO_PMIC,
38 MTK_AFE_IO_I2S,
39 MTK_AFE_IO_2ND_I2S,
40 MTK_AFE_IO_HW_GAIN1,
41 MTK_AFE_IO_HW_GAIN2,
42 MTK_AFE_IO_MRG_O,
43 MTK_AFE_IO_MRG_I,
44 MTK_AFE_IO_DAIBT,
45 MTK_AFE_IO_HDMI,
46};
47
48enum {
49 MTK_AFE_IRQ_1,
50 MTK_AFE_IRQ_2,
51 MTK_AFE_IRQ_3,
52 MTK_AFE_IRQ_4,
53 MTK_AFE_IRQ_5,
54 MTK_AFE_IRQ_6,
55 MTK_AFE_IRQ_7,
56 MTK_AFE_IRQ_8,
57 MTK_AFE_IRQ_NUM,
58};
59
60enum {
61 MTK_CLK_INFRASYS_AUD,
62 MTK_CLK_TOP_PDN_AUD,
63 MTK_CLK_TOP_PDN_AUD_BUS,
64 MTK_CLK_I2S0_M,
65 MTK_CLK_I2S1_M,
66 MTK_CLK_I2S2_M,
67 MTK_CLK_I2S3_M,
68 MTK_CLK_I2S3_B,
69 MTK_CLK_BCK0,
70 MTK_CLK_BCK1,
71 MTK_CLK_NUM
72};
73
74struct mtk_afe;
75struct snd_pcm_substream;
76
77struct mtk_afe_memif_data {
78 int id;
79 const char *name;
80 int reg_ofs_base;
81 int reg_ofs_cur;
82 int fs_shift;
83 int mono_shift;
84 int enable_shift;
85 int irq_reg_cnt;
86 int irq_cnt_shift;
87 int irq_en_shift;
88 int irq_fs_shift;
89 int irq_clr_shift;
90};
91
92struct mtk_afe_memif {
93 unsigned int phys_buf_addr;
94 int buffer_size;
95 unsigned int hw_ptr; /* Previous IRQ's HW ptr */
96 struct snd_pcm_substream *substream;
97 const struct mtk_afe_memif_data *data;
98 const struct mtk_afe_irq_data *irqdata;
99};
100
101struct mtk_afe {
102 /* address for ioremap audio hardware register */
103 void __iomem *base_addr;
104 struct device *dev;
105 struct regmap *regmap;
106 struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM];
107 struct clk *clocks[MTK_CLK_NUM];
108};
109#endif
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
new file mode 100644
index 000000000000..cc228db5fb76
--- /dev/null
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -0,0 +1,1233 @@
1/*
2 * Mediatek ALSA SoC AFE platform driver
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/pm_runtime.h>
25#include <sound/soc.h>
26#include "mtk-afe-common.h"
27
28/*****************************************************************************
29 * R E G I S T E R D E F I N I T I O N
30 *****************************************************************************/
31#define AUDIO_TOP_CON0 0x0000
32#define AUDIO_TOP_CON1 0x0004
33#define AFE_DAC_CON0 0x0010
34#define AFE_DAC_CON1 0x0014
35#define AFE_I2S_CON1 0x0034
36#define AFE_I2S_CON2 0x0038
37#define AFE_CONN_24BIT 0x006c
38
39#define AFE_CONN1 0x0024
40#define AFE_CONN2 0x0028
41#define AFE_CONN7 0x0460
42#define AFE_CONN8 0x0464
43#define AFE_HDMI_CONN0 0x0390
44
45/* Memory interface */
46#define AFE_DL1_BASE 0x0040
47#define AFE_DL1_CUR 0x0044
48#define AFE_DL2_BASE 0x0050
49#define AFE_DL2_CUR 0x0054
50#define AFE_AWB_BASE 0x0070
51#define AFE_AWB_CUR 0x007c
52#define AFE_VUL_BASE 0x0080
53#define AFE_VUL_CUR 0x008c
54#define AFE_DAI_BASE 0x0090
55#define AFE_DAI_CUR 0x009c
56#define AFE_MOD_PCM_BASE 0x0330
57#define AFE_MOD_PCM_CUR 0x033c
58#define AFE_HDMI_OUT_BASE 0x0374
59#define AFE_HDMI_OUT_CUR 0x0378
60
61#define AFE_ADDA2_TOP_CON0 0x0600
62
63#define AFE_HDMI_OUT_CON0 0x0370
64
65#define AFE_IRQ_MCU_CON 0x03a0
66#define AFE_IRQ_STATUS 0x03a4
67#define AFE_IRQ_CLR 0x03a8
68#define AFE_IRQ_CNT1 0x03ac
69#define AFE_IRQ_CNT2 0x03b0
70#define AFE_IRQ_MCU_EN 0x03b4
71#define AFE_IRQ_CNT5 0x03bc
72#define AFE_IRQ_CNT7 0x03dc
73
74#define AFE_TDM_CON1 0x0548
75#define AFE_TDM_CON2 0x054c
76
77#define AFE_BASE_END_OFFSET 8
78#define AFE_IRQ_STATUS_BITS 0xff
79
80/* AUDIO_TOP_CON0 (0x0000) */
81#define AUD_TCON0_PDN_SPDF (0x1 << 21)
82#define AUD_TCON0_PDN_HDMI (0x1 << 20)
83#define AUD_TCON0_PDN_24M (0x1 << 9)
84#define AUD_TCON0_PDN_22M (0x1 << 8)
85#define AUD_TCON0_PDN_AFE (0x1 << 2)
86
87/* AFE_I2S_CON1 (0x0034) */
88#define AFE_I2S_CON1_LOW_JITTER_CLK (0x1 << 12)
89#define AFE_I2S_CON1_RATE(x) (((x) & 0xf) << 8)
90#define AFE_I2S_CON1_FORMAT_I2S (0x1 << 3)
91#define AFE_I2S_CON1_EN (0x1 << 0)
92
93/* AFE_I2S_CON2 (0x0038) */
94#define AFE_I2S_CON2_LOW_JITTER_CLK (0x1 << 12)
95#define AFE_I2S_CON2_RATE(x) (((x) & 0xf) << 8)
96#define AFE_I2S_CON2_FORMAT_I2S (0x1 << 3)
97#define AFE_I2S_CON2_EN (0x1 << 0)
98
99/* AFE_CONN_24BIT (0x006c) */
100#define AFE_CONN_24BIT_O04 (0x1 << 4)
101#define AFE_CONN_24BIT_O03 (0x1 << 3)
102
103/* AFE_HDMI_CONN0 (0x0390) */
104#define AFE_HDMI_CONN0_O37_I37 (0x7 << 21)
105#define AFE_HDMI_CONN0_O36_I36 (0x6 << 18)
106#define AFE_HDMI_CONN0_O35_I33 (0x3 << 15)
107#define AFE_HDMI_CONN0_O34_I32 (0x2 << 12)
108#define AFE_HDMI_CONN0_O33_I35 (0x5 << 9)
109#define AFE_HDMI_CONN0_O32_I34 (0x4 << 6)
110#define AFE_HDMI_CONN0_O31_I31 (0x1 << 3)
111#define AFE_HDMI_CONN0_O30_I30 (0x0 << 0)
112
113/* AFE_TDM_CON1 (0x0548) */
114#define AFE_TDM_CON1_LRCK_WIDTH(x) (((x) - 1) << 24)
115#define AFE_TDM_CON1_32_BCK_CYCLES (0x2 << 12)
116#define AFE_TDM_CON1_WLEN_32BIT (0x2 << 8)
117#define AFE_TDM_CON1_MSB_ALIGNED (0x1 << 4)
118#define AFE_TDM_CON1_1_BCK_DELAY (0x1 << 3)
119#define AFE_TDM_CON1_BCK_INV (0x1 << 1)
120#define AFE_TDM_CON1_EN (0x1 << 0)
121
122enum afe_tdm_ch_start {
123 AFE_TDM_CH_START_O30_O31 = 0,
124 AFE_TDM_CH_START_O32_O33,
125 AFE_TDM_CH_START_O34_O35,
126 AFE_TDM_CH_START_O36_O37,
127 AFE_TDM_CH_ZERO,
128};
129
130static const struct snd_pcm_hardware mtk_afe_hardware = {
131 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
132 SNDRV_PCM_INFO_MMAP_VALID),
133 .buffer_bytes_max = 256 * 1024,
134 .period_bytes_min = 512,
135 .period_bytes_max = 128 * 1024,
136 .periods_min = 2,
137 .periods_max = 256,
138 .fifo_size = 0,
139};
140
141static snd_pcm_uframes_t mtk_afe_pcm_pointer
142 (struct snd_pcm_substream *substream)
143{
144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
145 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
146 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
147
148 return bytes_to_frames(substream->runtime, memif->hw_ptr);
149}
150
151static const struct snd_pcm_ops mtk_afe_pcm_ops = {
152 .ioctl = snd_pcm_lib_ioctl,
153 .pointer = mtk_afe_pcm_pointer,
154};
155
156static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
157{
158 size_t size;
159 struct snd_card *card = rtd->card->snd_card;
160 struct snd_pcm *pcm = rtd->pcm;
161
162 size = mtk_afe_hardware.buffer_bytes_max;
163
164 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
165 card->dev, size, size);
166}
167
168static void mtk_afe_pcm_free(struct snd_pcm *pcm)
169{
170 snd_pcm_lib_preallocate_free_for_all(pcm);
171}
172
173static const struct snd_soc_platform_driver mtk_afe_pcm_platform = {
174 .ops = &mtk_afe_pcm_ops,
175 .pcm_new = mtk_afe_pcm_new,
176 .pcm_free = mtk_afe_pcm_free,
177};
178
179struct mtk_afe_rate {
180 unsigned int rate;
181 unsigned int regvalue;
182};
183
184static const struct mtk_afe_rate mtk_afe_i2s_rates[] = {
185 { .rate = 8000, .regvalue = 0 },
186 { .rate = 11025, .regvalue = 1 },
187 { .rate = 12000, .regvalue = 2 },
188 { .rate = 16000, .regvalue = 4 },
189 { .rate = 22050, .regvalue = 5 },
190 { .rate = 24000, .regvalue = 6 },
191 { .rate = 32000, .regvalue = 8 },
192 { .rate = 44100, .regvalue = 9 },
193 { .rate = 48000, .regvalue = 10 },
194 { .rate = 88000, .regvalue = 11 },
195 { .rate = 96000, .regvalue = 12 },
196 { .rate = 174000, .regvalue = 13 },
197 { .rate = 192000, .regvalue = 14 },
198};
199
200static int mtk_afe_i2s_fs(unsigned int sample_rate)
201{
202 int i;
203
204 for (i = 0; i < ARRAY_SIZE(mtk_afe_i2s_rates); i++)
205 if (mtk_afe_i2s_rates[i].rate == sample_rate)
206 return mtk_afe_i2s_rates[i].regvalue;
207
208 return -EINVAL;
209}
210
211static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate)
212{
213 unsigned int val;
214 int fs = mtk_afe_i2s_fs(rate);
215
216 if (fs < 0)
217 return -EINVAL;
218
219 /* from external ADC */
220 regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1);
221
222 /* set input */
223 val = AFE_I2S_CON2_LOW_JITTER_CLK |
224 AFE_I2S_CON2_RATE(fs) |
225 AFE_I2S_CON2_FORMAT_I2S;
226
227 regmap_update_bits(afe->regmap, AFE_I2S_CON2, ~AFE_I2S_CON2_EN, val);
228
229 /* set output */
230 val = AFE_I2S_CON1_LOW_JITTER_CLK |
231 AFE_I2S_CON1_RATE(fs) |
232 AFE_I2S_CON1_FORMAT_I2S;
233
234 regmap_update_bits(afe->regmap, AFE_I2S_CON1, ~AFE_I2S_CON1_EN, val);
235 return 0;
236}
237
238static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable)
239{
240 unsigned int val;
241
242 regmap_read(afe->regmap, AFE_I2S_CON2, &val);
243 if (!!(val & AFE_I2S_CON2_EN) == enable)
244 return; /* must skip soft reset */
245
246 /* I2S soft reset begin */
247 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0x4);
248
249 /* input */
250 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable);
251
252 /* output */
253 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable);
254
255 /* I2S soft reset end */
256 udelay(1);
257 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0);
258}
259
260static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
261 struct clk *m_ck, struct clk *b_ck)
262{
263 int ret;
264
265 if (m_ck) {
266 ret = clk_prepare_enable(m_ck);
267 if (ret) {
268 dev_err(afe->dev, "Failed to enable m_ck\n");
269 return ret;
270 }
271 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
272 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
273 }
274
275 if (b_ck) {
276 ret = clk_prepare_enable(b_ck);
277 if (ret) {
278 dev_err(afe->dev, "Failed to enable b_ck\n");
279 return ret;
280 }
281 }
282 return 0;
283}
284
285static int mtk_afe_dais_set_clks(struct mtk_afe *afe,
286 struct clk *m_ck, unsigned int mck_rate,
287 struct clk *b_ck, unsigned int bck_rate)
288{
289 int ret;
290
291 if (m_ck) {
292 ret = clk_set_rate(m_ck, mck_rate);
293 if (ret) {
294 dev_err(afe->dev, "Failed to set m_ck rate\n");
295 return ret;
296 }
297 }
298
299 if (b_ck) {
300 ret = clk_set_rate(b_ck, bck_rate);
301 if (ret) {
302 dev_err(afe->dev, "Failed to set b_ck rate\n");
303 return ret;
304 }
305 }
306 return 0;
307}
308
309static void mtk_afe_dais_disable_clks(struct mtk_afe *afe,
310 struct clk *m_ck, struct clk *b_ck)
311{
312 if (m_ck) {
313 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
314 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
315 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
316 clk_disable_unprepare(m_ck);
317 }
318 if (b_ck)
319 clk_disable_unprepare(b_ck);
320}
321
322static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
323 struct snd_soc_dai *dai)
324{
325 struct snd_soc_pcm_runtime *rtd = substream->private_data;
326 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
327
328 if (dai->active)
329 return 0;
330
331 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
332 return 0;
333}
334
335static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
336 struct snd_soc_dai *dai)
337{
338 struct snd_soc_pcm_runtime *rtd = substream->private_data;
339 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
340
341 if (dai->active)
342 return;
343
344 mtk_afe_set_i2s_enable(afe, false);
345 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
346
347 /* disable AFE */
348 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
349}
350
351static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
352 struct snd_soc_dai *dai)
353{
354 struct snd_soc_pcm_runtime *rtd = substream->private_data;
355 struct snd_pcm_runtime * const runtime = substream->runtime;
356 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
357 int ret;
358
359 mtk_afe_dais_set_clks(afe,
360 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256,
361 NULL, 0);
362 /* config I2S */
363 ret = mtk_afe_set_i2s(afe, substream->runtime->rate);
364 if (ret)
365 return ret;
366
367 mtk_afe_set_i2s_enable(afe, true);
368
369 return 0;
370}
371
372static int mtk_afe_hdmi_startup(struct snd_pcm_substream *substream,
373 struct snd_soc_dai *dai)
374{
375 struct snd_soc_pcm_runtime *rtd = substream->private_data;
376 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
377
378 if (dai->active)
379 return 0;
380
381 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S3_M],
382 afe->clocks[MTK_CLK_I2S3_B]);
383 return 0;
384}
385
386static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
387 struct snd_soc_dai *dai)
388{
389 struct snd_soc_pcm_runtime *rtd = substream->private_data;
390 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
391
392 if (dai->active)
393 return;
394
395 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M],
396 afe->clocks[MTK_CLK_I2S3_B]);
397
398 /* disable AFE */
399 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
400}
401
402static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream,
403 struct snd_soc_dai *dai)
404{
405 struct snd_soc_pcm_runtime *rtd = substream->private_data;
406 struct snd_pcm_runtime * const runtime = substream->runtime;
407 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
408 unsigned int val;
409
410 mtk_afe_dais_set_clks(afe,
411 afe->clocks[MTK_CLK_I2S3_M], runtime->rate * 128,
412 afe->clocks[MTK_CLK_I2S3_B],
413 runtime->rate * runtime->channels * 32);
414
415 val = AFE_TDM_CON1_BCK_INV |
416 AFE_TDM_CON1_1_BCK_DELAY |
417 AFE_TDM_CON1_MSB_ALIGNED | /* I2S mode */
418 AFE_TDM_CON1_WLEN_32BIT |
419 AFE_TDM_CON1_32_BCK_CYCLES |
420 AFE_TDM_CON1_LRCK_WIDTH(32);
421 regmap_update_bits(afe->regmap, AFE_TDM_CON1, ~AFE_TDM_CON1_EN, val);
422
423 /* set tdm2 config */
424 switch (runtime->channels) {
425 case 1:
426 case 2:
427 val = AFE_TDM_CH_START_O30_O31;
428 val |= (AFE_TDM_CH_ZERO << 4);
429 val |= (AFE_TDM_CH_ZERO << 8);
430 val |= (AFE_TDM_CH_ZERO << 12);
431 break;
432 case 3:
433 case 4:
434 val = AFE_TDM_CH_START_O30_O31;
435 val |= (AFE_TDM_CH_START_O32_O33 << 4);
436 val |= (AFE_TDM_CH_ZERO << 8);
437 val |= (AFE_TDM_CH_ZERO << 12);
438 break;
439 case 5:
440 case 6:
441 val = AFE_TDM_CH_START_O30_O31;
442 val |= (AFE_TDM_CH_START_O32_O33 << 4);
443 val |= (AFE_TDM_CH_START_O34_O35 << 8);
444 val |= (AFE_TDM_CH_ZERO << 12);
445 break;
446 case 7:
447 case 8:
448 val = AFE_TDM_CH_START_O30_O31;
449 val |= (AFE_TDM_CH_START_O32_O33 << 4);
450 val |= (AFE_TDM_CH_START_O34_O35 << 8);
451 val |= (AFE_TDM_CH_START_O36_O37 << 12);
452 break;
453 default:
454 val = 0;
455 }
456 regmap_update_bits(afe->regmap, AFE_TDM_CON2, 0x0000ffff, val);
457
458 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
459 0x000000f0, runtime->channels << 4);
460 return 0;
461}
462
463static int mtk_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
464 struct snd_soc_dai *dai)
465{
466 struct snd_soc_pcm_runtime *rtd = substream->private_data;
467 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
468
469 dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name);
470
471 switch (cmd) {
472 case SNDRV_PCM_TRIGGER_START:
473 case SNDRV_PCM_TRIGGER_RESUME:
474 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
475 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF, 0);
476
477 /* set connections: O30~O37: L/R/LS/RS/C/LFE/CH7/CH8 */
478 regmap_write(afe->regmap, AFE_HDMI_CONN0,
479 AFE_HDMI_CONN0_O30_I30 | AFE_HDMI_CONN0_O31_I31 |
480 AFE_HDMI_CONN0_O32_I34 | AFE_HDMI_CONN0_O33_I35 |
481 AFE_HDMI_CONN0_O34_I32 | AFE_HDMI_CONN0_O35_I33 |
482 AFE_HDMI_CONN0_O36_I36 | AFE_HDMI_CONN0_O37_I37);
483
484 /* enable Out control */
485 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0x1);
486
487 /* enable tdm */
488 regmap_update_bits(afe->regmap, AFE_TDM_CON1, 0x1, 0x1);
489
490 return 0;
491 case SNDRV_PCM_TRIGGER_STOP:
492 case SNDRV_PCM_TRIGGER_SUSPEND:
493 /* disable tdm */
494 regmap_update_bits(afe->regmap, AFE_TDM_CON1, 0x1, 0);
495
496 /* disable Out control */
497 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0);
498
499 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
500 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF,
501 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF);
502
503 return 0;
504 default:
505 return -EINVAL;
506 }
507}
508
509static int mtk_afe_dais_startup(struct snd_pcm_substream *substream,
510 struct snd_soc_dai *dai)
511{
512 struct snd_soc_pcm_runtime *rtd = substream->private_data;
513 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
514 struct snd_pcm_runtime *runtime = substream->runtime;
515 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
516 int ret;
517
518 memif->substream = substream;
519
520 snd_soc_set_runtime_hwparams(substream, &mtk_afe_hardware);
521 ret = snd_pcm_hw_constraint_integer(runtime,
522 SNDRV_PCM_HW_PARAM_PERIODS);
523 if (ret < 0)
524 dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
525 return ret;
526}
527
528static void mtk_afe_dais_shutdown(struct snd_pcm_substream *substream,
529 struct snd_soc_dai *dai)
530{
531 struct snd_soc_pcm_runtime *rtd = substream->private_data;
532 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
533 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
534
535 memif->substream = NULL;
536}
537
538static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
539 struct snd_pcm_hw_params *params,
540 struct snd_soc_dai *dai)
541{
542 struct snd_soc_pcm_runtime *rtd = substream->private_data;
543 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
544 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
545 int ret;
546
547 dev_dbg(afe->dev,
548 "%s period = %u, rate= %u, channels=%u\n",
549 __func__, params_period_size(params), params_rate(params),
550 params_channels(params));
551
552 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
553 if (ret < 0)
554 return ret;
555
556 memif->phys_buf_addr = substream->runtime->dma_addr;
557 memif->buffer_size = substream->runtime->dma_bytes;
558 memif->hw_ptr = 0;
559
560 /* start */
561 regmap_write(afe->regmap,
562 memif->data->reg_ofs_base, memif->phys_buf_addr);
563 /* end */
564 regmap_write(afe->regmap,
565 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,
566 memif->phys_buf_addr + memif->buffer_size - 1);
567
568 /* set channel */
569 if (memif->data->mono_shift >= 0) {
570 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
571
572 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
573 1 << memif->data->mono_shift,
574 mono << memif->data->mono_shift);
575 }
576
577 /* set rate */
578 if (memif->data->fs_shift < 0)
579 return 0;
580 if (memif->data->id == MTK_AFE_MEMIF_DAI ||
581 memif->data->id == MTK_AFE_MEMIF_MOD_DAI) {
582 unsigned int val;
583
584 switch (params_rate(params)) {
585 case 8000:
586 val = 0;
587 break;
588 case 16000:
589 val = 1;
590 break;
591 case 32000:
592 val = 2;
593 break;
594 default:
595 return -EINVAL;
596 }
597
598 if (memif->data->id == MTK_AFE_MEMIF_DAI)
599 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
600 0x3 << memif->data->fs_shift,
601 val << memif->data->fs_shift);
602 else
603 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
604 0x3 << memif->data->fs_shift,
605 val << memif->data->fs_shift);
606
607 } else {
608 int fs = mtk_afe_i2s_fs(params_rate(params));
609
610 if (fs < 0)
611 return -EINVAL;
612
613 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
614 0xf << memif->data->fs_shift,
615 fs << memif->data->fs_shift);
616 }
617
618 return 0;
619}
620
621static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream,
622 struct snd_soc_dai *dai)
623{
624 return snd_pcm_lib_free_pages(substream);
625}
626
627static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream,
628 struct snd_soc_dai *dai)
629{
630 struct snd_soc_pcm_runtime *rtd = substream->private_data;
631 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
632
633 /* enable AFE */
634 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
635 return 0;
636}
637
638static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
639 struct snd_soc_dai *dai)
640{
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_pcm_runtime * const runtime = substream->runtime;
643 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
644 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
645 unsigned int counter = runtime->period_size;
646
647 dev_info(afe->dev, "%s %s cmd=%d\n", __func__, memif->data->name, cmd);
648
649 switch (cmd) {
650 case SNDRV_PCM_TRIGGER_START:
651 case SNDRV_PCM_TRIGGER_RESUME:
652 if (memif->data->enable_shift >= 0)
653 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
654 1 << memif->data->enable_shift,
655 1 << memif->data->enable_shift);
656
657 /* set irq counter */
658 regmap_update_bits(afe->regmap,
659 memif->data->irq_reg_cnt,
660 0x3ffff << memif->data->irq_cnt_shift,
661 counter << memif->data->irq_cnt_shift);
662
663 /* set irq fs */
664 if (memif->data->irq_fs_shift >= 0) {
665 int fs = mtk_afe_i2s_fs(runtime->rate);
666
667 if (fs < 0)
668 return -EINVAL;
669
670 regmap_update_bits(afe->regmap,
671 AFE_IRQ_MCU_CON,
672 0xf << memif->data->irq_fs_shift,
673 fs << memif->data->irq_fs_shift);
674 }
675 /* enable interrupt */
676 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON,
677 1 << memif->data->irq_en_shift,
678 1 << memif->data->irq_en_shift);
679
680 return 0;
681 case SNDRV_PCM_TRIGGER_STOP:
682 case SNDRV_PCM_TRIGGER_SUSPEND:
683 if (memif->data->enable_shift >= 0)
684 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
685 1 << memif->data->enable_shift, 0);
686 /* disable interrupt */
687 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON,
688 1 << memif->data->irq_en_shift,
689 0 << memif->data->irq_en_shift);
690 /* and clear pending IRQ */
691 regmap_write(afe->regmap, AFE_IRQ_CLR,
692 1 << memif->data->irq_clr_shift);
693 memif->hw_ptr = 0;
694 return 0;
695 default:
696 return -EINVAL;
697 }
698}
699
700/* FE DAIs */
701static const struct snd_soc_dai_ops mtk_afe_dai_ops = {
702 .startup = mtk_afe_dais_startup,
703 .shutdown = mtk_afe_dais_shutdown,
704 .hw_params = mtk_afe_dais_hw_params,
705 .hw_free = mtk_afe_dais_hw_free,
706 .prepare = mtk_afe_dais_prepare,
707 .trigger = mtk_afe_dais_trigger,
708};
709
710/* BE DAIs */
711static const struct snd_soc_dai_ops mtk_afe_i2s_ops = {
712 .startup = mtk_afe_i2s_startup,
713 .shutdown = mtk_afe_i2s_shutdown,
714 .prepare = mtk_afe_i2s_prepare,
715};
716
717static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = {
718 .startup = mtk_afe_hdmi_startup,
719 .shutdown = mtk_afe_hdmi_shutdown,
720 .prepare = mtk_afe_hdmi_prepare,
721 .trigger = mtk_afe_hdmi_trigger,
722
723};
724
725static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
726 /* FE DAIs: memory intefaces to CPU */
727 {
728 .name = "DL1", /* downlink 1 */
729 .id = MTK_AFE_MEMIF_DL1,
730 .playback = {
731 .stream_name = "DL1",
732 .channels_min = 1,
733 .channels_max = 2,
734 .rates = SNDRV_PCM_RATE_8000_48000,
735 .formats = SNDRV_PCM_FMTBIT_S16_LE,
736 },
737 .ops = &mtk_afe_dai_ops,
738 }, {
739 .name = "VUL", /* voice uplink */
740 .id = MTK_AFE_MEMIF_VUL,
741 .capture = {
742 .stream_name = "VUL",
743 .channels_min = 1,
744 .channels_max = 2,
745 .rates = SNDRV_PCM_RATE_8000_48000,
746 .formats = SNDRV_PCM_FMTBIT_S16_LE,
747 },
748 .ops = &mtk_afe_dai_ops,
749 }, {
750 /* BE DAIs */
751 .name = "I2S",
752 .id = MTK_AFE_IO_I2S,
753 .playback = {
754 .stream_name = "I2S Playback",
755 .channels_min = 1,
756 .channels_max = 2,
757 .rates = SNDRV_PCM_RATE_8000_48000,
758 .formats = SNDRV_PCM_FMTBIT_S16_LE,
759 },
760 .capture = {
761 .stream_name = "I2S Capture",
762 .channels_min = 1,
763 .channels_max = 2,
764 .rates = SNDRV_PCM_RATE_8000_48000,
765 .formats = SNDRV_PCM_FMTBIT_S16_LE,
766 },
767 .ops = &mtk_afe_i2s_ops,
768 .symmetric_rates = 1,
769 },
770};
771
772static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = {
773 /* FE DAIs */
774 {
775 .name = "HDMI",
776 .id = MTK_AFE_MEMIF_HDMI,
777 .playback = {
778 .stream_name = "HDMI",
779 .channels_min = 2,
780 .channels_max = 8,
781 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
782 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
783 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
784 SNDRV_PCM_RATE_192000,
785 .formats = SNDRV_PCM_FMTBIT_S16_LE,
786 },
787 .ops = &mtk_afe_dai_ops,
788 }, {
789 /* BE DAIs */
790 .name = "HDMIO",
791 .id = MTK_AFE_IO_HDMI,
792 .playback = {
793 .stream_name = "HDMIO Playback",
794 .channels_min = 2,
795 .channels_max = 8,
796 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
797 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
798 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
799 SNDRV_PCM_RATE_192000,
800 .formats = SNDRV_PCM_FMTBIT_S16_LE,
801 },
802 .ops = &mtk_afe_hdmi_ops,
803 },
804};
805
806static const struct snd_kcontrol_new mtk_afe_o03_mix[] = {
807 SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN1, 21, 1, 0),
808};
809
810static const struct snd_kcontrol_new mtk_afe_o04_mix[] = {
811 SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN2, 6, 1, 0),
812};
813
814static const struct snd_kcontrol_new mtk_afe_o09_mix[] = {
815 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0),
816};
817
818static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {
819 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0),
820};
821
822static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
823 /* Backend DAIs */
824 SND_SOC_DAPM_AIF_IN("I2S Capture", NULL, 0, SND_SOC_NOPM, 0, 0),
825 SND_SOC_DAPM_AIF_OUT("I2S Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
826
827 /* inter-connections */
828 SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),
829 SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),
830 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
831 SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
832
833 SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0,
834 mtk_afe_o03_mix, ARRAY_SIZE(mtk_afe_o03_mix)),
835 SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0,
836 mtk_afe_o04_mix, ARRAY_SIZE(mtk_afe_o04_mix)),
837 SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0,
838 mtk_afe_o09_mix, ARRAY_SIZE(mtk_afe_o09_mix)),
839 SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0,
840 mtk_afe_o10_mix, ARRAY_SIZE(mtk_afe_o10_mix)),
841};
842
843static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = {
844 {"I05", NULL, "DL1"},
845 {"I06", NULL, "DL1"},
846 {"I2S Playback", NULL, "O03"},
847 {"I2S Playback", NULL, "O04"},
848 {"VUL", NULL, "O09"},
849 {"VUL", NULL, "O10"},
850 {"I17", NULL, "I2S Capture"},
851 {"I18", NULL, "I2S Capture"},
852 { "O03", "I05 Switch", "I05" },
853 { "O04", "I06 Switch", "I06" },
854 { "O09", "I17 Switch", "I17" },
855 { "O10", "I18 Switch", "I18" },
856};
857
858static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = {
859 /* Backend DAIs */
860 SND_SOC_DAPM_AIF_OUT("HDMIO Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
861};
862
863static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {
864 {"HDMIO Playback", NULL, "HDMI"},
865};
866
867static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = {
868 .name = "mtk-afe-pcm-dai",
869 .dapm_widgets = mtk_afe_pcm_widgets,
870 .num_dapm_widgets = ARRAY_SIZE(mtk_afe_pcm_widgets),
871 .dapm_routes = mtk_afe_pcm_routes,
872 .num_dapm_routes = ARRAY_SIZE(mtk_afe_pcm_routes),
873};
874
875static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = {
876 .name = "mtk-afe-hdmi-dai",
877 .dapm_widgets = mtk_afe_hdmi_widgets,
878 .num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets),
879 .dapm_routes = mtk_afe_hdmi_routes,
880 .num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes),
881};
882
883static const char *aud_clks[MTK_CLK_NUM] = {
884 [MTK_CLK_INFRASYS_AUD] = "infra_sys_audio_clk",
885 [MTK_CLK_TOP_PDN_AUD] = "top_pdn_audio",
886 [MTK_CLK_TOP_PDN_AUD_BUS] = "top_pdn_aud_intbus",
887 [MTK_CLK_I2S0_M] = "i2s0_m",
888 [MTK_CLK_I2S1_M] = "i2s1_m",
889 [MTK_CLK_I2S2_M] = "i2s2_m",
890 [MTK_CLK_I2S3_M] = "i2s3_m",
891 [MTK_CLK_I2S3_B] = "i2s3_b",
892 [MTK_CLK_BCK0] = "bck0",
893 [MTK_CLK_BCK1] = "bck1",
894};
895
896static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = {
897 {
898 .name = "DL1",
899 .id = MTK_AFE_MEMIF_DL1,
900 .reg_ofs_base = AFE_DL1_BASE,
901 .reg_ofs_cur = AFE_DL1_CUR,
902 .fs_shift = 0,
903 .mono_shift = 21,
904 .enable_shift = 1,
905 .irq_reg_cnt = AFE_IRQ_CNT1,
906 .irq_cnt_shift = 0,
907 .irq_en_shift = 0,
908 .irq_fs_shift = 4,
909 .irq_clr_shift = 0,
910 }, {
911 .name = "DL2",
912 .id = MTK_AFE_MEMIF_DL2,
913 .reg_ofs_base = AFE_DL2_BASE,
914 .reg_ofs_cur = AFE_DL2_CUR,
915 .fs_shift = 4,
916 .mono_shift = 22,
917 .enable_shift = 2,
918 .irq_reg_cnt = AFE_IRQ_CNT1,
919 .irq_cnt_shift = 20,
920 .irq_en_shift = 2,
921 .irq_fs_shift = 16,
922 .irq_clr_shift = 2,
923 }, {
924 .name = "VUL",
925 .id = MTK_AFE_MEMIF_VUL,
926 .reg_ofs_base = AFE_VUL_BASE,
927 .reg_ofs_cur = AFE_VUL_CUR,
928 .fs_shift = 16,
929 .mono_shift = 27,
930 .enable_shift = 3,
931 .irq_reg_cnt = AFE_IRQ_CNT2,
932 .irq_cnt_shift = 0,
933 .irq_en_shift = 1,
934 .irq_fs_shift = 8,
935 .irq_clr_shift = 1,
936 }, {
937 .name = "DAI",
938 .id = MTK_AFE_MEMIF_DAI,
939 .reg_ofs_base = AFE_DAI_BASE,
940 .reg_ofs_cur = AFE_DAI_CUR,
941 .fs_shift = 24,
942 .mono_shift = -1,
943 .enable_shift = 4,
944 .irq_reg_cnt = AFE_IRQ_CNT2,
945 .irq_cnt_shift = 20,
946 .irq_en_shift = 3,
947 .irq_fs_shift = 20,
948 .irq_clr_shift = 3,
949 }, {
950 .name = "AWB",
951 .id = MTK_AFE_MEMIF_AWB,
952 .reg_ofs_base = AFE_AWB_BASE,
953 .reg_ofs_cur = AFE_AWB_CUR,
954 .fs_shift = 12,
955 .mono_shift = 24,
956 .enable_shift = 6,
957 .irq_reg_cnt = AFE_IRQ_CNT7,
958 .irq_cnt_shift = 0,
959 .irq_en_shift = 14,
960 .irq_fs_shift = 24,
961 .irq_clr_shift = 6,
962 }, {
963 .name = "MOD_DAI",
964 .id = MTK_AFE_MEMIF_MOD_DAI,
965 .reg_ofs_base = AFE_MOD_PCM_BASE,
966 .reg_ofs_cur = AFE_MOD_PCM_CUR,
967 .fs_shift = 30,
968 .mono_shift = 30,
969 .enable_shift = 7,
970 .irq_reg_cnt = AFE_IRQ_CNT2,
971 .irq_cnt_shift = 20,
972 .irq_en_shift = 3,
973 .irq_fs_shift = 20,
974 .irq_clr_shift = 3,
975 }, {
976 .name = "HDMI",
977 .id = MTK_AFE_MEMIF_HDMI,
978 .reg_ofs_base = AFE_HDMI_OUT_BASE,
979 .reg_ofs_cur = AFE_HDMI_OUT_CUR,
980 .fs_shift = -1,
981 .mono_shift = -1,
982 .enable_shift = -1,
983 .irq_reg_cnt = AFE_IRQ_CNT5,
984 .irq_cnt_shift = 0,
985 .irq_en_shift = 12,
986 .irq_fs_shift = -1,
987 .irq_clr_shift = 4,
988 },
989};
990
991static const struct regmap_config mtk_afe_regmap_config = {
992 .reg_bits = 32,
993 .reg_stride = 4,
994 .val_bits = 32,
995 .max_register = AFE_ADDA2_TOP_CON0,
996 .cache_type = REGCACHE_NONE,
997};
998
999static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1000{
1001 struct mtk_afe *afe = dev_id;
1002 unsigned int reg_value, hw_ptr;
1003 int i, ret;
1004
1005 ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &reg_value);
1006 if (ret) {
1007 dev_err(afe->dev, "%s irq status err\n", __func__);
1008 reg_value = AFE_IRQ_STATUS_BITS;
1009 goto err_irq;
1010 }
1011
1012 for (i = 0; i < MTK_AFE_MEMIF_NUM; i++) {
1013 struct mtk_afe_memif *memif = &afe->memif[i];
1014
1015 if (!(reg_value & (1 << memif->data->irq_clr_shift)))
1016 continue;
1017
1018 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur,
1019 &hw_ptr);
1020 if (ret || hw_ptr == 0) {
1021 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
1022 hw_ptr = memif->phys_buf_addr;
1023 }
1024 memif->hw_ptr = hw_ptr - memif->phys_buf_addr;
1025 snd_pcm_period_elapsed(memif->substream);
1026 }
1027
1028err_irq:
1029 /* clear irq */
1030 regmap_write(afe->regmap, AFE_IRQ_CLR, reg_value & AFE_IRQ_STATUS_BITS);
1031
1032 return IRQ_HANDLED;
1033}
1034
1035static int mtk_afe_runtime_suspend(struct device *dev)
1036{
1037 struct mtk_afe *afe = dev_get_drvdata(dev);
1038
1039 /* disable AFE clk */
1040 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
1041 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
1042
1043 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]);
1044 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK1]);
1045 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]);
1046 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]);
1047 clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]);
1048 return 0;
1049}
1050
1051static int mtk_afe_runtime_resume(struct device *dev)
1052{
1053 struct mtk_afe *afe = dev_get_drvdata(dev);
1054 int ret;
1055
1056 ret = clk_prepare_enable(afe->clocks[MTK_CLK_INFRASYS_AUD]);
1057 if (ret)
1058 return ret;
1059
1060 ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]);
1061 if (ret)
1062 goto err_infra;
1063
1064 ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD]);
1065 if (ret)
1066 goto err_top_aud_bus;
1067
1068 ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK0]);
1069 if (ret)
1070 goto err_top_aud;
1071
1072 ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK1]);
1073 if (ret)
1074 goto err_bck0;
1075
1076 /* enable AFE clk */
1077 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, 0);
1078
1079 /* set O3/O4 16bits */
1080 regmap_update_bits(afe->regmap, AFE_CONN_24BIT,
1081 AFE_CONN_24BIT_O03 | AFE_CONN_24BIT_O04, 0);
1082
1083 /* unmask all IRQs */
1084 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff);
1085 return 0;
1086
1087err_bck0:
1088 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]);
1089err_top_aud:
1090 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]);
1091err_top_aud_bus:
1092 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]);
1093err_infra:
1094 clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]);
1095 return ret;
1096}
1097
1098static int mtk_afe_init_audio_clk(struct mtk_afe *afe)
1099{
1100 size_t i;
1101
1102 for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
1103 afe->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
1104 if (IS_ERR(afe->clocks[i])) {
1105 dev_err(afe->dev, "%s devm_clk_get %s fail\n",
1106 __func__, aud_clks[i]);
1107 return PTR_ERR(afe->clocks[i]);
1108 }
1109 }
1110 clk_set_rate(afe->clocks[MTK_CLK_BCK0], 22579200); /* 22M */
1111 clk_set_rate(afe->clocks[MTK_CLK_BCK1], 24576000); /* 24M */
1112 return 0;
1113}
1114
1115static int mtk_afe_pcm_dev_probe(struct platform_device *pdev)
1116{
1117 int ret, i;
1118 unsigned int irq_id;
1119 struct mtk_afe *afe;
1120 struct resource *res;
1121
1122 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
1123 if (!afe)
1124 return -ENOMEM;
1125
1126 afe->dev = &pdev->dev;
1127
1128 irq_id = platform_get_irq(pdev, 0);
1129 if (!irq_id) {
1130 dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name);
1131 return -ENXIO;
1132 }
1133 ret = devm_request_irq(afe->dev, irq_id, mtk_afe_irq_handler,
1134 0, "Afe_ISR_Handle", (void *)afe);
1135 if (ret) {
1136 dev_err(afe->dev, "could not request_irq\n");
1137 return ret;
1138 }
1139
1140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1141 afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
1142 if (IS_ERR(afe->base_addr))
1143 return PTR_ERR(afe->base_addr);
1144
1145 afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
1146 &mtk_afe_regmap_config);
1147 if (IS_ERR(afe->regmap))
1148 return PTR_ERR(afe->regmap);
1149
1150 /* initial audio related clock */
1151 ret = mtk_afe_init_audio_clk(afe);
1152 if (ret) {
1153 dev_err(afe->dev, "mtk_afe_init_audio_clk fail\n");
1154 return ret;
1155 }
1156
1157 for (i = 0; i < MTK_AFE_MEMIF_NUM; i++)
1158 afe->memif[i].data = &memif_data[i];
1159
1160 platform_set_drvdata(pdev, afe);
1161
1162 pm_runtime_enable(&pdev->dev);
1163 if (!pm_runtime_enabled(&pdev->dev)) {
1164 ret = mtk_afe_runtime_resume(&pdev->dev);
1165 if (ret)
1166 goto err_pm_disable;
1167 }
1168
1169 ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
1170 if (ret)
1171 goto err_pm_disable;
1172
1173 ret = snd_soc_register_component(&pdev->dev,
1174 &mtk_afe_pcm_dai_component,
1175 mtk_afe_pcm_dais,
1176 ARRAY_SIZE(mtk_afe_pcm_dais));
1177 if (ret)
1178 goto err_platform;
1179
1180 ret = snd_soc_register_component(&pdev->dev,
1181 &mtk_afe_hdmi_dai_component,
1182 mtk_afe_hdmi_dais,
1183 ARRAY_SIZE(mtk_afe_hdmi_dais));
1184 if (ret)
1185 goto err_comp;
1186
1187 dev_info(&pdev->dev, "MTK AFE driver initialized.\n");
1188 return 0;
1189
1190err_comp:
1191 snd_soc_unregister_component(&pdev->dev);
1192err_platform:
1193 snd_soc_unregister_platform(&pdev->dev);
1194err_pm_disable:
1195 pm_runtime_disable(&pdev->dev);
1196 return ret;
1197}
1198
1199static int mtk_afe_pcm_dev_remove(struct platform_device *pdev)
1200{
1201 pm_runtime_disable(&pdev->dev);
1202 snd_soc_unregister_component(&pdev->dev);
1203 snd_soc_unregister_platform(&pdev->dev);
1204 return 0;
1205}
1206
1207static const struct of_device_id mtk_afe_pcm_dt_match[] = {
1208 { .compatible = "mediatek,mt8173-afe-pcm", },
1209 { }
1210};
1211MODULE_DEVICE_TABLE(of, mtk_afe_pcm_dt_match);
1212
1213static const struct dev_pm_ops mtk_afe_pm_ops = {
1214 SET_RUNTIME_PM_OPS(mtk_afe_runtime_suspend, mtk_afe_runtime_resume,
1215 NULL)
1216};
1217
1218static struct platform_driver mtk_afe_pcm_driver = {
1219 .driver = {
1220 .name = "mtk-afe-pcm",
1221 .owner = THIS_MODULE,
1222 .of_match_table = mtk_afe_pcm_dt_match,
1223 .pm = &mtk_afe_pm_ops,
1224 },
1225 .probe = mtk_afe_pcm_dev_probe,
1226 .remove = mtk_afe_pcm_dev_remove,
1227};
1228
1229module_platform_driver(mtk_afe_pcm_driver);
1230
1231MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver");
1232MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
1233MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index fded99362d39..3bebfb1d3a6f 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -245,6 +245,8 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
245static const struct snd_soc_dapm_route audio_map[] = { 245static const struct snd_soc_dapm_route audio_map[] = {
246 {"Ext Spk", NULL, "HPLOUT"}, 246 {"Ext Spk", NULL, "HPLOUT"},
247 {"Ext Spk", NULL, "HPROUT"}, 247 {"Ext Spk", NULL, "HPROUT"},
248 {"Ext Spk", NULL, "HPLCOM"},
249 {"Ext Spk", NULL, "HPRCOM"},
248 {"Headphone Jack", NULL, "LLOUT"}, 250 {"Headphone Jack", NULL, "LLOUT"},
249 {"Headphone Jack", NULL, "RLOUT"}, 251 {"Headphone Jack", NULL, "RLOUT"},
250 {"FM Transmitter", NULL, "LLOUT"}, 252 {"FM Transmitter", NULL, "LLOUT"},
@@ -288,15 +290,8 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
288 struct snd_soc_codec *codec = rtd->codec; 290 struct snd_soc_codec *codec = rtd->codec;
289 struct snd_soc_card *card = rtd->card; 291 struct snd_soc_card *card = rtd->card;
290 struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); 292 struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
291
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
293 int err; 293 int err;
294 294
295 /* Set up NC codec pins */
296 snd_soc_dapm_nc_pin(dapm, "MIC3L");
297 snd_soc_dapm_nc_pin(dapm, "MIC3R");
298 snd_soc_dapm_nc_pin(dapm, "LINE1R");
299
300 err = tpa6130a2_add_controls(codec); 295 err = tpa6130a2_add_controls(codec);
301 if (err < 0) { 296 if (err < 0) {
302 dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); 297 dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
@@ -383,6 +378,7 @@ static struct snd_soc_card rx51_sound_card = {
383 .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), 378 .num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
384 .codec_conf = rx51_codec_conf, 379 .codec_conf = rx51_codec_conf,
385 .num_configs = ARRAY_SIZE(rx51_codec_conf), 380 .num_configs = ARRAY_SIZE(rx51_codec_conf),
381 .fully_routed = true,
386 382
387 .controls = aic34_rx51_controls, 383 .controls = aic34_rx51_controls,
388 .num_controls = ARRAY_SIZE(aic34_rx51_controls), 384 .num_controls = ARRAY_SIZE(aic34_rx51_controls),
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 938144c59e2b..807fedfa1c76 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -32,3 +32,12 @@ config SND_SOC_STORM
32 help 32 help
33 Say Y or M if you want add support for SoC audio on the 33 Say Y or M if you want add support for SoC audio on the
34 Qualcomm Technologies IPQ806X-based Storm board. 34 Qualcomm Technologies IPQ806X-based Storm board.
35
36config SND_SOC_APQ8016_SBC
37 tristate "SoC Audio support for APQ8016 SBC platforms"
38 depends on SND_SOC_QCOM && (ARCH_QCOM || COMPILE_TEST)
39 select SND_SOC_LPASS_APQ8016
40 help
41 Support for Qualcomm Technologies LPASS audio block in
42 APQ8016 SOC-based systems.
43 Say Y if you want to use audio devices on MI2S.
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index ac7630833fe5..79e5c50a8f71 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -11,5 +11,7 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o
11 11
12# Machine 12# Machine
13snd-soc-storm-objs := storm.o 13snd-soc-storm-objs := storm.o
14snd-soc-apq8016-sbc-objs := apq8016_sbc.o
14 15
15obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o 16obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
17obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
new file mode 100644
index 000000000000..1efdf0088ecd
--- /dev/null
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -0,0 +1,198 @@
1/*
2 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/clk.h>
21#include <linux/platform_device.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <dt-bindings/sound/apq8016-lpass.h>
26
27struct apq8016_sbc_data {
28 void __iomem *mic_iomux;
29 void __iomem *spkr_iomux;
30 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
31};
32
33#define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17)
34#define MIC_CTRL_TLMM_SCLK_EN BIT(1)
35#define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16))
36
37static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd)
38{
39 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
40 struct snd_soc_card *card = rtd->card;
41 struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card);
42 int rval = 0;
43
44 switch (cpu_dai->id) {
45 case MI2S_PRIMARY:
46 writel(readl(pdata->spkr_iomux) | SPKR_CTL_PRI_WS_SLAVE_SEL_11,
47 pdata->spkr_iomux);
48 break;
49
50 case MI2S_QUATERNARY:
51 /* Configure the Quat MI2S to TLMM */
52 writel(readl(pdata->mic_iomux) | MIC_CTRL_QUA_WS_SLAVE_SEL_10 |
53 MIC_CTRL_TLMM_SCLK_EN,
54 pdata->mic_iomux);
55 break;
56
57 default:
58 dev_err(card->dev, "unsupported cpu dai configuration\n");
59 rval = -EINVAL;
60 break;
61
62 }
63
64 return rval;
65}
66
67static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
68{
69 struct device *dev = card->dev;
70 struct snd_soc_dai_link *link;
71 struct device_node *np, *codec, *cpu, *node = dev->of_node;
72 struct apq8016_sbc_data *data;
73 int ret, num_links;
74
75 ret = snd_soc_of_parse_card_name(card, "qcom,model");
76 if (ret) {
77 dev_err(dev, "Error parsing card name: %d\n", ret);
78 return ERR_PTR(ret);
79 }
80
81 /* Populate links */
82 num_links = of_get_child_count(node);
83
84 /* Allocate the private data and the DAI link array */
85 data = devm_kzalloc(dev, sizeof(*data) + sizeof(*link) * num_links,
86 GFP_KERNEL);
87 if (!data)
88 return ERR_PTR(-ENOMEM);
89
90 card->dai_link = &data->dai_link[0];
91 card->num_links = num_links;
92
93 link = data->dai_link;
94
95 for_each_child_of_node(node, np) {
96 cpu = of_get_child_by_name(np, "cpu");
97 codec = of_get_child_by_name(np, "codec");
98
99 if (!cpu || !codec) {
100 dev_err(dev, "Can't find cpu/codec DT node\n");
101 return ERR_PTR(-EINVAL);
102 }
103
104 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
105 if (!link->cpu_of_node) {
106 dev_err(card->dev, "error getting cpu phandle\n");
107 return ERR_PTR(-EINVAL);
108 }
109
110 link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0);
111 if (!link->codec_of_node) {
112 dev_err(card->dev, "error getting codec phandle\n");
113 return ERR_PTR(-EINVAL);
114 }
115
116 ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
117 if (ret) {
118 dev_err(card->dev, "error getting cpu dai name\n");
119 return ERR_PTR(ret);
120 }
121
122 ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name);
123 if (ret) {
124 dev_err(card->dev, "error getting codec dai name\n");
125 return ERR_PTR(ret);
126 }
127
128 link->platform_of_node = link->cpu_of_node;
129 /* For now we only support playback */
130 link->playback_only = true;
131
132 ret = of_property_read_string(np, "link-name", &link->name);
133 if (ret) {
134 dev_err(card->dev, "error getting codec dai_link name\n");
135 return ERR_PTR(ret);
136 }
137
138 link->stream_name = link->name;
139 link->init = apq8016_sbc_dai_init;
140 link++;
141 }
142
143 return data;
144}
145
146static int apq8016_sbc_platform_probe(struct platform_device *pdev)
147{
148 struct device *dev = &pdev->dev;
149 struct snd_soc_card *card;
150 struct apq8016_sbc_data *data;
151 struct resource *res;
152
153 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
154 if (!card)
155 return -ENOMEM;
156
157 card->dev = dev;
158 data = apq8016_sbc_parse_of(card);
159 if (IS_ERR(data)) {
160 dev_err(&pdev->dev, "Error resolving dai links: %ld\n",
161 PTR_ERR(data));
162 return PTR_ERR(data);
163 }
164
165 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mic-iomux");
166 data->mic_iomux = devm_ioremap_resource(dev, res);
167 if (IS_ERR(data->mic_iomux))
168 return PTR_ERR(data->mic_iomux);
169
170 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spkr-iomux");
171 data->spkr_iomux = devm_ioremap_resource(dev, res);
172 if (IS_ERR(data->spkr_iomux))
173 return PTR_ERR(data->spkr_iomux);
174
175 platform_set_drvdata(pdev, data);
176 snd_soc_card_set_drvdata(card, data);
177
178 return devm_snd_soc_register_card(&pdev->dev, card);
179}
180
181static const struct of_device_id apq8016_sbc_device_id[] = {
182 { .compatible = "qcom,apq8016-sbc-sndcard" },
183 {},
184};
185MODULE_DEVICE_TABLE(of, apq8016_sbc_device_id);
186
187static struct platform_driver apq8016_sbc_platform_driver = {
188 .driver = {
189 .name = "qcom-apq8016-sbc",
190 .of_match_table = of_match_ptr(apq8016_sbc_device_id),
191 },
192 .probe = apq8016_sbc_platform_probe,
193};
194module_platform_driver(apq8016_sbc_platform_driver);
195
196MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
197MODULE_DESCRIPTION("APQ8016 ASoC Machine Driver");
198MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
index b8bd296190ad..2d833bffdba0 100644
--- a/sound/soc/qcom/storm.c
+++ b/sound/soc/qcom/storm.c
@@ -69,11 +69,6 @@ static struct snd_soc_dai_link storm_dai_link = {
69 .ops = &storm_soc_ops, 69 .ops = &storm_soc_ops,
70}; 70};
71 71
72static struct snd_soc_card storm_soc_card = {
73 .name = "ipq806x-storm",
74 .dev = NULL,
75};
76
77static int storm_parse_of(struct snd_soc_card *card) 72static int storm_parse_of(struct snd_soc_card *card)
78{ 73{
79 struct snd_soc_dai_link *dai_link = card->dai_link; 74 struct snd_soc_dai_link *dai_link = card->dai_link;
@@ -99,14 +94,13 @@ static int storm_parse_of(struct snd_soc_card *card)
99 94
100static int storm_platform_probe(struct platform_device *pdev) 95static int storm_platform_probe(struct platform_device *pdev)
101{ 96{
102 struct snd_soc_card *card = &storm_soc_card; 97 struct snd_soc_card *card;
103 int ret; 98 int ret;
104 99
105 if (card->dev) { 100 card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
106 dev_err(&pdev->dev, "%s() error, existing soundcard\n", 101 if (!card)
107 __func__); 102 return -ENOMEM;
108 return -ENODEV; 103
109 }
110 card->dev = &pdev->dev; 104 card->dev = &pdev->dev;
111 platform_set_drvdata(pdev, card); 105 platform_set_drvdata(pdev, card);
112 106
@@ -128,16 +122,12 @@ static int storm_platform_probe(struct platform_device *pdev)
128 } 122 }
129 123
130 ret = devm_snd_soc_register_card(&pdev->dev, card); 124 ret = devm_snd_soc_register_card(&pdev->dev, card);
131 if (ret == -EPROBE_DEFER) { 125 if (ret)
132 card->dev = NULL;
133 return ret;
134 } else if (ret) {
135 dev_err(&pdev->dev, "%s() error registering soundcard: %d\n", 126 dev_err(&pdev->dev, "%s() error registering soundcard: %d\n",
136 __func__, ret); 127 __func__, ret);
137 return ret;
138 }
139 128
140 return 0; 129 return ret;
130
141} 131}
142 132
143#ifdef CONFIG_OF 133#ifdef CONFIG_OF
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index d460d2aa82ee..f1e5920654f6 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -137,15 +137,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
137 return mod->ops->name; 137 return mod->ops->name;
138} 138}
139 139
140struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod) 140struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
141 struct rsnd_mod *mod)
141{ 142{
142 if (!mod || !mod->ops || !mod->ops->dma_req) 143 if (!mod || !mod->ops || !mod->ops->dma_req)
143 return NULL; 144 return NULL;
144 145
145 return mod->ops->dma_req(mod); 146 return mod->ops->dma_req(io, mod);
146} 147}
147 148
148int rsnd_mod_init(struct rsnd_mod *mod, 149int rsnd_mod_init(struct rsnd_priv *priv,
150 struct rsnd_mod *mod,
149 struct rsnd_mod_ops *ops, 151 struct rsnd_mod_ops *ops,
150 struct clk *clk, 152 struct clk *clk,
151 enum rsnd_mod_type type, 153 enum rsnd_mod_type type,
@@ -160,6 +162,7 @@ int rsnd_mod_init(struct rsnd_mod *mod,
160 mod->ops = ops; 162 mod->ops = ops;
161 mod->type = type; 163 mod->type = type;
162 mod->clk = clk; 164 mod->clk = clk;
165 mod->priv = priv;
163 166
164 return ret; 167 return ret;
165} 168}
@@ -170,10 +173,31 @@ void rsnd_mod_quit(struct rsnd_mod *mod)
170 clk_unprepare(mod->clk); 173 clk_unprepare(mod->clk);
171} 174}
172 175
173int rsnd_mod_is_working(struct rsnd_mod *mod) 176void rsnd_mod_interrupt(struct rsnd_mod *mod,
177 void (*callback)(struct rsnd_mod *mod,
178 struct rsnd_dai_stream *io))
174{ 179{
175 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 180 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
181 struct rsnd_dai_stream *io;
182 struct rsnd_dai *rdai;
183 int i, j;
184
185 for_each_rsnd_dai(rdai, priv, j) {
186
187 for (i = 0; i < RSND_MOD_MAX; i++) {
188 io = &rdai->playback;
189 if (mod == io->mod[i])
190 callback(mod, io);
191
192 io = &rdai->capture;
193 if (mod == io->mod[i])
194 callback(mod, io);
195 }
196 }
197}
176 198
199int rsnd_io_is_working(struct rsnd_dai_stream *io)
200{
177 /* see rsnd_dai_stream_init/quit() */ 201 /* see rsnd_dai_stream_init/quit() */
178 return !!io->substream; 202 return !!io->substream;
179} 203}
@@ -181,10 +205,9 @@ int rsnd_mod_is_working(struct rsnd_mod *mod)
181/* 205/*
182 * settting function 206 * settting function
183 */ 207 */
184u32 rsnd_get_adinr(struct rsnd_mod *mod) 208u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
185{ 209{
186 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 210 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
187 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
188 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 211 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
189 struct device *dev = rsnd_priv_to_dev(priv); 212 struct device *dev = rsnd_priv_to_dev(priv);
190 u32 adinr = runtime->channels; 213 u32 adinr = runtime->channels;
@@ -207,26 +230,31 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
207/* 230/*
208 * rsnd_dai functions 231 * rsnd_dai functions
209 */ 232 */
210#define __rsnd_mod_call(mod, func, param...) \ 233#define __rsnd_mod_call(mod, io, func, param...) \
211({ \ 234({ \
212 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 235 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
213 struct device *dev = rsnd_priv_to_dev(priv); \ 236 struct device *dev = rsnd_priv_to_dev(priv); \
214 u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \ 237 u32 mask = 0xF << __rsnd_mod_shift_##func; \
215 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ 238 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \
239 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \
216 int ret = 0; \ 240 int ret = 0; \
217 if ((mod->status & mask) == call) { \ 241 int called = 0; \
218 dev_dbg(dev, "%s[%d] %s\n", \ 242 if (val == __rsnd_mod_call_##func) { \
219 rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ 243 called = 1; \
220 ret = (mod)->ops->func(mod, param); \ 244 ret = (mod)->ops->func(mod, io, param); \
221 mod->status = (mod->status & ~mask) | (~call & mask); \ 245 mod->status = (mod->status & ~mask) + \
246 (add << __rsnd_mod_shift_##func); \
222 } \ 247 } \
248 dev_dbg(dev, "%s[%d] 0x%08x %s\n", \
249 rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \
250 called ? #func : ""); \
223 ret; \ 251 ret; \
224}) 252})
225 253
226#define rsnd_mod_call(mod, func, param...) \ 254#define rsnd_mod_call(mod, io, func, param...) \
227 (!(mod) ? -ENODEV : \ 255 (!(mod) ? -ENODEV : \
228 !((mod)->ops->func) ? 0 : \ 256 !((mod)->ops->func) ? 0 : \
229 __rsnd_mod_call(mod, func, param)) 257 __rsnd_mod_call(mod, io, func, param))
230 258
231#define rsnd_dai_call(fn, io, param...) \ 259#define rsnd_dai_call(fn, io, param...) \
232({ \ 260({ \
@@ -236,7 +264,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
236 mod = (io)->mod[i]; \ 264 mod = (io)->mod[i]; \
237 if (!mod) \ 265 if (!mod) \
238 continue; \ 266 continue; \
239 ret = rsnd_mod_call(mod, fn, param); \ 267 ret = rsnd_mod_call(mod, io, fn, param); \
240 if (ret < 0) \ 268 if (ret < 0) \
241 break; \ 269 break; \
242 } \ 270 } \
@@ -260,7 +288,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
260 } 288 }
261 289
262 io->mod[mod->type] = mod; 290 io->mod[mod->type] = mod;
263 mod->io = io;
264 291
265 return 0; 292 return 0;
266} 293}
@@ -268,7 +295,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
268static void rsnd_dai_disconnect(struct rsnd_mod *mod, 295static void rsnd_dai_disconnect(struct rsnd_mod *mod,
269 struct rsnd_dai_stream *io) 296 struct rsnd_dai_stream *io)
270{ 297{
271 mod->io = NULL;
272 io->mod[mod->type] = NULL; 298 io->mod[mod->type] = NULL;
273} 299}
274 300
@@ -302,7 +328,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional)
302 return pos; 328 return pos;
303} 329}
304 330
305void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) 331bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte)
306{ 332{
307 io->byte_pos += byte; 333 io->byte_pos += byte;
308 334
@@ -319,8 +345,24 @@ void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte)
319 io->next_period_byte = io->byte_per_period; 345 io->next_period_byte = io->byte_per_period;
320 } 346 }
321 347
322 snd_pcm_period_elapsed(substream); 348 return true;
323 } 349 }
350
351 return false;
352}
353
354void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io)
355{
356 struct snd_pcm_substream *substream = io->substream;
357
358 /*
359 * this function should be called...
360 *
361 * - if rsnd_dai_pointer_update() returns true
362 * - without spin lock
363 */
364
365 snd_pcm_period_elapsed(substream);
324} 366}
325 367
326static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, 368static void rsnd_dai_stream_init(struct rsnd_dai_stream *io,
@@ -834,16 +876,18 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
834 } 876 }
835 877
836 if (change) 878 if (change)
837 cfg->update(mod); 879 cfg->update(cfg->io, mod);
838 880
839 return change; 881 return change;
840} 882}
841 883
842static int __rsnd_kctrl_new(struct rsnd_mod *mod, 884static int __rsnd_kctrl_new(struct rsnd_mod *mod,
885 struct rsnd_dai_stream *io,
843 struct snd_soc_pcm_runtime *rtd, 886 struct snd_soc_pcm_runtime *rtd,
844 const unsigned char *name, 887 const unsigned char *name,
845 struct rsnd_kctrl_cfg *cfg, 888 struct rsnd_kctrl_cfg *cfg,
846 void (*update)(struct rsnd_mod *mod)) 889 void (*update)(struct rsnd_dai_stream *io,
890 struct rsnd_mod *mod))
847{ 891{
848 struct snd_soc_card *soc_card = rtd->card; 892 struct snd_soc_card *soc_card = rtd->card;
849 struct snd_card *card = rtd->card->snd_card; 893 struct snd_card *card = rtd->card->snd_card;
@@ -872,6 +916,7 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
872 cfg->update = update; 916 cfg->update = update;
873 cfg->card = card; 917 cfg->card = card;
874 cfg->kctrl = kctrl; 918 cfg->kctrl = kctrl;
919 cfg->io = io;
875 920
876 return 0; 921 return 0;
877} 922}
@@ -882,36 +927,42 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg)
882} 927}
883 928
884int rsnd_kctrl_new_m(struct rsnd_mod *mod, 929int rsnd_kctrl_new_m(struct rsnd_mod *mod,
930 struct rsnd_dai_stream *io,
885 struct snd_soc_pcm_runtime *rtd, 931 struct snd_soc_pcm_runtime *rtd,
886 const unsigned char *name, 932 const unsigned char *name,
887 void (*update)(struct rsnd_mod *mod), 933 void (*update)(struct rsnd_dai_stream *io,
934 struct rsnd_mod *mod),
888 struct rsnd_kctrl_cfg_m *_cfg, 935 struct rsnd_kctrl_cfg_m *_cfg,
889 u32 max) 936 u32 max)
890{ 937{
891 _cfg->cfg.max = max; 938 _cfg->cfg.max = max;
892 _cfg->cfg.size = RSND_DVC_CHANNELS; 939 _cfg->cfg.size = RSND_DVC_CHANNELS;
893 _cfg->cfg.val = _cfg->val; 940 _cfg->cfg.val = _cfg->val;
894 return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); 941 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
895} 942}
896 943
897int rsnd_kctrl_new_s(struct rsnd_mod *mod, 944int rsnd_kctrl_new_s(struct rsnd_mod *mod,
945 struct rsnd_dai_stream *io,
898 struct snd_soc_pcm_runtime *rtd, 946 struct snd_soc_pcm_runtime *rtd,
899 const unsigned char *name, 947 const unsigned char *name,
900 void (*update)(struct rsnd_mod *mod), 948 void (*update)(struct rsnd_dai_stream *io,
949 struct rsnd_mod *mod),
901 struct rsnd_kctrl_cfg_s *_cfg, 950 struct rsnd_kctrl_cfg_s *_cfg,
902 u32 max) 951 u32 max)
903{ 952{
904 _cfg->cfg.max = max; 953 _cfg->cfg.max = max;
905 _cfg->cfg.size = 1; 954 _cfg->cfg.size = 1;
906 _cfg->cfg.val = &_cfg->val; 955 _cfg->cfg.val = &_cfg->val;
907 return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); 956 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
908} 957}
909 958
910int rsnd_kctrl_new_e(struct rsnd_mod *mod, 959int rsnd_kctrl_new_e(struct rsnd_mod *mod,
960 struct rsnd_dai_stream *io,
911 struct snd_soc_pcm_runtime *rtd, 961 struct snd_soc_pcm_runtime *rtd,
912 const unsigned char *name, 962 const unsigned char *name,
913 struct rsnd_kctrl_cfg_s *_cfg, 963 struct rsnd_kctrl_cfg_s *_cfg,
914 void (*update)(struct rsnd_mod *mod), 964 void (*update)(struct rsnd_dai_stream *io,
965 struct rsnd_mod *mod),
915 const char * const *texts, 966 const char * const *texts,
916 u32 max) 967 u32 max)
917{ 968{
@@ -919,7 +970,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
919 _cfg->cfg.size = 1; 970 _cfg->cfg.size = 1;
920 _cfg->cfg.val = &_cfg->val; 971 _cfg->cfg.val = &_cfg->val;
921 _cfg->cfg.texts = texts; 972 _cfg->cfg.texts = texts;
922 return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); 973 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
923} 974}
924 975
925/* 976/*
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 144308f15fb3..d306e298c63d 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -32,11 +32,12 @@ struct rsnd_dma_ctrl {
32/* 32/*
33 * Audio DMAC 33 * Audio DMAC
34 */ 34 */
35static void rsnd_dmaen_complete(void *data) 35static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
36 struct rsnd_dai_stream *io)
36{ 37{
37 struct rsnd_dma *dma = (struct rsnd_dma *)data; 38 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
38 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 39 bool elapsed = false;
39 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 40 unsigned long flags;
40 41
41 /* 42 /*
42 * Renesas sound Gen1 needs 1 DMAC, 43 * Renesas sound Gen1 needs 1 DMAC,
@@ -49,23 +50,36 @@ static void rsnd_dmaen_complete(void *data)
49 * rsnd_dai_pointer_update() will be called twice, 50 * rsnd_dai_pointer_update() will be called twice,
50 * ant it will breaks io->byte_pos 51 * ant it will breaks io->byte_pos
51 */ 52 */
53 spin_lock_irqsave(&priv->lock, flags);
54
55 if (rsnd_io_is_working(io))
56 elapsed = rsnd_dai_pointer_update(io, io->byte_per_period);
52 57
53 rsnd_dai_pointer_update(io, io->byte_per_period); 58 spin_unlock_irqrestore(&priv->lock, flags);
59
60 if (elapsed)
61 rsnd_dai_period_elapsed(io);
54} 62}
55 63
56static void rsnd_dmaen_stop(struct rsnd_dma *dma) 64static void rsnd_dmaen_complete(void *data)
65{
66 struct rsnd_mod *mod = data;
67
68 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
69}
70
71static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
57{ 72{
58 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 73 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
59 74
60 dmaengine_terminate_all(dmaen->chan); 75 dmaengine_terminate_all(dmaen->chan);
61} 76}
62 77
63static void rsnd_dmaen_start(struct rsnd_dma *dma) 78static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
64{ 79{
65 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 80 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
66 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 81 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
67 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 82 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
68 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
69 struct snd_pcm_substream *substream = io->substream; 83 struct snd_pcm_substream *substream = io->substream;
70 struct device *dev = rsnd_priv_to_dev(priv); 84 struct device *dev = rsnd_priv_to_dev(priv);
71 struct dma_async_tx_descriptor *desc; 85 struct dma_async_tx_descriptor *desc;
@@ -84,7 +98,7 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma)
84 } 98 }
85 99
86 desc->callback = rsnd_dmaen_complete; 100 desc->callback = rsnd_dmaen_complete;
87 desc->callback_param = dma; 101 desc->callback_param = mod;
88 102
89 if (dmaengine_submit(desc) < 0) { 103 if (dmaengine_submit(desc) < 0) {
90 dev_err(dev, "dmaengine_submit() fail\n"); 104 dev_err(dev, "dmaengine_submit() fail\n");
@@ -115,7 +129,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
115 return chan; 129 return chan;
116} 130}
117 131
118static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, 132static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
133 struct rsnd_mod *mod_from,
119 struct rsnd_mod *mod_to) 134 struct rsnd_mod *mod_to)
120{ 135{
121 if ((!mod_from && !mod_to) || 136 if ((!mod_from && !mod_to) ||
@@ -123,19 +138,19 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from,
123 return NULL; 138 return NULL;
124 139
125 if (mod_from) 140 if (mod_from)
126 return rsnd_mod_dma_req(mod_from); 141 return rsnd_mod_dma_req(io, mod_from);
127 else 142 else
128 return rsnd_mod_dma_req(mod_to); 143 return rsnd_mod_dma_req(io, mod_to);
129} 144}
130 145
131static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, 146static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
147 struct rsnd_dma *dma, int id,
132 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 148 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
133{ 149{
134 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 150 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
151 struct rsnd_priv *priv = rsnd_io_to_priv(io);
135 struct device *dev = rsnd_priv_to_dev(priv); 152 struct device *dev = rsnd_priv_to_dev(priv);
136 struct dma_slave_config cfg = {}; 153 struct dma_slave_config cfg = {};
137 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
138 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
139 int is_play = rsnd_io_is_play(io); 154 int is_play = rsnd_io_is_play(io);
140 int ret; 155 int ret;
141 156
@@ -145,7 +160,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
145 } 160 }
146 161
147 if (dev->of_node) { 162 if (dev->of_node) {
148 dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to); 163 dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to);
149 } else { 164 } else {
150 dma_cap_mask_t mask; 165 dma_cap_mask_t mask;
151 166
@@ -177,7 +192,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
177 return 0; 192 return 0;
178 193
179rsnd_dma_init_err: 194rsnd_dma_init_err:
180 rsnd_dma_quit(dma); 195 rsnd_dma_quit(io, dma);
181rsnd_dma_channel_err: 196rsnd_dma_channel_err:
182 197
183 /* 198 /*
@@ -189,7 +204,7 @@ rsnd_dma_channel_err:
189 return -EAGAIN; 204 return -EAGAIN;
190} 205}
191 206
192static void rsnd_dmaen_quit(struct rsnd_dma *dma) 207static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
193{ 208{
194 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 209 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
195 210
@@ -238,9 +253,9 @@ static const u8 gen2_id_table_cmd[] = {
238 0x38, /* SCU_CMD1 */ 253 0x38, /* SCU_CMD1 */
239}; 254};
240 255
241static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) 256static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
257 struct rsnd_mod *mod)
242{ 258{
243 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
244 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 259 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
245 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 260 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
246 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 261 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
@@ -268,11 +283,12 @@ static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod)
268 return entry[id]; 283 return entry[id];
269} 284}
270 285
271static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from, 286static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
287 struct rsnd_mod *mod_from,
272 struct rsnd_mod *mod_to) 288 struct rsnd_mod *mod_to)
273{ 289{
274 return (rsnd_dmapp_get_id(mod_from) << 24) + 290 return (rsnd_dmapp_get_id(io, mod_from) << 24) +
275 (rsnd_dmapp_get_id(mod_to) << 16); 291 (rsnd_dmapp_get_id(io, mod_to) << 16);
276} 292}
277 293
278#define rsnd_dmapp_addr(dmac, dma, reg) \ 294#define rsnd_dmapp_addr(dmac, dma, reg) \
@@ -299,7 +315,7 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
299 return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); 315 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
300} 316}
301 317
302static void rsnd_dmapp_stop(struct rsnd_dma *dma) 318static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
303{ 319{
304 int i; 320 int i;
305 321
@@ -312,7 +328,7 @@ static void rsnd_dmapp_stop(struct rsnd_dma *dma)
312 } 328 }
313} 329}
314 330
315static void rsnd_dmapp_start(struct rsnd_dma *dma) 331static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
316{ 332{
317 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 333 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
318 334
@@ -321,19 +337,21 @@ static void rsnd_dmapp_start(struct rsnd_dma *dma)
321 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); 337 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
322} 338}
323 339
324static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, 340static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
341 struct rsnd_dma *dma, int id,
325 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 342 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
326{ 343{
327 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 344 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
345 struct rsnd_priv *priv = rsnd_io_to_priv(io);
328 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 346 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
329 struct device *dev = rsnd_priv_to_dev(priv); 347 struct device *dev = rsnd_priv_to_dev(priv);
330 348
331 dmapp->dmapp_id = dmac->dmapp_num; 349 dmapp->dmapp_id = dmac->dmapp_num;
332 dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; 350 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
333 351
334 dmac->dmapp_num++; 352 dmac->dmapp_num++;
335 353
336 rsnd_dmapp_stop(dma); 354 rsnd_dmapp_stop(io, dma);
337 355
338 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", 356 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
339 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); 357 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
@@ -386,12 +404,12 @@ static struct rsnd_dma_ops rsnd_dmapp_ops = {
386#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) 404#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
387 405
388static dma_addr_t 406static dma_addr_t
389rsnd_gen2_dma_addr(struct rsnd_priv *priv, 407rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
390 struct rsnd_mod *mod, 408 struct rsnd_mod *mod,
391 int is_play, int is_from) 409 int is_play, int is_from)
392{ 410{
411 struct rsnd_priv *priv = rsnd_io_to_priv(io);
393 struct device *dev = rsnd_priv_to_dev(priv); 412 struct device *dev = rsnd_priv_to_dev(priv);
394 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
395 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); 413 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
396 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); 414 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
397 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); 415 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
@@ -438,7 +456,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv,
438 dev_err(dev, "DVC is selected without SRC\n"); 456 dev_err(dev, "DVC is selected without SRC\n");
439 457
440 /* use SSIU or SSI ? */ 458 /* use SSIU or SSI ? */
441 if (is_ssi && rsnd_ssi_use_busif(mod)) 459 if (is_ssi && rsnd_ssi_use_busif(io, mod))
442 is_ssi++; 460 is_ssi++;
443 461
444 return (is_from) ? 462 return (is_from) ?
@@ -446,10 +464,12 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv,
446 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; 464 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
447} 465}
448 466
449static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, 467static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
450 struct rsnd_mod *mod, 468 struct rsnd_mod *mod,
451 int is_play, int is_from) 469 int is_play, int is_from)
452{ 470{
471 struct rsnd_priv *priv = rsnd_io_to_priv(io);
472
453 /* 473 /*
454 * gen1 uses default DMA addr 474 * gen1 uses default DMA addr
455 */ 475 */
@@ -459,17 +479,17 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
459 if (!mod) 479 if (!mod)
460 return 0; 480 return 0;
461 481
462 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); 482 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
463} 483}
464 484
465#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ 485#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
466static void rsnd_dma_of_path(struct rsnd_dma *dma, 486static void rsnd_dma_of_path(struct rsnd_dma *dma,
487 struct rsnd_dai_stream *io,
467 int is_play, 488 int is_play,
468 struct rsnd_mod **mod_from, 489 struct rsnd_mod **mod_from,
469 struct rsnd_mod **mod_to) 490 struct rsnd_mod **mod_to)
470{ 491{
471 struct rsnd_mod *this = rsnd_dma_to_mod(dma); 492 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
472 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
473 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 493 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
474 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 494 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
475 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 495 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
@@ -524,17 +544,17 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
524 } 544 }
525} 545}
526 546
527void rsnd_dma_stop(struct rsnd_dma *dma) 547void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
528{ 548{
529 dma->ops->stop(dma); 549 dma->ops->stop(io, dma);
530} 550}
531 551
532void rsnd_dma_start(struct rsnd_dma *dma) 552void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
533{ 553{
534 dma->ops->start(dma); 554 dma->ops->start(io, dma);
535} 555}
536 556
537void rsnd_dma_quit(struct rsnd_dma *dma) 557void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
538{ 558{
539 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 559 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
540 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 560 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
@@ -543,15 +563,14 @@ void rsnd_dma_quit(struct rsnd_dma *dma)
543 if (!dmac) 563 if (!dmac)
544 return; 564 return;
545 565
546 dma->ops->quit(dma); 566 dma->ops->quit(io, dma);
547} 567}
548 568
549int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) 569int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
550{ 570{
551 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
552 struct rsnd_mod *mod_from; 571 struct rsnd_mod *mod_from;
553 struct rsnd_mod *mod_to; 572 struct rsnd_mod *mod_to;
554 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 573 struct rsnd_priv *priv = rsnd_io_to_priv(io);
555 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 574 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
556 int is_play = rsnd_io_is_play(io); 575 int is_play = rsnd_io_is_play(io);
557 576
@@ -564,10 +583,10 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
564 if (!dmac) 583 if (!dmac)
565 return -EAGAIN; 584 return -EAGAIN;
566 585
567 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); 586 rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to);
568 587
569 dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); 588 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
570 dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); 589 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
571 590
572 /* for Gen2 */ 591 /* for Gen2 */
573 if (mod_from && mod_to) 592 if (mod_from && mod_to)
@@ -579,7 +598,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
579 if (rsnd_is_gen1(priv)) 598 if (rsnd_is_gen1(priv))
580 dma->ops = &rsnd_dmaen_ops; 599 dma->ops = &rsnd_dmaen_ops;
581 600
582 return dma->ops->init(priv, dma, id, mod_from, mod_to); 601 return dma->ops->init(io, dma, id, mod_from, mod_to);
583} 602}
584 603
585int rsnd_dma_probe(struct platform_device *pdev, 604int rsnd_dma_probe(struct platform_device *pdev,
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index e5fcb062ad77..36fc020cbc18 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -63,7 +63,8 @@ static const char * const dvc_ramp_rate[] = {
63 "0.125 dB/8192 steps", /* 10111 */ 63 "0.125 dB/8192 steps", /* 10111 */
64}; 64};
65 65
66static void rsnd_dvc_volume_update(struct rsnd_mod *mod) 66static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
67 struct rsnd_mod *mod)
67{ 68{
68 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 69 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
69 u32 val[RSND_DVC_CHANNELS]; 70 u32 val[RSND_DVC_CHANNELS];
@@ -120,6 +121,7 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
120} 121}
121 122
122static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 123static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
124 struct rsnd_dai_stream *io,
123 struct rsnd_priv *priv) 125 struct rsnd_priv *priv)
124{ 126{
125 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 127 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
@@ -134,9 +136,9 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
134} 136}
135 137
136static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, 138static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
139 struct rsnd_dai_stream *io,
137 struct rsnd_priv *priv) 140 struct rsnd_priv *priv)
138{ 141{
139 struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
140 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); 142 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
141 struct device *dev = rsnd_priv_to_dev(priv); 143 struct device *dev = rsnd_priv_to_dev(priv);
142 int dvc_id = rsnd_mod_id(dvc_mod); 144 int dvc_id = rsnd_mod_id(dvc_mod);
@@ -168,10 +170,10 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
168 170
169 rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); 171 rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
170 172
171 rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); 173 rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod, io));
172 174
173 /* ch0/ch1 Volume */ 175 /* ch0/ch1 Volume */
174 rsnd_dvc_volume_update(dvc_mod); 176 rsnd_dvc_volume_update(io, dvc_mod);
175 177
176 rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); 178 rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
177 179
@@ -181,6 +183,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
181} 183}
182 184
183static int rsnd_dvc_quit(struct rsnd_mod *mod, 185static int rsnd_dvc_quit(struct rsnd_mod *mod,
186 struct rsnd_dai_stream *io,
184 struct rsnd_priv *priv) 187 struct rsnd_priv *priv)
185{ 188{
186 rsnd_mod_hw_stop(mod); 189 rsnd_mod_hw_stop(mod);
@@ -189,6 +192,7 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod,
189} 192}
190 193
191static int rsnd_dvc_start(struct rsnd_mod *mod, 194static int rsnd_dvc_start(struct rsnd_mod *mod,
195 struct rsnd_dai_stream *io,
192 struct rsnd_priv *priv) 196 struct rsnd_priv *priv)
193{ 197{
194 rsnd_mod_write(mod, CMD_CTRL, 0x10); 198 rsnd_mod_write(mod, CMD_CTRL, 0x10);
@@ -197,6 +201,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod,
197} 201}
198 202
199static int rsnd_dvc_stop(struct rsnd_mod *mod, 203static int rsnd_dvc_stop(struct rsnd_mod *mod,
204 struct rsnd_dai_stream *io,
200 struct rsnd_priv *priv) 205 struct rsnd_priv *priv)
201{ 206{
202 rsnd_mod_write(mod, CMD_CTRL, 0); 207 rsnd_mod_write(mod, CMD_CTRL, 0);
@@ -205,15 +210,15 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
205} 210}
206 211
207static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, 212static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
213 struct rsnd_dai_stream *io,
208 struct snd_soc_pcm_runtime *rtd) 214 struct snd_soc_pcm_runtime *rtd)
209{ 215{
210 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
211 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 216 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
212 int is_play = rsnd_io_is_play(io); 217 int is_play = rsnd_io_is_play(io);
213 int ret; 218 int ret;
214 219
215 /* Volume */ 220 /* Volume */
216 ret = rsnd_kctrl_new_m(mod, rtd, 221 ret = rsnd_kctrl_new_m(mod, io, rtd,
217 is_play ? 222 is_play ?
218 "DVC Out Playback Volume" : "DVC In Capture Volume", 223 "DVC Out Playback Volume" : "DVC In Capture Volume",
219 rsnd_dvc_volume_update, 224 rsnd_dvc_volume_update,
@@ -222,7 +227,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
222 return ret; 227 return ret;
223 228
224 /* Mute */ 229 /* Mute */
225 ret = rsnd_kctrl_new_m(mod, rtd, 230 ret = rsnd_kctrl_new_m(mod, io, rtd,
226 is_play ? 231 is_play ?
227 "DVC Out Mute Switch" : "DVC In Mute Switch", 232 "DVC Out Mute Switch" : "DVC In Mute Switch",
228 rsnd_dvc_volume_update, 233 rsnd_dvc_volume_update,
@@ -231,7 +236,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
231 return ret; 236 return ret;
232 237
233 /* Ramp */ 238 /* Ramp */
234 ret = rsnd_kctrl_new_s(mod, rtd, 239 ret = rsnd_kctrl_new_s(mod, io, rtd,
235 is_play ? 240 is_play ?
236 "DVC Out Ramp Switch" : "DVC In Ramp Switch", 241 "DVC Out Ramp Switch" : "DVC In Ramp Switch",
237 rsnd_dvc_volume_update, 242 rsnd_dvc_volume_update,
@@ -239,7 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
239 if (ret < 0) 244 if (ret < 0)
240 return ret; 245 return ret;
241 246
242 ret = rsnd_kctrl_new_e(mod, rtd, 247 ret = rsnd_kctrl_new_e(mod, io, rtd,
243 is_play ? 248 is_play ?
244 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", 249 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
245 &dvc->rup, 250 &dvc->rup,
@@ -248,7 +253,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
248 if (ret < 0) 253 if (ret < 0)
249 return ret; 254 return ret;
250 255
251 ret = rsnd_kctrl_new_e(mod, rtd, 256 ret = rsnd_kctrl_new_e(mod, io, rtd,
252 is_play ? 257 is_play ?
253 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", 258 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
254 &dvc->rdown, 259 &dvc->rdown,
@@ -261,7 +266,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
261 return 0; 266 return 0;
262} 267}
263 268
264static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod) 269static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
270 struct rsnd_mod *mod)
265{ 271{
266 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 272 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267 273
@@ -366,7 +372,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
366 372
367 dvc->info = &info->dvc_info[i]; 373 dvc->info = &info->dvc_info[i];
368 374
369 ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, 375 ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops,
370 clk, RSND_MOD_DVC, i); 376 clk, RSND_MOD_DVC, i);
371 if (ret) 377 if (ret)
372 return ret; 378 return ret;
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 03ff071d012f..09fcc54a8ee0 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -165,18 +165,18 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
165 enum rsnd_reg reg, u32 data); 165 enum rsnd_reg reg, u32 data);
166void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, 166void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
167 u32 mask, u32 data); 167 u32 mask, u32 data);
168u32 rsnd_get_adinr(struct rsnd_mod *mod); 168u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
169 169
170/* 170/*
171 * R-Car DMA 171 * R-Car DMA
172 */ 172 */
173struct rsnd_dma; 173struct rsnd_dma;
174struct rsnd_dma_ops { 174struct rsnd_dma_ops {
175 void (*start)(struct rsnd_dma *dma); 175 void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
176 void (*stop)(struct rsnd_dma *dma); 176 void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
177 int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, 177 int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); 178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
179 void (*quit)(struct rsnd_dma *dma); 179 void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
180}; 180};
181 181
182struct rsnd_dmaen { 182struct rsnd_dmaen {
@@ -200,10 +200,10 @@ struct rsnd_dma {
200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) 200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) 201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
202 202
203void rsnd_dma_start(struct rsnd_dma *dma); 203void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
204void rsnd_dma_stop(struct rsnd_dma *dma); 204void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
205int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); 205int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id);
206void rsnd_dma_quit(struct rsnd_dma *dma); 206void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
207int rsnd_dma_probe(struct platform_device *pdev, 207int rsnd_dma_probe(struct platform_device *pdev,
208 const struct rsnd_of_data *of_data, 208 const struct rsnd_of_data *of_data,
209 struct rsnd_priv *priv); 209 struct rsnd_priv *priv);
@@ -224,25 +224,35 @@ enum rsnd_mod_type {
224 224
225struct rsnd_mod_ops { 225struct rsnd_mod_ops {
226 char *name; 226 char *name;
227 struct dma_chan* (*dma_req)(struct rsnd_mod *mod); 227 struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io,
228 struct rsnd_mod *mod);
228 int (*probe)(struct rsnd_mod *mod, 229 int (*probe)(struct rsnd_mod *mod,
230 struct rsnd_dai_stream *io,
229 struct rsnd_priv *priv); 231 struct rsnd_priv *priv);
230 int (*remove)(struct rsnd_mod *mod, 232 int (*remove)(struct rsnd_mod *mod,
233 struct rsnd_dai_stream *io,
231 struct rsnd_priv *priv); 234 struct rsnd_priv *priv);
232 int (*init)(struct rsnd_mod *mod, 235 int (*init)(struct rsnd_mod *mod,
236 struct rsnd_dai_stream *io,
233 struct rsnd_priv *priv); 237 struct rsnd_priv *priv);
234 int (*quit)(struct rsnd_mod *mod, 238 int (*quit)(struct rsnd_mod *mod,
239 struct rsnd_dai_stream *io,
235 struct rsnd_priv *priv); 240 struct rsnd_priv *priv);
236 int (*start)(struct rsnd_mod *mod, 241 int (*start)(struct rsnd_mod *mod,
242 struct rsnd_dai_stream *io,
237 struct rsnd_priv *priv); 243 struct rsnd_priv *priv);
238 int (*stop)(struct rsnd_mod *mod, 244 int (*stop)(struct rsnd_mod *mod,
245 struct rsnd_dai_stream *io,
239 struct rsnd_priv *priv); 246 struct rsnd_priv *priv);
240 int (*pcm_new)(struct rsnd_mod *mod, 247 int (*pcm_new)(struct rsnd_mod *mod,
248 struct rsnd_dai_stream *io,
241 struct snd_soc_pcm_runtime *rtd); 249 struct snd_soc_pcm_runtime *rtd);
242 int (*hw_params)(struct rsnd_mod *mod, 250 int (*hw_params)(struct rsnd_mod *mod,
251 struct rsnd_dai_stream *io,
243 struct snd_pcm_substream *substream, 252 struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *hw_params); 253 struct snd_pcm_hw_params *hw_params);
245 int (*fallback)(struct rsnd_mod *mod, 254 int (*fallback)(struct rsnd_mod *mod,
255 struct rsnd_dai_stream *io,
246 struct rsnd_priv *priv); 256 struct rsnd_priv *priv);
247}; 257};
248 258
@@ -252,32 +262,43 @@ struct rsnd_mod {
252 enum rsnd_mod_type type; 262 enum rsnd_mod_type type;
253 struct rsnd_mod_ops *ops; 263 struct rsnd_mod_ops *ops;
254 struct rsnd_dma dma; 264 struct rsnd_dma dma;
255 struct rsnd_dai_stream *io; 265 struct rsnd_priv *priv;
256 struct clk *clk; 266 struct clk *clk;
257 u32 status; 267 u32 status;
258}; 268};
259/* 269/*
260 * status 270 * status
261 * 271 *
262 * bit 272 * 0xH0000CBA
263 * 0 0: probe 1: remove 273 *
264 * 1 0: init 1: quit 274 * A 0: probe 1: remove
265 * 2 0: start 1: stop 275 * B 0: init 1: quit
266 * 3 0: pcm_new 276 * C 0: start 1: stop
267 * 4 0: fallback
268 * 277 *
269 * 31 bit is always called (see __rsnd_mod_call) 278 * H is always called (see __rsnd_mod_call)
270 * 31 0: hw_params 279 * H 0: pcm_new
280 * H 0: fallback
281 * H 0: hw_params
271 */ 282 */
272#define __rsnd_mod_shift_probe 0 283#define __rsnd_mod_shift_probe 0
273#define __rsnd_mod_shift_remove 0 284#define __rsnd_mod_shift_remove 0
274#define __rsnd_mod_shift_init 1 285#define __rsnd_mod_shift_init 4
275#define __rsnd_mod_shift_quit 1 286#define __rsnd_mod_shift_quit 4
276#define __rsnd_mod_shift_start 2 287#define __rsnd_mod_shift_start 8
277#define __rsnd_mod_shift_stop 2 288#define __rsnd_mod_shift_stop 8
278#define __rsnd_mod_shift_pcm_new 3 289#define __rsnd_mod_shift_pcm_new 28 /* always called */
279#define __rsnd_mod_shift_fallback 4 290#define __rsnd_mod_shift_fallback 28 /* always called */
280#define __rsnd_mod_shift_hw_params 31 /* always called */ 291#define __rsnd_mod_shift_hw_params 28 /* always called */
292
293#define __rsnd_mod_add_probe 1
294#define __rsnd_mod_add_remove -1
295#define __rsnd_mod_add_init 1
296#define __rsnd_mod_add_quit -1
297#define __rsnd_mod_add_start 1
298#define __rsnd_mod_add_stop -1
299#define __rsnd_mod_add_pcm_new 0
300#define __rsnd_mod_add_fallback 0
301#define __rsnd_mod_add_hw_params 0
281 302
282#define __rsnd_mod_call_probe 0 303#define __rsnd_mod_call_probe 0
283#define __rsnd_mod_call_remove 1 304#define __rsnd_mod_call_remove 1
@@ -289,22 +310,25 @@ struct rsnd_mod {
289#define __rsnd_mod_call_fallback 0 310#define __rsnd_mod_call_fallback 0
290#define __rsnd_mod_call_hw_params 0 311#define __rsnd_mod_call_hw_params 0
291 312
292#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) 313#define rsnd_mod_to_priv(mod) ((mod)->priv)
293#define rsnd_mod_to_dma(mod) (&(mod)->dma) 314#define rsnd_mod_to_dma(mod) (&(mod)->dma)
294#define rsnd_mod_to_io(mod) ((mod)->io)
295#define rsnd_mod_id(mod) ((mod)->id) 315#define rsnd_mod_id(mod) ((mod)->id)
296#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) 316#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
297#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) 317#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
298 318
299int rsnd_mod_init(struct rsnd_mod *mod, 319int rsnd_mod_init(struct rsnd_priv *priv,
320 struct rsnd_mod *mod,
300 struct rsnd_mod_ops *ops, 321 struct rsnd_mod_ops *ops,
301 struct clk *clk, 322 struct clk *clk,
302 enum rsnd_mod_type type, 323 enum rsnd_mod_type type,
303 int id); 324 int id);
304void rsnd_mod_quit(struct rsnd_mod *mod); 325void rsnd_mod_quit(struct rsnd_mod *mod);
305char *rsnd_mod_name(struct rsnd_mod *mod); 326char *rsnd_mod_name(struct rsnd_mod *mod);
306int rsnd_mod_is_working(struct rsnd_mod *mod); 327struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
307struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); 328 struct rsnd_mod *mod);
329void rsnd_mod_interrupt(struct rsnd_mod *mod,
330 void (*callback)(struct rsnd_mod *mod,
331 struct rsnd_dai_stream *io));
308 332
309/* 333/*
310 * R-Car sound DAI 334 * R-Car sound DAI
@@ -329,7 +353,7 @@ struct rsnd_dai_stream {
329#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) 353#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
330#define rsnd_io_to_runtime(io) ((io)->substream ? \ 354#define rsnd_io_to_runtime(io) ((io)->substream ? \
331 (io)->substream->runtime : NULL) 355 (io)->substream->runtime : NULL)
332 356int rsnd_io_is_working(struct rsnd_dai_stream *io);
333 357
334struct rsnd_dai { 358struct rsnd_dai {
335 char name[RSND_DAI_NAME_SIZE]; 359 char name[RSND_DAI_NAME_SIZE];
@@ -355,7 +379,8 @@ struct rsnd_dai {
355 379
356struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); 380struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id);
357 381
358void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); 382bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
383void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
359int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); 384int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
360 385
361/* 386/*
@@ -459,7 +484,8 @@ struct rsnd_kctrl_cfg {
459 unsigned int size; 484 unsigned int size;
460 u32 *val; 485 u32 *val;
461 const char * const *texts; 486 const char * const *texts;
462 void (*update)(struct rsnd_mod *mod); 487 void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
488 struct rsnd_dai_stream *io;
463 struct snd_card *card; 489 struct snd_card *card;
464 struct snd_kcontrol *kctrl; 490 struct snd_kcontrol *kctrl;
465}; 491};
@@ -479,22 +505,28 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg);
479#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) 505#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg))
480 506
481int rsnd_kctrl_new_m(struct rsnd_mod *mod, 507int rsnd_kctrl_new_m(struct rsnd_mod *mod,
508 struct rsnd_dai_stream *io,
482 struct snd_soc_pcm_runtime *rtd, 509 struct snd_soc_pcm_runtime *rtd,
483 const unsigned char *name, 510 const unsigned char *name,
484 void (*update)(struct rsnd_mod *mod), 511 void (*update)(struct rsnd_dai_stream *io,
512 struct rsnd_mod *mod),
485 struct rsnd_kctrl_cfg_m *_cfg, 513 struct rsnd_kctrl_cfg_m *_cfg,
486 u32 max); 514 u32 max);
487int rsnd_kctrl_new_s(struct rsnd_mod *mod, 515int rsnd_kctrl_new_s(struct rsnd_mod *mod,
516 struct rsnd_dai_stream *io,
488 struct snd_soc_pcm_runtime *rtd, 517 struct snd_soc_pcm_runtime *rtd,
489 const unsigned char *name, 518 const unsigned char *name,
490 void (*update)(struct rsnd_mod *mod), 519 void (*update)(struct rsnd_dai_stream *io,
520 struct rsnd_mod *mod),
491 struct rsnd_kctrl_cfg_s *_cfg, 521 struct rsnd_kctrl_cfg_s *_cfg,
492 u32 max); 522 u32 max);
493int rsnd_kctrl_new_e(struct rsnd_mod *mod, 523int rsnd_kctrl_new_e(struct rsnd_mod *mod,
524 struct rsnd_dai_stream *io,
494 struct snd_soc_pcm_runtime *rtd, 525 struct snd_soc_pcm_runtime *rtd,
495 const unsigned char *name, 526 const unsigned char *name,
496 struct rsnd_kctrl_cfg_s *_cfg, 527 struct rsnd_kctrl_cfg_s *_cfg,
497 void (*update)(struct rsnd_mod *mod), 528 void (*update)(struct rsnd_dai_stream *io,
529 struct rsnd_mod *mod),
498 const char * const *texts, 530 const char * const *texts,
499 u32 max); 531 u32 max);
500 532
@@ -511,8 +543,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
511 struct rsnd_dai_stream *io, 543 struct rsnd_dai_stream *io,
512 struct snd_pcm_runtime *runtime); 544 struct snd_pcm_runtime *runtime);
513int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 545int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
546 struct rsnd_dai_stream *io,
514 int use_busif); 547 int use_busif);
515int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod); 548int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
549 struct rsnd_dai_stream *io);
516int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); 550int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod);
517int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); 551int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
518 552
@@ -529,7 +563,7 @@ void rsnd_ssi_remove(struct platform_device *pdev,
529struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 563struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
530int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 564int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
531int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 565int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
532int rsnd_ssi_use_busif(struct rsnd_mod *mod); 566int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
533 567
534/* 568/*
535 * R-Car DVC 569 * R-Car DVC
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
index 050b0dbcee65..8caca2e180c3 100644
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -45,61 +45,50 @@ static const struct of_device_id rsrc_card_of_match[] = {
45}; 45};
46MODULE_DEVICE_TABLE(of, rsrc_card_of_match); 46MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
47 47
48#define DAI_NAME_NUM 32
48struct rsrc_card_dai { 49struct rsrc_card_dai {
49 const char *name;
50 unsigned int fmt; 50 unsigned int fmt;
51 unsigned int sysclk; 51 unsigned int sysclk;
52 struct clk *clk; 52 struct clk *clk;
53 char dai_name[DAI_NAME_NUM];
53}; 54};
54 55
55#define RSRC_FB_NUM 2 /* FE/BE */
56#define IDX_CPU 0 56#define IDX_CPU 0
57#define IDX_CODEC 1 57#define IDX_CODEC 1
58struct rsrc_card_priv { 58struct rsrc_card_priv {
59 struct snd_soc_card snd_card; 59 struct snd_soc_card snd_card;
60 struct rsrc_card_dai_props {
61 struct rsrc_card_dai cpu_dai;
62 struct rsrc_card_dai codec_dai;
63 } dai_props[RSRC_FB_NUM];
64 struct snd_soc_codec_conf codec_conf; 60 struct snd_soc_codec_conf codec_conf;
65 struct snd_soc_dai_link dai_link[RSRC_FB_NUM]; 61 struct rsrc_card_dai *dai_props;
62 struct snd_soc_dai_link *dai_link;
63 int dai_num;
66 u32 convert_rate; 64 u32 convert_rate;
67}; 65};
68 66
69#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) 67#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
70#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) 68#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
71#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i) 69#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i))
72#define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data) 70#define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data)
73 71
74static int rsrc_card_startup(struct snd_pcm_substream *substream) 72static int rsrc_card_startup(struct snd_pcm_substream *substream)
75{ 73{
76 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
77 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 75 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
78 struct rsrc_card_dai_props *dai_props = 76 struct rsrc_card_dai *dai_props =
79 &priv->dai_props[rtd - rtd->card->rtd]; 77 rsrc_priv_to_props(priv, rtd - rtd->card->rtd);
80 int ret; 78 int ret;
81 79
82 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
83 if (ret)
84 return ret;
85
86 ret = clk_prepare_enable(dai_props->codec_dai.clk);
87 if (ret)
88 clk_disable_unprepare(dai_props->cpu_dai.clk);
89 80
90 return ret; 81 return clk_prepare_enable(dai_props->clk);
91} 82}
92 83
93static void rsrc_card_shutdown(struct snd_pcm_substream *substream) 84static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
94{ 85{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 86 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 87 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
97 struct rsrc_card_dai_props *dai_props = 88 struct rsrc_card_dai *dai_props =
98 &priv->dai_props[rtd - rtd->card->rtd]; 89 rsrc_priv_to_props(priv, rtd - rtd->card->rtd);
99
100 clk_disable_unprepare(dai_props->cpu_dai.clk);
101 90
102 clk_disable_unprepare(dai_props->codec_dai.clk); 91 clk_disable_unprepare(dai_props->clk);
103} 92}
104 93
105static struct snd_soc_ops rsrc_card_ops = { 94static struct snd_soc_ops rsrc_card_ops = {
@@ -107,21 +96,31 @@ static struct snd_soc_ops rsrc_card_ops = {
107 .shutdown = rsrc_card_shutdown, 96 .shutdown = rsrc_card_shutdown,
108}; 97};
109 98
110static int __rsrc_card_dai_init(struct snd_soc_dai *dai, 99static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
111 struct rsrc_card_dai *set)
112{ 100{
101 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
102 struct snd_soc_dai *dai;
103 struct snd_soc_dai_link *dai_link;
104 struct rsrc_card_dai *dai_props;
105 int num = rtd - rtd->card->rtd;
113 int ret; 106 int ret;
114 107
115 if (set->fmt) { 108 dai_link = rsrc_priv_to_link(priv, num);
116 ret = snd_soc_dai_set_fmt(dai, set->fmt); 109 dai_props = rsrc_priv_to_props(priv, num);
110 dai = dai_link->dynamic ?
111 rtd->cpu_dai :
112 rtd->codec_dai;
113
114 if (dai_props->fmt) {
115 ret = snd_soc_dai_set_fmt(dai, dai_props->fmt);
117 if (ret && ret != -ENOTSUPP) { 116 if (ret && ret != -ENOTSUPP) {
118 dev_err(dai->dev, "set_fmt error\n"); 117 dev_err(dai->dev, "set_fmt error\n");
119 goto err; 118 goto err;
120 } 119 }
121 } 120 }
122 121
123 if (set->sysclk) { 122 if (dai_props->sysclk) {
124 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); 123 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0);
125 if (ret && ret != -ENOTSUPP) { 124 if (ret && ret != -ENOTSUPP) {
126 dev_err(dai->dev, "set_sysclk error\n"); 125 dev_err(dai->dev, "set_sysclk error\n");
127 goto err; 126 goto err;
@@ -134,27 +133,6 @@ err:
134 return ret; 133 return ret;
135} 134}
136 135
137static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
138{
139 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
140 struct snd_soc_dai *codec = rtd->codec_dai;
141 struct snd_soc_dai *cpu = rtd->cpu_dai;
142 struct rsrc_card_dai_props *dai_props;
143 int num, ret;
144
145 num = rtd - rtd->card->rtd;
146 dai_props = &priv->dai_props[num];
147 ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai);
148 if (ret < 0)
149 return ret;
150
151 ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai);
152 if (ret < 0)
153 return ret;
154
155 return 0;
156}
157
158static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 136static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
159 struct snd_pcm_hw_params *params) 137 struct snd_pcm_hw_params *params)
160{ 138{
@@ -170,40 +148,47 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
170 return 0; 148 return 0;
171} 149}
172 150
173static int 151static int rsrc_card_parse_daifmt(struct device_node *node,
174rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, 152 struct device_node *np,
175 struct device_node *np, 153 struct rsrc_card_priv *priv,
176 struct rsrc_card_dai *dai, 154 int idx, bool is_fe)
177 struct snd_soc_dai_link *dai_link,
178 int *args_count)
179{ 155{
180 struct device *dev = rsrc_priv_to_dev(priv); 156 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
181 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); 157 struct device_node *bitclkmaster = NULL;
182 struct of_phandle_args args; 158 struct device_node *framemaster = NULL;
183 struct device_node **p_node; 159 struct device_node *codec = is_fe ? NULL : np;
184 struct clk *clk; 160 unsigned int daifmt;
185 const char **dai_name;
186 const char **name;
187 u32 val;
188 int ret;
189 161
190 if (args_count) { 162 daifmt = snd_soc_of_parse_daifmt(node, NULL,
191 p_node = &dai_link->cpu_of_node; 163 &bitclkmaster, &framemaster);
192 dai_name = &dai_link->cpu_dai_name; 164 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
193 name = &dai_link->cpu_name;
194 } else {
195 p_node = &dai_link->codec_of_node;
196 dai_name = &dai_link->codec_dai_name;
197 name = &dai_link->codec_name;
198 }
199 165
200 if (!np) { 166 if (!bitclkmaster && !framemaster)
201 /* use snd-soc-dummy */ 167 return -EINVAL;
202 *p_node = NULL; 168
203 *dai_name = "snd-soc-dummy-dai"; 169 if (codec == bitclkmaster)
204 *name = "snd-soc-dummy"; 170 daifmt |= (codec == framemaster) ?
205 return 0; 171 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
206 } 172 else
173 daifmt |= (codec == framemaster) ?
174 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
175
176 dai_props->fmt = daifmt;
177
178 of_node_put(bitclkmaster);
179 of_node_put(framemaster);
180
181 return 0;
182}
183
184static int rsrc_card_parse_links(struct device_node *np,
185 struct rsrc_card_priv *priv,
186 int idx, bool is_fe)
187{
188 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
189 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
190 struct of_phandle_args args;
191 int ret;
207 192
208 /* 193 /*
209 * Get node via "sound-dai = <&phandle port>" 194 * Get node via "sound-dai = <&phandle port>"
@@ -214,31 +199,82 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
214 if (ret) 199 if (ret)
215 return ret; 200 return ret;
216 201
217 *p_node = args.np; 202 if (is_fe) {
203 /* BE is dummy */
204 dai_link->codec_of_node = NULL;
205 dai_link->codec_dai_name = "snd-soc-dummy-dai";
206 dai_link->codec_name = "snd-soc-dummy";
207
208 /* FE settings */
209 dai_link->dynamic = 1;
210 dai_link->dpcm_merged_format = 1;
211 dai_link->cpu_of_node = args.np;
212 snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name);
213
214 /* set dai_name */
215 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s",
216 dai_link->cpu_dai_name);
217
218 /*
219 * In soc_bind_dai_link() will check cpu name after
220 * of_node matching if dai_link has cpu_dai_name.
221 * but, it will never match if name was created by
222 * fmt_single_name() remove cpu_dai_name if cpu_args
223 * was 0. See:
224 * fmt_single_name()
225 * fmt_multiple_name()
226 */
227 if (!args.args_count)
228 dai_link->cpu_dai_name = NULL;
229 } else {
230 struct device *dev = rsrc_priv_to_dev(priv);
231 const struct rsrc_card_of_data *of_data;
218 232
219 /* Get dai->name */ 233 of_data = rsrc_dev_to_of_data(dev);
220 ret = snd_soc_of_get_dai_name(np, dai_name);
221 if (ret < 0)
222 return ret;
223 234
224 /* 235 /* FE is dummy */
225 * FIXME 236 dai_link->cpu_of_node = NULL;
226 * 237 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
227 * rsrc assumes DPCM playback/capture 238 dai_link->cpu_name = "snd-soc-dummy";
228 */
229 dai_link->dpcm_playback = 1;
230 dai_link->dpcm_capture = 1;
231 239
232 if (args_count) { 240 /* BE settings */
233 *args_count = args.args_count; 241 dai_link->no_pcm = 1;
234 dai_link->dynamic = 1; 242 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
235 dai_link->dpcm_merged_format = 1; 243 dai_link->codec_of_node = args.np;
236 } else { 244 snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
237 dai_link->no_pcm = 1; 245
238 priv->codec_conf.of_node = (*p_node); 246 /* additional name prefix */
239 priv->codec_conf.name_prefix = of_data->prefix; 247 priv->codec_conf.of_node = dai_link->codec_of_node;
248 priv->codec_conf.name_prefix = of_data->prefix;
249
250 /* set dai_name */
251 snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s",
252 dai_link->codec_dai_name);
240 } 253 }
241 254
255 /* Simple Card assumes platform == cpu */
256 dai_link->platform_of_node = dai_link->cpu_of_node;
257 dai_link->dpcm_playback = 1;
258 dai_link->dpcm_capture = 1;
259 dai_link->name = dai_props->dai_name;
260 dai_link->stream_name = dai_props->dai_name;
261 dai_link->ops = &rsrc_card_ops;
262 dai_link->init = rsrc_card_dai_init;
263
264 return 0;
265}
266
267static int rsrc_card_parse_clk(struct device_node *np,
268 struct rsrc_card_priv *priv,
269 int idx, bool is_fe)
270{
271 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
272 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
273 struct clk *clk;
274 struct device_node *of_np = is_fe ? dai_link->cpu_of_node :
275 dai_link->codec_of_node;
276 u32 val;
277
242 /* 278 /*
243 * Parse dai->sysclk come from "clocks = <&xxx>" 279 * Parse dai->sysclk come from "clocks = <&xxx>"
244 * (if system has common clock) 280 * (if system has common clock)
@@ -247,173 +283,92 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
247 */ 283 */
248 if (of_property_read_bool(np, "clocks")) { 284 if (of_property_read_bool(np, "clocks")) {
249 clk = of_clk_get(np, 0); 285 clk = of_clk_get(np, 0);
250 if (IS_ERR(clk)) { 286 if (IS_ERR(clk))
251 ret = PTR_ERR(clk); 287 return PTR_ERR(clk);
252 return ret;
253 }
254 288
255 dai->sysclk = clk_get_rate(clk); 289 dai_props->sysclk = clk_get_rate(clk);
256 dai->clk = clk; 290 dai_props->clk = clk;
257 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { 291 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
258 dai->sysclk = val; 292 dai_props->sysclk = val;
259 } else { 293 } else {
260 clk = of_clk_get(args.np, 0); 294 clk = of_clk_get(of_np, 0);
261 if (!IS_ERR(clk)) 295 if (!IS_ERR(clk))
262 dai->sysclk = clk_get_rate(clk); 296 dai_props->sysclk = clk_get_rate(clk);
263 } 297 }
264 298
265 return 0; 299 return 0;
266} 300}
267 301
268static int rsrc_card_parse_daifmt(struct device_node *node,
269 struct rsrc_card_priv *priv,
270 struct device_node *codec,
271 int idx)
272{
273 struct device_node *bitclkmaster = NULL;
274 struct device_node *framemaster = NULL;
275 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
276 struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai;
277 struct rsrc_card_dai *codec_dai = &dai_props->codec_dai;
278 unsigned int daifmt;
279
280 daifmt = snd_soc_of_parse_daifmt(node, NULL,
281 &bitclkmaster, &framemaster);
282 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
283
284 if (!bitclkmaster && !framemaster)
285 return -EINVAL;
286
287 if (codec == bitclkmaster)
288 daifmt |= (codec == framemaster) ?
289 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
290 else
291 daifmt |= (codec == framemaster) ?
292 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
293
294 cpu_dai->fmt = daifmt;
295 codec_dai->fmt = daifmt;
296
297 of_node_put(bitclkmaster);
298 of_node_put(framemaster);
299
300 return 0;
301}
302
303static int rsrc_card_dai_link_of(struct device_node *node, 302static int rsrc_card_dai_link_of(struct device_node *node,
303 struct device_node *np,
304 struct rsrc_card_priv *priv, 304 struct rsrc_card_priv *priv,
305 int idx) 305 int idx)
306{ 306{
307 struct device *dev = rsrc_priv_to_dev(priv); 307 struct device *dev = rsrc_priv_to_dev(priv);
308 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); 308 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
309 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); 309 bool is_fe = false;
310 struct device_node *cpu = NULL; 310 int ret;
311 struct device_node *codec = NULL;
312 char *name;
313 char prop[128];
314 int ret, cpu_args;
315
316 cpu = of_get_child_by_name(node, "cpu");
317 codec = of_get_child_by_name(node, "codec");
318
319 if (!cpu || !codec) {
320 ret = -EINVAL;
321 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
322 goto dai_link_of_err;
323 }
324 311
325 ret = rsrc_card_parse_daifmt(node, priv, codec, idx); 312 if (0 == strcmp(np->name, "cpu"))
326 if (ret < 0) 313 is_fe = true;
327 goto dai_link_of_err;
328 314
329 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL, 315 ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe);
330 &dai_props->cpu_dai,
331 dai_link,
332 &cpu_args);
333 if (ret < 0) 316 if (ret < 0)
334 goto dai_link_of_err; 317 return ret;
335 318
336 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL, 319 ret = rsrc_card_parse_links(np, priv, idx, is_fe);
337 &dai_props->codec_dai,
338 dai_link,
339 NULL);
340 if (ret < 0) 320 if (ret < 0)
341 goto dai_link_of_err; 321 return ret;
342
343 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
344 ret = -EINVAL;
345 goto dai_link_of_err;
346 }
347
348 /* Simple Card assumes platform == cpu */
349 dai_link->platform_of_node = dai_link->cpu_of_node;
350
351 /* DAI link name is created from CPU/CODEC dai name */
352 name = devm_kzalloc(dev,
353 strlen(dai_link->cpu_dai_name) +
354 strlen(dai_link->codec_dai_name) + 2,
355 GFP_KERNEL);
356 if (!name) {
357 ret = -ENOMEM;
358 goto dai_link_of_err;
359 }
360
361 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
362 dai_link->codec_dai_name);
363 dai_link->name = dai_link->stream_name = name;
364 dai_link->ops = &rsrc_card_ops;
365 dai_link->init = rsrc_card_dai_init;
366
367 if (idx == IDX_CODEC)
368 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
369
370 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
371 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
372 dai_link->cpu_dai_name,
373 dai_props->cpu_dai.fmt,
374 dai_props->cpu_dai.sysclk);
375 dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
376 dai_link->codec_dai_name,
377 dai_props->codec_dai.fmt,
378 dai_props->codec_dai.sysclk);
379 322
380 /* 323 ret = rsrc_card_parse_clk(np, priv, idx, is_fe);
381 * In soc_bind_dai_link() will check cpu name after 324 if (ret < 0)
382 * of_node matching if dai_link has cpu_dai_name. 325 return ret;
383 * but, it will never match if name was created by
384 * fmt_single_name() remove cpu_dai_name if cpu_args
385 * was 0. See:
386 * fmt_single_name()
387 * fmt_multiple_name()
388 */
389 if (!cpu_args)
390 dai_link->cpu_dai_name = NULL;
391 326
392dai_link_of_err: 327 dev_dbg(dev, "\t%s / %04x / %d\n",
393 of_node_put(cpu); 328 dai_props->dai_name,
394 of_node_put(codec); 329 dai_props->fmt,
330 dai_props->sysclk);
395 331
396 return ret; 332 return ret;
397} 333}
398 334
399static int rsrc_card_parse_of(struct device_node *node, 335static int rsrc_card_parse_of(struct device_node *node,
400 struct rsrc_card_priv *priv) 336 struct rsrc_card_priv *priv,
337 struct device *dev)
401{ 338{
402 struct device *dev = rsrc_priv_to_dev(priv);
403 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); 339 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
340 struct rsrc_card_dai *props;
341 struct snd_soc_dai_link *links;
342 struct device_node *np;
404 int ret; 343 int ret;
405 int i; 344 int i, num;
406 345
407 if (!node) 346 if (!node)
408 return -EINVAL; 347 return -EINVAL;
409 348
410 /* Parse the card name from DT */ 349 num = of_get_child_count(node);
411 snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); 350 props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL);
351 links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL);
352 if (!props || !links)
353 return -ENOMEM;
354
355 priv->dai_props = props;
356 priv->dai_link = links;
357 priv->dai_num = num;
412 358
413 /* DAPM routes */ 359 /* Init snd_soc_card */
360 priv->snd_card.owner = THIS_MODULE;
361 priv->snd_card.dev = dev;
362 priv->snd_card.dai_link = priv->dai_link;
363 priv->snd_card.num_links = num;
364 priv->snd_card.codec_conf = &priv->codec_conf;
365 priv->snd_card.num_configs = 1;
414 priv->snd_card.of_dapm_routes = of_data->routes; 366 priv->snd_card.of_dapm_routes = of_data->routes;
415 priv->snd_card.num_of_dapm_routes = of_data->num_routes; 367 priv->snd_card.num_of_dapm_routes = of_data->num_routes;
416 368
369 /* Parse the card name from DT */
370 snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
371
417 /* sampling rate convert */ 372 /* sampling rate convert */
418 of_property_read_u32(node, "convert-rate", &priv->convert_rate); 373 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
419 374
@@ -421,11 +376,12 @@ static int rsrc_card_parse_of(struct device_node *node,
421 priv->snd_card.name ? priv->snd_card.name : "", 376 priv->snd_card.name ? priv->snd_card.name : "",
422 priv->convert_rate); 377 priv->convert_rate);
423 378
424 /* FE/BE */ 379 i = 0;
425 for (i = 0; i < RSRC_FB_NUM; i++) { 380 for_each_child_of_node(node, np) {
426 ret = rsrc_card_dai_link_of(node, priv, i); 381 ret = rsrc_card_dai_link_of(node, np, priv, i);
427 if (ret < 0) 382 if (ret < 0)
428 return ret; 383 return ret;
384 i++;
429 } 385 }
430 386
431 if (!priv->snd_card.name) 387 if (!priv->snd_card.name)
@@ -452,7 +408,6 @@ static int rsrc_card_unref(struct snd_soc_card *card)
452static int rsrc_card_probe(struct platform_device *pdev) 408static int rsrc_card_probe(struct platform_device *pdev)
453{ 409{
454 struct rsrc_card_priv *priv; 410 struct rsrc_card_priv *priv;
455 struct snd_soc_dai_link *dai_link;
456 struct device_node *np = pdev->dev.of_node; 411 struct device_node *np = pdev->dev.of_node;
457 struct device *dev = &pdev->dev; 412 struct device *dev = &pdev->dev;
458 int ret; 413 int ret;
@@ -462,16 +417,7 @@ static int rsrc_card_probe(struct platform_device *pdev)
462 if (!priv) 417 if (!priv)
463 return -ENOMEM; 418 return -ENOMEM;
464 419
465 /* Init snd_soc_card */ 420 ret = rsrc_card_parse_of(np, priv, dev);
466 priv->snd_card.owner = THIS_MODULE;
467 priv->snd_card.dev = dev;
468 dai_link = priv->dai_link;
469 priv->snd_card.dai_link = dai_link;
470 priv->snd_card.num_links = RSRC_FB_NUM;
471 priv->snd_card.codec_conf = &priv->codec_conf;
472 priv->snd_card.num_configs = 1;
473
474 ret = rsrc_card_parse_of(np, priv);
475 if (ret < 0) { 421 if (ret < 0) {
476 if (ret != -EPROBE_DEFER) 422 if (ret != -EPROBE_DEFER)
477 dev_err(dev, "parse error %d\n", ret); 423 dev_err(dev, "parse error %d\n", ret);
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index fbe9166e26d1..c61c17180142 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -117,10 +117,10 @@ struct rsnd_src {
117/* 117/*
118 * Gen1/Gen2 common functions 118 * Gen1/Gen2 common functions
119 */ 119 */
120static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) 120static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
121 struct rsnd_mod *mod)
121{ 122{
122 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 123 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
123 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
124 int is_play = rsnd_io_is_play(io); 124 int is_play = rsnd_io_is_play(io);
125 125
126 return rsnd_dma_request_channel(rsnd_src_of_node(priv), 126 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
@@ -129,9 +129,9 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
129} 129}
130 130
131int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 131int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
132 struct rsnd_dai_stream *io,
132 int use_busif) 133 int use_busif)
133{ 134{
134 struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
135 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 135 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
136 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 136 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
137 int ssi_id = rsnd_mod_id(ssi_mod); 137 int ssi_id = rsnd_mod_id(ssi_mod);
@@ -174,7 +174,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
174 u32 mask = ~0; 174 u32 mask = ~0;
175 175
176 rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, 176 rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
177 rsnd_get_adinr(ssi_mod)); 177 rsnd_get_adinr(ssi_mod, io));
178 rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); 178 rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
179 rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); 179 rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
180 180
@@ -196,7 +196,8 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
196 return 0; 196 return 0;
197} 197}
198 198
199int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) 199int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
200 struct rsnd_dai_stream *io)
200{ 201{
201 /* 202 /*
202 * DMA settings for SSIU 203 * DMA settings for SSIU
@@ -235,10 +236,9 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
235 return 0; 236 return 0;
236} 237}
237 238
238static u32 rsnd_src_convert_rate(struct rsnd_src *src) 239static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
240 struct rsnd_src *src)
239{ 241{
240 struct rsnd_mod *mod = &src->mod;
241 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
242 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 242 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
243 u32 convert_rate; 243 u32 convert_rate;
244 244
@@ -274,7 +274,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
274 * return convert rate if SRC is used, 274 * return convert rate if SRC is used,
275 * otherwise, return runtime->rate as usual 275 * otherwise, return runtime->rate as usual
276 */ 276 */
277 rate = rsnd_src_convert_rate(src); 277 rate = rsnd_src_convert_rate(io, src);
278 } 278 }
279 279
280 if (!rate) 280 if (!rate)
@@ -283,12 +283,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
283 return rate; 283 return rate;
284} 284}
285 285
286static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) 286static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
287 struct rsnd_dai_stream *io)
287{ 288{
288 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
289 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 289 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
290 struct rsnd_src *src = rsnd_mod_to_src(mod); 290 struct rsnd_src *src = rsnd_mod_to_src(mod);
291 u32 convert_rate = rsnd_src_convert_rate(src); 291 u32 convert_rate = rsnd_src_convert_rate(io, src);
292 u32 fsrate = 0; 292 u32 fsrate = 0;
293 293
294 if (convert_rate) 294 if (convert_rate)
@@ -299,7 +299,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
299 rsnd_mod_write(mod, SRC_SWRSR, 1); 299 rsnd_mod_write(mod, SRC_SWRSR, 1);
300 300
301 /* Set channel number and output bit length */ 301 /* Set channel number and output bit length */
302 rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); 302 rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod, io));
303 303
304 /* Enable the initial value of IFS */ 304 /* Enable the initial value of IFS */
305 if (fsrate) { 305 if (fsrate) {
@@ -316,6 +316,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
316} 316}
317 317
318static int rsnd_src_hw_params(struct rsnd_mod *mod, 318static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct rsnd_dai_stream *io,
319 struct snd_pcm_substream *substream, 320 struct snd_pcm_substream *substream,
320 struct snd_pcm_hw_params *fe_params) 321 struct snd_pcm_hw_params *fe_params)
321{ 322{
@@ -372,6 +373,7 @@ static int rsnd_src_init(struct rsnd_mod *mod,
372} 373}
373 374
374static int rsnd_src_quit(struct rsnd_mod *mod, 375static int rsnd_src_quit(struct rsnd_mod *mod,
376 struct rsnd_dai_stream *io,
375 struct rsnd_priv *priv) 377 struct rsnd_priv *priv)
376{ 378{
377 struct rsnd_src *src = rsnd_mod_to_src(mod); 379 struct rsnd_src *src = rsnd_mod_to_src(mod);
@@ -411,9 +413,9 @@ static int rsnd_src_stop(struct rsnd_mod *mod)
411/* 413/*
412 * Gen1 functions 414 * Gen1 functions
413 */ 415 */
414static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) 416static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io,
417 struct rsnd_mod *mod)
415{ 418{
416 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
417 struct src_route_config { 419 struct src_route_config {
418 u32 mask; 420 u32 mask;
419 int shift; 421 int shift;
@@ -448,13 +450,13 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod)
448 return 0; 450 return 0;
449} 451}
450 452
451static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) 453static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
454 struct rsnd_mod *mod)
452{ 455{
453 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
454 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 456 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
455 struct rsnd_src *src = rsnd_mod_to_src(mod); 457 struct rsnd_src *src = rsnd_mod_to_src(mod);
456 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 458 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
457 u32 convert_rate = rsnd_src_convert_rate(src); 459 u32 convert_rate = rsnd_src_convert_rate(io, src);
458 u32 mask; 460 u32 mask;
459 u32 val; 461 u32 val;
460 int shift; 462 int shift;
@@ -506,12 +508,13 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod)
506 return 0; 508 return 0;
507} 509}
508 510
509static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) 511static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
512 struct rsnd_dai_stream *io)
510{ 513{
511 struct rsnd_src *src = rsnd_mod_to_src(mod); 514 struct rsnd_src *src = rsnd_mod_to_src(mod);
512 int ret; 515 int ret;
513 516
514 ret = rsnd_src_set_convert_rate(mod); 517 ret = rsnd_src_set_convert_rate(mod, io);
515 if (ret < 0) 518 if (ret < 0)
516 return ret; 519 return ret;
517 520
@@ -523,7 +526,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
523 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); 526 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
524 527
525 /* Gen1/Gen2 are not compatible */ 528 /* Gen1/Gen2 are not compatible */
526 if (rsnd_src_convert_rate(src)) 529 if (rsnd_src_convert_rate(io, src))
527 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 530 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
528 531
529 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ 532 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
@@ -532,6 +535,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
532} 535}
533 536
534static int rsnd_src_init_gen1(struct rsnd_mod *mod, 537static int rsnd_src_init_gen1(struct rsnd_mod *mod,
538 struct rsnd_dai_stream *io,
535 struct rsnd_priv *priv) 539 struct rsnd_priv *priv)
536{ 540{
537 int ret; 541 int ret;
@@ -540,15 +544,15 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
540 if (ret < 0) 544 if (ret < 0)
541 return ret; 545 return ret;
542 546
543 ret = rsnd_src_set_route_gen1(mod); 547 ret = rsnd_src_set_route_gen1(io, mod);
544 if (ret < 0) 548 if (ret < 0)
545 return ret; 549 return ret;
546 550
547 ret = rsnd_src_set_convert_rate_gen1(mod); 551 ret = rsnd_src_set_convert_rate_gen1(mod, io);
548 if (ret < 0) 552 if (ret < 0)
549 return ret; 553 return ret;
550 554
551 ret = rsnd_src_set_convert_timing_gen1(mod); 555 ret = rsnd_src_set_convert_timing_gen1(io, mod);
552 if (ret < 0) 556 if (ret < 0)
553 return ret; 557 return ret;
554 558
@@ -556,6 +560,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
556} 560}
557 561
558static int rsnd_src_start_gen1(struct rsnd_mod *mod, 562static int rsnd_src_start_gen1(struct rsnd_mod *mod,
563 struct rsnd_dai_stream *io,
559 struct rsnd_priv *priv) 564 struct rsnd_priv *priv)
560{ 565{
561 int id = rsnd_mod_id(mod); 566 int id = rsnd_mod_id(mod);
@@ -566,6 +571,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod,
566} 571}
567 572
568static int rsnd_src_stop_gen1(struct rsnd_mod *mod, 573static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
574 struct rsnd_dai_stream *io,
569 struct rsnd_priv *priv) 575 struct rsnd_priv *priv)
570{ 576{
571 int id = rsnd_mod_id(mod); 577 int id = rsnd_mod_id(mod);
@@ -643,9 +649,9 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
643 return ret; 649 return ret;
644} 650}
645 651
646static int _rsnd_src_start_gen2(struct rsnd_mod *mod) 652static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
653 struct rsnd_dai_stream *io)
647{ 654{
648 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
649 u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; 655 u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
650 656
651 rsnd_mod_write(mod, SRC_CTRL, val); 657 rsnd_mod_write(mod, SRC_CTRL, val);
@@ -670,15 +676,15 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
670 return rsnd_src_stop(mod); 676 return rsnd_src_stop(mod);
671} 677}
672 678
673static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) 679static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
680 struct rsnd_dai_stream *io)
674{ 681{
675 struct rsnd_mod *mod = data;
676 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 682 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
677 683
678 spin_lock(&priv->lock); 684 spin_lock(&priv->lock);
679 685
680 /* ignore all cases if not working */ 686 /* ignore all cases if not working */
681 if (!rsnd_mod_is_working(mod)) 687 if (!rsnd_io_is_working(io))
682 goto rsnd_src_interrupt_gen2_out; 688 goto rsnd_src_interrupt_gen2_out;
683 689
684 if (rsnd_src_error_record_gen2(mod)) { 690 if (rsnd_src_error_record_gen2(mod)) {
@@ -691,24 +697,32 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
691 697
692 _rsnd_src_stop_gen2(mod); 698 _rsnd_src_stop_gen2(mod);
693 if (src->err < 1024) 699 if (src->err < 1024)
694 _rsnd_src_start_gen2(mod); 700 _rsnd_src_start_gen2(mod, io);
695 else 701 else
696 dev_warn(dev, "no more SRC restart\n"); 702 dev_warn(dev, "no more SRC restart\n");
697 } 703 }
704
698rsnd_src_interrupt_gen2_out: 705rsnd_src_interrupt_gen2_out:
699 spin_unlock(&priv->lock); 706 spin_unlock(&priv->lock);
707}
708
709static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
710{
711 struct rsnd_mod *mod = data;
712
713 rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2);
700 714
701 return IRQ_HANDLED; 715 return IRQ_HANDLED;
702} 716}
703 717
704static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) 718static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
719 struct rsnd_dai_stream *io)
705{ 720{
706 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 721 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
707 struct device *dev = rsnd_priv_to_dev(priv); 722 struct device *dev = rsnd_priv_to_dev(priv);
708 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
709 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 723 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
710 struct rsnd_src *src = rsnd_mod_to_src(mod); 724 struct rsnd_src *src = rsnd_mod_to_src(mod);
711 u32 convert_rate = rsnd_src_convert_rate(src); 725 u32 convert_rate = rsnd_src_convert_rate(io, src);
712 u32 cr, route; 726 u32 cr, route;
713 uint ratio; 727 uint ratio;
714 int ret; 728 int ret;
@@ -726,7 +740,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
726 return -EINVAL; 740 return -EINVAL;
727 } 741 }
728 742
729 ret = rsnd_src_set_convert_rate(mod); 743 ret = rsnd_src_set_convert_rate(mod, io);
730 if (ret < 0) 744 if (ret < 0)
731 return ret; 745 return ret;
732 746
@@ -762,12 +776,12 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
762 return 0; 776 return 0;
763} 777}
764 778
765static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) 779static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io,
780 struct rsnd_mod *mod)
766{ 781{
767 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
768 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 782 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
769 struct rsnd_src *src = rsnd_mod_to_src(mod); 783 struct rsnd_src *src = rsnd_mod_to_src(mod);
770 u32 convert_rate = rsnd_src_convert_rate(src); 784 u32 convert_rate = rsnd_src_convert_rate(io, src);
771 int ret; 785 int ret;
772 786
773 if (convert_rate) 787 if (convert_rate)
@@ -781,6 +795,7 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod)
781} 795}
782 796
783static int rsnd_src_probe_gen2(struct rsnd_mod *mod, 797static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
798 struct rsnd_dai_stream *io,
784 struct rsnd_priv *priv) 799 struct rsnd_priv *priv)
785{ 800{
786 struct rsnd_src *src = rsnd_mod_to_src(mod); 801 struct rsnd_src *src = rsnd_mod_to_src(mod);
@@ -802,7 +817,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
802 return ret; 817 return ret;
803 } 818 }
804 819
805 ret = rsnd_dma_init(priv, 820 ret = rsnd_dma_init(io,
806 rsnd_mod_to_dma(mod), 821 rsnd_mod_to_dma(mod),
807 src->info->dma_id); 822 src->info->dma_id);
808 823
@@ -810,14 +825,16 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
810} 825}
811 826
812static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 827static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
828 struct rsnd_dai_stream *io,
813 struct rsnd_priv *priv) 829 struct rsnd_priv *priv)
814{ 830{
815 rsnd_dma_quit(rsnd_mod_to_dma(mod)); 831 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
816 832
817 return 0; 833 return 0;
818} 834}
819 835
820static int rsnd_src_init_gen2(struct rsnd_mod *mod, 836static int rsnd_src_init_gen2(struct rsnd_mod *mod,
837 struct rsnd_dai_stream *io,
821 struct rsnd_priv *priv) 838 struct rsnd_priv *priv)
822{ 839{
823 int ret; 840 int ret;
@@ -826,11 +843,11 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
826 if (ret < 0) 843 if (ret < 0)
827 return ret; 844 return ret;
828 845
829 ret = rsnd_src_set_convert_rate_gen2(mod); 846 ret = rsnd_src_set_convert_rate_gen2(mod, io);
830 if (ret < 0) 847 if (ret < 0)
831 return ret; 848 return ret;
832 849
833 ret = rsnd_src_set_convert_timing_gen2(mod); 850 ret = rsnd_src_set_convert_timing_gen2(io, mod);
834 if (ret < 0) 851 if (ret < 0)
835 return ret; 852 return ret;
836 853
@@ -838,31 +855,33 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
838} 855}
839 856
840static int rsnd_src_start_gen2(struct rsnd_mod *mod, 857static int rsnd_src_start_gen2(struct rsnd_mod *mod,
858 struct rsnd_dai_stream *io,
841 struct rsnd_priv *priv) 859 struct rsnd_priv *priv)
842{ 860{
843 rsnd_dma_start(rsnd_mod_to_dma(mod)); 861 rsnd_dma_start(io, rsnd_mod_to_dma(mod));
844 862
845 return _rsnd_src_start_gen2(mod); 863 return _rsnd_src_start_gen2(mod, io);
846} 864}
847 865
848static int rsnd_src_stop_gen2(struct rsnd_mod *mod, 866static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
867 struct rsnd_dai_stream *io,
849 struct rsnd_priv *priv) 868 struct rsnd_priv *priv)
850{ 869{
851 int ret; 870 int ret;
852 871
853 ret = _rsnd_src_stop_gen2(mod); 872 ret = _rsnd_src_stop_gen2(mod);
854 873
855 rsnd_dma_stop(rsnd_mod_to_dma(mod)); 874 rsnd_dma_stop(io, rsnd_mod_to_dma(mod));
856 875
857 return ret; 876 return ret;
858} 877}
859 878
860static void rsnd_src_reconvert_update(struct rsnd_mod *mod) 879static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
880 struct rsnd_mod *mod)
861{ 881{
862 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
863 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 882 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
864 struct rsnd_src *src = rsnd_mod_to_src(mod); 883 struct rsnd_src *src = rsnd_mod_to_src(mod);
865 u32 convert_rate = rsnd_src_convert_rate(src); 884 u32 convert_rate = rsnd_src_convert_rate(io, src);
866 u32 fsrate; 885 u32 fsrate;
867 886
868 if (!runtime) 887 if (!runtime)
@@ -878,10 +897,10 @@ static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
878} 897}
879 898
880static int rsnd_src_pcm_new(struct rsnd_mod *mod, 899static int rsnd_src_pcm_new(struct rsnd_mod *mod,
900 struct rsnd_dai_stream *io,
881 struct snd_soc_pcm_runtime *rtd) 901 struct snd_soc_pcm_runtime *rtd)
882{ 902{
883 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 903 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
884 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
885 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 904 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
886 struct rsnd_src *src = rsnd_mod_to_src(mod); 905 struct rsnd_src *src = rsnd_mod_to_src(mod);
887 int ret; 906 int ret;
@@ -912,7 +931,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
912 /* 931 /*
913 * enable sync convert 932 * enable sync convert
914 */ 933 */
915 ret = rsnd_kctrl_new_s(mod, rtd, 934 ret = rsnd_kctrl_new_s(mod, io, rtd,
916 rsnd_io_is_play(io) ? 935 rsnd_io_is_play(io) ?
917 "SRC Out Rate Switch" : 936 "SRC Out Rate Switch" :
918 "SRC In Rate Switch", 937 "SRC In Rate Switch",
@@ -921,7 +940,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
921 if (ret < 0) 940 if (ret < 0)
922 return ret; 941 return ret;
923 942
924 ret = rsnd_kctrl_new_s(mod, rtd, 943 ret = rsnd_kctrl_new_s(mod, io, rtd,
925 rsnd_io_is_play(io) ? 944 rsnd_io_is_play(io) ?
926 "SRC Out Rate" : 945 "SRC Out Rate" :
927 "SRC In Rate", 946 "SRC In Rate",
@@ -1046,7 +1065,7 @@ int rsnd_src_probe(struct platform_device *pdev,
1046 1065
1047 src->info = &info->src_info[i]; 1066 src->info = &info->src_info[i];
1048 1067
1049 ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); 1068 ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i);
1050 if (ret) 1069 if (ret)
1051 return ret; 1070 return ret;
1052 } 1071 }
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 50fa3928a003..2fbe59f7f9b5 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -87,10 +87,9 @@ struct rsnd_ssi {
87#define rsnd_ssi_of_node(priv) \ 87#define rsnd_ssi_of_node(priv) \
88 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") 88 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
89 89
90int rsnd_ssi_use_busif(struct rsnd_mod *mod) 90int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
91{ 91{
92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
93 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
94 int use_busif = 0; 93 int use_busif = 0;
95 94
96 if (!rsnd_ssi_is_dma_mode(mod)) 95 if (!rsnd_ssi_is_dma_mode(mod))
@@ -199,15 +198,17 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
199 } 198 }
200 } 199 }
201 200
202 cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? 201 if (rsnd_ssi_is_dma_mode(&ssi->mod)) {
203 DMEN : /* DMA : enable DMA */ 202 cr_mode = UIEN | OIEN | /* over/under run */
204 DIEN; /* PIO : enable Data interrupt */ 203 DMEN; /* DMA : enable DMA */
205 204 } else {
205 cr_mode = DIEN; /* PIO : enable Data interrupt */
206 }
206 207
207 cr = ssi->cr_own | 208 cr = ssi->cr_own |
208 ssi->cr_clk | 209 ssi->cr_clk |
209 cr_mode | 210 cr_mode |
210 UIEN | OIEN | EN; 211 EN;
211 212
212 rsnd_mod_write(&ssi->mod, SSICR, cr); 213 rsnd_mod_write(&ssi->mod, SSICR, cr);
213 214
@@ -224,10 +225,9 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
224 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); 225 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
225} 226}
226 227
227static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) 228static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
228{ 229{
229 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); 230 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
230 struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod);
231 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 231 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
232 struct device *dev = rsnd_priv_to_dev(priv); 232 struct device *dev = rsnd_priv_to_dev(priv);
233 u32 cr; 233 u32 cr;
@@ -261,7 +261,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
261 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 261 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
262 262
263 if (ssi_parent) 263 if (ssi_parent)
264 rsnd_ssi_hw_stop(ssi_parent); 264 rsnd_ssi_hw_stop(io, ssi_parent);
265 else 265 else
266 rsnd_ssi_master_clk_stop(ssi); 266 rsnd_ssi_master_clk_stop(ssi);
267 } 267 }
@@ -279,10 +279,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
279 * SSI mod common functions 279 * SSI mod common functions
280 */ 280 */
281static int rsnd_ssi_init(struct rsnd_mod *mod, 281static int rsnd_ssi_init(struct rsnd_mod *mod,
282 struct rsnd_dai_stream *io,
282 struct rsnd_priv *priv) 283 struct rsnd_priv *priv)
283{ 284{
284 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 285 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
285 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
286 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 286 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
287 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 287 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
288 u32 cr; 288 u32 cr;
@@ -330,6 +330,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
330} 330}
331 331
332static int rsnd_ssi_quit(struct rsnd_mod *mod, 332static int rsnd_ssi_quit(struct rsnd_mod *mod,
333 struct rsnd_dai_stream *io,
333 struct rsnd_priv *priv) 334 struct rsnd_priv *priv)
334{ 335{
335 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 336 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
@@ -346,6 +347,7 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
346} 347}
347 348
348static int rsnd_ssi_hw_params(struct rsnd_mod *mod, 349static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
350 struct rsnd_dai_stream *io,
349 struct snd_pcm_substream *substream, 351 struct snd_pcm_substream *substream,
350 struct snd_pcm_hw_params *params) 352 struct snd_pcm_hw_params *params)
351{ 353{
@@ -369,7 +371,8 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
369 /* It will be removed on rsnd_ssi_hw_stop */ 371 /* It will be removed on rsnd_ssi_hw_stop */
370 ssi->chan = chan; 372 ssi->chan = chan;
371 if (ssi_parent) 373 if (ssi_parent)
372 return rsnd_ssi_hw_params(&ssi_parent->mod, substream, params); 374 return rsnd_ssi_hw_params(&ssi_parent->mod, io,
375 substream, params);
373 376
374 return 0; 377 return 0;
375} 378}
@@ -386,12 +389,12 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
386} 389}
387 390
388static int rsnd_ssi_start(struct rsnd_mod *mod, 391static int rsnd_ssi_start(struct rsnd_mod *mod,
392 struct rsnd_dai_stream *io,
389 struct rsnd_priv *priv) 393 struct rsnd_priv *priv)
390{ 394{
391 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 395 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
392 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
393 396
394 rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); 397 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod));
395 398
396 rsnd_ssi_hw_start(ssi, io); 399 rsnd_ssi_hw_start(ssi, io);
397 400
@@ -401,6 +404,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
401} 404}
402 405
403static int rsnd_ssi_stop(struct rsnd_mod *mod, 406static int rsnd_ssi_stop(struct rsnd_mod *mod,
407 struct rsnd_dai_stream *io,
404 struct rsnd_priv *priv) 408 struct rsnd_priv *priv)
405{ 409{
406 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 410 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
@@ -409,26 +413,26 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
409 413
410 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); 414 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
411 415
412 rsnd_ssi_hw_stop(ssi); 416 rsnd_ssi_hw_stop(io, ssi);
413 417
414 rsnd_src_ssiu_stop(mod); 418 rsnd_src_ssiu_stop(mod, io);
415 419
416 return 0; 420 return 0;
417} 421}
418 422
419static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) 423static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
424 struct rsnd_dai_stream *io)
420{ 425{
421 struct rsnd_ssi *ssi = data; 426 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
422 struct rsnd_mod *mod = &ssi->mod;
423 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 427 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
424 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
425 int is_dma = rsnd_ssi_is_dma_mode(mod); 428 int is_dma = rsnd_ssi_is_dma_mode(mod);
426 u32 status; 429 u32 status;
430 bool elapsed = false;
427 431
428 spin_lock(&priv->lock); 432 spin_lock(&priv->lock);
429 433
430 /* ignore all cases if not working */ 434 /* ignore all cases if not working */
431 if (!rsnd_mod_is_working(mod)) 435 if (!rsnd_io_is_working(io))
432 goto rsnd_ssi_interrupt_out; 436 goto rsnd_ssi_interrupt_out;
433 437
434 status = rsnd_mod_read(mod, SSISR); 438 status = rsnd_mod_read(mod, SSISR);
@@ -449,11 +453,11 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
449 else 453 else
450 *buf = rsnd_mod_read(mod, SSIRDR); 454 *buf = rsnd_mod_read(mod, SSIRDR);
451 455
452 rsnd_dai_pointer_update(io, sizeof(*buf)); 456 elapsed = rsnd_dai_pointer_update(io, sizeof(*buf));
453 } 457 }
454 458
455 /* PIO / DMA */ 459 /* DMA only */
456 if (status & (UIRQ | OIRQ)) { 460 if (is_dma && (status & (UIRQ | OIRQ))) {
457 struct device *dev = rsnd_priv_to_dev(priv); 461 struct device *dev = rsnd_priv_to_dev(priv);
458 462
459 /* 463 /*
@@ -462,9 +466,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
462 dev_dbg(dev, "%s[%d] restart\n", 466 dev_dbg(dev, "%s[%d] restart\n",
463 rsnd_mod_name(mod), rsnd_mod_id(mod)); 467 rsnd_mod_name(mod), rsnd_mod_id(mod));
464 468
465 rsnd_ssi_stop(mod, priv); 469 rsnd_ssi_stop(mod, io, priv);
466 if (ssi->err < 1024) 470 if (ssi->err < 1024)
467 rsnd_ssi_start(mod, priv); 471 rsnd_ssi_start(mod, io, priv);
468 else 472 else
469 dev_warn(dev, "no more SSI restart\n"); 473 dev_warn(dev, "no more SSI restart\n");
470 } 474 }
@@ -474,6 +478,16 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
474rsnd_ssi_interrupt_out: 478rsnd_ssi_interrupt_out:
475 spin_unlock(&priv->lock); 479 spin_unlock(&priv->lock);
476 480
481 if (elapsed)
482 rsnd_dai_period_elapsed(io);
483}
484
485static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
486{
487 struct rsnd_mod *mod = data;
488
489 rsnd_mod_interrupt(mod, __rsnd_ssi_interrupt);
490
477 return IRQ_HANDLED; 491 return IRQ_HANDLED;
478} 492}
479 493
@@ -481,6 +495,7 @@ rsnd_ssi_interrupt_out:
481 * SSI PIO 495 * SSI PIO
482 */ 496 */
483static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, 497static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
498 struct rsnd_dai_stream *io,
484 struct rsnd_priv *priv) 499 struct rsnd_priv *priv)
485{ 500{
486 struct device *dev = rsnd_priv_to_dev(priv); 501 struct device *dev = rsnd_priv_to_dev(priv);
@@ -490,7 +505,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
490 ret = devm_request_irq(dev, ssi->info->irq, 505 ret = devm_request_irq(dev, ssi->info->irq,
491 rsnd_ssi_interrupt, 506 rsnd_ssi_interrupt,
492 IRQF_SHARED, 507 IRQF_SHARED,
493 dev_name(dev), ssi); 508 dev_name(dev), mod);
494 509
495 return ret; 510 return ret;
496} 511}
@@ -506,6 +521,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
506}; 521};
507 522
508static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, 523static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
524 struct rsnd_dai_stream *io,
509 struct rsnd_priv *priv) 525 struct rsnd_priv *priv)
510{ 526{
511 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 527 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
@@ -516,25 +532,26 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
516 ret = devm_request_irq(dev, ssi->info->irq, 532 ret = devm_request_irq(dev, ssi->info->irq,
517 rsnd_ssi_interrupt, 533 rsnd_ssi_interrupt,
518 IRQF_SHARED, 534 IRQF_SHARED,
519 dev_name(dev), ssi); 535 dev_name(dev), mod);
520 if (ret) 536 if (ret)
521 return ret; 537 return ret;
522 538
523 ret = rsnd_dma_init( 539 ret = rsnd_dma_init(
524 priv, rsnd_mod_to_dma(mod), 540 io, rsnd_mod_to_dma(mod),
525 dma_id); 541 dma_id);
526 542
527 return ret; 543 return ret;
528} 544}
529 545
530static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, 546static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
547 struct rsnd_dai_stream *io,
531 struct rsnd_priv *priv) 548 struct rsnd_priv *priv)
532{ 549{
533 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 550 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
534 struct device *dev = rsnd_priv_to_dev(priv); 551 struct device *dev = rsnd_priv_to_dev(priv);
535 int irq = ssi->info->irq; 552 int irq = ssi->info->irq;
536 553
537 rsnd_dma_quit(rsnd_mod_to_dma(mod)); 554 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
538 555
539 /* PIO will request IRQ again */ 556 /* PIO will request IRQ again */
540 devm_free_irq(dev, irq, ssi); 557 devm_free_irq(dev, irq, ssi);
@@ -543,6 +560,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
543} 560}
544 561
545static int rsnd_ssi_fallback(struct rsnd_mod *mod, 562static int rsnd_ssi_fallback(struct rsnd_mod *mod,
563 struct rsnd_dai_stream *io,
546 struct rsnd_priv *priv) 564 struct rsnd_priv *priv)
547{ 565{
548 struct device *dev = rsnd_priv_to_dev(priv); 566 struct device *dev = rsnd_priv_to_dev(priv);
@@ -563,37 +581,39 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod,
563} 581}
564 582
565static int rsnd_ssi_dma_start(struct rsnd_mod *mod, 583static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
584 struct rsnd_dai_stream *io,
566 struct rsnd_priv *priv) 585 struct rsnd_priv *priv)
567{ 586{
568 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); 587 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
569 588
570 rsnd_dma_start(dma); 589 rsnd_dma_start(io, dma);
571 590
572 rsnd_ssi_start(mod, priv); 591 rsnd_ssi_start(mod, io, priv);
573 592
574 return 0; 593 return 0;
575} 594}
576 595
577static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, 596static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
597 struct rsnd_dai_stream *io,
578 struct rsnd_priv *priv) 598 struct rsnd_priv *priv)
579{ 599{
580 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); 600 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
581 601
582 rsnd_ssi_stop(mod, priv); 602 rsnd_ssi_stop(mod, io, priv);
583 603
584 rsnd_dma_stop(dma); 604 rsnd_dma_stop(io, dma);
585 605
586 return 0; 606 return 0;
587} 607}
588 608
589static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod) 609static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
610 struct rsnd_mod *mod)
590{ 611{
591 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 612 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
592 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
593 int is_play = rsnd_io_is_play(io); 613 int is_play = rsnd_io_is_play(io);
594 char *name; 614 char *name;
595 615
596 if (rsnd_ssi_use_busif(mod)) 616 if (rsnd_ssi_use_busif(io, mod))
597 name = is_play ? "rxu" : "txu"; 617 name = is_play ? "rxu" : "txu";
598 else 618 else
599 name = is_play ? "rx" : "tx"; 619 name = is_play ? "rx" : "tx";
@@ -776,7 +796,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
776 else if (rsnd_ssi_pio_available(ssi)) 796 else if (rsnd_ssi_pio_available(ssi))
777 ops = &rsnd_ssi_pio_ops; 797 ops = &rsnd_ssi_pio_ops;
778 798
779 ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); 799 ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i);
780 if (ret) 800 if (ret)
781 return ret; 801 return ret;
782 802