LKML Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards
       [not found] <CGME20190207170044epcas2p3d00762663b971845bc86db84af7d3b23@epcas2p3.samsung.com>
@ 2019-02-07 17:00 ` Sylwester Nawrocki
       [not found]   ` <CGME20190207170047epcas1p42d7ec4acfd976871c676efa5aecb33bc@epcas1p4.samsung.com>
                     ` (20 more replies)
  0 siblings, 21 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This series restores support for the secondary CPU DAI in samsung/i2s.c
driver and adds support for secondary CPU DAI on Odroid boards.

First two patches introduce changes in ASoC generic dmaengine driver
so as to use custom DMA config as introduced in commit
194c7dea00c6 "ASoC: dmaengine: add custom DMA config to snd_dmaengine_pcm_config"
for handling custom DMA channel names on all Samsung platforms.

Patches 7/22...16/22 are mostly clean up, following conversion to single
component with multiple DAIs in patch 5/22, allowing to reference both
primary/secondary DAI in DT.

I tried to avoid registering new platform device in probe() as it doesn't
play well with deferred probing but couldn't find a way to avoid that new
device, unique devices are needed to register "PCM" components for each
CPU DAI.

I am not entirely sure we should be removing the
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag like this, it might all
be a bit more explicit with the flag.

The patch set has been tested on Odroid U3, XU3, XU4 and Mini2440
(s3c2440 non-DT) boards.

This series depends on patch
"ASoC: samsung: Prevent clk_get_rate() calls in atomic context"

Sylwester Nawrocki (22):
  ASoC: dmaengine: Improve of_node test in
    dmaengine_pcm_request_chan_of()
  ASoC: dmaengine: Extend use of chan_names provided in custom DMA
    config
  ASoC: samsung: dmaengine: Allow to specify custom DMA device
  ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI
  ASoC: samsung: i2s: Convert to single component with multiple DAIs
  ASoC: samsung: i2s: Restore support for the secondary PCM
  ASoC: samsung: i2s: Move clk supplier data to common driver data
    structure
  ASoC: samsung: i2s: Add widgets and routes for DPCM support
  ASoC: samsung: i2s: Move core clk to the driver common data structure
  ASoC: samsung: i2s: Move opclk data to common driver data structure
  ASoC: samsung: i2s: Move registers cache to common driver data
    structure
  ASoC: samsung: i2s: Move SFR pointer to common driver data structure
  ASoC: samsung: i2s: Drop spinlock pointer from i2s_dai data structure
  ASoC: samsung: i2s: Move IP variant data to common driver data
    structure
  ASoC: samsung: i2s: Move quirks data to common driver data structure
  ASoC: samsung: i2s: Get rid of a static spinlock
  ASoC: samsung: odroid: Add support for secondary CPU DAI
  ASoC: samsung: Specify DMA channel names through custom DMA config
  ASoC: samsung: Drop DAI DMA data chan_name assignments
  ASoC: dmaengine: Remove unused
    SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag
  ARM: dts: exynos5422-odroidxu3: Add support for secondary DAI
  ARM: dts: exynos5422-odroidxu4: Add support for secondary DAI

 .../boot/dts/exynos5422-odroidxu3-audio.dtsi  |   6 +-
 arch/arm/boot/dts/exynos5422-odroidxu4.dts    |   4 +-
 include/sound/dmaengine_pcm.h                 |   6 -
 sound/soc/samsung/dma.h                       |   3 +-
 sound/soc/samsung/dmaengine.c                 |  16 +-
 sound/soc/samsung/i2s.c                       | 630 ++++++++++--------
 sound/soc/samsung/odroid.c                    | 132 +++-
 sound/soc/samsung/pcm.c                       |   2 +-
 sound/soc/samsung/s3c2412-i2s.c               |   4 +-
 sound/soc/samsung/s3c24xx-i2s.c               |   4 +-
 sound/soc/samsung/spdif.c                     |   2 +-
 sound/soc/soc-generic-dmaengine-pcm.c         |  13 +-
 12 files changed, 489 insertions(+), 333 deletions(-)

--
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 01/22] ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()
       [not found]   ` <CGME20190207170047epcas1p42d7ec4acfd976871c676efa5aecb33bc@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:29       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()" to the asoc tree Mark Brown
  0 siblings, 2 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

Currently when of_node of the "PCM" device is null
dmaengine_pcm_request_chan_of() function will bail out, including cases
when custom DMA device is intended to be used.  To have the channels
properly requested when custom DMA device is provided extend the of_node
test to also consider dma_dev->of_node.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/soc-generic-dmaengine-pcm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 30e791a53352..6d7638c1233d 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -415,7 +415,8 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
 
 	if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT |
 			   SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) ||
-	    !dev->of_node)
+	     (!dev->of_node && !(config && config->dma_dev &&
+				config->dma_dev->of_node)))
 		return 0;
 
 	if (config && config->dma_dev) {
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 02/22] ASoC: dmaengine: Extend use of chan_names provided in custom DMA config
       [not found]   ` <CGME20190207170051epcas1p37a1acaef52cffb01af00c8d34dd9b1dd@epcas1p3.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:31       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: dmaengine: Extend use of chan_names provided in custom DMA config" to the asoc tree Mark Brown
  0 siblings, 2 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

There are currently two ways to specify custom DMA channel names:
 - through the SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag and
   snd_dmaengine_dai_dma_data data structure,
 - through chan_names field of struct snd_dmaengine_pcm_config.

In order to replace the DAI DMA data method with the custom DMA config
one on non-DT platforms the dmaengine_pcm_new() function is extended
to also consider channel names specified in the custom DMA config.
If both config->chan_names and dma_data->chan_name are provided
the former will be used.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/soc-generic-dmaengine-pcm.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6d7638c1233d..1b44e363c50c 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -288,9 +288,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 		dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 		if (!pcm->chan[i] &&
-		    (pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME))
+		    ((pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME) ||
+		     (config && config->chan_names[i]))) {
+			const char *chan_name = dma_data->chan_name;
+
+			if (config && config->chan_names[i])
+				chan_name = config->chan_names[i];
+
 			pcm->chan[i] = dma_request_slave_channel(dev,
-				dma_data->chan_name);
+				chan_name);
+		}
 
 		if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) {
 			pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd,
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 03/22] ASoC: samsung: dmaengine: Allow to specify custom DMA device
       [not found]   ` <CGME20190207170054epcas1p1e61320d308bc5be30187919f3360f501@epcas1p1.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:31       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: samsung: dmaengine: Allow to specify custom DMA device" to the asoc tree Mark Brown
  0 siblings, 2 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The additional function argument will allow to select proper DMA device
for requesting DMA channel for the secondary CPU DAI.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/dma.h         | 3 ++-
 sound/soc/samsung/dmaengine.c   | 4 +++-
 sound/soc/samsung/i2s.c         | 4 ++--
 sound/soc/samsung/pcm.c         | 2 +-
 sound/soc/samsung/s3c2412-i2s.c | 2 +-
 sound/soc/samsung/s3c24xx-i2s.c | 2 +-
 sound/soc/samsung/spdif.c       | 2 +-
 7 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 7ae580d677c8..0ae15d01a3f6 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -17,5 +17,6 @@
  * otherwise actual DMA channel names must be passed to this function.
  */
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
-				       const char *tx, const char *rx);
+				       const char *tx, const char *rx,
+				       struct device *dma_dev);
 #endif /* _SAMSUNG_DMA_H */
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 9104c98deeb7..84601fa9aa46 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -25,7 +25,8 @@
 #include "dma.h"
 
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
-				       const char *tx, const char *rx)
+				       const char *tx, const char *rx,
+				       struct device *dma_dev)
 {
 	unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
 	struct snd_dmaengine_pcm_config *pcm_conf;
@@ -36,6 +37,7 @@ int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
 
 	pcm_conf->prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config;
 	pcm_conf->compat_filter_fn = filter;
+	pcm_conf->dma_dev = dma_dev;
 
 	if (dev->of_node) {
 		pcm_conf->chan_names[SNDRV_PCM_STREAM_PLAYBACK] = tx;
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index ce00fe2f6aae..9d3dcb2204fe 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1345,7 +1345,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->i2s_dai_drv.playback.channels_max = 6;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret < 0)
 		goto err_disable_clk;
 
@@ -1382,7 +1382,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->sec_dai = sec_dai;
 
 		ret = samsung_asoc_dma_platform_register(&pdev->dev,
-					sec_dai->filter, "tx-sec", NULL);
+					sec_dai->filter, "tx-sec", NULL, NULL);
 		if (ret < 0)
 			goto err_disable_clk;
 
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 37f95eee1558..3c7baa561084 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -553,7 +553,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
 	pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
 		goto err_dis_pclk;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index cc0840fff5aa..67dfa27ae321 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -177,7 +177,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev,
 						 pdata->dma_filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		pr_err("failed to register the DMA: %d\n", ret);
 		return ret;
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 8d58d02183bf..ba0f2b94f8d4 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -446,7 +446,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
 	s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, NULL,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register the DMA: %d\n", ret);
 		return ret;
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index cb59911e65c0..5e4afb330416 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -430,7 +430,7 @@ static int spdif_probe(struct platform_device *pdev)
 	spdif->dma_playback = &spdif_stereo_out;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
 		goto err4;
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI
       [not found]   ` <CGME20190207170058epcas1p4e2fadf4aae2ece3c47c0750a094a4fbb@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:37       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI" to the asoc tree Mark Brown
  0 siblings, 2 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

Make sure i2s->rclk_srcrate is properly initialized also during
playback through the secondary DAI.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9d3dcb2204fe..d5ddad23d5e5 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -604,6 +604,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 	unsigned int fmt)
 {
 	struct i2s_dai *i2s = to_info(dai);
+	struct i2s_dai *other = get_other_dai(i2s);
 	int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
 	u32 mod, tmp = 0;
 	unsigned long flags;
@@ -661,7 +662,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 		 * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
 		 * clock configuration assigned in DT is not overwritten.
 		 */
-		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL)
+		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL &&
+		    other->clk_data.clks == NULL)
 			i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 							0, SND_SOC_CLOCK_IN);
 		break;
@@ -699,6 +701,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
 	struct i2s_dai *i2s = to_info(dai);
+	struct i2s_dai *other = get_other_dai(i2s);
 	u32 mod, mask = 0, val = 0;
 	struct clk *rclksrc;
 	unsigned long flags;
@@ -784,6 +787,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 	i2s->frmclk = params_rate(params);
 
 	rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
+	if (!rclksrc || IS_ERR(rclksrc))
+		rclksrc = other->clk_table[CLK_I2S_RCLK_SRC];
+
 	if (rclksrc && !IS_ERR(rclksrc))
 		i2s->rclk_srcrate = clk_get_rate(rclksrc);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 05/22] ASoC: samsung: i2s: Convert to single component with multiple DAIs
       [not found]   ` <CGME20190207170102epcas1p445f2a5d8e70bc3a6e42424034c2eb34a@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:38       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Convert to single component with multiple DAIs" to the asoc tree Mark Brown
  0 siblings, 2 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This patch includes minimal changes as a prerequisite for adding support
for the Exynos secondary I2S interface as second DAI of the I2S component.
Doing it that way allows to avoid problems as indicated in commmit
6b01e0365b1689 ("ASoC: samsung: i2s: disable secondary DAI until it gets fixed")

