All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s
@ 2022-07-06 21:13 ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

This series is a preparatory cleanup of the jz4740-i2s driver before
adding support for a new SoC. The last two patches lift unnecessary
restrictions on sample rates and formats -- the existing ones appear
to be derived from the limitations of the JZ4740's internal codec and
don't reflect the actual capabilities of the I2S controller.

I'm unable to test the series on any JZ47xx SoCs, but I have tested
on an X1000 (which is the SoC I'll be adding in a followup series).

Aidan MacDonald (11):
  ASoC: jz4740-i2s: Remove Open Firmware dependency
  ASoC: jz4740-i2s: Refactor DMA channel setup
  ASoC: jz4740-i2s: Convert to regmap API
  ASoC: jz4740-i2s: Simplify using regmap fields
  ASoC: jz4740-i2s: Remove unused SoC version IDs
  ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
  ASoC: jz4740-i2s: Remove some unused macros
  ASoC: jz4740-i2s: Align macro values and sort includes
  ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
  ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
  ASoC: jz4740-i2s: Support continuous sample rate

 sound/soc/jz4740/Kconfig      |   3 +-
 sound/soc/jz4740/jz4740-i2s.c | 351 +++++++++++++++++-----------------
 2 files changed, 177 insertions(+), 177 deletions(-)

-- 
2.35.1


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

* [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s
@ 2022-07-06 21:13 ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

This series is a preparatory cleanup of the jz4740-i2s driver before
adding support for a new SoC. The last two patches lift unnecessary
restrictions on sample rates and formats -- the existing ones appear
to be derived from the limitations of the JZ4740's internal codec and
don't reflect the actual capabilities of the I2S controller.

I'm unable to test the series on any JZ47xx SoCs, but I have tested
on an X1000 (which is the SoC I'll be adding in a followup series).

Aidan MacDonald (11):
  ASoC: jz4740-i2s: Remove Open Firmware dependency
  ASoC: jz4740-i2s: Refactor DMA channel setup
  ASoC: jz4740-i2s: Convert to regmap API
  ASoC: jz4740-i2s: Simplify using regmap fields
  ASoC: jz4740-i2s: Remove unused SoC version IDs
  ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
  ASoC: jz4740-i2s: Remove some unused macros
  ASoC: jz4740-i2s: Align macro values and sort includes
  ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
  ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
  ASoC: jz4740-i2s: Support continuous sample rate

 sound/soc/jz4740/Kconfig      |   3 +-
 sound/soc/jz4740/jz4740-i2s.c | 351 +++++++++++++++++-----------------
 2 files changed, 177 insertions(+), 177 deletions(-)

-- 
2.35.1


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

* [PATCH 01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

This driver doesn't require Open Firmware support. Remove the
OF-specific includes and drop the Kconfig dependency.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/Kconfig      | 2 +-
 sound/soc/jz4740/jz4740-i2s.c | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
index 29144720cb62..e72f826062e9 100644
--- a/sound/soc/jz4740/Kconfig
+++ b/sound/soc/jz4740/Kconfig
@@ -2,7 +2,7 @@
 config SND_JZ4740_SOC_I2S
 	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
 	depends on MIPS || COMPILE_TEST
-	depends on OF && HAS_IOMEM
+	depends on HAS_IOMEM
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	help
 	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 79afac0c5003..298ff0a83931 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -5,10 +5,9 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-- 
2.35.1


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

* [PATCH 01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

This driver doesn't require Open Firmware support. Remove the
OF-specific includes and drop the Kconfig dependency.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/Kconfig      | 2 +-
 sound/soc/jz4740/jz4740-i2s.c | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
index 29144720cb62..e72f826062e9 100644
--- a/sound/soc/jz4740/Kconfig
+++ b/sound/soc/jz4740/Kconfig
@@ -2,7 +2,7 @@
 config SND_JZ4740_SOC_I2S
 	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
 	depends on MIPS || COMPILE_TEST
-	depends on OF && HAS_IOMEM
+	depends on HAS_IOMEM
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	help
 	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 79afac0c5003..298ff0a83931 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -5,10 +5,9 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-- 
2.35.1


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

* [PATCH 02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

It's simpler to set up the playback and capture DMA settings
at driver probe time instead of during DAI probing.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 298ff0a83931..ecd8df70d39c 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -95,7 +95,6 @@ struct i2s_soc_info {
 struct jz4740_i2s {
 	struct resource *mem;
 	void __iomem *base;
-	dma_addr_t phys_base;
 
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
@@ -370,21 +369,6 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 	return 0;
 }
 
-static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s)
-{
-	struct snd_dmaengine_dai_dma_data *dma_data;
-
-	/* Playback */
-	dma_data = &i2s->playback_dma_data;
-	dma_data->maxburst = 16;
-	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-
-	/* Capture */
-	dma_data = &i2s->capture_dma_data;
-	dma_data->maxburst = 16;
-	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-}
-
 static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
@@ -395,7 +379,6 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 	if (ret)
 		return ret;
 
-	jz4740_i2s_init_pcm_config(i2s);
 	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
 		&i2s->capture_dma_data);
 
@@ -529,7 +512,11 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->base))
 		return PTR_ERR(i2s->base);
 
-	i2s->phys_base = mem->start;
+	i2s->playback_dma_data.maxburst = 16;
+	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
+
+	i2s->capture_dma_data.maxburst = 16;
+	i2s->capture_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
 
 	i2s->clk_aic = devm_clk_get(dev, "aic");
 	if (IS_ERR(i2s->clk_aic))
-- 
2.35.1


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

* [PATCH 02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

It's simpler to set up the playback and capture DMA settings
at driver probe time instead of during DAI probing.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 298ff0a83931..ecd8df70d39c 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -95,7 +95,6 @@ struct i2s_soc_info {
 struct jz4740_i2s {
 	struct resource *mem;
 	void __iomem *base;
-	dma_addr_t phys_base;
 
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
@@ -370,21 +369,6 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 	return 0;
 }
 
-static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s)
-{
-	struct snd_dmaengine_dai_dma_data *dma_data;
-
-	/* Playback */
-	dma_data = &i2s->playback_dma_data;
-	dma_data->maxburst = 16;
-	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-
-	/* Capture */
-	dma_data = &i2s->capture_dma_data;
-	dma_data->maxburst = 16;
-	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-}
-
 static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
@@ -395,7 +379,6 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 	if (ret)
 		return ret;
 
-	jz4740_i2s_init_pcm_config(i2s);
 	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
 		&i2s->capture_dma_data);
 
@@ -529,7 +512,11 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->base))
 		return PTR_ERR(i2s->base);
 
-	i2s->phys_base = mem->start;
+	i2s->playback_dma_data.maxburst = 16;
+	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
+
+	i2s->capture_dma_data.maxburst = 16;
+	i2s->capture_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
 
 	i2s->clk_aic = devm_clk_get(dev, "aic");
 	if (IS_ERR(i2s->clk_aic))
-- 
2.35.1


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

* [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

Using regmap for accessing the AIC registers makes the driver a
little easier to read, and later refactors can take advantage of
regmap APIs to further simplify the driver.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/Kconfig      |  1 +
 sound/soc/jz4740/jz4740-i2s.c | 99 +++++++++++++++--------------------
 2 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
index e72f826062e9..dd3b4507fbe6 100644
--- a/sound/soc/jz4740/Kconfig
+++ b/sound/soc/jz4740/Kconfig
@@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
 	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
 	depends on MIPS || COMPILE_TEST
 	depends on HAS_IOMEM
+	select REGMAP_MMIO
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	help
 	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index ecd8df70d39c..66a901f56392 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
 #include <linux/clk.h>
@@ -94,7 +95,7 @@ struct i2s_soc_info {
 
 struct jz4740_i2s {
 	struct resource *mem;
-	void __iomem *base;
+	struct regmap *regmap;
 
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
@@ -105,39 +106,24 @@ struct jz4740_i2s {
 	const struct i2s_soc_info *soc_info;
 };
 
-static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
-	unsigned int reg)
-{
-	return readl(i2s->base + reg);
-}
-
-static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
-	unsigned int reg, uint32_t value)
-{
-	writel(value, i2s->base + reg);
-}
-
 static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf, ctrl;
 	int ret;
 
 	if (snd_soc_dai_active(dai))
 		return 0;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-	ctrl |= JZ_AIC_CTRL_FLUSH;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
+	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
+			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);
 
 	ret = clk_prepare_enable(i2s->clk_i2s);
 	if (ret)
 		return ret;
 
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-	conf |= JZ_AIC_CONF_ENABLE;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
 
 	return 0;
 }
@@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf;
 
 	if (snd_soc_dai_active(dai))
 		return;
 
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-	conf &= ~JZ_AIC_CONF_ENABLE;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+			   JZ_AIC_CONF_ENABLE, 0);
 
 	clk_disable_unprepare(i2s->clk_i2s);
 }
@@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
-	uint32_t ctrl;
 	uint32_t mask;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 	else
 		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		ctrl |= mask;
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		ctrl &= ~mask;
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-
 	return 0;
 }
 
 static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
-	uint32_t format = 0;
-	uint32_t conf;
-
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-
-	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
+	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
+				       JZ_AIC_CONF_SYNC_CLK_MASTER;
+	unsigned int conf = 0, format = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 	case SND_SOC_DAIFMT_BP_FP:
@@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
+	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
 
 	return 0;
 }
@@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	uint32_t ctrl, div_reg;
 	int div;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
+	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
+	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
 
-	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
 	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
 
 	switch (params_format(params)) {
@@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
 
 	return 0;
 }
@@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int jz4740_i2s_suspend(struct snd_soc_component *component)
 {
 	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
-	uint32_t conf;
 
 	if (snd_soc_component_active(component)) {
-		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-		conf &= ~JZ_AIC_CONF_ENABLE;
-		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+				   JZ_AIC_CONF_ENABLE, 0);
 
 		clk_disable_unprepare(i2s->clk_i2s);
 	}
@@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct snd_soc_component *component)
 static int jz4740_i2s_resume(struct snd_soc_component *component)
 {
 	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
-	uint32_t conf;
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk_aic);
@@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 			return ret;
 		}
 
-		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-		conf |= JZ_AIC_CONF_ENABLE;
-		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
 	}
 
 	return 0;
@@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 			JZ_AIC_CONF_INTERNAL_CODEC;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
 
 	return 0;
 }
@@ -495,11 +465,19 @@ static const struct of_device_id jz4740_of_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, jz4740_of_matches);
 
+static const struct regmap_config jz4740_i2s_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= JZ_REG_AIC_FIFO,
+};
+
 static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct jz4740_i2s *i2s;
 	struct resource *mem;
+	void __iomem *regs;
 	int ret;
 
 	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
@@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 
 	i2s->soc_info = device_get_match_data(dev);
 
-	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
-	if (IS_ERR(i2s->base))
-		return PTR_ERR(i2s->base);
+	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
 
 	i2s->playback_dma_data.maxburst = 16;
 	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
@@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->clk_i2s))
 		return PTR_ERR(i2s->clk_i2s);
 
+	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &jz4740_i2s_regmap_config);
+	if (IS_ERR(i2s->regmap))
+		return PTR_ERR(i2s->regmap);
+
 	platform_set_drvdata(pdev, i2s);
 
 	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
-- 
2.35.1


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

* [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

Using regmap for accessing the AIC registers makes the driver a
little easier to read, and later refactors can take advantage of
regmap APIs to further simplify the driver.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/Kconfig      |  1 +
 sound/soc/jz4740/jz4740-i2s.c | 99 +++++++++++++++--------------------
 2 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
index e72f826062e9..dd3b4507fbe6 100644
--- a/sound/soc/jz4740/Kconfig
+++ b/sound/soc/jz4740/Kconfig
@@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
 	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
 	depends on MIPS || COMPILE_TEST
 	depends on HAS_IOMEM
+	select REGMAP_MMIO
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	help
 	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index ecd8df70d39c..66a901f56392 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
 #include <linux/clk.h>
@@ -94,7 +95,7 @@ struct i2s_soc_info {
 
 struct jz4740_i2s {
 	struct resource *mem;
-	void __iomem *base;
+	struct regmap *regmap;
 
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
@@ -105,39 +106,24 @@ struct jz4740_i2s {
 	const struct i2s_soc_info *soc_info;
 };
 
-static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
-	unsigned int reg)
-{
-	return readl(i2s->base + reg);
-}
-
-static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
-	unsigned int reg, uint32_t value)
-{
-	writel(value, i2s->base + reg);
-}
-
 static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf, ctrl;
 	int ret;
 
 	if (snd_soc_dai_active(dai))
 		return 0;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-	ctrl |= JZ_AIC_CTRL_FLUSH;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
+	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
+			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);
 
 	ret = clk_prepare_enable(i2s->clk_i2s);
 	if (ret)
 		return ret;
 
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-	conf |= JZ_AIC_CONF_ENABLE;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
 
 	return 0;
 }
@@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf;
 
 	if (snd_soc_dai_active(dai))
 		return;
 
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-	conf &= ~JZ_AIC_CONF_ENABLE;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+			   JZ_AIC_CONF_ENABLE, 0);
 
 	clk_disable_unprepare(i2s->clk_i2s);
 }
@@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
-	uint32_t ctrl;
 	uint32_t mask;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 	else
 		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		ctrl |= mask;
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		ctrl &= ~mask;
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-
 	return 0;
 }
 
 static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
-	uint32_t format = 0;
-	uint32_t conf;
-
-	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-
-	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
+	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
+				       JZ_AIC_CONF_SYNC_CLK_MASTER;
+	unsigned int conf = 0, format = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 	case SND_SOC_DAIFMT_BP_FP:
@@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
+	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
+	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
 
 	return 0;
 }
@@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	uint32_t ctrl, div_reg;
 	int div;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
+	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
+	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
 
-	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
 	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
 
 	switch (params_format(params)) {
@@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
 
 	return 0;
 }
@@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int jz4740_i2s_suspend(struct snd_soc_component *component)
 {
 	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
-	uint32_t conf;
 
 	if (snd_soc_component_active(component)) {
-		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-		conf &= ~JZ_AIC_CONF_ENABLE;
-		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+				   JZ_AIC_CONF_ENABLE, 0);
 
 		clk_disable_unprepare(i2s->clk_i2s);
 	}
@@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct snd_soc_component *component)
 static int jz4740_i2s_resume(struct snd_soc_component *component)
 {
 	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
-	uint32_t conf;
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk_aic);
@@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 			return ret;
 		}
 
-		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-		conf |= JZ_AIC_CONF_ENABLE;
-		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
+				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
 	}
 
 	return 0;
@@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 			JZ_AIC_CONF_INTERNAL_CODEC;
 	}
 
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
 
 	return 0;
 }
@@ -495,11 +465,19 @@ static const struct of_device_id jz4740_of_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, jz4740_of_matches);
 
+static const struct regmap_config jz4740_i2s_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= JZ_REG_AIC_FIFO,
+};
+
 static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct jz4740_i2s *i2s;
 	struct resource *mem;
+	void __iomem *regs;
 	int ret;
 
 	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
@@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 
 	i2s->soc_info = device_get_match_data(dev);
 
-	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
-	if (IS_ERR(i2s->base))
-		return PTR_ERR(i2s->base);
+	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
 
 	i2s->playback_dma_data.maxburst = 16;
 	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
@@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->clk_i2s))
 		return PTR_ERR(i2s->clk_i2s);
 
+	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &jz4740_i2s_regmap_config);
+	if (IS_ERR(i2s->regmap))
+		return PTR_ERR(i2s->regmap);
+
 	platform_set_drvdata(pdev, i2s);
 
 	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
-- 
2.35.1


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

* [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

The differences between register fields on different SoC versions
can be abstracted away using the regmap field API. This is easier
to understand and extend than comparisons based on the version ID.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 100 ++++++++++++++++++++++++----------
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 66a901f56392..cbb89f724f64 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
 struct i2s_soc_info {
 	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
+
+	struct reg_field field_rx_fifo_thresh;
+	struct reg_field field_tx_fifo_thresh;
+	struct reg_field field_i2sdiv_capture;
+	struct reg_field field_i2sdiv_playback;
 };
 
 struct jz4740_i2s {
 	struct resource *mem;
 	struct regmap *regmap;
 
+	struct regmap_field *field_rx_fifo_thresh;
+	struct regmap_field *field_tx_fifo_thresh;
+	struct regmap_field *field_i2sdiv_capture;
+	struct regmap_field *field_i2sdiv_playback;
+
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
 
@@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+	struct regmap_field *div_field;
 	unsigned int sample_size;
-	uint32_t ctrl, div_reg;
+	uint32_t ctrl;
 	int div;
 
 	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
-	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
 
 	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
 
@@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 		else
 			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
 
-		div_reg &= ~I2SDIV_DV_MASK;
-		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
+		div_field = i2s->field_i2sdiv_playback;
 	} else {
 		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
 		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
 
-		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
-			div_reg &= ~I2SDIV_IDV_MASK;
-			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
-		} else {
-			div_reg &= ~I2SDIV_DV_MASK;
-			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
-		}
+		div_field = i2s->field_i2sdiv_capture;
 	}
 
 	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
-	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
+	regmap_field_write(div_field, div - 1);
 
 	return 0;
 }
@@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf;
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk_aic);
@@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
 		&i2s->capture_dma_data);
 
-	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
-		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
-			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
-			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
-			JZ_AIC_CONF_I2S |
-			JZ_AIC_CONF_INTERNAL_CODEC;
-	} else {
-		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
-			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
-			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
-			JZ_AIC_CONF_I2S |
-			JZ_AIC_CONF_INTERNAL_CODEC;
-	}
-
 	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
