121121#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
122122#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
123123
124+ /* Defines required for sun50i-h6 support */
125+ #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20)
126+ #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET (offset ) ((offset) << 20)
127+ #define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16)
128+ #define SUN50I_H6_I2S_TX_CHAN_SEL (chan ) ((chan - 1) << 16)
129+ #define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(19, 16)
130+ #define SUN50I_H6_I2S_TX_CHAN_EN (num_chan ) (((1 << num_chan) - 1))
131+
132+ #define SUN50I_H6_I2S_TX_CHAN_MAP0_REG 0x44
133+ #define SUN50I_H6_I2S_TX_CHAN_MAP1_REG 0x48
134+
135+ #define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64
136+ #define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68
137+ #define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C
138+
124139struct sun4i_i2s ;
125140
126141/**
@@ -445,6 +460,25 @@ static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
445460 SUN8I_I2S_TX_CHAN_OFFSET (i2s -> offset ));
446461}
447462
463+ static void sun50i_h6_i2s_set_txchanoffset (const struct sun4i_i2s * i2s , int output )
464+ {
465+ if (output >= 0 && output < 4 ) {
466+ regmap_update_bits (i2s -> regmap ,
467+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4 ),
468+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK ,
469+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET (i2s -> offset ));
470+ }
471+
472+ }
473+
474+ static void sun50i_h6_i2s_set_rxchanoffset (const struct sun4i_i2s * i2s )
475+ {
476+ regmap_update_bits (i2s -> regmap ,
477+ SUN8I_I2S_RX_CHAN_SEL_REG ,
478+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK ,
479+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET (i2s -> offset ));
480+ }
481+
448482static void sun8i_i2s_set_txchanen (const struct sun4i_i2s * i2s , int output ,
449483 int channel )
450484{
@@ -464,6 +498,26 @@ static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
464498 SUN8I_I2S_TX_CHAN_EN (channel ));
465499}
466500
501+
502+ static void sun50i_h6_i2s_set_txchanen (const struct sun4i_i2s * i2s , int output ,
503+ int channel )
504+ {
505+ if (output >= 0 && output < 4 ) {
506+ regmap_update_bits (i2s -> regmap ,
507+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4 ),
508+ SUN50I_H6_I2S_TX_CHAN_EN_MASK ,
509+ SUN50I_H6_I2S_TX_CHAN_EN (channel ));
510+ }
511+ }
512+
513+ static void sun50i_h6_i2s_set_rxchanen (const struct sun4i_i2s * i2s , int channel )
514+ {
515+ regmap_update_bits (i2s -> regmap ,
516+ SUN8I_I2S_RX_CHAN_SEL_REG ,
517+ SUN50I_H6_I2S_TX_CHAN_EN_MASK ,
518+ SUN50I_H6_I2S_TX_CHAN_EN (channel ));
519+ }
520+
467521static void sun4i_i2s_set_txchansel (const struct sun4i_i2s * i2s , int output ,
468522 int channel )
469523{
@@ -500,6 +554,25 @@ static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
500554 SUN8I_I2S_TX_CHAN_SEL (channel ));
501555}
502556
557+ static void sun50i_h6_i2s_set_txchansel (const struct sun4i_i2s * i2s , int output ,
558+ int channel )
559+ {
560+ if (output >= 0 && output < 4 ) {
561+ regmap_update_bits (i2s -> regmap ,
562+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4 ),
563+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK ,
564+ SUN50I_H6_I2S_TX_CHAN_SEL (channel ));
565+ }
566+ }
567+
568+ static void sun50i_h6_i2s_set_rxchansel (const struct sun4i_i2s * i2s , int channel )
569+ {
570+ regmap_update_bits (i2s -> regmap ,
571+ SUN8I_I2S_RX_CHAN_SEL_REG ,
572+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK ,
573+ SUN50I_H6_I2S_TX_CHAN_SEL (channel ));
574+ }
575+
503576static void sun4i_i2s_set_txchanmap (const struct sun4i_i2s * i2s , int output ,
504577 int channel )
505578{
@@ -525,6 +598,20 @@ static void sun8i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
525598 regmap_write (i2s -> regmap , SUN8I_I2S_RX_CHAN_MAP_REG , channel );
526599}
527600
601+ static void sun50i_h6_i2s_set_txchanmap (const struct sun4i_i2s * i2s , int output ,
602+ int channel )
603+ {
604+ if (output >= 0 && output < 4 ) {
605+ regmap_write (i2s -> regmap ,
606+ SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output * 8 ), channel );
607+ }
608+ }
609+
610+ static void sun50i_h6_i2s_set_rxchanmap (const struct sun4i_i2s * i2s , int channel )
611+ {
612+ regmap_write (i2s -> regmap , SUN50I_H6_I2S_RX_CHAN_MAP1_REG , channel );
613+ }
614+
528615static int sun4i_i2s_hw_params (struct snd_pcm_substream * substream ,
529616 struct snd_pcm_hw_params * params ,
530617 struct snd_soc_dai * dai )
@@ -998,6 +1085,22 @@ static const struct reg_default sun8i_i2s_reg_defaults[] = {
9981085 { SUN8I_I2S_RX_CHAN_MAP_REG , 0x00000000 },
9991086};
10001087
1088+ static const struct reg_default sun50i_i2s_reg_defaults [] = {
1089+ { SUN4I_I2S_CTRL_REG , 0x00060000 },
1090+ { SUN4I_I2S_FMT0_REG , 0x00000033 },
1091+ { SUN4I_I2S_FMT1_REG , 0x00000030 },
1092+ { SUN4I_I2S_FIFO_CTRL_REG , 0x000400f0 },
1093+ { SUN4I_I2S_DMA_INT_CTRL_REG , 0x00000000 },
1094+ { SUN4I_I2S_CLK_DIV_REG , 0x00000000 },
1095+ { SUN8I_I2S_CHAN_CFG_REG , 0x00000000 },
1096+ { SUN8I_I2S_TX_CHAN_SEL_REG , 0x00000000 },
1097+ { SUN50I_H6_I2S_TX_CHAN_MAP0_REG , 0x00000000 },
1098+ { SUN50I_H6_I2S_TX_CHAN_MAP1_REG , 0x00000000 },
1099+ { SUN50I_H6_I2S_RX_CHAN_SEL_REG , 0x00000000 },
1100+ { SUN50I_H6_I2S_RX_CHAN_MAP0_REG , 0x00000000 },
1101+ { SUN50I_H6_I2S_RX_CHAN_MAP1_REG , 0x00000000 },
1102+ };
1103+
10011104static const struct regmap_config sun4i_i2s_regmap_config = {
10021105 .reg_bits = 32 ,
10031106 .reg_stride = 4 ,
@@ -1025,6 +1128,19 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
10251128 .volatile_reg = sun8i_i2s_volatile_reg ,
10261129};
10271130
1131+ static const struct regmap_config sun50i_i2s_regmap_config = {
1132+ .reg_bits = 32 ,
1133+ .reg_stride = 4 ,
1134+ .val_bits = 32 ,
1135+ .max_register = SUN50I_H6_I2S_RX_CHAN_MAP1_REG ,
1136+ .cache_type = REGCACHE_FLAT ,
1137+ .reg_defaults = sun50i_i2s_reg_defaults ,
1138+ .num_reg_defaults = ARRAY_SIZE (sun50i_i2s_reg_defaults ),
1139+ .writeable_reg = sun4i_i2s_wr_reg ,
1140+ .readable_reg = sun8i_i2s_rd_reg ,
1141+ .volatile_reg = sun8i_i2s_volatile_reg ,
1142+ };
1143+
10281144static int sun4i_i2s_runtime_resume (struct device * dev )
10291145{
10301146 struct sun4i_i2s * i2s = dev_get_drvdata (dev );
@@ -1199,6 +1315,33 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
11991315 .set_rxchanmap = sun4i_i2s_set_rxchanmap ,
12001316};
12011317
1318+ static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
1319+ .has_reset = true,
1320+ .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
1321+ .sun4i_i2s_regmap = & sun50i_i2s_regmap_config ,
1322+ .has_fmt_set_lrck_period = true,
1323+ .has_chcfg = true,
1324+ .has_chsel_tx_chen = true,
1325+ .has_chsel_offset = true,
1326+ .field_clkdiv_mclk_en = REG_FIELD (SUN4I_I2S_CLK_DIV_REG , 8 , 8 ),
1327+ .field_fmt_wss = REG_FIELD (SUN4I_I2S_FMT0_REG , 0 , 2 ),
1328+ .field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 6 ),
1329+ .field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
1330+ .field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 19 , 19 ),
1331+ .field_fmt_mode = REG_FIELD (SUN4I_I2S_CTRL_REG , 4 , 5 ),
1332+ .get_sr = sun8i_i2s_get_sr_wss ,
1333+ .get_wss = sun8i_i2s_get_sr_wss ,
1334+ .set_format = sun8i_i2s_set_format ,
1335+ .set_txchanoffset = sun50i_h6_i2s_set_txchanoffset ,
1336+ .set_rxchanoffset = sun50i_h6_i2s_set_rxchanoffset ,
1337+ .set_txchanen = sun50i_h6_i2s_set_txchanen ,
1338+ .set_rxchanen = sun50i_h6_i2s_set_rxchanen ,
1339+ .set_txchansel = sun50i_h6_i2s_set_txchansel ,
1340+ .set_rxchansel = sun50i_h6_i2s_set_rxchansel ,
1341+ .set_txchanmap = sun50i_h6_i2s_set_txchanmap ,
1342+ .set_rxchanmap = sun50i_h6_i2s_set_rxchanmap ,
1343+ };
1344+
12021345static int sun4i_i2s_init_regmap_fields (struct device * dev ,
12031346 struct sun4i_i2s * i2s )
12041347{
@@ -1391,6 +1534,10 @@ static const struct of_device_id sun4i_i2s_match[] = {
13911534 .compatible = "allwinner,sun50i-a64-codec-i2s" ,
13921535 .data = & sun50i_a64_codec_i2s_quirks ,
13931536 },
1537+ {
1538+ .compatible = "allwinner,sun50i-h6-i2s" ,
1539+ .data = & sun50i_h6_i2s_quirks ,
1540+ },
13941541 {}
13951542};
13961543MODULE_DEVICE_TABLE (of , sun4i_i2s_match );
0 commit comments