[linux-sunxi] [PATCH v6 6/7] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible

2019-10-16 Thread codekipper
From: Jernej Skrabec 

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 
Signed-off-by: Marcus Cooper 
---
 .../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.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-7-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 2/7] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets

2019-10-16 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index f1a80973c450..875567881f30 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -157,6 +157,8 @@ struct sun4i_i2s_quirks {
int (*set_chan_cfg)(const struct sun4i_i2s *,
const struct snd_pcm_hw_params *);
int (*set_fmt)(struct sun4i_i2s *, unsigned int);
+   void(*set_txchanoffset)(const struct sun4i_i2s *, int);
+   void(*set_rxchanoffset)(const struct sun4i_i2s *);
 };
 
 struct sun4i_i2s {
@@ -467,6 +469,23 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s 
*i2s,
return 0;
 }
 
+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)
@@ -661,12 +680,10 @@ static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
 
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   SUN8I_I2S_CTRL_MODE_MASK, mode);
-   regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
-  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-  SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
-   regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
-  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-  SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
+   if (i2s->variant->set_txchanoffset)
+   i2s->variant->set_txchanoffset(i2s, 0);
+   if (i2s->variant->set_rxchanoffset)
+   i2s->variant->set_rxchanoffset(i2s);
 
/* DAI clock master masks */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1136,6 +1153,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks 
= {
.get_wss= sun8i_i2s_get_sr_wss,
.set_chan_cfg   = sun8i_i2s_set_chan_cfg,
.set_fmt= sun8i_i2s_set_soc_fmt,
+   .set_txchanoffset   = sun8i_i2s_set_txchanoffset,
+   .set_rxchanoffset   = sun8i_i2s_set_rxchanoffset,
 };
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-3-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 3/7] ASoC: sun4i-i2s: Add functions for RX and TX channel enables

2019-10-16 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 32 +---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 875567881f30..8d28a386872f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -159,6 +159,8 @@ struct sun4i_i2s_quirks {
int (*set_fmt)(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 {
@@ -462,9 +464,7 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s 
*i2s,
   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
   SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
 
-   regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
-  SUN8I_I2S_TX_CHAN_EN_MASK,
-  SUN8I_I2S_TX_CHAN_EN(channels));
+   i2s->variant->set_txchanen(i2s, 0, channels);
 
return 0;
 }
@@ -486,6 +486,24 @@ 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)
@@ -510,6 +528,12 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
return ret;
}
 
+   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:
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
@@ -1155,6 +1179,8 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks 
= {
.set_fmt= sun8i_i2s_set_soc_fmt,
.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.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-4-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 7/7] ASoC: sun4i-i2s: Add support for H6 I2S

2019-10-16 Thread codekipper
   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)
@@ -1073,6 +1157,22 @@ static const struct reg_default sun8i_i2s_reg_defaults[] 
= {
{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x },
 };
 
+static const struct reg_default sun50i_i2s_reg_defaults[] = {
+   { SUN4I_I2S_CTRL_REG, 0x0006 },
+   { SUN4I_I2S_FMT0_REG, 0x0033 },
+   { SUN4I_I2S_FMT1_REG, 0x0030 },
+   { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
+   { SUN4I_I2S_DMA_INT_CTRL_REG, 0x },
+   { SUN4I_I2S_CLK_DIV_REG, 0x },
+   { SUN8I_I2S_CHAN_CFG_REG, 0x },
+   { SUN8I_I2S_TX_CHAN_SEL_REG, 0x },
+   { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x },
+   { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x },
+};
+
 static const struct regmap_config sun4i_i2s_regmap_config = {
.reg_bits   = 32,
.reg_stride = 4,
@@ -1100,6 +1200,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);
@@ -1282,6 +1395,32 @@ 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   = _i2s_regmap_config,
+   .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),
+   .bclk_dividers  = sun8i_i2s_clk_div,
+   .num_bclk_dividers  = ARRAY_SIZE(sun8i_i2s_clk_div),
+   .mclk_dividers  = sun8i_i2s_clk_div,
+   .num_mclk_dividers  = ARRAY_SIZE(sun8i_i2s_clk_div),
+   .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
+   .get_sr = sun8i_i2s_get_sr_wss,
+   .get_wss= sun8i_i2s_get_sr_wss,
+   .set_chan_cfg   = sun8i_i2s_set_chan_cfg,
+   .set_fmt= sun8i_i2s_set_soc_fmt,
+   .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)
 {
@@ -1451,6 +1590,10 @@ static const struct of_device_id sun4i_i2s_match[] = {
.compatible = "allwinner,sun50i-a64-codec-i2s",
.data = _a64_codec_i2s_quirks,
},
+   {
+   .compatible = "allwinner,sun50i-h6-i2s",
+   .data = _h6_i2s_quirks,
+   },
{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-8-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 4/7] ASoC: sun4i-i2s: Add functions for RX and TX channel selects

2019-10-16 Thread codekipper
set_txchanen(i2s, 0, channels);
 
@@ -1118,6 +1152,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks 
= {
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
.set_fmt= sun4i_i2s_set_soc_fmt,
+   .set_txchansel  = sun4i_i2s_set_txchansel,
+   .set_rxchansel  = sun4i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
@@ -1136,6 +1172,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
.set_fmt= sun4i_i2s_set_soc_fmt,
+   .set_txchansel  = sun4i_i2s_set_txchansel,
+   .set_rxchansel  = sun4i_i2s_set_rxchansel,
 };
 
 /*
@@ -1159,6 +1197,8 @@ static const struct sun4i_i2s_quirks 
sun8i_a83t_i2s_quirks = {
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
.set_fmt= sun4i_i2s_set_soc_fmt,
+   .set_txchansel  = sun4i_i2s_set_txchansel,
+   .set_rxchansel  = sun4i_i2s_set_rxchansel,
 };
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
@@ -1181,6 +1221,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 = {
@@ -1199,6 +1241,8 @@ static const struct sun4i_i2s_quirks 
sun50i_a64_codec_i2s_quirks = {
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
.set_fmt= sun4i_i2s_set_soc_fmt,
+   .set_txchansel  = sun4i_i2s_set_txchansel,
+   .set_rxchansel  = sun4i_i2s_set_rxchansel,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-5-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 5/7] ASoC: sun4i-i2s: Add functions for RX and TX channel mapping

2019-10-16 Thread codekipper
rks sun50i_a64_codec_i2s_quirks = {
@@ -1243,6 +1278,8 @@ static const struct sun4i_i2s_quirks 
sun50i_a64_codec_i2s_quirks = {
.set_fmt= sun4i_i2s_set_soc_fmt,
.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,
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-6-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 1/7] ASoC: sun4i-i2s: Move channel select offset

2019-10-16 Thread codekipper
From: Marcus Cooper 

On the newer SoCs the offset is used to set the mode of the
connection. As it is to be used elsewhere then it makes sense
to move it to the main structure.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index d0a8d5810c0a..f1a80973c450 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -156,7 +156,7 @@ struct sun4i_i2s_quirks {
s8  (*get_wss)(const struct sun4i_i2s *, int);
int (*set_chan_cfg)(const struct sun4i_i2s *,
const struct snd_pcm_hw_params *);
-   int (*set_fmt)(const struct sun4i_i2s *, unsigned int);
+   int (*set_fmt)(struct sun4i_i2s *, unsigned int);
 };
 
 struct sun4i_i2s {
@@ -169,6 +169,7 @@ struct sun4i_i2s {
unsigned intmclk_freq;
unsigned intslots;
unsigned intslot_width;
+   unsigned intoffset;
 
struct snd_dmaengine_dai_dma_data   capture_dma_data;
struct snd_dmaengine_dai_dma_data   playback_dma_data;
@@ -516,7 +517,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
  slots, slot_width);
 }
 
-static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+static int sun4i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
 unsigned int fmt)
 {
u32 val;
@@ -589,11 +590,10 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s 
*i2s,
return 0;
 }
 
-static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
+static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
 unsigned int fmt)
 {
u32 mode, val;
-   u8 offset;
 
/*
 * DAI clock polarity
@@ -632,27 +632,27 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s 
*i2s,
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
mode = SUN8I_I2S_CTRL_MODE_PCM;
-   offset = 1;
+   i2s->offset = 1;
break;
 
case SND_SOC_DAIFMT_DSP_B:
mode = SUN8I_I2S_CTRL_MODE_PCM;
-   offset = 0;
+   i2s->offset = 0;
break;
 
case SND_SOC_DAIFMT_I2S:
mode = SUN8I_I2S_CTRL_MODE_LEFT;
-   offset = 1;
+   i2s->offset = 1;
break;
 
case SND_SOC_DAIFMT_LEFT_J:
mode = SUN8I_I2S_CTRL_MODE_LEFT;
-   offset = 0;
+   i2s->offset = 0;
break;
 
case SND_SOC_DAIFMT_RIGHT_J:
mode = SUN8I_I2S_CTRL_MODE_RIGHT;
-   offset = 0;
+   i2s->offset = 0;
break;
 
default:
@@ -663,10 +663,10 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s 
*i2s,
   SUN8I_I2S_CTRL_MODE_MASK, mode);
regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-  SUN8I_I2S_TX_CHAN_OFFSET(offset));
+  SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-  SUN8I_I2S_TX_CHAN_OFFSET(offset));
+  SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
 
/* DAI clock master masks */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-2-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 0/7] ASoC: sun4i-i2s: Updates to the driver

2019-10-16 Thread codekipper
From: Marcus Cooper 

Hi All,
To be able to add support for the Allwinner H6 I've 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've also
stripped out all the other patches unrelated to this which I will deliver
after support for the H6 has gone in.

These other patches are required for HDMI audio which is driving this
patchset and they can be found here
https://github.com/codekipper/linux-sunxi/commits/upstream-i2s
BR,
CK

---
v6 changes compared to v5 are:
- rebased onto the recent tdm delivery
- stripped out patches not required for the H6 delivery

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 (2):
  dt-bindings: ASoC: sun4i-i2s: Add H6 compatible
  ASoC: sun4i-i2s: Add support for H6 I2S

Marcus Cooper (5):
  ASoC: sun4i-i2s: Move channel select offset
  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 RX and TX channel mapping

 .../sound/allwinner,sun4i-a10-i2s.yaml|   2 +
 sound/soc/sunxi/sun4i-i2s.c   | 337 --
 2 files changed, 305 insertions(+), 34 deletions(-)

-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20191016070740.121435-1-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 3/3] ASoC: sun4i-i2s: Adjust LRCLK width

2019-08-26 Thread codekipper
From: Marcus Cooper 

Some codecs 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 values obtained by the tdm slot bindings
to adjust the LRCLK width accordingly.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 056a299c03fb..0965a97c96e5 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -455,7 +455,10 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s 
*i2s,
break;
 
case SND_SOC_DAIFMT_I2S:
-   lrck_period = params_physical_width(params);
+   if (i2s->slot_width)
+   lrck_period = i2s->slot_width;
+   else
+   lrck_period = params_physical_width(params);
break;
 
default:
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190826180734.15801-4-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 1/3] ASoC: sun4i-i2s: incorrect regmap for A83T

2019-08-26 Thread codekipper
From: Marcus Cooper 

The regmap configuration is set up for the legacy block on the
A83T whereas it uses the new block with a larger register map.

Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T")
Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 57bf2a33753e..34575a8aa9f6 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -1100,7 +1100,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
.has_reset  = true,
.reg_offset_txdata  = SUN8I_I2S_FIFO_TX_REG,
-   .sun4i_i2s_regmap   = _i2s_regmap_config,
+   .sun4i_i2s_regmap   = _i2s_regmap_config,
.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),
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190826180734.15801-2-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 2/3] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2019-08-26 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 34575a8aa9f6..056a299c03fb 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -135,6 +135,7 @@ struct sun4i_i2s;
  * @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.
+ * @field_fmt_sext: regmap field to set the sign extension.
  */
 struct sun4i_i2s_quirks {
boolhas_reset;
@@ -145,6 +146,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_clkdiv_mclk_en;
struct reg_fieldfield_fmt_wss;
struct reg_fieldfield_fmt_sr;
+   struct reg_fieldfield_fmt_sext;
 
const struct sun4i_i2s_clk_div  *bclk_dividers;
unsigned intnum_bclk_dividers;
@@ -177,6 +179,7 @@ struct sun4i_i2s {
struct regmap_field *field_clkdiv_mclk_en;
struct regmap_field *field_fmt_wss;
struct regmap_field *field_fmt_sr;
+   struct regmap_field *field_fmt_sext;
 
const struct sun4i_i2s_quirks   *variant;
 };
@@ -354,6 +357,10 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 
regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 
+
+   /* Set sign extension to pad out LSB with 0 */
+   regmap_field_write(i2s->field_fmt_sext, 0);
+
return 0;
 }
 