-	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
+
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
+		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
+		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
+
+	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
+	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
 
 	return 0;
 }
@@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
 	.version = JZ_I2S_JZ4760,
 	.dai = &jz4740_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static struct snd_soc_dai_driver jz4770_i2s_dai = {
@@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 static const struct i2s_soc_info jz4770_i2s_soc_info = {
 	.version = JZ_I2S_JZ4770,
 	.dai = &jz4770_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
 	.version = JZ_I2S_JZ4780,
 	.dai = &jz4770_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct snd_soc_component_driver jz4740_i2s_component = {
@@ -465,6 +475,36 @@ static const struct of_device_id jz4740_of_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, jz4740_of_matches);
 
+static int jz4740_i2s_init_regmap_fields(struct device *dev,
+					 struct jz4740_i2s *i2s)
+{
+	i2s->field_rx_fifo_thresh =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_rx_fifo_thresh);
+	if (IS_ERR(i2s->field_rx_fifo_thresh))
+		return PTR_ERR(i2s->field_rx_fifo_thresh);
+
+	i2s->field_tx_fifo_thresh =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_tx_fifo_thresh);
+	if (IS_ERR(i2s->field_tx_fifo_thresh))
+		return PTR_ERR(i2s->field_tx_fifo_thresh);
+
+	i2s->field_i2sdiv_capture =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_i2sdiv_capture);
+	if (IS_ERR(i2s->field_i2sdiv_capture))
+		return PTR_ERR(i2s->field_i2sdiv_capture);
+
+	i2s->field_i2sdiv_playback =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_i2sdiv_playback);
+	if (IS_ERR(i2s->field_i2sdiv_playback))
+		return PTR_ERR(i2s->field_i2sdiv_playback);
+
+	return 0;
+}
+
 static const struct regmap_config jz4740_i2s_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->regmap))
 		return PTR_ERR(i2s->regmap);
 
+	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, i2s);
 
 	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
-- 
2.35.1


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

* [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

The differences between register fields on different SoC versions
can be abstracted away using the regmap field API. This is easier
to understand and extend than comparisons based on the version ID.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 100 ++++++++++++++++++++++++----------
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 66a901f56392..cbb89f724f64 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
 struct i2s_soc_info {
 	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
+
+	struct reg_field field_rx_fifo_thresh;
+	struct reg_field field_tx_fifo_thresh;
+	struct reg_field field_i2sdiv_capture;
+	struct reg_field field_i2sdiv_playback;
 };
 
 struct jz4740_i2s {
 	struct resource *mem;
 	struct regmap *regmap;
 
+	struct regmap_field *field_rx_fifo_thresh;
+	struct regmap_field *field_tx_fifo_thresh;
+	struct regmap_field *field_i2sdiv_capture;
+	struct regmap_field *field_i2sdiv_playback;
+
 	struct clk *clk_aic;
 	struct clk *clk_i2s;
 
@@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+	struct regmap_field *div_field;
 	unsigned int sample_size;
-	uint32_t ctrl, div_reg;
+	uint32_t ctrl;
 	int div;
 
 	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
-	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
 
 	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
 
@@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 		else
 			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
 
-		div_reg &= ~I2SDIV_DV_MASK;
-		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
+		div_field = i2s->field_i2sdiv_playback;
 	} else {
 		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
 		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
 
-		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
-			div_reg &= ~I2SDIV_IDV_MASK;
-			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
-		} else {
-			div_reg &= ~I2SDIV_DV_MASK;
-			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
-		}
+		div_field = i2s->field_i2sdiv_capture;
 	}
 
 	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
-	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
+	regmap_field_write(div_field, div - 1);
 
 	return 0;
 }
@@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
 static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf;
 	int ret;
 
 	ret = clk_prepare_enable(i2s->clk_aic);
@@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
 	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
 		&i2s->capture_dma_data);
 
-	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
-		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
-			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
-			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
-			JZ_AIC_CONF_I2S |
-			JZ_AIC_CONF_INTERNAL_CODEC;
-	} else {
-		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
-			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
-			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
-			JZ_AIC_CONF_I2S |
-			JZ_AIC_CONF_INTERNAL_CODEC;
-	}
-
 	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
-	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
+
+	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
+		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
+		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
+
+	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
+	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
 
 	return 0;
 }
@@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
 	.version = JZ_I2S_JZ4760,
 	.dai = &jz4740_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static struct snd_soc_dai_driver jz4770_i2s_dai = {
@@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 static const struct i2s_soc_info jz4770_i2s_soc_info = {
 	.version = JZ_I2S_JZ4770,
 	.dai = &jz4770_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
 	.version = JZ_I2S_JZ4780,
 	.dai = &jz4770_i2s_dai,
+	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
+	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
+	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
+	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 };
 
 static const struct snd_soc_component_driver jz4740_i2s_component = {
@@ -465,6 +475,36 @@ static const struct of_device_id jz4740_of_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, jz4740_of_matches);
 
+static int jz4740_i2s_init_regmap_fields(struct device *dev,
+					 struct jz4740_i2s *i2s)
+{
+	i2s->field_rx_fifo_thresh =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_rx_fifo_thresh);
+	if (IS_ERR(i2s->field_rx_fifo_thresh))
+		return PTR_ERR(i2s->field_rx_fifo_thresh);
+
+	i2s->field_tx_fifo_thresh =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_tx_fifo_thresh);
+	if (IS_ERR(i2s->field_tx_fifo_thresh))
+		return PTR_ERR(i2s->field_tx_fifo_thresh);
+
+	i2s->field_i2sdiv_capture =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_i2sdiv_capture);
+	if (IS_ERR(i2s->field_i2sdiv_capture))
+		return PTR_ERR(i2s->field_i2sdiv_capture);
+
+	i2s->field_i2sdiv_playback =
+		devm_regmap_field_alloc(dev, i2s->regmap,
+					i2s->soc_info->field_i2sdiv_playback);
+	if (IS_ERR(i2s->field_i2sdiv_playback))
+		return PTR_ERR(i2s->field_i2sdiv_playback);
+
+	return 0;
+}
+
 static const struct regmap_config jz4740_i2s_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s->regmap))
 		return PTR_ERR(i2s->regmap);
 
+	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, i2s);
 
 	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
-- 
2.35.1


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

* [PATCH 05/11] ASoC: jz4740-i2s: Remove unused SoC version IDs
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

Using version IDs makes the code hard to follow -- it's better to
describe the functional differences between SoCs instead. Remove
the IDs since they're no longer used.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index cbb89f724f64..8bb9449d13d3 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -81,15 +81,7 @@
 #define I2SDIV_IDV_SHIFT 8
 #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
 
-enum jz47xx_i2s_version {
-	JZ_I2S_JZ4740,
-	JZ_I2S_JZ4760,
-	JZ_I2S_JZ4770,
-	JZ_I2S_JZ4780,
-};
-
 struct i2s_soc_info {
-	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
 
 	struct reg_field field_rx_fifo_thresh;
@@ -406,7 +398,6 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 };
 
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
-	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
@@ -415,7 +406,6 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
-	.version = JZ_I2S_JZ4760,
 	.dai = &jz4740_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
@@ -442,7 +432,6 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 };
 
 static const struct i2s_soc_info jz4770_i2s_soc_info = {
-	.version = JZ_I2S_JZ4770,
 	.dai = &jz4770_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
@@ -451,7 +440,6 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
-	.version = JZ_I2S_JZ4780,
 	.dai = &jz4770_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
-- 
2.35.1


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

* [PATCH 05/11] ASoC: jz4740-i2s: Remove unused SoC version IDs
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

Using version IDs makes the code hard to follow -- it's better to
describe the functional differences between SoCs instead. Remove
the IDs since they're no longer used.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index cbb89f724f64..8bb9449d13d3 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -81,15 +81,7 @@
 #define I2SDIV_IDV_SHIFT 8
 #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
 
-enum jz47xx_i2s_version {
-	JZ_I2S_JZ4740,
-	JZ_I2S_JZ4760,
-	JZ_I2S_JZ4770,
-	JZ_I2S_JZ4780,
-};
-
 struct i2s_soc_info {
-	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
 
 	struct reg_field field_rx_fifo_thresh;
@@ -406,7 +398,6 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 };
 
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
-	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
@@ -415,7 +406,6 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
-	.version = JZ_I2S_JZ4760,
 	.dai = &jz4740_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
@@ -442,7 +432,6 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 };
 
 static const struct i2s_soc_info jz4770_i2s_soc_info = {
-	.version = JZ_I2S_JZ4770,
 	.dai = &jz4770_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
@@ -451,7 +440,6 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
-	.version = JZ_I2S_JZ4780,
 	.dai = &jz4770_i2s_dai,
 	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
-- 
2.35.1


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

* [PATCH 06/11] ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

Get rid of a couple of macros and improve readability by using
FIELD_PREP() and GENMASK() for the sample size setting.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 8bb9449d13d3..3c3cf78bf848 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -3,6 +3,7 @@
  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
  */
 
+#include <linux/bitfield.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -49,8 +50,8 @@
 #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
 #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
 
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
+#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
+#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
 #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
 #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
 #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
@@ -65,9 +66,6 @@
 #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
 #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
 
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET  16
-
 #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
 #define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
 #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
@@ -245,8 +243,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
-		ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
+		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE;
+		ctrl |= FIELD_PREP(JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE, sample_size);
+
 		if (params_channels(params) == 1)
 			ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
 		else
@@ -254,8 +253,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 
 		div_field = i2s->field_i2sdiv_playback;
 	} else {
-		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
-		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
+		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE;
+		ctrl |= FIELD_PREP(JZ_AIC_CTRL_INPUT_SAMPLE_SIZE, sample_size);
 
 		div_field = i2s->field_i2sdiv_capture;
 	}
-- 
2.35.1


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

* [PATCH 06/11] ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

Get rid of a couple of macros and improve readability by using
FIELD_PREP() and GENMASK() for the sample size setting.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 8bb9449d13d3..3c3cf78bf848 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -3,6 +3,7 @@
  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
  */
 
+#include <linux/bitfield.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -49,8 +50,8 @@
 #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
 #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
 
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
+#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
+#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
 #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
 #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
 #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
@@ -65,9 +66,6 @@
 #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
 #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
 
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET  16
-
 #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
 #define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
 #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
@@ -245,8 +243,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
-		ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
+		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE;
+		ctrl |= FIELD_PREP(JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE, sample_size);
+
 		if (params_channels(params) == 1)
 			ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
 		else
@@ -254,8 +253,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 
 		div_field = i2s->field_i2sdiv_playback;
 	} else {
-		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
-		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
+		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE;
+		ctrl |= FIELD_PREP(JZ_AIC_CTRL_INPUT_SAMPLE_SIZE, sample_size);
 
 		div_field = i2s->field_i2sdiv_capture;
 	}
-- 
2.35.1


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

* [PATCH 07/11] ASoC: jz4740-i2s: Remove some unused macros
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

These macros are unused and can be dropped; the information is now
encoded in regmap fields.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 3c3cf78bf848..b8d2723c5f90 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -35,8 +35,6 @@
 #define JZ_REG_AIC_CLK_DIV	0x30
 #define JZ_REG_AIC_FIFO		0x34
 
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf <<  8)
 #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
 #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
 #define JZ_AIC_CONF_I2S BIT(4)
@@ -45,11 +43,6 @@
 #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
 #define JZ_AIC_CONF_ENABLE BIT(0)
 
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
-#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
-#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
-
 #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
 #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
 #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
@@ -73,12 +66,6 @@
 
 #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
 
-#define JZ_AIC_CLK_DIV_MASK 0xf
-#define I2SDIV_DV_SHIFT 0
-#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
-#define I2SDIV_IDV_SHIFT 8
-#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
-
 struct i2s_soc_info {
 	struct snd_soc_dai_driver *dai;
 
-- 
2.35.1


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

* [PATCH 07/11] ASoC: jz4740-i2s: Remove some unused macros
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

These macros are unused and can be dropped; the information is now
encoded in regmap fields.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 3c3cf78bf848..b8d2723c5f90 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -35,8 +35,6 @@
 #define JZ_REG_AIC_CLK_DIV	0x30
 #define JZ_REG_AIC_FIFO		0x34
 
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf <<  8)
 #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
 #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
 #define JZ_AIC_CONF_I2S BIT(4)
@@ -45,11 +43,6 @@
 #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
 #define JZ_AIC_CONF_ENABLE BIT(0)
 
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
-#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
-#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
-
 #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
 #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
 #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
@@ -73,12 +66,6 @@
 
 #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
 