The samsung_i2s_get_pri_dai() helper added in this patch is temporary and
will be removed in one of subsequent patches.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 192 ++++++++++++++++++++++++----------------
 1 file changed, 115 insertions(+), 77 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d5ddad23d5e5..4bc3b181f1c2 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -34,6 +34,9 @@
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 
+#define SAMSUNG_I2S_ID_PRIMARY		1
+#define SAMSUNG_I2S_ID_SECONDARY	2
+
 struct samsung_i2s_variant_regs {
 	unsigned int	bfs_off;
 	unsigned int	rfs_off;
@@ -79,8 +82,10 @@ struct i2s_dai {
 #define DAI_OPENED	(1 << 0) /* Dai is opened */
 #define DAI_MANAGER	(1 << 1) /* Dai is the manager */
 	unsigned mode;
+
 	/* Driver for this DAI */
-	struct snd_soc_dai_driver i2s_dai_drv;
+	struct snd_soc_dai_driver *drv;
+
 	/* DMA parameters */
 	struct snd_dmaengine_dai_dma_data dma_playback;
 	struct snd_dmaengine_dai_dma_data dma_capture;
@@ -92,8 +97,6 @@ struct i2s_dai {
 	u32	suspend_i2spsr;
 	const struct samsung_i2s_variant_regs *variant_regs;
 
-	/* Spinlock protecting access to the device's registers */
-	spinlock_t spinlock;
 	spinlock_t *lock;
 
 	/* Below fields are only valid if this is the primary FIFO */
@@ -104,10 +107,29 @@ struct i2s_dai {
 /* Lock for cross i/f checks */
 static DEFINE_SPINLOCK(lock);
 
-/* If this is the 'overlay' stereo DAI */
+struct samsung_i2s_priv {
+	struct platform_device *pdev;
+
+	/* Spinlock protecting access to the device's registers */
+	spinlock_t spinlock;
+
+	/* CPU DAIs and their corresponding drivers */
+	struct i2s_dai *dai;
+	struct snd_soc_dai_driver *dai_drv;
+	int num_dais;
+};
+
+struct i2s_dai *samsung_i2s_get_pri_dai(struct device *dev)
+{
+	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
+
+	return &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
+}
+
+/* Returns true if this is the 'overlay' stereo DAI */
 static inline bool is_secondary(struct i2s_dai *i2s)
 {
-	return i2s->pri_dai ? true : false;
+	return i2s->drv->id == SAMSUNG_I2S_ID_SECONDARY;
 }
 
 /* If operating in SoC-Slave mode */
@@ -202,7 +224,9 @@ static inline bool any_active(struct i2s_dai *i2s)
 
 static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
 {
-	return snd_soc_dai_get_drvdata(dai);
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
+
+	return &priv->dai[dai->id - 1];
 }
 
 static inline bool is_opened(struct i2s_dai *i2s)
@@ -1065,7 +1089,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 
 static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 {
-	struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
+	struct i2s_dai *i2s = to_info(dai);
 	unsigned long flags;
 
 	pm_runtime_get_sync(dai->dev);
@@ -1102,47 +1126,63 @@ static const struct snd_soc_component_driver samsung_i2s_component = {
 					SNDRV_PCM_FMTBIT_S16_LE | \
 					SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev,
-				const struct samsung_i2s_dai_data *i2s_dai_data,
-				bool sec)
+static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
+			  const struct samsung_i2s_dai_data *i2s_dai_data,
+			  int num_dais)
 {
-	struct i2s_dai *i2s;
-
-	i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
-	if (i2s == NULL)
-		return NULL;
-
-	i2s->pdev = pdev;
-	i2s->pri_dai = NULL;
-	i2s->sec_dai = NULL;
-	i2s->i2s_dai_drv.id = 1;
-	i2s->i2s_dai_drv.symmetric_rates = 1;
-	i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
-	i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
-	i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
-	i2s->i2s_dai_drv.suspend = i2s_suspend;
-	i2s->i2s_dai_drv.resume = i2s_resume;
-	i2s->i2s_dai_drv.playback.channels_min = 1;
-	i2s->i2s_dai_drv.playback.channels_max = 2;
-	i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates;
-	i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
-
-	if (!sec) {
-		i2s->i2s_dai_drv.name = SAMSUNG_I2S_DAI;
-		i2s->i2s_dai_drv.capture.channels_min = 1;
-		i2s->i2s_dai_drv.capture.channels_max = 2;
-		i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates;
-		i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
-	} else {
-		i2s->i2s_dai_drv.name = SAMSUNG_I2S_DAI_SEC;
+	static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" };
+	struct snd_soc_dai_driver *dai_drv;
+	struct i2s_dai *dai;
+	int i;
+
+	priv->dai = devm_kcalloc(&priv->pdev->dev, num_dais,
+				     sizeof(*dai), GFP_KERNEL);
+	if (!priv->dai)
+		return -ENOMEM;
+
+	priv->dai_drv = devm_kcalloc(&priv->pdev->dev, num_dais,
+				     sizeof(*dai_drv), GFP_KERNEL);
+	if (!priv->dai_drv)
+		return -ENOMEM;
+
+	for (i = 0; i < num_dais; i++) {
+		dai_drv = &priv->dai_drv[i];
+
+		dai_drv->probe = samsung_i2s_dai_probe;
+		dai_drv->remove = samsung_i2s_dai_remove;
+		dai_drv->suspend = i2s_suspend;
+		dai_drv->resume = i2s_resume;
+
+		dai_drv->symmetric_rates = 1;
+		dai_drv->ops = &samsung_i2s_dai_ops;
+
+		dai_drv->playback.channels_min = 1;
+		dai_drv->playback.channels_max = 2;
+		dai_drv->playback.rates = i2s_dai_data->pcm_rates;
+		dai_drv->playback.formats = SAMSUNG_I2S_FMTS;
+
+		dai_drv->id = i + 1;
+		dai_drv->name = dai_names[i];
+
+		priv->dai[i].drv = &priv->dai_drv[i];
+		priv->dai[i].pdev = priv->pdev;
 	}
-	return i2s;
+
+	/* Initialize capture only for the primary DAI */
+	dai_drv = &priv->dai_drv[SAMSUNG_I2S_ID_PRIMARY - 1];
+
+	dai_drv->capture.channels_min = 1;
+	dai_drv->capture.channels_max = 2;
+	dai_drv->capture.rates = i2s_dai_data->pcm_rates;
+	dai_drv->capture.formats = SAMSUNG_I2S_FMTS;
+
+	return 0;
 }
 
 #ifdef CONFIG_PM
 static int i2s_runtime_suspend(struct device *dev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 
 	i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
 	i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
@@ -1157,7 +1197,7 @@ static int i2s_runtime_suspend(struct device *dev)
 
 static int i2s_runtime_resume(struct device *dev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk);
@@ -1192,7 +1232,7 @@ static void i2s_unregister_clocks(struct i2s_dai *i2s)
 
 static void i2s_unregister_clock_provider(struct platform_device *pdev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(&pdev->dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(&pdev->dev);
 
 	of_clk_del_provider(pdev->dev.of_node);
 	i2s_unregister_clocks(i2s);
@@ -1200,11 +1240,12 @@ static void i2s_unregister_clock_provider(struct platform_device *pdev)
 
 static int i2s_register_clock_provider(struct platform_device *pdev)
 {
+
 	const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
 	const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
 	const char *p_names[2] = { NULL };
 	struct device *dev = &pdev->dev;
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
 	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
 	struct clk *rclksrc;
@@ -1279,7 +1320,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	u32 regs_base, quirks = 0, idma_addr = 0;
 	struct device_node *np = pdev->dev.of_node;
 	const struct samsung_i2s_dai_data *i2s_dai_data;
-	int ret;
+	int num_dais, ret;
+	struct samsung_i2s_priv *priv;
 
 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
 		i2s_dai_data = of_device_get_match_data(&pdev->dev);
@@ -1287,14 +1329,24 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		i2s_dai_data = (struct samsung_i2s_dai_data *)
 				platform_get_device_id(pdev)->driver_data;
 
-	pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false);
-	if (!pri_dai) {
-		dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
-	}
 
-	spin_lock_init(&pri_dai->spinlock);
-	pri_dai->lock = &pri_dai->spinlock;
+	quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
+	quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
+
+	num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
+	priv->pdev = pdev;
+
+	ret = i2s_alloc_dais(priv, i2s_dai_data, num_dais);
+	if (ret < 0)
+		return ret;
+
+	pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
+
+	spin_lock_init(&priv->spinlock);
+	pri_dai->lock = &priv->spinlock;
 
 	if (!np) {
 		if (i2s_pdata == NULL) {
@@ -1306,10 +1358,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
 		pri_dai->filter = i2s_pdata->dma_filter;
 
-		quirks = i2s_pdata->type.quirks;
 		idma_addr = i2s_pdata->type.idma_addr;
 	} else {
-		quirks = i2s_dai_data->quirks;
 		if (of_property_read_u32(np, "samsung,idma-addr",
 					 &idma_addr)) {
 			if (quirks & QUIRK_SUPPORTS_IDMA) {
@@ -1318,7 +1368,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 			}
 		}
 	}
-	quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
@@ -1348,28 +1397,17 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
 
 	if (quirks & QUIRK_PRI_6CHAN)
-		pri_dai->i2s_dai_drv.playback.channels_max = 6;
+		pri_dai->drv->playback.channels_max = 6;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
 						 NULL, NULL, NULL);
 	if (ret < 0)
 		goto err_disable_clk;
 
-	ret = devm_snd_soc_register_component(&pdev->dev,
-					&samsung_i2s_component,
-					&pri_dai->i2s_dai_drv, 1);
-	if (ret < 0)
-		goto err_disable_clk;
-
 	if (quirks & QUIRK_SEC_DAI) {
-		sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true);
-		if (!sec_dai) {
-			dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
-			ret = -ENOMEM;
-			goto err_disable_clk;
-		}
+		sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
 
-		sec_dai->lock = &pri_dai->spinlock;
+		sec_dai->lock = &priv->spinlock;
 		sec_dai->variant_regs = pri_dai->variant_regs;
 		sec_dai->dma_playback.addr = regs_base + I2STXDS;
 		sec_dai->dma_playback.chan_name = "tx-sec";
@@ -1392,11 +1430,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		if (ret < 0)
 			goto err_disable_clk;
 
-		ret = devm_snd_soc_register_component(&pdev->dev,
-						&samsung_i2s_component,
-						&sec_dai->i2s_dai_drv, 1);
-		if (ret < 0)
-			goto err_disable_clk;
 	}
 
 	if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
@@ -1405,7 +1438,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		goto err_disable_clk;
 	}
 
-	dev_set_drvdata(&pdev->dev, pri_dai);
+	dev_set_drvdata(&pdev->dev, priv);
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					&samsung_i2s_component,
+					priv->dai_drv, num_dais);
+	if (ret < 0)
+		goto err_disable_clk;
 
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -1427,9 +1466,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 static int samsung_i2s_remove(struct platform_device *pdev)
 {
-	struct i2s_dai *pri_dai;
-
-	pri_dai = dev_get_drvdata(&pdev->dev);
+	struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
+	struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
 
 	pm_runtime_get_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 06/22] ASoC: samsung: i2s: Restore support for the secondary PCM
       [not found]   ` <CGME20190207170105epcas1p3d4a1da9ae268f8e95b32fb499e5a1dad@epcas1p3.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:41       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This patch introduces again registration of additional platform device as
we still need it for registering the secondary dmaengine PCM component.

This patch in most part is a revert of changes done in commit
be2c92eb64023e ("ASoC: samsung: i2s: Remove virtual device for secondary DAI")

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 52 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 4bc3b181f1c2..994dcd4b01fb 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -109,6 +109,7 @@ static DEFINE_SPINLOCK(lock);
 
 struct samsung_i2s_priv {
 	struct platform_device *pdev;
+	struct platform_device *pdev_sec;
 
 	/* Spinlock protecting access to the device's registers */
 	spinlock_t spinlock;
@@ -1312,6 +1313,34 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
 	return ret;
 }
 
+/* Create platform device for the secondary PCM */
+static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
+{
+	struct platform_device *pdev;
+	int ret;
+
+	pdev = platform_device_register_simple("samsung-i2s-sec", -1, NULL, 0);
+	if (!pdev)
+		return -ENOMEM;
+
+	ret = device_attach(&pdev->dev);
+	if (ret < 0) {
+		dev_info(&pdev->dev, "device_attach() failed\n");
+		return ret;
+	}
+
+	priv->pdev_sec = pdev;
+
+	return 0;
+}
+
+static void i2s_delete_secondary_device(struct samsung_i2s_priv *priv)
+{
+	if (priv->pdev_sec) {
+		platform_device_del(priv->pdev_sec);
+		priv->pdev_sec = NULL;
+	}
+}
 static int samsung_i2s_probe(struct platform_device *pdev)
 {
 	struct i2s_dai *pri_dai, *sec_dai = NULL;
@@ -1329,13 +1358,15 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		i2s_dai_data = (struct samsung_i2s_dai_data *)
 				platform_get_device_id(pdev)->driver_data;
 
+	/* Nothing to do if it is the secondary device probing */
+	if (!i2s_dai_data)
+		return 0;
+
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
-	quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
-
 	num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
 	priv->pdev = pdev;
 
@@ -1425,8 +1456,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		sec_dai->pri_dai = pri_dai;
 		pri_dai->sec_dai = sec_dai;
 
-		ret = samsung_asoc_dma_platform_register(&pdev->dev,
-					sec_dai->filter, "tx-sec", NULL, NULL);
+		ret = i2s_create_secondary_device(priv);
+		if (ret < 0)
+			goto err_disable_clk;
+
+		ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev,
+						sec_dai->filter, "tx-sec", NULL,
+						&pdev->dev);
 		if (ret < 0)
 			goto err_disable_clk;
 
@@ -1461,6 +1497,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 err_disable_clk:
 	clk_disable_unprepare(pri_dai->clk);
+	i2s_delete_secondary_device(priv);
 	return ret;
 }
 
@@ -1469,12 +1506,16 @@ static int samsung_i2s_remove(struct platform_device *pdev)
 	struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
 	struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
 
+	if (!priv)
+		return 0;
+
 	pm_runtime_get_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 	i2s_unregister_clock_provider(pdev);
 	clk_disable_unprepare(pri_dai->clk);
 	pm_runtime_put_noidle(&pdev->dev);
+	i2s_delete_secondary_device(priv);
 
 	return 0;
 }
@@ -1573,6 +1614,9 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
 		.name           = "samsung-i2s",
 		.driver_data	= (kernel_ulong_t)&i2sv3_dai_type,
 	},
+	{
+		.name           = "samsung-i2s-sec",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids);
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 07/22] ASoC: samsung: i2s: Move clk supplier data to common driver data structure
       [not found]   ` <CGME20190207170109epcas1p20929934c01ae67a05cd6a56f13ed8486@epcas1p2.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:41       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

Having the clocks provider data in struct samsung_i2s_priv, i.e. per the I2S
controller instance, rather than per CPU DAI better models the hardware and
simplifies the code a little. The clock provider is common for both DAIs.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 68 ++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 994dcd4b01fb..978614673ffb 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -99,9 +99,7 @@ struct i2s_dai {
 
 	spinlock_t *lock;
 
-	/* Below fields are only valid if this is the primary FIFO */
-	struct clk *clk_table[3];
-	struct clk_onecell_data clk_data;
+	struct samsung_i2s_priv *priv;
 };
 
 /* Lock for cross i/f checks */
@@ -118,6 +116,10 @@ struct samsung_i2s_priv {
 	struct i2s_dai *dai;
 	struct snd_soc_dai_driver *dai_drv;
 	int num_dais;
+
+	/* The clock provider's data */
+	struct clk *clk_table[3];
+	struct clk_onecell_data clk_data;
 };
 
 struct i2s_dai *samsung_i2s_get_pri_dai(struct device *dev)
@@ -625,11 +627,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
 	return ret;
 }
 
-static int i2s_set_fmt(struct snd_soc_dai *dai,
-	unsigned int fmt)
+static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
-	struct i2s_dai *other = get_other_dai(i2s);
 	int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
 	u32 mod, tmp = 0;
 	unsigned long flags;
@@ -687,8 +688,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 		 * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
 		 * clock configuration assigned in DT is not overwritten.
 		 */
-		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL &&
-		    other->clk_data.clks == NULL)
+		if (i2s->rclk_srcrate == 0 && priv->clk_data.clks == NULL)
 			i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 							0, SND_SOC_CLOCK_IN);
 		break;
@@ -725,8 +725,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 static int i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
-	struct i2s_dai *other = get_other_dai(i2s);
 	u32 mod, mask = 0, val = 0;
 	struct clk *rclksrc;
 	unsigned long flags;
@@ -811,10 +811,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 
 	i2s->frmclk = params_rate(params);
 
-	rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
-	if (!rclksrc || IS_ERR(rclksrc))
-		rclksrc = other->clk_table[CLK_I2S_RCLK_SRC];
-
+	rclksrc = priv->clk_table[CLK_I2S_RCLK_SRC];
 	if (rclksrc && !IS_ERR(rclksrc))
 		i2s->rclk_srcrate = clk_get_rate(rclksrc);
 
@@ -1221,31 +1218,30 @@ static int i2s_runtime_resume(struct device *dev)
 }
 #endif /* CONFIG_PM */
 
-static void i2s_unregister_clocks(struct i2s_dai *i2s)
+static void i2s_unregister_clocks(struct samsung_i2s_priv *priv)
 {
 	int i;
 
-	for (i = 0; i < i2s->clk_data.clk_num; i++) {
-		if (!IS_ERR(i2s->clk_table[i]))
-			clk_unregister(i2s->clk_table[i]);
+	for (i = 0; i < priv->clk_data.clk_num; i++) {
+		if (!IS_ERR(priv->clk_table[i]))
+			clk_unregister(priv->clk_table[i]);
 	}
 }
 
-static void i2s_unregister_clock_provider(struct platform_device *pdev)
+static void i2s_unregister_clock_provider(struct samsung_i2s_priv *priv)
 {
-	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(&pdev->dev);
-
-	of_clk_del_provider(pdev->dev.of_node);
-	i2s_unregister_clocks(i2s);
+	of_clk_del_provider(priv->pdev->dev.of_node);
+	i2s_unregister_clocks(priv);
 }
 
-static int i2s_register_clock_provider(struct platform_device *pdev)
+
+static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 {
 
 	const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
 	const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
 	const char *p_names[2] = { NULL };
-	struct device *dev = &pdev->dev;
+	struct device *dev = &priv->pdev->dev;
 	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
 	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
@@ -1277,37 +1273,37 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
 		u32 val = readl(i2s->addr + I2SPSR);
 		writel(val | PSR_PSREN, i2s->addr + I2SPSR);
 
-		i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
+		priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
 				i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
 				ARRAY_SIZE(p_names),
 				CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
 				i2s->addr + I2SMOD, reg_info->rclksrc_off,
 				1, 0, i2s->lock);
 
-		i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
+		priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
 				i2s_clk_name[CLK_I2S_RCLK_PSR],
 				i2s_clk_name[CLK_I2S_RCLK_SRC],
 				CLK_SET_RATE_PARENT,
 				i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
 
 		p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
-		i2s->clk_data.clk_num = 2;
+		priv->clk_data.clk_num = 2;
 	}
 
-	i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
+	priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
 				i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
 				CLK_SET_RATE_PARENT,
 				i2s->addr + I2SMOD, reg_info->cdclkcon_off,
 				CLK_GATE_SET_TO_DISABLE, i2s->lock);
 
-	i2s->clk_data.clk_num += 1;
-	i2s->clk_data.clks = i2s->clk_table;
+	priv->clk_data.clk_num += 1;
+	priv->clk_data.clks = priv->clk_table;
 
 	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
-				  &i2s->clk_data);
+				  &priv->clk_data);
 	if (ret < 0) {
 		dev_err(dev, "failed to add clock provider: %d\n", ret);
-		i2s_unregister_clocks(i2s);
+		i2s_unregister_clocks(priv);
 	}
 
 	return ret;
@@ -1426,6 +1422,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai->dma_capture.addr_width = 4;
 	pri_dai->quirks = quirks;
 	pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
+	pri_dai->priv = priv;
 
 	if (quirks & QUIRK_PRI_6CHAN)
 		pri_dai->drv->playback.channels_max = 6;
@@ -1454,6 +1451,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		sec_dai->quirks = quirks;
 		sec_dai->idma_playback.addr = idma_addr;
 		sec_dai->pri_dai = pri_dai;
+		sec_dai->priv = priv;
 		pri_dai->sec_dai = sec_dai;
 
 		ret = i2s_create_secondary_device(priv);
@@ -1485,11 +1483,11 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
-	ret = i2s_register_clock_provider(pdev);
+	ret = i2s_register_clock_provider(priv);
 	if (ret < 0)
 		goto err_disable_pm;
 
-	pri_dai->op_clk = clk_get_parent(pri_dai->clk_table[CLK_I2S_RCLK_SRC]);
+	pri_dai->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
 
 	return 0;
 
@@ -1512,7 +1510,7 @@ static int samsung_i2s_remove(struct platform_device *pdev)
 	pm_runtime_get_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
-	i2s_unregister_clock_provider(pdev);
+	i2s_unregister_clock_provider(priv);
 	clk_disable_unprepare(pri_dai->clk);
 	pm_runtime_put_noidle(&pdev->dev);
 	i2s_delete_secondary_device(priv);
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 08/22] ASoC: samsung: i2s: Add widgets and routes for DPCM support
       [not found]   ` <CGME20190207170112epcas1p31ed740ef43d8a3eb71ca7245fba1bc3d@epcas1p3.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:42       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This patch adds DAPM widgets required to model the internal mixer
of the I2S controller merging audio streams from the primary and
from the secondary PCM interface.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 978614673ffb..b435e6226ec2 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1116,8 +1116,31 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
 	.delay = i2s_delay,
 };
 
+static const struct snd_soc_dapm_widget samsung_i2s_widgets[] = {
+	/* Backend DAI  */
+	SND_SOC_DAPM_AIF_OUT("Mixer DAI TX", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("Mixer DAI RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+
+	/* Playback Mixer */
+	SND_SOC_DAPM_MIXER("Playback Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = {
+	{ "Playback Mixer", NULL, "Primary" },
+	{ "Playback Mixer", NULL, "Secondary" },
+
+	{ "Mixer DAI TX", NULL, "Playback Mixer" },
+	{ "Playback Mixer", NULL, "Mixer DAI RX" },
+};
+
 static const struct snd_soc_component_driver samsung_i2s_component = {
-	.name		= "samsung-i2s",
+	.name = "samsung-i2s",
+
+	.dapm_widgets = samsung_i2s_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(samsung_i2s_widgets),
+
+	.dapm_routes = samsung_i2s_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(samsung_i2s_dapm_routes),
 };
 
 #define SAMSUNG_I2S_FMTS	(SNDRV_PCM_FMTBIT_S8 | \
@@ -1129,6 +1152,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
 			  int num_dais)
 {
 	static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" };
+	static const char *stream_names[] = { "Primary", "Secondary" };
 	struct snd_soc_dai_driver *dai_drv;
 	struct i2s_dai *dai;
 	int i;
@@ -1158,6 +1182,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
 		dai_drv->playback.channels_max = 2;
 		dai_drv->playback.rates = i2s_dai_data->pcm_rates;
 		dai_drv->playback.formats = SAMSUNG_I2S_FMTS;
+		dai_drv->playback.stream_name = stream_names[i];
 
 		dai_drv->id = i + 1;
 		dai_drv->name = dai_names[i];
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 09/22] ASoC: samsung: i2s: Move core clk to the driver common data structure
       [not found]   ` <CGME20190207170116epcas2p1e0768a74062c8af83842ddb59309850f@epcas2p1.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:44       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The core clock is also common for both CPU DAIs so move it to
the driver's private data structure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index b435e6226ec2..c2c3a3286c63 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -71,8 +71,6 @@ struct i2s_dai {
 	 * 0 indicates CPU driver is free to choose any value.
 	 */
 	unsigned rfs, bfs;
-	/* I2S Controller's core clock */
-	struct clk *clk;
 	/* Clock for generating I2S signals */
 	struct clk *op_clk;
 	/* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
@@ -117,6 +115,9 @@ struct samsung_i2s_priv {
 	struct snd_soc_dai_driver *dai_drv;
 	int num_dais;
 
+	/* The I2S controller's core clock */
+	struct clk *clk;
+
 	/* The clock provider's data */
 	struct clk *clk_table[3];
 	struct clk_onecell_data clk_data;
