Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver
@ 2019-08-14  6:08 codekipper
  2019-08-14  6:08 ` [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample codekipper
                   ` (14 more replies)
  0 siblings, 15 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Hi All,

here is a patch series to add some improvements to the sun4i-i2s driver
found whilst getting slave clocking and hdmi audio working on the newer
SoCs. As the LibreELEC project is progressing extremely well then there
has been some activity getting H6 SoC support with surround sound
working and these changes are also included.

The functionality included with the new patch set has been extended to
cover more sample resolutions, multi-lane data output for HDMI audio
and some bug fixes that have been discovered along the way. I have
changed some of the original reg fields into function calls as this made
it easier to setup for multi-channel audio especially across different
SoCs.

I can see more usage of the tdm property since I last attempted to push
these patches and the examples currently in mainline sort of the opposite
to what I'm trying to achieve. When we first started looking at the i2s
driver, the codecs that we were using allowed for the frame width to be
determined based on the sampling resolution but in most use cases it
seems that a fixed width is required(my highest priority should be to get
HDMI audio support in). We're using the tdm property to override the old
way to calculate the frame width. What I've seen in what has already been
mainlined is that the i2s driver has a frame width that is fixed to 32
bits and this can be overridden using the tdm property.

My test branch for this can be found at
https://github.com/codekipper/linux-sunxi/commits/upstream-i2s , I've been
using a Pine64 to test with; validating the new SoC block with HDMI audio
and ensuring that I've not broken the old block by making sure that the audio
codec still works. If we able to get the first three patches delivered then
that is enough for HDMI audio support on the newer SoCs(H3, A64 etc).

I still need to investigate the FIFO syncing issues which i've not had a
chance to change or address the concerns that broonie and wens brought up.
This change has been moved to the top of the patch stack. I would also like
to make the multi-channel audio and audio mapping more configurable via the
device tree. Currently what is implemented suites our current needs.

BR,
CK

---
v5 changes compared to v4 are:
- removed delivered patches.
- Added more details to commit messages.
- replaced some reg fields with function calls.
- Added DSP_A and DSP_B support for H3 and later SoCs.
- Added support for the Allwinner H6.

v4 changes compared to v3 are:
- Moved patches around so that the more controversial of patches are
  at the top of the stack.
- Added more details to commit messages.
- Fixed 20bit audio PCM format to use 4 bytes.
- Reduced number of flags used to indicate a new SoC.

v3 changes compared to v2 are:
 - added back slave mode changes
 - added back the use of tdm properties
 - changes to regmap and caching
 - removed loopback functionality
 - fixes to the channel offset mask

v2 changes compared to v1 are:
 - removed slave mode changes which didn't set mclk and bclk div.
 - removed use of tdm and now use a dedicated property.
 - fix commit message to better explain reason for sign extending
 - add divider calculations for newer SoCs.
 - add support for multi-lane i2s data output.
 - add support for 20, 24 and 32 bit samples.
 - add loopback property so blocks can be tested without a codec.


---
Jernej Skrabec (3):
  clk: sunxi-ng: h6: Allow I2S to change parent rate
  dt-bindings: ASoC: sun4i-i2s: Add H6 compatible
  ASoC: sun4i-i2s: Add support for H6 I2S

Marcus Cooper (12):
  ASoC: sun4i-i2s: Add regmap field to sign extend sample
  ASoC: sun4i-i2s: Add set_tdm_slot functionality
  ASoC: sun4i-i2s: Correct divider calculations
  ASoC: sun4i-i2s: Support more formats on newer SoCs
  ASoC: sun4i-i2s: Add functions for RX and TX channel offsets
  ASoC: sun4i-i2s: Add functions for RX and TX channel enables
  ASoC: sun4i-i2s: Add functions for RX and TX channel selects
  ASoC: sun4i-i2s: Add functions for channel mapping
  ASoC: sun4i-i2s: Add multi-lane functionality
  ASoC: sun4i-i2s: Add multichannel functionality
  ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  ASoC: sun4i-i2s: Adjust regmap settings

 .../sound/allwinner,sun4i-a10-i2s.yaml        |   2 +
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c          |   8 +-
 sound/soc/sunxi/sun4i-i2s.c                   | 690 ++++++++++++++----
 3 files changed, 542 insertions(+), 158 deletions(-)

-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:43   ` Maxime Ripard
  2019-08-14  6:08 ` [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality codekipper
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

On the newer SoCs such as the H3 and A64 this is set by default
to transfer a 0 after each sample in each slot. However the A10
and A20 SoCs that this driver was developed on had a default
setting where it padded the audio gain with zeros.

This isn't a problem whilst we have only support for 16bit audio
but with larger sample resolution rates in the pipeline then SEXT
bits should be cleared so that they also pad at the LSB. Without
this the audio gets distorted.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 793457394efe..8201334a059b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -135,6 +135,7 @@ struct sun4i_i2s;
  * @field_fmt_bclk: regmap field to set clk polarity.
  * @field_fmt_lrclk: regmap field to set frame polarity.
  * @field_fmt_mode: regmap field to set the operational mode.
+ * @field_fmt_sext: regmap field to set the sign extension.
  * @field_txchanmap: location of the tx channel mapping register.
  * @field_rxchanmap: location of the rx channel mapping register.
  * @field_txchansel: location of the tx channel select bit fields.
@@ -159,6 +160,7 @@ struct sun4i_i2s_quirks {
 	struct reg_field		field_fmt_bclk;
 	struct reg_field		field_fmt_lrclk;
 	struct reg_field		field_fmt_mode;
+	struct reg_field		field_fmt_sext;
 	struct reg_field		field_txchanmap;
 	struct reg_field		field_rxchanmap;
 	struct reg_field		field_txchansel;
@@ -186,6 +188,7 @@ struct sun4i_i2s {
 	struct regmap_field	*field_fmt_bclk;
 	struct regmap_field	*field_fmt_lrclk;
 	struct regmap_field	*field_fmt_mode;
+	struct regmap_field	*field_fmt_sext;
 	struct regmap_field	*field_txchanmap;
 	struct regmap_field	*field_rxchanmap;
 	struct regmap_field	*field_txchansel;
@@ -345,6 +348,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 				   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
 				   SUN8I_I2S_FMT0_LRCK_PERIOD(32));
 
+	/* Set sign extension to pad out LSB with 0 */
+	regmap_field_write(i2s->field_fmt_sext, 0);
+
 	return 0;
 }
 
@@ -917,6 +923,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.has_slave_select_bit	= true,
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
+	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -936,6 +943,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.has_slave_select_bit	= true,
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
+	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -979,6 +987,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
+	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
 	.field_txchanmap	= REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.field_txchansel	= REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -998,6 +1007,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
+	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -1045,6 +1055,12 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
 	if (IS_ERR(i2s->field_fmt_mode))
 		return PTR_ERR(i2s->field_fmt_mode);
 
+	i2s->field_fmt_sext =
+			devm_regmap_field_alloc(dev, i2s->regmap,
+						i2s->variant->field_fmt_sext);
+	if (IS_ERR(i2s->field_fmt_sext))
+		return PTR_ERR(i2s->field_fmt_sext);
+
 	i2s->field_txchanmap =
 			devm_regmap_field_alloc(dev, i2s->regmap,
 						i2s->variant->field_txchanmap);
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
  2019-08-14  6:08 ` [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:09   ` Maxime Ripard
  2019-08-14  9:30   ` Mark Brown
  2019-08-14  6:08 ` [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations codekipper
                   ` (12 subsequent siblings)
  14 siblings, 2 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Codecs without a control connection such as i2s based HDMI audio and
the Pine64 DAC require a different amount of bit clocks per frame than
what is calculated by the sample width. Use the tdm slot bindings to
provide this mechanism.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 8201334a059b..7c37b6291df0 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -195,6 +195,9 @@ struct sun4i_i2s {
 	struct regmap_field	*field_rxchansel;
 
 	const struct sun4i_i2s_quirks	*variant;
+
+	unsigned int	tdm_slots;
+	unsigned int	slot_width;
 };
 
 struct sun4i_i2s_clk_div {
@@ -346,7 +349,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 	if (i2s->variant->has_fmt_set_lrck_period)
 		regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 				   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
-				   SUN8I_I2S_FMT0_LRCK_PERIOD(32));
+				   SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
 
 	/* Set sign extension to pad out LSB with 0 */
 	regmap_field_write(i2s->field_fmt_sext, 0);
@@ -450,7 +453,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	regmap_field_write(i2s->field_fmt_sr, sr);
 
 	return sun4i_i2s_set_clk_rate(dai, params_rate(params),
-				      params_width(params));
+				      i2s->tdm_slots ?
+				      i2s->slot_width : params_width(params));
 }
 
 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
@@ -693,10 +697,25 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 	return 0;
 }
 
+static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
+				      unsigned int tx_mask,
+				      unsigned int rx_mask,
+				      int slots, int width)
+{
+	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
+	i2s->tdm_slots = slots;
+
+	i2s->slot_width = width;
+
+	return 0;
+}
+
 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 	.hw_params	= sun4i_i2s_hw_params,
 	.set_fmt	= sun4i_i2s_set_fmt,
 	.set_sysclk	= sun4i_i2s_set_sysclk,
+	.set_tdm_slot	= sun4i_i2s_set_dai_tdm_slot,
 	.trigger	= sun4i_i2s_trigger,
 };
 
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
  2019-08-14  6:08 ` [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample codekipper
  2019-08-14  6:08 ` [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:13   ` Maxime Ripard
  2019-08-14  9:31   ` Mark Brown
  2019-08-14  6:08 ` [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs codekipper
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

The clock division circuitry is different on the H3 and later SoCs.
The division of bclk is now based on pll2.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 73 +++++++++++++++++++++++++------------
 1 file changed, 49 insertions(+), 24 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 7c37b6291df0..34f31439ae7b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -127,8 +127,6 @@ struct sun4i_i2s;
  * @has_chsel_offset: SoC uses offset for selecting dai operational mode.
  * @reg_offset_txdata: offset of the tx fifo.
  * @sun4i_i2s_regmap: regmap config to use.
- * @mclk_offset: Value by which mclkdiv needs to be adjusted.
- * @bclk_offset: Value by which bclkdiv needs to be adjusted.
  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
  * @field_fmt_wss: regmap field to set word select size.
  * @field_fmt_sr: regmap field to set sample resolution.
@@ -150,8 +148,6 @@ struct sun4i_i2s_quirks {
 	bool				has_chsel_offset;
 	unsigned int			reg_offset_txdata;	/* TX FIFO */
 	const struct regmap_config	*sun4i_i2s_regmap;
-	unsigned int			mclk_offset;
-	unsigned int			bclk_offset;
 
 	/* Register fields for i2s */
 	struct reg_field		field_clkdiv_mclk_en;
@@ -212,7 +208,25 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 	{ .div = 8, .val = 3 },
 	{ .div = 12, .val = 4 },
 	{ .div = 16, .val = 5 },
-	/* TODO - extend divide ratio supported by newer SoCs */
+};
+
+static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
+	{ .div = 0, .val = 0 },
+	{ .div = 1, .val = 1 },
+	{ .div = 2, .val = 2 },
+	{ .div = 4, .val = 3 },
+	{ .div = 6, .val = 4 },
+	{ .div = 8, .val = 5 },
+	{ .div = 12, .val = 6 },
+	{ .div = 16, .val = 7 },
+	{ .div = 24, .val = 8 },
+	{ .div = 32, .val = 9 },
+	{ .div = 48, .val = 10 },
+	{ .div = 64, .val = 11 },
+	{ .div = 96, .val = 12 },
+	{ .div = 128, .val = 13 },
+	{ .div = 176, .val = 14 },
+	{ .div = 192, .val = 15 },
 };
 
 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
@@ -224,21 +238,21 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
 	{ .div = 12, .val = 5 },
 	{ .div = 16, .val = 6 },
 	{ .div = 24, .val = 7 },
-	/* TODO - extend divide ratio supported by newer SoCs */
 };
 
 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
 				  unsigned int oversample_rate,
-				  unsigned int word_size)
+				  unsigned int word_size,
+				  const struct sun4i_i2s_clk_div *bdiv,
+				  unsigned int size)
 {
 	int div = oversample_rate / word_size / 2;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
-		const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i];
-
+	for (i = 0; i < size; i++) {
 		if (bdiv->div == div)
 			return bdiv->val;
+		bdiv++;
 	}
 
 	return -EINVAL;
@@ -247,16 +261,17 @@ static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
 				  unsigned int oversample_rate,
 				  unsigned int module_rate,
-				  unsigned int sampling_rate)
+				  unsigned int sampling_rate,
+				  const struct sun4i_i2s_clk_div *mdiv,
+				  unsigned int size)
 {
 	int div = module_rate / sampling_rate / oversample_rate;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) {
-		const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i];
-
+	for (i = 0; i < size; i++) {
 		if (mdiv->div == div)
 			return mdiv->val;
+		mdiv++;
 	}
 
 	return -EINVAL;
@@ -321,24 +336,36 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 		return -EINVAL;
 	}
 
-	bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
-					  word_size);
+	if (i2s->variant->has_fmt_set_lrck_period)
+		bclk_div = sun4i_i2s_get_bclk_div(i2s, clk_rate / rate,
+						  word_size,
+						  sun8i_i2s_clk_div,
+						  ARRAY_SIZE(sun8i_i2s_clk_div));
+	else
+		bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
+						  word_size,
+						  sun4i_i2s_bclk_div,
+						  ARRAY_SIZE(sun4i_i2s_bclk_div));
 	if (bclk_div < 0) {
 		dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
 		return -EINVAL;
 	}
 
-	mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
-					  clk_rate, rate);
+	if (i2s->variant->has_fmt_set_lrck_period)
+		mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
+						  clk_rate, rate,
+						  sun8i_i2s_clk_div,
+						  ARRAY_SIZE(sun8i_i2s_clk_div));
+	else
+		mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
+						  clk_rate, rate,
+						  sun4i_i2s_mclk_div,
+						  ARRAY_SIZE(sun4i_i2s_mclk_div));
 	if (mclk_div < 0) {
 		dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
 		return -EINVAL;
 	}
 
-	/* Adjust the clock division values if needed */
-	bclk_div += i2s->variant->bclk_offset;
-	mclk_div += i2s->variant->mclk_offset;
-
 	regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
 		     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
 		     SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
@@ -994,8 +1021,6 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.has_reset		= true,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
-	.mclk_offset		= 1,
-	.bclk_offset		= 2,
 	.has_fmt_set_lrck_period = true,
 	.has_chcfg		= true,
 	.has_chsel_tx_chen	= true,
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (2 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:16   ` Maxime Ripard
  2019-08-14  6:08 ` [PATCH v5 05/15] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets codekipper
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

There is a need to support more formats on the newer SoCs(H3 and later).
Extend the formats supported to include DSP_A and DSP_B modes.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 87 +++++++++++++++++++++++++++----------
 1 file changed, 63 insertions(+), 24 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 34f31439ae7b..3553c17318b0 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -27,6 +27,8 @@
 #define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
 #define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
 #define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
+#define SUN4I_I2S_CTRL_PCM			BIT(4)
+#define SUN4I_I2S_CTRL_LOOP			BIT(3)
 #define SUN4I_I2S_CTRL_TX_EN			BIT(2)
 #define SUN4I_I2S_CTRL_RX_EN			BIT(1)
 #define SUN4I_I2S_CTRL_GL_EN			BIT(0)
@@ -91,6 +93,9 @@
 /* Defines required for sun8i-h3 support */
 #define SUN8I_I2S_CTRL_BCLK_OUT			BIT(18)
 #define SUN8I_I2S_CTRL_LRCK_OUT			BIT(17)
+#define SUN8I_I2S_CTRL_MODE_RIGHT_J			(2 << 0)
+#define SUN8I_I2S_CTRL_MODE_I2S_LEFT_J			(1 << 0)
+#define SUN8I_I2S_CTRL_MODE_PCM				(0 << 0)
 
 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK		GENMASK(17, 8)
 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)	((period - 1) << 8)
@@ -164,6 +169,7 @@ struct sun4i_i2s_quirks {
 
 	s8	(*get_sr)(const struct sun4i_i2s *, int);
 	s8	(*get_wss)(const struct sun4i_i2s *, int);
+	int	(*set_format)(struct sun4i_i2s *, unsigned int);
 };
 
 struct sun4i_i2s {
@@ -194,6 +200,7 @@ struct sun4i_i2s {
 
 	unsigned int	tdm_slots;
 	unsigned int	slot_width;
+	unsigned int	offset;
 };
 
 struct sun4i_i2s_clk_div {
@@ -484,19 +491,14 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 				      i2s->slot_width : params_width(params));
 }
 
-static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+static int sun4i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
 {
-	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 	u32 val;
-	u32 offset = 0;
-	u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
-	u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
 
 	/* DAI Mode */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
 		val = SUN4I_I2S_FMT0_FMT_I2S;
-		offset = 1;
 		break;
 	case SND_SOC_DAIFMT_LEFT_J:
 		val = SUN4I_I2S_FMT0_FMT_LEFT_J;
@@ -505,32 +507,64 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 		val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
 		break;
 	default:
-		dev_err(dai->dev, "Unsupported format: %d\n",
-			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 		return -EINVAL;
 	}
 
-	if (i2s->variant->has_chsel_offset) {
-		/*
-		 * offset being set indicates that we're connected to an i2s
-		 * device, however offset is only used on the sun8i block and
-		 * i2s shares the same setting with the LJ format. Increment
-		 * val so that the bit to value to write is correct.
-		 */
-		if (offset > 0)
-			val++;
-		/* blck offset determines whether i2s or LJ */
-		regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
-				   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-				   SUN8I_I2S_TX_CHAN_OFFSET(offset));
+	regmap_field_write(i2s->field_fmt_mode, val);
+
+	return 0;
+}
+
+static int sun8i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
+{
+	u32 val;
 
-		regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
-				   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-				   SUN8I_I2S_TX_CHAN_OFFSET(offset));
+	/* DAI Mode */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		i2s->offset = 1;
+	case SND_SOC_DAIFMT_LEFT_J:
+		val = SUN8I_I2S_CTRL_MODE_I2S_LEFT_J;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		val = SUN8I_I2S_CTRL_MODE_RIGHT_J;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		i2s->offset = 1;
+	case SND_SOC_DAIFMT_DSP_B:
+		val = SUN8I_I2S_CTRL_MODE_PCM;
+		break;
+
+	default:
+		return -EINVAL;
 	}
 