@@ -1073,6 +1080,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks 
= {
.mclk_dividers  = sun4i_i2s_mclk_div,
.num_mclk_dividers  = ARRAY_SIZE(sun4i_i2s_mclk_div),
.get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
+   .field_fmt_sext = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
.get_sr = sun4i_i2s_get_sr,
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
@@ -1091,6 +1099,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
.mclk_dividers  = sun4i_i2s_mclk_div,
.num_mclk_dividers  = ARRAY_SIZE(sun4i_i2s_mclk_div),
.get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
+   .field_fmt_sext = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
.get_sr = sun4i_i2s_get_sr,
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
@@ -1109,6 +1118,7 @@ static const struct sun4i_i2s_quirks 
sun8i_a83t_i2s_quirks = {
.mclk_dividers  = sun8i_i2s_clk_div,
.num_mclk_dividers  = ARRAY_SIZE(sun8i_i2s_clk_div),
.get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
+   .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_chan_cfg   = sun8i_i2s_set_chan_cfg,
@@ -1127,6 +1137,7 @@ static const struct sun4i_i2s_quirks 
sun50i_a64_codec_i2s_quirks = {
.mclk_dividers  = sun4i_i2s_mclk_div,
.num_mclk_dividers  = ARRAY_SIZE(sun4i_i2s_mclk_div),
.get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
+   .field_fmt_sext = REG_FIELD(SUN4I_I2S_FMT1_REG, 8, 8),
.get_sr = sun4i_i2s_get_sr,
.get_wss= sun4i_i2s_get_wss,
.set_chan_cfg   = sun4i_i2s_set_chan_cfg,
@@ -1154,6 +1165,12 @@ static int sun4i_i2s_init_regmap_fields(struct device 
*dev,
if (IS_ERR(i2s->field_fmt_sr))
return PTR_ERR(i2s->field_fmt_sr);
 
+   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);
+
return 0;
 }
 
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190826180734.15801-3-codekipper%40gmail.com.


[linux-sunxi] [PATCH v6 0/3] ASoC: sun4i-i2s: Updates to the driver

2019-08-26 Thread codekipper
From: Marcus Cooper 

Hi All,

here is a patch series to add some improvements to the sun4i-i2s driver
which is enough to get HDMI audio working on the A83T, A64, H3 and
H5 platforms.

I've dropped a lot of the functionality that was presented earlier in favour
of getting initial HDMI audio delivered. H6 and multi-channel HDMI will
follow shortly.

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.

BR,
CK

---
v6 changes compared to v5 are:
- removed patches for multi-channel and H6 HDMI audio.
- removed patch for 20, 24 and 32 bit (will push support for just 20 and 24bit)
- ditched tdm patches as support has already been added.
- added fix for A83T reg map.

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.

---

Marcus Cooper (3):
  ASoC: sun4i-i2s: incorrect regmap for A83T
  ASoC: sun4i-i2s: Add regmap field to sign extend sample
  ASoC: sun4i-i2s: Adjust LRCLK width

 sound/soc/sunxi/sun4i-i2s.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190826180734.15801-1-codekipper%40gmail.com.


[linux-sunxi] [PATCH] ASoC: sun4i-i2s: incorrect regmap for A83t

2019-08-21 Thread codekipper
From: Marcus Cooper 

Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T")
Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index cbc6e59aa089..056a299c03fb 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -1109,7 +1109,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
.has_reset  = true,
.reg_offset_txdata  = SUN8I_I2S_FIFO_TX_REG,
-   .sun4i_i2s_regmap   = _i2s_regmap_config,
+   .sun4i_i2s_regmap   = _i2s_regmap_config,
.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),
-- 
2.23.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190821162320.28653-1-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 03/15] ASoC: sun4i-i2s: Correct divider calculations

2019-08-14 Thread codekipper
 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   = _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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-4-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 11/15] ASoC: sun4i-i2s: Add support for H6 I2S

2019-08-14 Thread codekipper
t * 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, 0x },
 };
 
+static const struct reg_default sun50i_i2s_reg_defaults[] = {
+   { SUN4I_I2S_CTRL_REG, 0x0006 },
+   { SUN4I_I2S_FMT0_REG, 0x0033 },
+   { SUN4I_I2S_FMT1_REG, 0x0030 },
+   { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
+   { SUN4I_I2S_DMA_INT_CTRL_REG, 0x },
+   { SUN4I_I2S_CLK_DIV_REG, 0x },
+   { SUN8I_I2S_CHAN_CFG_REG, 0x },
+   { SUN8I_I2S_TX_CHAN_SEL_REG, 0x },
+   { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x },
+   { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x },
+   { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x },
+};
+
 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   = _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 = _a64_codec_i2s_quirks,
},
+   {
+   .compatible = "allwinner,sun50i-h6-i2s",
+   .data = _h6_i2s_quirks,
+   },
{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.22.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-12-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 07/15] ASoC: sun4i-i2s: Add functions for RX and TX channel selects

2019-08-14 Thread codekipper
 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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-8-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 05/15] ASoC: sun4i-i2s: Add functions for RX and TX channel offsets

2019-08-14 Thread codekipper
From: Marcus Cooper 

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 
---
 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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-6-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 10/15] dt-bindings: ASoC: sun4i-i2s: Add H6 compatible

2019-08-14 Thread codekipper
From: Jernej Skrabec 

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 
---
 .../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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-11-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 14/15] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support

2019-08-14 Thread codekipper
From: Marcus Cooper 

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 
---
 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 = _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", )) {
if (val >= 2 && val <= 8)
-- 
2.22.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-15-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 00/15] ASoC: sun4i-i2s: Updates to the driver

2019-08-14 Thread codekipper
From: Marcus Cooper 

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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-1-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 12/15] ASoC: sun4i-i2s: Add multi-lane functionality

2019-08-14 Thread codekipper
From: Marcus Cooper 

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 
---
 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(>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(>dev, _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", )) {
+   if (val >= 2 && val <= 8)
+   soc_dai->playback.channels_max = val;
+   }
+
pm_runtime_enable(>dev);
if (!pm_runtime_enabled(>dev)) {
ret = sun4i_i2s_runtime_resume(>dev);
@@ -1465,7 +1487,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 
ret = devm_snd_soc_register_component(>dev,
  _i2s_component,
- _i2s_dai, 1);
+ soc_dai, 1);
if (ret) {
dev_err(>dev, "Could not register DAI\n");
goto err_suspend;
-- 
2.22.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-13-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 04/15] ASoC: sun4i-i2s: Support more formats on newer SoCs

2019-08-14 Thread codekipper
 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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-5-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 08/15] ASoC: sun4i-i2s: Add functions for channel mapping

2019-08-14 Thread codekipper
_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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-9-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 01/15] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2019-08-14 Thread codekipper
  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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-2-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 09/15] clk: sunxi-ng: h6: Allow I2S to change parent rate

2019-08-14 Thread codekipper
From: Jernej Skrabec 

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 
---
 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,
  _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,
  _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,
  _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,
  _div_ops,
- 0),
+ CLK_SET_RATE_PARENT),
},
 };
 
-- 
2.22.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-10-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 15/15] ASoC: sun4i-i2s: Adjust regmap settings

2019-08-14 Thread codekipper
From: Marcus Cooper 

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

Signed-off-by: Marcus Cooper 
---
 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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-16-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 06/15] ASoC: sun4i-i2s: Add functions for RX and TX channel enables

2019-08-14 Thread codekipper
From: Marcus Cooper 

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 
---
 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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-7-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 13/15] ASoC: sun4i-i2s: Add multichannel functionality

2019-08-14 Thread codekipper
   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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-14-codekipper%40gmail.com.


[linux-sunxi] [PATCH v5 02/15] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2019-08-14 Thread codekipper
From: Marcus Cooper 

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 
---
 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 inttdm_slots;
+   unsigned intslot_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

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190814060854.26345-3-codekipper%40gmail.com.


[linux-sunxi] [PATCH] ASoC: sun4i-i2s: Incorrect SR and WSS computation

2019-07-29 Thread codekipper
From: Marcus Cooper 

The A64 audio codec uses the original I2S block but the SR and
WSS computation currently assigned is for the newer block.

Fixes: 619c15f7fac9 (ASoC: sun4i-i2s: Change SR and WSS computation)
Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 9b2232908b65..7fa5c61169db 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -1002,8 +1002,8 @@ static const struct sun4i_i2s_quirks 
sun50i_a64_codec_i2s_quirks = {
.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,
+   .get_sr = sun4i_i2s_get_sr,
+   .get_wss= sun4i_i2s_get_wss,
 };
 
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
-- 
2.22.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190729152130.27955-1-codekipper%40gmail.com.


[linux-sunxi] [PATCH v4 6/9] ASoC: sun4i-i2s: Add multi-lane functionality

2019-06-03 Thread codekipper
e from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-7-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 1/9] ASoC: sun4i-i2s: Fix sun8i tx channel offset mask

2019-06-03 Thread codekipper
From: Marcus Cooper 

Although not causing any noticeable issues, the mask for the
channel offset is covering too many bits.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index c53bfed8d4c2..90bd3963d8ae 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -106,7 +106,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, 11)
+#define SUN8I_I2S_TX_CHAN_OFFSET_MASK  GENMASK(13, 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)
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-2-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 3/9] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2019-06-03 Thread codekipper
linux-sunxi+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-4-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 9/9] ASoC: sun4i-i2s: Adjust regmap settings

2019-06-03 Thread codekipper
From: Marcus Cooper 

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

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 29 +
 1 file changed, 9 insertions(+), 20 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 351b8021173b..92828a84902d 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -595,9 +595,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);
@@ -616,9 +618,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);
@@ -771,13 +775,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)
@@ -796,6 +794,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:
@@ -806,23 +806,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);
 }
@@ -877,7 +866,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,
 };
 
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-10-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 8/9] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support

2019-06-03 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 3549a87ed9e9..351b8021173b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -428,6 +428,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));
@@ -440,7 +445,18 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
sr = 0;
wss = 0;
break;
-
+   case 20:
+   sr = 1;
+   wss = 1;
+   break;
+   case 24:
+   sr = 2;
+   wss = 2;
+   break;
+   case 32:
+   sr = 4;
+   wss = 4;
+   break;
default:
dev_err(dai->dev, "Unsupported sample width: %d\n",
params_width(params));
@@ -722,6 +738,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 = {
@@ -729,14 +752,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 = _i2s_dai_ops,
.symmetric_rates = 1,
@@ -1161,6 +1184,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
goto err_pm_disable;
}
 
+   if (i2s->variant->is_h3_i2s_based) {
+   soc_dai->playback.formats = SUN8I_FORMATS;
+   soc_dai->capture.formats = SUN8I_FORMATS;
+   }
+
if (!of_property_read_u32(pdev->dev.of_node,
  "allwinner,playback-channels", )) {
if (val >= 2 && val <= 8)
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-9-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 4/9] ASoC: sun4i-i2s: Reduce quirks for sun8i-h3

2019-06-03 Thread codekipper
From: Marcus Cooper 

We have a number of flags used to identify the functionality
of the IP block found on the sun8i-h3 and later devices. As it
is only neccessary to identify this new block then replace
these flags with just one.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 23 +++
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index e2961d8f6e8c..329883750d6f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -119,10 +119,7 @@
  *
  * @has_reset: SoC needs reset deasserted.
  * @has_slave_select_bit: SoC has a bit to enable slave mode.
- * @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
- * @has_chcfg: tx and rx slot number need to be set.
- * @has_chsel_tx_chen: SoC requires that the tx channels are enabled.
- * @has_chsel_offset: SoC uses offset for selecting dai operational mode.
+ * @is_h3_i2s_based: This block is similiar to what is found on the h3.
  * @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.
@@ -143,10 +140,7 @@
 struct sun4i_i2s_quirks {
boolhas_reset;
boolhas_slave_select_bit;
-   boolhas_fmt_set_lrck_period;
-   boolhas_chcfg;
-   boolhas_chsel_tx_chen;
-   boolhas_chsel_offset;
+   boolis_h3_i2s_based;
unsigned intreg_offset_txdata;  /* TX FIFO */
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
@@ -340,7 +334,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 
/* Set sync period */
-   if (i2s->variant->has_fmt_set_lrck_period)
+   if (i2s->variant->is_h3_i2s_based)
regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
   SUN8I_I2S_FMT0_LRCK_PERIOD(32));
@@ -366,7 +360,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
return -EINVAL;
}
 
-   if (i2s->variant->has_chcfg) {
+   if (i2s->variant->is_h3_i2s_based) {
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));
@@ -386,7 +380,7 @@ 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)
+   if (i2s->variant->is_h3_i2s_based)
regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
   SUN8I_I2S_TX_CHAN_EN_MASK,
   SUN8I_I2S_TX_CHAN_EN(channels));
@@ -449,7 +443,7 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
return -EINVAL;
}
 
-   if (i2s->variant->has_chsel_offset) {
+   if (i2s->variant->is_h3_i2s_based) {
/*
 * offset being set indicates that we're connected to an i2s
 * device, however offset is only used on the sun8i block and
@@ -942,10 +936,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = 
{
.mclk_offset= 1,
.bclk_offset= 2,
.fmt_offset = 3,
-   .has_fmt_set_lrck_period = true,
-   .has_chcfg  = true,
-   .has_chsel_tx_chen  = true,
-   .has_chsel_offset   = true,
+   .is_h3_i2s_based = 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),
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-5-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 7/9] ASoC: sun4i-i2s: Add multichannel functionality

2019-06-03 Thread codekipper
ap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+12, 
0x76);
+   regmap_write(i2s->regmap, 
SUN8I_I2S_TX_CHAN_SEL_REG+12,
+chan_sel | 0x30);
+   }
+   }
+   } else {
+   /* Map the channels for capture */
+   regmap_field_write(i2s->field_rxchanmap, 0x3210);
+   regmap_field_write(i2s->field_rxchansel,
+  SUN4I_I2S_CHAN_SEL(params_channels(params)));
+
+   if (i2s->variant->is_h3_i2s_based) {
+   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));
+
+   regmap_update_bits(i2s->regmap, 
SUN8I_I2S_RX_CHAN_SEL_REG,
+  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+  
SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
+   }
}
 
-   /* 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)));
-
-   if (i2s->variant->is_h3_i2s_based)
-   regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
-  SUN8I_I2S_TX_CHAN_EN_MASK,
-  SUN8I_I2S_TX_CHAN_EN(channels));
-
switch (params_physical_width(params)) {
case 16:
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
@@ -445,7 +461,6 @@ 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 offset = 0;
u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL;
 
@@ -453,7 +468,7 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
val = SUN4I_I2S_FMT0_FMT_I2S;
-   offset = 1;
+   i2s->offset = 1;
break;
case SND_SOC_DAIFMT_LEFT_J:
val = SUN4I_I2S_FMT0_FMT_LEFT_J;
@@ -474,16 +489,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
 * i2s shares the same setting with the LJ format. Increment
 * val so that the bit to value to write is correct.
 */
-   if (offset > 0)
+   if (i2s->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_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
-  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
-  SUN8I_I2S_TX_CHAN_OFFSET(offset));
}
 
regmap_field_write(i2s->field_fmt_mode, val);
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-8-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 5/9] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2019-06-03 Thread codekipper
From: Marcus Cooper 