-#define JZ_AIC_CLK_DIV_MASK 0xf
-#define I2SDIV_DV_SHIFT 0
-#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
-#define I2SDIV_IDV_SHIFT 8
-#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
-
 struct i2s_soc_info {
 	struct snd_soc_dai_driver *dai;
 
-- 
2.35.1


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

* [PATCH 08/11] ASoC: jz4740-i2s: Align macro values and sort includes
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

Some purely cosmetic changes: line up all the macro values to
make things easier to read and sort the includes alphabetically.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 66 +++++++++++++++++------------------
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index b8d2723c5f90..3a21ee9d34d1 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -4,6 +4,9 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -13,11 +16,6 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <linux/clk.h>
-#include <linux/delay.h>
-
-#include <linux/dma-mapping.h>
-
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -35,36 +33,36 @@
 #define JZ_REG_AIC_CLK_DIV	0x30
 #define JZ_REG_AIC_FIFO		0x34
 
-#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
-#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
-#define JZ_AIC_CONF_I2S BIT(4)
-#define JZ_AIC_CONF_RESET BIT(3)
-#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
-#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
-#define JZ_AIC_CONF_ENABLE BIT(0)
-
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
-#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
-#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
-#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
-#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
-#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
+#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST	BIT(6)
+#define JZ_AIC_CONF_INTERNAL_CODEC	BIT(5)
+#define JZ_AIC_CONF_I2S			BIT(4)
+#define JZ_AIC_CONF_RESET		BIT(3)
+#define JZ_AIC_CONF_BIT_CLK_MASTER	BIT(2)
+#define JZ_AIC_CONF_SYNC_CLK_MASTER	BIT(1)
+#define JZ_AIC_CONF_ENABLE		BIT(0)
+
+#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE	GENMASK(21, 19)
+#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE	GENMASK(18, 16)
+#define JZ_AIC_CTRL_ENABLE_RX_DMA	BIT(15)
+#define JZ_AIC_CTRL_ENABLE_TX_DMA	BIT(14)
+#define JZ_AIC_CTRL_MONO_TO_STEREO	BIT(11)
+#define JZ_AIC_CTRL_SWITCH_ENDIANNESS	BIT(10)
+#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED	BIT(9)
 #define JZ_AIC_CTRL_FLUSH		BIT(8)
-#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
-#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
-#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
-#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
-#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
-#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
-#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
-
-#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
-#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
-#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
-#define JZ_AIC_I2S_FMT_MSB BIT(0)
-
-#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
+#define JZ_AIC_CTRL_ENABLE_ROR_INT	BIT(6)
+#define JZ_AIC_CTRL_ENABLE_TUR_INT	BIT(5)
+#define JZ_AIC_CTRL_ENABLE_RFS_INT	BIT(4)
+#define JZ_AIC_CTRL_ENABLE_TFS_INT	BIT(3)
+#define JZ_AIC_CTRL_ENABLE_LOOPBACK	BIT(2)
+#define JZ_AIC_CTRL_ENABLE_PLAYBACK	BIT(1)
+#define JZ_AIC_CTRL_ENABLE_CAPTURE	BIT(0)
+
+#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK	BIT(12)
+#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK	BIT(13)
+#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK	BIT(4)
+#define JZ_AIC_I2S_FMT_MSB		BIT(0)
+
+#define JZ_AIC_I2S_STATUS_BUSY		BIT(2)
 
 struct i2s_soc_info {
 	struct snd_soc_dai_driver *dai;
-- 
2.35.1


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

* [PATCH 08/11] ASoC: jz4740-i2s: Align macro values and sort includes
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

Some purely cosmetic changes: line up all the macro values to
make things easier to read and sort the includes alphabetically.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 66 +++++++++++++++++------------------
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index b8d2723c5f90..3a21ee9d34d1 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -4,6 +4,9 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -13,11 +16,6 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <linux/clk.h>
-#include <linux/delay.h>
-
-#include <linux/dma-mapping.h>
-
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -35,36 +33,36 @@
 #define JZ_REG_AIC_CLK_DIV	0x30
 #define JZ_REG_AIC_FIFO		0x34
 
-#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
-#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
-#define JZ_AIC_CONF_I2S BIT(4)
-#define JZ_AIC_CONF_RESET BIT(3)
-#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
-#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
-#define JZ_AIC_CONF_ENABLE BIT(0)
-
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
-#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
-#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
-#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
-#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
-#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
+#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST	BIT(6)
+#define JZ_AIC_CONF_INTERNAL_CODEC	BIT(5)
+#define JZ_AIC_CONF_I2S			BIT(4)
+#define JZ_AIC_CONF_RESET		BIT(3)
+#define JZ_AIC_CONF_BIT_CLK_MASTER	BIT(2)
+#define JZ_AIC_CONF_SYNC_CLK_MASTER	BIT(1)
+#define JZ_AIC_CONF_ENABLE		BIT(0)
+
+#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE	GENMASK(21, 19)
+#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE	GENMASK(18, 16)
+#define JZ_AIC_CTRL_ENABLE_RX_DMA	BIT(15)
+#define JZ_AIC_CTRL_ENABLE_TX_DMA	BIT(14)
+#define JZ_AIC_CTRL_MONO_TO_STEREO	BIT(11)
+#define JZ_AIC_CTRL_SWITCH_ENDIANNESS	BIT(10)
+#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED	BIT(9)
 #define JZ_AIC_CTRL_FLUSH		BIT(8)
-#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
-#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
-#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
-#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
-#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
-#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
-#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
-
-#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
-#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
-#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
-#define JZ_AIC_I2S_FMT_MSB BIT(0)
-
-#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
+#define JZ_AIC_CTRL_ENABLE_ROR_INT	BIT(6)
+#define JZ_AIC_CTRL_ENABLE_TUR_INT	BIT(5)
+#define JZ_AIC_CTRL_ENABLE_RFS_INT	BIT(4)
+#define JZ_AIC_CTRL_ENABLE_TFS_INT	BIT(3)
+#define JZ_AIC_CTRL_ENABLE_LOOPBACK	BIT(2)
+#define JZ_AIC_CTRL_ENABLE_PLAYBACK	BIT(1)
+#define JZ_AIC_CTRL_ENABLE_CAPTURE	BIT(0)
+
+#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK	BIT(12)
+#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK	BIT(13)
+#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK	BIT(4)
+#define JZ_AIC_I2S_FMT_MSB		BIT(0)
+
+#define JZ_AIC_I2S_STATUS_BUSY		BIT(2)
 
 struct i2s_soc_info {
 	struct snd_soc_dai_driver *dai;
-- 
2.35.1


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

* [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

On some Ingenic SoCs, such as the X1000, there is a programmable
divider used to generate the I2S system clock from a PLL, rather
than a fixed PLL/2 clock. It doesn't make much sense to call the
clock "pll half" on those SoCs, so the clock name should really be
a SoC-dependent value.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 3a21ee9d34d1..80b355d715ce 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -71,6 +71,8 @@ struct i2s_soc_info {
 	struct reg_field field_tx_fifo_thresh;
 	struct reg_field field_i2sdiv_capture;
 	struct reg_field field_i2sdiv_playback;
+
+	const char *pll_clk_name;
 };
 
 struct jz4740_i2s {
@@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 		clk_set_parent(i2s->clk_i2s, parent);
 		break;
 	case JZ4740_I2S_CLKSRC_PLL:
-		parent = clk_get(NULL, "pll half");
+		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
 		if (IS_ERR(parent))
 			return PTR_ERR(parent);
 		clk_set_parent(i2s->clk_i2s, parent);
@@ -387,6 +389,7 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
@@ -395,6 +398,7 @@ static const struct i2s_soc_info jz4760_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static struct snd_soc_dai_driver jz4770_i2s_dai = {
@@ -421,6 +425,7 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
@@ -429,6 +434,7 @@ static const struct i2s_soc_info jz4780_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct snd_soc_component_driver jz4740_i2s_component = {
-- 
2.35.1


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

* [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

On some Ingenic SoCs, such as the X1000, there is a programmable
divider used to generate the I2S system clock from a PLL, rather
than a fixed PLL/2 clock. It doesn't make much sense to call the
clock "pll half" on those SoCs, so the clock name should really be
a SoC-dependent value.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 3a21ee9d34d1..80b355d715ce 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -71,6 +71,8 @@ struct i2s_soc_info {
 	struct reg_field field_tx_fifo_thresh;
 	struct reg_field field_i2sdiv_capture;
 	struct reg_field field_i2sdiv_playback;
+
+	const char *pll_clk_name;
 };
 
 struct jz4740_i2s {
@@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 		clk_set_parent(i2s->clk_i2s, parent);
 		break;
 	case JZ4740_I2S_CLKSRC_PLL:
-		parent = clk_get(NULL, "pll half");
+		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
 		if (IS_ERR(parent))
 			return PTR_ERR(parent);
 		clk_set_parent(i2s->clk_i2s, parent);
@@ -387,6 +389,7 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
@@ -395,6 +398,7 @@ static const struct i2s_soc_info jz4760_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static struct snd_soc_dai_driver jz4770_i2s_dai = {
@@ -421,6 +425,7 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct i2s_soc_info jz4780_i2s_soc_info = {
@@ -429,6 +434,7 @@ static const struct i2s_soc_info jz4780_i2s_soc_info = {
 	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
 	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
 	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
+	.pll_clk_name		= "pll half",
 };
 
 static const struct snd_soc_component_driver jz4740_i2s_component = {
-- 
2.35.1


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

* [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

The audio controller on JZ47xx SoCs supports 20- and 24-bit
samples coming from memory. Allow those formats to be used
with the I2S driver.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 80b355d715ce..ee99c5e781ec 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_FORMAT_S8:
 		sample_size = 0;
 		break;
-	case SNDRV_PCM_FORMAT_S16:
+	case SNDRV_PCM_FORMAT_S16_LE:
 		sample_size = 1;
 		break;
+	case SNDRV_PCM_FORMAT_S20_LE:
+		sample_size = 3;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		sample_size = 4;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
 };
 
 #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
-		SNDRV_PCM_FMTBIT_S16_LE)
+			 SNDRV_PCM_FMTBIT_S16_LE | \
+			 SNDRV_PCM_FMTBIT_S20_LE | \
+			 SNDRV_PCM_FMTBIT_S24_LE)
 
 static struct snd_soc_dai_driver jz4740_i2s_dai = {
 	.probe = jz4740_i2s_dai_probe,
-- 
2.35.1


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

* [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

The audio controller on JZ47xx SoCs supports 20- and 24-bit
samples coming from memory. Allow those formats to be used
with the I2S driver.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 80b355d715ce..ee99c5e781ec 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_FORMAT_S8:
 		sample_size = 0;
 		break;
-	case SNDRV_PCM_FORMAT_S16:
+	case SNDRV_PCM_FORMAT_S16_LE:
 		sample_size = 1;
 		break;
+	case SNDRV_PCM_FORMAT_S20_LE:
+		sample_size = 3;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		sample_size = 4;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
 };
 
 #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
-		SNDRV_PCM_FMTBIT_S16_LE)
+			 SNDRV_PCM_FMTBIT_S16_LE | \
+			 SNDRV_PCM_FMTBIT_S20_LE | \
+			 SNDRV_PCM_FMTBIT_S24_LE)
 
 static struct snd_soc_dai_driver jz4740_i2s_dai = {
 	.probe = jz4740_i2s_dai_probe,
-- 
2.35.1


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

* [PATCH 11/11] ASoC: jz4740-i2s: Support continuous sample rate
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-06 21:13   ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: linux-mips, alsa-devel, linux-kernel

The I2S controller on JZ47xx SoCs doesn't impose restrictions on
sample rate and the driver doesn't make any assumptions about it,
so the DAI should advertise a continuous sample rate range.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index ee99c5e781ec..053697c7f19e 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -378,13 +378,13 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 	.playback = {
 		.channels_min = 1,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.capture = {
 		.channels_min = 2,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.symmetric_rate = 1,
@@ -415,13 +415,13 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 	.playback = {
 		.channels_min = 1,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.capture = {
 		.channels_min = 2,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.ops = &jz4740_i2s_dai_ops,
-- 
2.35.1


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

* [PATCH 11/11] ASoC: jz4740-i2s: Support continuous sample rate
@ 2022-07-06 21:13   ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-06 21:13 UTC (permalink / raw)
  To: paul, lgirdwood, broonie, perex, tiwai
  Cc: alsa-devel, linux-mips, linux-kernel

The I2S controller on JZ47xx SoCs doesn't impose restrictions on
sample rate and the driver doesn't make any assumptions about it,
so the DAI should advertise a continuous sample rate range.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 sound/soc/jz4740/jz4740-i2s.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index ee99c5e781ec..053697c7f19e 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -378,13 +378,13 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
 	.playback = {
 		.channels_min = 1,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.capture = {
 		.channels_min = 2,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.symmetric_rate = 1,
@@ -415,13 +415,13 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
 	.playback = {
 		.channels_min = 1,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.capture = {
 		.channels_min = 2,
 		.channels_max = 2,
-		.rates = SNDRV_PCM_RATE_8000_48000,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.formats = JZ4740_I2S_FMTS,
 	},
 	.ops = &jz4740_i2s_dai_ops,
-- 
2.35.1


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

* Re: [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-06 21:53     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-06 21:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel

Hi Aidan,

Le mer., juil. 6 2022 at 22:13:22 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Using regmap for accessing the AIC registers makes the driver a
> little easier to read, and later refactors can take advantage of
> regmap APIs to further simplify the driver.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/Kconfig      |  1 +
>  sound/soc/jz4740/jz4740-i2s.c | 99 
> +++++++++++++++--------------------
>  2 files changed, 42 insertions(+), 58 deletions(-)
> 
> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
> index e72f826062e9..dd3b4507fbe6 100644
> --- a/sound/soc/jz4740/Kconfig
> +++ b/sound/soc/jz4740/Kconfig
> @@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>  	depends on MIPS || COMPILE_TEST
>  	depends on HAS_IOMEM
> +	select REGMAP_MMIO
>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>  	help
>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic 
> JZ4740
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index ecd8df70d39c..66a901f56392 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -9,6 +9,7 @@
>  #include <linux/module.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/platform_device.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
> 
>  #include <linux/clk.h>
> @@ -94,7 +95,7 @@ struct i2s_soc_info {
> 
>  struct jz4740_i2s {
>  	struct resource *mem;
> -	void __iomem *base;
> +	struct regmap *regmap;
> 
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> @@ -105,39 +106,24 @@ struct jz4740_i2s {
>  	const struct i2s_soc_info *soc_info;
>  };
> 
> -static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
> -	unsigned int reg)
> -{
> -	return readl(i2s->base + reg);
> -}
> -
> -static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
> -	unsigned int reg, uint32_t value)
> -{
> -	writel(value, i2s->base + reg);
> -}
> -
>  static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf, ctrl;
>  	int ret;
> 
>  	if (snd_soc_dai_active(dai))
>  		return 0;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> -	ctrl |= JZ_AIC_CTRL_FLUSH;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> +	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
> +			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);

I don't think you need regmap_write_bits() here, since there is no 
cache to bypass. You could use regmap_update_bits(), or even better, 
regmap_set_bits().

> 
>  	ret = clk_prepare_enable(i2s->clk_i2s);
>  	if (ret)
>  		return ret;
> 
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -	conf |= JZ_AIC_CONF_ENABLE;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);

Use regmap_set_bits() when you want to set all the bits of the mask.

> 
>  	return 0;
>  }
> @@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct 
> snd_pcm_substream *substream,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf;
> 
>  	if (snd_soc_dai_active(dai))
>  		return;
> 
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -	conf &= ~JZ_AIC_CONF_ENABLE;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +			   JZ_AIC_CONF_ENABLE, 0);

Use regmap_clear_bits() when you want to clear all bits of the mask.

Otherwise, looks fairly good!

Cheers,
-Paul

> 
>  	clk_disable_unprepare(i2s->clk_i2s);
>  }
> @@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct 
> snd_pcm_substream *substream, int cmd,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -
> -	uint32_t ctrl;
>  	uint32_t mask;
> 
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> @@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct 
> snd_pcm_substream *substream, int cmd,
>  	else
>  		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> -
>  	switch (cmd) {
>  	case SNDRV_PCM_TRIGGER_START:
>  	case SNDRV_PCM_TRIGGER_RESUME:
>  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> -		ctrl |= mask;
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
>  		break;
>  	case SNDRV_PCM_TRIGGER_STOP:
>  	case SNDRV_PCM_TRIGGER_SUSPEND:
>  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> -		ctrl &= ~mask;
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> -
>  	return 0;
>  }
> 
>  static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int 
> fmt)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -
> -	uint32_t format = 0;
> -	uint32_t conf;
> -
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -
> -	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
> +	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
> +				       JZ_AIC_CONF_SYNC_CLK_MASTER;
> +	unsigned int conf = 0, format = 0;
> 
>  	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
>  	case SND_SOC_DAIFMT_BP_FP:
> @@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai 
> *dai, unsigned int fmt)
>  		return -EINVAL;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
> 
>  	return 0;
>  }
> @@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	uint32_t ctrl, div_reg;
>  	int div;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> +	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
> +	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
> 
> -	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
> 
>  	switch (params_format(params)) {
> @@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  		}
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
> 
>  	return 0;
>  }
> @@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct 
> snd_soc_dai *dai, int clk_id,
>  static int jz4740_i2s_suspend(struct snd_soc_component *component)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
> -	uint32_t conf;
> 
>  	if (snd_soc_component_active(component)) {
> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -		conf &= ~JZ_AIC_CONF_ENABLE;
> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +				   JZ_AIC_CONF_ENABLE, 0);
> 
>  		clk_disable_unprepare(i2s->clk_i2s);
>  	}
> @@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct 
> snd_soc_component *component)
>  static int jz4740_i2s_resume(struct snd_soc_component *component)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
> -	uint32_t conf;
>  	int ret;
> 
>  	ret = clk_prepare_enable(i2s->clk_aic);
> @@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  			return ret;
>  		}
> 
> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -		conf |= JZ_AIC_CONF_ENABLE;
> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>  	}
> 
>  	return 0;
> @@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  			JZ_AIC_CONF_INTERNAL_CODEC;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
> 
>  	return 0;
>  }
> @@ -495,11 +465,19 @@ static const struct of_device_id 
> jz4740_of_matches[] = {
>  };
>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
> 
> +static const struct regmap_config jz4740_i2s_regmap_config = {
> +	.reg_bits	= 32,
> +	.reg_stride	= 4,
> +	.val_bits	= 32,
> +	.max_register	= JZ_REG_AIC_FIFO,
> +};
> +
>  static int jz4740_i2s_dev_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct jz4740_i2s *i2s;
>  	struct resource *mem;
> +	void __iomem *regs;
>  	int ret;
> 
>  	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
> @@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
> 
>  	i2s->soc_info = device_get_match_data(dev);
> 
> -	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
> -	if (IS_ERR(i2s->base))
> -		return PTR_ERR(i2s->base);
> +	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> 
>  	i2s->playback_dma_data.maxburst = 16;
>  	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> @@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->clk_i2s))
>  		return PTR_ERR(i2s->clk_i2s);
> 
> +	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> +					    &jz4740_i2s_regmap_config);
> +	if (IS_ERR(i2s->regmap))
> +		return PTR_ERR(i2s->regmap);
> +
>  	platform_set_drvdata(pdev, i2s);
> 
>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
> --
> 2.35.1
> 



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

* Re: [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
@ 2022-07-06 21:53     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-06 21:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie

Hi Aidan,

Le mer., juil. 6 2022 at 22:13:22 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Using regmap for accessing the AIC registers makes the driver a
> little easier to read, and later refactors can take advantage of
> regmap APIs to further simplify the driver.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/Kconfig      |  1 +
>  sound/soc/jz4740/jz4740-i2s.c | 99 
> +++++++++++++++--------------------
>  2 files changed, 42 insertions(+), 58 deletions(-)
> 
> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
> index e72f826062e9..dd3b4507fbe6 100644
> --- a/sound/soc/jz4740/Kconfig
> +++ b/sound/soc/jz4740/Kconfig
> @@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>  	depends on MIPS || COMPILE_TEST
>  	depends on HAS_IOMEM
> +	select REGMAP_MMIO
>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>  	help
>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic 
> JZ4740
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index ecd8df70d39c..66a901f56392 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -9,6 +9,7 @@
>  #include <linux/module.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/platform_device.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
> 
>  #include <linux/clk.h>
> @@ -94,7 +95,7 @@ struct i2s_soc_info {
> 
>  struct jz4740_i2s {
>  	struct resource *mem;
> -	void __iomem *base;
> +	struct regmap *regmap;
> 
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> @@ -105,39 +106,24 @@ struct jz4740_i2s {
>  	const struct i2s_soc_info *soc_info;
>  };
> 
> -static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
> -	unsigned int reg)
> -{
> -	return readl(i2s->base + reg);
> -}
> -
> -static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
> -	unsigned int reg, uint32_t value)
> -{
> -	writel(value, i2s->base + reg);
> -}
> -
>  static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf, ctrl;
>  	int ret;
> 
>  	if (snd_soc_dai_active(dai))
>  		return 0;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> -	ctrl |= JZ_AIC_CTRL_FLUSH;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> +	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
> +			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);

I don't think you need regmap_write_bits() here, since there is no 
cache to bypass. You could use regmap_update_bits(), or even better, 
regmap_set_bits().

> 
>  	ret = clk_prepare_enable(i2s->clk_i2s);
>  	if (ret)
>  		return ret;
> 
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -	conf |= JZ_AIC_CONF_ENABLE;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);

Use regmap_set_bits() when you want to set all the bits of the mask.

> 
>  	return 0;
>  }
> @@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct 
> snd_pcm_substream *substream,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf;
> 
>  	if (snd_soc_dai_active(dai))
>  		return;
> 
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -	conf &= ~JZ_AIC_CONF_ENABLE;
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +			   JZ_AIC_CONF_ENABLE, 0);

Use regmap_clear_bits() when you want to clear all bits of the mask.

Otherwise, looks fairly good!

Cheers,
-Paul