+	/*
+	 * bclk offset determines whether i2s or LJ if in i2s mode and
+	 * DSP_A or DSP_B if in PCM mode.
+	 */
+	i2s->variant->set_txchanoffset(i2s, 0);
+	i2s->variant->set_rxchanoffset(i2s);
+
 	regmap_field_write(i2s->field_fmt_mode, val);
 
+	return 0;
+}
+
+static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+	u32 val;
+	u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
+	u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
+
+	/* Set DAI Mode */
+	if (i2s->variant->set_format(i2s, fmt) != 0) {
+		dev_err(dai->dev, "Unsupported format: %d\n",
+			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
 	/* DAI clock polarity */
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 	case SND_SOC_DAIFMT_IB_IF:
@@ -976,6 +1010,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
+	.set_format		= sun4i_i2s_set_format,
 };
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
@@ -996,6 +1031,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
+	.set_format		= sun4i_i2s_set_format,
 };
 
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
@@ -1015,6 +1051,7 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
+	.set_format		= sun4i_i2s_set_format,
 };
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
@@ -1038,6 +1075,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.field_rxchansel	= REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
+	.set_format		= sun8i_i2s_set_format,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
@@ -1058,6 +1096,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
+	.set_format		= sun4i_i2s_set_format,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 05/15] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (3 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 06/15] ASoC: sun4i-i2s: Add functions for RX and TX channel enables codekipper
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Newer SoCs like the H6 have the channel offset bits in a different
position to what is on the H3. As we will eventually add multi-
channel support then create function calls as opposed to regmap
fields to add support for different devices.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 3553c17318b0..4a748747ccd7 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -112,7 +112,7 @@
 #define SUN8I_I2S_TX_CHAN_MAP_REG	0x44
 #define SUN8I_I2S_TX_CHAN_SEL_REG	0x34
 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK		GENMASK(13, 12)
-#define SUN8I_I2S_TX_CHAN_OFFSET(offset)	(offset << 12)
+#define SUN8I_I2S_TX_CHAN_OFFSET(offset)	((offset) << 12)
 #define SUN8I_I2S_TX_CHAN_EN_MASK		GENMASK(11, 4)
 #define SUN8I_I2S_TX_CHAN_EN(num_chan)		(((1 << num_chan) - 1) << 4)
 
@@ -170,6 +170,8 @@ struct sun4i_i2s_quirks {
 	s8	(*get_sr)(const struct sun4i_i2s *, int);
 	s8	(*get_wss)(const struct sun4i_i2s *, int);
 	int	(*set_format)(struct sun4i_i2s *, unsigned int);
+	void	(*set_txchanoffset)(const struct sun4i_i2s *, int);
+	void	(*set_rxchanoffset)(const struct sun4i_i2s *);
 };
 
 struct sun4i_i2s {
@@ -424,6 +426,24 @@ static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width)
 	return (width - 8) / 4 + 1;
 }
 
+static void sun8i_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+				   SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
+	}
+}
+
+static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
+{
+	regmap_update_bits(i2s->regmap,
+			   SUN8I_I2S_RX_CHAN_SEL_REG,
+			   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+			   SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
+}
+
 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
 			       struct snd_soc_dai *dai)
@@ -1076,6 +1096,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
 	.set_format		= sun8i_i2s_set_format,
+	.set_txchanoffset	= sun8i_i2s_set_txchanoffset,
+	.set_rxchanoffset	= sun8i_i2s_set_rxchanoffset,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 06/15] ASoC: sun4i-i2s: Add functions for RX and TX channel enables
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (4 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 05/15] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 07/15] ASoC: sun4i-i2s: Add functions for RX and TX channel selects codekipper
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Newer SoCs like the H6 have the channel enable bits in a different
position to what is on the H3. As we will eventually add multi-
channel support then create function calls as opposed to regmap
fields to add support for different devices.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 4a748747ccd7..ad2ff83deeb7 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -172,6 +172,8 @@ struct sun4i_i2s_quirks {
 	int	(*set_format)(struct sun4i_i2s *, unsigned int);
 	void	(*set_txchanoffset)(const struct sun4i_i2s *, int);
 	void	(*set_rxchanoffset)(const struct sun4i_i2s *);
+	void	(*set_txchanen)(const struct sun4i_i2s *, int, int);
+	void	(*set_rxchanen)(const struct sun4i_i2s *, int);
 };
 
 struct sun4i_i2s {
@@ -444,6 +446,25 @@ static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
 			   SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
 }
 
+static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
+				   int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN8I_I2S_TX_CHAN_EN_MASK,
+				   SUN8I_I2S_TX_CHAN_EN(channel));
+	}
+}
+
+static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_update_bits(i2s->regmap,
+			   SUN8I_I2S_RX_CHAN_SEL_REG,
+			   SUN8I_I2S_TX_CHAN_EN_MASK,
+			   SUN8I_I2S_TX_CHAN_EN(channel));
+}
+
 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
 			       struct snd_soc_dai *dai)
@@ -479,10 +500,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	regmap_field_write(i2s->field_rxchansel,
 			   SUN4I_I2S_CHAN_SEL(params_channels(params)));
 
-	if (i2s->variant->has_chsel_tx_chen)
-		regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
-				   SUN8I_I2S_TX_CHAN_EN_MASK,
-				   SUN8I_I2S_TX_CHAN_EN(channels));
+	if (i2s->variant->set_txchanen)
+		i2s->variant->set_txchanen(i2s, 0, channels);
+
+	if (i2s->variant->set_rxchanen)
+		i2s->variant->set_rxchanen(i2s, channels);
 
 	switch (params_physical_width(params)) {
 	case 16:
@@ -1098,6 +1120,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.set_format		= sun8i_i2s_set_format,
 	.set_txchanoffset	= sun8i_i2s_set_txchanoffset,
 	.set_rxchanoffset	= sun8i_i2s_set_rxchanoffset,
+	.set_txchanen		= sun8i_i2s_set_txchanen,
+	.set_rxchanen		= sun8i_i2s_set_rxchanen,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 07/15] ASoC: sun4i-i2s: Add functions for RX and TX channel selects
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (5 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 06/15] ASoC: sun4i-i2s: Add functions for RX and TX channel enables codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 08/15] ASoC: sun4i-i2s: Add functions for channel mapping codekipper
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Newer SoCs like the H6 have the channel select bits in a different
positions than what is on the H3. As we will eventually add multi-
channel support then create function calls as opposed to regmap
fields to add support for different devices.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 87 ++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 34 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index ad2ff83deeb7..0b98adde0717 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -115,6 +115,8 @@
 #define SUN8I_I2S_TX_CHAN_OFFSET(offset)	((offset) << 12)
 #define SUN8I_I2S_TX_CHAN_EN_MASK		GENMASK(11, 4)
 #define SUN8I_I2S_TX_CHAN_EN(num_chan)		(((1 << num_chan) - 1) << 4)
+#define SUN8I_I2S_TX_CHAN_SEL_MASK		GENMASK(2, 0)
+#define SUN8I_I2S_TX_CHAN_SEL(chan)		(chan - 1)
 
 #define SUN8I_I2S_RX_CHAN_SEL_REG	0x54
 #define SUN8I_I2S_RX_CHAN_MAP_REG	0x58
@@ -141,8 +143,6 @@ struct sun4i_i2s;
  * @field_fmt_sext: regmap field to set the sign extension.
  * @field_txchanmap: location of the tx channel mapping register.
  * @field_rxchanmap: location of the rx channel mapping register.
- * @field_txchansel: location of the tx channel select bit fields.
- * @field_rxchansel: location of the rx channel select bit fields.
  */
 struct sun4i_i2s_quirks {
 	bool				has_reset;
@@ -164,8 +164,6 @@ struct sun4i_i2s_quirks {
 	struct reg_field		field_fmt_sext;
 	struct reg_field		field_txchanmap;
 	struct reg_field		field_rxchanmap;
-	struct reg_field		field_txchansel;
-	struct reg_field		field_rxchansel;
 
 	s8	(*get_sr)(const struct sun4i_i2s *, int);
 	s8	(*get_wss)(const struct sun4i_i2s *, int);
@@ -174,6 +172,8 @@ struct sun4i_i2s_quirks {
 	void	(*set_rxchanoffset)(const struct sun4i_i2s *);
 	void	(*set_txchanen)(const struct sun4i_i2s *, int, int);
 	void	(*set_rxchanen)(const struct sun4i_i2s *, int);
+	void	(*set_txchansel)(const struct sun4i_i2s *, int, int);
+	void	(*set_rxchansel)(const struct sun4i_i2s *, int);
 };
 
 struct sun4i_i2s {
@@ -197,8 +197,6 @@ struct sun4i_i2s {
 	struct regmap_field	*field_fmt_sext;
 	struct regmap_field	*field_txchanmap;
 	struct regmap_field	*field_rxchanmap;
-	struct regmap_field	*field_txchansel;
-	struct regmap_field	*field_rxchansel;
 
 	const struct sun4i_i2s_quirks	*variant;
 
@@ -465,6 +463,42 @@ static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
 			   SUN8I_I2S_TX_CHAN_EN(channel));
 }
 
+static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
+				    int channel)
+{
+	/* Configure the channels */
+	regmap_write(i2s->regmap,
+		     SUN4I_I2S_TX_CHAN_SEL_REG,
+		     SUN4I_I2S_CHAN_SEL(channel));
+}
+
+static void sun8i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
+				    int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN8I_I2S_TX_CHAN_SEL_MASK,
+				   SUN8I_I2S_TX_CHAN_SEL(channel));
+	}
+}
+
+static void sun4i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
+{
+	/* Configure the channels */
+	regmap_write(i2s->regmap,
+		     SUN4I_I2S_RX_CHAN_SEL_REG,
+		     SUN4I_I2S_CHAN_SEL(channel));
+}
+
+static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_RX_CHAN_SEL_REG,
+				   SUN8I_I2S_TX_CHAN_SEL_MASK,
+				   SUN8I_I2S_TX_CHAN_SEL(channel));
+}
+
 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
 			       struct snd_soc_dai *dai)
@@ -494,11 +528,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	regmap_field_write(i2s->field_rxchanmap, 0x00003210);
 
 	/* Configure the channels */
-	regmap_field_write(i2s->field_txchansel,
-			   SUN4I_I2S_CHAN_SEL(params_channels(params)));
-
-	regmap_field_write(i2s->field_rxchansel,
-			   SUN4I_I2S_CHAN_SEL(params_channels(params)));
+	i2s->variant->set_txchansel(i2s, 0, channels);
+	i2s->variant->set_rxchansel(i2s, channels);
 
 	if (i2s->variant->set_txchanen)
 		i2s->variant->set_txchanen(i2s, 0, channels);
@@ -1048,11 +1079,11 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
-	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
-	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
+	.set_txchansel		= sun4i_i2s_set_txchansel,
+	.set_rxchansel		= sun4i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
@@ -1069,11 +1100,11 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
-	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
-	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
+	.set_txchansel		= sun4i_i2s_set_txchansel,
+	.set_rxchansel		= sun4i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
@@ -1089,11 +1120,11 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
-	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
-	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
 	.set_format		= sun4i_i2s_set_format,
+	.set_txchansel		= sun4i_i2s_set_txchansel,
+	.set_rxchansel		= sun4i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
@@ -1113,8 +1144,6 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
 	.field_txchanmap	= REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
-	.field_txchansel	= REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
-	.field_rxchansel	= REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
 	.set_format		= sun8i_i2s_set_format,
@@ -1122,6 +1151,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.set_rxchanoffset	= sun8i_i2s_set_rxchanoffset,
 	.set_txchanen		= sun8i_i2s_set_txchanen,
 	.set_rxchanen		= sun8i_i2s_set_rxchanen,
+	.set_txchansel		= sun8i_i2s_set_txchansel,
+	.set_rxchansel		= sun8i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
@@ -1138,11 +1169,11 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
 	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
 	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
-	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
-	.field_rxchansel	= REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
+	.set_txchansel		= sun4i_i2s_set_txchansel,
+	.set_rxchansel		= sun4i_i2s_set_rxchansel,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
@@ -1199,19 +1230,7 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
 	i2s->field_rxchanmap =
 			devm_regmap_field_alloc(dev, i2s->regmap,
 						i2s->variant->field_rxchanmap);
-	if (IS_ERR(i2s->field_rxchanmap))
-		return PTR_ERR(i2s->field_rxchanmap);
-
-	i2s->field_txchansel =
-			devm_regmap_field_alloc(dev, i2s->regmap,
-						i2s->variant->field_txchansel);
-	if (IS_ERR(i2s->field_txchansel))
-		return PTR_ERR(i2s->field_txchansel);
-
-	i2s->field_rxchansel =
-			devm_regmap_field_alloc(dev, i2s->regmap,
-						i2s->variant->field_rxchansel);
-	return PTR_ERR_OR_ZERO(i2s->field_rxchansel);
+	return PTR_ERR_OR_ZERO(i2s->field_rxchanmap);
 }
 
 static int sun4i_i2s_probe(struct platform_device *pdev)
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 08/15] ASoC: sun4i-i2s: Add functions for channel mapping
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (6 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 07/15] ASoC: sun4i-i2s: Add functions for RX and TX channel selects codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate codekipper
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

As we will eventually add multi-channel audio support to the i2s
then create function calls as opposed to regmap fields to add
support for different devices.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 71 +++++++++++++++++++++----------------
 1 file changed, 40 insertions(+), 31 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 0b98adde0717..6de3cb41aaf6 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -141,8 +141,6 @@ struct sun4i_i2s;
  * @field_fmt_lrclk: regmap field to set frame polarity.
  * @field_fmt_mode: regmap field to set the operational mode.
  * @field_fmt_sext: regmap field to set the sign extension.
- * @field_txchanmap: location of the tx channel mapping register.
- * @field_rxchanmap: location of the rx channel mapping register.
  */
 struct sun4i_i2s_quirks {
 	bool				has_reset;
@@ -162,8 +160,6 @@ struct sun4i_i2s_quirks {
 	struct reg_field		field_fmt_lrclk;
 	struct reg_field		field_fmt_mode;
 	struct reg_field		field_fmt_sext;
-	struct reg_field		field_txchanmap;
-	struct reg_field		field_rxchanmap;
 
 	s8	(*get_sr)(const struct sun4i_i2s *, int);
 	s8	(*get_wss)(const struct sun4i_i2s *, int);
@@ -174,6 +170,8 @@ struct sun4i_i2s_quirks {
 	void	(*set_rxchanen)(const struct sun4i_i2s *, int);
 	void	(*set_txchansel)(const struct sun4i_i2s *, int, int);
 	void	(*set_rxchansel)(const struct sun4i_i2s *, int);
+	void	(*set_txchanmap)(const struct sun4i_i2s *, int, int);
+	void	(*set_rxchanmap)(const struct sun4i_i2s *, int);
 };
 
 struct sun4i_i2s {
@@ -195,8 +193,6 @@ struct sun4i_i2s {
 	struct regmap_field	*field_fmt_lrclk;
 	struct regmap_field	*field_fmt_mode;
 	struct regmap_field	*field_fmt_sext;
-	struct regmap_field	*field_txchanmap;
-	struct regmap_field	*field_rxchanmap;
 
 	const struct sun4i_i2s_quirks	*variant;
 
@@ -499,6 +495,31 @@ static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
 				   SUN8I_I2S_TX_CHAN_SEL(channel));
 }
 
+static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
+				    int channel)
+{
+	regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, channel);
+}
+
+static void sun8i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
+				    int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_write(i2s->regmap,
+			     SUN8I_I2S_TX_CHAN_MAP_REG + (output * 4), channel);
+	}
+}
+
+static void sun4i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, channel);
+}
+
+static void sun8i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, channel);
+}
+
 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
 			       struct snd_soc_dai *dai)
@@ -524,8 +545,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	/* Map the channels for playback and capture */
-	regmap_field_write(i2s->field_txchanmap, 0x76543210);
-	regmap_field_write(i2s->field_rxchanmap, 0x00003210);
+	i2s->variant->set_txchanmap(i2s, 0, 0x76543210);
+	i2s->variant->set_rxchanmap(i2s, 0x00003210);
 
 	/* Configure the channels */
 	i2s->variant->set_txchansel(i2s, 0, channels);
@@ -1077,13 +1098,13 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.has_slave_select_bit	= true,
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
-	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
-	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
 	.set_txchansel		= sun4i_i2s_set_txchansel,
 	.set_rxchansel		= sun4i_i2s_set_rxchansel,
+	.set_txchanmap		= sun4i_i2s_set_txchanmap,
+	.set_rxchanmap		= sun4i_i2s_set_rxchanmap,
 };
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
@@ -1098,13 +1119,13 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.has_slave_select_bit	= true,
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
-	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
-	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
 	.set_txchansel		= sun4i_i2s_set_txchansel,
 	.set_rxchansel		= sun4i_i2s_set_rxchansel,
+	.set_txchanmap		= sun4i_i2s_set_txchanmap,
+	.set_rxchanmap		= sun4i_i2s_set_rxchanmap,
 };
 
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
@@ -1118,13 +1139,13 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.has_slave_select_bit	= true,
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
-	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
-	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
 	.set_format		= sun4i_i2s_set_format,
 	.set_txchansel		= sun4i_i2s_set_txchansel,
 	.set_rxchansel		= sun4i_i2s_set_rxchansel,