@@ -1205,6 +1206,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
 #ifdef CONFIG_PM
 static int i2s_runtime_suspend(struct device *dev)
 {
+	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
 	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 
 	i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
@@ -1213,24 +1215,25 @@ static int i2s_runtime_suspend(struct device *dev)
 
 	if (i2s->op_clk)
 		clk_disable_unprepare(i2s->op_clk);
-	clk_disable_unprepare(i2s->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return 0;
 }
 
 static int i2s_runtime_resume(struct device *dev)
 {
+	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
 	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	int ret;
 
-	ret = clk_prepare_enable(i2s->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret)
 		return ret;
 
 	if (i2s->op_clk) {
 		ret = clk_prepare_enable(i2s->op_clk);
 		if (ret) {
-			clk_disable_unprepare(i2s->clk);
+			clk_disable_unprepare(priv->clk);
 			return ret;
 		}
 	}
@@ -1428,13 +1431,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 	regs_base = res->start;
 
-	pri_dai->clk = devm_clk_get(&pdev->dev, "iis");
-	if (IS_ERR(pri_dai->clk)) {
+	priv->clk = devm_clk_get(&pdev->dev, "iis");
+	if (IS_ERR(priv->clk)) {
 		dev_err(&pdev->dev, "Failed to get iis clock\n");
-		return PTR_ERR(pri_dai->clk);
+		return PTR_ERR(priv->clk);
 	}
 
-	ret = clk_prepare_enable(pri_dai->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
 		return ret;
@@ -1472,7 +1475,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 		sec_dai->dma_playback.addr_width = 4;
 		sec_dai->addr = pri_dai->addr;
-		sec_dai->clk = pri_dai->clk;
 		sec_dai->quirks = quirks;
 		sec_dai->idma_playback.addr = idma_addr;
 		sec_dai->pri_dai = pri_dai;
@@ -1519,7 +1521,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 err_disable_pm:
 	pm_runtime_disable(&pdev->dev);
 err_disable_clk:
-	clk_disable_unprepare(pri_dai->clk);
+	clk_disable_unprepare(priv->clk);
 	i2s_delete_secondary_device(priv);
 	return ret;
 }
@@ -1527,7 +1529,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 static int samsung_i2s_remove(struct platform_device *pdev)
 {
 	struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
-	struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
 
 	if (!priv)
 		return 0;
@@ -1536,7 +1537,7 @@ static int samsung_i2s_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	i2s_unregister_clock_provider(priv);
-	clk_disable_unprepare(pri_dai->clk);
+	clk_disable_unprepare(priv->clk);
 	pm_runtime_put_noidle(&pdev->dev);
 	i2s_delete_secondary_device(priv);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 10/22] ASoC: samsung: i2s: Move opclk data to common driver data structure
       [not found]   ` <CGME20190207170120epcas1p211e1582a6124d6b7d0e33db6c0017480@epcas1p2.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:44       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The clock for generating I2S signals is also common for both CPU DAIs
so move it to the driver's common data structure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 70 +++++++++++++++++++----------------------
 1 file changed, 33 insertions(+), 37 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index c2c3a3286c63..b7b28813645a 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -62,8 +62,6 @@ struct i2s_dai {
 	struct platform_device *pdev;
 	/* Memory mapped SFR region */
 	void __iomem	*addr;
-	/* Rate of RCLK source clock */
-	unsigned long rclk_srcrate;
 	/* Frame Clock */
 	unsigned frmclk;
 	/*
@@ -71,8 +69,6 @@ struct i2s_dai {
 	 * 0 indicates CPU driver is free to choose any value.
 	 */
 	unsigned rfs, bfs;
-	/* Clock for generating I2S signals */
-	struct clk *op_clk;
 	/* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
 	struct i2s_dai *pri_dai;
 	/* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
@@ -118,6 +114,12 @@ struct samsung_i2s_priv {
 	/* The I2S controller's core clock */
 	struct clk *clk;
 
+	/* Clock for generating I2S signals */
+	struct clk *op_clk;
+
+	/* Rate of RCLK source clock */
+	unsigned long rclk_srcrate;
+
 	/* The clock provider's data */
 	struct clk *clk_table[3];
 	struct clk_onecell_data clk_data;
@@ -496,9 +498,10 @@ static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
 	writel(readl(fic) & ~flush, fic);
 }
 
-static int i2s_set_sysclk(struct snd_soc_dai *dai,
-	  int clk_id, unsigned int rfs, int dir)
+static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
+			  int dir)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	struct i2s_dai *other = get_other_dai(i2s);
 	const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
@@ -554,44 +557,39 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
 			clk_id = 1;
 
 		if (!any_active(i2s)) {
-			if (i2s->op_clk && !IS_ERR(i2s->op_clk)) {
+			if (priv->op_clk && !IS_ERR(priv->op_clk)) {
 				if ((clk_id && !(mod & rsrc_mask)) ||
 					(!clk_id && (mod & rsrc_mask))) {
-					clk_disable_unprepare(i2s->op_clk);
-					clk_put(i2s->op_clk);
+					clk_disable_unprepare(priv->op_clk);
+					clk_put(priv->op_clk);
 				} else {
-					i2s->rclk_srcrate =
-						clk_get_rate(i2s->op_clk);
+					priv->rclk_srcrate =
+						clk_get_rate(priv->op_clk);
 					goto done;
 				}
 			}
 
 			if (clk_id)
-				i2s->op_clk = clk_get(&i2s->pdev->dev,
+				priv->op_clk = clk_get(&i2s->pdev->dev,
 						"i2s_opclk1");
 			else
-				i2s->op_clk = clk_get(&i2s->pdev->dev,
+				priv->op_clk = clk_get(&i2s->pdev->dev,
 						"i2s_opclk0");
 
-			if (WARN_ON(IS_ERR(i2s->op_clk))) {
-				ret = PTR_ERR(i2s->op_clk);
-				i2s->op_clk = NULL;
+			if (WARN_ON(IS_ERR(priv->op_clk))) {
+				ret = PTR_ERR(priv->op_clk);
+				priv->op_clk = NULL;
 				goto err;
 			}
 
-			ret = clk_prepare_enable(i2s->op_clk);
+			ret = clk_prepare_enable(priv->op_clk);
 			if (ret) {
-				clk_put(i2s->op_clk);
-				i2s->op_clk = NULL;
+				clk_put(priv->op_clk);
+				priv->op_clk = NULL;
 				goto err;
 			}
-			i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
+			priv->rclk_srcrate = clk_get_rate(priv->op_clk);
 
-			/* Over-ride the other's */
-			if (other) {
-				other->op_clk = i2s->op_clk;
-				other->rclk_srcrate = i2s->rclk_srcrate;
-			}
 		} else if ((!clk_id && (mod & rsrc_mask))
 				|| (clk_id && !(mod & rsrc_mask))) {
 			dev_err(&i2s->pdev->dev,
@@ -600,8 +598,6 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
 			goto err;
 		} else {
 			/* Call can't be on the active DAI */
-			i2s->op_clk = other->op_clk;
-			i2s->rclk_srcrate = other->rclk_srcrate;
 			goto done;
 		}
 
@@ -689,7 +685,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		 * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
 		 * clock configuration assigned in DT is not overwritten.
 		 */
-		if (i2s->rclk_srcrate == 0 && priv->clk_data.clks == NULL)
+		if (priv->rclk_srcrate == 0 && priv->clk_data.clks == NULL)
 			i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 							0, SND_SOC_CLOCK_IN);
 		break;
@@ -814,7 +810,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 
 	rclksrc = priv->clk_table[CLK_I2S_RCLK_SRC];
 	if (rclksrc && !IS_ERR(rclksrc))
-		i2s->rclk_srcrate = clk_get_rate(rclksrc);
+		priv->rclk_srcrate = clk_get_rate(rclksrc);
 
 	return 0;
 }
@@ -872,6 +868,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
 
 static int config_setup(struct i2s_dai *i2s)
 {
+	struct samsung_i2s_priv *priv = i2s->priv;
 	struct i2s_dai *other = get_other_dai(i2s);
 	unsigned rfs, bfs, blc;
 	u32 psr;
@@ -920,11 +917,11 @@ static int config_setup(struct i2s_dai *i2s)
 		return 0;
 
 	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
-		psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
+		psr = priv->rclk_srcrate / i2s->frmclk / rfs;
 		writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
 		dev_dbg(&i2s->pdev->dev,
 			"RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
-				i2s->rclk_srcrate, psr, rfs, bfs);
+				priv->rclk_srcrate, psr, rfs, bfs);
 	}
 
 	return 0;
@@ -1067,7 +1064,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 	/* Reset any constraint on RFS and BFS */
 	i2s->rfs = 0;
 	i2s->bfs = 0;
-	i2s->rclk_srcrate = 0;
 
 	spin_lock_irqsave(i2s->lock, flags);
 	i2s_txctrl(i2s, 0);
@@ -1213,8 +1209,8 @@ static int i2s_runtime_suspend(struct device *dev)
 	i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
 	i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
 
-	if (i2s->op_clk)
-		clk_disable_unprepare(i2s->op_clk);
+	if (priv->op_clk)
+		clk_disable_unprepare(priv->op_clk);
 	clk_disable_unprepare(priv->clk);
 
 	return 0;
@@ -1230,8 +1226,8 @@ static int i2s_runtime_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	if (i2s->op_clk) {
-		ret = clk_prepare_enable(i2s->op_clk);
+	if (priv->op_clk) {
+		ret = clk_prepare_enable(priv->op_clk);
 		if (ret) {
 			clk_disable_unprepare(priv->clk);
 			return ret;
@@ -1514,7 +1510,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_disable_pm;
 
-	pri_dai->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
+	priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
 
 	return 0;
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 11/22] ASoC: samsung: i2s: Move registers cache to common driver data structure
       [not found]   ` <CGME20190207170123epcas1p2fae464ba7f102d841548c5a523cc6660@epcas1p2.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:45       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

There is no need to keep the PM suspend/resume register cache separate
for each DAI as those registers are common, move related i2s_dai data
structure to the driver's common data structure.  This will allow us
to simplify the code a little eventually and to make it easier to follow.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index b7b28813645a..b0913cc488ab 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -86,9 +86,6 @@ struct i2s_dai {
 	struct snd_dmaengine_dai_dma_data idma_playback;
 	dma_filter_fn filter;
 	u32	quirks;
-	u32	suspend_i2smod;
-	u32	suspend_i2scon;
-	u32	suspend_i2spsr;
 	const struct samsung_i2s_variant_regs *variant_regs;
 
 	spinlock_t *lock;
@@ -120,6 +117,11 @@ struct samsung_i2s_priv {
 	/* Rate of RCLK source clock */
 	unsigned long rclk_srcrate;
 
+	/* Cache of selected I2S registers for system suspend */
+	u32 suspend_i2smod;
+	u32 suspend_i2scon;
+	u32 suspend_i2spsr;
+
 	/* The clock provider's data */
 	struct clk *clk_table[3];
 	struct clk_onecell_data clk_data;
@@ -1205,9 +1207,9 @@ static int i2s_runtime_suspend(struct device *dev)
 	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
 	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 
-	i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
-	i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
-	i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+	priv->suspend_i2smod = readl(i2s->addr + I2SMOD);
+	priv->suspend_i2scon = readl(i2s->addr + I2SCON);
+	priv->suspend_i2spsr = readl(i2s->addr + I2SPSR);
 
 	if (priv->op_clk)
 		clk_disable_unprepare(priv->op_clk);
@@ -1234,9 +1236,9 @@ static int i2s_runtime_resume(struct device *dev)
 		}
 	}
 
-	writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
-	writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
-	writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
+	writel(priv->suspend_i2scon, i2s->addr + I2SCON);
+	writel(priv->suspend_i2smod, i2s->addr + I2SMOD);
+	writel(priv->suspend_i2spsr, i2s->addr + I2SPSR);
 
 	return 0;
 }
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 12/22] ASoC: samsung: i2s: Move SFR pointer to common driver data structure
       [not found]   ` <CGME20190207170127epcas2p31da340c3f63e75e7bcb5c9c864a42173@epcas2p3.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:46       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The SFR region is common for both DAIs so move related data structure
field from struct i2s_dai to the common driver data structure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 105 ++++++++++++++++++++++------------------
 1 file changed, 58 insertions(+), 47 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index b0913cc488ab..9fae732bb620 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -60,8 +60,7 @@ struct samsung_i2s_dai_data {
 struct i2s_dai {
 	/* Platform device for this DAI */
 	struct platform_device *pdev;
-	/* Memory mapped SFR region */
-	void __iomem	*addr;
+
 	/* Frame Clock */
 	unsigned frmclk;
 	/*
@@ -100,6 +99,9 @@ struct samsung_i2s_priv {
 	struct platform_device *pdev;
 	struct platform_device *pdev_sec;
 
+	/* Memory mapped SFR region */
+	void __iomem *addr;
+
 	/* Spinlock protecting access to the device's registers */
 	spinlock_t spinlock;
 
@@ -143,7 +145,9 @@ static inline bool is_secondary(struct i2s_dai *i2s)
 /* If operating in SoC-Slave mode */
 static inline bool is_slave(struct i2s_dai *i2s)
 {
-	u32 mod = readl(i2s->addr + I2SMOD);
+	struct samsung_i2s_priv *priv = i2s->priv;
+
+	u32 mod = readl(priv->addr + I2SMOD);
 	return (mod & (1 << i2s->variant_regs->mss_off)) ? true : false;
 }
 
@@ -155,7 +159,7 @@ static inline bool tx_active(struct i2s_dai *i2s)
 	if (!i2s)
 		return false;
 
-	active = readl(i2s->addr + I2SCON);
+	active = readl(i2s->priv->addr + I2SCON);
 
 	if (is_secondary(i2s))
 		active &= CON_TXSDMA_ACTIVE;
@@ -193,7 +197,7 @@ static inline bool rx_active(struct i2s_dai *i2s)
 	if (!i2s)
 		return false;
 
-	active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE;
+	active = readl(i2s->priv->addr + I2SCON) & CON_RXDMA_ACTIVE;
 
 	return active ? true : false;
 }
@@ -256,8 +260,10 @@ static inline bool is_manager(struct i2s_dai *i2s)
 /* Read RCLK of I2S (in multiples of LRCLK) */
 static inline unsigned get_rfs(struct i2s_dai *i2s)
 {
+	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 rfs;
-	rfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
+
+	rfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
 	rfs &= i2s->variant_regs->rfs_mask;
 
 	switch (rfs) {
@@ -275,7 +281,8 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
 /* Write RCLK of I2S (in multiples of LRCLK) */
 static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
 {
-	u32 mod = readl(i2s->addr + I2SMOD);
+	struct samsung_i2s_priv *priv = i2s->priv;
+	u32 mod = readl(priv->addr + I2SMOD);
 	int rfs_shift = i2s->variant_regs->rfs_off;
 
 	mod &= ~(i2s->variant_regs->rfs_mask << rfs_shift);
@@ -307,14 +314,16 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
 		break;
 	}
 
-	writel(mod, i2s->addr + I2SMOD);
+	writel(mod, priv->addr + I2SMOD);
 }
 
 /* Read Bit-Clock of I2S (in multiples of LRCLK) */
 static inline unsigned get_bfs(struct i2s_dai *i2s)
 {
+	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 bfs;
-	bfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
+
+	bfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
 	bfs &= i2s->variant_regs->bfs_mask;
 
 	switch (bfs) {
@@ -333,7 +342,8 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
 /* Write Bit-Clock of I2S (in multiples of LRCLK) */
 static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 {
-	u32 mod = readl(i2s->addr + I2SMOD);
+	struct samsung_i2s_priv *priv = i2s->priv;
+	u32 mod = readl(priv->addr + I2SMOD);
 	int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
 	int bfs_shift = i2s->variant_regs->bfs_off;
 
@@ -378,13 +388,13 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 		return;
 	}
 
-	writel(mod, i2s->addr + I2SMOD);
+	writel(mod, priv->addr + I2SMOD);
 }
 
 /* Sample-Size */
 static inline int get_blc(struct i2s_dai *i2s)
 {
-	int blc = readl(i2s->addr + I2SMOD);
+	int blc = readl(i2s->priv->addr + I2SMOD);
 
 	blc = (blc >> 13) & 0x3;
 
@@ -398,7 +408,8 @@ static inline int get_blc(struct i2s_dai *i2s)
 /* TX Channel Control */
 static void i2s_txctrl(struct i2s_dai *i2s, int on)
 {
-	void __iomem *addr = i2s->addr;
+	struct samsung_i2s_priv *priv = i2s->priv;
+	void __iomem *addr = priv->addr;
 	int txr_off = i2s->variant_regs->txr_off;
 	u32 con = readl(addr + I2SCON);
 	u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
@@ -448,7 +459,8 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on)
 /* RX Channel Control */
 static void i2s_rxctrl(struct i2s_dai *i2s, int on)
 {
-	void __iomem *addr = i2s->addr;
+	struct samsung_i2s_priv *priv = i2s->priv;
+	void __iomem *addr = priv->addr;
 	int txr_off = i2s->variant_regs->txr_off;
 	u32 con = readl(addr + I2SCON);
 	u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
@@ -485,9 +497,9 @@ static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
 		return;
 
 	if (is_secondary(i2s))
-		fic = i2s->addr + I2SFICS;
+		fic = i2s->priv->addr + I2SFICS;
 	else
-		fic = i2s->addr + I2SFIC;
+		fic = i2s->priv->addr + I2SFIC;
 
 	/* Flush the FIFO */
 	writel(readl(fic) | flush, fic);
@@ -516,7 +528,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 	pm_runtime_get_sync(dai->dev);
 
 	spin_lock_irqsave(i2s->lock, flags);
-	mod = readl(i2s->addr + I2SMOD);
+	mod = readl(priv->addr + I2SMOD);
 	spin_unlock_irqrestore(i2s->lock, flags);
 
 	switch (clk_id) {
@@ -613,9 +625,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 	}
 
 	spin_lock_irqsave(i2s->lock, flags);
-	mod = readl(i2s->addr + I2SMOD);
+	mod = readl(priv->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
-	writel(mod, i2s->addr + I2SMOD);
+	writel(mod, priv->addr + I2SMOD);
 	spin_unlock_irqrestore(i2s->lock, flags);
 done:
 	pm_runtime_put(dai->dev);
@@ -698,7 +710,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	pm_runtime_get_sync(dai->dev);
 	spin_lock_irqsave(i2s->lock, flags);
-	mod = readl(i2s->addr + I2SMOD);
+	mod = readl(priv->addr + I2SMOD);
 	/*
 	 * Don't change the I2S mode if any controller is active on this
 	 * channel.
@@ -714,7 +726,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
 	mod &= ~(sdf_mask | lrp_rlow | mod_slave);
 	mod |= tmp;
-	writel(mod, i2s->addr + I2SMOD);
+	writel(mod, priv->addr + I2SMOD);
 	spin_unlock_irqrestore(i2s->lock, flags);
 	pm_runtime_put(dai->dev);
 
@@ -801,9 +813,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	spin_lock_irqsave(i2s->lock, flags);
-	mod = readl(i2s->addr + I2SMOD);
+	mod = readl(priv->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
-	writel(mod, i2s->addr + I2SMOD);
+	writel(mod, priv->addr + I2SMOD);
 	spin_unlock_irqrestore(i2s->lock, flags);
 
 	snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
@@ -837,7 +849,7 @@ static int i2s_startup(struct snd_pcm_substream *substream,
 		i2s->mode |= DAI_MANAGER;
 
 	if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
-		writel(CON_RSTCLR, i2s->addr + I2SCON);
+		writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
 
 	spin_unlock_irqrestore(&lock, flags);
 
@@ -920,7 +932,7 @@ static int config_setup(struct i2s_dai *i2s)
 
 	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
 		psr = priv->rclk_srcrate / i2s->frmclk / rfs;
-		writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
+		writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR);
 		dev_dbg(&i2s->pdev->dev,
 			"RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
 				priv->rclk_srcrate, psr, rfs, bfs);
@@ -1008,8 +1020,9 @@ static int i2s_set_clkdiv(struct snd_soc_dai *dai,
 static snd_pcm_sframes_t
 i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
-	u32 reg = readl(i2s->addr + I2SFIC);
+	u32 reg = readl(priv->addr + I2SFIC);
 	snd_pcm_sframes_t delay;
 	const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
 
@@ -1018,7 +1031,7 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 		delay = FIC_RXCOUNT(reg);
 	else if (is_secondary(i2s))
-		delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
+		delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS));
 	else
 		delay = (reg >> i2s_regs->ftx0cnt_off) & 0x7f;
 
@@ -1042,6 +1055,7 @@ static int i2s_resume(struct snd_soc_dai *dai)
 
 static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	struct i2s_dai *other = get_other_dai(i2s);
 	unsigned long flags;
@@ -1056,10 +1070,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 					   &i2s->dma_capture);
 
 		if (i2s->quirks & QUIRK_NEED_RSTCLR)
-			writel(CON_RSTCLR, i2s->addr + I2SCON);
+			writel(CON_RSTCLR, priv->addr + I2SCON);
 
 		if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
-			idma_reg_addr_init(i2s->addr,
+			idma_reg_addr_init(priv->addr,
 					i2s->sec_dai->idma_playback.addr);
 	}
 
@@ -1094,7 +1108,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 	if (!is_secondary(i2s)) {
 		if (i2s->quirks & QUIRK_NEED_RSTCLR) {
 			spin_lock_irqsave(i2s->lock, flags);
-			writel(0, i2s->addr + I2SCON);
+			writel(0, i2s->priv->addr + I2SCON);
 			spin_unlock_irqrestore(i2s->lock, flags);
 		}
 	}
@@ -1205,11 +1219,10 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
 static int i2s_runtime_suspend(struct device *dev)
 {
 	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
-	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 
-	priv->suspend_i2smod = readl(i2s->addr + I2SMOD);
-	priv->suspend_i2scon = readl(i2s->addr + I2SCON);
-	priv->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+	priv->suspend_i2smod = readl(priv->addr + I2SMOD);
+	priv->suspend_i2scon = readl(priv->addr + I2SCON);
+	priv->suspend_i2spsr = readl(priv->addr + I2SPSR);
 
 	if (priv->op_clk)
 		clk_disable_unprepare(priv->op_clk);
@@ -1221,7 +1234,6 @@ static int i2s_runtime_suspend(struct device *dev)
 static int i2s_runtime_resume(struct device *dev)
 {
 	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
-	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	int ret;
 
 	ret = clk_prepare_enable(priv->clk);
@@ -1236,9 +1248,9 @@ static int i2s_runtime_resume(struct device *dev)
 		}
 	}
 
-	writel(priv->suspend_i2scon, i2s->addr + I2SCON);
-	writel(priv->suspend_i2smod, i2s->addr + I2SMOD);
-	writel(priv->suspend_i2spsr, i2s->addr + I2SPSR);
+	writel(priv->suspend_i2scon, priv->addr + I2SCON);
+	writel(priv->suspend_i2smod, priv->addr + I2SMOD);
+	writel(priv->suspend_i2spsr, priv->addr + I2SPSR);
 
 	return 0;
 }
@@ -1296,21 +1308,21 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 
 	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
 		/* Activate the prescaler */
-		u32 val = readl(i2s->addr + I2SPSR);
-		writel(val | PSR_PSREN, i2s->addr + I2SPSR);
+		u32 val = readl(priv->addr + I2SPSR);
+		writel(val | PSR_PSREN, priv->addr + I2SPSR);
 
 		priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
 				i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
 				ARRAY_SIZE(p_names),
 				CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
-				i2s->addr + I2SMOD, reg_info->rclksrc_off,
+				priv->addr + I2SMOD, reg_info->rclksrc_off,
 				1, 0, i2s->lock);
 
 		priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
 				i2s_clk_name[CLK_I2S_RCLK_PSR],
 				i2s_clk_name[CLK_I2S_RCLK_SRC],
 				CLK_SET_RATE_PARENT,
-				i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
+				priv->addr + I2SPSR, 8, 6, 0, i2s->lock);
 
 		p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
 		priv->clk_data.clk_num = 2;
@@ -1319,7 +1331,7 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 	priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
 				i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
 				CLK_SET_RATE_PARENT,
-				i2s->addr + I2SMOD, reg_info->cdclkcon_off,
+				priv->addr + I2SMOD, reg_info->cdclkcon_off,
 				CLK_GATE_SET_TO_DISABLE, i2s->lock);
 
 	priv->clk_data.clk_num += 1;
@@ -1423,9 +1435,9 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(pri_dai->addr))
-		return PTR_ERR(pri_dai->addr);
+	priv->addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->addr))
+		return PTR_ERR(priv->addr);
 
 	regs_base = res->start;
 
@@ -1472,7 +1484,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		}
 
 		sec_dai->dma_playback.addr_width = 4;
-		sec_dai->addr = pri_dai->addr;
 		sec_dai->quirks = quirks;
 		sec_dai->idma_playback.addr = idma_addr;
 		sec_dai->pri_dai = pri_dai;
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 13/22] ASoC: samsung: i2s: Drop spinlock pointer from i2s_dai data structure
       [not found]   ` <CGME20190207170130epcas1p4809b7a8dc797ced2982dc3b305a0991b@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:47       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

As we now have the 'priv' pointer in most of the places we can use
priv->lock directly, dropping extra indirection in the SFR region
spinlock access.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 51 +++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9fae732bb620..c7499e25ce2b 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -87,8 +87,6 @@ struct i2s_dai {
 	u32	quirks;
 	const struct samsung_i2s_variant_regs *variant_regs;
 
-	spinlock_t *lock;
-
 	struct samsung_i2s_priv *priv;
 };
 
@@ -103,7 +101,7 @@ struct samsung_i2s_priv {
 	void __iomem *addr;
 
 	/* Spinlock protecting access to the device's registers */
-	spinlock_t spinlock;
+	spinlock_t lock;
 
 	/* CPU DAIs and their corresponding drivers */
 	struct i2s_dai *dai;
@@ -527,9 +525,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 
 	pm_runtime_get_sync(dai->dev);
 
-	spin_lock_irqsave(i2s->lock, flags);
+	spin_lock_irqsave(&priv->lock, flags);
 	mod = readl(priv->addr + I2SMOD);
-	spin_unlock_irqrestore(i2s->lock, flags);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	switch (clk_id) {
 	case SAMSUNG_I2S_OPCLK:
@@ -624,11 +622,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 		goto err;
 	}
 
-	spin_lock_irqsave(i2s->lock, flags);
+	spin_lock_irqsave(&priv->lock, flags);
 	mod = readl(priv->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
 	writel(mod, priv->addr + I2SMOD);
-	spin_unlock_irqrestore(i2s->lock, flags);
+	spin_unlock_irqrestore(&priv->lock, flags);
 done:
 	pm_runtime_put(dai->dev);
 
@@ -709,7 +707,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	}
 
 	pm_runtime_get_sync(dai->dev);
-	spin_lock_irqsave(i2s->lock, flags);
+	spin_lock_irqsave(&priv->lock, flags);
 	mod = readl(priv->addr + I2SMOD);
 	/*
 	 * Don't change the I2S mode if any controller is active on this
@@ -717,7 +715,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	 */
 	if (any_active(i2s) &&
 		((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) {
-		spin_unlock_irqrestore(i2s->lock, flags);
+		spin_unlock_irqrestore(&priv->lock, flags);
 		pm_runtime_put(dai->dev);
 		dev_err(&i2s->pdev->dev,
 				"%s:%d Other DAI busy\n", __func__, __LINE__);
@@ -727,7 +725,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	mod &= ~(sdf_mask | lrp_rlow | mod_slave);
 	mod |= tmp;
 	writel(mod, priv->addr + I2SMOD);
-	spin_unlock_irqrestore(i2s->lock, flags);
+	spin_unlock_irqrestore(&priv->lock, flags);
 	pm_runtime_put(dai->dev);
 
 	return 0;
@@ -812,11 +810,11 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(i2s->lock, flags);
+	spin_lock_irqsave(&priv->lock, flags);
 	mod = readl(priv->addr + I2SMOD);
 	mod = (mod & ~mask) | val;
 	writel(mod, priv->addr + I2SMOD);
-	spin_unlock_irqrestore(i2s->lock, flags);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
 
@@ -944,6 +942,7 @@ static int config_setup(struct i2s_dai *i2s)
 static int i2s_trigger(struct snd_pcm_substream *substream,
 	int cmd, struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct i2s_dai *i2s = to_info(rtd->cpu_dai);
@@ -954,10 +953,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		pm_runtime_get_sync(dai->dev);
-		spin_lock_irqsave(i2s->lock, flags);
+		spin_lock_irqsave(&priv->lock, flags);
 
 		if (config_setup(i2s)) {
-			spin_unlock_irqrestore(i2s->lock, flags);
+			spin_unlock_irqrestore(&priv->lock, flags);
 			return -EINVAL;
 		}
 
@@ -966,12 +965,12 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
 		else
 			i2s_txctrl(i2s, 1);
 
-		spin_unlock_irqrestore(i2s->lock, flags);
+		spin_unlock_irqrestore(&priv->lock, flags);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		spin_lock_irqsave(i2s->lock, flags);
+		spin_lock_irqsave(&priv->lock, flags);
 
 		if (capture) {
 			i2s_rxctrl(i2s, 0);
@@ -981,7 +980,7 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
 			i2s_fifo(i2s, FIC_TXFLUSH);
 		}
 
-		spin_unlock_irqrestore(i2s->lock, flags);
+		spin_unlock_irqrestore(&priv->lock, flags);
 		pm_runtime_put(dai->dev);
 		break;
 	}
@@ -1081,13 +1080,13 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 	i2s->rfs = 0;
 	i2s->bfs = 0;
 
-	spin_lock_irqsave(i2s->lock, flags);
+	spin_lock_irqsave(&priv->lock, flags);
 	i2s_txctrl(i2s, 0);
 	i2s_rxctrl(i2s, 0);
 	i2s_fifo(i2s, FIC_TXFLUSH);
 	i2s_fifo(other, FIC_TXFLUSH);
 	i2s_fifo(i2s, FIC_RXFLUSH);
-	spin_unlock_irqrestore(i2s->lock, flags);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* Gate CDCLK by default */
 	if (!is_opened(other))
@@ -1107,9 +1106,9 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 
 	if (!is_secondary(i2s)) {
 		if (i2s->quirks & QUIRK_NEED_RSTCLR) {
-			spin_lock_irqsave(i2s->lock, flags);
+			spin_lock_irqsave(&priv->lock, flags);
 			writel(0, i2s->priv->addr + I2SCON);
-			spin_unlock_irqrestore(i2s->lock, flags);
+			spin_unlock_irqrestore(&priv->lock, flags);
 		}
 	}
 
@@ -1316,13 +1315,13 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 				ARRAY_SIZE(p_names),
 				CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
 				priv->addr + I2SMOD, reg_info->rclksrc_off,
-				1, 0, i2s->lock);
+				1, 0, &priv->lock);
 
 		priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
 				i2s_clk_name[CLK_I2S_RCLK_PSR],
 				i2s_clk_name[CLK_I2S_RCLK_SRC],
 				CLK_SET_RATE_PARENT,
-				priv->addr + I2SPSR, 8, 6, 0, i2s->lock);
+				priv->addr + I2SPSR, 8, 6, 0, &priv->lock);
 
 		p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
 		priv->clk_data.clk_num = 2;
@@ -1332,7 +1331,7 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 				i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
 				CLK_SET_RATE_PARENT,
 				priv->addr + I2SMOD, reg_info->cdclkcon_off,
-				CLK_GATE_SET_TO_DISABLE, i2s->lock);
+				CLK_GATE_SET_TO_DISABLE, &priv->lock);
 
 	priv->clk_data.clk_num += 1;
 	priv->clk_data.clks = priv->clk_table;