Some codecs require a different amount of a 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 
---
 sound/soc/sunxi/sun4i-i2s.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 329883750d6f..bca73b3c0d74 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -186,6 +186,9 @@ struct sun4i_i2s {
struct regmap_field *field_rxchansel;
 
const struct sun4i_i2s_quirks   *variant;
+
+   unsigned inttdm_slots;
+   unsigned intslot_width;
 };
 
 struct sun4i_i2s_clk_div {
@@ -337,7 +340,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
if (i2s->variant->is_h3_i2s_based)
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);
@@ -414,7 +417,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
   sr + i2s->variant->fmt_offset);
 
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)
@@ -657,11 +661,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,
.trigger= sun4i_i2s_trigger,
+   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
 };
 
 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-6-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 2/9] ASoC: sun4i-i2s: Add offset to RX channel select

2019-06-03 Thread codekipper
From: Marcus Cooper 

Whilst testing the capture functionality of the i2s on the newer
SoCs it was noticed that the recording was somewhat distorted.
This was due to the offset not being set correctly on the receiver
side.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 90bd3963d8ae..fd7c37596f21 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -456,6 +456,10 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
   SUN8I_I2S_TX_CHAN_OFFSET(offset));
+
+   regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
+  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+  SUN8I_I2S_TX_CHAN_OFFSET(offset));
}
 
regmap_field_write(i2s->field_fmt_mode, val);
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-3-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4 0/9]ASoC: sun4i-i2s: Updates to the driver

2019-06-03 Thread codekipper
From: Marcus Cooper 

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 surround sound working and this is 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 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.

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.

BR,
CK

---
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.


Marcus Cooper (9):
  ASoC: sun4i-i2s: Fix sun8i tx channel offset mask
  ASoC: sun4i-i2s: Add offset to RX channel select
  ASoC: sun4i-i2s: Add regmap field to sign extend sample
  ASoC: sun4i-i2s: Reduce quirks for sun8i-h3
  ASoC: sun4i-i2s: Add set_tdm_slot functionality
  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/soc/sunxi/sun4i-i2s.c | 242 
 1 file changed, 164 insertions(+), 78 deletions(-)

-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190603174735.21002-1-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v7] sun8i: h3: Add support for the Beelink-x2 STB

2019-06-02 Thread codekipper
};
+
+   leds {
+   compatible = "gpio-leds";
+
+   blue {
+   label = "beelink-x2:blue:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+   default-state = "on";
+   };
+
+   red {
+   label = "beelink-x2:red:standby";
+   gpios = < 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
+   };
+   };
+
+   wifi_pwrseq: wifi_pwrseq {
+   compatible = "mmc-pwrseq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+_otg {
+   dr_mode = "otg";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on except for the OTG port */
+   status = "okay";
+   usb0_id_det-gpios = < 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */
+   usb0_vbus-supply = <_usb0_vbus>;
+};
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index bdd1854197..c7e9d3eda0 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -172,6 +172,12 @@ S: Maintained
 F: configs/beelink_gs1_defconfig
 F: arch/arm/dts/sun50i-h6-beelink-gs1.dts
 
+BEELINK X2 BOARD
+M: Marcus Cooper 
+S: Maintained
+F: configs/beelink_x2_defconfig
+F: arch/arm/dts/sun8i-h3-beelink-x2.dts
+
 COLOMBUS BOARD
 M: Maxime Ripard 
 S: Maintained
diff --git a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig
new file mode 100644
index 00..be946956fa
--- /dev/null
+++ b/configs/beelink_x2_defconfig
@@ -0,0 +1,16 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=567
+CONFIG_DRAM_ZQ=3881979
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-beelink-x2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_CONSOLE_MUX=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SUN8I_EMAC=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190602063840.3289-1-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v6] sun8i: h3: Add support for the Beelink-x2 STB

2019-05-29 Thread codekipper
imple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+_otg {
+   dr_mode = "otg";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on except for the OTG port */
+   status = "okay";
+   usb0_id_det-gpios = < 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */
+   usb0_vbus-supply = <_usb0_vbus>;
+};
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index bdd1854197..c7e9d3eda0 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -172,6 +172,12 @@ S: Maintained
 F: configs/beelink_gs1_defconfig
 F: arch/arm/dts/sun50i-h6-beelink-gs1.dts
 
+BEELINK X2 BOARD
+M: Marcus Cooper 
+S: Maintained
+F: configs/beelink_x2_defconfig
+F: arch/arm/dts/sun8i-h3-beelink-x2.dts
+
 COLOMBUS BOARD
 M: Maxime Ripard 
 S: Maintained
diff --git a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig
new file mode 100644
index 00..0580020bc6
--- /dev/null
+++ b/configs/beelink_x2_defconfig
@@ -0,0 +1,18 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=567
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-beelink-x2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_TEXT_BASE=0x60
+CONFIG_CONSOLE_MUX=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SUN8I_EMAC=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190529115458.11140-1-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5] sun8i: h3: Add support for the Beelink-x2 STB

2019-05-26 Thread codekipper
gpios = < 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
+   };
+   };
+
+   wifi_pwrseq: wifi_pwrseq {
+   compatible = "mmc-pwrseq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+_otg {
+   dr_mode = "otg";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on except for the OTG port */
+   status = "okay";
+   usb0_id_det-gpios = < 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */
+   usb0_vbus-supply = <_usb0_vbus>;
+};
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index bdd1854197..28f2bece40 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -172,6 +172,11 @@ S: Maintained
 F: configs/beelink_gs1_defconfig
 F: arch/arm/dts/sun50i-h6-beelink-gs1.dts
 
+BEELINK X2 BOARD
+M: Marcus Cooper 
+S: Maintained
+F: configs/beelink_x2_defconfig
+
 COLOMBUS BOARD
 M: Maxime Ripard 
 S: Maintained
diff --git a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig
new file mode 100644
index 00..0580020bc6
--- /dev/null
+++ b/configs/beelink_x2_defconfig
@@ -0,0 +1,18 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=567
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-beelink-x2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_TEXT_BASE=0x60
+CONFIG_CONSOLE_MUX=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SUN8I_EMAC=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190526145711.3622-1-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v4] sun8i: h3: Add support for the Beelink-x2 STB

2019-05-26 Thread codekipper
seq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+_otg {
+   dr_mode = "otg";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on except for the OTG port */
+   status = "okay";
+   usb0_id_det-gpios = < 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */
+   usb0_vbus-supply = <_usb0_vbus>;
+};
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index bdd1854197..28f2bece40 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -172,6 +172,11 @@ S: Maintained
 F: configs/beelink_gs1_defconfig
 F: arch/arm/dts/sun50i-h6-beelink-gs1.dts
 
+BEELINK X2 BOARD
+M: Marcus Cooper 
+S: Maintained
+F: configs/beelink_x2_defconfig
+
 COLOMBUS BOARD
 M: Maxime Ripard 
 S: Maintained
diff --git a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig
new file mode 100644
index 00..6508e470a0
--- /dev/null
+++ b/configs/beelink_x2_defconfig
@@ -0,0 +1,19 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=624
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-beelink-x2"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_CONSOLE_MUX=y
+CONFIG_SPL_I2C_SUPPORT=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SUN8I_EMAC=y
+CONFIG_SY8106A_POWER=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
-- 
2.21.0

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/linux-sunxi/20190526062841.18532-1-codekipper%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 5/9] ASoC: sun4i-i2s: Correct divider calculations

2018-12-21 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 82 +
 1 file changed, 56 insertions(+), 26 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 93a484d7e228..b31f84787218 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -129,10 +129,10 @@
  * @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.
  * @fmt_offset: Value by which wss and sr needs to be adjusted.
  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
+ * @field_clkdiv_mclk: regmap field for mclkdiv.
+ * @field_clkdiv_bclk: regmap field for bclkdiv.
  * @field_fmt_wss: regmap field to set word select size.
  * @field_fmt_sr: regmap field to set sample resolution.
  * @field_fmt_bclk: regmap field to set clk polarity.
@@ -153,8 +153,6 @@ struct sun4i_i2s_quirks {
boolhas_chsel_offset;
unsigned intreg_offset_txdata;  /* TX FIFO */
const struct regmap_config  *sun4i_i2s_regmap;
-   unsigned intmclk_offset;
-   unsigned intbclk_offset;
unsigned intfmt_offset;
 
/* Register fields for i2s */
@@ -210,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[] = {
@@ -222,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 = _i2s_bclk_div[i];
-
+   for (i = 0; i < size; i++) {
if (bdiv->div == div)
return bdiv->val;
+   bdiv++;
}
 
return -EINVAL;
@@ -245,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 = _i2s_mclk_div[i];
-
+   for (i = 0; i < size; i++) {
if (mdiv->div == div)
return mdiv->val;
+   mdiv++;
}
 
return -EINVAL;
@@ -319,24 +336,39 @@ 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,
+ 

[linux-sunxi] [PATCH v3 7/9] ASoC: sun4i-i2s: Do not divide clocks when slave

2018-12-21 Thread codekipper
From: Marcus Cooper 

There is no need to set the clock and calculate the division of
the audio pll for the bclk and sync signals when they are not
required.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 144 +++-
 1 file changed, 77 insertions(+), 67 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index e85789d84c0c..8cec2f42c94e 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -194,6 +194,8 @@ struct sun4i_i2s {
struct regmap_field *field_rxchansel;
 
const struct sun4i_i2s_quirks   *variant;
+
+   bool bit_clk_master;
 };
 
 struct sun4i_i2s_clk_div {
@@ -298,82 +300,86 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
int bclk_div, mclk_div;
int ret;
 
-   switch (rate) {
-   case 176400:
-   case 88200:
-   case 44100:
-   case 22050:
-   case 11025:
-   clk_rate = 22579200;
-   break;
+   if (i2s->bit_clk_master) {
+   switch (rate) {
+   case 176400:
+   case 88200:
+   case 44100:
+   case 22050:
+   case 11025:
+   clk_rate = 22579200;
+   break;
 
-   case 192000:
-   case 128000:
-   case 96000:
-   case 64000:
-   case 48000:
-   case 32000:
-   case 24000:
-   case 16000:
-   case 12000:
-   case 8000:
-   clk_rate = 24576000;
-   break;
+   case 192000:
+   case 128000:
+   case 96000:
+   case 64000:
+   case 48000:
+   case 32000:
+   case 24000:
+   case 16000:
+   case 12000:
+   case 8000:
+   clk_rate = 24576000;
+   break;
 
-   default:
-   dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
-   return -EINVAL;
-   }
+   default:
+   dev_err(dai->dev, "Unsupported sample rate: %u\n", 
rate);
+   return -EINVAL;
+   }
 
-   ret = clk_set_rate(i2s->mod_clk, clk_rate);
-   if (ret)
-   return ret;
+   ret = clk_set_rate(i2s->mod_clk, clk_rate);
+   if (ret) {
+   dev_err(dai->dev, "Unable to set clock\n");
+   return ret;
+   }
 
-   oversample_rate = i2s->mclk_freq / rate;
-   if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
-   dev_err(dai->dev, "Unsupported oversample rate: %d\n",
-   oversample_rate);
-   return -EINVAL;
-   }
+   oversample_rate = i2s->mclk_freq / rate;
+   if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
+   dev_err(dai->dev, "Unsupported oversample rate: %d\n",
+   oversample_rate);
+   return -EINVAL;
+   }
 
-   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;
-   }
+   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;
+   }
 
 
-   if (i2s->variant->has_fmt_set_lrck_period)
-   mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
-   

[linux-sunxi] [PATCH v3 2/9] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2018-12-21 Thread codekipper
From: Marcus Cooper 

On the newer SoCs this is set by default to transfer a 0 after
each sample in each slot. Add the regmap field to configure this
and set it so that it pads the sample with 0s.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 64d073cb2aee..80bf29e0cc86 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -138,6 +138,7 @@
  * @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.
@@ -163,6 +164,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_fmt_bclk;
struct reg_fieldfield_fmt_lrclk;
struct reg_fieldfield_fmt_mode;
+   struct reg_fieldfield_fmt_sext;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -187,6 +189,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;
@@ -346,6 +349,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;
 }
 
@@ -876,6 +882,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),
@@ -893,6 +900,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),
@@ -933,6 +941,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),
@@ -995,6 +1004,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.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 3/9] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support

2018-12-21 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 41 ++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 80bf29e0cc86..adb988ae9ac5 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -399,6 +399,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));
@@ -411,7 +416,18 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
sr = 0;
wss = 0;
break;
-
+   case 20:
+   sr = 1;
+   wss = 1;
+   break;
+   case 24:
+   sr = 2;
+   wss = 2;
+   break;
+   case 32:
+   sr = 4;
+   wss = 4;
+   break;
default:
dev_err(dai->dev, "Unsupported sample width: %d\n",
params_width(params));
@@ -687,6 +703,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_3LE | \
+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 = {
@@ -694,14 +717,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 = _i2s_dai_ops,
.symmetric_rates = 1,
@@ -1106,6 +1129,18 @@ 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(>dev, _i2s_dai,
+  sizeof(*soc_dai), GFP_KERNEL);
+   if (!soc_dai) {
+   ret = -ENOMEM;
+   goto err_pm_disable;
+   }
+
+   if (i2s->variant->has_fmt_set_lrck_period) {
+   soc_dai->playback.formats = SUN8I_FORMATS;
+   soc_dai->capture.formats = SUN8I_FORMATS;
+   }
+
pm_runtime_enable(>dev);
if (!pm_runtime_enabled(>dev)) {
ret = sun4i_i2s_runtime_resume(>dev);
-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 4/9] ASoC: sun4i-i2s: Fix offset mask

2018-12-21 Thread codekipper
From: Marcus Cooper 

Also add offset to RX channel select

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index adb988ae9ac5..93a484d7e228 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -110,7 +110,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, 11)
+#define SUN8I_I2S_TX_CHAN_OFFSET_MASK  GENMASK(13, 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)
@@ -482,6 +482,10 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
   SUN8I_I2S_TX_CHAN_OFFSET(offset));
+
+   regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
+  SUN8I_I2S_TX_CHAN_OFFSET_MASK,
+  SUN8I_I2S_TX_CHAN_OFFSET(offset));
}
 
regmap_field_write(i2s->field_fmt_mode, val);
-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 6/9] ASoC: sun4i-i2s: Add multi-lane functionality

2018-12-21 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 37 -
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index b31f84787218..e85789d84c0c 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -27,7 +27,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)
@@ -394,14 +394,23 @@ 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) {
+   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;
}
 