> 
>  	clk_disable_unprepare(i2s->clk_i2s);
>  }
> @@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct 
> snd_pcm_substream *substream, int cmd,
>  	struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -
> -	uint32_t ctrl;
>  	uint32_t mask;
> 
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> @@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct 
> snd_pcm_substream *substream, int cmd,
>  	else
>  		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> -
>  	switch (cmd) {
>  	case SNDRV_PCM_TRIGGER_START:
>  	case SNDRV_PCM_TRIGGER_RESUME:
>  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> -		ctrl |= mask;
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
>  		break;
>  	case SNDRV_PCM_TRIGGER_STOP:
>  	case SNDRV_PCM_TRIGGER_SUSPEND:
>  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> -		ctrl &= ~mask;
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> -
>  	return 0;
>  }
> 
>  static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int 
> fmt)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -
> -	uint32_t format = 0;
> -	uint32_t conf;
> -
> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -
> -	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
> +	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
> +				       JZ_AIC_CONF_SYNC_CLK_MASTER;
> +	unsigned int conf = 0, format = 0;
> 
>  	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
>  	case SND_SOC_DAIFMT_BP_FP:
> @@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai 
> *dai, unsigned int fmt)
>  		return -EINVAL;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
> 
>  	return 0;
>  }
> @@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	uint32_t ctrl, div_reg;
>  	int div;
> 
> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
> +	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
> +	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
> 
> -	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
> 
>  	switch (params_format(params)) {
> @@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  		}
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
> 
>  	return 0;
>  }
> @@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct 
> snd_soc_dai *dai, int clk_id,
>  static int jz4740_i2s_suspend(struct snd_soc_component *component)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
> -	uint32_t conf;
> 
>  	if (snd_soc_component_active(component)) {
> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -		conf &= ~JZ_AIC_CONF_ENABLE;
> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +				   JZ_AIC_CONF_ENABLE, 0);
> 
>  		clk_disable_unprepare(i2s->clk_i2s);
>  	}
> @@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct 
> snd_soc_component *component)
>  static int jz4740_i2s_resume(struct snd_soc_component *component)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
> -	uint32_t conf;
>  	int ret;
> 
>  	ret = clk_prepare_enable(i2s->clk_aic);
> @@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  			return ret;
>  		}
> 
> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
> -		conf |= JZ_AIC_CONF_ENABLE;
> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
> +				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>  	}
> 
>  	return 0;
> @@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  			JZ_AIC_CONF_INTERNAL_CODEC;
>  	}
> 
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
> 
>  	return 0;
>  }
> @@ -495,11 +465,19 @@ static const struct of_device_id 
> jz4740_of_matches[] = {
>  };
>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
> 
> +static const struct regmap_config jz4740_i2s_regmap_config = {
> +	.reg_bits	= 32,
> +	.reg_stride	= 4,
> +	.val_bits	= 32,
> +	.max_register	= JZ_REG_AIC_FIFO,
> +};
> +
>  static int jz4740_i2s_dev_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct jz4740_i2s *i2s;
>  	struct resource *mem;
> +	void __iomem *regs;
>  	int ret;
> 
>  	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
> @@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
> 
>  	i2s->soc_info = device_get_match_data(dev);
> 
> -	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
> -	if (IS_ERR(i2s->base))
> -		return PTR_ERR(i2s->base);
> +	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> 
>  	i2s->playback_dma_data.maxburst = 16;
>  	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> @@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->clk_i2s))
>  		return PTR_ERR(i2s->clk_i2s);
> 
> +	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> +					    &jz4740_i2s_regmap_config);
> +	if (IS_ERR(i2s->regmap))
> +		return PTR_ERR(i2s->regmap);
> +
>  	platform_set_drvdata(pdev, i2s);
> 
>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
> --
> 2.35.1
> 



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

* Re: [PATCH 01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:16     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:16 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel

Hi Aidan,

Le mer., juil. 6 2022 at 22:13:20 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> This driver doesn't require Open Firmware support. Remove the
> OF-specific includes and drop the Kconfig dependency.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/Kconfig      | 2 +-
>  sound/soc/jz4740/jz4740-i2s.c | 3 +--
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
> index 29144720cb62..e72f826062e9 100644
> --- a/sound/soc/jz4740/Kconfig
> +++ b/sound/soc/jz4740/Kconfig
> @@ -2,7 +2,7 @@
>  config SND_JZ4740_SOC_I2S
>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>  	depends on MIPS || COMPILE_TEST
> -	depends on OF && HAS_IOMEM
> +	depends on HAS_IOMEM
>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>  	help
>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic 
> JZ4740
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 79afac0c5003..298ff0a83931 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -5,10 +5,9 @@
> 
>  #include <linux/init.h>
>  #include <linux/io.h>
> -#include <linux/of.h>
> -#include <linux/of_device.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/mod_devicetable.h>
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
> 
> --
> 2.35.1
> 



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

* Re: [PATCH 01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
@ 2022-07-07  9:16     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:16 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie

Hi Aidan,

Le mer., juil. 6 2022 at 22:13:20 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> This driver doesn't require Open Firmware support. Remove the
> OF-specific includes and drop the Kconfig dependency.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/Kconfig      | 2 +-
>  sound/soc/jz4740/jz4740-i2s.c | 3 +--
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
> index 29144720cb62..e72f826062e9 100644
> --- a/sound/soc/jz4740/Kconfig
> +++ b/sound/soc/jz4740/Kconfig
> @@ -2,7 +2,7 @@
>  config SND_JZ4740_SOC_I2S
>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>  	depends on MIPS || COMPILE_TEST
> -	depends on OF && HAS_IOMEM
> +	depends on HAS_IOMEM
>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>  	help
>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic 
> JZ4740
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 79afac0c5003..298ff0a83931 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -5,10 +5,9 @@
> 
>  #include <linux/init.h>
>  #include <linux/io.h>
> -#include <linux/of.h>
> -#include <linux/of_device.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/mod_devicetable.h>
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
> 
> --
> 2.35.1
> 



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

* Re: [PATCH 02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:30     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:30 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:21 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> It's simpler to set up the playback and capture DMA settings
> at driver probe time instead of during DAI probing.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 23 +++++------------------
>  1 file changed, 5 insertions(+), 18 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 298ff0a83931..ecd8df70d39c 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -95,7 +95,6 @@ struct i2s_soc_info {
>  struct jz4740_i2s {
>  	struct resource *mem;
>  	void __iomem *base;
> -	dma_addr_t phys_base;

Acked-by: Paul Cercueil <paul@crapouillou.net>

Note that you can remove "mem" too, it's not used anywhere.

Cheers,
-Paul

> 
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> @@ -370,21 +369,6 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  	return 0;
>  }
> 
> -static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s)
> -{
> -	struct snd_dmaengine_dai_dma_data *dma_data;
> -
> -	/* Playback */
> -	dma_data = &i2s->playback_dma_data;
> -	dma_data->maxburst = 16;
> -	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
> -
> -	/* Capture */
> -	dma_data = &i2s->capture_dma_data;
> -	dma_data->maxburst = 16;
> -	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
> -}
> -
>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> @@ -395,7 +379,6 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  	if (ret)
>  		return ret;
> 
> -	jz4740_i2s_init_pcm_config(i2s);
>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>  		&i2s->capture_dma_data);
> 
> @@ -529,7 +512,11 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->base))
>  		return PTR_ERR(i2s->base);
> 
> -	i2s->phys_base = mem->start;
> +	i2s->playback_dma_data.maxburst = 16;
> +	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> +
> +	i2s->capture_dma_data.maxburst = 16;
> +	i2s->capture_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> 
>  	i2s->clk_aic = devm_clk_get(dev, "aic");
>  	if (IS_ERR(i2s->clk_aic))
> --
> 2.35.1
> 



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

* Re: [PATCH 02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
@ 2022-07-07  9:30     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:30 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:21 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> It's simpler to set up the playback and capture DMA settings
> at driver probe time instead of during DAI probing.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 23 +++++------------------
>  1 file changed, 5 insertions(+), 18 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 298ff0a83931..ecd8df70d39c 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -95,7 +95,6 @@ struct i2s_soc_info {
>  struct jz4740_i2s {
>  	struct resource *mem;
>  	void __iomem *base;
> -	dma_addr_t phys_base;

Acked-by: Paul Cercueil <paul@crapouillou.net>

Note that you can remove "mem" too, it's not used anywhere.

Cheers,
-Paul

> 
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> @@ -370,21 +369,6 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  	return 0;
>  }
> 
> -static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s)
> -{
> -	struct snd_dmaengine_dai_dma_data *dma_data;
> -
> -	/* Playback */
> -	dma_data = &i2s->playback_dma_data;
> -	dma_data->maxburst = 16;
> -	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
> -
> -	/* Capture */
> -	dma_data = &i2s->capture_dma_data;
> -	dma_data->maxburst = 16;
> -	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
> -}
> -
>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> @@ -395,7 +379,6 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  	if (ret)
>  		return ret;
> 
> -	jz4740_i2s_init_pcm_config(i2s);
>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>  		&i2s->capture_dma_data);
> 
> @@ -529,7 +512,11 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->base))
>  		return PTR_ERR(i2s->base);
> 
> -	i2s->phys_base = mem->start;
> +	i2s->playback_dma_data.maxburst = 16;
> +	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> +
> +	i2s->capture_dma_data.maxburst = 16;
> +	i2s->capture_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
> 
>  	i2s->clk_aic = devm_clk_get(dev, "aic");
>  	if (IS_ERR(i2s->clk_aic))
> --
> 2.35.1
> 



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

* Re: [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:36     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:36 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:23 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The differences between register fields on different SoC versions
> can be abstracted away using the regmap field API. This is easier
> to understand and extend than comparisons based on the version ID.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 100 
> ++++++++++++++++++++++++----------
>  1 file changed, 72 insertions(+), 28 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 66a901f56392..cbb89f724f64 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
>  struct i2s_soc_info {
>  	enum jz47xx_i2s_version version;
>  	struct snd_soc_dai_driver *dai;
> +
> +	struct reg_field field_rx_fifo_thresh;
> +	struct reg_field field_tx_fifo_thresh;
> +	struct reg_field field_i2sdiv_capture;
> +	struct reg_field field_i2sdiv_playback;
>  };
> 
>  struct jz4740_i2s {
>  	struct resource *mem;
>  	struct regmap *regmap;
> 
> +	struct regmap_field *field_rx_fifo_thresh;
> +	struct regmap_field *field_tx_fifo_thresh;
> +	struct regmap_field *field_i2sdiv_capture;
> +	struct regmap_field *field_i2sdiv_playback;
> +
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> 
> @@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +	struct regmap_field *div_field;
>  	unsigned int sample_size;
> -	uint32_t ctrl, div_reg;
> +	uint32_t ctrl;
>  	int div;
> 
>  	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
> -	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
> 
>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
> 
> @@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  		else
>  			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
> 
> -		div_reg &= ~I2SDIV_DV_MASK;
> -		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
> +		div_field = i2s->field_i2sdiv_playback;
>  	} else {
>  		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
>  		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
> 
> -		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
> -			div_reg &= ~I2SDIV_IDV_MASK;
> -			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
> -		} else {
> -			div_reg &= ~I2SDIV_DV_MASK;
> -			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
> -		}
> +		div_field = i2s->field_i2sdiv_capture;
>  	}
> 
>  	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
> -	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
> +	regmap_field_write(div_field, div - 1);
> 
>  	return 0;
>  }
> @@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf;
>  	int ret;
> 
>  	ret = clk_prepare_enable(i2s->clk_aic);
> @@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>  		&i2s->capture_dma_data);
> 
> -	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
> -		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
> -			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> -			JZ_AIC_CONF_I2S |
> -			JZ_AIC_CONF_INTERNAL_CODEC;
> -	} else {
> -		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
> -			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |

I believe you can remove these macros completely now that they are 
unused. Same goes for I2S_IDV_MASK, etc.

Cheers,
-Paul

> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> -			JZ_AIC_CONF_I2S |
> -			JZ_AIC_CONF_INTERNAL_CODEC;
> -	}
> -
>  	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> -	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
> +
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
> +		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> +		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
> +
> +	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
> +	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
> 
>  	return 0;
>  }
> @@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai 
> = {
>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4740,
>  	.dai = &jz4740_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4760,
>  	.dai = &jz4740_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
> @@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai 
> = {
>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4770,
>  	.dai = &jz4770_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4780,
>  	.dai = &jz4770_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct snd_soc_component_driver jz4740_i2s_component = {
> @@ -465,6 +475,36 @@ static const struct of_device_id 
> jz4740_of_matches[] = {
>  };
>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
> 
> +static int jz4740_i2s_init_regmap_fields(struct device *dev,
> +					 struct jz4740_i2s *i2s)
> +{
> +	i2s->field_rx_fifo_thresh =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_rx_fifo_thresh);
> +	if (IS_ERR(i2s->field_rx_fifo_thresh))
> +		return PTR_ERR(i2s->field_rx_fifo_thresh);
> +
> +	i2s->field_tx_fifo_thresh =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_tx_fifo_thresh);
> +	if (IS_ERR(i2s->field_tx_fifo_thresh))
> +		return PTR_ERR(i2s->field_tx_fifo_thresh);
> +
> +	i2s->field_i2sdiv_capture =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_i2sdiv_capture);
> +	if (IS_ERR(i2s->field_i2sdiv_capture))
> +		return PTR_ERR(i2s->field_i2sdiv_capture);
> +
> +	i2s->field_i2sdiv_playback =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_i2sdiv_playback);
> +	if (IS_ERR(i2s->field_i2sdiv_playback))
> +		return PTR_ERR(i2s->field_i2sdiv_playback);
> +
> +	return 0;
> +}
> +
>  static const struct regmap_config jz4740_i2s_regmap_config = {
>  	.reg_bits	= 32,
>  	.reg_stride	= 4,
> @@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->regmap))
>  		return PTR_ERR(i2s->regmap);
> 
> +	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
> +	if (ret)
> +		return ret;
> +
>  	platform_set_drvdata(pdev, i2s);
> 
>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
> --
> 2.35.1
> 



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

* Re: [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
@ 2022-07-07  9:36     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:36 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:23 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The differences between register fields on different SoC versions
> can be abstracted away using the regmap field API. This is easier
> to understand and extend than comparisons based on the version ID.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 100 
> ++++++++++++++++++++++++----------
>  1 file changed, 72 insertions(+), 28 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 66a901f56392..cbb89f724f64 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
>  struct i2s_soc_info {
>  	enum jz47xx_i2s_version version;
>  	struct snd_soc_dai_driver *dai;
> +
> +	struct reg_field field_rx_fifo_thresh;
> +	struct reg_field field_tx_fifo_thresh;
> +	struct reg_field field_i2sdiv_capture;
> +	struct reg_field field_i2sdiv_playback;
>  };
> 
>  struct jz4740_i2s {
>  	struct resource *mem;
>  	struct regmap *regmap;
> 
> +	struct regmap_field *field_rx_fifo_thresh;
> +	struct regmap_field *field_tx_fifo_thresh;
> +	struct regmap_field *field_i2sdiv_capture;
> +	struct regmap_field *field_i2sdiv_playback;
> +
>  	struct clk *clk_aic;
>  	struct clk *clk_i2s;
> 
> @@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +	struct regmap_field *div_field;
>  	unsigned int sample_size;
> -	uint32_t ctrl, div_reg;
> +	uint32_t ctrl;
>  	int div;
> 
>  	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
> -	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
> 
>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
> 
> @@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  		else
>  			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
> 
> -		div_reg &= ~I2SDIV_DV_MASK;
> -		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
> +		div_field = i2s->field_i2sdiv_playback;
>  	} else {
>  		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
>  		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
> 
> -		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
> -			div_reg &= ~I2SDIV_IDV_MASK;
> -			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
> -		} else {
> -			div_reg &= ~I2SDIV_DV_MASK;
> -			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
> -		}
> +		div_field = i2s->field_i2sdiv_capture;
>  	}
> 
>  	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
> -	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
> +	regmap_field_write(div_field, div - 1);
> 
>  	return 0;
>  }
> @@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct 
> snd_soc_component *component)
>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>  {
>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> -	uint32_t conf;
>  	int ret;
> 
>  	ret = clk_prepare_enable(i2s->clk_aic);
> @@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct 
> snd_soc_dai *dai)
>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>  		&i2s->capture_dma_data);
> 
> -	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
> -		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
> -			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> -			JZ_AIC_CONF_I2S |
> -			JZ_AIC_CONF_INTERNAL_CODEC;
> -	} else {
> -		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
> -			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |

I believe you can remove these macros completely now that they are 
unused. Same goes for I2S_IDV_MASK, etc.

Cheers,
-Paul

> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> -			JZ_AIC_CONF_I2S |
> -			JZ_AIC_CONF_INTERNAL_CODEC;
> -	}
> -
>  	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
> -	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
> +
> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
> +		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
> +		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
> +
> +	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
> +	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
> 
>  	return 0;
>  }
> @@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai 
> = {
>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4740,
>  	.dai = &jz4740_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4760,
>  	.dai = &jz4740_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
> @@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai 
> = {
>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4770,
>  	.dai = &jz4770_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>  	.version = JZ_I2S_JZ4780,
>  	.dai = &jz4770_i2s_dai,
> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  };
> 
>  static const struct snd_soc_component_driver jz4740_i2s_component = {
> @@ -465,6 +475,36 @@ static const struct of_device_id 
> jz4740_of_matches[] = {
>  };
>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
> 
> +static int jz4740_i2s_init_regmap_fields(struct device *dev,
> +					 struct jz4740_i2s *i2s)
> +{
> +	i2s->field_rx_fifo_thresh =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_rx_fifo_thresh);
> +	if (IS_ERR(i2s->field_rx_fifo_thresh))
> +		return PTR_ERR(i2s->field_rx_fifo_thresh);
> +
> +	i2s->field_tx_fifo_thresh =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_tx_fifo_thresh);
> +	if (IS_ERR(i2s->field_tx_fifo_thresh))
> +		return PTR_ERR(i2s->field_tx_fifo_thresh);
> +
> +	i2s->field_i2sdiv_capture =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_i2sdiv_capture);
> +	if (IS_ERR(i2s->field_i2sdiv_capture))
> +		return PTR_ERR(i2s->field_i2sdiv_capture);
> +
> +	i2s->field_i2sdiv_playback =
> +		devm_regmap_field_alloc(dev, i2s->regmap,
> +					i2s->soc_info->field_i2sdiv_playback);
> +	if (IS_ERR(i2s->field_i2sdiv_playback))
> +		return PTR_ERR(i2s->field_i2sdiv_playback);
> +
> +	return 0;
> +}
> +
>  static const struct regmap_config jz4740_i2s_regmap_config = {
>  	.reg_bits	= 32,
>  	.reg_stride	= 4,
> @@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(i2s->regmap))
>  		return PTR_ERR(i2s->regmap);
> 
> +	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
> +	if (ret)
> +		return ret;
> +
>  	platform_set_drvdata(pdev, i2s);
> 
>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
> --
> 2.35.1
> 



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