@@ -1410,8 +1409,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 	pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
 
-	spin_lock_init(&priv->spinlock);
-	pri_dai->lock = &priv->spinlock;
+	spin_lock_init(&priv->lock);
 
 	if (!np) {
 		if (i2s_pdata == NULL) {
@@ -1473,7 +1471,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	if (quirks & QUIRK_SEC_DAI) {
 		sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
 
-		sec_dai->lock = &priv->spinlock;
 		sec_dai->variant_regs = pri_dai->variant_regs;
 		sec_dai->dma_playback.addr = regs_base + I2STXDS;
 		sec_dai->dma_playback.chan_name = "tx-sec";
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 14/22] ASoC: samsung: i2s: Move IP variant data to common driver data structure
       [not found]   ` <CGME20190207170134epcas2p1a22a5c2f680f33fe562fa22f3aec9e6a@epcas2p1.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:48       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The IP variant data is another thing common for both DAIs, move it
to the driver's common data structure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 42 ++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index c7499e25ce2b..6ea0f0050fc8 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -85,7 +85,6 @@ struct i2s_dai {
 	struct snd_dmaengine_dai_dma_data idma_playback;
 	dma_filter_fn filter;
 	u32	quirks;
-	const struct samsung_i2s_variant_regs *variant_regs;
 
 	struct samsung_i2s_priv *priv;
 };
@@ -122,6 +121,8 @@ struct samsung_i2s_priv {
 	u32 suspend_i2scon;
 	u32 suspend_i2spsr;
 
+	const struct samsung_i2s_variant_regs *variant_regs;
+
 	/* The clock provider's data */
 	struct clk *clk_table[3];
 	struct clk_onecell_data clk_data;
@@ -146,7 +147,7 @@ static inline bool is_slave(struct i2s_dai *i2s)
 	struct samsung_i2s_priv *priv = i2s->priv;
 
 	u32 mod = readl(priv->addr + I2SMOD);
-	return (mod & (1 << i2s->variant_regs->mss_off)) ? true : false;
+	return (mod & (1 << priv->variant_regs->mss_off)) ? true : false;
 }
 
 /* If this interface of the controller is transmitting data */
@@ -261,8 +262,8 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
 	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 rfs;
 
-	rfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
-	rfs &= i2s->variant_regs->rfs_mask;
+	rfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->rfs_off;
+	rfs &= priv->variant_regs->rfs_mask;
 
 	switch (rfs) {
 	case 7: return 192;
@@ -281,9 +282,9 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
 {
 	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 mod = readl(priv->addr + I2SMOD);
-	int rfs_shift = i2s->variant_regs->rfs_off;
+	int rfs_shift = priv->variant_regs->rfs_off;
 
-	mod &= ~(i2s->variant_regs->rfs_mask << rfs_shift);
+	mod &= ~(priv->variant_regs->rfs_mask << rfs_shift);
 
 	switch (rfs) {
 	case 192:
@@ -321,8 +322,8 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
 	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 bfs;
 
-	bfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
-	bfs &= i2s->variant_regs->bfs_mask;
+	bfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->bfs_off;
+	bfs &= priv->variant_regs->bfs_mask;
 
 	switch (bfs) {
 	case 8: return 256;
@@ -343,7 +344,7 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 mod = readl(priv->addr + I2SMOD);
 	int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
-	int bfs_shift = i2s->variant_regs->bfs_off;
+	int bfs_shift = priv->variant_regs->bfs_off;
 
 	/* Non-TDM I2S controllers do not support BCLK > 48 * FS */
 	if (!tdm && bfs > 48) {
@@ -351,7 +352,7 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 		return;
 	}
 
-	mod &= ~(i2s->variant_regs->bfs_mask << bfs_shift);
+	mod &= ~(priv->variant_regs->bfs_mask << bfs_shift);
 
 	switch (bfs) {
 	case 48:
@@ -408,7 +409,7 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on)
 {
 	struct samsung_i2s_priv *priv = i2s->priv;
 	void __iomem *addr = priv->addr;
-	int txr_off = i2s->variant_regs->txr_off;
+	int txr_off = priv->variant_regs->txr_off;
 	u32 con = readl(addr + I2SCON);
 	u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
 
@@ -459,7 +460,7 @@ static void i2s_rxctrl(struct i2s_dai *i2s, int on)
 {
 	struct samsung_i2s_priv *priv = i2s->priv;
 	void __iomem *addr = priv->addr;
-	int txr_off = i2s->variant_regs->txr_off;
+	int txr_off = priv->variant_regs->txr_off;
 	u32 con = readl(addr + I2SCON);
 	u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
 
@@ -516,7 +517,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	struct i2s_dai *other = get_other_dai(i2s);
-	const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
+	const struct samsung_i2s_variant_regs *i2s_regs = priv->variant_regs;
 	unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
 	unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
 	u32 mod, mask, val = 0;
@@ -644,9 +645,9 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	u32 mod, tmp = 0;
 	unsigned long flags;
 
-	lrp_shift = i2s->variant_regs->lrp_off;
-	sdf_shift = i2s->variant_regs->sdf_off;
-	mod_slave = 1 << i2s->variant_regs->mss_off;
+	lrp_shift = priv->variant_regs->lrp_off;
+	sdf_shift = priv->variant_regs->sdf_off;
+	mod_slave = 1 << priv->variant_regs->mss_off;
 
 	sdf_mask = MOD_SDF_MASK << sdf_shift;
 	lrp_rlow = MOD_LR_RLOW << lrp_shift;
@@ -1023,7 +1024,6 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 	struct i2s_dai *i2s = to_info(dai);
 	u32 reg = readl(priv->addr + I2SFIC);
 	snd_pcm_sframes_t delay;
-	const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
 
 	WARN_ON(!pm_runtime_active(dai->dev));
 
@@ -1032,7 +1032,7 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 	else if (is_secondary(i2s))
 		delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS));
 	else
-		delay = (reg >> i2s_regs->ftx0cnt_off) & 0x7f;
+		delay = (reg >> priv->variant_regs->ftx0cnt_off) & 0x7f;
 
 	return delay;
 }
@@ -1280,7 +1280,7 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 	const char *p_names[2] = { NULL };
 	struct device *dev = &priv->pdev->dev;
 	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
-	const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
+	const struct samsung_i2s_variant_regs *reg_info = priv->variant_regs;
 	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
 	struct clk *rclksrc;
 	int ret, i;
@@ -1399,6 +1399,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
+	priv->variant_regs = i2s_dai_data->i2s_variant_regs;
+
 	quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
 	num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
 	priv->pdev = pdev;
@@ -1457,7 +1459,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai->dma_playback.addr_width = 4;
 	pri_dai->dma_capture.addr_width = 4;
 	pri_dai->quirks = quirks;
-	pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
 	pri_dai->priv = priv;
 
 	if (quirks & QUIRK_PRI_6CHAN)
@@ -1471,7 +1472,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	if (quirks & QUIRK_SEC_DAI) {
 		sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
 
-		sec_dai->variant_regs = pri_dai->variant_regs;
 		sec_dai->dma_playback.addr = regs_base + I2STXDS;
 		sec_dai->dma_playback.chan_name = "tx-sec";
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 15/22] ASoC: samsung: i2s: Move quirks data to common driver data structure
       [not found]   ` <CGME20190207170138epcas2p31134b2beee877922d27fab5c79fdc7b1@epcas2p3.samsung.com>
@ 2019-02-07 17:00     ` " Sylwester Nawrocki
  2019-02-11 13:49       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

The quirk flags are common for the primary and the secondary DAI
so move respective field from struct i2s_dai to common driver data
structure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 6ea0f0050fc8..e11d678e9c1f 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -84,7 +84,6 @@ struct i2s_dai {
 	struct snd_dmaengine_dai_dma_data dma_capture;
 	struct snd_dmaengine_dai_dma_data idma_playback;
 	dma_filter_fn filter;
-	u32	quirks;
 
 	struct samsung_i2s_priv *priv;
 };
@@ -122,19 +121,13 @@ struct samsung_i2s_priv {
 	u32 suspend_i2spsr;
 
 	const struct samsung_i2s_variant_regs *variant_regs;
+	u32 quirks;
 
 	/* The clock provider's data */
 	struct clk *clk_table[3];
 	struct clk_onecell_data clk_data;
 };
 
-struct i2s_dai *samsung_i2s_get_pri_dai(struct device *dev)
-{
-	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
-
-	return &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
-}
-
 /* Returns true if this is the 'overlay' stereo DAI */
 static inline bool is_secondary(struct i2s_dai *i2s)
 {
@@ -343,7 +336,7 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 {
 	struct samsung_i2s_priv *priv = i2s->priv;
 	u32 mod = readl(priv->addr + I2SMOD);
-	int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
+	int tdm = priv->quirks & QUIRK_SUPPORTS_TDM;
 	int bfs_shift = priv->variant_regs->bfs_off;
 
 	/* Non-TDM I2S controllers do not support BCLK > 48 * FS */
@@ -563,7 +556,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
 	case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
 		mask = 1 << i2s_regs->rclksrc_off;
 
-		if ((i2s->quirks & QUIRK_NO_MUXPSR)
+		if ((priv->quirks & QUIRK_NO_MUXPSR)
 				|| (clk_id == SAMSUNG_I2S_RCLKSRC_0))
 			clk_id = 0;
 		else
@@ -830,8 +823,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 
 /* We set constraints on the substream acc to the version of I2S */
 static int i2s_startup(struct snd_pcm_substream *substream,
-	  struct snd_soc_dai *dai)
+	struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	struct i2s_dai *other = get_other_dai(i2s);
 	unsigned long flags;
@@ -847,7 +841,7 @@ static int i2s_startup(struct snd_pcm_substream *substream,
 	else
 		i2s->mode |= DAI_MANAGER;
 
-	if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
+	if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR))
 		writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
 
 	spin_unlock_irqrestore(&lock, flags);
@@ -929,7 +923,7 @@ static int config_setup(struct i2s_dai *i2s)
 	if (is_slave(i2s))
 		return 0;
 
-	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+	if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
 		psr = priv->rclk_srcrate / i2s->frmclk / rfs;
 		writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR);
 		dev_dbg(&i2s->pdev->dev,
@@ -1068,10 +1062,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 		snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
 					   &i2s->dma_capture);
 
-		if (i2s->quirks & QUIRK_NEED_RSTCLR)
+		if (priv->quirks & QUIRK_NEED_RSTCLR)
 			writel(CON_RSTCLR, priv->addr + I2SCON);
 
-		if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
+		if (priv->quirks & QUIRK_SUPPORTS_IDMA)
 			idma_reg_addr_init(priv->addr,
 					i2s->sec_dai->idma_playback.addr);
 	}
@@ -1099,13 +1093,14 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 
 static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	unsigned long flags;
 
 	pm_runtime_get_sync(dai->dev);
 
 	if (!is_secondary(i2s)) {
-		if (i2s->quirks & QUIRK_NEED_RSTCLR) {
+		if (priv->quirks & QUIRK_NEED_RSTCLR) {
 			spin_lock_irqsave(&priv->lock, flags);
 			writel(0, i2s->priv->addr + I2SCON);
 			spin_unlock_irqrestore(&priv->lock, flags);
@@ -1279,7 +1274,6 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 	const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
 	const char *p_names[2] = { NULL };
 	struct device *dev = &priv->pdev->dev;
-	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	const struct samsung_i2s_variant_regs *reg_info = priv->variant_regs;
 	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
 	struct clk *rclksrc;
@@ -1305,7 +1299,7 @@ static int i2s_register_clock_provider(struct samsung_i2s_priv *priv)
 			return -ENOMEM;
 	}
 
-	if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+	if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
 		/* Activate the prescaler */
 		u32 val = readl(priv->addr + I2SPSR);
 		writel(val | PSR_PSREN, priv->addr + I2SPSR);
@@ -1399,11 +1393,11 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	priv->variant_regs = i2s_dai_data->i2s_variant_regs;
-
 	quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
 	num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
 	priv->pdev = pdev;
+	priv->variant_regs = i2s_dai_data->i2s_variant_regs;
+	priv->quirks = quirks;
 
 	ret = i2s_alloc_dais(priv, i2s_dai_data, num_dais);
 	if (ret < 0)
@@ -1458,7 +1452,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai->dma_capture.chan_name = "rx";
 	pri_dai->dma_playback.addr_width = 4;
 	pri_dai->dma_capture.addr_width = 4;
-	pri_dai->quirks = quirks;
 	pri_dai->priv = priv;
 
 	if (quirks & QUIRK_PRI_6CHAN)
@@ -1481,7 +1474,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		}
 
 		sec_dai->dma_playback.addr_width = 4;
-		sec_dai->quirks = quirks;
 		sec_dai->idma_playback.addr = idma_addr;
 		sec_dai->pri_dai = pri_dai;
 		sec_dai->priv = priv;
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 16/22] ASoC: samsung: i2s: Get rid of a static spinlock
       [not found]   ` <CGME20190207170141epcas1p29a038bfd0df69df10e916ea8a695a85b@epcas1p2.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:51       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This patch makes the spinlock serializing access to the primary/secondary
PCM a per I2S controller lock, rather than a global one. There is no need
to have a global lock across multiple I2S controllers in the SoC.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index e11d678e9c1f..9931d007bc13 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -88,9 +88,6 @@ struct i2s_dai {
 	struct samsung_i2s_priv *priv;
 };
 
-/* Lock for cross i/f checks */
-static DEFINE_SPINLOCK(lock);
-
 struct samsung_i2s_priv {
 	struct platform_device *pdev;
 	struct platform_device *pdev_sec;
@@ -101,6 +98,9 @@ struct samsung_i2s_priv {
 	/* Spinlock protecting access to the device's registers */
 	spinlock_t lock;
 
+	/* Lock for cross i/f checks */
+	spinlock_t pcm_lock;
+
 	/* CPU DAIs and their corresponding drivers */
 	struct i2s_dai *dai;
 	struct snd_soc_dai_driver *dai_drv;
@@ -832,7 +832,7 @@ static int i2s_startup(struct snd_pcm_substream *substream,
 
 	pm_runtime_get_sync(dai->dev);
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&priv->pcm_lock, flags);
 
 	i2s->mode |= DAI_OPENED;
 
@@ -844,7 +844,7 @@ static int i2s_startup(struct snd_pcm_substream *substream,
 	if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR))
 		writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&priv->pcm_lock, flags);
 
 	return 0;
 }
@@ -852,11 +852,12 @@ static int i2s_startup(struct snd_pcm_substream *substream,
 static void i2s_shutdown(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct i2s_dai *i2s = to_info(dai);
 	struct i2s_dai *other = get_other_dai(i2s);
 	unsigned long flags;
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&priv->pcm_lock, flags);
 
 	i2s->mode &= ~DAI_OPENED;
 	i2s->mode &= ~DAI_MANAGER;
@@ -868,7 +869,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
 	i2s->rfs = 0;
 	i2s->bfs = 0;
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&priv->pcm_lock, flags);
 
 	pm_runtime_put(dai->dev);
 }