+   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,
@@ -412,8 +421,19 @@ 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, 0x3210);
+   regmap_field_write(i2s->field_txchanmap, 0x10);
+   if (i2s->variant->has_chsel_tx_chen) {
+   if (channels > 2)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+4, 0x32);
+   if (channels > 4)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+8, 0x54);
+   if (channels > 6)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+12, 0x76);
+   }
 
/* Configure the channels */
regmap_field_write(i2s->field_txchansel,
@@ -1094,9 +1114,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(>dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s)
@@ -1175,6 +1196,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
soc_dai->capture.formats = SUN8I_FORMATS;
}
 
+   if (!of_property_read_u32(pdev->dev.of_node,
+ "allwinner,playback-channels", )) {
+   if (val >= 2 && val <= 8)
+   soc_dai->playback.channels_max = val;
+   }
+
pm_runtime_enable(>dev);
if (!pm_runtime_enabled(>dev)) {
ret = sun4i_i2s_runtime_resume(>dev);
@@ -1184,7 +1211,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 
ret = devm_snd_soc_register_component(>dev,
  _i2s_component,
- _i2s_dai, 1);
+ soc_dai, 1);
if (ret) {
dev_err(>dev, "Could not register DAI\n");
goto err_suspend;
-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 8/9] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-12-21 Thread codekipper
From: Marcus Cooper 

Some codecs require a different amount of a 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 
---
 sound/soc/sunxi/sun4i-i2s.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 8cec2f42c94e..cfcf427270fd 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -196,6 +196,9 @@ struct sun4i_i2s {
const struct sun4i_i2s_quirks   *variant;
 
bool bit_clk_master;
+
+   unsigned inttdm_slots;
+   unsigned intslot_width;
 };
 
 struct sun4i_i2s_clk_div {
@@ -385,7 +388,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);
@@ -498,7 +501,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
   sr + i2s->variant->fmt_offset);
 
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)
@@ -749,11 +753,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,
.trigger= sun4i_i2s_trigger,
+   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
 };
 
 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 9/9] ASoC: sun4i-i2s: Add multichannel functionality

2018-12-21 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 121 +++-
 1 file changed, 64 insertions(+), 57 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index cfcf427270fd..2be3a3e7a3c0 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -199,6 +199,7 @@ struct sun4i_i2s {
 
unsigned inttdm_slots;
unsigned intslot_width;
+   unsigned intoffset;
 };
 
 struct sun4i_i2s_clk_div {
@@ -406,56 +407,71 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
int lines;
 
channels = params_channels(params);
-   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;
-   }
-
-   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 */
-   regmap_field_write(i2s->field_rxchanmap, 0x3210);
-   regmap_field_write(i2s->field_txchanmap, 0x10);
-   if (i2s->variant->has_chsel_tx_chen) {
-   if (channels > 2)
-   regmap_write(i2s->regmap,
-SUN8I_I2S_TX_CHAN_MAP_REG+4, 0x32);
-   if (channels > 4)
-   regmap_write(i2s->regmap,
-SUN8I_I2S_TX_CHAN_MAP_REG+8, 0x54);
-   if (channels > 6)
-   regmap_write(i2s->regmap,
-SUN8I_I2S_TX_CHAN_MAP_REG+12, 0x76);
+   /* 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_field_write(i2s->field_txchanmap, 0x10);
+   /* Configure the channels */
+   regmap_field_write(i2s->field_txchansel, SUN4I_I2S_CHAN_SEL(2));
+
+   if (i2s->variant->has_chsel_tx_chen) {
+   u32 chan_sel = SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset) | 
0x1;
+   regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
+chan_sel | 0x30);
+
+   if (channels > 2) {
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+4, 0x32);
+   regmap_write(i2s->regmap, 
SUN8I_I2S_TX_CHAN_SEL_REG+4,
+chan_sel | 0x30);
+   }
+   if (channels > 4) {
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+8, 0x54);
+   regmap_write(i2s->regmap, 
SUN8I_I2S_TX_CHAN_SEL_REG+8,
+chan_sel | 0x30);
+   }
+   if (channels > 6) {
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+12, 
0x76);
+   regmap_write(i2s->regmap, 
SUN8I_I2S_TX_CHAN_SEL_REG+12,

[linux-sunxi] [PATCH v3 1/9] ASoC: sun4i-i2s: Adjust regmap settings

2018-12-21 Thread codekipper
From: Marcus Cooper 

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

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 29 +
 1 file changed, 9 insertions(+), 20 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index d5ec1a20499d..64d073cb2aee 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -548,9 +548,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);
@@ -569,9 +571,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);
@@ -703,13 +707,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)
@@ -728,6 +726,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:
@@ -738,23 +738,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);
 }
@@ -809,7 +798,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,
 };
 
-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 0/9] ASoC: sun4i-i2s: Updates to the driver

2018-12-21 Thread codekipper
From: Marcus Cooper 

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. Since the last push there has been some activity getting surround
sound working and this is 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 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.

Anyway, I've moved the more controversial patches to the top of the stack
as I'm expecting feedback.

Have a great Xmas and New Year,

BR,
CK

---

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.

---

Marcus Cooper (9):
  ASoC: sun4i-i2s: Adjust regmap settings
  ASoC: sun4i-i2s: Add regmap field to sign extend sample
  ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  ASoC: sun4i-i2s: Fix offset mask
  ASoC: sun4i-i2s: Correct divider calculations
  ASoC: sun4i-i2s: Add multi-lane functionality
  ASoC: sun4i-i2s: Do not divide clocks when slave
  ASoC: sun4i-i2s: Add set_tdm_slot functionality
  ASoC: sun4i-i2s: Add multichannel functionality

 sound/soc/sunxi/sun4i-i2s.c | 399 
 1 file changed, 267 insertions(+), 132 deletions(-)

-- 
2.20.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3] sun8i: h3: Add support for the Beelink-x2 STB

2018-11-15 Thread codekipper
From: Marcus Cooper 

The Beelink X2 is an STB based on the Allwinner H3 SoC with a uSD slot,
2 USB ports( 1 * USB-2 Host, 1 USB OTG), a 10/100M ethernet port using the
SoC's integrated PHY, Wifi via an sdio wifi chip, HDMI, an IR receiver, a
dual colour LED and an optical S/PDIF connector.

Signed-off-by: Marcus Cooper 
---
Changes in v3:
- Removed incorrect commit author
- Included v1-v2 change info

Changes in v2:
- updated dts to reflex current linux kernel status

---
 arch/arm/dts/Makefile|   1 +
 arch/arm/dts/sun8i-h3-beelink-x2.dts | 179 +++
 board/sunxi/MAINTAINERS  |   5 +
 configs/beelink_x2_defconfig |  19 +++
 4 files changed, 204 insertions(+)
 create mode 100644 arch/arm/dts/sun8i-h3-beelink-x2.dts
 create mode 100644 configs/beelink_x2_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 1cbb45d679..cc217d4f98 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -370,6 +370,7 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h2-plus-orangepi-r1.dtb \
sun8i-h2-plus-orangepi-zero.dtb \
sun8i-h3-bananapi-m2-plus.dtb \
+   sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
sun8i-h3-nanopi-m1.dtb \
sun8i-h3-nanopi-m1-plus.dtb \
diff --git a/arch/arm/dts/sun8i-h3-beelink-x2.dts 
b/arch/arm/dts/sun8i-h3-beelink-x2.dts
new file mode 100644
index 00..683c5c31a9
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-beelink-x2.dts
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Device Tree Source for Beelink X2
+//
+// Copyright (C) 2018 Marcus Cooper 
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "Beelink X2";
+   compatible = "roofull,beelink-x2", "allwinner,sun8i-h3";
+
+   aliases {
+   serial0 = 
+   /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+   ethernet1 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
+   leds {
+   compatible = "gpio-leds";
+
+   blue {
+   label = "beelink-x2:blue:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+   default-state = "on";
+   };
+
+   red {
+   label = "beelink-x2:red:standby";
+   gpios = < 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
+   };
+   };
+
+   wifi_pwrseq: wifi_pwrseq {
+   compatible = "mmc-pwrseq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   

[linux-sunxi] [PATCH v2] sun8i: h3: Add support for the Beelink-x2 STB

2018-11-15 Thread codekipper
From: Marcus Cooper 

The Beelink X2 is an STB based on the Allwinner H3 SoC with a uSD slot,
2 USB ports( 1 * USB-2 Host, 1 USB OTG), a 10/100M ethernet port using the
SoC's integrated PHY, Wifi via an sdio wifi chip, HDMI, an IR receiver, a
dual colour LED and an optical S/PDIF connector.

Signed-off-by: Marcus Cooper 
---
 arch/arm/dts/Makefile|   1 +
 arch/arm/dts/sun8i-h3-beelink-x2.dts | 179 +++
 board/sunxi/MAINTAINERS  |   5 +
 configs/beelink_x2_defconfig |  19 +++
 4 files changed, 204 insertions(+)
 create mode 100644 arch/arm/dts/sun8i-h3-beelink-x2.dts
 create mode 100644 configs/beelink_x2_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 1cbb45d679..cc217d4f98 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -370,6 +370,7 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h2-plus-orangepi-r1.dtb \
sun8i-h2-plus-orangepi-zero.dtb \
sun8i-h3-bananapi-m2-plus.dtb \
+   sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
sun8i-h3-nanopi-m1.dtb \
sun8i-h3-nanopi-m1-plus.dtb \
diff --git a/arch/arm/dts/sun8i-h3-beelink-x2.dts 
b/arch/arm/dts/sun8i-h3-beelink-x2.dts
new file mode 100644
index 00..683c5c31a9
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-beelink-x2.dts
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Device Tree Source for Beelink X2
+//
+// Copyright (C) 2018 Marcus Cooper 
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "Beelink X2";
+   compatible = "roofull,beelink-x2", "allwinner,sun8i-h3";
+
+   aliases {
+   serial0 = 
+   /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+   ethernet1 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
+   leds {
+   compatible = "gpio-leds";
+
+   blue {
+   label = "beelink-x2:blue:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+   default-state = "on";
+   };
+
+   red {
+   label = "beelink-x2:red:standby";
+   gpios = < 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
+   };
+   };
+
+   wifi_pwrseq: wifi_pwrseq {
+   compatible = "mmc-pwrseq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   non-removable;
+   status = "okay";
+
+   /*
+* Explicitly define the sdio device, so that we can add an ethernet
+* alias for it (which e.g. makes u-boot set a mac-address).
+*/
+   sdiowifi: sdio_wifi@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+_usb0_vbus {
+   gpio = <_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+_otg {
+   dr_mode = "otg";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always 

[linux-sunxi] [PATCH v2 6/6] ASoC: sun4i-i2s: Add support for loopback

2018-03-12 Thread codekipper
From: Marcus Cooper 

The DAI has a loopback register which can be set and therefore routes
the transmit fifo to receive fifo. This is useful for testing the block
without the need for any external hardware.

Signed-off-by: Marcus Cooper 
---
 Documentation/devicetree/bindings/sound/sun4i-i2s.txt |  3 +++
 sound/soc/sunxi/sun4i-i2s.c   | 11 +++
 2 files changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt 
b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index 3f966ac61b9e..325e3d4571f1 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -32,6 +32,9 @@ Optional properties:
 - allwinner,slot-width-override:if this property is present then the dai is
configured to extend the slot width to the
value specified. Min 8, Max 32.
+- loopback:if this property is present then the dai is configured in
+   loopback mode where the output fifo is redirected to the input
+   fifo.
 
 - allwinner,playback-channels:  if this property is present then the number
of available channels is extended and the
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 7cf4dfe440de..a3c33814d33e 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -31,6 +31,7 @@
 #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_LOOPBIT(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)
@@ -195,6 +196,8 @@ struct sun4i_i2s {
 
const struct sun4i_i2s_quirks   *variant;
 
+   bool loopback;
+
unsigned intslot_width;
 };
 
@@ -639,6 +642,11 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
+
+   /* Debugging without codec */
+   if (i2s->loopback)
+   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+  SUN4I_I2S_CTRL_LOOP, SUN4I_I2S_CTRL_LOOP);
 }
 
 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
@@ -1204,6 +1212,9 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
soc_dai->playback.channels_max = val;
}
 
+   if (of_property_read_bool(pdev->dev.of_node, "loopback"))
+   i2s->loopback = true;
+
pm_runtime_enable(>dev);
if (!pm_runtime_enabled(>dev)) {
ret = sun4i_i2s_runtime_resume(>dev);
-- 
2.16.2

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 5/6] ASoc: sun4i-i2s: Add 20, 24 and 32 bit support

2018-03-12 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 436480df1844..7cf4dfe440de 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -451,6 +451,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));
@@ -463,7 +468,18 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
sr = 0;
wss = 0;
break;
-
+   case 20:
+   sr = 1;
+   wss = 1;
+   break;
+   case 24:
+   sr = 2;
+   wss = 2;
+   break;
+   case 32:
+   sr = 4;
+   wss = 4;
+   break;
default:
dev_err(dai->dev, "Unsupported sample width: %d\n",
params_width(params));
@@ -766,6 +782,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_3LE | \
+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 = {
@@ -773,14 +796,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 = _i2s_dai_ops,
.symmetric_rates = 1,
@@ -1170,6 +1193,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", )) {
if (val >= 2 && val <= 8)
-- 
2.16.2

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 3/6] ASoC: sun4i-i2s: Correct divider calculations

2018-03-12 Thread codekipper
From: Marcus Cooper 

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 
---
 sound/soc/sunxi/sun4i-i2s.c | 76 +++--
 1 file changed, 52 insertions(+), 24 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 396b11346361..2bd0befa02a8 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -129,10 +129,10 @@
  * @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.
  * @fmt_offset: Value by which wss and sr needs to be adjusted.
  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
+ * @field_clkdiv_mclk: regmap field for mclkdiv.
+ * @field_clkdiv_bclk: regmap field for bclkdiv.
  * @field_fmt_wss: regmap field to set word select size.
  * @field_fmt_sr: regmap field to set sample resolution.
  * @field_fmt_bclk: regmap field to set clk polarity.
@@ -153,8 +153,6 @@ struct sun4i_i2s_quirks {
boolhas_chsel_offset;
unsigned intreg_offset_txdata;  /* TX FIFO */
const struct regmap_config  *sun4i_i2s_regmap;
-   unsigned intmclk_offset;
-   unsigned intbclk_offset;
unsigned intfmt_offset;
 
/* Register fields for i2s */
@@ -212,7 +210,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 +240,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 = _i2s_bclk_div[i];
-
+   for (i = 0; i < size; i++) {
if (bdiv->div == div)
return bdiv->val;
+   bdiv++;
}
 
return -EINVAL;
@@ -247,16 +263,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 = _i2s_mclk_div[i];
-
+   for (i = 0; i < size; i++) {
if (mdiv->div == div)
return mdiv->val;
+   mdiv++;
}
 
return -EINVAL;
@@ -321,24 +338,37 @@ 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,
+ 

[linux-sunxi] [PATCH v2 2/6] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2018-03-12 Thread codekipper
From: Marcus Cooper 

On the newer SoCs (H3, H5, A64 etc) this is set by default to
transfer a 0 after each sample in each slot whereas on the
earlier SoCs (A20, A31 etc) the default sign extension is to
pad the LSB.

Add the regmap field to configure this and set it so that it
pads the sample with 0s.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 873054a6c3be..396b11346361 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -138,6 +138,7 @@
  * @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.
@@ -163,6 +164,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_fmt_bclk;
struct reg_fieldfield_fmt_lrclk;
struct reg_fieldfield_fmt_mode;
+   struct reg_fieldfield_fmt_sext;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -187,6 +189,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;
@@ -348,6 +351,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
   SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
 
+   /* Set sign extension to pad out LSB with 0 */
+   regmap_field_write(i2s->field_fmt_sext, 0);
+
return 0;
 }
 
@@ -901,6 +907,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),
@@ -918,6 +925,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),
@@ -958,6 +966,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),
@@ -1003,6 +1012,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.16.2

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 0/6] ASoC: sun4i-i2s: Updates to the driver