+	.set_txchanmap		= sun4i_i2s_set_txchanmap,
+	.set_rxchanmap		= sun4i_i2s_set_rxchanmap,
 };
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
@@ -1142,8 +1163,6 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
-	.field_txchanmap	= REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
-	.field_rxchanmap	= REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.get_sr			= sun8i_i2s_get_sr_wss,
 	.get_wss		= sun8i_i2s_get_sr_wss,
 	.set_format		= sun8i_i2s_set_format,
@@ -1153,6 +1172,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.set_rxchanen		= sun8i_i2s_set_rxchanen,
 	.set_txchansel		= sun8i_i2s_set_txchansel,
 	.set_rxchansel		= sun8i_i2s_set_rxchansel,
+	.set_txchanmap		= sun8i_i2s_set_txchanmap,
+	.set_rxchanmap		= sun8i_i2s_set_rxchanmap,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
@@ -1167,13 +1188,13 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
 	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
 	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
-	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
-	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
 	.get_sr			= sun4i_i2s_get_sr,
 	.get_wss		= sun4i_i2s_get_wss,
 	.set_format		= sun4i_i2s_set_format,
 	.set_txchansel		= sun4i_i2s_set_txchansel,
 	.set_rxchansel		= sun4i_i2s_set_rxchansel,
+	.set_txchanmap		= sun4i_i2s_set_txchanmap,
+	.set_rxchanmap		= sun4i_i2s_set_rxchanmap,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
@@ -1218,19 +1239,7 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
 	i2s->field_fmt_sext =
 			devm_regmap_field_alloc(dev, i2s->regmap,
 						i2s->variant->field_fmt_sext);
-	if (IS_ERR(i2s->field_fmt_sext))
-		return PTR_ERR(i2s->field_fmt_sext);
-
-	i2s->field_txchanmap =
-			devm_regmap_field_alloc(dev, i2s->regmap,
-						i2s->variant->field_txchanmap);
-	if (IS_ERR(i2s->field_txchanmap))
-		return PTR_ERR(i2s->field_txchanmap);
-
-	i2s->field_rxchanmap =
-			devm_regmap_field_alloc(dev, i2s->regmap,
-						i2s->variant->field_rxchanmap);
-	return PTR_ERR_OR_ZERO(i2s->field_rxchanmap);
+	return PTR_ERR_OR_ZERO(i2s->field_fmt_sext);
 }
 
 static int sun4i_i2s_probe(struct platform_device *pdev)
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (7 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 08/15] ASoC: sun4i-i2s: Add functions for channel mapping codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-21  4:07   ` [linux-sunxi] " Chen-Yu Tsai
  2019-08-21  9:19   ` Code Kipper
  2019-08-14  6:08 ` [PATCH v5 10/15] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible codekipper
                   ` (5 subsequent siblings)
  14 siblings, 2 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: Jernej Skrabec, alsa-devel, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Jernej Skrabec <jernej.skrabec@siol.net>

I2S doesn't work if parent rate couldn't be change. Difference between
wanted and actual rate is too big.

Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index aebef4af9861..d89353a3cdec 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -505,7 +505,7 @@ static struct ccu_div i2s3_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("i2s3",
 						      audio_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_SET_RATE_PARENT),
 	},
 };
 
@@ -518,7 +518,7 @@ static struct ccu_div i2s0_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("i2s0",
 						      audio_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_SET_RATE_PARENT),
 	},
 };
 
@@ -531,7 +531,7 @@ static struct ccu_div i2s1_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("i2s1",
 						      audio_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_SET_RATE_PARENT),
 	},
 };
 
@@ -544,7 +544,7 @@ static struct ccu_div i2s2_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("i2s2",
 						      audio_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_SET_RATE_PARENT),
 	},
 };
 
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 10/15] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (8 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S codekipper
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: Jernej Skrabec, alsa-devel, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 I2S is very similar to H3, except that it supports up to 16 channels
and thus few registers have fields on different position.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml      | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
index eb3992138eec..6928d0a1dcc8 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
@@ -24,6 +24,7 @@ properties:
       - items:
           - const: allwinner,sun50i-a64-i2s
           - const: allwinner,sun8i-h3-i2s
+      - const: allwinner,sun50i-h6-i2s
 
   reg:
     maxItems: 1
@@ -59,6 +60,7 @@ allOf:
               - allwinner,sun8i-a83t-i2s
               - allwinner,sun8i-h3-i2s
               - allwinner,sun50i-a64-codec-i2s
+              - allwinner,sun50i-h6-i2s
 
     then:
       required:
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (9 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 10/15] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:57   ` Jernej Škrabec
  2019-08-14  6:08 ` [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality codekipper
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: Jernej Skrabec, alsa-devel, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 I2S is very similar to that in H3, except it supports up to 16
channels.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 sound/soc/sunxi/sun4i-i2s.c | 148 ++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 6de3cb41aaf6..a8d98696fe7c 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -121,6 +121,21 @@
 #define SUN8I_I2S_RX_CHAN_SEL_REG	0x54
 #define SUN8I_I2S_RX_CHAN_MAP_REG	0x58
 
+/* Defines required for sun50i-h6 support */
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK	GENMASK(21, 20)
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)	((offset) << 20)
+#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK		GENMASK(19, 16)
+#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)		((chan - 1) << 16)
+#define SUN50I_H6_I2S_TX_CHAN_EN_MASK		GENMASK(15, 0)
+#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)	(((1 << num_chan) - 1))
+
+#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG	0x44
+#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG	0x48
+
+#define SUN50I_H6_I2S_RX_CHAN_SEL_REG	0x64
+#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG	0x68
+#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG	0x6C
+
 struct sun4i_i2s;
 
 /**
@@ -440,6 +455,25 @@ static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
 			   SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
 }
 
+static void sun50i_h6_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
+				   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
+	}
+
+}
+
+static void sun50i_h6_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
+{
+	regmap_update_bits(i2s->regmap,
+			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
+			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
+			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
+}
+
 static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
 				   int channel)
 {
@@ -459,6 +493,26 @@ static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
 			   SUN8I_I2S_TX_CHAN_EN(channel));
 }
 
+
+static void sun50i_h6_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
+				       int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
+				   SUN50I_H6_I2S_TX_CHAN_EN(channel));
+	}
+}
+
+static void sun50i_h6_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_update_bits(i2s->regmap,
+			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
+			   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
+			   SUN50I_H6_I2S_TX_CHAN_EN(channel));
+}
+
 static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
 				    int channel)
 {
@@ -495,6 +549,25 @@ static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
 				   SUN8I_I2S_TX_CHAN_SEL(channel));
 }
 
+static void sun50i_h6_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
+				       int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_update_bits(i2s->regmap,
+				   SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
+				   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
+				   SUN50I_H6_I2S_TX_CHAN_SEL(channel));
+	}
+}
+
+static void sun50i_h6_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_update_bits(i2s->regmap,
+			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
+			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
+			   SUN50I_H6_I2S_TX_CHAN_SEL(channel));
+}
+
 static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
 				    int channel)
 {
@@ -520,6 +593,20 @@ static void sun8i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
 	regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, channel);
 }
 
+static void sun50i_h6_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
+				       int channel)
+{
+	if (output >= 0 && output < 4) {
+		regmap_write(i2s->regmap,
+			     SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output * 8), channel);
+	}
+}
+
+static void sun50i_h6_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
+{
+	regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, channel);
+}
+
 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
 			       struct snd_soc_dai *dai)
@@ -996,6 +1083,22 @@ static const struct reg_default sun8i_i2s_reg_defaults[] = {
 	{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
 };
 
+static const struct reg_default sun50i_i2s_reg_defaults[] = {
+	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
+	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
+	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
+	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
+	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
+	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
+	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
+	{ SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
+	{ SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 },
+	{ SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 },
+	{ SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
+	{ SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
+	{ SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
+};
+
 static const struct regmap_config sun4i_i2s_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -1023,6 +1126,19 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
 	.volatile_reg	= sun8i_i2s_volatile_reg,
 };
 
+static const struct regmap_config sun50i_i2s_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= SUN50I_H6_I2S_RX_CHAN_MAP1_REG,
+	.cache_type	= REGCACHE_FLAT,
+	.reg_defaults	= sun50i_i2s_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(sun50i_i2s_reg_defaults),
+	.writeable_reg	= sun4i_i2s_wr_reg,
+	.readable_reg	= sun8i_i2s_rd_reg,
+	.volatile_reg	= sun8i_i2s_volatile_reg,
+};
+
 static int sun4i_i2s_runtime_resume(struct device *dev)
 {
 	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
@@ -1197,6 +1313,34 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.set_rxchanmap		= sun4i_i2s_set_rxchanmap,
 };
 
+static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
+	.has_reset		= true,
+	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
+	.sun4i_i2s_regmap	= &sun50i_i2s_regmap_config,
+	.has_fmt_set_lrck_period = true,
+	.has_chcfg		= true,
+	.has_chsel_tx_chen	= true,
+	.has_chsel_offset	= true,
+	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
+	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
+	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
+	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
+	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
+	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
+	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
+	.get_sr			= sun8i_i2s_get_sr_wss,
+	.get_wss		= sun8i_i2s_get_sr_wss,
+	.set_format		= sun8i_i2s_set_format,
+	.set_txchanoffset	= sun50i_h6_i2s_set_txchanoffset,
+	.set_rxchanoffset	= sun50i_h6_i2s_set_rxchanoffset,
+	.set_txchanen		= sun50i_h6_i2s_set_txchanen,
+	.set_rxchanen		= sun50i_h6_i2s_set_rxchanen,
+	.set_txchansel		= sun50i_h6_i2s_set_txchansel,
+	.set_rxchansel		= sun50i_h6_i2s_set_rxchansel,
+	.set_txchanmap		= sun50i_h6_i2s_set_txchanmap,
+	.set_rxchanmap		= sun50i_h6_i2s_set_rxchanmap,
+};
+
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
 					struct sun4i_i2s *i2s)
 {
@@ -1389,6 +1533,10 @@ static const struct of_device_id sun4i_i2s_match[] = {
 		.compatible = "allwinner,sun50i-a64-codec-i2s",
 		.data = &sun50i_a64_codec_i2s_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-i2s",
+		.data = &sun50i_h6_i2s_quirks,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (10 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:20   ` Maxime Ripard
  2019-08-14  8:27   ` [linux-sunxi] " Jernej Škrabec
  2019-08-14  6:08 ` [PATCH v5 13/15] ASoC: sun4i-i2s: Add multichannel functionality codekipper
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

The i2s block supports multi-lane i2s output however this functionality
is only possible in earlier SoCs where the pins are exposed and for
the i2s block used for HDMI audio on the later SoCs.

To enable this functionality, an optional property has been added to
the bindings.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a8d98696fe7c..a020c3b372a8 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -23,7 +23,7 @@
 
 #define SUN4I_I2S_CTRL_REG		0x00
 #define SUN4I_I2S_CTRL_SDO_EN_MASK		GENMASK(11, 8)
-#define SUN4I_I2S_CTRL_SDO_EN(sdo)			BIT(8 + (sdo))
+#define SUN4I_I2S_CTRL_SDO_EN(lines)		(((1 << lines) - 1) << 8)
 #define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
 #define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
 #define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
@@ -614,6 +614,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 	int sr, wss, channels;
 	u32 width;
+	int lines;
 
 	channels = params_channels(params);
 	if (channels != 2) {
@@ -622,6 +623,13 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
+	lines = (channels + 1) / 2;
+
+	/* Enable the required output lines */
+	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+			   SUN4I_I2S_CTRL_SDO_EN_MASK,
+			   SUN4I_I2S_CTRL_SDO_EN(lines));
+
 	if (i2s->variant->has_chcfg) {
 		regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 				   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
@@ -1389,9 +1397,10 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
 static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
+	struct snd_soc_dai_driver *soc_dai;
 	struct resource *res;
 	void __iomem *regs;
-	int irq, ret;
+	int irq, ret, val;
 
 	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
 	if (!i2s)
@@ -1456,6 +1465,19 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 	i2s->capture_dma_data.maxburst = 8;
 
+	soc_dai = devm_kmemdup(&pdev->dev, &sun4i_i2s_dai,
+			       sizeof(*soc_dai), GFP_KERNEL);
+	if (!soc_dai) {
+		ret = -ENOMEM;
+		goto err_pm_disable;
+	}
+
+	if (!of_property_read_u32(pdev->dev.of_node,
+				  "allwinner,playback-channels", &val)) {
+		if (val >= 2 && val <= 8)
+			soc_dai->playback.channels_max = val;
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
@@ -1465,7 +1487,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 
 	ret = devm_snd_soc_register_component(&pdev->dev,
 					      &sun4i_i2s_component,
-					      &sun4i_i2s_dai, 1);
+					      soc_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Could not register DAI\n");
 		goto err_suspend;
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 13/15] ASoC: sun4i-i2s: Add multichannel functionality
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (11 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  6:08 ` [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support codekipper
  2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
  14 siblings, 0 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

The i2s block can be used to pass PCM data over multiple channels
and is sometimes used for the audio side of an HDMI connection.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 93 +++++++++++++++++++++++++------------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a020c3b372a8..a71969167053 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -617,41 +617,74 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	int lines;
 
 	channels = params_channels(params);
-	if (channels != 2) {
-		dev_err(dai->dev, "Unsupported number of channels: %d\n",
-			channels);
-		return -EINVAL;
-	}
-
-	lines = (channels + 1) / 2;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		if ((channels > dai->driver->playback.channels_max) ||
+			(channels < dai->driver->playback.channels_min)) {
+			dev_err(dai->dev, "Unsupported number of channels: %d\n",
+				channels);
+			return -EINVAL;
+		}
 
-	/* Enable the required output lines */
-	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
-			   SUN4I_I2S_CTRL_SDO_EN_MASK,
-			   SUN4I_I2S_CTRL_SDO_EN(lines));
-
-	if (i2s->variant->has_chcfg) {
-		regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
-				   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
-				   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
-		regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
-				   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
-				   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
-	}
+		lines = (channels + 1) / 2;
 
-	/* Map the channels for playback and capture */
-	i2s->variant->set_txchanmap(i2s, 0, 0x76543210);
-	i2s->variant->set_rxchanmap(i2s, 0x00003210);
+		/* Enable the required output lines */
+		regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+				   SUN4I_I2S_CTRL_SDO_EN_MASK,
+				   SUN4I_I2S_CTRL_SDO_EN(lines));
+
+		i2s->variant->set_txchanmap(i2s, 0, 0x10);
+		i2s->variant->set_txchansel(i2s, 0, channels > 1 ? 2:1);
+
+		if (i2s->variant->set_txchanen)
+			i2s->variant->set_txchanen(i2s, 0, 2);
+
+		if (i2s->variant->has_chcfg) {
+			regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
+					   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
+					   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
+
+			if (channels > 2) {
+				i2s->variant->set_txchanmap(i2s, 1, 0x32);
+				i2s->variant->set_txchanoffset(i2s, 1);
+				i2s->variant->set_txchansel(i2s, 1,
+							    channels > 3 ? 2:1);
+				i2s->variant->set_txchanen(i2s, 1, 2);
+			}
+			if (channels > 4) {
+				i2s->variant->set_txchanmap(i2s, 2, 0x54);
+				i2s->variant->set_txchanoffset(i2s, 2);
+				i2s->variant->set_txchansel(i2s, 2,
+							    channels > 5 ? 2:1);
+				i2s->variant->set_txchanen(i2s, 2, 2);
+			}
+			if (channels > 6) {
+				i2s->variant->set_txchanmap(i2s, 3, 0x76);
+				i2s->variant->set_txchanoffset(i2s, 3);
+				i2s->variant->set_txchansel(i2s, 3,
+							    channels > 6 ? 2:1);
+				i2s->variant->set_txchanen(i2s, 3, 2);
+			}
+		}
+	} else {
+		if ((channels > dai->driver->capture.channels_max) ||
+			(channels < dai->driver->capture.channels_min)) {
+			dev_err(dai->dev, "Unsupported number of channels: %d\n",
+				channels);
+			return -EINVAL;
+		}
 
-	/* Configure the channels */
-	i2s->variant->set_txchansel(i2s, 0, channels);
-	i2s->variant->set_rxchansel(i2s, channels);
+		/* Map the channels for capture */
+		i2s->variant->set_rxchanmap(i2s, 0x10);
+		i2s->variant->set_rxchansel(i2s, channels);
 
-	if (i2s->variant->set_txchanen)
-		i2s->variant->set_txchanen(i2s, 0, channels);
+		if (i2s->variant->set_rxchanen)
+			i2s->variant->set_rxchanen(i2s, channels);
 
-	if (i2s->variant->set_rxchanen)
-		i2s->variant->set_rxchanen(i2s, channels);
+		if (i2s->variant->has_chcfg)
+			regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
+					   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
+					   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
+	}
 
 	switch (params_physical_width(params)) {
 	case 16:
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (12 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 13/15] ASoC: sun4i-i2s: Add multichannel functionality codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  8:28   ` [linux-sunxi] " Jernej Škrabec
  2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
  14 siblings, 1 reply; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Extend the functionality of the driver to include support of 20 and
24 bits per sample for the earlier SoCs.

Newer SoCs can also handle 32bit samples.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a71969167053..d3c8789f70bb 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -690,6 +690,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 	case 16:
 		width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 		break;
+	case 20:
+	case 24:
+	case 32:
+		width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+		break;
 	default:
 		dev_err(dai->dev, "Unsupported physical sample width: %d\n",
 			params_physical_width(params));
@@ -1015,6 +1020,13 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 	return 0;
 }
 
+#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
+			 SNDRV_PCM_FMTBIT_S20_LE | \
+			 SNDRV_PCM_FMTBIT_S24_LE)
+
+#define SUN8I_FORMATS	(SUN4I_FORMATS | \
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
 static struct snd_soc_dai_driver sun4i_i2s_dai = {
 	.probe = sun4i_i2s_dai_probe,
 	.capture = {
@@ -1022,14 +1034,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		.formats = SUN4I_FORMATS,
 	},
 	.playback = {
 		.stream_name = "Playback",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		.formats = SUN4I_FORMATS,
 	},
 	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rates = 1,
@@ -1505,6 +1517,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		goto err_pm_disable;
 	}
 