@@ -1406,6 +1407,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
 
 	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->pcm_lock);
 
 	if (!np) {
 		if (i2s_pdata == NULL) {
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI
       [not found]   ` <CGME20190207170145epcas1p465da0715aa629b525c17d263c1b49a68@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:57       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This patch adds DPCM links in order to support the secondary I2S interface.
For the secondary PCM interface to be actually available one more entry
should be added to the sound-dai property in sound/cpu node in DT.
The changes in driver are done in a way so we are backwards compatible with
existing DTS/DTB, i.e. if the cpu sound-dai property contains only one entry
only one PCM will be registered.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/odroid.c | 132 +++++++++++++++++++++++++++----------
 1 file changed, 96 insertions(+), 36 deletions(-)

diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
index e7b371b07230..bab61e8278a0 100644
--- a/sound/soc/samsung/odroid.c
+++ b/sound/soc/samsung/odroid.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
@@ -17,21 +18,24 @@
 
 struct odroid_priv {
 	struct snd_soc_card card;
-	struct snd_soc_dai_link dai_link;
-
 	struct clk *clk_i2s_bus;
 	struct clk *sclk_i2s;
 };
 
-static int odroid_card_startup(struct snd_pcm_substream *substream)
+static int odroid_card_fe_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
+
 	return 0;
 }
 
-static int odroid_card_hw_params(struct snd_pcm_substream *substream,
+static const struct snd_soc_ops odroid_card_fe_ops = {
+	.startup = odroid_card_fe_startup,
+};
+
+static int odroid_card_be_hw_params(struct snd_pcm_substream *substream,
 				      struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -86,19 +90,56 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static const struct snd_soc_ops odroid_card_ops = {
-	.startup = odroid_card_startup,
-	.hw_params = odroid_card_hw_params,
+static const struct snd_soc_ops odroid_card_be_ops = {
+	.hw_params = odroid_card_be_hw_params,
+};
+
+static struct snd_soc_dai_link odroid_card_dais[] = {
+	{
+		/* Primary FE <-> BE link */
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.ops = &odroid_card_fe_ops,
+		.name = "Primary",
+		.stream_name = "Primary",
+		.platform_name = "3830000.i2s",
+		.dynamic = 1,
+		.dpcm_playback = 1,
+	}, {
+		/* BE <-> CODECs link */
+		.name = "I2S Mixer",
+		.cpu_name = "snd-soc-dummy",
+		.cpu_dai_name = "snd-soc-dummy-dai",
+		.platform_name = "snd-soc-dummy",
+		.ops = &odroid_card_be_ops,
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+				SND_SOC_DAIFMT_CBS_CFS,
+	}, {
+		/* Secondary FE <-> BE link */
+		.playback_only = 1,
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.ops = &odroid_card_fe_ops,
+		.name = "Secondary",
+		.stream_name = "Secondary",
+		.platform_name = "samsung-i2s-sec",
+		.dynamic = 1,
+		.dpcm_playback = 1,
+	}
 };
 
+
 static int odroid_audio_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *cpu, *codec;
+	struct device_node *cpu, *cpu_dai, *codec;
 	struct odroid_priv *priv;
-	struct snd_soc_dai_link *link;
 	struct snd_soc_card *card;
-	int ret;
+	struct snd_soc_dai_link *link, *codec_link;
+	int num_pcms, ret, i;
+	struct of_phandle_args args = {};
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -130,45 +171,67 @@ static int odroid_audio_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	link = &priv->dai_link;
-
-	link->ops = &odroid_card_ops;
-	link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-			SND_SOC_DAIFMT_CBS_CFS;
-
-	card->dai_link = &priv->dai_link;
-	card->num_links = 1;
+	card->dai_link = odroid_card_dais;
+	card->num_links = ARRAY_SIZE(odroid_card_dais);
 
 	cpu = of_get_child_by_name(dev->of_node, "cpu");
 	codec = of_get_child_by_name(dev->of_node, "codec");
+	link = card->dai_link;
+	codec_link = &card->dai_link[1];
 
-	link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
-	if (!link->cpu_of_node) {
-		dev_err(dev, "Failed parsing cpu/sound-dai property\n");
-		return -EINVAL;
+	/*
+	 * For backwards compatibility create the secondary CPU DAI link only
+	 * if there are 2 CPU DAI entries in the cpu sound-dai property in DT.
+	 */
+	num_pcms = of_count_phandle_with_args(cpu, "sound-dai",
+					      "#sound-dai-cells");
+	if (num_pcms == 1)
+		card->num_links--;
+
+	for (i = 0; i < num_pcms; i++, link += 2) {
+		ret = of_parse_phandle_with_args(cpu, "sound-dai",
+						 "#sound-dai-cells", i, &args);
+		if (ret < 0)
+			return ret;
+
+		if (!args.np) {
+			dev_err(dev, "sound-dai property parse error: %d\n", ret);
+			return -EINVAL;
+		}
+
+		ret = snd_soc_get_dai_name(&args, &link->cpu_dai_name);
+		of_node_put(args.np);
+
+		if (ret < 0)
+			return ret;
 	}
 
-	ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+	cpu_dai = of_parse_phandle(cpu, "sound-dai", 0);
+	of_node_put(cpu);
+	of_node_put(codec);
+
+	ret = snd_soc_of_get_dai_link_codecs(dev, codec, codec_link);
 	if (ret < 0)
 		goto err_put_codec_n;
 
-	link->platform_of_node = link->cpu_of_node;
-
-	link->name = "Primary";
-	link->stream_name = link->name;
-
+	/* Set capture capability only for boards with the MAX98090 CODEC */
+	if (codec_link->num_codecs > 1) {
+		card->dai_link[0].dpcm_capture = 1;
+		card->dai_link[1].dpcm_capture = 1;
+	}
 
-	priv->sclk_i2s = of_clk_get_by_name(link->cpu_of_node, "i2s_opclk1");
+	priv->sclk_i2s = of_clk_get_by_name(cpu_dai, "i2s_opclk1");
 	if (IS_ERR(priv->sclk_i2s)) {
 		ret = PTR_ERR(priv->sclk_i2s);
-		goto err_put_i2s_n;
+		goto err_put_codec_n;
 	}
 
-	priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node, "iis");
+	priv->clk_i2s_bus = of_clk_get_by_name(cpu_dai, "iis");
 	if (IS_ERR(priv->clk_i2s_bus)) {
 		ret = PTR_ERR(priv->clk_i2s_bus);
 		goto err_put_sclk;
 	}
+	of_node_put(cpu_dai);
 
 	ret = devm_snd_soc_register_card(dev, card);
 	if (ret < 0) {
@@ -182,10 +245,8 @@ static int odroid_audio_probe(struct platform_device *pdev)
 	clk_put(priv->clk_i2s_bus);
 err_put_sclk:
 	clk_put(priv->sclk_i2s);
-err_put_i2s_n:
-	of_node_put(link->cpu_of_node);
 err_put_codec_n:
-	snd_soc_of_put_dai_link_codecs(link);
+	snd_soc_of_put_dai_link_codecs(codec_link);
 	return ret;
 }
 
@@ -193,8 +254,7 @@ static int odroid_audio_remove(struct platform_device *pdev)
 {
 	struct odroid_priv *priv = platform_get_drvdata(pdev);
 
-	of_node_put(priv->dai_link.cpu_of_node);
-	snd_soc_of_put_dai_link_codecs(&priv->dai_link);
+	snd_soc_of_put_dai_link_codecs(&priv->card.dai_link[1]);
 	clk_put(priv->sclk_i2s);
 	clk_put(priv->clk_i2s_bus);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 18/22] ASoC: samsung: Specify DMA channel names through custom DMA config
       [not found]   ` <CGME20190207170148epcas2p2e0f4a1e154cb8cd52d257978a669e84c@epcas2p2.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 13:58       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

This is a part of conversion of Samsung platforms to use the custom DMA
config for specifying DMA channel names, in addition to passing custom
DMA device for the secondary CPU DAI's "PCM" component for some variants
of the I2S controller.

We also don't set the SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME any more
as setting it wouldn't allow to specify DMA channels through the custom
DMA config.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/dmaengine.c   | 12 ++++--------
 sound/soc/samsung/i2s.c         |  2 +-
 sound/soc/samsung/s3c2412-i2s.c |  2 +-
 sound/soc/samsung/s3c24xx-i2s.c |  2 +-
 4 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 84601fa9aa46..302871974cb3 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -28,7 +28,6 @@ int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
 				       const char *tx, const char *rx,
 				       struct device *dma_dev)
 {
-	unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
 	struct snd_dmaengine_pcm_config *pcm_conf;
 
 	pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL);
@@ -39,14 +38,11 @@ int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
 	pcm_conf->compat_filter_fn = filter;
 	pcm_conf->dma_dev = dma_dev;
 
-	if (dev->of_node) {
-		pcm_conf->chan_names[SNDRV_PCM_STREAM_PLAYBACK] = tx;
-		pcm_conf->chan_names[SNDRV_PCM_STREAM_CAPTURE] = rx;
-	} else {
-		flags |= SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME;
-	}
+	pcm_conf->chan_names[SNDRV_PCM_STREAM_PLAYBACK] = tx;
+	pcm_conf->chan_names[SNDRV_PCM_STREAM_CAPTURE] = rx;
 
-	return devm_snd_dmaengine_pcm_register(dev, pcm_conf, flags);
+	return devm_snd_dmaengine_pcm_register(dev, pcm_conf,
+				SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
 
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9931d007bc13..2e91d183dd41 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1460,7 +1460,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->drv->playback.channels_max = 6;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
-						 NULL, NULL, NULL);
+						 "tx", "rx", NULL);
 	if (ret < 0)
 		goto err_disable_clk;
 
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 67dfa27ae321..c08638b0e458 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -177,7 +177,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev,
 						 pdata->dma_filter,
-						 NULL, NULL, NULL);
+						 "tx", "rx", NULL);
 	if (ret) {
 		pr_err("failed to register the DMA: %d\n", ret);
 		return ret;
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index ba0f2b94f8d4..a8026b640c95 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -446,7 +446,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
 	s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, NULL,
-						 NULL, NULL, NULL);
+						 "tx", "rx", NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register the DMA: %d\n", ret);
 		return ret;
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 19/22] ASoC: samsung: Drop DAI DMA data chan_name assignments
       [not found]   ` <CGME20190207170152epcas1p254264a82287a54dc2452f5e73daab13d@epcas1p2.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 14:03       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

There is now no need to pass DMA channel names through the DAI DMA data,
custom DMA config of the PCM is now used for this purpose.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 sound/soc/samsung/i2s.c         | 4 ----
 sound/soc/samsung/s3c2412-i2s.c | 2 --
 sound/soc/samsung/s3c24xx-i2s.c | 2 --
 3 files changed, 8 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 2e91d183dd41..f012d892e6dc 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1450,8 +1450,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	}
 	pri_dai->dma_playback.addr = regs_base + I2STXD;
 	pri_dai->dma_capture.addr = regs_base + I2SRXD;
-	pri_dai->dma_playback.chan_name = "tx";
-	pri_dai->dma_capture.chan_name = "rx";
 	pri_dai->dma_playback.addr_width = 4;
 	pri_dai->dma_capture.addr_width = 4;
 	pri_dai->priv = priv;
@@ -1466,9 +1464,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 	if (quirks & QUIRK_SEC_DAI) {
 		sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
-
 		sec_dai->dma_playback.addr = regs_base + I2STXDS;
-		sec_dai->dma_playback.chan_name = "tx-sec";
 
 		if (!np) {
 			sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index c08638b0e458..a00e35147e50 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -35,12 +35,10 @@
 #include <linux/platform_data/asoc-s3c.h>
 
 static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = {
-	.chan_name	= "tx",
 	.addr_width	= 4,
 };
 
 static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = {
-	.chan_name	= "rx",
 	.addr_width	= 4,
 };
 
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index a8026b640c95..600b3b4cdb5b 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -31,12 +31,10 @@
 #include "s3c24xx-i2s.h"
 
 static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = {
-	.chan_name	= "tx",
 	.addr_width	= 2,
 };
 
 static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = {
-	.chan_name	= "rx",
 	.addr_width	= 2,
 };
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH 20/22] ASoC: dmaengine: Remove unused SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag
       [not found]   ` <CGME20190207170155epcas1p42ba30c540d35290c010b5bfa4645e3b1@epcas1p4.samsung.com>
@ 2019-02-07 17:00     ` Sylwester Nawrocki
  2019-02-11 14:04       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-07 17:00 UTC (permalink / raw)
  To: broonie
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc, Sylwester Nawrocki

There is now no users of this flag so remove it together with related
data structure field.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 include/sound/dmaengine_pcm.h         |  6 ------
 sound/soc/soc-generic-dmaengine-pcm.c | 21 ++++-----------------
 2 files changed, 4 insertions(+), 23 deletions(-)

diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index 2c4cfaa135a6..764c787928a4 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -63,7 +63,6 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
  * @slave_id: Slave requester id for the DMA channel.
  * @filter_data: Custom DMA channel filter data, this will usually be used when
  * requesting the DMA channel.
- * @chan_name: Custom channel name to use when requesting DMA channel.
  * @fifo_size: FIFO size of the DAI controller in bytes
  * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
  */
@@ -73,7 +72,6 @@ struct snd_dmaengine_dai_dma_data {
 	u32 maxburst;
 	unsigned int slave_id;
 	void *filter_data;
-	const char *chan_name;
 	unsigned int fifo_size;
 	unsigned int flags;
 };
@@ -99,10 +97,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
  * playback.
  */
 #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
-/*
- * The PCM streams have custom channel names specified.
- */
-#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
 
 /**
  * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 1b44e363c50c..f1ab6285a085 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -265,7 +265,6 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 	const struct snd_dmaengine_pcm_config *config = pcm->config;
 	struct device *dev = component->dev;
-	struct snd_dmaengine_dai_dma_data *dma_data;
 	struct snd_pcm_substream *substream;
 	size_t prealloc_buffer_size;
 	size_t max_buffer_size;
@@ -285,19 +284,9 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 		if (!substream)
 			continue;
 
-		dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-		if (!pcm->chan[i] &&
-		    ((pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME) ||
-		     (config && config->chan_names[i]))) {
-			const char *chan_name = dma_data->chan_name;
-
-			if (config && config->chan_names[i])
-				chan_name = config->chan_names[i];
-
+		if (!pcm->chan[i] && config && config->chan_names[i])
 			pcm->chan[i] = dma_request_slave_channel(dev,
-				chan_name);
-		}
+				config->chan_names[i]);
 
 		if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) {
 			pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd,
@@ -420,10 +409,8 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
 	const char *name;
 	struct dma_chan *chan;
 
-	if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT |
-			   SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) ||
-	     (!dev->of_node && !(config && config->dma_dev &&
-				config->dma_dev->of_node)))
+	if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || (!dev->of_node &&
+	    !(config && config->dma_dev && config->dma_dev->of_node)))
 		return 0;
 
 	if (config && config->dma_dev) {
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 01/22] ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()
  2019-02-07 17:00     ` [PATCH 01/22] ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of() Sylwester Nawrocki