2018-03-12 Thread codekipper
From: Marcus Cooper <codekip...@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. The original attempt had some changes related to the slave work
but I've left them out for this release as I would still like to do some
more investigations.

The functionality included with the new patch set has been extended to
cover more sample resolutions, multi-lane data output for HDMI audio
and loopback so block testing can be made without an external codec.

I've also moved away from using tdm to set the slot width and now use
a dedicated property.

This has been tested on a Pine64 using the ES9023 audio POT board
(https://github.com/codekipper/linux-sunxi/commits/upstream)
and HDMI audio
(https://github.com/codekipper/linux-sunxi/commits/sunxi-wip-a64)

BR,
CK

---
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.

---

Marcus Cooper (6):
  ASoC: sun4i-i2s: Add slot width override
  ASoC: sun4i-i2s: Add regmap field to sign extend sample
  ASoC: sun4i-i2s: Correct divider calculations
  ASoC: sun4i-i2s: Add multi-lane functionality
  ASoc: sun4i-i2s: Add 20, 24 and 32 bit support
  ASoC: sun4i-i2s: Add support for loopback

 .../devicetree/bindings/sound/sun4i-i2s.txt|  11 ++
 sound/soc/sunxi/sun4i-i2s.c| 199 -
 2 files changed, 170 insertions(+), 40 deletions(-)

-- 
2.16.2

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 1/6] ASoC: sun4i-i2s: Add slot width override

2018-03-12 Thread codekipper
From: Marcus Cooper 

Some codecs require a different amount of a bit clocks per frame
than what is calculated by using the sample width. Use a slot
width override property to provide this mechanism.

Signed-off-by: Marcus Cooper 
---
 Documentation/devicetree/bindings/sound/sun4i-i2s.txt |  5 +
 sound/soc/sunxi/sun4i-i2s.c   | 15 ---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt 
b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index b9d50d6cdef3..48addef65b8f 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -28,6 +28,11 @@ Required properties for the following compatibles:
- "allwinner,sun8i-h3-i2s"
 - resets: phandle to the reset line for this codec
 
+Optional properties:
+- allwinner,slot-width-override:if this property is present then the dai is
+   configured to extend the slot width to the
+   value specified. Min 8, Max 32.
+
 Example:
 
 i2s0: i2s@1c22400 {
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a4aa931ebfae..873054a6c3be 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -193,6 +193,8 @@ struct sun4i_i2s {
struct regmap_field *field_rxchansel;
 
const struct sun4i_i2s_quirks   *variant;
+
+   unsigned intslot_width;
 };
 
 struct sun4i_i2s_clk_div {
@@ -344,7 +346,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));
 
return 0;
 }
@@ -418,7 +420,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
   sr + i2s->variant->fmt_offset);
 
return sun4i_i2s_set_clk_rate(dai, params_rate(params),
- params_width(params));
+ i2s->slot_width ?
+ i2s->slot_width : params_width(params));
 }
 
 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
@@ -1029,7 +1032,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
struct sun4i_i2s *i2s;
struct resource *res;
void __iomem *regs;
-   int irq, ret;
+   int irq, ret, val;
 
i2s = devm_kzalloc(>dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s)
@@ -1096,6 +1099,12 @@ 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;
 
+   if (!of_property_read_u32(pdev->dev.of_node,
+ "allwinner,slot-width-override", )) {
+   if (val >= 8 && val <= 32)
+   i2s->slot_width = val;
+   }
+
pm_runtime_enable(>dev);
if (!pm_runtime_enabled(>dev)) {
ret = sun4i_i2s_runtime_resume(>dev);
-- 
2.16.2

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 4/6] ASoC: sun4i-i2s: Add multi-lane functionality

2018-03-12 Thread codekipper
From: Marcus Cooper 

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 
---
 .../devicetree/bindings/sound/sun4i-i2s.txt|  3 ++
 sound/soc/sunxi/sun4i-i2s.c| 48 +-
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt 
b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index 48addef65b8f..3f966ac61b9e 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -33,6 +33,9 @@ Optional properties:
configured to extend the slot width to the
value specified. Min 8, Max 32.
 
+- allwinner,playback-channels:  if this property is present then the number
+   of available channels is extended and the
+   outputs enabled.
 Example:
 
 i2s0: i2s@1c22400 {
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 2bd0befa02a8..436480df1844 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -27,7 +27,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)
@@ -394,14 +394,23 @@ 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) {
+   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;
}
 
+   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,
@@ -412,8 +421,19 @@ 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, 0x3210);
+   regmap_field_write(i2s->field_txchanmap, 0x10);
+   if (i2s->variant->has_chsel_tx_chen) {
+   if (channels > 2)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+4, 0x32);
+   if (channels > 4)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+8, 0x54);
+   if (channels > 6)
+   regmap_write(i2s->regmap,
+SUN8I_I2S_TX_CHAN_MAP_REG+12, 0x76);
+   }
 
/* Configure the channels */
regmap_field_write(i2s->field_txchansel,
@@ -692,12 +712,6 @@ static int sun4i_i2s_startup(struct snd_pcm_substream 
*substream,
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
 
-   /* Enable the first output line */
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
-  SUN4I_I2S_CTRL_SDO_EN_MASK,
-  SUN4I_I2S_CTRL_SDO_EN(0));
-
-
return clk_prepare_enable(i2s->mod_clk);
 }
 
@@ -1073,6 +1087,7 @@ 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, val;
@@ -1148,6 +1163,19 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
i2s->slot_width = val;
}
 
+   soc_dai = devm_kmemdup(>dev, _i2s_dai,
+  sizeof(*soc_dai), GFP_KERNEL);
+   if (!soc_dai) {
+   ret = -ENOMEM;
+   

[linux-sunxi][PATCH v2] ARM: sun6i: a31: Enable HDMI support on the Mele I7

2018-02-01 Thread codekipper
From: Marcus Cooper 

The Mele I7 has an HDMI connector wired to the HDMI pins
on the SoC. Enable the display pipeline and HDMI output.

Signed-off-by: Marcus Cooper 
---
v2 changes compared to v1 are:
- Reordered nodes.
---
 arch/arm/boot/dts/sun6i-a31-i7.dts | 29 +
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-i7.dts 
b/arch/arm/boot/dts/sun6i-a31-i7.dts
index 010a84c7c012..a3b70173c527 100644
--- a/arch/arm/boot/dts/sun6i-a31-i7.dts
+++ b/arch/arm/boot/dts/sun6i-a31-i7.dts
@@ -58,6 +58,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -93,6 +104,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -113,6 +128,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
@@ -161,6 +186,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2] ARM: dts: sun7i: Enable HDMI support on the Olimex EVB

2018-02-01 Thread codekipper
From: Marcus Cooper 

Enable the display pipeline and HDMI output on the Olimex
A20-SOM-EVB.

Signed-off-by: Marcus Cooper 
---
v2 changes compared to v1 are:
- corrected indentation.
---
 arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts 
b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
index 64c8ef9a2756..44b9eefdbbf9 100644
--- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -61,6 +61,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -79,6 +90,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -107,6 +122,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: sun6i: a31: Enable HDMI support on the Mele I7

2018-01-30 Thread codekipper
From: Marcus Cooper 

The Mele I7 has an HDMI connector wired to the HDMI pins
on the SoC. Enable the display pipeline and HDMI output.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sun6i-a31-i7.dts | 29 +
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-i7.dts 
b/arch/arm/boot/dts/sun6i-a31-i7.dts
index 010a84c7c012..4f69be4988a5 100644
--- a/arch/arm/boot/dts/sun6i-a31-i7.dts
+++ b/arch/arm/boot/dts/sun6i-a31-i7.dts
@@ -58,6 +58,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -93,6 +104,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -101,6 +116,16 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_mii_a>;
@@ -161,6 +186,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sun4i: Enable HDMI support on the MK802

2018-01-30 Thread codekipper
From: Marcus Cooper 

Enable the display pipeline and HDMI output.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sun4i-a10-mk802.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts 
b/arch/arm/boot/dts/sun4i-a10-mk802.dts
index 7198b34e2e50..982a704d5663 100644
--- a/arch/arm/boot/dts/sun4i-a10-mk802.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts
@@ -56,12 +56,27 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
 };
 
  {
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -70,6 +85,16 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
vmmc-supply = <_vcc3v3>;
bus-width = <4>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sun7i: Enable HDMI support on the Olimex EVB

2018-01-29 Thread codekipper
From: Marcus Cooper 

Enable the display pipeline and HDMI output on the Olimex
A20-SOM-EVB.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts 
b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
index 64c8ef9a2756..07906d4f8758 100644
--- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -61,6 +61,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -79,6 +90,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -107,6 +122,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sun7i: Enable HDMI support on the MK808C

2018-01-29 Thread codekipper
From: Marcus Cooper 

Enable the display pipeline and HDMI output

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sun7i-a20-mk808c.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-mk808c.dts 
b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
index f7413094183c..5b5773b34640 100644
--- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts
+++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
@@ -66,12 +66,27 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
 };
 
  {
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -80,6 +95,16 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sunxi: h3/h5: Add DAI node for HDMI

2018-01-29 Thread codekipper
From: Marcus Cooper 

Add the new DAI block for I2S2 which is used for HDMI audio.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 7a83b15225c7..238e7007d5b9 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -568,6 +568,19 @@
status = "disabled";
};
 
+   i2s2: i2s@1c22800 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22800 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S2>, < CLK_I2S2>;
+   clock-names = "apb", "mod";
+   dmas = < 27>;
+   resets = < RST_BUS_I2S2>;
+   dma-names = "tx";
+   status = "disabled";
+   };
+
codec: codec@1c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-h3-codec";
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 3/5] arm64: allwinner: a64: Add SPDIF to the Pine64

2018-01-29 Thread codekipper
From: Marcus Cooper 

The S/PDIF transmitter can be reached on the Euler connector.
But as this is a GPIO then leave it disabled so that an overlay
can override the status property.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 604cdaedac38..d1161069af9e 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -230,6 +230,11 @@
regulator-name = "vcc-rtc";
 };
 
+/* On Euler connector */
+ {
+   status = "disabled";
+};
+
 /* On Exp and Euler connectors */
  {
pinctrl-names = "default";
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 0/5] Add tested digital audio blocks to A64

2018-01-29 Thread codekipper
From: Marcus Cooper 

Hi All,

this patch series adds the digital audio blocks to the A64 SoC. No block
changes are necessary.

BR,
CK

---
v2 changes compared to v1 are:
- Added SoC specific compatiables
- moved spdif default pins to dtsi
- Added i2s2 block for HDMI as it has now been tested.
---
Marcus Cooper (5):
  arm64: allwinner: a64: Add the SPDIF block and pin
  arm64: allwinner: a64: Add SPDIF to the A64
  arm64: allwinner: a64: Add SPDIF to the Pine64
  arm64: allwinner: a64: Add DAI nodes
  arm64: allwinner: a64: Add DAI node for HDMI

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts |  5 ++
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi  | 81 ++
 2 files changed, 86 insertions(+)

-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 5/5] arm64: allwinner: a64: Add DAI node for HDMI

2018-01-29 Thread codekipper
From: Marcus Cooper 

Add the new DAI block for I2S2 which is used for HDMI audio.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1b6dc31e7d91..c913dada7653 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -449,6 +449,20 @@
status = "disabled";
};
 
+   i2s2: i2s@1c22800 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun50i-a64-i2s",
+"allwinner,sun8i-h3-i2s";
+   reg = <0x01c22800 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S2>, < CLK_I2S2>;
+   clock-names = "apb", "mod";
+   resets = < RST_BUS_I2S2>;
+   dma-names = "tx";
+   dmas = < 27>;
+   status = "disabled";
+   };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 4/5] arm64: allwinner: a64: Add DAI nodes

2018-01-29 Thread codekipper
From: Marcus Cooper 

Add the DAI blocks to the device tree. I2S0 and I2S1 are for
connecting to an external codec.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 28 +++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index b9e69657a2e8..1b6dc31e7d91 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -421,6 +421,34 @@
status = "disabled";
};
 