+	if (i2s->variant->has_fmt_set_lrck_period) {
+		soc_dai->playback.formats = SUN8I_FORMATS;
+		soc_dai->capture.formats = SUN8I_FORMATS;
+	}
+
 	if (!of_property_read_u32(pdev->dev.of_node,
 				  "allwinner,playback-channels", &val)) {
 		if (val >= 2 && val <= 8)
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
                   ` (13 preceding siblings ...)
  2019-08-14  6:08 ` [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support codekipper
@ 2019-08-14  6:08 ` codekipper
  2019-08-14  7:20   ` Maxime Ripard
                     ` (2 more replies)
  14 siblings, 3 replies; 43+ messages in thread
From: codekipper @ 2019-08-14  6:08 UTC (permalink / raw)
  To: maxime.ripard, wens, linux-sunxi
  Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
	broonie, linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
to reflect this.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 31 ++++++++++---------------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index d3c8789f70bb..ecfc1ed79379 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -876,9 +876,11 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
 {
 	/* Flush RX FIFO */
+	regcache_cache_bypass(i2s->regmap, true);
 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
 			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
+	regcache_cache_bypass(i2s->regmap, false);
 
 	/* Clear RX counter */
 	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
@@ -897,9 +899,11 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 {
 	/* Flush TX FIFO */
+	regcache_cache_bypass(i2s->regmap, true);
 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
 			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
+	regcache_cache_bypass(i2s->regmap, false);
 
 	/* Clear TX counter */
 	regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
@@ -1053,13 +1057,7 @@ static const struct snd_soc_component_driver sun4i_i2s_component = {
 
 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
 {
-	switch (reg) {
-	case SUN4I_I2S_FIFO_TX_REG:
-		return false;
-
-	default:
-		return true;
-	}
+	return true;
 }
 
 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
@@ -1078,6 +1076,8 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case SUN4I_I2S_FIFO_RX_REG:
+	case SUN4I_I2S_FIFO_TX_REG:
+	case SUN4I_I2S_FIFO_STA_REG:
 	case SUN4I_I2S_INT_STA_REG:
 	case SUN4I_I2S_RX_CNT_REG:
 	case SUN4I_I2S_TX_CNT_REG:
@@ -1088,23 +1088,12 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 	}
 }
 
-static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case SUN8I_I2S_FIFO_TX_REG:
-		return false;
-
-	default:
-		return true;
-	}
-}
-
 static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 {
 	if (reg == SUN8I_I2S_INT_STA_REG)
 		return true;
 	if (reg == SUN8I_I2S_FIFO_TX_REG)
-		return false;
+		return true;
 
 	return sun4i_i2s_volatile_reg(dev, reg);
 }
@@ -1175,7 +1164,7 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
 	.reg_defaults	= sun8i_i2s_reg_defaults,
 	.num_reg_defaults	= ARRAY_SIZE(sun8i_i2s_reg_defaults),
 	.writeable_reg	= sun4i_i2s_wr_reg,
-	.readable_reg	= sun8i_i2s_rd_reg,
+	.readable_reg	= sun4i_i2s_rd_reg,
 	.volatile_reg	= sun8i_i2s_volatile_reg,
 };
 
@@ -1188,7 +1177,7 @@ static const struct regmap_config sun50i_i2s_regmap_config = {
 	.reg_defaults	= sun50i_i2s_reg_defaults,
 	.num_reg_defaults	= ARRAY_SIZE(sun50i_i2s_reg_defaults),
 	.writeable_reg	= sun4i_i2s_wr_reg,
-	.readable_reg	= sun8i_i2s_rd_reg,
+	.readable_reg	= sun4i_i2s_rd_reg,
 	.volatile_reg	= sun8i_i2s_volatile_reg,
 };
 
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample
  2019-08-14  6:08 ` [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample codekipper
@ 2019-08-14  6:43   ` Maxime Ripard
  2019-08-14 11:24     ` Code Kipper
  0 siblings, 1 reply; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  6:43 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 4571 bytes --]

Hi,

On Wed, Aug 14, 2019 at 08:08:40AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> On the newer SoCs such as the H3 and A64 this is set by default
> to transfer a 0 after each sample in each slot. However the A10
> and A20 SoCs that this driver was developed on had a default
> setting where it padded the audio gain with zeros.
>
> This isn't a problem whilst we have only support for 16bit audio
> but with larger sample resolution rates in the pipeline then SEXT
> bits should be cleared so that they also pad at the LSB. Without
> this the audio gets distorted.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 793457394efe..8201334a059b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -135,6 +135,7 @@ struct sun4i_i2s;
>   * @field_fmt_bclk: regmap field to set clk polarity.
>   * @field_fmt_lrclk: regmap field to set frame polarity.
>   * @field_fmt_mode: regmap field to set the operational mode.
> + * @field_fmt_sext: regmap field to set the sign extension.
>   * @field_txchanmap: location of the tx channel mapping register.
>   * @field_rxchanmap: location of the rx channel mapping register.
>   * @field_txchansel: location of the tx channel select bit fields.
> @@ -159,6 +160,7 @@ struct sun4i_i2s_quirks {
>  	struct reg_field		field_fmt_bclk;
>  	struct reg_field		field_fmt_lrclk;
>  	struct reg_field		field_fmt_mode;
> +	struct reg_field		field_fmt_sext;
>  	struct reg_field		field_txchanmap;
>  	struct reg_field		field_rxchanmap;
>  	struct reg_field		field_txchansel;
> @@ -186,6 +188,7 @@ struct sun4i_i2s {
>  	struct regmap_field	*field_fmt_bclk;
>  	struct regmap_field	*field_fmt_lrclk;
>  	struct regmap_field	*field_fmt_mode;
> +	struct regmap_field	*field_fmt_sext;
>  	struct regmap_field	*field_txchanmap;
>  	struct regmap_field	*field_rxchanmap;
>  	struct regmap_field	*field_txchansel;
> @@ -345,6 +348,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
>  				   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
>  				   SUN8I_I2S_FMT0_LRCK_PERIOD(32));
>
> +	/* Set sign extension to pad out LSB with 0 */
> +	regmap_field_write(i2s->field_fmt_sext, 0);
> +
>  	return 0;
>  }
>
> @@ -917,6 +923,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
>  	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
>  	.has_slave_select_bit	= true,
>  	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> +	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
>  	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
>  	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
>  	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
> @@ -936,6 +943,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
>  	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
>  	.has_slave_select_bit	= true,
>  	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> +	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
>  	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
>  	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
>  	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
> @@ -979,6 +987,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
>  	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
>  	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
>  	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
> +	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
>  	.field_txchanmap	= REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
>  	.field_rxchanmap	= REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
>  	.field_txchansel	= REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
> @@ -998,6 +1007,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
>  	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
>  	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
>  	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> +	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
>  	.field_txchanmap	= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
>  	.field_rxchanmap	= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
>  	.field_txchansel	= REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),

You're missing the A83t here

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality
  2019-08-14  6:08 ` [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality codekipper
@ 2019-08-14  7:09   ` Maxime Ripard
  2019-08-16  6:27     ` Code Kipper
  2019-08-14  9:30   ` Mark Brown
  1 sibling, 1 reply; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  7:09 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 1992 bytes --]

Hi,

On Wed, Aug 14, 2019 at 08:08:41AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> Codecs without a control connection such as i2s based HDMI audio and
> the Pine64 DAC require a different amount of bit clocks per frame than
> what is calculated by the sample width. Use the tdm slot bindings to
> provide this mechanism.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 23 +++++++++++++++++++++--
>  1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 8201334a059b..7c37b6291df0 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -195,6 +195,9 @@ struct sun4i_i2s {
>  	struct regmap_field	*field_rxchansel;
>
>  	const struct sun4i_i2s_quirks	*variant;
> +
> +	unsigned int	tdm_slots;
> +	unsigned int	slot_width;
>  };
>
>  struct sun4i_i2s_clk_div {
> @@ -346,7 +349,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
>  	if (i2s->variant->has_fmt_set_lrck_period)
>  		regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
>  				   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
> -				   SUN8I_I2S_FMT0_LRCK_PERIOD(32));
> +				   SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
>
>
>  	/* Set sign extension to pad out LSB with 0 */
>  	regmap_field_write(i2s->field_fmt_sext, 0);
> @@ -450,7 +453,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
>  	regmap_field_write(i2s->field_fmt_sr, sr);
>
>  	return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> -				      params_width(params));
> +				      i2s->tdm_slots ?
> +				      i2s->slot_width : params_width(params));

This is slightly more complicated than that.

On the H3 (and all related ones), the CHAN_CFG_TX_SLOT_NUM and
_RX_SLOT_NUM fields in the CHAN_CFG register need to be set to the
number of slots as well.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations
  2019-08-14  6:08 ` [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations codekipper
@ 2019-08-14  7:13   ` Maxime Ripard
  2019-08-14  9:31   ` Mark Brown
  1 sibling, 0 replies; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  7:13 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 3322 bytes --]

Hi,

(I just noticed this, but can you update my mail address, it's not
@free-electrons for quite a while, you probably want to change your
scripts to use mripard@kernel.org)

On Wed, Aug 14, 2019 at 08:08:42AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> The clock division circuitry is different on the H3 and later SoCs.
> The division of bclk is now based on pll2.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 73 +++++++++++++++++++++++++------------
>  1 file changed, 49 insertions(+), 24 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 7c37b6291df0..34f31439ae7b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -127,8 +127,6 @@ struct sun4i_i2s;
>   * @has_chsel_offset: SoC uses offset for selecting dai operational mode.
>   * @reg_offset_txdata: offset of the tx fifo.
>   * @sun4i_i2s_regmap: regmap config to use.
> - * @mclk_offset: Value by which mclkdiv needs to be adjusted.
> - * @bclk_offset: Value by which bclkdiv needs to be adjusted.
>   * @field_clkdiv_mclk_en: regmap field to enable mclk output.
>   * @field_fmt_wss: regmap field to set word select size.
>   * @field_fmt_sr: regmap field to set sample resolution.
> @@ -150,8 +148,6 @@ struct sun4i_i2s_quirks {
>  	bool				has_chsel_offset;
>  	unsigned int			reg_offset_txdata;	/* TX FIFO */
>  	const struct regmap_config	*sun4i_i2s_regmap;
> -	unsigned int			mclk_offset;
> -	unsigned int			bclk_offset;
>
>  	/* Register fields for i2s */
>  	struct reg_field		field_clkdiv_mclk_en;
> @@ -212,7 +208,25 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>  	{ .div = 8, .val = 3 },
>  	{ .div = 12, .val = 4 },
>  	{ .div = 16, .val = 5 },
> -	/* TODO - extend divide ratio supported by newer SoCs */
> +};
> +
> +static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
> +	{ .div = 0, .val = 0 },

Having a divider of 0 seems like a bad idea.

> +	{ .div = 1, .val = 1 },
> +	{ .div = 2, .val = 2 },
> +	{ .div = 4, .val = 3 },
> +	{ .div = 6, .val = 4 },
> +	{ .div = 8, .val = 5 },
> +	{ .div = 12, .val = 6 },
> +	{ .div = 16, .val = 7 },
> +	{ .div = 24, .val = 8 },
> +	{ .div = 32, .val = 9 },
> +	{ .div = 48, .val = 10 },
> +	{ .div = 64, .val = 11 },
> +	{ .div = 96, .val = 12 },
> +	{ .div = 128, .val = 13 },
> +	{ .div = 176, .val = 14 },
> +	{ .div = 192, .val = 15 },
>  };
>
>  static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
> @@ -224,21 +238,21 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
>  	{ .div = 12, .val = 5 },
>  	{ .div = 16, .val = 6 },
>  	{ .div = 24, .val = 7 },
> -	/* TODO - extend divide ratio supported by newer SoCs */
>  };
>
>  static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
>  				  unsigned int oversample_rate,
> -				  unsigned int word_size)
> +				  unsigned int word_size,
> +				  const struct sun4i_i2s_clk_div *bdiv,
> +				  unsigned int size)

Wouldn't it be simpler to just have the divider list in the variant
structure? It would avoid having to refactor all the functions, and
it's not like it's really going to change from one call to another
anyway.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs
  2019-08-14  6:08 ` [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs codekipper
@ 2019-08-14  7:16   ` Maxime Ripard
  2019-08-14 11:23     ` Code Kipper
  0 siblings, 1 reply; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  7:16 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 4892 bytes --]

On Wed, Aug 14, 2019 at 08:08:43AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> There is a need to support more formats on the newer SoCs(H3 and later).
> Extend the formats supported to include DSP_A and DSP_B modes.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 87 +++++++++++++++++++++++++++----------
>  1 file changed, 63 insertions(+), 24 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 34f31439ae7b..3553c17318b0 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -27,6 +27,8 @@
>  #define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
>  #define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
>  #define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
> +#define SUN4I_I2S_CTRL_PCM			BIT(4)
> +#define SUN4I_I2S_CTRL_LOOP			BIT(3)
>  #define SUN4I_I2S_CTRL_TX_EN			BIT(2)
>  #define SUN4I_I2S_CTRL_RX_EN			BIT(1)
>  #define SUN4I_I2S_CTRL_GL_EN			BIT(0)
> @@ -91,6 +93,9 @@
>  /* Defines required for sun8i-h3 support */
>  #define SUN8I_I2S_CTRL_BCLK_OUT			BIT(18)
>  #define SUN8I_I2S_CTRL_LRCK_OUT			BIT(17)
> +#define SUN8I_I2S_CTRL_MODE_RIGHT_J			(2 << 0)
> +#define SUN8I_I2S_CTRL_MODE_I2S_LEFT_J			(1 << 0)
> +#define SUN8I_I2S_CTRL_MODE_PCM				(0 << 0)
>
>  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK		GENMASK(17, 8)
>  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)	((period - 1) << 8)
> @@ -164,6 +169,7 @@ struct sun4i_i2s_quirks {
>
>  	s8	(*get_sr)(const struct sun4i_i2s *, int);
>  	s8	(*get_wss)(const struct sun4i_i2s *, int);
> +	int	(*set_format)(struct sun4i_i2s *, unsigned int);
>  };
>
>  struct sun4i_i2s {
> @@ -194,6 +200,7 @@ struct sun4i_i2s {
>
>  	unsigned int	tdm_slots;
>  	unsigned int	slot_width;
> +	unsigned int	offset;
>  };
>
>  struct sun4i_i2s_clk_div {
> @@ -484,19 +491,14 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
>  				      i2s->slot_width : params_width(params));
>  }
>
> -static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +static int sun4i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
>  {
> -	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>  	u32 val;
> -	u32 offset = 0;
> -	u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
> -	u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
>
>  	/* DAI Mode */
>  	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
>  	case SND_SOC_DAIFMT_I2S:
>  		val = SUN4I_I2S_FMT0_FMT_I2S;
> -		offset = 1;
>  		break;
>  	case SND_SOC_DAIFMT_LEFT_J:
>  		val = SUN4I_I2S_FMT0_FMT_LEFT_J;
> @@ -505,32 +507,64 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>  		val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
>  		break;
>  	default:
> -		dev_err(dai->dev, "Unsupported format: %d\n",
> -			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
>  		return -EINVAL;
>  	}
>
> -	if (i2s->variant->has_chsel_offset) {
> -		/*
> -		 * offset being set indicates that we're connected to an i2s
> -		 * device, however offset is only used on the sun8i block and
> -		 * i2s shares the same setting with the LJ format. Increment
> -		 * val so that the bit to value to write is correct.
> -		 */
> -		if (offset > 0)
> -			val++;
> -		/* blck offset determines whether i2s or LJ */
> -		regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
> -				   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
> -				   SUN8I_I2S_TX_CHAN_OFFSET(offset));
> +	regmap_field_write(i2s->field_fmt_mode, val);
> +
> +	return 0;
> +}
> +
> +static int sun8i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
> +{
> +	u32 val;
>
> -		regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
> -				   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
> -				   SUN8I_I2S_TX_CHAN_OFFSET(offset));
> +	/* DAI Mode */
> +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> +	case SND_SOC_DAIFMT_I2S:
> +		i2s->offset = 1;
> +	case SND_SOC_DAIFMT_LEFT_J:
> +		val = SUN8I_I2S_CTRL_MODE_I2S_LEFT_J;
> +		break;
> +	case SND_SOC_DAIFMT_RIGHT_J:
> +		val = SUN8I_I2S_CTRL_MODE_RIGHT_J;
> +		break;
> +	case SND_SOC_DAIFMT_DSP_A:
> +		i2s->offset = 1;
> +	case SND_SOC_DAIFMT_DSP_B:
> +		val = SUN8I_I2S_CTRL_MODE_PCM;
> +		break;
> +
> +	default:
> +		return -EINVAL;
>  	}
>
> +	/*
> +	 * bclk offset determines whether i2s or LJ if in i2s mode and
> +	 * DSP_A or DSP_B if in PCM mode.
> +	 */
> +	i2s->variant->set_txchanoffset(i2s, 0);
> +	i2s->variant->set_rxchanoffset(i2s);
> +
>  	regmap_field_write(i2s->field_fmt_mode, val);

It's a bit more complicated in the sun8i case. The LRCK period also
needs to be changed when in PCM / DSP_* mode since it changes from a
number of periods for one channel to a number of periods for all the
channels.

I have patches that still need a bit of rework and take care of all of
that, I'll try to post them by the end of the week

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
@ 2019-08-14  7:20   ` Maxime Ripard
  2019-08-14 11:31     ` [linux-sunxi] " Jernej Škrabec
  2019-08-14  8:37   ` [linux-sunxi] " Jernej Škrabec
  2019-08-14 11:31   ` Chen-Yu Tsai
  2 siblings, 1 reply; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  7:20 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 506 bytes --]

On Wed, Aug 14, 2019 at 08:08:54AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
> to reflect this.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>