@ 2019-02-11 13:29       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()" to the asoc tree Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:29 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:00, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> Currently when of_node of the "PCM" device is null
> dmaengine_pcm_request_chan_of() function will bail out, including cases
> when custom DMA device is intended to be used.  To have the channels
> properly requested when custom DMA device is provided extend the of_node
> test to also consider dma_dev->of_node.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/soc-generic-dmaengine-pcm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 02/22] ASoC: dmaengine: Extend use of chan_names provided in custom DMA config
  2019-02-07 17:00     ` [PATCH 02/22] ASoC: dmaengine: Extend use of chan_names provided in custom DMA config Sylwester Nawrocki
@ 2019-02-11 13:31       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: dmaengine: Extend use of chan_names provided in custom DMA config" to the asoc tree Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:31 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:00, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> There are currently two ways to specify custom DMA channel names:
>  - through the SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag and
>    snd_dmaengine_dai_dma_data data structure,
>  - through chan_names field of struct snd_dmaengine_pcm_config.
>
> In order to replace the DAI DMA data method with the custom DMA config
> one on non-DT platforms the dmaengine_pcm_new() function is extended
> to also consider channel names specified in the custom DMA config.
> If both config->chan_names and dma_data->chan_name are provided
> the former will be used.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/soc-generic-dmaengine-pcm.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 03/22] ASoC: samsung: dmaengine: Allow to specify custom DMA device
  2019-02-07 17:00     ` [PATCH 03/22] ASoC: samsung: dmaengine: Allow to specify custom DMA device Sylwester Nawrocki
@ 2019-02-11 13:31       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: samsung: dmaengine: Allow to specify custom DMA device" to the asoc tree Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:31 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:00, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The additional function argument will allow to select proper DMA device
> for requesting DMA channel for the secondary CPU DAI.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/dma.h         | 3 ++-
>  sound/soc/samsung/dmaengine.c   | 4 +++-
>  sound/soc/samsung/i2s.c         | 4 ++--
>  sound/soc/samsung/pcm.c         | 2 +-
>  sound/soc/samsung/s3c2412-i2s.c | 2 +-
>  sound/soc/samsung/s3c24xx-i2s.c | 2 +-
>  sound/soc/samsung/spdif.c       | 2 +-
>  7 files changed, 11 insertions(+), 8 deletions(-)
>

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI
  2019-02-07 17:00     ` [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI Sylwester Nawrocki
@ 2019-02-11 13:37       ` Krzysztof Kozlowski
  2019-02-11 14:32         ` Sylwester Nawrocki
  2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI" to the asoc tree Mark Brown
  1 sibling, 1 reply; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:37 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> Make sure i2s->rclk_srcrate is properly initialized also during
> playback through the secondary DAI.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
> index 9d3dcb2204fe..d5ddad23d5e5 100644
> --- a/sound/soc/samsung/i2s.c
> +++ b/sound/soc/samsung/i2s.c
> @@ -604,6 +604,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
>         unsigned int fmt)
>  {
>         struct i2s_dai *i2s = to_info(dai);
> +       struct i2s_dai *other = get_other_dai(i2s);
>         int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
>         u32 mod, tmp = 0;
>         unsigned long flags;
> @@ -661,7 +662,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
>                  * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
>                  * clock configuration assigned in DT is not overwritten.
>                  */
> -               if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL)
> +               if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL &&
> +                   other->clk_data.clks == NULL)
>                         i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
>                                                         0, SND_SOC_CLOCK_IN);
>                 break;
> @@ -699,6 +701,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
>         struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>  {
>         struct i2s_dai *i2s = to_info(dai);
> +       struct i2s_dai *other = get_other_dai(i2s);
>         u32 mod, mask = 0, val = 0;
>         struct clk *rclksrc;
>         unsigned long flags;
> @@ -784,6 +787,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
>         i2s->frmclk = params_rate(params);
>
>         rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
> +       if (!rclksrc || IS_ERR(rclksrc))

IS_ERR_OR_NULL

Best regards,
Krzysztof

> +               rclksrc = other->clk_table[CLK_I2S_RCLK_SRC];
> +
>         if (rclksrc && !IS_ERR(rclksrc))
>                 i2s->rclk_srcrate = clk_get_rate(rclksrc);
>
> --
> 2.20.1
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 05/22] ASoC: samsung: i2s: Convert to single component with multiple DAIs
  2019-02-07 17:00     ` [PATCH 05/22] ASoC: samsung: i2s: Convert to single component with multiple DAIs Sylwester Nawrocki
@ 2019-02-11 13:38       ` Krzysztof Kozlowski
  2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Convert to single component with multiple DAIs" to the asoc tree Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:38 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch includes minimal changes as a prerequisite for adding support
> for the Exynos secondary I2S interface as second DAI of the I2S component.
> Doing it that way allows to avoid problems as indicated in commmit
> 6b01e0365b1689 ("ASoC: samsung: i2s: disable secondary DAI until it gets fixed")
>
> The samsung_i2s_get_pri_dai() helper added in this patch is temporary and
> will be removed in one of subsequent patches.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 192 ++++++++++++++++++++++++----------------
>  1 file changed, 115 insertions(+), 77 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 06/22] ASoC: samsung: i2s: Restore support for the secondary PCM
  2019-02-07 17:00     ` [PATCH 06/22] ASoC: samsung: i2s: Restore support for the secondary PCM Sylwester Nawrocki
@ 2019-02-11 13:41       ` Krzysztof Kozlowski
  2019-02-11 14:50         ` Sylwester Nawrocki
  0 siblings, 1 reply; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:41 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch introduces again registration of additional platform device as
> we still need it for registering the secondary dmaengine PCM component.
>
> This patch in most part is a revert of changes done in commit
> be2c92eb64023e ("ASoC: samsung: i2s: Remove virtual device for secondary DAI")
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 52 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 48 insertions(+), 4 deletions(-)
>
> diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
> index 4bc3b181f1c2..994dcd4b01fb 100644
> --- a/sound/soc/samsung/i2s.c
> +++ b/sound/soc/samsung/i2s.c
> @@ -109,6 +109,7 @@ static DEFINE_SPINLOCK(lock);
>
>  struct samsung_i2s_priv {
>         struct platform_device *pdev;
> +       struct platform_device *pdev_sec;
>
>         /* Spinlock protecting access to the device's registers */
>         spinlock_t spinlock;
> @@ -1312,6 +1313,34 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
>         return ret;
>  }
>
> +/* Create platform device for the secondary PCM */
> +static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
> +{
> +       struct platform_device *pdev;
> +       int ret;
> +
> +       pdev = platform_device_register_simple("samsung-i2s-sec", -1, NULL, 0);
> +       if (!pdev)
> +               return -ENOMEM;
> +
> +       ret = device_attach(&pdev->dev);
> +       if (ret < 0) {
> +               dev_info(&pdev->dev, "device_attach() failed\n");
> +               return ret;
> +       }
> +
> +       priv->pdev_sec = pdev;
> +
> +       return 0;
> +}
> +
> +static void i2s_delete_secondary_device(struct samsung_i2s_priv *priv)
> +{
> +       if (priv->pdev_sec) {
> +               platform_device_del(priv->pdev_sec);
> +               priv->pdev_sec = NULL;
> +       }
> +}
>  static int samsung_i2s_probe(struct platform_device *pdev)
>  {
>         struct i2s_dai *pri_dai, *sec_dai = NULL;
> @@ -1329,13 +1358,15 @@ static int samsung_i2s_probe(struct platform_device *pdev)
>                 i2s_dai_data = (struct samsung_i2s_dai_data *)
>                                 platform_get_device_id(pdev)->driver_data;
>
> +       /* Nothing to do if it is the secondary device probing */
> +       if (!i2s_dai_data)
> +               return 0;
> +
>         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>         if (!priv)
>                 return -ENOMEM;
>
>         quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
> -       quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
> -
>         num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
>         priv->pdev = pdev;
>
> @@ -1425,8 +1456,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
>                 sec_dai->pri_dai = pri_dai;
>                 pri_dai->sec_dai = sec_dai;
>
> -               ret = samsung_asoc_dma_platform_register(&pdev->dev,
> -                                       sec_dai->filter, "tx-sec", NULL, NULL);
> +               ret = i2s_create_secondary_device(priv);
> +               if (ret < 0)
> +                       goto err_disable_clk;
> +
> +               ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev,
> +                                               sec_dai->filter, "tx-sec", NULL,
> +                                               &pdev->dev);
>                 if (ret < 0)
>                         goto err_disable_clk;
>
> @@ -1461,6 +1497,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
>         pm_runtime_disable(&pdev->dev);
>  err_disable_clk:
>         clk_disable_unprepare(pri_dai->clk);
> +       i2s_delete_secondary_device(priv);
>         return ret;
>  }
>
> @@ -1469,12 +1506,16 @@ static int samsung_i2s_remove(struct platform_device *pdev)
>         struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
>         struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
>
> +       if (!priv)

This is not obvious. Maybe comment that it is secondary device remove()?

> +               return 0;
> +
>         pm_runtime_get_sync(&pdev->dev);
>         pm_runtime_disable(&pdev->dev);
>
>         i2s_unregister_clock_provider(pdev);
>         clk_disable_unprepare(pri_dai->clk);
>         pm_runtime_put_noidle(&pdev->dev);
> +       i2s_delete_secondary_device(priv);
>
>         return 0;
>  }
> @@ -1573,6 +1614,9 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
>                 .name           = "samsung-i2s",
>                 .driver_data    = (kernel_ulong_t)&i2sv3_dai_type,
>         },
> +       {

Nit - squash with previous line.

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 07/22] ASoC: samsung: i2s: Move clk supplier data to common driver data structure
  2019-02-07 17:00     ` [PATCH 07/22] ASoC: samsung: i2s: Move clk supplier data to common driver data structure Sylwester Nawrocki
@ 2019-02-11 13:41       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:41 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> Having the clocks provider data in struct samsung_i2s_priv, i.e. per the I2S
> controller instance, rather than per CPU DAI better models the hardware and
> simplifies the code a little. The clock provider is common for both DAIs.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 68 ++++++++++++++++++++---------------------
>  1 file changed, 33 insertions(+), 35 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 08/22] ASoC: samsung: i2s: Add widgets and routes for DPCM support
  2019-02-07 17:00     ` [PATCH 08/22] ASoC: samsung: i2s: Add widgets and routes for DPCM support Sylwester Nawrocki
@ 2019-02-11 13:42       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:42 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch adds DAPM widgets required to model the internal mixer
> of the I2S controller merging audio streams from the primary and
> from the secondary PCM interface.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 09/22] ASoC: samsung: i2s: Move core clk to the driver common data structure
  2019-02-07 17:00     ` [PATCH 09/22] ASoC: samsung: i2s: Move core clk to the driver common data structure Sylwester Nawrocki
@ 2019-02-11 13:44       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:44 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The core clock is also common for both CPU DAIs so move it to
> the driver's private data structure.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)
>

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 10/22] ASoC: samsung: i2s: Move opclk data to common driver data structure
  2019-02-07 17:00     ` [PATCH 10/22] ASoC: samsung: i2s: Move opclk data to common driver " Sylwester Nawrocki
@ 2019-02-11 13:44       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:44 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The clock for generating I2S signals is also common for both CPU DAIs
> so move it to the driver's common data structure.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 70 +++++++++++++++++++----------------------
>  1 file changed, 33 insertions(+), 37 deletions(-)
>

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 11/22] ASoC: samsung: i2s: Move registers cache to common driver data structure
  2019-02-07 17:00     ` [PATCH 11/22] ASoC: samsung: i2s: Move registers cache " Sylwester Nawrocki
@ 2019-02-11 13:45       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:45 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> There is no need to keep the PM suspend/resume register cache separate
> for each DAI as those registers are common, move related i2s_dai data
> structure to the driver's common data structure.  This will allow us
> to simplify the code a little eventually and to make it easier to follow.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 20 +++++++++++---------
>  1 file changed, 11 insertions(+), 9 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 12/22] ASoC: samsung: i2s: Move SFR pointer to common driver data structure
  2019-02-07 17:00     ` [PATCH 12/22] ASoC: samsung: i2s: Move SFR pointer " Sylwester Nawrocki
@ 2019-02-11 13:46       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:46 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The SFR region is common for both DAIs so move related data structure
> field from struct i2s_dai to the common driver data structure.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 105 ++++++++++++++++++++++------------------
>  1 file changed, 58 insertions(+), 47 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 13/22] ASoC: samsung: i2s: Drop spinlock pointer from i2s_dai data structure
  2019-02-07 17:00     ` [PATCH 13/22] ASoC: samsung: i2s: Drop spinlock pointer from i2s_dai " Sylwester Nawrocki
@ 2019-02-11 13:47       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:47 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> As we now have the 'priv' pointer in most of the places we can use
> priv->lock directly, dropping extra indirection in the SFR region
> spinlock access.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 51 +++++++++++++++++++----------------------
>  1 file changed, 24 insertions(+), 27 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 14/22] ASoC: samsung: i2s: Move IP variant data to common driver data structure
  2019-02-07 17:00     ` [PATCH 14/22] ASoC: samsung: i2s: Move IP variant data to common driver " Sylwester Nawrocki
@ 2019-02-11 13:48       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:48 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The IP variant data is another thing common for both DAIs, move it
> to the driver's common data structure.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 42 ++++++++++++++++++++---------------------
>  1 file changed, 21 insertions(+), 21 deletions(-)
>

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 15/22] ASoC: samsung: i2s: Move quirks data to common driver data structure
  2019-02-07 17:00     ` [PATCH 15/22] ASoC: samsung: i2s: Move quirks " Sylwester Nawrocki
@ 2019-02-11 13:49       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:49 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> The quirk flags are common for the primary and the secondary DAI
> so move respective field from struct i2s_dai to common driver data
> structure.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 36 ++++++++++++++----------------------
>  1 file changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
> index 6ea0f0050fc8..e11d678e9c1f 100644
> --- a/sound/soc/samsung/i2s.c
> +++ b/sound/soc/samsung/i2s.c
> @@ -84,7 +84,6 @@ struct i2s_dai {
>         struct snd_dmaengine_dai_dma_data dma_capture;
>         struct snd_dmaengine_dai_dma_data idma_playback;
>         dma_filter_fn filter;
> -       u32     quirks;
>
>         struct samsung_i2s_priv *priv;
>  };
> @@ -122,19 +121,13 @@ struct samsung_i2s_priv {
>         u32 suspend_i2spsr;
>
>         const struct samsung_i2s_variant_regs *variant_regs;
> +       u32 quirks;
>
>         /* The clock provider's data */
>         struct clk *clk_table[3];
>         struct clk_onecell_data clk_data;
>  };
>
> -struct i2s_dai *samsung_i2s_get_pri_dai(struct device *dev)
> -{
> -       struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
> -
> -       return &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
> -}
> -
>  /* Returns true if this is the 'overlay' stereo DAI */
>  static inline bool is_secondary(struct i2s_dai *i2s)
>  {
> @@ -343,7 +336,7 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
>  {
>         struct samsung_i2s_priv *priv = i2s->priv;
>         u32 mod = readl(priv->addr + I2SMOD);
> -       int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
> +       int tdm = priv->quirks & QUIRK_SUPPORTS_TDM;
>         int bfs_shift = priv->variant_regs->bfs_off;
>
>         /* Non-TDM I2S controllers do not support BCLK > 48 * FS */
> @@ -563,7 +556,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs,
>         case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
>                 mask = 1 << i2s_regs->rclksrc_off;
>
> -               if ((i2s->quirks & QUIRK_NO_MUXPSR)
> +               if ((priv->quirks & QUIRK_NO_MUXPSR)
>                                 || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
>                         clk_id = 0;
>                 else
> @@ -830,8 +823,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
>
>  /* We set constraints on the substream acc to the version of I2S */
>  static int i2s_startup(struct snd_pcm_substream *substream,
> -         struct snd_soc_dai *dai)
> +       struct snd_soc_dai *dai)

This change looks unrelated.

For the rest:
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 16/22] ASoC: samsung: i2s: Get rid of a static spinlock
  2019-02-07 17:00     ` [PATCH 16/22] ASoC: samsung: i2s: Get rid of a static spinlock Sylwester Nawrocki
@ 2019-02-11 13:51       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:51 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch makes the spinlock serializing access to the primary/secondary
> PCM a per I2S controller lock, rather than a global one. There is no need
> to have a global lock across multiple I2S controllers in the SoC.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI
  2019-02-07 17:00     ` [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI Sylwester Nawrocki
@ 2019-02-11 13:57       ` Krzysztof Kozlowski
  2019-02-11 15:19         ` Sylwester Nawrocki
  0 siblings, 1 reply; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:57 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This patch adds DPCM links in order to support the secondary I2S interface.
> For the secondary PCM interface to be actually available one more entry
> should be added to the sound-dai property in sound/cpu node in DT.
> The changes in driver are done in a way so we are backwards compatible with
> existing DTS/DTB, i.e. if the cpu sound-dai property contains only one entry
> only one PCM will be registered.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/odroid.c | 132 +++++++++++++++++++++++++++----------
>  1 file changed, 96 insertions(+), 36 deletions(-)
>
> diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
> index e7b371b07230..bab61e8278a0 100644
> --- a/sound/soc/samsung/odroid.c
> +++ b/sound/soc/samsung/odroid.c
> @@ -7,6 +7,7 @@
>   */
>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/module.h>
> @@ -17,21 +18,24 @@
>
>  struct odroid_priv {
>         struct snd_soc_card card;
> -       struct snd_soc_dai_link dai_link;
> -
>         struct clk *clk_i2s_bus;
>         struct clk *sclk_i2s;
>  };
>
> -static int odroid_card_startup(struct snd_pcm_substream *substream)
> +static int odroid_card_fe_startup(struct snd_pcm_substream *substream)
>  {
>         struct snd_pcm_runtime *runtime = substream->runtime;
>
>         snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
> +
>         return 0;
>  }
>
> -static int odroid_card_hw_params(struct snd_pcm_substream *substream,
> +static const struct snd_soc_ops odroid_card_fe_ops = {
> +       .startup = odroid_card_fe_startup,
> +};
> +
> +static int odroid_card_be_hw_params(struct snd_pcm_substream *substream,
>                                       struct snd_pcm_hw_params *params)
>  {
>         struct snd_soc_pcm_runtime *rtd = substream->private_data;
> @@ -86,19 +90,56 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
>         return 0;
>  }
>
> -static const struct snd_soc_ops odroid_card_ops = {
> -       .startup = odroid_card_startup,
> -       .hw_params = odroid_card_hw_params,
> +static const struct snd_soc_ops odroid_card_be_ops = {
> +       .hw_params = odroid_card_be_hw_params,
> +};
> +
> +static struct snd_soc_dai_link odroid_card_dais[] = {
> +       {
> +               /* Primary FE <-> BE link */
> +               .codec_name = "snd-soc-dummy",
> +               .codec_dai_name = "snd-soc-dummy-dai",
> +               .ops = &odroid_card_fe_ops,
> +               .name = "Primary",
> +               .stream_name = "Primary",
> +               .platform_name = "3830000.i2s",

Why exposing address as platform_name? I think it is not used so how
about some friendlier name?

> +               .dynamic = 1,
> +               .dpcm_playback = 1,
> +       }, {
> +               /* BE <-> CODECs link */
> +               .name = "I2S Mixer",
> +               .cpu_name = "snd-soc-dummy",
> +               .cpu_dai_name = "snd-soc-dummy-dai",
> +               .platform_name = "snd-soc-dummy",
> +               .ops = &odroid_card_be_ops,
> +               .no_pcm = 1,
> +               .dpcm_playback = 1,
> +               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
> +                               SND_SOC_DAIFMT_CBS_CFS,
> +       }, {
> +               /* Secondary FE <-> BE link */
> +               .playback_only = 1,
> +               .codec_name = "snd-soc-dummy",
> +               .codec_dai_name = "snd-soc-dummy-dai",
> +               .ops = &odroid_card_fe_ops,
> +               .name = "Secondary",
> +               .stream_name = "Secondary",
> +               .platform_name = "samsung-i2s-sec",
> +               .dynamic = 1,
> +               .dpcm_playback = 1,
> +       }
>  };
>
> +

Unneeded new line.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 18/22] ASoC: samsung: Specify DMA channel names through custom DMA config
  2019-02-07 17:00     ` [PATCH 18/22] ASoC: samsung: Specify DMA channel names through custom DMA config Sylwester Nawrocki