+   i2s0: i2s@1c22000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun50i-a64-i2s",
+"allwinner,sun8i-h3-i2s";
+   reg = <0x01c22000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S0>, < CLK_I2S0>;
+   clock-names = "apb", "mod";
+   resets = < RST_BUS_I2S0>;
+   dma-names = "rx", "tx";
+   dmas = < 3>, < 3>;
+   status = "disabled";
+   };
+
+   i2s1: i2s@1c22400 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun50i-a64-i2s",
+"allwinner,sun8i-h3-i2s";
+   reg = <0x01c22400 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S1>, < CLK_I2S1>;
+   clock-names = "apb", "mod";
+   resets = < RST_BUS_I2S1>;
+   dma-names = "rx", "tx";
+   dmas = < 4>, < 4>;
+   status = "disabled";
+   };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 2/5] arm64: allwinner: a64: Add SPDIF to the A64

2018-01-29 Thread codekipper
From: Marcus Cooper 

Add the device tree sound bindings for the S/PDIF block.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 43c54a2133f0..b9e69657a2e8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -112,6 +112,24 @@
method = "smc";
};
 
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = https://groups.google.com/d/optout.


[linux-sunxi][PATCH v2 1/5] arm64: allwinner: a64: Add the SPDIF block and pin

2018-01-29 Thread codekipper
From: Marcus Cooper 

Add the SPDIF transceiver controller block and pin to the A64 dtsi.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 21 +
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index d783d164b9c3..43c54a2133f0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -336,6 +336,11 @@
drive-strength = <40>;
};
 
+   spdif_tx_pin: spdif {
+   pins = "PH8";
+   function = "spdif";
+   };
+
spi0_pins: spi0 {
pins = "PC0", "PC1", "PC2", "PC3";
function = "spi0";
@@ -382,6 +387,22 @@
};
};
 
+   spdif: spdif@1c21000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun50i-a64-spdif",
+"allwinner,sun8i-h3-spdif";
+   reg = <0x01c21000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_SPDIF>, < CLK_SPDIF>;
+   resets = < RST_BUS_SPDIF>;
+   clock-names = "apb", "spdif";
+   dmas = < 2>;
+   dma-names = "tx";
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pin>;
+   status = "disabled";
+   };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.16.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 2/3] ASoC: sun4i-i2s: Do not divide clocks when slave

2018-01-24 Thread codekipper
From: Marcus Cooper 

There is no need to set the clock and calculate the division of
the audio pll for the bclk and sync signals when they are not
required.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 116 
 1 file changed, 64 insertions(+), 52 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index d7a9141514cf..626679057d0f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -195,6 +195,8 @@ struct sun4i_i2s {
 
const struct sun4i_i2s_quirks   *variant;
 
+   bool bit_clk_master;
+
unsigned inttdm_slots;
unsigned intslot_width;
 };
@@ -282,67 +284,73 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
int bclk_div, mclk_div;
int ret;
 
-   switch (rate) {
-   case 176400:
-   case 88200:
-   case 44100:
-   case 22050:
-   case 11025:
-   clk_rate = 22579200;
-   break;
+   if (i2s->bit_clk_master) {
+   switch (rate) {
+   case 176400:
+   case 88200:
+   case 44100:
+   case 22050:
+   case 11025:
+   clk_rate = 22579200;
+   break;
 
-   case 192000:
-   case 128000:
-   case 96000:
-   case 64000:
-   case 48000:
-   case 32000:
-   case 24000:
-   case 16000:
-   case 12000:
-   case 8000:
-   clk_rate = 24576000;
-   break;
+   case 192000:
+   case 128000:
+   case 96000:
+   case 64000:
+   case 48000:
+   case 32000:
+   case 24000:
+   case 16000:
+   case 12000:
+   case 8000:
+   clk_rate = 24576000;
+   break;
 
-   default:
-   dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
-   return -EINVAL;
-   }
+   default:
+   dev_err(dai->dev, "Unsupported sample rate: %u\n", 
rate);
+   return -EINVAL;
+   }
 
-   ret = clk_set_rate(i2s->mod_clk, clk_rate);
-   if (ret)
-   return ret;
+   ret = clk_set_rate(i2s->mod_clk, clk_rate);
+   if (ret) {
+   dev_err(dai->dev, "Unable to set clock\n");
+   return ret;
+   }
 
-   oversample_rate = i2s->mclk_freq / rate;
-   if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
-   dev_err(dai->dev, "Unsupported oversample rate: %d\n",
-   oversample_rate);
-   return -EINVAL;
-   }
+   oversample_rate = i2s->mclk_freq / rate;
+   if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
+   dev_err(dai->dev, "Unsupported oversample rate: %d\n",
+   oversample_rate);
+   return -EINVAL;
+   }
 
-   bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
- word_size);
-   if (bclk_div < 0) {
-   dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
-   return -EINVAL;
-   }
+   bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
+ word_size);
+   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 (mclk_div < 0) {
-   dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
-   return -EINVAL;
-   }
+   mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
+ clk_rate, rate);
+   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;
+   /* 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));
+   regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
+

[linux-sunxi] [PATCH 3/3] ASoC: sun4i-i2s: Add regmap field to sign extend sample

2018-01-24 Thread codekipper
From: Marcus Cooper 

On the newer SoCs this is set by default to transfer a 0 after
each sample in each slot. Add the regmap field to configure this
and set it so that it pads the sample with 0s.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 626679057d0f..9fda1240b717 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -139,6 +139,7 @@
  * @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.
@@ -164,6 +165,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_fmt_bclk;
struct reg_fieldfield_fmt_lrclk;
struct reg_fieldfield_fmt_mode;
+   struct reg_fieldfield_fmt_sext;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -188,6 +190,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;
@@ -358,6 +361,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
   SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
 
+   /* Set sign extension to pad out LSB with 0 */
+   regmap_field_write(i2s->field_fmt_sext, 0);
+
return 0;
 }
 
@@ -929,6 +935,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),
@@ -946,6 +953,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),
@@ -986,6 +994,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),
@@ -1031,6 +1040,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.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 1/3] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-01-24 Thread codekipper
From: Marcus Cooper 

Some codecs require a different amount of a 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 
---
 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 dca1143c1150..d7a9141514cf 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -96,6 +96,7 @@
 #define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
 #define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)
 
+#define SUN8I_I2S_FMT0_LRCK_MAX_PERIOD (GENMASK(17, 8) >> 8)
 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
 
@@ -193,6 +194,9 @@ struct sun4i_i2s {
struct regmap_field *field_rxchansel;
 
const struct sun4i_i2s_quirks   *variant;
+
+   unsigned inttdm_slots;
+   unsigned intslot_width;
 };
 
 struct sun4i_i2s_clk_div {
@@ -344,7 +348,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));
 
return 0;
 }
@@ -418,7 +422,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
   sr + i2s->variant->fmt_offset);
 
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)
@@ -691,6 +696,19 @@ 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,
@@ -698,6 +716,7 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
.shutdown   = sun4i_i2s_shutdown,
.startup= sun4i_i2s_startup,
.trigger= sun4i_i2s_trigger,
+   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
 };
 
 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH 2/5] arm64: allwinner: a64: Add SPDIF TX pin to the A64

2018-01-24 Thread codekipper
From: Marcus Cooper 

Add the SPDIF TX pin to the A64 dtsi.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index c82979038b0b..db1694ec3ee4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -336,6 +336,11 @@
drive-strength = <40>;
};
 
+   spdif_tx_pins_a: spdif@0 {
+   pins = "PH8";
+   function = "spdif";
+   };
+
spi0_pins: spi0 {
pins = "PC0", "PC1", "PC2", "PC3";
function = "spi0";
-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH 3/5] arm64: allwinner: a64: Add SPDIF to the A64

2018-01-24 Thread codekipper
From: Marcus Cooper 

Add the device tree sound bindings for the S/PDIF block.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index db1694ec3ee4..f060a58f374c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -112,6 +112,25 @@
method = "smc";
};
 
+
+   sound_spdif {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "On-board SPDIF";
+
+   simple-audio-card,cpu {
+   sound-dai = <>;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <_out>;
+   };
+   };
+
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupts = https://groups.google.com/d/optout.


[linux-sunxi][PATCH 0/5] Add tested digital audio blocks to A64

2018-01-24 Thread codekipper
From: Marcus Cooper 

Hi All,

this patch series adds the digital audio blocks to the A64 SoC. No block
changes are necessary.

BR,
CK

Marcus Cooper (5):
  arm64: allwinner: a64: Add the SPDIF block
  arm64: allwinner: a64: Add SPDIF TX pin to the A64
  arm64: allwinner: a64: Add SPDIF to the A64
  arm64: allwinner: a64: Add SPDIF to the Pine64
  arm64: allwinner: a64: Add DAI nodes

 .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts |  7 +++
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi  | 63 ++
 2 files changed, 70 insertions(+)

-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH 4/5] arm64: allwinner: a64: Add SPDIF to the Pine64

2018-01-24 Thread codekipper
From: Marcus Cooper 

---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 604cdaedac38..70e8ff9a1f38 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -230,6 +230,13 @@
regulator-name = "vcc-rtc";
 };
 
+/* On Euler connector */
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_tx_pins_a>;
+   status = "disabled";
+};
+
 /* On Exp and Euler connectors */
  {
pinctrl-names = "default";
-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH 5/5] arm64: allwinner: a64: Add DAI nodes

2018-01-24 Thread codekipper
From: Marcus Cooper 

Add the DAI blocks to the device tree. I2S0 and I2S1 are for
connecting to an external codec.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index f060a58f374c..f3354f8c2026 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -419,6 +419,32 @@
status = "disabled";
};
 
+   i2s0: i2s@1c22000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S0>, < CLK_I2S0>;
+   clock-names = "apb", "mod";
+   resets = < RST_BUS_I2S0>;
+   dma-names = "rx", "tx";
+   dmas = < 3>, < 3>;
+   status = "disabled";
+   };
+
+   i2s1: i2s@1c22400 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22400 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S1>, < CLK_I2S1>;
+   clock-names = "apb", "mod";
+   resets = < RST_BUS_I2S1>;
+   dma-names = "rx", "tx";
+   dmas = < 4>, < 4>;
+   status = "disabled";
+   };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH 1/5] arm64: allwinner: a64: Add the SPDIF block

2018-01-24 Thread codekipper
From: Marcus Cooper 

Add the SPDIF transceiver controller block to the A64 dtsi.

Signed-off-by: Marcus Cooper 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index d783d164b9c3..c82979038b0b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -382,6 +382,19 @@
};
};
 
+   spdif: spdif@1c21000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-spdif";
+   reg = <0x01c21000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_SPDIF>, < CLK_SPDIF>;
+   resets = < RST_BUS_SPDIF>;
+   clock-names = "apb", "spdif";
+   dmas = < 2>;
+   dma-names = "tx";
+   status = "disabled";
+   };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.16.0

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH] sunxi: Add support for the Beelink-x2 STB

2018-01-21 Thread codekipper
From: Marcus Cooper 

The Beelink X2 is an STB based on the Allwinner H3 SoC with a uSD slot,
2 USB ports( 1 * USB-2 Host, 1 USB OTG), a 10/100M ethernet port using
the SoC's integrated PHY, Wifi via an sdio wifi chip, HDMI, a dual
colour LED, an IR receiver and an optical S/PDIF connector.

Signed-off-by: Marcus Cooper 
---
 arch/arm/dts/Makefile|   1 +
 arch/arm/dts/sun8i-h3-beelink-x2.dts | 155 +++
 board/sunxi/MAINTAINERS  |   5 ++
 configs/beelink_x2_defconfig |  18 
 4 files changed, 179 insertions(+)
 create mode 100644 arch/arm/dts/sun8i-h3-beelink-x2.dts
 create mode 100644 configs/beelink_x2_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9540ba4313..f899cef7ac 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -335,6 +335,7 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \
 dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h2-plus-orangepi-zero.dtb \
sun8i-h3-bananapi-m2-plus.dtb \
+   sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
sun8i-h3-orangepi-2.dtb \
sun8i-h3-orangepi-lite.dtb \
diff --git a/arch/arm/dts/sun8i-h3-beelink-x2.dts 
b/arch/arm/dts/sun8i-h3-beelink-x2.dts
new file mode 100644
index 00..43f67eb8db
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-beelink-x2.dts
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 Marcus Cooper 
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "Beelink X2";
+   compatible = "roofull,beelink-x2", "allwinner,sun8i-h3";
+
+   aliases {
+   serial0 = 
+   /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+   ethernet1 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   leds {
+   compatible = "gpio-leds";
+
+   blue {
+   label = "beelink-x2:blue:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+   default-state = "on";
+   };
+
+   red {
+   label = "beelink-x2:red:standby";
+   gpios = < 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */
+   };
+   };
+
+   wifi_pwrseq: wifi_pwrseq {
+   compatible = "mmc-pwrseq-simple";
+   reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy = <>;
+   phy-mode = "mii";
+   allwinner,use-internal-phy;
+   allwinner,leds-active-low;
+   status = "okay";
+   phy1: ethernet-phy@1 {
+   reg = <1>;
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>, <_cd_pin>;
+   vmmc-supply = 

[linux-sunxi][PATCH v2] ARM: dts: sunxi: h3/h5 :Add DAI nodes

2017-09-04 Thread codekipper
From: Marcus Cooper 

Add the new DAI blocks to the device tree. I2S0 and I2S1 are for
connecting to an external codec.

Signed-off-by: Marcus Cooper 
---
v2 changes compared to v1 are:
- removed i2s2 which is used for HDMI audio
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 11240a8313c2..ef87d29036d9 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -450,6 +450,32 @@
status = "disabled";
};
 
+   i2s0: i2s@01c22000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S0>, < CLK_I2S0>;
+   clock-names = "apb", "mod";
+   dmas = < 3>, < 3>;
+   resets = < RST_BUS_I2S0>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
+   i2s1: i2s@01c22400 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22400 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S1>, < CLK_I2S1>;
+   clock-names = "apb", "mod";
+   dmas = < 4>, < 4>;
+   resets = < RST_BUS_I2S1>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
codec: codec@01c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-h3-codec";
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sun6i: a31: Add DAI nodes

2017-09-03 Thread codekipper
From: Marcus Cooper 

Add the new DAI blocks to the device tree.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index b147cb0dc14b..f3d74dc5b292 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -662,6 +662,32 @@
status = "disabled";
};
 
+   i2s0: i2s@01c22000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun6i-a31-i2s";
+   reg = <0x01c22000 0x400>;
+   interrupts = ;
+   clocks = < CLK_APB1_DAUDIO0>, < CLK_DAUDIO0>;
+   resets = < RST_APB1_DAUDIO0>;
+   clock-names = "apb", "mod";
+   dmas = < 3>, < 3>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
+   i2s1: i2s@01c22400 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun6i-a31-i2s";
+   reg = <0x01c22400 0x400>;
+   interrupts = ;
+   clocks = < CLK_APB1_DAUDIO1>, < CLK_DAUDIO1>;
+   resets = < RST_APB1_DAUDIO1>;
+   clock-names = "apb", "mod";
+   dmas = < 4>, < 4>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
lradc: lradc@01c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi][PATCH] ARM: dts: sunxi: h3/h5 :Add DAI nodes