* Re: [PATCH 05/11] ASoC: jz4740-i2s: Remove unused SoC version IDs
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:37     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:37 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:24 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Using version IDs makes the code hard to follow -- it's better to
> describe the functional differences between SoCs instead. Remove
> the IDs since they're no longer used.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 12 ------------
>  1 file changed, 12 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index cbb89f724f64..8bb9449d13d3 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -81,15 +81,7 @@
>  #define I2SDIV_IDV_SHIFT 8
>  #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
> 
> -enum jz47xx_i2s_version {
> -	JZ_I2S_JZ4740,
> -	JZ_I2S_JZ4760,
> -	JZ_I2S_JZ4770,
> -	JZ_I2S_JZ4780,
> -};
> -
>  struct i2s_soc_info {
> -	enum jz47xx_i2s_version version;
>  	struct snd_soc_dai_driver *dai;
> 
>  	struct reg_field field_rx_fifo_thresh;
> @@ -406,7 +398,6 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = 
> {
>  };
> 
>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4740,
>  	.dai = &jz4740_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
> @@ -415,7 +406,6 @@ static const struct i2s_soc_info 
> jz4740_i2s_soc_info = {
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4760,
>  	.dai = &jz4740_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> @@ -442,7 +432,6 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = 
> {
>  };
> 
>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4770,
>  	.dai = &jz4770_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> @@ -451,7 +440,6 @@ static const struct i2s_soc_info 
> jz4770_i2s_soc_info = {
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4780,
>  	.dai = &jz4770_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> --
> 2.35.1
> 



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

* Re: [PATCH 05/11] ASoC: jz4740-i2s: Remove unused SoC version IDs
@ 2022-07-07  9:37     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:37 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:24 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Using version IDs makes the code hard to follow -- it's better to
> describe the functional differences between SoCs instead. Remove
> the IDs since they're no longer used.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 12 ------------
>  1 file changed, 12 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index cbb89f724f64..8bb9449d13d3 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -81,15 +81,7 @@
>  #define I2SDIV_IDV_SHIFT 8
>  #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
> 
> -enum jz47xx_i2s_version {
> -	JZ_I2S_JZ4740,
> -	JZ_I2S_JZ4760,
> -	JZ_I2S_JZ4770,
> -	JZ_I2S_JZ4780,
> -};
> -
>  struct i2s_soc_info {
> -	enum jz47xx_i2s_version version;
>  	struct snd_soc_dai_driver *dai;
> 
>  	struct reg_field field_rx_fifo_thresh;
> @@ -406,7 +398,6 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = 
> {
>  };
> 
>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4740,
>  	.dai = &jz4740_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
> @@ -415,7 +406,6 @@ static const struct i2s_soc_info 
> jz4740_i2s_soc_info = {
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4760,
>  	.dai = &jz4740_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> @@ -442,7 +432,6 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = 
> {
>  };
> 
>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4770,
>  	.dai = &jz4770_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> @@ -451,7 +440,6 @@ static const struct i2s_soc_info 
> jz4770_i2s_soc_info = {
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
> -	.version = JZ_I2S_JZ4780,
>  	.dai = &jz4770_i2s_dai,
>  	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
> --
> 2.35.1
> 



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

* Re: [PATCH 06/11] ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:40     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:40 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:25 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Get rid of a couple of macros and improve readability by using
> FIELD_PREP() and GENMASK() for the sample size setting.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 8bb9449d13d3..3c3cf78bf848 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -3,6 +3,7 @@
>   *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
>   */
> 
> +#include <linux/bitfield.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -49,8 +50,8 @@
>  #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
>  #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
> 
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
> +#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
> +#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
>  #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
>  #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
>  #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
> @@ -65,9 +66,6 @@
>  #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
>  #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
> 
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET  16
> -
>  #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
>  #define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
>  #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
> @@ -245,8 +243,9 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	}
> 
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
> -		ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
> +		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE;
> +		ctrl |= FIELD_PREP(JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE, sample_size);
> +
>  		if (params_channels(params) == 1)
>  			ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
>  		else
> @@ -254,8 +253,8 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
> 
>  		div_field = i2s->field_i2sdiv_playback;
>  	} else {
> -		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
> -		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
> +		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE;
> +		ctrl |= FIELD_PREP(JZ_AIC_CTRL_INPUT_SAMPLE_SIZE, sample_size);
> 
>  		div_field = i2s->field_i2sdiv_capture;
>  	}
> --
> 2.35.1
> 



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

* Re: [PATCH 06/11] ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback
@ 2022-07-07  9:40     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:40 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:25 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Get rid of a couple of macros and improve readability by using
> FIELD_PREP() and GENMASK() for the sample size setting.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 8bb9449d13d3..3c3cf78bf848 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -3,6 +3,7 @@
>   *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
>   */
> 
> +#include <linux/bitfield.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -49,8 +50,8 @@
>  #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
>  #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
> 
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
> +#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
> +#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
>  #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
>  #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
>  #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
> @@ -65,9 +66,6 @@
>  #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
>  #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
> 
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET  16
> -
>  #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
>  #define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
>  #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
> @@ -245,8 +243,9 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	}
> 
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
> -		ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
> +		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE;
> +		ctrl |= FIELD_PREP(JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE, sample_size);
> +
>  		if (params_channels(params) == 1)
>  			ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
>  		else
> @@ -254,8 +253,8 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
> 
>  		div_field = i2s->field_i2sdiv_playback;
>  	} else {
> -		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
> -		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
> +		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE;
> +		ctrl |= FIELD_PREP(JZ_AIC_CTRL_INPUT_SAMPLE_SIZE, sample_size);
> 
>  		div_field = i2s->field_i2sdiv_capture;
>  	}
> --
> 2.35.1
> 



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

* Re: [PATCH 07/11] ASoC: jz4740-i2s: Remove some unused macros
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:42     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:42 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:26 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> These macros are unused and can be dropped; the information is now
> encoded in regmap fields.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

I think you can remove the macros in the patches where they are being 
made obsolete.

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 13 -------------
>  1 file changed, 13 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 3c3cf78bf848..b8d2723c5f90 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -35,8 +35,6 @@
>  #define JZ_REG_AIC_CLK_DIV	0x30
>  #define JZ_REG_AIC_FIFO		0x34
> 
> -#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
> -#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf <<  8)
>  #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
>  #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
>  #define JZ_AIC_CONF_I2S BIT(4)
> @@ -45,11 +43,6 @@
>  #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
>  #define JZ_AIC_CONF_ENABLE BIT(0)
> 
> -#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
> -#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
> -#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
> -#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
> -
>  #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
>  #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
>  #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
> @@ -73,12 +66,6 @@
> 
>  #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
> 
> -#define JZ_AIC_CLK_DIV_MASK 0xf
> -#define I2SDIV_DV_SHIFT 0
> -#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
> -#define I2SDIV_IDV_SHIFT 8
> -#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
> -
>  struct i2s_soc_info {
>  	struct snd_soc_dai_driver *dai;
> 
> --
> 2.35.1
> 



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

* Re: [PATCH 07/11] ASoC: jz4740-i2s: Remove some unused macros
@ 2022-07-07  9:42     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:42 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:26 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> These macros are unused and can be dropped; the information is now
> encoded in regmap fields.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

I think you can remove the macros in the patches where they are being 
made obsolete.

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 13 -------------
>  1 file changed, 13 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 3c3cf78bf848..b8d2723c5f90 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -35,8 +35,6 @@
>  #define JZ_REG_AIC_CLK_DIV	0x30
>  #define JZ_REG_AIC_FIFO		0x34
> 
> -#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
> -#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf <<  8)
>  #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
>  #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
>  #define JZ_AIC_CONF_I2S BIT(4)
> @@ -45,11 +43,6 @@
>  #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
>  #define JZ_AIC_CONF_ENABLE BIT(0)
> 
> -#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
> -#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
> -#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
> -#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
> -
>  #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
>  #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
>  #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
> @@ -73,12 +66,6 @@
> 
>  #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
> 
> -#define JZ_AIC_CLK_DIV_MASK 0xf
> -#define I2SDIV_DV_SHIFT 0
> -#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
> -#define I2SDIV_IDV_SHIFT 8
> -#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
> -
>  struct i2s_soc_info {
>  	struct snd_soc_dai_driver *dai;
> 
> --
> 2.35.1
> 



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

* Re: [PATCH 08/11] ASoC: jz4740-i2s: Align macro values and sort includes
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:42     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:42 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:27 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Some purely cosmetic changes: line up all the macro values to
> make things easier to read and sort the includes alphabetically.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 66 
> +++++++++++++++++------------------
>  1 file changed, 32 insertions(+), 34 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index b8d2723c5f90..3a21ee9d34d1 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -4,6 +4,9 @@
>   */
> 
>  #include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -13,11 +16,6 @@
>  #include <linux/regmap.h>
>  #include <linux/slab.h>
> 
> -#include <linux/clk.h>
> -#include <linux/delay.h>
> -
> -#include <linux/dma-mapping.h>
> -
>  #include <sound/core.h>
>  #include <sound/pcm.h>
>  #include <sound/pcm_params.h>
> @@ -35,36 +33,36 @@
>  #define JZ_REG_AIC_CLK_DIV	0x30
>  #define JZ_REG_AIC_FIFO		0x34
> 
> -#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
> -#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
> -#define JZ_AIC_CONF_I2S BIT(4)
> -#define JZ_AIC_CONF_RESET BIT(3)
> -#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
> -#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
> -#define JZ_AIC_CONF_ENABLE BIT(0)
> -
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
> -#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
> -#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
> -#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
> -#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
> -#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
> +#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST	BIT(6)
> +#define JZ_AIC_CONF_INTERNAL_CODEC	BIT(5)
> +#define JZ_AIC_CONF_I2S			BIT(4)
> +#define JZ_AIC_CONF_RESET		BIT(3)
> +#define JZ_AIC_CONF_BIT_CLK_MASTER	BIT(2)
> +#define JZ_AIC_CONF_SYNC_CLK_MASTER	BIT(1)
> +#define JZ_AIC_CONF_ENABLE		BIT(0)
> +
> +#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE	GENMASK(21, 19)
> +#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE	GENMASK(18, 16)
> +#define JZ_AIC_CTRL_ENABLE_RX_DMA	BIT(15)
> +#define JZ_AIC_CTRL_ENABLE_TX_DMA	BIT(14)
> +#define JZ_AIC_CTRL_MONO_TO_STEREO	BIT(11)
> +#define JZ_AIC_CTRL_SWITCH_ENDIANNESS	BIT(10)
> +#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED	BIT(9)
>  #define JZ_AIC_CTRL_FLUSH		BIT(8)
> -#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
> -#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
> -#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
> -#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
> -#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
> -#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
> -#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
> -
> -#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
> -#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
> -#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
> -#define JZ_AIC_I2S_FMT_MSB BIT(0)
> -
> -#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
> +#define JZ_AIC_CTRL_ENABLE_ROR_INT	BIT(6)
> +#define JZ_AIC_CTRL_ENABLE_TUR_INT	BIT(5)
> +#define JZ_AIC_CTRL_ENABLE_RFS_INT	BIT(4)
> +#define JZ_AIC_CTRL_ENABLE_TFS_INT	BIT(3)
> +#define JZ_AIC_CTRL_ENABLE_LOOPBACK	BIT(2)
> +#define JZ_AIC_CTRL_ENABLE_PLAYBACK	BIT(1)
> +#define JZ_AIC_CTRL_ENABLE_CAPTURE	BIT(0)
> +
> +#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK	BIT(12)
> +#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK	BIT(13)
> +#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK	BIT(4)
> +#define JZ_AIC_I2S_FMT_MSB		BIT(0)
> +
> +#define JZ_AIC_I2S_STATUS_BUSY		BIT(2)
> 
>  struct i2s_soc_info {
>  	struct snd_soc_dai_driver *dai;
> --
> 2.35.1
> 



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

* Re: [PATCH 08/11] ASoC: jz4740-i2s: Align macro values and sort includes
@ 2022-07-07  9:42     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:42 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:27 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> Some purely cosmetic changes: line up all the macro values to
> make things easier to read and sort the includes alphabetically.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 66 
> +++++++++++++++++------------------
>  1 file changed, 32 insertions(+), 34 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index b8d2723c5f90..3a21ee9d34d1 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -4,6 +4,9 @@
>   */
> 
>  #include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -13,11 +16,6 @@
>  #include <linux/regmap.h>
>  #include <linux/slab.h>
> 
> -#include <linux/clk.h>
> -#include <linux/delay.h>
> -
> -#include <linux/dma-mapping.h>
> -
>  #include <sound/core.h>
>  #include <sound/pcm.h>
>  #include <sound/pcm_params.h>
> @@ -35,36 +33,36 @@
>  #define JZ_REG_AIC_CLK_DIV	0x30
>  #define JZ_REG_AIC_FIFO		0x34
> 
> -#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
> -#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
> -#define JZ_AIC_CONF_I2S BIT(4)
> -#define JZ_AIC_CONF_RESET BIT(3)
> -#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
> -#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
> -#define JZ_AIC_CONF_ENABLE BIT(0)
> -
> -#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE GENMASK(21, 19)
> -#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE GENMASK(18, 16)
> -#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
> -#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
> -#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
> -#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
> -#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
> +#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST	BIT(6)
> +#define JZ_AIC_CONF_INTERNAL_CODEC	BIT(5)
> +#define JZ_AIC_CONF_I2S			BIT(4)
> +#define JZ_AIC_CONF_RESET		BIT(3)
> +#define JZ_AIC_CONF_BIT_CLK_MASTER	BIT(2)
> +#define JZ_AIC_CONF_SYNC_CLK_MASTER	BIT(1)
> +#define JZ_AIC_CONF_ENABLE		BIT(0)
> +
> +#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE	GENMASK(21, 19)
> +#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE	GENMASK(18, 16)
> +#define JZ_AIC_CTRL_ENABLE_RX_DMA	BIT(15)
> +#define JZ_AIC_CTRL_ENABLE_TX_DMA	BIT(14)
> +#define JZ_AIC_CTRL_MONO_TO_STEREO	BIT(11)
> +#define JZ_AIC_CTRL_SWITCH_ENDIANNESS	BIT(10)
> +#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED	BIT(9)
>  #define JZ_AIC_CTRL_FLUSH		BIT(8)
> -#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
> -#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
> -#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
> -#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
> -#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
> -#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
> -#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
> -
> -#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
> -#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
> -#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
> -#define JZ_AIC_I2S_FMT_MSB BIT(0)
> -
> -#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
> +#define JZ_AIC_CTRL_ENABLE_ROR_INT	BIT(6)
> +#define JZ_AIC_CTRL_ENABLE_TUR_INT	BIT(5)
> +#define JZ_AIC_CTRL_ENABLE_RFS_INT	BIT(4)
> +#define JZ_AIC_CTRL_ENABLE_TFS_INT	BIT(3)
> +#define JZ_AIC_CTRL_ENABLE_LOOPBACK	BIT(2)
> +#define JZ_AIC_CTRL_ENABLE_PLAYBACK	BIT(1)
> +#define JZ_AIC_CTRL_ENABLE_CAPTURE	BIT(0)
> +
> +#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK	BIT(12)
> +#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK	BIT(13)
> +#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK	BIT(4)
> +#define JZ_AIC_I2S_FMT_MSB		BIT(0)
> +
> +#define JZ_AIC_I2S_STATUS_BUSY		BIT(2)
> 
>  struct i2s_soc_info {
>  	struct snd_soc_dai_driver *dai;
> --
> 2.35.1
> 



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

* Re: [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:47     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:47 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:28 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> On some Ingenic SoCs, such as the X1000, there is a programmable
> divider used to generate the I2S system clock from a PLL, rather
> than a fixed PLL/2 clock. It doesn't make much sense to call the
> clock "pll half" on those SoCs, so the clock name should really be
> a SoC-dependent value.

Do you really need the .set_sysclk() callback? I've never seen it used 
on any of the Ingenic boards I have, so to me it's pretty much dead 
code. Unless you do use this callback, I'd suggest to drop this patch 
until you do need it.

Cheers,
-Paul

> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 3a21ee9d34d1..80b355d715ce 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -71,6 +71,8 @@ struct i2s_soc_info {
>  	struct reg_field field_tx_fifo_thresh;
>  	struct reg_field field_i2sdiv_capture;
>  	struct reg_field field_i2sdiv_playback;
> +
> +	const char *pll_clk_name;
>  };
> 
>  struct jz4740_i2s {
> @@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct 
> snd_soc_dai *dai, int clk_id,
>  		clk_set_parent(i2s->clk_i2s, parent);
>  		break;
>  	case JZ4740_I2S_CLKSRC_PLL:
> -		parent = clk_get(NULL, "pll half");
> +		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
>  		if (IS_ERR(parent))
>  			return PTR_ERR(parent);
>  		clk_set_parent(i2s->clk_i2s, parent);
> @@ -387,6 +389,7 @@ static const struct i2s_soc_info 
> jz4740_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
> @@ -395,6 +398,7 @@ static const struct i2s_soc_info 
> jz4760_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
> @@ -421,6 +425,7 @@ static const struct i2s_soc_info 
> jz4770_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
> @@ -429,6 +434,7 @@ static const struct i2s_soc_info 
> jz4780_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct snd_soc_component_driver jz4740_i2s_component = {
> --
> 2.35.1
> 



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

* Re: [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
@ 2022-07-07  9:47     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:47 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:28 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> On some Ingenic SoCs, such as the X1000, there is a programmable
> divider used to generate the I2S system clock from a PLL, rather
> than a fixed PLL/2 clock. It doesn't make much sense to call the
> clock "pll half" on those SoCs, so the clock name should really be
> a SoC-dependent value.

Do you really need the .set_sysclk() callback? I've never seen it used 
on any of the Ingenic boards I have, so to me it's pretty much dead 
code. Unless you do use this callback, I'd suggest to drop this patch 
until you do need it.

Cheers,
-Paul

> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 3a21ee9d34d1..80b355d715ce 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -71,6 +71,8 @@ struct i2s_soc_info {
>  	struct reg_field field_tx_fifo_thresh;
>  	struct reg_field field_i2sdiv_capture;
>  	struct reg_field field_i2sdiv_playback;
> +
> +	const char *pll_clk_name;
>  };
> 
>  struct jz4740_i2s {
> @@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct 
> snd_soc_dai *dai, int clk_id,
>  		clk_set_parent(i2s->clk_i2s, parent);
>  		break;
>  	case JZ4740_I2S_CLKSRC_PLL:
> -		parent = clk_get(NULL, "pll half");
> +		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
>  		if (IS_ERR(parent))
>  			return PTR_ERR(parent);
>  		clk_set_parent(i2s->clk_i2s, parent);
> @@ -387,6 +389,7 @@ static const struct i2s_soc_info 
> jz4740_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
> @@ -395,6 +398,7 @@ static const struct i2s_soc_info 
> jz4760_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
> @@ -421,6 +425,7 @@ static const struct i2s_soc_info 
> jz4770_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
> @@ -429,6 +434,7 @@ static const struct i2s_soc_info 
> jz4780_i2s_soc_info = {
>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
> +	.pll_clk_name		= "pll half",
>  };
> 
>  static const struct snd_soc_component_driver jz4740_i2s_component = {
> --
> 2.35.1
> 



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

* Re: [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:53     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:29 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The audio controller on JZ47xx SoCs supports 20- and 24-bit
> samples coming from memory. Allow those formats to be used
> with the I2S driver.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 80b355d715ce..ee99c5e781ec 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	case SNDRV_PCM_FORMAT_S8:
>  		sample_size = 0;
>  		break;
> -	case SNDRV_PCM_FORMAT_S16:
> +	case SNDRV_PCM_FORMAT_S16_LE:
>  		sample_size = 1;
>  		break;
> +	case SNDRV_PCM_FORMAT_S20_LE:
> +		sample_size = 3;
> +		break;
> +	case SNDRV_PCM_FORMAT_S24_LE:
> +		sample_size = 4;
> +		break;

Did you test these? It is unclear to me, looking at the JZ4740 PM, if 
the 18-bit, 20-bit and 24-bit samples are in 4 bytes or 3 bytes.

Cheers,
-Paul

>  	default:
>  		return -EINVAL;
>  	}
> @@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops 
> jz4740_i2s_dai_ops = {
>  };
> 
>  #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
> -		SNDRV_PCM_FMTBIT_S16_LE)
> +			 SNDRV_PCM_FMTBIT_S16_LE | \
> +			 SNDRV_PCM_FMTBIT_S20_LE | \
> +			 SNDRV_PCM_FMTBIT_S24_LE)
> 
>  static struct snd_soc_dai_driver jz4740_i2s_dai = {
>  	.probe = jz4740_i2s_dai_probe,
> --
> 2.35.1
> 



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

* Re: [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
@ 2022-07-07  9:53     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:29 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The audio controller on JZ47xx SoCs supports 20- and 24-bit
> samples coming from memory. Allow those formats to be used
> with the I2S driver.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
> ---
>  sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index 80b355d715ce..ee99c5e781ec 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct 
> snd_pcm_substream *substream,
>  	case SNDRV_PCM_FORMAT_S8:
>  		sample_size = 0;
>  		break;
> -	case SNDRV_PCM_FORMAT_S16:
> +	case SNDRV_PCM_FORMAT_S16_LE:
>  		sample_size = 1;
>  		break;
> +	case SNDRV_PCM_FORMAT_S20_LE:
> +		sample_size = 3;
> +		break;
> +	case SNDRV_PCM_FORMAT_S24_LE:
> +		sample_size = 4;
> +		break;

Did you test these? It is unclear to me, looking at the JZ4740 PM, if 
the 18-bit, 20-bit and 24-bit samples are in 4 bytes or 3 bytes.

Cheers,
-Paul

>  	default:
>  		return -EINVAL;
>  	}
> @@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops 
> jz4740_i2s_dai_ops = {
>  };
> 
>  #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
> -		SNDRV_PCM_FMTBIT_S16_LE)
> +			 SNDRV_PCM_FMTBIT_S16_LE | \
> +			 SNDRV_PCM_FMTBIT_S20_LE | \
> +			 SNDRV_PCM_FMTBIT_S24_LE)
> 
>  static struct snd_soc_dai_driver jz4740_i2s_dai = {
>  	.probe = jz4740_i2s_dai_probe,
> --
> 2.35.1
> 



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

* Re: [PATCH 11/11] ASoC: jz4740-i2s: Support continuous sample rate
  2022-07-06 21:13   ` Aidan MacDonald
@ 2022-07-07  9:53     ` Paul Cercueil
  -1 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel



Le mer., juil. 6 2022 at 22:13:30 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The I2S controller on JZ47xx SoCs doesn't impose restrictions on
> sample rate and the driver doesn't make any assumptions about it,
> so the DAI should advertise a continuous sample rate range.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index ee99c5e781ec..053697c7f19e 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -378,13 +378,13 @@ static struct snd_soc_dai_driver jz4740_i2s_dai 
> = {
>  	.playback = {
>  		.channels_min = 1,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.capture = {
>  		.channels_min = 2,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.symmetric_rate = 1,
> @@ -415,13 +415,13 @@ static struct snd_soc_dai_driver jz4770_i2s_dai 
> = {
>  	.playback = {
>  		.channels_min = 1,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.capture = {
>  		.channels_min = 2,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.ops = &jz4740_i2s_dai_ops,
> --
> 2.35.1
> 



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

* Re: [PATCH 11/11] ASoC: jz4740-i2s: Support continuous sample rate
@ 2022-07-07  9:53     ` Paul Cercueil
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Cercueil @ 2022-07-07  9:53 UTC (permalink / raw)
  To: Aidan MacDonald
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie



Le mer., juil. 6 2022 at 22:13:30 +0100, Aidan MacDonald 
<aidanmacdonald.0x0@gmail.com> a écrit :
> The I2S controller on JZ47xx SoCs doesn't impose restrictions on
> sample rate and the driver doesn't make any assumptions about it,
> so the DAI should advertise a continuous sample rate range.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>

Acked-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  sound/soc/jz4740/jz4740-i2s.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/soc/jz4740/jz4740-i2s.c 
> b/sound/soc/jz4740/jz4740-i2s.c
> index ee99c5e781ec..053697c7f19e 100644
> --- a/sound/soc/jz4740/jz4740-i2s.c
> +++ b/sound/soc/jz4740/jz4740-i2s.c
> @@ -378,13 +378,13 @@ static struct snd_soc_dai_driver jz4740_i2s_dai 
> = {
>  	.playback = {
>  		.channels_min = 1,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.capture = {
>  		.channels_min = 2,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.symmetric_rate = 1,
> @@ -415,13 +415,13 @@ static struct snd_soc_dai_driver jz4770_i2s_dai 
> = {
>  	.playback = {
>  		.channels_min = 1,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.capture = {
>  		.channels_min = 2,
>  		.channels_max = 2,
> -		.rates = SNDRV_PCM_RATE_8000_48000,
> +		.rates = SNDRV_PCM_RATE_CONTINUOUS,
>  		.formats = JZ4740_I2S_FMTS,
>  	},
>  	.ops = &jz4740_i2s_dai_ops,
> --
> 2.35.1
> 



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

* Re: (subset) [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s
  2022-07-06 21:13 ` Aidan MacDonald
@ 2022-07-07 13:54   ` Mark Brown
  -1 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2022-07-07 13:54 UTC (permalink / raw)
  To: paul, aidanmacdonald.0x0, tiwai, lgirdwood, perex
  Cc: linux-mips, linux-kernel, alsa-devel

On Wed, 6 Jul 2022 22:13:19 +0100, Aidan MacDonald wrote:
> This series is a preparatory cleanup of the jz4740-i2s driver before
> adding support for a new SoC. The last two patches lift unnecessary
> restrictions on sample rates and formats -- the existing ones appear
> to be derived from the limitations of the JZ4740's internal codec and
> don't reflect the actual capabilities of the I2S controller.
> 
> I'm unable to test the series on any JZ47xx SoCs, but I have tested
> on an X1000 (which is the SoC I'll be adding in a followup series).
> 
> [...]

Applied to

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

Thanks!

[01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
        commit: 98356c89d44dac838dfbab02975645d828de3099
[02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
        commit: 8a7691010992886290b340a1ba943067c2e70f85

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

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

* Re: (subset) [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s
@ 2022-07-07 13:54   ` Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2022-07-07 13:54 UTC (permalink / raw)
  To: paul, aidanmacdonald.0x0, tiwai, lgirdwood, perex
  Cc: alsa-devel, linux-mips, linux-kernel

On Wed, 6 Jul 2022 22:13:19 +0100, Aidan MacDonald wrote:
> This series is a preparatory cleanup of the jz4740-i2s driver before
> adding support for a new SoC. The last two patches lift unnecessary
> restrictions on sample rates and formats -- the existing ones appear
> to be derived from the limitations of the JZ4740's internal codec and
> don't reflect the actual capabilities of the I2S controller.
> 
> I'm unable to test the series on any JZ47xx SoCs, but I have tested
> on an X1000 (which is the SoC I'll be adding in a followup series).
> 
> [...]

Applied to

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

Thanks!

[01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency
        commit: 98356c89d44dac838dfbab02975645d828de3099
[02/11] ASoC: jz4740-i2s: Refactor DMA channel setup
        commit: 8a7691010992886290b340a1ba943067c2e70f85

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

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

* Re: [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
  2022-07-06 21:53     ` Paul Cercueil
@ 2022-07-07 14:12       ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:12 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel


Paul Cercueil <paul@crapouillou.net> writes:

> Hi Aidan,
>
> Le mer., juil. 6 2022 at 22:13:22 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> Using regmap for accessing the AIC registers makes the driver a
>> little easier to read, and later refactors can take advantage of
>> regmap APIs to further simplify the driver.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/Kconfig      |  1 +
>>  sound/soc/jz4740/jz4740-i2s.c | 99 +++++++++++++++--------------------
>>  2 files changed, 42 insertions(+), 58 deletions(-)
>> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
>> index e72f826062e9..dd3b4507fbe6 100644
>> --- a/sound/soc/jz4740/Kconfig
>> +++ b/sound/soc/jz4740/Kconfig
>> @@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
>>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>>  	depends on MIPS || COMPILE_TEST
>>  	depends on HAS_IOMEM
>> +	select REGMAP_MMIO
>>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>>  	help
>>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index ecd8df70d39c..66a901f56392 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -9,6 +9,7 @@
>>  #include <linux/module.h>
>>  #include <linux/mod_devicetable.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>>  #include <linux/slab.h>
>>  #include <linux/clk.h>
>> @@ -94,7 +95,7 @@ struct i2s_soc_info {
>>  struct jz4740_i2s {
>>  	struct resource *mem;
>> -	void __iomem *base;
>> +	struct regmap *regmap;
>>  	struct clk *clk_aic;
>>  	struct clk *clk_i2s;
>> @@ -105,39 +106,24 @@ struct jz4740_i2s {
>>  	const struct i2s_soc_info *soc_info;
>>  };
>> -static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
>> -	unsigned int reg)
>> -{
>> -	return readl(i2s->base + reg);
>> -}
>> -
>> -static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
>> -	unsigned int reg, uint32_t value)
>> -{
>> -	writel(value, i2s->base + reg);
>> -}
>> -
>>  static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf, ctrl;
>>  	int ret;
>>  	if (snd_soc_dai_active(dai))
>>  		return 0;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> -	ctrl |= JZ_AIC_CTRL_FLUSH;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> +	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
>> +			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);
>
> I don't think you need regmap_write_bits() here, since there is no cache to
> bypass. You could use regmap_update_bits(), or even better, regmap_set_bits().
>

write_bits isn't _exactly_ just a cache bypass operation -- it means
"write the register even if the value is the same as what was read."
An update_bits doesn't necessarily perform a register write, even if
there is no cache and the register is volatile.

The distinction shouldn't matter here, since the flush bit is supposed
to be self-clearing. So I might as well use regmap_set_bits().

Also: I just noticed this will need to be a regmap field. It seems that
all SoCs newer than jz4740 have separate transmit/receive flush bits.
At least the JZ4760, JZ4780, and X1000 manuals say as much. Not sure
about the JZ4770 since I don't have any documentation for that SoC.

>>  	ret = clk_prepare_enable(i2s->clk_i2s);
>>  	if (ret)
>>  		return ret;
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -	conf |= JZ_AIC_CONF_ENABLE;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>
> Use regmap_set_bits() when you want to set all the bits of the mask.
>
>>  	return 0;
>>  }
>> @@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct
>> snd_pcm_substream *substream,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf;
>>  	if (snd_soc_dai_active(dai))
>>  		return;
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -	conf &= ~JZ_AIC_CONF_ENABLE;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +			   JZ_AIC_CONF_ENABLE, 0);
>
> Use regmap_clear_bits() when you want to clear all bits of the mask.
>
> Otherwise, looks fairly good!
>
> Cheers,
> -Paul
>

Thanks, I didn't know about set/clear bits but that'll make it even
simpler.

>>  	clk_disable_unprepare(i2s->clk_i2s);
>>  }
>> @@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream
>> *substream, int cmd,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -
>> -	uint32_t ctrl;
>>  	uint32_t mask;
>>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>> @@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream
>> *substream, int cmd,
>>  	else
>>  		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> -
>>  	switch (cmd) {
>>  	case SNDRV_PCM_TRIGGER_START:
>>  	case SNDRV_PCM_TRIGGER_RESUME:
>>  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>> -		ctrl |= mask;
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
>>  		break;
>>  	case SNDRV_PCM_TRIGGER_STOP:
>>  	case SNDRV_PCM_TRIGGER_SUSPEND:
>>  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>> -		ctrl &= ~mask;
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
>>  		break;
>>  	default:
>>  		return -EINVAL;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> -
>>  	return 0;
>>  }
>>  static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -
>> -	uint32_t format = 0;
>> -	uint32_t conf;
>> -
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -
>> -	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
>> +	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
>> +				       JZ_AIC_CONF_SYNC_CLK_MASTER;
>> +	unsigned int conf = 0, format = 0;
>>  	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
>>  	case SND_SOC_DAIFMT_BP_FP:
>> @@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai,
>> unsigned int fmt)
>>  		return -EINVAL;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
>>  	return 0;
>>  }
>> @@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  	uint32_t ctrl, div_reg;
>>  	int div;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> +	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
>> +	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
>> -	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
>>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
>>  	switch (params_format(params)) {
>> @@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  		}
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
>>  	return 0;
>>  }
>> @@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai
>> *dai, int clk_id,
>>  static int jz4740_i2s_suspend(struct snd_soc_component *component)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
>> -	uint32_t conf;
>>  	if (snd_soc_component_active(component)) {
>> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -		conf &= ~JZ_AIC_CONF_ENABLE;
>> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +				   JZ_AIC_CONF_ENABLE, 0);
>>  		clk_disable_unprepare(i2s->clk_i2s);
>>  	}
>> @@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct snd_soc_component
>> *component)
>>  static int jz4740_i2s_resume(struct snd_soc_component *component)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
>> -	uint32_t conf;
>>  	int ret;
>>  	ret = clk_prepare_enable(i2s->clk_aic);
>> @@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct snd_soc_component
>> *component)
>>  			return ret;
>>  		}
>> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -		conf |= JZ_AIC_CONF_ENABLE;
>> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>>  	}
>>  	return 0;
>> @@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>>  			JZ_AIC_CONF_INTERNAL_CODEC;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
>>  	return 0;
>>  }
>> @@ -495,11 +465,19 @@ static const struct of_device_id jz4740_of_matches[] =
>> {
>>  };
>>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
>> +static const struct regmap_config jz4740_i2s_regmap_config = {
>> +	.reg_bits	= 32,
>> +	.reg_stride	= 4,
>> +	.val_bits	= 32,
>> +	.max_register	= JZ_REG_AIC_FIFO,
>> +};
>> +
>>  static int jz4740_i2s_dev_probe(struct platform_device *pdev)
>>  {
>>  	struct device *dev = &pdev->dev;
>>  	struct jz4740_i2s *i2s;
>>  	struct resource *mem;
>> +	void __iomem *regs;
>>  	int ret;
>>  	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
>> @@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	i2s->soc_info = device_get_match_data(dev);
>> -	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
>> -	if (IS_ERR(i2s->base))
>> -		return PTR_ERR(i2s->base);
>> +	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
>> +	if (IS_ERR(regs))
>> +		return PTR_ERR(regs);
>>  	i2s->playback_dma_data.maxburst = 16;
>>  	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
>> @@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	if (IS_ERR(i2s->clk_i2s))
>>  		return PTR_ERR(i2s->clk_i2s);
>> +	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> +					    &jz4740_i2s_regmap_config);
>> +	if (IS_ERR(i2s->regmap))
>> +		return PTR_ERR(i2s->regmap);
>> +
>>  	platform_set_drvdata(pdev, i2s);
>>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API
@ 2022-07-07 14:12       ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:12 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie


Paul Cercueil <paul@crapouillou.net> writes:

> Hi Aidan,
>
> Le mer., juil. 6 2022 at 22:13:22 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> Using regmap for accessing the AIC registers makes the driver a
>> little easier to read, and later refactors can take advantage of
>> regmap APIs to further simplify the driver.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/Kconfig      |  1 +
>>  sound/soc/jz4740/jz4740-i2s.c | 99 +++++++++++++++--------------------
>>  2 files changed, 42 insertions(+), 58 deletions(-)
>> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
>> index e72f826062e9..dd3b4507fbe6 100644
>> --- a/sound/soc/jz4740/Kconfig
>> +++ b/sound/soc/jz4740/Kconfig
>> @@ -3,6 +3,7 @@ config SND_JZ4740_SOC_I2S
>>  	tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
>>  	depends on MIPS || COMPILE_TEST
>>  	depends on HAS_IOMEM
>> +	select REGMAP_MMIO
>>  	select SND_SOC_GENERIC_DMAENGINE_PCM
>>  	help
>>  	  Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index ecd8df70d39c..66a901f56392 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -9,6 +9,7 @@
>>  #include <linux/module.h>
>>  #include <linux/mod_devicetable.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>>  #include <linux/slab.h>
>>  #include <linux/clk.h>
>> @@ -94,7 +95,7 @@ struct i2s_soc_info {
>>  struct jz4740_i2s {
>>  	struct resource *mem;
>> -	void __iomem *base;
>> +	struct regmap *regmap;
>>  	struct clk *clk_aic;
>>  	struct clk *clk_i2s;
>> @@ -105,39 +106,24 @@ struct jz4740_i2s {
>>  	const struct i2s_soc_info *soc_info;
>>  };
>> -static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
>> -	unsigned int reg)
>> -{
>> -	return readl(i2s->base + reg);
>> -}
>> -
>> -static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
>> -	unsigned int reg, uint32_t value)
>> -{
>> -	writel(value, i2s->base + reg);
>> -}
>> -
>>  static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf, ctrl;
>>  	int ret;
>>  	if (snd_soc_dai_active(dai))
>>  		return 0;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> -	ctrl |= JZ_AIC_CTRL_FLUSH;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> +	regmap_write_bits(i2s->regmap, JZ_REG_AIC_CTRL,
>> +			  JZ_AIC_CTRL_FLUSH, JZ_AIC_CTRL_FLUSH);
>
> I don't think you need regmap_write_bits() here, since there is no cache to
> bypass. You could use regmap_update_bits(), or even better, regmap_set_bits().
>

write_bits isn't _exactly_ just a cache bypass operation -- it means
"write the register even if the value is the same as what was read."
An update_bits doesn't necessarily perform a register write, even if
there is no cache and the register is volatile.

The distinction shouldn't matter here, since the flush bit is supposed
to be self-clearing. So I might as well use regmap_set_bits().

Also: I just noticed this will need to be a regmap field. It seems that
all SoCs newer than jz4740 have separate transmit/receive flush bits.
At least the JZ4760, JZ4780, and X1000 manuals say as much. Not sure
about the JZ4770 since I don't have any documentation for that SoC.

>>  	ret = clk_prepare_enable(i2s->clk_i2s);
>>  	if (ret)
>>  		return ret;
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -	conf |= JZ_AIC_CONF_ENABLE;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +			   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>
> Use regmap_set_bits() when you want to set all the bits of the mask.
>
>>  	return 0;
>>  }
>> @@ -146,14 +132,12 @@ static void jz4740_i2s_shutdown(struct
>> snd_pcm_substream *substream,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf;
>>  	if (snd_soc_dai_active(dai))
>>  		return;
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -	conf &= ~JZ_AIC_CONF_ENABLE;
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +			   JZ_AIC_CONF_ENABLE, 0);
>
> Use regmap_clear_bits() when you want to clear all bits of the mask.
>
> Otherwise, looks fairly good!
>
> Cheers,
> -Paul
>

Thanks, I didn't know about set/clear bits but that'll make it even
simpler.

>>  	clk_disable_unprepare(i2s->clk_i2s);
>>  }
>> @@ -162,8 +146,6 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream
>> *substream, int cmd,
>>  	struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -
>> -	uint32_t ctrl;
>>  	uint32_t mask;
>>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
>> @@ -171,38 +153,30 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream
>> *substream, int cmd,
>>  	else
>>  		mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> -
>>  	switch (cmd) {
>>  	case SNDRV_PCM_TRIGGER_START:
>>  	case SNDRV_PCM_TRIGGER_RESUME:
>>  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>> -		ctrl |= mask;
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, mask);
>>  		break;
>>  	case SNDRV_PCM_TRIGGER_STOP:
>>  	case SNDRV_PCM_TRIGGER_SUSPEND:
>>  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>> -		ctrl &= ~mask;
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CTRL, mask, 0);
>>  		break;
>>  	default:
>>  		return -EINVAL;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> -
>>  	return 0;
>>  }
>>  static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -
>> -	uint32_t format = 0;
>> -	uint32_t conf;
>> -
>> -	conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -
>> -	conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
>> +	const unsigned int conf_mask = JZ_AIC_CONF_BIT_CLK_MASTER |
>> +				       JZ_AIC_CONF_SYNC_CLK_MASTER;
>> +	unsigned int conf = 0, format = 0;
>>  	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
>>  	case SND_SOC_DAIFMT_BP_FP:
>> @@ -238,8 +212,8 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai,
>> unsigned int fmt)
>>  		return -EINVAL;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
>> +	regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF, conf_mask, conf);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_I2S_FMT, format);
>>  	return 0;
>>  }
>> @@ -252,9 +226,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  	uint32_t ctrl, div_reg;
>>  	int div;
>> -	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
>> +	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
>> +	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
>> -	div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
>>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
>>  	switch (params_format(params)) {
>> @@ -291,8 +265,8 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  		}
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
>>  	return 0;
>>  }
>> @@ -329,12 +303,10 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai
>> *dai, int clk_id,
>>  static int jz4740_i2s_suspend(struct snd_soc_component *component)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
>> -	uint32_t conf;
>>  	if (snd_soc_component_active(component)) {
>> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -		conf &= ~JZ_AIC_CONF_ENABLE;
>> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +				   JZ_AIC_CONF_ENABLE, 0);
>>  		clk_disable_unprepare(i2s->clk_i2s);
>>  	}
>> @@ -347,7 +319,6 @@ static int jz4740_i2s_suspend(struct snd_soc_component
>> *component)
>>  static int jz4740_i2s_resume(struct snd_soc_component *component)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
>> -	uint32_t conf;
>>  	int ret;
>>  	ret = clk_prepare_enable(i2s->clk_aic);
>> @@ -361,9 +332,8 @@ static int jz4740_i2s_resume(struct snd_soc_component
>> *component)
>>  			return ret;
>>  		}
>> -		conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
>> -		conf |= JZ_AIC_CONF_ENABLE;
>> -		jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +		regmap_update_bits(i2s->regmap, JZ_REG_AIC_CONF,
>> +				   JZ_AIC_CONF_ENABLE, JZ_AIC_CONF_ENABLE);
>>  	}
>>  	return 0;
>> @@ -396,8 +366,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>>  			JZ_AIC_CONF_INTERNAL_CODEC;
>>  	}
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> -	jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
>>  	return 0;
>>  }
>> @@ -495,11 +465,19 @@ static const struct of_device_id jz4740_of_matches[] =
>> {
>>  };
>>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
>> +static const struct regmap_config jz4740_i2s_regmap_config = {
>> +	.reg_bits	= 32,
>> +	.reg_stride	= 4,
>> +	.val_bits	= 32,
>> +	.max_register	= JZ_REG_AIC_FIFO,
>> +};
>> +
>>  static int jz4740_i2s_dev_probe(struct platform_device *pdev)
>>  {
>>  	struct device *dev = &pdev->dev;
>>  	struct jz4740_i2s *i2s;
>>  	struct resource *mem;
>> +	void __iomem *regs;
>>  	int ret;
>>  	i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
>> @@ -508,9 +486,9 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	i2s->soc_info = device_get_match_data(dev);
>> -	i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
>> -	if (IS_ERR(i2s->base))
>> -		return PTR_ERR(i2s->base);
>> +	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
>> +	if (IS_ERR(regs))
>> +		return PTR_ERR(regs);
>>  	i2s->playback_dma_data.maxburst = 16;
>>  	i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO;
>> @@ -526,6 +504,11 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	if (IS_ERR(i2s->clk_i2s))
>>  		return PTR_ERR(i2s->clk_i2s);
>> +	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> +					    &jz4740_i2s_regmap_config);
>> +	if (IS_ERR(i2s->regmap))
>> +		return PTR_ERR(i2s->regmap);
>> +
>>  	platform_set_drvdata(pdev, i2s);
>>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
  2022-07-07  9:36     ` Paul Cercueil
@ 2022-07-07 14:13       ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:13 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:23 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> The differences between register fields on different SoC versions
>> can be abstracted away using the regmap field API. This is easier
>> to understand and extend than comparisons based on the version ID.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 100 ++++++++++++++++++++++++----------
>>  1 file changed, 72 insertions(+), 28 deletions(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 66a901f56392..cbb89f724f64 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
>>  struct i2s_soc_info {
>>  	enum jz47xx_i2s_version version;
>>  	struct snd_soc_dai_driver *dai;
>> +
>> +	struct reg_field field_rx_fifo_thresh;
>> +	struct reg_field field_tx_fifo_thresh;
>> +	struct reg_field field_i2sdiv_capture;
>> +	struct reg_field field_i2sdiv_playback;
>>  };
>>  struct jz4740_i2s {
>>  	struct resource *mem;
>>  	struct regmap *regmap;
>> +	struct regmap_field *field_rx_fifo_thresh;
>> +	struct regmap_field *field_tx_fifo_thresh;
>> +	struct regmap_field *field_i2sdiv_capture;
>> +	struct regmap_field *field_i2sdiv_playback;
>> +
>>  	struct clk *clk_aic;
>>  	struct clk *clk_i2s;
>> @@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct
>> snd_pcm_substream *substream,
>>  	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> +	struct regmap_field *div_field;
>>  	unsigned int sample_size;
>> -	uint32_t ctrl, div_reg;
>> +	uint32_t ctrl;
>>  	int div;
>>  	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
>> -	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
>>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
>> @@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct
>> snd_pcm_substream *substream,
>>  		else
>>  			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
>> -		div_reg &= ~I2SDIV_DV_MASK;
>> -		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
>> +		div_field = i2s->field_i2sdiv_playback;
>>  	} else {
>>  		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
>>  		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
>> -		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
>> -			div_reg &= ~I2SDIV_IDV_MASK;
>> -			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
>> -		} else {
>> -			div_reg &= ~I2SDIV_DV_MASK;
>> -			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
>> -		}
>> +		div_field = i2s->field_i2sdiv_capture;
>>  	}
>>  	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
>> -	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
>> +	regmap_field_write(div_field, div - 1);
>>  	return 0;
>>  }
>> @@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct snd_soc_component
>> *component)
>>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf;
>>  	int ret;
>>  	ret = clk_prepare_enable(i2s->clk_aic);
>> @@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai
>> *dai)
>>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>>  		&i2s->capture_dma_data);
>> -	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
>> -		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
>> -			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
>> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> -			JZ_AIC_CONF_I2S |
>> -			JZ_AIC_CONF_INTERNAL_CODEC;
>> -	} else {
>> -		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
>> -			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
>
> I believe you can remove these macros completely now that they are unused. Same
> goes for I2S_IDV_MASK, etc.
>
> Cheers,
> -Paul
>

Alright, I'll squash the macro and version ID removals into this patch.

>> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> -			JZ_AIC_CONF_I2S |
>> -			JZ_AIC_CONF_INTERNAL_CODEC;
>> -	}
>> -
>>  	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> -	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
>> +
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
>> +		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> +		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
>> +
>> +	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
>> +	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
>>  	return 0;
>>  }
>> @@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
>>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4740,
>>  	.dai = &jz4740_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4760,
>>  	.dai = &jz4740_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
>> @@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
>>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4770,
>>  	.dai = &jz4770_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4780,
>>  	.dai = &jz4770_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct snd_soc_component_driver jz4740_i2s_component = {
>> @@ -465,6 +475,36 @@ static const struct of_device_id jz4740_of_matches[] = {
>>  };
>>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
>> +static int jz4740_i2s_init_regmap_fields(struct device *dev,
>> +					 struct jz4740_i2s *i2s)
>> +{
>> +	i2s->field_rx_fifo_thresh =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_rx_fifo_thresh);
>> +	if (IS_ERR(i2s->field_rx_fifo_thresh))
>> +		return PTR_ERR(i2s->field_rx_fifo_thresh);
>> +
>> +	i2s->field_tx_fifo_thresh =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_tx_fifo_thresh);
>> +	if (IS_ERR(i2s->field_tx_fifo_thresh))
>> +		return PTR_ERR(i2s->field_tx_fifo_thresh);
>> +
>> +	i2s->field_i2sdiv_capture =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_i2sdiv_capture);
>> +	if (IS_ERR(i2s->field_i2sdiv_capture))
>> +		return PTR_ERR(i2s->field_i2sdiv_capture);
>> +
>> +	i2s->field_i2sdiv_playback =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_i2sdiv_playback);
>> +	if (IS_ERR(i2s->field_i2sdiv_playback))
>> +		return PTR_ERR(i2s->field_i2sdiv_playback);
>> +
>> +	return 0;
>> +}
>> +
>>  static const struct regmap_config jz4740_i2s_regmap_config = {
>>  	.reg_bits	= 32,
>>  	.reg_stride	= 4,
>> @@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	if (IS_ERR(i2s->regmap))
>>  		return PTR_ERR(i2s->regmap);
>> +	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
>> +	if (ret)
>> +		return ret;
>> +
>>  	platform_set_drvdata(pdev, i2s);
>>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields
@ 2022-07-07 14:13       ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:13 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:23 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> The differences between register fields on different SoC versions
>> can be abstracted away using the regmap field API. This is easier
>> to understand and extend than comparisons based on the version ID.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 100 ++++++++++++++++++++++++----------
>>  1 file changed, 72 insertions(+), 28 deletions(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 66a901f56392..cbb89f724f64 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -91,12 +91,22 @@ enum jz47xx_i2s_version {
>>  struct i2s_soc_info {
>>  	enum jz47xx_i2s_version version;
>>  	struct snd_soc_dai_driver *dai;
>> +
>> +	struct reg_field field_rx_fifo_thresh;
>> +	struct reg_field field_tx_fifo_thresh;
>> +	struct reg_field field_i2sdiv_capture;
>> +	struct reg_field field_i2sdiv_playback;
>>  };
>>  struct jz4740_i2s {
>>  	struct resource *mem;
>>  	struct regmap *regmap;
>> +	struct regmap_field *field_rx_fifo_thresh;
>> +	struct regmap_field *field_tx_fifo_thresh;
>> +	struct regmap_field *field_i2sdiv_capture;
>> +	struct regmap_field *field_i2sdiv_playback;
>> +
>>  	struct clk *clk_aic;
>>  	struct clk *clk_i2s;
>> @@ -222,12 +232,12 @@ static int jz4740_i2s_hw_params(struct
>> snd_pcm_substream *substream,
>>  	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> +	struct regmap_field *div_field;
>>  	unsigned int sample_size;
>> -	uint32_t ctrl, div_reg;
>> +	uint32_t ctrl;
>>  	int div;
>>  	regmap_read(i2s->regmap, JZ_REG_AIC_CTRL, &ctrl);
>> -	regmap_read(i2s->regmap, JZ_REG_AIC_CLK_DIV, &div_reg);
>>  	div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
>> @@ -250,23 +260,16 @@ static int jz4740_i2s_hw_params(struct
>> snd_pcm_substream *substream,
>>  		else
>>  			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
>> -		div_reg &= ~I2SDIV_DV_MASK;
>> -		div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
>> +		div_field = i2s->field_i2sdiv_playback;
>>  	} else {
>>  		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
>>  		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
>> -		if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
>> -			div_reg &= ~I2SDIV_IDV_MASK;
>> -			div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
>> -		} else {
>> -			div_reg &= ~I2SDIV_DV_MASK;
>> -			div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
>> -		}
>> +		div_field = i2s->field_i2sdiv_capture;
>>  	}
>>  	regmap_write(i2s->regmap, JZ_REG_AIC_CTRL, ctrl);
>> -	regmap_write(i2s->regmap, JZ_REG_AIC_CLK_DIV, div_reg);
>> +	regmap_field_write(div_field, div - 1);
>>  	return 0;
>>  }
>> @@ -342,7 +345,6 @@ static int jz4740_i2s_resume(struct snd_soc_component
>> *component)
>>  static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
>>  {
>>  	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> -	uint32_t conf;
>>  	int ret;
>>  	ret = clk_prepare_enable(i2s->clk_aic);
>> @@ -352,22 +354,14 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai
>> *dai)
>>  	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
>>  		&i2s->capture_dma_data);
>> -	if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
>> -		conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
>> -			(8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
>> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> -			JZ_AIC_CONF_I2S |
>> -			JZ_AIC_CONF_INTERNAL_CODEC;
>> -	} else {
>> -		conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
>> -			(8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
>
> I believe you can remove these macros completely now that they are unused. Same
> goes for I2S_IDV_MASK, etc.
>
> Cheers,
> -Paul
>

Alright, I'll squash the macro and version ID removals into this patch.

>> -			JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> -			JZ_AIC_CONF_I2S |
>> -			JZ_AIC_CONF_INTERNAL_CODEC;
>> -	}
>> -
>>  	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
>> -	regmap_write(i2s->regmap, JZ_REG_AIC_CONF, conf);
>> +
>> +	regmap_write(i2s->regmap, JZ_REG_AIC_CONF,
>> +		     JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
>> +		     JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC);
>> +
>> +	regmap_field_write(i2s->field_rx_fifo_thresh, 7);
>> +	regmap_field_write(i2s->field_tx_fifo_thresh, 8);
>>  	return 0;
>>  }
>> @@ -414,11 +408,19 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
>>  static const struct i2s_soc_info jz4740_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4740,
>>  	.dai = &jz4740_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 12, 15),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4760,
>>  	.dai = &jz4740_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
>> @@ -442,11 +444,19 @@ static struct snd_soc_dai_driver jz4770_i2s_dai = {
>>  static const struct i2s_soc_info jz4770_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4770,
>>  	.dai = &jz4770_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>>  	.version = JZ_I2S_JZ4780,
>>  	.dai = &jz4770_i2s_dai,
>> +	.field_rx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 24, 27),
>> +	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>> +	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>> +	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  };
>>  static const struct snd_soc_component_driver jz4740_i2s_component = {
>> @@ -465,6 +475,36 @@ static const struct of_device_id jz4740_of_matches[] = {
>>  };
>>  MODULE_DEVICE_TABLE(of, jz4740_of_matches);
>> +static int jz4740_i2s_init_regmap_fields(struct device *dev,
>> +					 struct jz4740_i2s *i2s)
>> +{
>> +	i2s->field_rx_fifo_thresh =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_rx_fifo_thresh);
>> +	if (IS_ERR(i2s->field_rx_fifo_thresh))
>> +		return PTR_ERR(i2s->field_rx_fifo_thresh);
>> +
>> +	i2s->field_tx_fifo_thresh =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_tx_fifo_thresh);
>> +	if (IS_ERR(i2s->field_tx_fifo_thresh))
>> +		return PTR_ERR(i2s->field_tx_fifo_thresh);
>> +
>> +	i2s->field_i2sdiv_capture =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_i2sdiv_capture);
>> +	if (IS_ERR(i2s->field_i2sdiv_capture))
>> +		return PTR_ERR(i2s->field_i2sdiv_capture);
>> +
>> +	i2s->field_i2sdiv_playback =
>> +		devm_regmap_field_alloc(dev, i2s->regmap,
>> +					i2s->soc_info->field_i2sdiv_playback);
>> +	if (IS_ERR(i2s->field_i2sdiv_playback))
>> +		return PTR_ERR(i2s->field_i2sdiv_playback);
>> +
>> +	return 0;
>> +}
>> +
>>  static const struct regmap_config jz4740_i2s_regmap_config = {
>>  	.reg_bits	= 32,
>>  	.reg_stride	= 4,
>> @@ -509,6 +549,10 @@ static int jz4740_i2s_dev_probe(struct platform_device
>> *pdev)
>>  	if (IS_ERR(i2s->regmap))
>>  		return PTR_ERR(i2s->regmap);
>> +	ret = jz4740_i2s_init_regmap_fields(dev, i2s);
>> +	if (ret)
>> +		return ret;
>> +
>>  	platform_set_drvdata(pdev, i2s);
>>  	ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
  2022-07-07  9:47     ` Paul Cercueil
@ 2022-07-07 14:24       ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:24 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:28 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> On some Ingenic SoCs, such as the X1000, there is a programmable
>> divider used to generate the I2S system clock from a PLL, rather
>> than a fixed PLL/2 clock. It doesn't make much sense to call the
>> clock "pll half" on those SoCs, so the clock name should really be
>> a SoC-dependent value.
>
> Do you really need the .set_sysclk() callback? I've never seen it used on any
> of the Ingenic boards I have, so to me it's pretty much dead code. Unless you
> do use this callback, I'd suggest to drop this patch until you do need it.
>
> Cheers,
> -Paul
>

Yes, one of my boards has an external codec (AK4376) that needs the
sysclock and I've patched simple-card to be able to set a non-zero
sysclock ID.

>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 3a21ee9d34d1..80b355d715ce 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -71,6 +71,8 @@ struct i2s_soc_info {
>>  	struct reg_field field_tx_fifo_thresh;
>>  	struct reg_field field_i2sdiv_capture;
>>  	struct reg_field field_i2sdiv_playback;
>> +
>> +	const char *pll_clk_name;
>>  };
>>  struct jz4740_i2s {
>> @@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai,
>> int clk_id,
>>  		clk_set_parent(i2s->clk_i2s, parent);
>>  		break;
>>  	case JZ4740_I2S_CLKSRC_PLL:
>> -		parent = clk_get(NULL, "pll half");
>> +		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
>>  		if (IS_ERR(parent))
>>  			return PTR_ERR(parent);
>>  		clk_set_parent(i2s->clk_i2s, parent);
>> @@ -387,6 +389,7 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>> @@ -395,6 +398,7 @@ static const struct i2s_soc_info jz4760_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
>> @@ -421,6 +425,7 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>> @@ -429,6 +434,7 @@ static const struct i2s_soc_info jz4780_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct snd_soc_component_driver jz4740_i2s_component = {
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific
@ 2022-07-07 14:24       ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:24 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:28 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> On some Ingenic SoCs, such as the X1000, there is a programmable
>> divider used to generate the I2S system clock from a PLL, rather
>> than a fixed PLL/2 clock. It doesn't make much sense to call the
>> clock "pll half" on those SoCs, so the clock name should really be
>> a SoC-dependent value.
>
> Do you really need the .set_sysclk() callback? I've never seen it used on any
> of the Ingenic boards I have, so to me it's pretty much dead code. Unless you
> do use this callback, I'd suggest to drop this patch until you do need it.
>
> Cheers,
> -Paul
>

Yes, one of my boards has an external codec (AK4376) that needs the
sysclock and I've patched simple-card to be able to set a non-zero
sysclock ID.

>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 8 +++++++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 3a21ee9d34d1..80b355d715ce 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -71,6 +71,8 @@ struct i2s_soc_info {
>>  	struct reg_field field_tx_fifo_thresh;
>>  	struct reg_field field_i2sdiv_capture;
>>  	struct reg_field field_i2sdiv_playback;
>> +
>> +	const char *pll_clk_name;
>>  };
>>  struct jz4740_i2s {
>> @@ -265,7 +267,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai,
>> int clk_id,
>>  		clk_set_parent(i2s->clk_i2s, parent);
>>  		break;
>>  	case JZ4740_I2S_CLKSRC_PLL:
>> -		parent = clk_get(NULL, "pll half");
>> +		parent = clk_get(NULL, i2s->soc_info->pll_clk_name);
>>  		if (IS_ERR(parent))
>>  			return PTR_ERR(parent);
>>  		clk_set_parent(i2s->clk_i2s, parent);
>> @@ -387,6 +389,7 @@ static const struct i2s_soc_info jz4740_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 8, 11),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct i2s_soc_info jz4760_i2s_soc_info = {
>> @@ -395,6 +398,7 @@ static const struct i2s_soc_info jz4760_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static struct snd_soc_dai_driver jz4770_i2s_dai = {
>> @@ -421,6 +425,7 @@ static const struct i2s_soc_info jz4770_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct i2s_soc_info jz4780_i2s_soc_info = {
>> @@ -429,6 +434,7 @@ static const struct i2s_soc_info jz4780_i2s_soc_info = {
>>  	.field_tx_fifo_thresh	= REG_FIELD(JZ_REG_AIC_CONF, 16, 20),
>>  	.field_i2sdiv_capture	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 8, 11),
>>  	.field_i2sdiv_playback	= REG_FIELD(JZ_REG_AIC_CLK_DIV, 0, 3),
>> +	.pll_clk_name		= "pll half",
>>  };
>>  static const struct snd_soc_component_driver jz4740_i2s_component = {
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
  2022-07-07  9:53     ` Paul Cercueil
@ 2022-07-07 14:25       ` Aidan MacDonald
  -1 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:25 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: lgirdwood, broonie, perex, tiwai, linux-mips, alsa-devel, linux-kernel


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:29 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> The audio controller on JZ47xx SoCs supports 20- and 24-bit
>> samples coming from memory. Allow those formats to be used
>> with the I2S driver.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
>>  1 file changed, 10 insertions(+), 2 deletions(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 80b355d715ce..ee99c5e781ec 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  	case SNDRV_PCM_FORMAT_S8:
>>  		sample_size = 0;
>>  		break;
>> -	case SNDRV_PCM_FORMAT_S16:
>> +	case SNDRV_PCM_FORMAT_S16_LE:
>>  		sample_size = 1;
>>  		break;
>> +	case SNDRV_PCM_FORMAT_S20_LE:
>> +		sample_size = 3;
>> +		break;
>> +	case SNDRV_PCM_FORMAT_S24_LE:
>> +		sample_size = 4;
>> +		break;
>
> Did you test these? It is unclear to me, looking at the JZ4740 PM, if the
> 18-bit, 20-bit and 24-bit samples are in 4 bytes or 3 bytes.
>
> Cheers,
> -Paul
>

I was only able to test 24-bit -- in practice 20-bit seems pretty rare
and I'm finding it difficult to convert anything into that format with
standard tools like ffmpeg, sox, etc. so I can't really test it.

From what I understand, this is configuring the number of significant
bits in the FIFO and has nothing to do with the in-memory format. So
my commit message is a bit inaccurate.

DMA can only do 4-byte transfers so that's why only 4-byte formats are
usable. I suppose I could handle the 3-byte variants here, but there's
probably no point to doing that if DMA can't transfer them.

>>  	default:
>>  		return -EINVAL;
>>  	}
>> @@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops =
>> {
>>  };
>>  #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
>> -		SNDRV_PCM_FMTBIT_S16_LE)
>> +			 SNDRV_PCM_FMTBIT_S16_LE | \
>> +			 SNDRV_PCM_FMTBIT_S20_LE | \
>> +			 SNDRV_PCM_FMTBIT_S24_LE)
>>  static struct snd_soc_dai_driver jz4740_i2s_dai = {
>>  	.probe = jz4740_i2s_dai_probe,
>> --
>> 2.35.1
>> 


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

* Re: [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats
@ 2022-07-07 14:25       ` Aidan MacDonald
  0 siblings, 0 replies; 56+ messages in thread
From: Aidan MacDonald @ 2022-07-07 14:25 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: alsa-devel, lgirdwood, linux-kernel, linux-mips, tiwai, broonie


Paul Cercueil <paul@crapouillou.net> writes:

> Le mer., juil. 6 2022 at 22:13:29 +0100, Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> a écrit :
>> The audio controller on JZ47xx SoCs supports 20- and 24-bit
>> samples coming from memory. Allow those formats to be used
>> with the I2S driver.
>> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
>> ---
>>  sound/soc/jz4740/jz4740-i2s.c | 12 ++++++++++--
>>  1 file changed, 10 insertions(+), 2 deletions(-)
>> diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
>> index 80b355d715ce..ee99c5e781ec 100644
>> --- a/sound/soc/jz4740/jz4740-i2s.c
>> +++ b/sound/soc/jz4740/jz4740-i2s.c
>> @@ -222,9 +222,15 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream
>> *substream,
>>  	case SNDRV_PCM_FORMAT_S8:
>>  		sample_size = 0;
>>  		break;
>> -	case SNDRV_PCM_FORMAT_S16:
>> +	case SNDRV_PCM_FORMAT_S16_LE:
>>  		sample_size = 1;
>>  		break;
>> +	case SNDRV_PCM_FORMAT_S20_LE:
>> +		sample_size = 3;
>> +		break;
>> +	case SNDRV_PCM_FORMAT_S24_LE:
>> +		sample_size = 4;
>> +		break;
>
> Did you test these? It is unclear to me, looking at the JZ4740 PM, if the
> 18-bit, 20-bit and 24-bit samples are in 4 bytes or 3 bytes.
>
> Cheers,
> -Paul
>

I was only able to test 24-bit -- in practice 20-bit seems pretty rare
and I'm finding it difficult to convert anything into that format with
standard tools like ffmpeg, sox, etc. so I can't really test it.

From what I understand, this is configuring the number of significant
bits in the FIFO and has nothing to do with the in-memory format. So
my commit message is a bit inaccurate.

DMA can only do 4-byte transfers so that's why only 4-byte formats are
usable. I suppose I could handle the 3-byte variants here, but there's
probably no point to doing that if DMA can't transfer them.

>>  	default:
>>  		return -EINVAL;
>>  	}
>> @@ -362,7 +368,9 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops =
>> {
>>  };
>>  #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
>> -		SNDRV_PCM_FMTBIT_S16_LE)
>> +			 SNDRV_PCM_FMTBIT_S16_LE | \
>> +			 SNDRV_PCM_FMTBIT_S20_LE | \
>> +			 SNDRV_PCM_FMTBIT_S24_LE)
>>  static struct snd_soc_dai_driver jz4740_i2s_dai = {
>>  	.probe = jz4740_i2s_dai_probe,
>> --
>> 2.35.1
>> 


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

end of thread, other threads:[~2022-07-07 14:41 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-06 21:13 [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s Aidan MacDonald
2022-07-06 21:13 ` Aidan MacDonald
2022-07-06 21:13 ` [PATCH 01/11] ASoC: jz4740-i2s: Remove Open Firmware dependency Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:16   ` Paul Cercueil
2022-07-07  9:16     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 02/11] ASoC: jz4740-i2s: Refactor DMA channel setup Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:30   ` Paul Cercueil
2022-07-07  9:30     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 03/11] ASoC: jz4740-i2s: Convert to regmap API Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-06 21:53   ` Paul Cercueil
2022-07-06 21:53     ` Paul Cercueil
2022-07-07 14:12     ` Aidan MacDonald
2022-07-07 14:12       ` Aidan MacDonald
2022-07-06 21:13 ` [PATCH 04/11] ASoC: jz4740-i2s: Simplify using regmap fields Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:36   ` Paul Cercueil
2022-07-07  9:36     ` Paul Cercueil
2022-07-07 14:13     ` Aidan MacDonald
2022-07-07 14:13       ` Aidan MacDonald
2022-07-06 21:13 ` [PATCH 05/11] ASoC: jz4740-i2s: Remove unused SoC version IDs Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:37   ` Paul Cercueil
2022-07-07  9:37     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 06/11] ASoC: jz4740-i2s: Use FIELD_PREP() macros in hw_params callback Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:40   ` Paul Cercueil
2022-07-07  9:40     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 07/11] ASoC: jz4740-i2s: Remove some unused macros Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:42   ` Paul Cercueil
2022-07-07  9:42     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 08/11] ASoC: jz4740-i2s: Align macro values and sort includes Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:42   ` Paul Cercueil
2022-07-07  9:42     ` Paul Cercueil
2022-07-06 21:13 ` [PATCH 09/11] ASoC: jz4740-i2s: Make the PLL clock name SoC-specific Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:47   ` Paul Cercueil
2022-07-07  9:47     ` Paul Cercueil
2022-07-07 14:24     ` Aidan MacDonald
2022-07-07 14:24       ` Aidan MacDonald
2022-07-06 21:13 ` [PATCH 10/11] ASoC: jz4740-i2s: Support S20_LE and S24_LE sample formats Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:53   ` Paul Cercueil
2022-07-07  9:53     ` Paul Cercueil
2022-07-07 14:25     ` Aidan MacDonald
2022-07-07 14:25       ` Aidan MacDonald
2022-07-06 21:13 ` [PATCH 11/11] ASoC: jz4740-i2s: Support continuous sample rate Aidan MacDonald
2022-07-06 21:13   ` Aidan MacDonald
2022-07-07  9:53   ` Paul Cercueil
2022-07-07  9:53     ` Paul Cercueil
2022-07-07 13:54 ` (subset) [PATCH 00/11] ASoC: cleanups and improvements for jz4740-i2s Mark Brown
2022-07-07 13:54   ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.