@ 2019-02-11 13:58       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 13:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> This is a part of conversion of Samsung platforms to use the custom DMA
> config for specifying DMA channel names, in addition to passing custom
> DMA device for the secondary CPU DAI's "PCM" component for some variants
> of the I2S controller.
>
> We also don't set the SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME any more
> as setting it wouldn't allow to specify DMA channels through the custom
> DMA config.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/dmaengine.c   | 12 ++++--------
>  sound/soc/samsung/i2s.c         |  2 +-
>  sound/soc/samsung/s3c2412-i2s.c |  2 +-
>  sound/soc/samsung/s3c24xx-i2s.c |  2 +-
>  4 files changed, 7 insertions(+), 11 deletions(-)
>

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 19/22] ASoC: samsung: Drop DAI DMA data chan_name assignments
  2019-02-07 17:00     ` [PATCH 19/22] ASoC: samsung: Drop DAI DMA data chan_name assignments Sylwester Nawrocki
@ 2019-02-11 14:03       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 14:03 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> There is now no need to pass DMA channel names through the DAI DMA data,
> custom DMA config of the PCM is now used for this purpose.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  sound/soc/samsung/i2s.c         | 4 ----
>  sound/soc/samsung/s3c2412-i2s.c | 2 --
>  sound/soc/samsung/s3c24xx-i2s.c | 2 --
>  3 files changed, 8 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 20/22] ASoC: dmaengine: Remove unused SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag
  2019-02-07 17:00     ` [PATCH 20/22] ASoC: dmaengine: Remove unused SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag Sylwester Nawrocki
@ 2019-02-11 14:04       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 14:04 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Thu, 7 Feb 2019 at 18:01, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> There is now no users of this flag so remove it together with related
> data structure field.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  include/sound/dmaengine_pcm.h         |  6 ------
>  sound/soc/soc-generic-dmaengine-pcm.c | 21 ++++-----------------
>  2 files changed, 4 insertions(+), 23 deletions(-)

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI
  2019-02-11 13:37       ` Krzysztof Kozlowski
@ 2019-02-11 14:32         ` Sylwester Nawrocki
  2019-02-11 15:03           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-11 14:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On 2/11/19 14:37, Krzysztof Kozlowski wrote:
>> @@ -784,6 +787,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
>>         i2s->frmclk = params_rate(params);
>>
>>         rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
>> +       if (!rclksrc || IS_ERR(rclksrc))

> IS_ERR_OR_NULL

Thanks for your review! That line will be removed by subsequent patch
(7/22) so I'd say such a change wouldn't make a difference anyway.
Besides not using IS_ERR_OR_NULL() was intentional.


-- 
Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 06/22] ASoC: samsung: i2s: Restore support for the secondary PCM
  2019-02-11 13:41       ` Krzysztof Kozlowski
@ 2019-02-11 14:50         ` Sylwester Nawrocki
  0 siblings, 0 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-11 14:50 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On 2/11/19 14:41, Krzysztof Kozlowski wrote:
>> @@ -1469,12 +1506,16 @@ static int samsung_i2s_remove(struct platform_device *pdev)
>>         struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
>>         struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
>>
>> +       if (!priv)

> This is not obvious. Maybe comment that it is secondary device remove()?

Sure, I will a comment here, I was considering it earlier but somehow it got missed.

>> @@ -1573,6 +1614,9 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
>>                 .name           = "samsung-i2s",
>>                 .driver_data    = (kernel_ulong_t)&i2sv3_dai_type,
>>         },
>> +       {

> Nit - squash with previous line.

Will change it.


-- 
Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI
  2019-02-11 14:32         ` Sylwester Nawrocki
@ 2019-02-11 15:03           ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 15:03 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Mon, 11 Feb 2019 at 15:32, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> On 2/11/19 14:37, Krzysztof Kozlowski wrote:
> >> @@ -784,6 +787,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
> >>         i2s->frmclk = params_rate(params);
> >>
> >>         rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
> >> +       if (!rclksrc || IS_ERR(rclksrc))
>
> > IS_ERR_OR_NULL
>
> Thanks for your review! That line will be removed by subsequent patch
> (7/22) so I'd say such a change wouldn't make a difference anyway.

Then let's skip it:
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI
  2019-02-11 13:57       ` Krzysztof Kozlowski
@ 2019-02-11 15:19         ` Sylwester Nawrocki
  2019-02-11 15:34           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-11 15:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On 2/11/19 14:57, Krzysztof Kozlowski wrote:
>> static struct snd_soc_dai_link odroid_card_dais[] = {
>> +       {
>> +               /* Primary FE <-> BE link */
>> +               .codec_name = "snd-soc-dummy",
>> +               .codec_dai_name = "snd-soc-dummy-dai",
>> +               .ops = &odroid_card_fe_ops,
>> +               .name = "Primary",
>> +               .stream_name = "Primary",
>> +               .platform_name = "3830000.i2s",

> Why exposing address as platform_name? I think it is not used so how
> about some friendlier name?
 
This entry is for selecting "PCM" (DMA) component for the link. 
For proper matching we need to use names of devices for which
the dmaengine based PCM component is registered (with a call to
samsung_asoc_dma_platform_register()).

We can't use platform_of_node because 2 PCM components ("3830000.i2s", 
"samsung-i2s-sec") are now associated with same DT node.


>> +       }, {
>> +               /* BE <-> CODECs link */
>> +       }, {
>> +               /* Secondary FE <-> BE link */

>> +               .platform_name = "samsung-i2s-sec",

>> +       }
>>  };


--
Thanks, 
Sylwester

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI
  2019-02-11 15:19         ` Sylwester Nawrocki
@ 2019-02-11 15:34           ` Krzysztof Kozlowski
  0 siblings, 0 replies; 53+ messages in thread
From: Krzysztof Kozlowski @ 2019-02-11 15:34 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: broonie, lgirdwood, sbkim73, Marek Szyprowski,
	Bartłomiej Żołnierkiewicz, alsa-devel,
	linux-kernel, linux-samsung-soc

On Mon, 11 Feb 2019 at 16:19, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>
> On 2/11/19 14:57, Krzysztof Kozlowski wrote:
> >> static struct snd_soc_dai_link odroid_card_dais[] = {
> >> +       {
> >> +               /* Primary FE <-> BE link */
> >> +               .codec_name = "snd-soc-dummy",
> >> +               .codec_dai_name = "snd-soc-dummy-dai",
> >> +               .ops = &odroid_card_fe_ops,
> >> +               .name = "Primary",
> >> +               .stream_name = "Primary",
> >> +               .platform_name = "3830000.i2s",
>
> > Why exposing address as platform_name? I think it is not used so how
> > about some friendlier name?
>
> This entry is for selecting "PCM" (DMA) component for the link.
> For proper matching we need to use names of devices for which
> the dmaengine based PCM component is registered (with a call to
> samsung_asoc_dma_platform_register()).
>
> We can't use platform_of_node because 2 PCM components ("3830000.i2s",
> "samsung-i2s-sec") are now associated with same DT node.

Thanks for explanation.
With the unneeded empty line fixup:
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards
  2019-02-07 17:00 ` [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards Sylwester Nawrocki
                     ` (19 preceding siblings ...)
       [not found]   ` <CGME20190207170155epcas1p42ba30c540d35290c010b5bfa4645e3b1@epcas1p4.samsung.com>
@ 2019-02-12 16:40   ` Mark Brown
  2019-02-12 18:17     ` Sylwester Nawrocki
  20 siblings, 1 reply; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:40 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc

[-- Attachment #1: Type: text/plain, Size: 524 bytes --]

On Thu, Feb 07, 2019 at 06:00:08PM +0100, Sylwester Nawrocki wrote:

> I am not entirely sure we should be removing the
> SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag like this, it might all
> be a bit more explicit with the flag.

I'm fairly happy with what you're doing here and the Samsung driver is
the only user so the view of people working on that is pretty important
here.  I've gone ahead and applied the first few patches so they don't
need rereviewing, the rest looked fine modulo the comments from
Krzysztof.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Applied "ASoC: samsung: i2s: Convert to single component with multiple DAIs" to the asoc tree
  2019-02-07 17:00     ` [PATCH 05/22] ASoC: samsung: i2s: Convert to single component with multiple DAIs Sylwester Nawrocki
  2019-02-11 13:38       ` Krzysztof Kozlowski
@ 2019-02-12 16:58       ` Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Mark Brown, broonie, alsa-devel,
	linux-samsung-soc, b.zolnierkie, sbkim73, lgirdwood, krzk,
	linux-kernel, m.szyprowski, alsa-devel

The patch

   ASoC: samsung: i2s: Convert to single component with multiple DAIs

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From a404b72d2bdd45878e1441650967a75452d5e420 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Thu, 7 Feb 2019 18:00:13 +0100
Subject: [PATCH] ASoC: samsung: i2s: Convert to single component with multiple
 DAIs

This patch includes minimal changes as a prerequisite for adding support
for the Exynos secondary I2S interface as second DAI of the I2S component.
Doing it that way allows to avoid problems as indicated in commmit
6b01e0365b1689 ("ASoC: samsung: i2s: disable secondary DAI until it gets fixed")

The samsung_i2s_get_pri_dai() helper added in this patch is temporary and
will be removed in one of subsequent patches.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/samsung/i2s.c | 192 ++++++++++++++++++++++++----------------
 1 file changed, 115 insertions(+), 77 deletions(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index efc8704d36e3..455bc65d115a 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -34,6 +34,9 @@
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 
+#define SAMSUNG_I2S_ID_PRIMARY		1
+#define SAMSUNG_I2S_ID_SECONDARY	2
+
 struct samsung_i2s_variant_regs {
 	unsigned int	bfs_off;
 	unsigned int	rfs_off;
@@ -79,8 +82,10 @@ struct i2s_dai {
 #define DAI_OPENED	(1 << 0) /* Dai is opened */
 #define DAI_MANAGER	(1 << 1) /* Dai is the manager */
 	unsigned mode;
+
 	/* Driver for this DAI */
-	struct snd_soc_dai_driver i2s_dai_drv;
+	struct snd_soc_dai_driver *drv;
+
 	/* DMA parameters */
 	struct snd_dmaengine_dai_dma_data dma_playback;
 	struct snd_dmaengine_dai_dma_data dma_capture;
@@ -92,8 +97,6 @@ struct i2s_dai {
 	u32	suspend_i2spsr;
 	const struct samsung_i2s_variant_regs *variant_regs;
 
-	/* Spinlock protecting access to the device's registers */
-	spinlock_t spinlock;
 	spinlock_t *lock;
 
 	/* Below fields are only valid if this is the primary FIFO */
@@ -104,10 +107,29 @@ struct i2s_dai {
 /* Lock for cross i/f checks */
 static DEFINE_SPINLOCK(lock);
 
-/* If this is the 'overlay' stereo DAI */
+struct samsung_i2s_priv {
+	struct platform_device *pdev;
+
+	/* Spinlock protecting access to the device's registers */
+	spinlock_t spinlock;
+
+	/* CPU DAIs and their corresponding drivers */
+	struct i2s_dai *dai;
+	struct snd_soc_dai_driver *dai_drv;
+	int num_dais;
+};
+
+struct i2s_dai *samsung_i2s_get_pri_dai(struct device *dev)
+{
+	struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
+
+	return &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
+}
+
+/* Returns true if this is the 'overlay' stereo DAI */
 static inline bool is_secondary(struct i2s_dai *i2s)
 {
-	return i2s->pri_dai ? true : false;
+	return i2s->drv->id == SAMSUNG_I2S_ID_SECONDARY;
 }
 
 /* If operating in SoC-Slave mode */
@@ -202,7 +224,9 @@ static inline bool any_active(struct i2s_dai *i2s)
 
 static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
 {
-	return snd_soc_dai_get_drvdata(dai);
+	struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
+
+	return &priv->dai[dai->id - 1];
 }
 
 static inline bool is_opened(struct i2s_dai *i2s)
@@ -1059,7 +1083,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 
 static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 {
-	struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
+	struct i2s_dai *i2s = to_info(dai);
 	unsigned long flags;
 
 	pm_runtime_get_sync(dai->dev);
@@ -1096,47 +1120,63 @@ static const struct snd_soc_component_driver samsung_i2s_component = {
 					SNDRV_PCM_FMTBIT_S16_LE | \
 					SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev,
-				const struct samsung_i2s_dai_data *i2s_dai_data,
-				bool sec)
+static int i2s_alloc_dais(struct samsung_i2s_priv *priv,
+			  const struct samsung_i2s_dai_data *i2s_dai_data,
+			  int num_dais)
 {
-	struct i2s_dai *i2s;
-
-	i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
-	if (i2s == NULL)
-		return NULL;
-
-	i2s->pdev = pdev;
-	i2s->pri_dai = NULL;
-	i2s->sec_dai = NULL;
-	i2s->i2s_dai_drv.id = 1;
-	i2s->i2s_dai_drv.symmetric_rates = 1;
-	i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
-	i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
-	i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
-	i2s->i2s_dai_drv.suspend = i2s_suspend;
-	i2s->i2s_dai_drv.resume = i2s_resume;
-	i2s->i2s_dai_drv.playback.channels_min = 1;
-	i2s->i2s_dai_drv.playback.channels_max = 2;
-	i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates;
-	i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
-
-	if (!sec) {
-		i2s->i2s_dai_drv.name = SAMSUNG_I2S_DAI;
-		i2s->i2s_dai_drv.capture.channels_min = 1;
-		i2s->i2s_dai_drv.capture.channels_max = 2;
-		i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates;
-		i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
-	} else {
-		i2s->i2s_dai_drv.name = SAMSUNG_I2S_DAI_SEC;
+	static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" };
+	struct snd_soc_dai_driver *dai_drv;
+	struct i2s_dai *dai;
+	int i;
+
+	priv->dai = devm_kcalloc(&priv->pdev->dev, num_dais,
+				     sizeof(*dai), GFP_KERNEL);
+	if (!priv->dai)
+		return -ENOMEM;
+
+	priv->dai_drv = devm_kcalloc(&priv->pdev->dev, num_dais,
+				     sizeof(*dai_drv), GFP_KERNEL);
+	if (!priv->dai_drv)
+		return -ENOMEM;
+
+	for (i = 0; i < num_dais; i++) {
+		dai_drv = &priv->dai_drv[i];
+
+		dai_drv->probe = samsung_i2s_dai_probe;
+		dai_drv->remove = samsung_i2s_dai_remove;
+		dai_drv->suspend = i2s_suspend;
+		dai_drv->resume = i2s_resume;
+
+		dai_drv->symmetric_rates = 1;
+		dai_drv->ops = &samsung_i2s_dai_ops;
+
+		dai_drv->playback.channels_min = 1;
+		dai_drv->playback.channels_max = 2;
+		dai_drv->playback.rates = i2s_dai_data->pcm_rates;
+		dai_drv->playback.formats = SAMSUNG_I2S_FMTS;
+
+		dai_drv->id = i + 1;
+		dai_drv->name = dai_names[i];
+
+		priv->dai[i].drv = &priv->dai_drv[i];
+		priv->dai[i].pdev = priv->pdev;
 	}
-	return i2s;
+
+	/* Initialize capture only for the primary DAI */
+	dai_drv = &priv->dai_drv[SAMSUNG_I2S_ID_PRIMARY - 1];
+
+	dai_drv->capture.channels_min = 1;
+	dai_drv->capture.channels_max = 2;
+	dai_drv->capture.rates = i2s_dai_data->pcm_rates;
+	dai_drv->capture.formats = SAMSUNG_I2S_FMTS;
+
+	return 0;
 }
 
 #ifdef CONFIG_PM
 static int i2s_runtime_suspend(struct device *dev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 
 	i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
 	i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
@@ -1151,7 +1191,7 @@ static int i2s_runtime_suspend(struct device *dev)
 
 static int i2s_runtime_resume(struct device *dev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk);
@@ -1186,7 +1226,7 @@ static void i2s_unregister_clocks(struct i2s_dai *i2s)
 
 static void i2s_unregister_clock_provider(struct platform_device *pdev)
 {
-	struct i2s_dai *i2s = dev_get_drvdata(&pdev->dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(&pdev->dev);
 
 	of_clk_del_provider(pdev->dev.of_node);
 	i2s_unregister_clocks(i2s);
@@ -1194,11 +1234,12 @@ static void i2s_unregister_clock_provider(struct platform_device *pdev)
 
 static int i2s_register_clock_provider(struct platform_device *pdev)
 {
+
 	const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
 	const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
 	const char *p_names[2] = { NULL };
 	struct device *dev = &pdev->dev;
-	struct i2s_dai *i2s = dev_get_drvdata(dev);
+	struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
 	const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
 	const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
 	struct clk *rclksrc;
@@ -1273,7 +1314,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	u32 regs_base, quirks = 0, idma_addr = 0;
 	struct device_node *np = pdev->dev.of_node;
 	const struct samsung_i2s_dai_data *i2s_dai_data;
-	int ret;
+	int num_dais, ret;
+	struct samsung_i2s_priv *priv;
 
 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
 		i2s_dai_data = of_device_get_match_data(&pdev->dev);
@@ -1281,14 +1323,24 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		i2s_dai_data = (struct samsung_i2s_dai_data *)
 				platform_get_device_id(pdev)->driver_data;
 
-	pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false);
-	if (!pri_dai) {
-		dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
-	}
 
-	spin_lock_init(&pri_dai->spinlock);
-	pri_dai->lock = &pri_dai->spinlock;
+	quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
+	quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
+
+	num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
+	priv->pdev = pdev;
+
+	ret = i2s_alloc_dais(priv, i2s_dai_data, num_dais);
+	if (ret < 0)
+		return ret;
+
+	pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
+
+	spin_lock_init(&priv->spinlock);
+	pri_dai->lock = &priv->spinlock;
 
 	if (!np) {
 		if (i2s_pdata == NULL) {
@@ -1300,10 +1352,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
 		pri_dai->filter = i2s_pdata->dma_filter;
 
-		quirks = i2s_pdata->type.quirks;
 		idma_addr = i2s_pdata->type.idma_addr;
 	} else {
-		quirks = i2s_dai_data->quirks;
 		if (of_property_read_u32(np, "samsung,idma-addr",
 					 &idma_addr)) {
 			if (quirks & QUIRK_SUPPORTS_IDMA) {
@@ -1312,7 +1362,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 			}
 		}
 	}
-	quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
@@ -1342,28 +1391,17 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 	pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
 
 	if (quirks & QUIRK_PRI_6CHAN)
-		pri_dai->i2s_dai_drv.playback.channels_max = 6;
+		pri_dai->drv->playback.channels_max = 6;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
 						 NULL, NULL, NULL);
 	if (ret < 0)
 		goto err_disable_clk;
 
-	ret = devm_snd_soc_register_component(&pdev->dev,
-					&samsung_i2s_component,
-					&pri_dai->i2s_dai_drv, 1);
-	if (ret < 0)
-		goto err_disable_clk;
-
 	if (quirks & QUIRK_SEC_DAI) {
-		sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true);
-		if (!sec_dai) {
-			dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
-			ret = -ENOMEM;
-			goto err_disable_clk;
-		}
+		sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
 
-		sec_dai->lock = &pri_dai->spinlock;
+		sec_dai->lock = &priv->spinlock;
 		sec_dai->variant_regs = pri_dai->variant_regs;
 		sec_dai->dma_playback.addr = regs_base + I2STXDS;
 		sec_dai->dma_playback.chan_name = "tx-sec";
@@ -1386,11 +1424,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		if (ret < 0)
 			goto err_disable_clk;
 
-		ret = devm_snd_soc_register_component(&pdev->dev,
-						&samsung_i2s_component,
-						&sec_dai->i2s_dai_drv, 1);
-		if (ret < 0)
-			goto err_disable_clk;
 	}
 
 	if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
@@ -1399,7 +1432,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		goto err_disable_clk;
 	}
 
-	dev_set_drvdata(&pdev->dev, pri_dai);
+	dev_set_drvdata(&pdev->dev, priv);
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					&samsung_i2s_component,
+					priv->dai_drv, num_dais);
+	if (ret < 0)
+		goto err_disable_clk;
 
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -1421,9 +1460,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 
 static int samsung_i2s_remove(struct platform_device *pdev)
 {
-	struct i2s_dai *pri_dai;
-
-	pri_dai = dev_get_drvdata(&pdev->dev);
+	struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
+	struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
 
 	pm_runtime_get_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Applied "ASoC: samsung: dmaengine: Allow to specify custom DMA device" to the asoc tree
  2019-02-07 17:00     ` [PATCH 03/22] ASoC: samsung: dmaengine: Allow to specify custom DMA device Sylwester Nawrocki
  2019-02-11 13:31       ` Krzysztof Kozlowski
@ 2019-02-12 16:58       ` Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Mark Brown, broonie, alsa-devel,
	linux-samsung-soc, b.zolnierkie, sbkim73, lgirdwood, krzk,
	linux-kernel, m.szyprowski, alsa-devel

The patch

   ASoC: samsung: dmaengine: Allow to specify custom DMA device

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 96f06cde2c00d78395f5200cbbdf216c5ce3bc3f Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Thu, 7 Feb 2019 18:00:11 +0100
Subject: [PATCH] ASoC: samsung: dmaengine: Allow to specify custom DMA device

The additional function argument will allow to select proper DMA device
for requesting DMA channel for the secondary CPU DAI.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/samsung/dma.h         | 3 ++-
 sound/soc/samsung/dmaengine.c   | 4 +++-
 sound/soc/samsung/i2s.c         | 4 ++--
 sound/soc/samsung/pcm.c         | 2 +-
 sound/soc/samsung/s3c2412-i2s.c | 2 +-
 sound/soc/samsung/s3c24xx-i2s.c | 2 +-
 sound/soc/samsung/spdif.c       | 2 +-
 7 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 7ae580d677c8..0ae15d01a3f6 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -17,5 +17,6 @@
  * otherwise actual DMA channel names must be passed to this function.
  */
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
-				       const char *tx, const char *rx);
+				       const char *tx, const char *rx,
+				       struct device *dma_dev);
 #endif /* _SAMSUNG_DMA_H */
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 9104c98deeb7..84601fa9aa46 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -25,7 +25,8 @@
 #include "dma.h"
 
 int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
-				       const char *tx, const char *rx)
+				       const char *tx, const char *rx,
+				       struct device *dma_dev)
 {
 	unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
 	struct snd_dmaengine_pcm_config *pcm_conf;
@@ -36,6 +37,7 @@ int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
 
 	pcm_conf->prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config;
 	pcm_conf->compat_filter_fn = filter;
+	pcm_conf->dma_dev = dma_dev;
 
 	if (dev->of_node) {
 		pcm_conf->chan_names[SNDRV_PCM_STREAM_PLAYBACK] = tx;
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d6c62aa13041..efc8704d36e3 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1345,7 +1345,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->i2s_dai_drv.playback.channels_max = 6;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret < 0)
 		goto err_disable_clk;
 
@@ -1382,7 +1382,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
 		pri_dai->sec_dai = sec_dai;
 
 		ret = samsung_asoc_dma_platform_register(&pdev->dev,
-					sec_dai->filter, "tx-sec", NULL);
+					sec_dai->filter, "tx-sec", NULL, NULL);
 		if (ret < 0)
 			goto err_disable_clk;
 
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 37f95eee1558..3c7baa561084 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -553,7 +553,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
 	pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
 		goto err_dis_pclk;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index cc0840fff5aa..67dfa27ae321 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -177,7 +177,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev,
 						 pdata->dma_filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		pr_err("failed to register the DMA: %d\n", ret);
 		return ret;
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 8d58d02183bf..ba0f2b94f8d4 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -446,7 +446,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
 	s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, NULL,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register the DMA: %d\n", ret);
 		return ret;
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index cb59911e65c0..5e4afb330416 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -430,7 +430,7 @@ static int spdif_probe(struct platform_device *pdev)
 	spdif->dma_playback = &spdif_stereo_out;
 
 	ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