2017-09-03 Thread codekipper
From: Marcus Cooper 

Add the new DAI blocks to the device tree. I2S0 and I2S1 are for
connecting to an external codec whereas I2S2 is used for HDMI
audio.

Signed-off-by: Marcus Cooper 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 39 ++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 11240a8313c2..cf6fcc857324 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -450,6 +450,45 @@
status = "disabled";
};
 
+   i2s0: i2s@01c22000 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22000 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S0>, < CLK_I2S0>;
+   clock-names = "apb", "mod";
+   dmas = < 3>, < 3>;
+   resets = < RST_BUS_I2S0>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
+   i2s1: i2s@01c22400 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22400 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S1>, < CLK_I2S1>;
+   clock-names = "apb", "mod";
+   dmas = < 4>, < 4>;
+   resets = < RST_BUS_I2S1>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
+   i2s2: i2s@01c22800 {
+   #sound-dai-cells = <0>;
+   compatible = "allwinner,sun8i-h3-i2s";
+   reg = <0x01c22800 0x400>;
+   interrupts = ;
+   clocks = < CLK_BUS_I2S2>, < CLK_I2S2>;
+   clock-names = "apb", "mod";
+   dmas = < 5>, < 5>;
+   resets = < RST_BUS_I2S2>;
+   dma-names = "rx", "tx";
+   status = "disabled";
+   };
+
codec: codec@01c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-h3-codec";
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 5/8] ASoC: sun4i-i2s: Add regmap field to set DAI format

2017-08-19 Thread codekipper
From: Marcus Cooper 

On the newer SoCs the bits to configure the operational mode are
located in a different register. Add a regmap field so that this
location can be configured.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 761b7c0f6a32..d9910f6617ad 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -106,6 +106,7 @@
  * @field_fmt_sr: regmap field to set sample resolution.
  * @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_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.
@@ -125,6 +126,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_fmt_sr;
struct reg_fieldfield_fmt_bclk;
struct reg_fieldfield_fmt_lrclk;
+   struct reg_fieldfield_fmt_mode;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -148,6 +150,7 @@ struct sun4i_i2s {
struct regmap_field *field_fmt_sr;
struct regmap_field *field_fmt_bclk;
struct regmap_field *field_fmt_lrclk;
+   struct regmap_field *field_fmt_mode;
struct regmap_field *field_txchanmap;
struct regmap_field *field_rxchanmap;
struct regmap_field *field_txchansel;
@@ -365,9 +368,7 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
return -EINVAL;
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
-  SUN4I_I2S_FMT0_FMT_MASK,
-  val);
+   regmap_field_write(i2s->field_fmt_mode, val);
 
/* DAI clock polarity */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -722,6 +723,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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_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),
@@ -737,6 +739,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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_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),
@@ -776,6 +779,12 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
if (IS_ERR(i2s->field_fmt_lrclk))
return PTR_ERR(i2s->field_fmt_lrclk);
 
+   i2s->field_fmt_mode =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_mode);
+   if (IS_ERR(i2s->field_fmt_mode))
+   return PTR_ERR(i2s->field_fmt_mode);
+
i2s->field_txchanmap =
devm_regmap_field_alloc(dev, i2s->regmap,
i2s->variant->field_txchanmap);
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 4/8] ASoC: sun4i-i2s: Add mclk enable regmap field

2017-08-19 Thread codekipper
From: Marcus Cooper 

The location of the mclk output enable bit is different on newer
SoCs. Use a regmap field to enable it.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 8c7ad5bfe821..761b7c0f6a32 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -101,6 +101,7 @@
  * @mclk_offset: Value by which mclkdiv needs to be adjusted.
  * @bclk_offset: Value by which bclkdiv needs to be adjusted.
  * @fmt_offset: Value by which wss and sr 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.
  * @field_fmt_bclk: regmap field to set clk polarity.
@@ -119,6 +120,7 @@ struct sun4i_i2s_quirks {
unsigned intfmt_offset;
 
/* Register fields for i2s */
+   struct reg_fieldfield_clkdiv_mclk_en;
struct reg_fieldfield_fmt_wss;
struct reg_fieldfield_fmt_sr;
struct reg_fieldfield_fmt_bclk;
@@ -141,6 +143,7 @@ struct sun4i_i2s {
struct snd_dmaengine_dai_dma_data   playback_dma_data;
 
/* Register fields for i2s */
+   struct regmap_field *field_clkdiv_mclk_en;
struct regmap_field *field_fmt_wss;
struct regmap_field *field_fmt_sr;
struct regmap_field *field_fmt_bclk;
@@ -283,8 +286,9 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
 
regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
-SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
-SUN4I_I2S_CLK_DIV_MCLK_EN);
+SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
+
+   regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 
return 0;
 }
@@ -713,6 +717,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.has_reset  = false,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
.field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
@@ -727,6 +732,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.has_reset  = true,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
.field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
@@ -740,6 +746,12 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
struct sun4i_i2s *i2s)
 {
+   i2s->field_clkdiv_mclk_en =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_clkdiv_mclk_en);
+   if (IS_ERR(i2s->field_clkdiv_mclk_en))
+   return PTR_ERR(i2s->field_clkdiv_mclk_en);
+
i2s->field_fmt_wss =
devm_regmap_field_alloc(dev, i2s->regmap,
i2s->variant->field_fmt_wss);
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 6/8] ASoC: sun4i-i2s: Check for slave select bit

2017-08-19 Thread codekipper
From: Marcus Cooper 

The newer SoCs do not have this setting. Instead they set the pin
direction. Add a check to see if the bit is valid and if so set
it accordingly.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 sound/soc/sunxi/sun4i-i2s.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index d9910f6617ad..573acca24a2c 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -96,6 +96,7 @@
  * struct sun4i_i2s_quirks - Differences between SoC variants.
  *
  * @has_reset: SoC needs reset deasserted.
+ * @has_slave_select_bit: SoC has a bit to enable slave 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.
@@ -114,6 +115,7 @@
  */
 struct sun4i_i2s_quirks {
boolhas_reset;
+   boolhas_slave_select_bit;
unsigned intreg_offset_txdata;  /* TX FIFO */
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
@@ -394,24 +396,25 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
regmap_field_write(i2s->field_fmt_bclk, bclk_polarity);
regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity);
 
-   /* DAI clock master masks */
-   switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-   case SND_SOC_DAIFMT_CBS_CFS:
-   /* BCLK and LRCLK master */
-   val = SUN4I_I2S_CTRL_MODE_MASTER;
-   break;
-   case SND_SOC_DAIFMT_CBM_CFM:
-   /* BCLK and LRCLK slave */
-   val = SUN4I_I2S_CTRL_MODE_SLAVE;
-   break;
-   default:
-   return -EINVAL;
+   if (i2s->variant->has_slave_select_bit) {
+   /* DAI clock master masks */
+   switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+   case SND_SOC_DAIFMT_CBS_CFS:
+   /* BCLK and LRCLK master */
+   val = SUN4I_I2S_CTRL_MODE_MASTER;
+   break;
+   case SND_SOC_DAIFMT_CBM_CFM:
+   /* BCLK and LRCLK slave */
+   val = SUN4I_I2S_CTRL_MODE_SLAVE;
+   break;
+   default:
+   return -EINVAL;
+   }
+   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+  SUN4I_I2S_CTRL_MODE_MASK,
+  val);
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
-  SUN4I_I2S_CTRL_MODE_MASK,
-  val);
-
/* Set significant bits in our FIFOs */
regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
   SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
@@ -723,6 +726,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
.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),
@@ -739,6 +743,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
.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),
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 3/8] ASoC: sun4i-i2s: bclk and lrclk polarity tidyup

2017-08-19 Thread codekipper
From: Marcus Cooper 

On newer SoCs the bit fields for the blck and lrclk polarity are in
a different locations. Use regmap fields to set the polarity bits
as intended.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 45 -
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 563de785d639..8c7ad5bfe821 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -50,6 +50,8 @@
 #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)
 #define SUN4I_I2S_FMT0_FMT_LEFT_J  (1 << 0)
 #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
+#define SUN4I_I2S_FMT0_POLARITY_INVERTED   (1)
+#define SUN4I_I2S_FMT0_POLARITY_NORMAL (0)
 
 #define SUN4I_I2S_FMT1_REG 0x08
 #define SUN4I_I2S_FIFO_TX_REG  0x0c
@@ -101,6 +103,8 @@
  * @fmt_offset: Value by which wss and sr needs to be adjusted.
  * @field_fmt_wss: regmap field to set word select size.
  * @field_fmt_sr: regmap field to set sample resolution.
+ * @field_fmt_bclk: regmap field to set clk polarity.
+ * @field_fmt_lrclk: regmap field to set frame polarity.
  * @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.
@@ -117,6 +121,8 @@ struct sun4i_i2s_quirks {
/* Register fields for i2s */
struct reg_fieldfield_fmt_wss;
struct reg_fieldfield_fmt_sr;
+   struct reg_fieldfield_fmt_bclk;
+   struct reg_fieldfield_fmt_lrclk;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -137,6 +143,8 @@ struct sun4i_i2s {
/* Register fields for i2s */
struct regmap_field *field_fmt_wss;
struct regmap_field *field_fmt_sr;
+   struct regmap_field *field_fmt_bclk;
+   struct regmap_field *field_fmt_lrclk;
struct regmap_field *field_txchanmap;
struct regmap_field *field_rxchanmap;
struct regmap_field *field_txchansel;
@@ -335,6 +343,8 @@ 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;
 
/* DAI Mode */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -359,32 +369,25 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_IB_IF:
/* Invert both clocks */
-   val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
-   SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
+   bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED;
+   lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED;
break;
case SND_SOC_DAIFMT_IB_NF:
/* Invert bit clock */
-   val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
-   SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
+   bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED;
break;
case SND_SOC_DAIFMT_NB_IF:
/* Invert frame clock */
-   val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED |
-   SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL;
+   lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED;
break;
case SND_SOC_DAIFMT_NB_NF:
-   /* Nothing to do for both normal cases */
-   val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL |
-   SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
break;
default:
return -EINVAL;
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
-  SUN4I_I2S_FMT0_BCLK_POLARITY_MASK |
-  SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK,
-  val);
+   regmap_field_write(i2s->field_fmt_bclk, bclk_polarity);
+   regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity);
 
/* DAI clock master masks */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -712,6 +715,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.sun4i_i2s_regmap   = _i2s_regmap_config,
.field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
+   .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
+   .field_fmt_lrclk= 

[linux-sunxi] [PATCH v5 7/8] ASoC: sun4i-i2s: Update global enable with bitmask

2017-08-19 Thread codekipper
From: Marcus Cooper 

The default value of the config register is different on newer
SoCs and therefore enabling/disabling with a register write
will clear bits used to set the direction of the clock and frame
pins.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 sound/soc/sunxi/sun4i-i2s.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 573acca24a2c..19d50ca10d1f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -529,8 +529,8 @@ static int sun4i_i2s_startup(struct snd_pcm_substream 
*substream,
struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 
/* Enable the whole hardware block */
-   regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG,
-SUN4I_I2S_CTRL_GL_EN);
+   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+  SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
 
/* Enable the first output line */
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
@@ -553,7 +553,8 @@ static void sun4i_i2s_shutdown(struct snd_pcm_substream 
*substream,
   SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
 
/* Disable the whole hardware block */
-   regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0);
+   regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
+  SUN4I_I2S_CTRL_GL_EN, 0);
 }
 
 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 2/8] ASoC: sun4i-i2s: Add regfields for word size select and sample resolution

2017-08-19 Thread codekipper
From: Marcus Cooper 

On newer SoCs the location of the slot width select and sample
resolution are different and also there is a bigger range of
support.

For the current supported rates then an offset is required.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 sound/soc/sunxi/sun4i-i2s.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 87feb5a14cff..563de785d639 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -98,6 +98,9 @@
  * @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.
+ * @fmt_offset: Value by which wss and sr needs to be adjusted.
+ * @field_fmt_wss: regmap field to set word select size.
+ * @field_fmt_sr: regmap field to set sample resolution.
  * @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.
@@ -109,8 +112,11 @@ struct sun4i_i2s_quirks {
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
unsigned intbclk_offset;
+   unsigned intfmt_offset;
 
/* Register fields for i2s */
+   struct reg_fieldfield_fmt_wss;
+   struct reg_fieldfield_fmt_sr;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -129,6 +135,8 @@ struct sun4i_i2s {
struct snd_dmaengine_dai_dma_data   playback_dma_data;
 
/* Register fields for i2s */
+   struct regmap_field *field_fmt_wss;
+   struct regmap_field *field_fmt_sr;
struct regmap_field *field_txchanmap;
struct regmap_field *field_rxchanmap;
struct regmap_field *field_txchansel;
@@ -314,9 +322,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
return -EINVAL;
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
-  SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
-  SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
+   regmap_field_write(i2s->field_fmt_wss,
+  wss + i2s->variant->fmt_offset);
+   regmap_field_write(i2s->field_fmt_sr,
+  sr + i2s->variant->fmt_offset);
 
return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
  params_width(params));
@@ -701,6 +710,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.has_reset  = false,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
+   .field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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),
@@ -711,6 +722,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.has_reset  = true,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
+   .field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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),
@@ -720,6 +733,18 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks 
= {
 static int sun4i_i2s_init_regmap_fields(struct device *dev,
struct sun4i_i2s *i2s)
 {
+   i2s->field_fmt_wss =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_wss);
+   if (IS_ERR(i2s->field_fmt_wss))
+   return PTR_ERR(i2s->field_fmt_wss);
+
+   i2s->field_fmt_sr =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_sr);
+   if (IS_ERR(i2s->field_fmt_sr))
+   return PTR_ERR(i2s->field_fmt_sr);
+
i2s->field_txchanmap =
devm_regmap_field_alloc(dev, i2s->regmap,

[linux-sunxi] [PATCH v5 8/8] ASoC: sun4i-i2s: Add support for H3

2017-08-19 Thread codekipper
From: Marcus Cooper 

The sun8i-h3 introduces a lot of changes to the i2s block such
as different register locations, extended clock division and
more operational modes. As we have to consider the earlier
implementation then these changes need to be isolated.

None of the new functionality has been implemented yet, the
driver has just been expanded to allow it work on the H3 SoC.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 .../devicetree/bindings/sound/sun4i-i2s.txt|   2 +
 sound/soc/sunxi/sun4i-i2s.c| 176 -
 2 files changed, 176 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt 
b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index ee21da865771..fc5da6080759 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -8,6 +8,7 @@ Required properties:
 - compatible: should be one of the following:
- "allwinner,sun4i-a10-i2s"
- "allwinner,sun6i-a31-i2s"
+   - "allwinner,sun8i-h3-i2s"
 - reg: physical base address of the controller and length of memory mapped
   region.
 - interrupts: should contain the I2S interrupt.
@@ -22,6 +23,7 @@ Required properties:
 
 Required properties for the following compatibles:
- "allwinner,sun6i-a31-i2s"
+   - "allwinner,sun8i-h3-i2s"
 - resets: phandle to the reset line for this codec
 
 Example:
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 19d50ca10d1f..04f92583a969 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -92,11 +92,41 @@
 #define SUN4I_I2S_RX_CHAN_SEL_REG  0x38
 #define SUN4I_I2S_RX_CHAN_MAP_REG  0x3c
 
+/* Defines required for sun8i-h3 support */
+#define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
+#define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)
+
+#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
+#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
+
+#define SUN8I_I2S_INT_STA_REG  0x0c
+#define SUN8I_I2S_FIFO_TX_REG  0x20
+
+#define SUN8I_I2S_CHAN_CFG_REG 0x30
+#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASKGENMASK(6, 4)
+#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)   (chan - 1)
+#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASKGENMASK(2, 0)
+#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)   (chan - 1)
+
+#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, 11)
+#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_RX_CHAN_SEL_REG  0x54
+#define SUN8I_I2S_RX_CHAN_MAP_REG  0x58
+
 /**
  * struct sun4i_i2s_quirks - Differences between SoC variants.
  *
  * @has_reset: SoC needs reset deasserted.
  * @has_slave_select_bit: SoC has a bit to enable slave mode.
+ * @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
+ * @has_chcfg: tx and rx slot number need to be set.
+ * @has_chsel_tx_chen: SoC requires that the tx channels are enabled.
+ * @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.
@@ -116,6 +146,10 @@
 struct sun4i_i2s_quirks {
boolhas_reset;
boolhas_slave_select_bit;
+   boolhas_fmt_set_lrck_period;
+   boolhas_chcfg;
+   boolhas_chsel_tx_chen;
+   boolhas_chsel_offset;
unsigned intreg_offset_txdata;  /* TX FIFO */
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
@@ -173,6 +207,7 @@ 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 sun4i_i2s_mclk_div[] = {
@@ -184,6 +219,7 @@ 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,
@@ -295,6 +331,12 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
 
regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 
+   /* Set sync period */
+   if (i2s->variant->has_fmt_set_lrck_period)

[linux-sunxi] [PATCH v5 0/8] ASoC: Add I2S support for Allwinner H3 SoCs

2017-08-19 Thread codekipper
From: Marcus Cooper <codekip...@gmail.com>

Hi All,
please find attached a series of patches to bring i2s support to the
Allwinner H3 SoC. This has been tested with the following setups:

A20 Olimex EVB connected to a pcm5102
Orange Pi 2 connected to a uda1380
Orange Pi 2 hdmi audio playback
Pine 64 connected to the audio DAC board

To get i2s working some additional patches are required which will be
delivered later. For now they have been pushed here

https://github.com/codekipper/linux-sunxi/commits/sunxi-audio-h3

I don't own a A33 device which uses the i2s block for the audio codec
so if someone could test against that it would be much appreciated.

I'm also wondering if there is a preferred way of setting the lrclk
size in the dts?..currently it is set to the sample width but for example
the pcm5102a wants it to be 32 bits whatever the sample rate.

Thanks in advance,
CK

---

v5 changes compared to v4 are:
- fixed bad logic in fmt0 set LRCK period define.
- fixed PTR_ERR checks in init of regmap fields
- added reviewed-by to commit messages
- removed delivered patches

v4 changes compared to v3 are:
- moved clkdiv variant adjustment out of function
- used PTR_ERR_OR_ZERO for checks
- tidy up of extra lines and lines over 80 chars.
- reduced names of polarity, wss and sr reg fields.
- added reviewed-by to commit messages
- added comments for functionality that hasn't been implemented yet.
- removed delivered patches

v3 changes compared to v2 are:
- initial changes to prepare driver for newer SoCs has been broken down
  into smaller patches
- reduce use of regmap fields to where just needed.
- clkdiv expansion will be delivered later.
- defines for H3 variant segregated.
- fixed regmap config issue with SUN8I_I2S_FIFO_TX_REG.

v2 changes compared to v1 are:
 - massive refactoring to remove duplicate code making use of regmap_fields.
 - extending the clock divisors.
 - removed code that should be delivered when we support 20/24bits

---

Marcus Cooper (8):
  ASoC: sun4i-i2s: Add regmap fields for channels
  ASoC: sun4i-i2s: Add regfields for word size select and sample
resolution
  ASoC: sun4i-i2s: bclk and lrclk polarity tidyup
  ASoC: sun4i-i2s: Add mclk enable regmap field
  ASoC: sun4i-i2s: Add regmap field to set DAI format
  ASoC: sun4i-i2s: Check for slave select bit
  ASoC: sun4i-i2s: Update global enable with bitmask
  ASoC: sun4i-i2s: Add support for H3

 .../devicetree/bindings/sound/sun4i-i2s.txt|   2 +
 sound/soc/sunxi/sun4i-i2s.c| 406 ++---
 2 files changed, 357 insertions(+), 51 deletions(-)

-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v5 1/8] ASoC: sun4i-i2s: Add regmap fields for channels

2017-08-19 Thread codekipper
From: Marcus Cooper 

On the original i2s block the channel mapping and selection were
configured for stereo audio by default: This is not the case with
the newer SoCs and they are also located at different offsets.

To support the newer SoC then regmap fields have been added to the
quirks and these are initialised to their correct settings during
probing.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 sound/soc/sunxi/sun4i-i2s.c | 77 -
 1 file changed, 69 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index dfb79492..87feb5a14cff 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -82,7 +82,7 @@
 #define SUN4I_I2S_TX_CNT_REG   0x2c
 
 #define SUN4I_I2S_TX_CHAN_SEL_REG  0x30
-#define SUN4I_I2S_TX_CHAN_SEL(num_chan)(((num_chan) - 1) << 0)
+#define SUN4I_I2S_CHAN_SEL(num_chan)   (((num_chan) - 1) << 0)
 
 #define SUN4I_I2S_TX_CHAN_MAP_REG  0x34
 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample)((sample) << (chan << 2))
@@ -98,6 +98,10 @@
  * @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_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 {
boolhas_reset;
@@ -105,6 +109,12 @@ struct sun4i_i2s_quirks {
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
unsigned intbclk_offset;
+
+   /* Register fields for i2s */
+   struct reg_fieldfield_txchanmap;
+   struct reg_fieldfield_rxchanmap;
+   struct reg_fieldfield_txchansel;
+   struct reg_fieldfield_rxchansel;
 };
 
 struct sun4i_i2s {
@@ -118,6 +128,12 @@ struct sun4i_i2s {
struct snd_dmaengine_dai_dma_data   capture_dma_data;
struct snd_dmaengine_dai_dma_data   playback_dma_data;
 
+   /* Register fields for i2s */
+   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;
 };
 
@@ -268,6 +284,17 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
if (params_channels(params) != 2)
return -EINVAL;
 
+   /* Map the channels for playback and capture */
+   regmap_field_write(i2s->field_txchanmap, 0x76543210);
+   regmap_field_write(i2s->field_rxchanmap, 0x3210);
+
+   /* 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)));
+
switch (params_physical_width(params)) {
case 16:
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
@@ -490,13 +517,6 @@ static int sun4i_i2s_startup(struct snd_pcm_substream 
*substream,
   SUN4I_I2S_CTRL_SDO_EN_MASK,
   SUN4I_I2S_CTRL_SDO_EN(0));
 
-   /* Enable the first two channels */
-   regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
-SUN4I_I2S_TX_CHAN_SEL(2));
-
-   /* Map them to the two first samples coming in */
-   regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG,
-SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1));
 
return clk_prepare_enable(i2s->mod_clk);
 }
@@ -681,14 +701,49 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks 
= {
.has_reset  = false,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .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),
 };
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
.has_reset  = true,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_txchanmap= REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31),
+   .field_rxchanmap= REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
+   

[linux-sunxi] [PATCH v3 08/11] ASoC: sun4i-i2s: Add regmap field to set DAI format

2017-08-12 Thread codekipper
From: Marcus Cooper 

On the newer SoCs the bits to configure the operational mode are
located in a different register. Add a regmap field so that this
location can be configured.

Signed-off-by: Marcus Cooper 
---
 sound/soc/sunxi/sun4i-i2s.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 33af99076d62..b61ef87d0049 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -106,6 +106,7 @@
  * @field_fmt_sr: regmap field to set sample resolution.
  * @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_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.
@@ -125,6 +126,7 @@ struct sun4i_i2s_quirks {
struct reg_fieldfield_fmt_sr;
struct reg_fieldfield_fmt_bclk;
struct reg_fieldfield_fmt_lrclk;
+   struct reg_fieldfield_fmt_mode;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -148,6 +150,7 @@ struct sun4i_i2s {
struct regmap_field *field_fmt_sr;
struct regmap_field *field_fmt_bclk;
struct regmap_field *field_fmt_lrclk;
+   struct regmap_field *field_fmt_mode;
struct regmap_field *field_txchanmap;
struct regmap_field *field_rxchanmap;
struct regmap_field *field_txchansel;
@@ -365,9 +368,7 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
return -EINVAL;
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
-  SUN4I_I2S_FMT0_FMT_MASK,
-  val);
+   regmap_field_write(i2s->field_fmt_mode, val);
 
/* DAI clock polarity */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -722,6 +723,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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_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),
@@ -737,6 +739,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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_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),
@@ -781,6 +784,13 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
ret = PTR_ERR_OR_ZERO(i2s->field_rxchansel);
}
 
+   if (!ret) {
+   i2s->field_fmt_mode =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_mode);
+   ret = PTR_ERR_OR_ZERO(i2s->field_fmt_mode);
+   }
+
if (!ret) {
i2s->field_fmt_wss =
devm_regmap_field_alloc(dev, i2s->regmap,
-- 
2.14.1

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v3 05/11] ASoC: sun4i-i2s: Add regfields for word size select and sample resolution

2017-08-12 Thread codekipper
From: Marcus Cooper 

On newer SoCs the location of the slot width select and sample
resolution are different and also there is a bigger range of
support.

For the current supported rates then an offset is required.

Signed-off-by: Marcus Cooper 
Reviewed-by: Chen-Yu Tsai 
---
 sound/soc/sunxi/sun4i-i2s.c | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a65dcb013247..482fe0c65c1f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -98,6 +98,9 @@
  * @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.
+ * @fmt_offset: Value by which wss and sr needs to be adjusted.
+ * @field_fmt_wss: regmap field to set word select size.
+ * @field_fmt_sr: regmap field to set sample resolution.
  * @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.
@@ -109,8 +112,11 @@ struct sun4i_i2s_quirks {
const struct regmap_config  *sun4i_i2s_regmap;
unsigned intmclk_offset;
unsigned intbclk_offset;
+   unsigned intfmt_offset;
 
/* Register fields for i2s */
+   struct reg_fieldfield_fmt_wss;
+   struct reg_fieldfield_fmt_sr;
struct reg_fieldfield_txchanmap;
struct reg_fieldfield_rxchanmap;
struct reg_fieldfield_txchansel;
@@ -129,6 +135,8 @@ struct sun4i_i2s {
struct snd_dmaengine_dai_dma_data   playback_dma_data;
 
/* Register fields for i2s */
+   struct regmap_field *field_fmt_wss;
+   struct regmap_field *field_fmt_sr;
struct regmap_field *field_txchanmap;
struct regmap_field *field_rxchanmap;
struct regmap_field *field_txchansel;
@@ -314,9 +322,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
*substream,
return -EINVAL;
}
 
-   regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
-  SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
-  SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
+   regmap_field_write(i2s->field_fmt_wss,
+  wss + i2s->variant->fmt_offset);
+   regmap_field_write(i2s->field_fmt_sr,
+  sr + i2s->variant->fmt_offset);
 
return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
  params_width(params));
@@ -701,6 +710,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = 
{
.has_reset  = false,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
+   .field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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),
@@ -711,6 +722,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = 
{
.has_reset  = true,
.reg_offset_txdata  = SUN4I_I2S_FIFO_TX_REG,
.sun4i_i2s_regmap   = _i2s_regmap_config,
+   .field_fmt_wss  = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
+   .field_fmt_sr   = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
.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),
@@ -748,6 +761,20 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
ret = PTR_ERR_OR_ZERO(i2s->field_rxchansel);
}
 
+   if (!ret) {
+   i2s->field_fmt_wss =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_wss);
+   ret = PTR_ERR_OR_ZERO(i2s->field_fmt_wss);
+   }
+
+   if (!ret) {
+   i2s->field_fmt_sr =
+   devm_regmap_field_alloc(dev, i2s->regmap,
+   i2s->variant->field_fmt_sr);
+   ret = PTR_ERR_OR_ZERO(i2s->field_fmt_sr);
+   }
+
return ret;
 }
 
-- 
2.14.1

-- 
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 

  1   2   3   >