@@ -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 = {