This patch looks like it's fixing something while the commit log
doesn't mention what is being fixed.

Having some context here would be great.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality
  2019-08-14  6:08 ` [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality codekipper
@ 2019-08-14  7:20   ` Maxime Ripard
  2019-08-14 11:16     ` Code Kipper
  2019-08-14  8:27   ` [linux-sunxi] " Jernej Škrabec
  1 sibling, 1 reply; 43+ messages in thread
From: Maxime Ripard @ 2019-08-14  7:20 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-sunxi, linux-kernel, lgirdwood, be17068, wens,
	broonie, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 651 bytes --]

On Wed, Aug 14, 2019 at 08:08:51AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> The i2s block supports multi-lane i2s output however this functionality
> is only possible in earlier SoCs where the pins are exposed and for
> the i2s block used for HDMI audio on the later SoCs.
>
> To enable this functionality, an optional property has been added to
> the bindings.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>

Wasn't the plan to support only stereo for now?

Either way, that property should be documented.

Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S
  2019-08-14  6:08 ` [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S codekipper
@ 2019-08-14  7:57   ` Jernej Škrabec
  2019-08-14 11:08     ` Code Kipper
  0 siblings, 1 reply; 43+ messages in thread
From: Jernej Škrabec @ 2019-08-14  7:57 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-kernel, wens, lgirdwood, be17068, linux-sunxi,
	broonie, maxime.ripard, linux-arm-kernel

Hi!

Dne sreda, 14. avgust 2019 ob 08:08:50 CEST je codekipper@gmail.com 
napisal(a):
> From: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> H6 I2S is very similar to that in H3, except it supports up to 16
> channels.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Your Signed-off-by is missing here and on all other patches made originally by 
me.

Best regards,
Jernej

> ---
>  sound/soc/sunxi/sun4i-i2s.c | 148 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 6de3cb41aaf6..a8d98696fe7c 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -121,6 +121,21 @@
>  #define SUN8I_I2S_RX_CHAN_SEL_REG	0x54
>  #define SUN8I_I2S_RX_CHAN_MAP_REG	0x58
> 
> +/* Defines required for sun50i-h6 support */
> +#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK	GENMASK(21, 20)
> +#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)	((offset) << 20)
> +#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK		GENMASK(19, 16)
> +#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)		((chan - 1) << 16)
> +#define SUN50I_H6_I2S_TX_CHAN_EN_MASK		GENMASK(15, 0)
> +#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)	(((1 << num_chan) - 1))
> +
> +#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG	0x44
> +#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG	0x48
> +
> +#define SUN50I_H6_I2S_RX_CHAN_SEL_REG	0x64
> +#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG	0x68
> +#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG	0x6C
> +
>  struct sun4i_i2s;
> 
>  /**
> @@ -440,6 +455,25 @@ static void sun8i_i2s_set_rxchanoffset(const struct
> sun4i_i2s *i2s) SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
>  }
> 
> +static void sun50i_h6_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int
> output) +{
> +	if (output >= 0 && output < 4) {
> +		regmap_update_bits(i2s->regmap,
> +				   SUN8I_I2S_TX_CHAN_SEL_REG + 
(output * 4),
> +				   
SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
> +				   
SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
> +	}
> +
> +}
> +
> +static void sun50i_h6_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
> +{
> +	regmap_update_bits(i2s->regmap,
> +			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> +			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
> +			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s-
>offset));
> +}
> +
>  static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
> int channel)
>  {
> @@ -459,6 +493,26 @@ static void sun8i_i2s_set_rxchanen(const struct
> sun4i_i2s *i2s, int channel) SUN8I_I2S_TX_CHAN_EN(channel));
>  }
> 
> +
> +static void sun50i_h6_i2s_set_txchanen(const struct sun4i_i2s *i2s, int
> output, +				       int channel)
> +{
> +	if (output >= 0 && output < 4) {
> +		regmap_update_bits(i2s->regmap,
> +				   SUN8I_I2S_TX_CHAN_SEL_REG + 
(output * 4),
> +				   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
> +				   
SUN50I_H6_I2S_TX_CHAN_EN(channel));
> +	}
> +}
> +
> +static void sun50i_h6_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int
> channel) +{
> +	regmap_update_bits(i2s->regmap,
> +			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> +			   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
> +			   SUN50I_H6_I2S_TX_CHAN_EN(channel));
> +}
> +
>  static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int
> output, int channel)
>  {
> @@ -495,6 +549,25 @@ static void sun8i_i2s_set_rxchansel(const struct
> sun4i_i2s *i2s, int channel) SUN8I_I2S_TX_CHAN_SEL(channel));
>  }
> 
> +static void sun50i_h6_i2s_set_txchansel(const struct sun4i_i2s *i2s, int
> output, +				       int channel)
> +{
> +	if (output >= 0 && output < 4) {
> +		regmap_update_bits(i2s->regmap,
> +				   SUN8I_I2S_TX_CHAN_SEL_REG + 
(output * 4),
> +				   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
> +				   
SUN50I_H6_I2S_TX_CHAN_SEL(channel));
> +	}
> +}
> +
> +static void sun50i_h6_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int
> channel) +{
> +	regmap_update_bits(i2s->regmap,
> +			   SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> +			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
> +			   SUN50I_H6_I2S_TX_CHAN_SEL(channel));
> +}
> +
>  static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int
> output, int channel)
>  {
> @@ -520,6 +593,20 @@ static void sun8i_i2s_set_rxchanmap(const struct
> sun4i_i2s *i2s, int channel) regmap_write(i2s->regmap,
> SUN8I_I2S_RX_CHAN_MAP_REG, channel);
>  }
> 
> +static void sun50i_h6_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int
> output, +				       int channel)
> +{
> +	if (output >= 0 && output < 4) {
> +		regmap_write(i2s->regmap,
> +			     SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output 
* 8), channel);
> +	}
> +}
> +
> +static void sun50i_h6_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int
> channel) +{
> +	regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, channel);
> +}
> +
>  static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
>  			       struct snd_pcm_hw_params *params,
>  			       struct snd_soc_dai *dai)
> @@ -996,6 +1083,22 @@ static const struct reg_default
> sun8i_i2s_reg_defaults[] = { { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
>  };
> 
> +static const struct reg_default sun50i_i2s_reg_defaults[] = {
> +	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
> +	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
> +	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
> +	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
> +	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
> +	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
> +	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
> +	{ SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
> +	{ SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 },
> +	{ SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 },
> +	{ SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
> +	{ SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
> +	{ SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
> +};
> +
>  static const struct regmap_config sun4i_i2s_regmap_config = {
>  	.reg_bits	= 32,
>  	.reg_stride	= 4,
> @@ -1023,6 +1126,19 @@ static const struct regmap_config
> sun8i_i2s_regmap_config = { .volatile_reg	= sun8i_i2s_volatile_reg,
>  };
> 
> +static const struct regmap_config sun50i_i2s_regmap_config = {
> +	.reg_bits	= 32,
> +	.reg_stride	= 4,
> +	.val_bits	= 32,
> +	.max_register	= SUN50I_H6_I2S_RX_CHAN_MAP1_REG,
> +	.cache_type	= REGCACHE_FLAT,
> +	.reg_defaults	= sun50i_i2s_reg_defaults,
> +	.num_reg_defaults	= ARRAY_SIZE(sun50i_i2s_reg_defaults),
> +	.writeable_reg	= sun4i_i2s_wr_reg,
> +	.readable_reg	= sun8i_i2s_rd_reg,
> +	.volatile_reg	= sun8i_i2s_volatile_reg,
> +};
> +
>  static int sun4i_i2s_runtime_resume(struct device *dev)
>  {
>  	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
> @@ -1197,6 +1313,34 @@ static const struct sun4i_i2s_quirks
> sun50i_a64_codec_i2s_quirks = { .set_rxchanmap		= 
sun4i_i2s_set_rxchanmap,
>  };
> 
> +static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
> +	.has_reset		= true,
> +	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
> +	.sun4i_i2s_regmap	= &sun50i_i2s_regmap_config,
> +	.has_fmt_set_lrck_period = true,
> +	.has_chcfg		= true,
> +	.has_chsel_tx_chen	= true,
> +	.has_chsel_offset	= true,
> +	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> +	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 
0, 2),
> +	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
> +	.field_fmt_bclk		= REG_FIELD(SUN4I_I2S_FMT0_REG, 
7, 7),
> +	.field_fmt_lrclk	= REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
> +	.field_fmt_mode		= REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 
5),
> +	.field_fmt_sext		= REG_FIELD(SUN4I_I2S_FMT1_REG, 
4, 5),
> +	.get_sr			= sun8i_i2s_get_sr_wss,
> +	.get_wss		= sun8i_i2s_get_sr_wss,
> +	.set_format		= sun8i_i2s_set_format,
> +	.set_txchanoffset	= sun50i_h6_i2s_set_txchanoffset,
> +	.set_rxchanoffset	= sun50i_h6_i2s_set_rxchanoffset,
> +	.set_txchanen		= sun50i_h6_i2s_set_txchanen,
> +	.set_rxchanen		= sun50i_h6_i2s_set_rxchanen,
> +	.set_txchansel		= sun50i_h6_i2s_set_txchansel,
> +	.set_rxchansel		= sun50i_h6_i2s_set_rxchansel,
> +	.set_txchanmap		= sun50i_h6_i2s_set_txchanmap,
> +	.set_rxchanmap		= sun50i_h6_i2s_set_rxchanmap,
> +};
> +
>  static int sun4i_i2s_init_regmap_fields(struct device *dev,
>  					struct sun4i_i2s *i2s)
>  {
> @@ -1389,6 +1533,10 @@ static const struct of_device_id sun4i_i2s_match[] =
> { .compatible = "allwinner,sun50i-a64-codec-i2s",
>  		.data = &sun50i_a64_codec_i2s_quirks,
>  	},
> +	{
> +		.compatible = "allwinner,sun50i-h6-i2s",
> +		.data = &sun50i_h6_i2s_quirks,
> +	},
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, sun4i_i2s_match);





_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality
  2019-08-14  6:08 ` [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality codekipper
  2019-08-14  7:20   ` Maxime Ripard
@ 2019-08-14  8:27   ` " Jernej Škrabec
  1 sibling, 0 replies; 43+ messages in thread
From: Jernej Škrabec @ 2019-08-14  8:27 UTC (permalink / raw)
  To: linux-sunxi, codekipper
  Cc: alsa-devel, linux-kernel, lgirdwood, be17068, wens, broonie,
	maxime.ripard, linux-arm-kernel

Hi!

Dne sreda, 14. avgust 2019 ob 08:08:51 CEST je codekipper@gmail.com 
napisal(a):
> From: Marcus Cooper <codekipper@gmail.com>
> 
> The i2s block supports multi-lane i2s output however this functionality
> is only possible in earlier SoCs where the pins are exposed and for
> the i2s block used for HDMI audio on the later SoCs.
> 
> To enable this functionality, an optional property has been added to
> the bindings.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 28 +++++++++++++++++++++++++---
>  1 file changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index a8d98696fe7c..a020c3b372a8 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -23,7 +23,7 @@
> 
>  #define SUN4I_I2S_CTRL_REG		0x00
>  #define SUN4I_I2S_CTRL_SDO_EN_MASK		GENMASK(11, 8)
> -#define SUN4I_I2S_CTRL_SDO_EN(sdo)			BIT(8 + 
(sdo))
> +#define SUN4I_I2S_CTRL_SDO_EN(lines)		(((1 << lines) - 1) 
<< 8)
>  #define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
>  #define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
>  #define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
> @@ -614,6 +614,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream
> *substream, struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>  	int sr, wss, channels;
>  	u32 width;
> +	int lines;
> 
>  	channels = params_channels(params);
>  	if (channels != 2) {
> @@ -622,6 +623,13 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream
> *substream, return -EINVAL;
>  	}
> 
> +	lines = (channels + 1) / 2;
> +
> +	/* Enable the required output lines */
> +	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
> +			   SUN4I_I2S_CTRL_SDO_EN_MASK,
> +			   SUN4I_I2S_CTRL_SDO_EN(lines));

As Maxime said before, this doesn't work for TDM. Maybe we can skip this for 
now, until we agree on method how to describe channel allocation?

> +
>  	if (i2s->variant->has_chcfg) {
>  		regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
>  				   
SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
> @@ -1389,9 +1397,10 @@ static int sun4i_i2s_init_regmap_fields(struct device
> *dev, static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
> +	struct snd_soc_dai_driver *soc_dai;
>  	struct resource *res;
>  	void __iomem *regs;
> -	int irq, ret;
> +	int irq, ret, val;
> 
>  	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
>  	if (!i2s)
> @@ -1456,6 +1465,19 @@ static int sun4i_i2s_probe(struct platform_device
> *pdev) i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
> i2s->capture_dma_data.maxburst = 8;
> 
> +	soc_dai = devm_kmemdup(&pdev->dev, &sun4i_i2s_dai,
> +			       sizeof(*soc_dai), GFP_KERNEL);
> +	if (!soc_dai) {
> +		ret = -ENOMEM;
> +		goto err_pm_disable;
> +	}
> +
> +	if (!of_property_read_u32(pdev->dev.of_node,
> +				  "allwinner,playback-channels", 
&val)) {
> +		if (val >= 2 && val <= 8)
> +			soc_dai->playback.channels_max = val;
> +	}
> +

Rather than inventing new DT properties, I would rather have multiple 
snd_soc_dai_driver structures, depending on capabilities of that particular 
I2S block. That way we avoid some boilerplate code as can be seen here and 
it's IMO more transparent.

In this case, I would make another snd_soc_dai_driver struct for H3, which has 
channel_max property set to 8 and from patch 14, additional supported formats.

Best regards,
Jernej

>  	pm_runtime_enable(&pdev->dev);
>  	if (!pm_runtime_enabled(&pdev->dev)) {
>  		ret = sun4i_i2s_runtime_resume(&pdev->dev);
> @@ -1465,7 +1487,7 @@ static int sun4i_i2s_probe(struct platform_device
> *pdev)
> 
>  	ret = devm_snd_soc_register_component(&pdev->dev,
>  					      
&sun4i_i2s_component,
> -					      &sun4i_i2s_dai, 
1);
> +					      soc_dai, 1);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Could not register DAI\n");
>  		goto err_suspend;





_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  2019-08-14  6:08 ` [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support codekipper
@ 2019-08-14  8:28   ` " Jernej Škrabec
  2019-08-14  9:03     ` Code Kipper
  0 siblings, 1 reply; 43+ messages in thread
From: Jernej Škrabec @ 2019-08-14  8:28 UTC (permalink / raw)
  To: linux-sunxi, codekipper
  Cc: alsa-devel, linux-kernel, lgirdwood, be17068, wens, broonie,
	maxime.ripard, linux-arm-kernel

Hi!

Dne sreda, 14. avgust 2019 ob 08:08:53 CEST je codekipper@gmail.com 
napisal(a):
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Extend the functionality of the driver to include support of 20 and
> 24 bits per sample for the earlier SoCs.
> 
> Newer SoCs can also handle 32bit samples.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 21 +++++++++++++++++++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index a71969167053..d3c8789f70bb 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -690,6 +690,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream
> *substream, case 16:
>  		width = DMA_SLAVE_BUSWIDTH_2_BYTES;
>  		break;
> +	case 20:
> +	case 24:
> +	case 32:

params_physical_width() returns 32 also for 20 and 24-bit formats, so drop 20 
and 24.

Best regards,
Jernej

> +		width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +		break;
>  	default:
>  		dev_err(dai->dev, "Unsupported physical sample width: 
%d\n",
>  			params_physical_width(params));
> @@ -1015,6 +1020,13 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai
> *dai) return 0;
>  }
> 
> +#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
> +			 SNDRV_PCM_FMTBIT_S20_LE | \
> +			 SNDRV_PCM_FMTBIT_S24_LE)
> +
> +#define SUN8I_FORMATS	(SUN4I_FORMATS | \
> +			 SNDRV_PCM_FMTBIT_S32_LE)
> +
>  static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  	.probe = sun4i_i2s_dai_probe,
>  	.capture = {
> @@ -1022,14 +1034,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  		.channels_min = 2,
>  		.channels_max = 2,
>  		.rates = SNDRV_PCM_RATE_8000_192000,
> -		.formats = SNDRV_PCM_FMTBIT_S16_LE,
> +		.formats = SUN4I_FORMATS,
>  	},
>  	.playback = {
>  		.stream_name = "Playback",
>  		.channels_min = 2,
>  		.channels_max = 2,
>  		.rates = SNDRV_PCM_RATE_8000_192000,
> -		.formats = SNDRV_PCM_FMTBIT_S16_LE,
> +		.formats = SUN4I_FORMATS,
>  	},
>  	.ops = &sun4i_i2s_dai_ops,
>  	.symmetric_rates = 1,
> @@ -1505,6 +1517,11 @@ static int sun4i_i2s_probe(struct platform_device
> *pdev) goto err_pm_disable;
>  	}
> 
> +	if (i2s->variant->has_fmt_set_lrck_period) {
> +		soc_dai->playback.formats = SUN8I_FORMATS;
> +		soc_dai->capture.formats = SUN8I_FORMATS;
> +	}
> +
>  	if (!of_property_read_u32(pdev->dev.of_node,
>  				  "allwinner,playback-channels", 
&val)) {
>  		if (val >= 2 && val <= 8)





_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
  2019-08-14  7:20   ` Maxime Ripard
@ 2019-08-14  8:37   ` " Jernej Škrabec
  2019-08-14  9:02     ` Code Kipper
  2019-08-14 11:31   ` Chen-Yu Tsai
  2 siblings, 1 reply; 43+ messages in thread
From: Jernej Škrabec @ 2019-08-14  8:37 UTC (permalink / raw)
  To: linux-sunxi, codekipper
  Cc: alsa-devel, linux-kernel, lgirdwood, be17068, wens, broonie,
	maxime.ripard, linux-arm-kernel

Hi!

Dne sreda, 14. avgust 2019 ob 08:08:54 CEST je codekipper@gmail.com 
napisal(a):
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
> to reflect this.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 31 ++++++++++---------------------
>  1 file changed, 10 insertions(+), 21 deletions(-)
> 
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index d3c8789f70bb..ecfc1ed79379 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -876,9 +876,11 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai,
> unsigned int fmt) static void sun4i_i2s_start_capture(struct sun4i_i2s
> *i2s)
>  {
>  	/* Flush RX FIFO */
> +	regcache_cache_bypass(i2s->regmap, true);
>  	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
>  			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
>  			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
> +	regcache_cache_bypass(i2s->regmap, false);

Did you try with regmap_write_bits() instead? This function will 
unconditionally write bits so it's nicer solution, because you don't have to 
use regcache_cache_bypass().

> 
>  	/* Clear RX counter */
>  	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
> @@ -897,9 +899,11 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s
> *i2s) static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
>  {
>  	/* Flush TX FIFO */
> +	regcache_cache_bypass(i2s->regmap, true);
>  	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
>  			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
>  			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
> +	regcache_cache_bypass(i2s->regmap, false);

Ditto.

> 
>  	/* Clear TX counter */
>  	regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
> @@ -1053,13 +1057,7 @@ static const struct snd_soc_component_driver
> sun4i_i2s_component = {
> 
>  static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
>  {
> -	switch (reg) {
> -	case SUN4I_I2S_FIFO_TX_REG:
> -		return false;
> -
> -	default:
> -		return true;
> -	}
> +	return true;

Why did you change this? Manual mentions that SUN4I_I2S_FIFO_TX_REG is write-
only register. Even if it can be read, then it's better to remove whole 
function, which will automatically mean that all registers can be read.


>  }
> 
>  static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
> @@ -1078,6 +1076,8 @@ static bool sun4i_i2s_volatile_reg(struct device *dev,
> unsigned int reg) {
>  	switch (reg) {
>  	case SUN4I_I2S_FIFO_RX_REG:
> +	case SUN4I_I2S_FIFO_TX_REG:
> +	case SUN4I_I2S_FIFO_STA_REG:
>  	case SUN4I_I2S_INT_STA_REG:
>  	case SUN4I_I2S_RX_CNT_REG:
>  	case SUN4I_I2S_TX_CNT_REG:

SUN4I_I2S_FIFO_CTRL_REG should be put here, because it has two bits which 
returns to 0 immediately after they are set to 1.

Best regards,
Jernej

> @@ -1088,23 +1088,12 @@ static bool sun4i_i2s_volatile_reg(struct device
> *dev, unsigned int reg) }
>  }
> 
> -static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case SUN8I_I2S_FIFO_TX_REG:
> -		return false;
> -
> -	default:
> -		return true;
> -	}
> -}
> -
>  static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
>  {
>  	if (reg == SUN8I_I2S_INT_STA_REG)
>  		return true;
>  	if (reg == SUN8I_I2S_FIFO_TX_REG)
> -		return false;
> +		return true;
> 
>  	return sun4i_i2s_volatile_reg(dev, reg);
>  }
> @@ -1175,7 +1164,7 @@ static const struct regmap_config
> sun8i_i2s_regmap_config = { .reg_defaults	= sun8i_i2s_reg_defaults,
>  	.num_reg_defaults	= ARRAY_SIZE(sun8i_i2s_reg_defaults),
>  	.writeable_reg	= sun4i_i2s_wr_reg,
> -	.readable_reg	= sun8i_i2s_rd_reg,
> +	.readable_reg	= sun4i_i2s_rd_reg,
>  	.volatile_reg	= sun8i_i2s_volatile_reg,
>  };
> 
> @@ -1188,7 +1177,7 @@ static const struct regmap_config
> sun50i_i2s_regmap_config = { .reg_defaults	= sun50i_i2s_reg_defaults,
>  	.num_reg_defaults	= ARRAY_SIZE(sun50i_i2s_reg_defaults),
>  	.writeable_reg	= sun4i_i2s_wr_reg,
> -	.readable_reg	= sun8i_i2s_rd_reg,
> +	.readable_reg	= sun4i_i2s_rd_reg,
>  	.volatile_reg	= sun8i_i2s_volatile_reg,
>  };





_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  8:37   ` [linux-sunxi] " Jernej Škrabec
@ 2019-08-14  9:02     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14  9:02 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Linux-ALSA, linux-kernel, Chen-Yu Tsai, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, 14 Aug 2019 at 10:38, Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
>
> Hi!
>
> Dne sreda, 14. avgust 2019 ob 08:08:54 CEST je codekipper@gmail.com
> napisal(a):
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
> > to reflect this.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 31 ++++++++++---------------------
> >  1 file changed, 10 insertions(+), 21 deletions(-)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index d3c8789f70bb..ecfc1ed79379 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -876,9 +876,11 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai,
> > unsigned int fmt) static void sun4i_i2s_start_capture(struct sun4i_i2s
> > *i2s)
> >  {
> >       /* Flush RX FIFO */
> > +     regcache_cache_bypass(i2s->regmap, true);
> >       regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
> >                          SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
> >                          SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
> > +     regcache_cache_bypass(i2s->regmap, false);
>
> Did you try with regmap_write_bits() instead? This function will
> unconditionally write bits so it's nicer solution, because you don't have to
> use regcache_cache_bypass().

I didn't....with all the rework I've avoided messing with this change.
Now that the dust
has settled, I can go back to look at this.
Thanks,
CK
>
> >
> >       /* Clear RX counter */
> >       regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
> > @@ -897,9 +899,11 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s
> > *i2s) static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
> >  {
> >       /* Flush TX FIFO */
> > +     regcache_cache_bypass(i2s->regmap, true);
> >       regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
> >                          SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
> >                          SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
> > +     regcache_cache_bypass(i2s->regmap, false);
>
> Ditto.
>
> >
> >       /* Clear TX counter */
> >       regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
> > @@ -1053,13 +1057,7 @@ static const struct snd_soc_component_driver
> > sun4i_i2s_component = {
> >
> >  static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
> >  {
> > -     switch (reg) {
> > -     case SUN4I_I2S_FIFO_TX_REG:
> > -             return false;
> > -
> > -     default:
> > -             return true;
> > -     }
> > +     return true;
>
> Why did you change this? Manual mentions that SUN4I_I2S_FIFO_TX_REG is write-
> only register. Even if it can be read, then it's better to remove whole
> function, which will automatically mean that all registers can be read.
>
>
> >  }
> >
> >  static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
> > @@ -1078,6 +1076,8 @@ static bool sun4i_i2s_volatile_reg(struct device *dev,
> > unsigned int reg) {
> >       switch (reg) {
> >       case SUN4I_I2S_FIFO_RX_REG:
> > +     case SUN4I_I2S_FIFO_TX_REG:
> > +     case SUN4I_I2S_FIFO_STA_REG:
> >       case SUN4I_I2S_INT_STA_REG:
> >       case SUN4I_I2S_RX_CNT_REG:
> >       case SUN4I_I2S_TX_CNT_REG:
>
> SUN4I_I2S_FIFO_CTRL_REG should be put here, because it has two bits which
> returns to 0 immediately after they are set to 1.
>
> Best regards,
> Jernej
>
> > @@ -1088,23 +1088,12 @@ static bool sun4i_i2s_volatile_reg(struct device
> > *dev, unsigned int reg) }
> >  }
> >
> > -static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
> > -{
> > -     switch (reg) {
> > -     case SUN8I_I2S_FIFO_TX_REG:
> > -             return false;
> > -
> > -     default:
> > -             return true;
> > -     }
> > -}
> > -
> >  static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
> >  {
> >       if (reg == SUN8I_I2S_INT_STA_REG)
> >               return true;
> >       if (reg == SUN8I_I2S_FIFO_TX_REG)
> > -             return false;
> > +             return true;
> >
> >       return sun4i_i2s_volatile_reg(dev, reg);
> >  }
> > @@ -1175,7 +1164,7 @@ static const struct regmap_config
> > sun8i_i2s_regmap_config = { .reg_defaults     = sun8i_i2s_reg_defaults,
> >       .num_reg_defaults       = ARRAY_SIZE(sun8i_i2s_reg_defaults),
> >       .writeable_reg  = sun4i_i2s_wr_reg,
> > -     .readable_reg   = sun8i_i2s_rd_reg,
> > +     .readable_reg   = sun4i_i2s_rd_reg,
> >       .volatile_reg   = sun8i_i2s_volatile_reg,
> >  };
> >
> > @@ -1188,7 +1177,7 @@ static const struct regmap_config
> > sun50i_i2s_regmap_config = { .reg_defaults    = sun50i_i2s_reg_defaults,
> >       .num_reg_defaults       = ARRAY_SIZE(sun50i_i2s_reg_defaults),
> >       .writeable_reg  = sun4i_i2s_wr_reg,
> > -     .readable_reg   = sun8i_i2s_rd_reg,
> > +     .readable_reg   = sun4i_i2s_rd_reg,
> >       .volatile_reg   = sun8i_i2s_volatile_reg,
> >  };
>
>
>
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  2019-08-14  8:28   ` [linux-sunxi] " Jernej Škrabec
@ 2019-08-14  9:03     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14  9:03 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Linux-ALSA, linux-kernel, Chen-Yu Tsai, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, 14 Aug 2019 at 10:28, Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
>
> Hi!
>
> Dne sreda, 14. avgust 2019 ob 08:08:53 CEST je codekipper@gmail.com
> napisal(a):
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > Extend the functionality of the driver to include support of 20 and
> > 24 bits per sample for the earlier SoCs.
> >
> > Newer SoCs can also handle 32bit samples.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 21 +++++++++++++++++++--
> >  1 file changed, 19 insertions(+), 2 deletions(-)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index a71969167053..d3c8789f70bb 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -690,6 +690,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream
> > *substream, case 16:
> >               width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> >               break;
> > +     case 20:
> > +     case 24:
> > +     case 32:
>
> params_physical_width() returns 32 also for 20 and 24-bit formats, so drop 20
> and 24.
ACK
>
> Best regards,
> Jernej
>
> > +             width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> > +             break;
> >       default:
> >               dev_err(dai->dev, "Unsupported physical sample width:
> %d\n",
> >                       params_physical_width(params));
> > @@ -1015,6 +1020,13 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai
> > *dai) return 0;
> >  }
> >
> > +#define SUN4I_FORMATS        (SNDRV_PCM_FMTBIT_S16_LE | \
> > +                      SNDRV_PCM_FMTBIT_S20_LE | \
> > +                      SNDRV_PCM_FMTBIT_S24_LE)
> > +
> > +#define SUN8I_FORMATS        (SUN4I_FORMATS | \
> > +                      SNDRV_PCM_FMTBIT_S32_LE)
> > +
> >  static struct snd_soc_dai_driver sun4i_i2s_dai = {
> >       .probe = sun4i_i2s_dai_probe,
> >       .capture = {
> > @@ -1022,14 +1034,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
> >               .channels_min = 2,
> >               .channels_max = 2,
> >               .rates = SNDRV_PCM_RATE_8000_192000,
> > -             .formats = SNDRV_PCM_FMTBIT_S16_LE,
> > +             .formats = SUN4I_FORMATS,
> >       },
> >       .playback = {
> >               .stream_name = "Playback",
> >               .channels_min = 2,
> >               .channels_max = 2,
> >               .rates = SNDRV_PCM_RATE_8000_192000,
> > -             .formats = SNDRV_PCM_FMTBIT_S16_LE,
> > +             .formats = SUN4I_FORMATS,
> >       },
> >       .ops = &sun4i_i2s_dai_ops,
> >       .symmetric_rates = 1,
> > @@ -1505,6 +1517,11 @@ static int sun4i_i2s_probe(struct platform_device
> > *pdev) goto err_pm_disable;
> >       }
> >
> > +     if (i2s->variant->has_fmt_set_lrck_period) {
> > +             soc_dai->playback.formats = SUN8I_FORMATS;
> > +             soc_dai->capture.formats = SUN8I_FORMATS;
> > +     }
> > +
> >       if (!of_property_read_u32(pdev->dev.of_node,
> >                                 "allwinner,playback-channels",
> &val)) {
> >               if (val >= 2 && val <= 8)
>
>
>
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality
  2019-08-14  6:08 ` [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality codekipper
  2019-08-14  7:09   ` Maxime Ripard
@ 2019-08-14  9:30   ` Mark Brown
  2019-08-16  6:22     ` Code Kipper
  1 sibling, 1 reply; 43+ messages in thread
From: Mark Brown @ 2019-08-14  9:30 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-kernel, lgirdwood, be17068, linux-sunxi,
	maxime.ripard, wens, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 1082 bytes --]

On Wed, Aug 14, 2019 at 08:08:41AM +0200, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Codecs without a control connection such as i2s based HDMI audio and
> the Pine64 DAC require a different amount of bit clocks per frame than

This isn't a universal property of CODECs without a control, and it's
something that CODECs with control can require too.

>  	return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> -				      params_width(params));
> +				      i2s->tdm_slots ?
> +				      i2s->slot_width : params_width(params));

Please write normal conditional statements unless there's a strong
reason to do otherwise, it makes things more legible.

> +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
> +				      unsigned int tx_mask,
> +				      unsigned int rx_mask,
> +				      int slots, int width)
> +{
> +	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +
> +	i2s->tdm_slots = slots;
> +
> +	i2s->slot_width = width;
> +
> +	return 0;
> +}

No validation of the parameters here?

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations
  2019-08-14  6:08 ` [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations codekipper
  2019-08-14  7:13   ` Maxime Ripard
@ 2019-08-14  9:31   ` Mark Brown
  1 sibling, 0 replies; 43+ messages in thread
From: Mark Brown @ 2019-08-14  9:31 UTC (permalink / raw)
  To: codekipper
  Cc: alsa-devel, linux-kernel, lgirdwood, be17068, linux-sunxi,
	maxime.ripard, wens, linux-arm-kernel

[-- Attachment #1.1: Type: text/plain, Size: 554 bytes --]

On Wed, Aug 14, 2019 at 08:08:42AM +0200, codekipper@gmail.com wrote:

> +	if (i2s->variant->has_fmt_set_lrck_period)
> +		bclk_div = sun4i_i2s_get_bclk_div(i2s, clk_rate / rate,
> +						  word_size,
> +						  sun8i_i2s_clk_div,
> +						  ARRAY_SIZE(sun8i_i2s_clk_div));
> +	else
> +		bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
> +						  word_size,
> +						  sun4i_i2s_bclk_div,
> +						  ARRAY_SIZE(sun4i_i2s_bclk_div));

Are we sure there'll never be any new variants which would make a switch
statement for the variant work better?

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S
  2019-08-14  7:57   ` Jernej Škrabec
@ 2019-08-14 11:08     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14 11:08 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Linux-ALSA, linux-kernel, Chen-Yu Tsai, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, 14 Aug 2019 at 09:57, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Hi!
>
> Dne sreda, 14. avgust 2019 ob 08:08:50 CEST je codekipper@gmail.com
> napisal(a):
> > From: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> > H6 I2S is very similar to that in H3, except it supports up to 16
> > channels.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>
> Your Signed-off-by is missing here and on all other patches made originally by
> me.
ACK
>
> Best regards,
> Jernej
>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 148 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 148 insertions(+)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index 6de3cb41aaf6..a8d98696fe7c 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -121,6 +121,21 @@
> >  #define SUN8I_I2S_RX_CHAN_SEL_REG    0x54
> >  #define SUN8I_I2S_RX_CHAN_MAP_REG    0x58
> >
> > +/* Defines required for sun50i-h6 support */
> > +#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK        GENMASK(21, 20)
> > +#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)     ((offset) << 20)
> > +#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK               GENMASK(19, 16)
> > +#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)              ((chan - 1) << 16)
> > +#define SUN50I_H6_I2S_TX_CHAN_EN_MASK                GENMASK(15, 0)
> > +#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)   (((1 << num_chan) - 1))
> > +
> > +#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG       0x44
> > +#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG       0x48
> > +
> > +#define SUN50I_H6_I2S_RX_CHAN_SEL_REG        0x64
> > +#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG       0x68
> > +#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG       0x6C
> > +
> >  struct sun4i_i2s;
> >
> >  /**
> > @@ -440,6 +455,25 @@ static void sun8i_i2s_set_rxchanoffset(const struct
> > sun4i_i2s *i2s) SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
> >  }
> >
> > +static void sun50i_h6_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int
> > output) +{
> > +     if (output >= 0 && output < 4) {
> > +             regmap_update_bits(i2s->regmap,
> > +                                SUN8I_I2S_TX_CHAN_SEL_REG +
> (output * 4),
> > +
> SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
> > +
> SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
> > +     }
> > +
> > +}
> > +
> > +static void sun50i_h6_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
> > +{
> > +     regmap_update_bits(i2s->regmap,
> > +                        SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> > +                        SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
> > +                        SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s-
> >offset));
> > +}
> > +
> >  static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
> > int channel)
> >  {
> > @@ -459,6 +493,26 @@ static void sun8i_i2s_set_rxchanen(const struct
> > sun4i_i2s *i2s, int channel) SUN8I_I2S_TX_CHAN_EN(channel));
> >  }
> >
> > +
> > +static void sun50i_h6_i2s_set_txchanen(const struct sun4i_i2s *i2s, int
> > output, +                                    int channel)
> > +{
> > +     if (output >= 0 && output < 4) {
> > +             regmap_update_bits(i2s->regmap,
> > +                                SUN8I_I2S_TX_CHAN_SEL_REG +
> (output * 4),
> > +                                SUN50I_H6_I2S_TX_CHAN_EN_MASK,
> > +
> SUN50I_H6_I2S_TX_CHAN_EN(channel));
> > +     }
> > +}
> > +
> > +static void sun50i_h6_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int
> > channel) +{
> > +     regmap_update_bits(i2s->regmap,
> > +                        SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> > +                        SUN50I_H6_I2S_TX_CHAN_EN_MASK,
> > +                        SUN50I_H6_I2S_TX_CHAN_EN(channel));
> > +}
> > +
> >  static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int
> > output, int channel)
> >  {
> > @@ -495,6 +549,25 @@ static void sun8i_i2s_set_rxchansel(const struct
> > sun4i_i2s *i2s, int channel) SUN8I_I2S_TX_CHAN_SEL(channel));
> >  }
> >
> > +static void sun50i_h6_i2s_set_txchansel(const struct sun4i_i2s *i2s, int
> > output, +                                    int channel)
> > +{
> > +     if (output >= 0 && output < 4) {
> > +             regmap_update_bits(i2s->regmap,
> > +                                SUN8I_I2S_TX_CHAN_SEL_REG +
> (output * 4),
> > +                                SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
> > +
> SUN50I_H6_I2S_TX_CHAN_SEL(channel));
> > +     }
> > +}
> > +
> > +static void sun50i_h6_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int
> > channel) +{
> > +     regmap_update_bits(i2s->regmap,
> > +                        SUN50I_H6_I2S_RX_CHAN_SEL_REG,
> > +                        SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
> > +                        SUN50I_H6_I2S_TX_CHAN_SEL(channel));
> > +}
> > +
> >  static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int
> > output, int channel)
> >  {
> > @@ -520,6 +593,20 @@ static void sun8i_i2s_set_rxchanmap(const struct
> > sun4i_i2s *i2s, int channel) regmap_write(i2s->regmap,
> > SUN8I_I2S_RX_CHAN_MAP_REG, channel);
> >  }
> >
> > +static void sun50i_h6_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int
> > output, +                                    int channel)
> > +{
> > +     if (output >= 0 && output < 4) {
> > +             regmap_write(i2s->regmap,
> > +                          SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output
> * 8), channel);
> > +     }
> > +}
> > +
> > +static void sun50i_h6_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int
> > channel) +{
> > +     regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, channel);
> > +}
> > +
> >  static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
> >                              struct snd_pcm_hw_params *params,
> >                              struct snd_soc_dai *dai)
> > @@ -996,6 +1083,22 @@ static const struct reg_default
> > sun8i_i2s_reg_defaults[] = { { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
> >  };
> >
> > +static const struct reg_default sun50i_i2s_reg_defaults[] = {
> > +     { SUN4I_I2S_CTRL_REG, 0x00060000 },
> > +     { SUN4I_I2S_FMT0_REG, 0x00000033 },
> > +     { SUN4I_I2S_FMT1_REG, 0x00000030 },
> > +     { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
> > +     { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
> > +     { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
> > +     { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
> > +     { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
> > +     { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 },
> > +     { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 },
> > +     { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
> > +     { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
> > +     { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
> > +};
> > +
> >  static const struct regmap_config sun4i_i2s_regmap_config = {
> >       .reg_bits       = 32,
> >       .reg_stride     = 4,
> > @@ -1023,6 +1126,19 @@ static const struct regmap_config
> > sun8i_i2s_regmap_config = { .volatile_reg     = sun8i_i2s_volatile_reg,
> >  };
> >
> > +static const struct regmap_config sun50i_i2s_regmap_config = {
> > +     .reg_bits       = 32,
> > +     .reg_stride     = 4,
> > +     .val_bits       = 32,
> > +     .max_register   = SUN50I_H6_I2S_RX_CHAN_MAP1_REG,
> > +     .cache_type     = REGCACHE_FLAT,
> > +     .reg_defaults   = sun50i_i2s_reg_defaults,
> > +     .num_reg_defaults       = ARRAY_SIZE(sun50i_i2s_reg_defaults),
> > +     .writeable_reg  = sun4i_i2s_wr_reg,
> > +     .readable_reg   = sun8i_i2s_rd_reg,
> > +     .volatile_reg   = sun8i_i2s_volatile_reg,
> > +};
> > +
> >  static int sun4i_i2s_runtime_resume(struct device *dev)
> >  {
> >       struct sun4i_i2s *i2s = dev_get_drvdata(dev);
> > @@ -1197,6 +1313,34 @@ static const struct sun4i_i2s_quirks
> > sun50i_a64_codec_i2s_quirks = { .set_rxchanmap                =
> sun4i_i2s_set_rxchanmap,
> >  };
> >
> > +static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
> > +     .has_reset              = true,
> > +     .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
> > +     .sun4i_i2s_regmap       = &sun50i_i2s_regmap_config,
> > +     .has_fmt_set_lrck_period = true,
> > +     .has_chcfg              = true,
> > +     .has_chsel_tx_chen      = true,
> > +     .has_chsel_offset       = true,
> > +     .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> > +     .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG,
> 0, 2),
> > +     .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
> > +     .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG,
> 7, 7),
> > +     .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
> > +     .field_fmt_mode         = REG_FIELD(SUN4I_I2S_CTRL_REG, 4,
> 5),
> > +     .field_fmt_sext         = REG_FIELD(SUN4I_I2S_FMT1_REG,
> 4, 5),
> > +     .get_sr                 = sun8i_i2s_get_sr_wss,
> > +     .get_wss                = sun8i_i2s_get_sr_wss,
> > +     .set_format             = sun8i_i2s_set_format,
> > +     .set_txchanoffset       = sun50i_h6_i2s_set_txchanoffset,
> > +     .set_rxchanoffset       = sun50i_h6_i2s_set_rxchanoffset,
> > +     .set_txchanen           = sun50i_h6_i2s_set_txchanen,
> > +     .set_rxchanen           = sun50i_h6_i2s_set_rxchanen,
> > +     .set_txchansel          = sun50i_h6_i2s_set_txchansel,
> > +     .set_rxchansel          = sun50i_h6_i2s_set_rxchansel,
> > +     .set_txchanmap          = sun50i_h6_i2s_set_txchanmap,
> > +     .set_rxchanmap          = sun50i_h6_i2s_set_rxchanmap,
> > +};
> > +
> >  static int sun4i_i2s_init_regmap_fields(struct device *dev,
> >                                       struct sun4i_i2s *i2s)
> >  {
> > @@ -1389,6 +1533,10 @@ static const struct of_device_id sun4i_i2s_match[] =
> > { .compatible = "allwinner,sun50i-a64-codec-i2s",
> >               .data = &sun50i_a64_codec_i2s_quirks,
> >       },
> > +     {
> > +             .compatible = "allwinner,sun50i-h6-i2s",
> > +             .data = &sun50i_h6_i2s_quirks,
> > +     },
> >       {}
> >  };
> >  MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
>
>
>
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality
  2019-08-14  7:20   ` Maxime Ripard
@ 2019-08-14 11:16     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14 11:16 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Linux-ALSA, linux-sunxi, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	Chen-Yu Tsai, Mark Brown, linux-arm-kernel

On Wed, 14 Aug 2019 at 13:08, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> On Wed, Aug 14, 2019 at 08:08:51AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > The i2s block supports multi-lane i2s output however this functionality
> > is only possible in earlier SoCs where the pins are exposed and for
> > the i2s block used for HDMI audio on the later SoCs.
> >
> > To enable this functionality, an optional property has been added to
> > the bindings.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
>
> Wasn't the plan to support only stereo for now?
Stereo HDMI can be introduced on the H3 and later if we get the first
three patches
merged. Post those patches is the work to get multi-channel working.
>
> Either way, that property should be documented.
I can do this...but I'm thinking we should bang our heads together to
find a solution
that we all agree on...especially if we're considering multi-channel
tdm support.
Thanks,
CK
>
> Maxime
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs
  2019-08-14  7:16   ` Maxime Ripard
@ 2019-08-14 11:23     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14 11:23 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Linux-ALSA, linux-sunxi, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	Chen-Yu Tsai, Mark Brown, linux-arm-kernel

On Wed, 14 Aug 2019 at 13:08, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> On Wed, Aug 14, 2019 at 08:08:43AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > There is a need to support more formats on the newer SoCs(H3 and later).
> > Extend the formats supported to include DSP_A and DSP_B modes.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 87 +++++++++++++++++++++++++++----------
> >  1 file changed, 63 insertions(+), 24 deletions(-)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index 34f31439ae7b..3553c17318b0 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -27,6 +27,8 @@
> >  #define SUN4I_I2S_CTRL_MODE_MASK             BIT(5)
> >  #define SUN4I_I2S_CTRL_MODE_SLAVE                    (1 << 5)
> >  #define SUN4I_I2S_CTRL_MODE_MASTER                   (0 << 5)
> > +#define SUN4I_I2S_CTRL_PCM                   BIT(4)
> > +#define SUN4I_I2S_CTRL_LOOP                  BIT(3)
> >  #define SUN4I_I2S_CTRL_TX_EN                 BIT(2)
> >  #define SUN4I_I2S_CTRL_RX_EN                 BIT(1)
> >  #define SUN4I_I2S_CTRL_GL_EN                 BIT(0)
> > @@ -91,6 +93,9 @@
> >  /* Defines required for sun8i-h3 support */
> >  #define SUN8I_I2S_CTRL_BCLK_OUT                      BIT(18)
> >  #define SUN8I_I2S_CTRL_LRCK_OUT                      BIT(17)
> > +#define SUN8I_I2S_CTRL_MODE_RIGHT_J                  (2 << 0)
> > +#define SUN8I_I2S_CTRL_MODE_I2S_LEFT_J                       (1 << 0)
> > +#define SUN8I_I2S_CTRL_MODE_PCM                              (0 << 0)
> >
> >  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK              GENMASK(17, 8)
> >  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)   ((period - 1) << 8)
> > @@ -164,6 +169,7 @@ struct sun4i_i2s_quirks {
> >
> >       s8      (*get_sr)(const struct sun4i_i2s *, int);
> >       s8      (*get_wss)(const struct sun4i_i2s *, int);
> > +     int     (*set_format)(struct sun4i_i2s *, unsigned int);
> >  };
> >
> >  struct sun4i_i2s {
> > @@ -194,6 +200,7 @@ struct sun4i_i2s {
> >
> >       unsigned int    tdm_slots;
> >       unsigned int    slot_width;
> > +     unsigned int    offset;
> >  };
> >
> >  struct sun4i_i2s_clk_div {
> > @@ -484,19 +491,14 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
> >                                     i2s->slot_width : params_width(params));
> >  }
> >
> > -static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> > +static int sun4i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
> >  {
> > -     struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> >       u32 val;
> > -     u32 offset = 0;
> > -     u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
> > -     u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
> >
> >       /* DAI Mode */
> >       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> >       case SND_SOC_DAIFMT_I2S:
> >               val = SUN4I_I2S_FMT0_FMT_I2S;
> > -             offset = 1;
> >               break;
> >       case SND_SOC_DAIFMT_LEFT_J:
> >               val = SUN4I_I2S_FMT0_FMT_LEFT_J;
> > @@ -505,32 +507,64 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> >               val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
> >               break;
> >       default:
> > -             dev_err(dai->dev, "Unsupported format: %d\n",
> > -                     fmt & SND_SOC_DAIFMT_FORMAT_MASK);
> >               return -EINVAL;
> >       }
> >
> > -     if (i2s->variant->has_chsel_offset) {
> > -             /*
> > -              * offset being set indicates that we're connected to an i2s
> > -              * device, however offset is only used on the sun8i block and
> > -              * i2s shares the same setting with the LJ format. Increment
> > -              * val so that the bit to value to write is correct.
> > -              */
> > -             if (offset > 0)
> > -                     val++;
> > -             /* blck offset determines whether i2s or LJ */
> > -             regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
> > -                                SUN8I_I2S_TX_CHAN_OFFSET_MASK,
> > -                                SUN8I_I2S_TX_CHAN_OFFSET(offset));
> > +     regmap_field_write(i2s->field_fmt_mode, val);
> > +
> > +     return 0;
> > +}
> > +
> > +static int sun8i_i2s_set_format(struct sun4i_i2s *i2s, unsigned int fmt)
> > +{
> > +     u32 val;
> >
> > -             regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
> > -                                SUN8I_I2S_TX_CHAN_OFFSET_MASK,
> > -                                SUN8I_I2S_TX_CHAN_OFFSET(offset));
> > +     /* DAI Mode */
> > +     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> > +     case SND_SOC_DAIFMT_I2S:
> > +             i2s->offset = 1;
> > +     case SND_SOC_DAIFMT_LEFT_J:
> > +             val = SUN8I_I2S_CTRL_MODE_I2S_LEFT_J;
> > +             break;
> > +     case SND_SOC_DAIFMT_RIGHT_J:
> > +             val = SUN8I_I2S_CTRL_MODE_RIGHT_J;
> > +             break;
> > +     case SND_SOC_DAIFMT_DSP_A:
> > +             i2s->offset = 1;
> > +     case SND_SOC_DAIFMT_DSP_B:
> > +             val = SUN8I_I2S_CTRL_MODE_PCM;
> > +             break;
> > +
> > +     default:
> > +             return -EINVAL;
> >       }
> >
> > +     /*
> > +      * bclk offset determines whether i2s or LJ if in i2s mode and
> > +      * DSP_A or DSP_B if in PCM mode.
> > +      */
> > +     i2s->variant->set_txchanoffset(i2s, 0);
> > +     i2s->variant->set_rxchanoffset(i2s);
> > +
> >       regmap_field_write(i2s->field_fmt_mode, val);
>
> It's a bit more complicated in the sun8i case. The LRCK period also
> needs to be changed when in PCM / DSP_* mode since it changes from a
> number of periods for one channel to a number of periods for all the
> channels.
Yeah I was thinking that but I don't have any hardware to test this with (been
helping out someone trying to connect to a modem).
>
> I have patches that still need a bit of rework and take care of all of
> that, I'll try to post them by the end of the week

This patch could be dropped for now or at least we just keep the
offset parts in.
BR,
CK

>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample
  2019-08-14  6:43   ` Maxime Ripard
@ 2019-08-14 11:24     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-14 11:24 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Linux-ALSA, linux-sunxi, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	Chen-Yu Tsai, Mark Brown, linux-arm-kernel

On Wed, 14 Aug 2019 at 13:08, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> Hi,
>
> On Wed, Aug 14, 2019 at 08:08:40AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > On the newer SoCs such as the H3 and A64 this is set by default
> > to transfer a 0 after each sample in each slot. However the A10
> > and A20 SoCs that this driver was developed on had a default
> > setting where it padded the audio gain with zeros.
> >
> > This isn't a problem whilst we have only support for 16bit audio
> > but with larger sample resolution rates in the pipeline then SEXT
> > bits should be cleared so that they also pad at the LSB. Without
> > this the audio gets distorted.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index 793457394efe..8201334a059b 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -135,6 +135,7 @@ struct sun4i_i2s;
> >   * @field_fmt_bclk: regmap field to set clk polarity.
> >   * @field_fmt_lrclk: regmap field to set frame polarity.
> >   * @field_fmt_mode: regmap field to set the operational mode.
> > + * @field_fmt_sext: regmap field to set the sign extension.
> >   * @field_txchanmap: location of the tx channel mapping register.
> >   * @field_rxchanmap: location of the rx channel mapping register.
> >   * @field_txchansel: location of the tx channel select bit fields.
> > @@ -159,6 +160,7 @@ struct sun4i_i2s_quirks {
> >       struct reg_field                field_fmt_bclk;
> >       struct reg_field                field_fmt_lrclk;
> >       struct reg_field                field_fmt_mode;
> > +     struct reg_field                field_fmt_sext;
> >       struct reg_field                field_txchanmap;
> >       struct reg_field                field_rxchanmap;
> >       struct reg_field                field_txchansel;
> > @@ -186,6 +188,7 @@ struct sun4i_i2s {
> >       struct regmap_field     *field_fmt_bclk;
> >       struct regmap_field     *field_fmt_lrclk;
> >       struct regmap_field     *field_fmt_mode;
> > +     struct regmap_field     *field_fmt_sext;
> >       struct regmap_field     *field_txchanmap;
> >       struct regmap_field     *field_rxchanmap;
> >       struct regmap_field     *field_txchansel;
> > @@ -345,6 +348,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
> >                                  SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
> >                                  SUN8I_I2S_FMT0_LRCK_PERIOD(32));
> >
> > +     /* Set sign extension to pad out LSB with 0 */
> > +     regmap_field_write(i2s->field_fmt_sext, 0);
> > +
> >       return 0;
> >  }
> >
> > @@ -917,6 +923,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
> >       .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
> >       .has_slave_select_bit   = true,
> >       .field_fmt_mode         = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> > +     .field_fmt_sext         = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
> >       .field_txchanmap        = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
> >       .field_rxchanmap        = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
> >       .field_txchansel        = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
> > @@ -936,6 +943,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
> >       .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
> >       .has_slave_select_bit   = true,
> >       .field_fmt_mode         = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> > +     .field_fmt_sext         = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
> >       .field_txchanmap        = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
> >       .field_rxchanmap        = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
> >       .field_txchansel        = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
> > @@ -979,6 +987,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
> >       .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
> >       .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
> >       .field_fmt_mode         = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5),
> > +     .field_fmt_sext         = REG_FIELD(SUN4I_I2S_FMT1_REG, 4, 5),
> >       .field_txchanmap        = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31),
> >       .field_rxchanmap        = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31),
> >       .field_txchansel        = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
> > @@ -998,6 +1007,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
> >       .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
> >       .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
> >       .field_fmt_mode         = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1),
> > +     .field_fmt_sext         = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
> >       .field_txchanmap        = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
> >       .field_rxchanmap        = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
> >       .field_txchansel        = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
>
> You're missing the A83t here

ARRGGGHHHHH...ACK...thanks,
CK
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] Re: [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  7:20   ` Maxime Ripard
@ 2019-08-14 11:31     ` " Jernej Škrabec
  0 siblings, 0 replies; 43+ messages in thread
From: Jernej Škrabec @ 2019-08-14 11:31 UTC (permalink / raw)
  To: linux-sunxi, maxime.ripard
  Cc: alsa-devel, be17068, lgirdwood, linux-kernel, codekipper, wens,
	broonie, linux-arm-kernel

Dne sreda, 14. avgust 2019 ob 09:20:07 CEST je Maxime Ripard napisal(a):
> On Wed, Aug 14, 2019 at 08:08:54AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> > 
> > Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
> > to reflect this.
> > 
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> 
> This patch looks like it's fixing something while the commit log
> doesn't mention what is being fixed.

Main issue addressed here is that SUN4I_I2S_FIFO_CTRL_REG has two self-clear 
registers (SUN4I_I2S_FIFO_CTRL_FLUSH_RX and SUN4I_I2S_FIFO_CTRL_FLUSH_TX) and 
thus it should be marked as volatile.

Best regards,
Jernej

> 
> Having some context here would be great.
> 
> Maxime
> 
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com





_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings
  2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
  2019-08-14  7:20   ` Maxime Ripard
  2019-08-14  8:37   ` [linux-sunxi] " Jernej Škrabec
@ 2019-08-14 11:31   ` Chen-Yu Tsai
  2 siblings, 0 replies; 43+ messages in thread
From: Chen-Yu Tsai @ 2019-08-14 11:31 UTC (permalink / raw)
  To: Code Kipper
  Cc: Linux-ALSA, linux-kernel, Liam Girdwood, Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, Aug 14, 2019 at 2:09 PM <codekipper@gmail.com> wrote:
>
> From: Marcus Cooper <codekipper@gmail.com>
>
> Bypass the regmap cache when flushing the i2s FIFOs and modify the tables
> to reflect this.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 31 ++++++++++---------------------
>  1 file changed, 10 insertions(+), 21 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index d3c8789f70bb..ecfc1ed79379 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -876,9 +876,11 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>  static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
>  {
>         /* Flush RX FIFO */
> +       regcache_cache_bypass(i2s->regmap, true);
>         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
>                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
>                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
> +       regcache_cache_bypass(i2s->regmap, false);
>
>         /* Clear RX counter */
>         regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
> @@ -897,9 +899,11 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
>  static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
>  {
>         /* Flush TX FIFO */
> +       regcache_cache_bypass(i2s->regmap, true);
>         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
>                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
>                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
> +       regcache_cache_bypass(i2s->regmap, false);
>
>         /* Clear TX counter */
>         regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
> @@ -1053,13 +1057,7 @@ static const struct snd_soc_component_driver sun4i_i2s_component = {
>
>  static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
>  {
> -       switch (reg) {
> -       case SUN4I_I2S_FIFO_TX_REG:
> -               return false;
> -
> -       default:
> -               return true;
> -       }
> +       return true;

The commit log needs to explain why this is relevant. And I'm not sure why one
would read back the TX FIFO. Also, if it's always true, just drop the callback.

ChenYu

>  }
>
>  static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
> @@ -1078,6 +1076,8 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
>  {
>         switch (reg) {
>         case SUN4I_I2S_FIFO_RX_REG:
> +       case SUN4I_I2S_FIFO_TX_REG:
> +       case SUN4I_I2S_FIFO_STA_REG:
>         case SUN4I_I2S_INT_STA_REG:
>         case SUN4I_I2S_RX_CNT_REG:
>         case SUN4I_I2S_TX_CNT_REG:
> @@ -1088,23 +1088,12 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
>         }
>  }
>
> -static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
> -{
> -       switch (reg) {
> -       case SUN8I_I2S_FIFO_TX_REG:
> -               return false;
> -
> -       default:
> -               return true;
> -       }
> -}
> -
>  static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
>  {
>         if (reg == SUN8I_I2S_INT_STA_REG)
>                 return true;
>         if (reg == SUN8I_I2S_FIFO_TX_REG)
> -               return false;
> +               return true;
>
>         return sun4i_i2s_volatile_reg(dev, reg);
>  }
> @@ -1175,7 +1164,7 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
>         .reg_defaults   = sun8i_i2s_reg_defaults,
>         .num_reg_defaults       = ARRAY_SIZE(sun8i_i2s_reg_defaults),
>         .writeable_reg  = sun4i_i2s_wr_reg,
> -       .readable_reg   = sun8i_i2s_rd_reg,
> +       .readable_reg   = sun4i_i2s_rd_reg,
>         .volatile_reg   = sun8i_i2s_volatile_reg,
>  };
>
> @@ -1188,7 +1177,7 @@ static const struct regmap_config sun50i_i2s_regmap_config = {
>         .reg_defaults   = sun50i_i2s_reg_defaults,
>         .num_reg_defaults       = ARRAY_SIZE(sun50i_i2s_reg_defaults),
>         .writeable_reg  = sun4i_i2s_wr_reg,
> -       .readable_reg   = sun8i_i2s_rd_reg,
> +       .readable_reg   = sun4i_i2s_rd_reg,
>         .volatile_reg   = sun8i_i2s_volatile_reg,
>  };
>
> --
> 2.22.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality
  2019-08-14  9:30   ` Mark Brown
@ 2019-08-16  6:22     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-16  6:22 UTC (permalink / raw)
  To: Mark Brown
  Cc: Linux-ALSA, linux-kernel, Liam Girdwood, Andrea Venturi \(pers\),
	linux-sunxi, Maxime Ripard, Chen-Yu Tsai, linux-arm-kernel

On Wed, 14 Aug 2019 at 11:30, Mark Brown <broonie@kernel.org> wrote:
>
> On Wed, Aug 14, 2019 at 08:08:41AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > Codecs without a control connection such as i2s based HDMI audio and
> > the Pine64 DAC require a different amount of bit clocks per frame than
>
> This isn't a universal property of CODECs without a control, and it's
> something that CODECs with control can require too.

ACK
>
> >       return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> > -                                   params_width(params));
> > +                                   i2s->tdm_slots ?
> > +                                   i2s->slot_width : params_width(params));
>
> Please write normal conditional statements unless there's a strong
> reason to do otherwise, it makes things more legible.
ACK
>
> > +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
> > +                                   unsigned int tx_mask,
> > +                                   unsigned int rx_mask,
> > +                                   int slots, int width)
> > +{
> > +     struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> > +
> > +     i2s->tdm_slots = slots;
> > +
> > +     i2s->slot_width = width;
> > +
> > +     return 0;
> > +}
>
> No validation of the parameters here?
ACK
Thanks,
CK

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality
  2019-08-14  7:09   ` Maxime Ripard
@ 2019-08-16  6:27     ` Code Kipper
  0 siblings, 0 replies; 43+ messages in thread
From: Code Kipper @ 2019-08-16  6:27 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Linux-ALSA, linux-sunxi, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	Chen-Yu Tsai, Mark Brown, linux-arm-kernel

On Wed, 14 Aug 2019 at 13:08, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> Hi,
>
> On Wed, Aug 14, 2019 at 08:08:41AM +0200, codekipper@gmail.com wrote:
> > From: Marcus Cooper <codekipper@gmail.com>
> >
> > Codecs without a control connection such as i2s based HDMI audio and
> > the Pine64 DAC require a different amount of bit clocks per frame than
> > what is calculated by the sample width. Use the tdm slot bindings to
> > provide this mechanism.
> >
> > Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> > ---
> >  sound/soc/sunxi/sun4i-i2s.c | 23 +++++++++++++++++++++--
> >  1 file changed, 21 insertions(+), 2 deletions(-)
> >
> > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> > index 8201334a059b..7c37b6291df0 100644
> > --- a/sound/soc/sunxi/sun4i-i2s.c
> > +++ b/sound/soc/sunxi/sun4i-i2s.c
> > @@ -195,6 +195,9 @@ struct sun4i_i2s {
> >       struct regmap_field     *field_rxchansel;
> >
> >       const struct sun4i_i2s_quirks   *variant;
> > +
> > +     unsigned int    tdm_slots;
> > +     unsigned int    slot_width;
> >  };
> >
> >  struct sun4i_i2s_clk_div {
> > @@ -346,7 +349,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
> >       if (i2s->variant->has_fmt_set_lrck_period)
> >               regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
> >                                  SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
> > -                                SUN8I_I2S_FMT0_LRCK_PERIOD(32));
> > +                                SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
> >
> >
> >       /* Set sign extension to pad out LSB with 0 */
> >       regmap_field_write(i2s->field_fmt_sext, 0);
> > @@ -450,7 +453,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
> >       regmap_field_write(i2s->field_fmt_sr, sr);
> >
> >       return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> > -                                   params_width(params));
> > +                                   i2s->tdm_slots ?
> > +                                   i2s->slot_width : params_width(params));
>
> This is slightly more complicated than that.

At this point we're only supporting 2 channels with fixed slot
settings. I've added a comment to state
that we're using the tdm_slot at the moment as an indicator to
override the slot width. Do you think
that is enough for now?.

Thanks,
CK
>
> On the H3 (and all related ones), the CHAN_CFG_TX_SLOT_NUM and
> _RX_SLOT_NUM fields in the CHAN_CFG register need to be set to the
> number of slots as well.
>
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-14  6:08 ` [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate codekipper
@ 2019-08-21  4:07   ` " Chen-Yu Tsai
  2019-08-21  5:52     ` Code Kipper
  2019-08-21  9:19   ` Code Kipper
  1 sibling, 1 reply; 43+ messages in thread
From: Chen-Yu Tsai @ 2019-08-21  4:07 UTC (permalink / raw)
  To: Code Kipper
  Cc: Jernej Skrabec, Linux-ALSA, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, Aug 14, 2019 at 2:09 PM <codekipper@gmail.com> wrote:
>
> From: Jernej Skrabec <jernej.skrabec@siol.net>
>
> I2S doesn't work if parent rate couldn't be change. Difference between
> wanted and actual rate is too big.
>
> Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

This lacks your SoB. Please reply and I can add it when applying.

ChenYu

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-21  4:07   ` [linux-sunxi] " Chen-Yu Tsai
@ 2019-08-21  5:52     ` Code Kipper
  2019-08-21  6:01       ` Chen-Yu Tsai
  0 siblings, 1 reply; 43+ messages in thread
From: Code Kipper @ 2019-08-21  5:52 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jernej Skrabec, Linux-ALSA, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

Thanks....I've added to my next patch series but if you could add it
when applying that would be great.
BR,
CK

On Wed, 21 Aug 2019 at 06:07, Chen-Yu Tsai <wens@csie.org> wrote:
>
> On Wed, Aug 14, 2019 at 2:09 PM <codekipper@gmail.com> wrote:
> >
> > From: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> > I2S doesn't work if parent rate couldn't be change. Difference between
> > wanted and actual rate is too big.
> >
> > Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>
> This lacks your SoB. Please reply and I can add it when applying.
>
> ChenYu

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-21  5:52     ` Code Kipper
@ 2019-08-21  6:01       ` Chen-Yu Tsai
  0 siblings, 0 replies; 43+ messages in thread
From: Chen-Yu Tsai @ 2019-08-21  6:01 UTC (permalink / raw)
  To: Code Kipper
  Cc: Jernej Skrabec, Linux-ALSA, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, Aug 21, 2019 at 1:52 PM Code Kipper <codekipper@gmail.com> wrote:
>
> Thanks....I've added to my next patch series but if you could add it
> when applying that would be great.

Please reply with an explicit SoB to put it on the record.

ChenYu

> BR,
> CK
>
> On Wed, 21 Aug 2019 at 06:07, Chen-Yu Tsai <wens@csie.org> wrote:
> >
> > On Wed, Aug 14, 2019 at 2:09 PM <codekipper@gmail.com> wrote:
> > >
> > > From: Jernej Skrabec <jernej.skrabec@siol.net>
> > >
> > > I2S doesn't work if parent rate couldn't be change. Difference between
> > > wanted and actual rate is too big.
> > >
> > > Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> > This lacks your SoB. Please reply and I can add it when applying.
> >
> > ChenYu
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/CAEKpxBnxf%3Diejk887A7qFkzt3BXVxiRS1PeA45aZYR9DsBAU4Q%40mail.gmail.com.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-14  6:08 ` [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate codekipper
  2019-08-21  4:07   ` [linux-sunxi] " Chen-Yu Tsai
@ 2019-08-21  9:19   ` Code Kipper
  2019-08-21  9:35     ` [linux-sunxi] " Chen-Yu Tsai
  1 sibling, 1 reply; 43+ messages in thread
From: Code Kipper @ 2019-08-21  9:19 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, linux-sunxi
  Cc: Jernej Skrabec, Linux-ALSA, Liam Girdwood, linux-kernel,
	Andrea Venturi \(pers\),
	Mark Brown, linux-arm-kernel

On Wed, 14 Aug 2019 at 08:09, <codekipper@gmail.com> wrote:
>
> From: Jernej Skrabec <jernej.skrabec@siol.net>
>
> I2S doesn't work if parent rate couldn't be change. Difference between
> wanted and actual rate is too big.
>
> Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Signed-off-by: Marcus Cooper <codekipper@gmail.com>

> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
> index aebef4af9861..d89353a3cdec 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
> @@ -505,7 +505,7 @@ static struct ccu_div i2s3_clk = {
>                 .hw.init        = CLK_HW_INIT_PARENTS("i2s3",
>                                                       audio_parents,
>                                                       &ccu_div_ops,
> -                                                     0),
> +                                                     CLK_SET_RATE_PARENT),
>         },
>  };
>
> @@ -518,7 +518,7 @@ static struct ccu_div i2s0_clk = {
>                 .hw.init        = CLK_HW_INIT_PARENTS("i2s0",
>                                                       audio_parents,
>                                                       &ccu_div_ops,
> -                                                     0),
> +                                                     CLK_SET_RATE_PARENT),
>         },
>  };
>
> @@ -531,7 +531,7 @@ static struct ccu_div i2s1_clk = {
>                 .hw.init        = CLK_HW_INIT_PARENTS("i2s1",
>                                                       audio_parents,
>                                                       &ccu_div_ops,
> -                                                     0),
> +                                                     CLK_SET_RATE_PARENT),
>         },
>  };
>
> @@ -544,7 +544,7 @@ static struct ccu_div i2s2_clk = {
>                 .hw.init        = CLK_HW_INIT_PARENTS("i2s2",
>                                                       audio_parents,
>                                                       &ccu_div_ops,
> -                                                     0),
> +                                                     CLK_SET_RATE_PARENT),
>         },
>  };
>
> --
> 2.22.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [linux-sunxi] Re: [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate
  2019-08-21  9:19   ` Code Kipper
@ 2019-08-21  9:35     ` " Chen-Yu Tsai
  0 siblings, 0 replies; 43+ messages in thread
From: Chen-Yu Tsai @ 2019-08-21  9:35 UTC (permalink / raw)
  To: Code Kipper
  Cc: Jernej Skrabec, Linux-ALSA, linux-kernel, Liam Girdwood,
	Andrea Venturi \(pers\),
	linux-sunxi, Mark Brown, Maxime Ripard, linux-arm-kernel

On Wed, Aug 21, 2019 at 5:19 PM Code Kipper <codekipper@gmail.com> wrote:
>
> On Wed, 14 Aug 2019 at 08:09, <codekipper@gmail.com> wrote:
> >
> > From: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> > I2S doesn't work if parent rate couldn't be change. Difference between
> > wanted and actual rate is too big.
> >
> > Fix this by adding CLK_SET_RATE_PARENT flag to I2S clocks.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>

Applied for 5.4

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, back to index

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-14  6:08 [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver codekipper
2019-08-14  6:08 ` [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample codekipper
2019-08-14  6:43   ` Maxime Ripard
2019-08-14 11:24     ` Code Kipper
2019-08-14  6:08 ` [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality codekipper
2019-08-14  7:09   ` Maxime Ripard
2019-08-16  6:27     ` Code Kipper
2019-08-14  9:30   ` Mark Brown
2019-08-16  6:22     ` Code Kipper
2019-08-14  6:08 ` [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations codekipper
2019-08-14  7:13   ` Maxime Ripard
2019-08-14  9:31   ` Mark Brown
2019-08-14  6:08 ` [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs codekipper
2019-08-14  7:16   ` Maxime Ripard
2019-08-14 11:23     ` Code Kipper
2019-08-14  6:08 ` [PATCH v5 05/15] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets codekipper
2019-08-14  6:08 ` [PATCH v5 06/15] ASoC: sun4i-i2s: Add functions for RX and TX channel enables codekipper
2019-08-14  6:08 ` [PATCH v5 07/15] ASoC: sun4i-i2s: Add functions for RX and TX channel selects codekipper
2019-08-14  6:08 ` [PATCH v5 08/15] ASoC: sun4i-i2s: Add functions for channel mapping codekipper
2019-08-14  6:08 ` [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate codekipper
2019-08-21  4:07   ` [linux-sunxi] " Chen-Yu Tsai
2019-08-21  5:52     ` Code Kipper
2019-08-21  6:01       ` Chen-Yu Tsai
2019-08-21  9:19   ` Code Kipper
2019-08-21  9:35     ` [linux-sunxi] " Chen-Yu Tsai
2019-08-14  6:08 ` [PATCH v5 10/15] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible codekipper
2019-08-14  6:08 ` [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S codekipper
2019-08-14  7:57   ` Jernej Škrabec
2019-08-14 11:08     ` Code Kipper
2019-08-14  6:08 ` [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality codekipper
2019-08-14  7:20   ` Maxime Ripard
2019-08-14 11:16     ` Code Kipper
2019-08-14  8:27   ` [linux-sunxi] " Jernej Škrabec
2019-08-14  6:08 ` [PATCH v5 13/15] ASoC: sun4i-i2s: Add multichannel functionality codekipper
2019-08-14  6:08 ` [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support codekipper
2019-08-14  8:28   ` [linux-sunxi] " Jernej Škrabec
2019-08-14  9:03     ` Code Kipper
2019-08-14  6:08 ` [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings codekipper
2019-08-14  7:20   ` Maxime Ripard
2019-08-14 11:31     ` [linux-sunxi] " Jernej Škrabec
2019-08-14  8:37   ` [linux-sunxi] " Jernej Škrabec
2019-08-14  9:02     ` Code Kipper
2019-08-14 11:31   ` Chen-Yu Tsai

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

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


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


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