-						 NULL, NULL);
+						 NULL, NULL, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
 		goto err4;
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Applied "ASoC: dmaengine: Extend use of chan_names provided in custom DMA config" to the asoc tree
  2019-02-07 17:00     ` [PATCH 02/22] ASoC: dmaengine: Extend use of chan_names provided in custom DMA config Sylwester Nawrocki
  2019-02-11 13:31       ` Krzysztof Kozlowski
@ 2019-02-12 16:58       ` Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Mark Brown, broonie, alsa-devel,
	linux-samsung-soc, b.zolnierkie, sbkim73, lgirdwood, krzk,
	linux-kernel, m.szyprowski, alsa-devel

The patch

   ASoC: dmaengine: Extend use of chan_names provided in custom DMA config

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 10cbf3507bcb9baa82bf3445502e8ccafaa09fc8 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Thu, 7 Feb 2019 18:00:10 +0100
Subject: [PATCH] ASoC: dmaengine: Extend use of chan_names provided in custom
 DMA config

There are currently two ways to specify custom DMA channel names:
 - through the SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag and
   snd_dmaengine_dai_dma_data data structure,
 - through chan_names field of struct snd_dmaengine_pcm_config.

In order to replace the DAI DMA data method with the custom DMA config
one on non-DT platforms the dmaengine_pcm_new() function is extended
to also consider channel names specified in the custom DMA config.
If both config->chan_names and dma_data->chan_name are provided
the former will be used.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/soc-generic-dmaengine-pcm.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6d7638c1233d..1b44e363c50c 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -288,9 +288,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 		dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 		if (!pcm->chan[i] &&
-		    (pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME))
+		    ((pcm->flags & SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME) ||
+		     (config && config->chan_names[i]))) {
+			const char *chan_name = dma_data->chan_name;
+
+			if (config && config->chan_names[i])
+				chan_name = config->chan_names[i];
+
 			pcm->chan[i] = dma_request_slave_channel(dev,
-				dma_data->chan_name);
+				chan_name);
+		}
 
 		if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) {
 			pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd,
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Applied "ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()" to the asoc tree
  2019-02-07 17:00     ` [PATCH 01/22] ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of() Sylwester Nawrocki
  2019-02-11 13:29       ` Krzysztof Kozlowski
@ 2019-02-12 16:58       ` Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Mark Brown, broonie, alsa-devel,
	linux-samsung-soc, b.zolnierkie, sbkim73, lgirdwood, krzk,
	linux-kernel, m.szyprowski, alsa-devel

The patch

   ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 51256d348c9af1bf544a4432abc1d5f2fd3ef34b Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Thu, 7 Feb 2019 18:00:09 +0100
Subject: [PATCH] ASoC: dmaengine: Improve of_node test in
 dmaengine_pcm_request_chan_of()

Currently when of_node of the "PCM" device is null
dmaengine_pcm_request_chan_of() function will bail out, including cases
when custom DMA device is intended to be used.  To have the channels
properly requested when custom DMA device is provided extend the of_node
test to also consider dma_dev->of_node.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/soc-generic-dmaengine-pcm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 30e791a53352..6d7638c1233d 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -415,7 +415,8 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
 
 	if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT |
 			   SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) ||
-	    !dev->of_node)
+	     (!dev->of_node && !(config && config->dma_dev &&
+				config->dma_dev->of_node)))
 		return 0;
 
 	if (config && config->dma_dev) {
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Applied "ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI" to the asoc tree
  2019-02-07 17:00     ` [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI Sylwester Nawrocki
  2019-02-11 13:37       ` Krzysztof Kozlowski
@ 2019-02-12 16:58       ` Mark Brown
  1 sibling, 0 replies; 53+ messages in thread
From: Mark Brown @ 2019-02-12 16:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Krzysztof Kozlowski, Mark Brown, broonie, alsa-devel,
	linux-samsung-soc, b.zolnierkie, sbkim73, lgirdwood, krzk,
	linux-kernel, m.szyprowski, alsa-devel

The patch

   ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 323fb7b947b265753de34703dbbf8acc8ea3a4de Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Thu, 7 Feb 2019 18:00:12 +0100
Subject: [PATCH] ASoC: samsung: i2s: Fix prescaler setting for the secondary
 DAI

Make sure i2s->rclk_srcrate is properly initialized also during
playback through the secondary DAI.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/samsung/i2s.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index ce00fe2f6aae..d4bde4834ce5 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -604,6 +604,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 	unsigned int fmt)
 {
 	struct i2s_dai *i2s = to_info(dai);
+	struct i2s_dai *other = get_other_dai(i2s);
 	int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave;
 	u32 mod, tmp = 0;
 	unsigned long flags;
@@ -661,7 +662,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
 		 * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
 		 * clock configuration assigned in DT is not overwritten.
 		 */
-		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL)
+		if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL &&
+		    other->clk_data.clks == NULL)
 			i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 							0, SND_SOC_CLOCK_IN);
 		break;
@@ -699,6 +701,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
 	struct i2s_dai *i2s = to_info(dai);
+	struct i2s_dai *other = get_other_dai(i2s);
 	u32 mod, mask = 0, val = 0;
 	struct clk *rclksrc;
 	unsigned long flags;
@@ -784,6 +787,9 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
 	i2s->frmclk = params_rate(params);
 
 	rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
+	if (!rclksrc || IS_ERR(rclksrc))
+		rclksrc = other->clk_table[CLK_I2S_RCLK_SRC];
+
 	if (rclksrc && !IS_ERR(rclksrc))
 		i2s->rclk_srcrate = clk_get_rate(rclksrc);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards
  2019-02-12 16:40   ` [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards Mark Brown
@ 2019-02-12 18:17     ` Sylwester Nawrocki
  0 siblings, 0 replies; 53+ messages in thread
From: Sylwester Nawrocki @ 2019-02-12 18:17 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood, krzk, sbkim73, m.szyprowski, b.zolnierkie, alsa-devel,
	linux-kernel, linux-samsung-soc

On 2/12/19 17:40, Mark Brown wrote:
> On Thu, Feb 07, 2019 at 06:00:08PM +0100, Sylwester Nawrocki wrote:
> 
>> I am not entirely sure we should be removing the
>> SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag like this, it might all
>> be a bit more explicit with the flag.
> 
> I'm fairly happy with what you're doing here and the Samsung driver is
> the only user so the view of people working on that is pretty important
> here.  I've gone ahead and applied the first few patches so they don't
> need rereviewing, the rest looked fine modulo the comments from
> Krzysztof.
 
Thank you, I've just resent the whole series with Krzysztof's comments 
addressed and with few more clean up patches added.

I've found one minor problem with the Odroid machine driver patch - 
limiting sampling rate to same value on both PCMs doesn't work properly.
I've got a patch fixing that almost ready and will post it tomorrow as
a folow up or v3 of "ASoC: samsung: odroid: Add support for secondary 
CPU DAI".

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, back to index

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20190207170044epcas2p3d00762663b971845bc86db84af7d3b23@epcas2p3.samsung.com>
2019-02-07 17:00 ` [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards Sylwester Nawrocki
     [not found]   ` <CGME20190207170047epcas1p42d7ec4acfd976871c676efa5aecb33bc@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 01/22] ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of() Sylwester Nawrocki
2019-02-11 13:29       ` Krzysztof Kozlowski
2019-02-12 16:58       ` Applied "ASoC: dmaengine: Improve of_node test in dmaengine_pcm_request_chan_of()" to the asoc tree Mark Brown
     [not found]   ` <CGME20190207170051epcas1p37a1acaef52cffb01af00c8d34dd9b1dd@epcas1p3.samsung.com>
2019-02-07 17:00     ` [PATCH 02/22] ASoC: dmaengine: Extend use of chan_names provided in custom DMA config Sylwester Nawrocki
2019-02-11 13:31       ` Krzysztof Kozlowski
2019-02-12 16:58       ` Applied "ASoC: dmaengine: Extend use of chan_names provided in custom DMA config" to the asoc tree Mark Brown
     [not found]   ` <CGME20190207170054epcas1p1e61320d308bc5be30187919f3360f501@epcas1p1.samsung.com>
2019-02-07 17:00     ` [PATCH 03/22] ASoC: samsung: dmaengine: Allow to specify custom DMA device Sylwester Nawrocki
2019-02-11 13:31       ` Krzysztof Kozlowski
2019-02-12 16:58       ` Applied "ASoC: samsung: dmaengine: Allow to specify custom DMA device" to the asoc tree Mark Brown
     [not found]   ` <CGME20190207170058epcas1p4e2fadf4aae2ece3c47c0750a094a4fbb@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 04/22] ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI Sylwester Nawrocki
2019-02-11 13:37       ` Krzysztof Kozlowski
2019-02-11 14:32         ` Sylwester Nawrocki
2019-02-11 15:03           ` Krzysztof Kozlowski
2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Fix prescaler setting for the secondary DAI" to the asoc tree Mark Brown
     [not found]   ` <CGME20190207170102epcas1p445f2a5d8e70bc3a6e42424034c2eb34a@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 05/22] ASoC: samsung: i2s: Convert to single component with multiple DAIs Sylwester Nawrocki
2019-02-11 13:38       ` Krzysztof Kozlowski
2019-02-12 16:58       ` Applied "ASoC: samsung: i2s: Convert to single component with multiple DAIs" to the asoc tree Mark Brown
     [not found]   ` <CGME20190207170105epcas1p3d4a1da9ae268f8e95b32fb499e5a1dad@epcas1p3.samsung.com>
2019-02-07 17:00     ` [PATCH 06/22] ASoC: samsung: i2s: Restore support for the secondary PCM Sylwester Nawrocki
2019-02-11 13:41       ` Krzysztof Kozlowski
2019-02-11 14:50         ` Sylwester Nawrocki
     [not found]   ` <CGME20190207170109epcas1p20929934c01ae67a05cd6a56f13ed8486@epcas1p2.samsung.com>
2019-02-07 17:00     ` [PATCH 07/22] ASoC: samsung: i2s: Move clk supplier data to common driver data structure Sylwester Nawrocki
2019-02-11 13:41       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170112epcas1p31ed740ef43d8a3eb71ca7245fba1bc3d@epcas1p3.samsung.com>
2019-02-07 17:00     ` [PATCH 08/22] ASoC: samsung: i2s: Add widgets and routes for DPCM support Sylwester Nawrocki
2019-02-11 13:42       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170116epcas2p1e0768a74062c8af83842ddb59309850f@epcas2p1.samsung.com>
2019-02-07 17:00     ` [PATCH 09/22] ASoC: samsung: i2s: Move core clk to the driver common data structure Sylwester Nawrocki
2019-02-11 13:44       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170120epcas1p211e1582a6124d6b7d0e33db6c0017480@epcas1p2.samsung.com>
2019-02-07 17:00     ` [PATCH 10/22] ASoC: samsung: i2s: Move opclk data to common driver " Sylwester Nawrocki
2019-02-11 13:44       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170123epcas1p2fae464ba7f102d841548c5a523cc6660@epcas1p2.samsung.com>
2019-02-07 17:00     ` [PATCH 11/22] ASoC: samsung: i2s: Move registers cache " Sylwester Nawrocki
2019-02-11 13:45       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170127epcas2p31da340c3f63e75e7bcb5c9c864a42173@epcas2p3.samsung.com>
2019-02-07 17:00     ` [PATCH 12/22] ASoC: samsung: i2s: Move SFR pointer " Sylwester Nawrocki
2019-02-11 13:46       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170130epcas1p4809b7a8dc797ced2982dc3b305a0991b@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 13/22] ASoC: samsung: i2s: Drop spinlock pointer from i2s_dai " Sylwester Nawrocki
2019-02-11 13:47       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170134epcas2p1a22a5c2f680f33fe562fa22f3aec9e6a@epcas2p1.samsung.com>
2019-02-07 17:00     ` [PATCH 14/22] ASoC: samsung: i2s: Move IP variant data to common driver " Sylwester Nawrocki
2019-02-11 13:48       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170138epcas2p31134b2beee877922d27fab5c79fdc7b1@epcas2p3.samsung.com>
2019-02-07 17:00     ` [PATCH 15/22] ASoC: samsung: i2s: Move quirks " Sylwester Nawrocki
2019-02-11 13:49       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170141epcas1p29a038bfd0df69df10e916ea8a695a85b@epcas1p2.samsung.com>
2019-02-07 17:00     ` [PATCH 16/22] ASoC: samsung: i2s: Get rid of a static spinlock Sylwester Nawrocki
2019-02-11 13:51       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170145epcas1p465da0715aa629b525c17d263c1b49a68@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 17/22] ASoC: samsung: odroid: Add support for secondary CPU DAI Sylwester Nawrocki
2019-02-11 13:57       ` Krzysztof Kozlowski
2019-02-11 15:19         ` Sylwester Nawrocki
2019-02-11 15:34           ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170148epcas2p2e0f4a1e154cb8cd52d257978a669e84c@epcas2p2.samsung.com>
2019-02-07 17:00     ` [PATCH 18/22] ASoC: samsung: Specify DMA channel names through custom DMA config Sylwester Nawrocki
2019-02-11 13:58       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170152epcas1p254264a82287a54dc2452f5e73daab13d@epcas1p2.samsung.com>
2019-02-07 17:00     ` [PATCH 19/22] ASoC: samsung: Drop DAI DMA data chan_name assignments Sylwester Nawrocki
2019-02-11 14:03       ` Krzysztof Kozlowski
     [not found]   ` <CGME20190207170155epcas1p42ba30c540d35290c010b5bfa4645e3b1@epcas1p4.samsung.com>
2019-02-07 17:00     ` [PATCH 20/22] ASoC: dmaengine: Remove unused SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME flag Sylwester Nawrocki
2019-02-11 14:04       ` Krzysztof Kozlowski
2019-02-12 16:40   ` [PATCH 00/22] ASoC: dmaengine updates, secondary CPU DAI for Odroid boards Mark Brown
2019-02-12 18:17     ` Sylwester Nawrocki

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org linux-kernel@archiver.kernel.org
	public-inbox-index lkml


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox