0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/dmaengine.h>
0012 #include <linux/module.h>
0013 #include <linux/of_device.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/regmap.h>
0017 #include <linux/reset.h>
0018
0019 #include <sound/dmaengine_pcm.h>
0020 #include <sound/pcm_params.h>
0021 #include <sound/soc.h>
0022 #include <sound/soc-dai.h>
0023
0024 #define SUN4I_I2S_CTRL_REG 0x00
0025 #define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8)
0026 #define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo))
0027 #define SUN4I_I2S_CTRL_MODE_MASK BIT(5)
0028 #define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5)
0029 #define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5)
0030 #define SUN4I_I2S_CTRL_TX_EN BIT(2)
0031 #define SUN4I_I2S_CTRL_RX_EN BIT(1)
0032 #define SUN4I_I2S_CTRL_GL_EN BIT(0)
0033
0034 #define SUN4I_I2S_FMT0_REG 0x04
0035 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(7)
0036 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 7)
0037 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 7)
0038 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK BIT(6)
0039 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 6)
0040 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 6)
0041 #define SUN4I_I2S_FMT0_SR_MASK GENMASK(5, 4)
0042 #define SUN4I_I2S_FMT0_SR(sr) ((sr) << 4)
0043 #define SUN4I_I2S_FMT0_WSS_MASK GENMASK(3, 2)
0044 #define SUN4I_I2S_FMT0_WSS(wss) ((wss) << 2)
0045 #define SUN4I_I2S_FMT0_FMT_MASK GENMASK(1, 0)
0046 #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)
0047 #define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0)
0048 #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
0049
0050 #define SUN4I_I2S_FMT1_REG 0x08
0051 #define SUN4I_I2S_FMT1_REG_SEXT_MASK BIT(8)
0052 #define SUN4I_I2S_FMT1_REG_SEXT(sext) ((sext) << 8)
0053
0054 #define SUN4I_I2S_FIFO_TX_REG 0x0c
0055 #define SUN4I_I2S_FIFO_RX_REG 0x10
0056
0057 #define SUN4I_I2S_FIFO_CTRL_REG 0x14
0058 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX BIT(25)
0059 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX BIT(24)
0060 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK BIT(2)
0061 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode) ((mode) << 2)
0062 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK GENMASK(1, 0)
0063 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode) (mode)
0064
0065 #define SUN4I_I2S_FIFO_STA_REG 0x18
0066
0067 #define SUN4I_I2S_DMA_INT_CTRL_REG 0x1c
0068 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN BIT(7)
0069 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN BIT(3)
0070
0071 #define SUN4I_I2S_INT_STA_REG 0x20
0072
0073 #define SUN4I_I2S_CLK_DIV_REG 0x24
0074 #define SUN4I_I2S_CLK_DIV_MCLK_EN BIT(7)
0075 #define SUN4I_I2S_CLK_DIV_BCLK_MASK GENMASK(6, 4)
0076 #define SUN4I_I2S_CLK_DIV_BCLK(bclk) ((bclk) << 4)
0077 #define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0)
0078 #define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0)
0079
0080 #define SUN4I_I2S_TX_CNT_REG 0x28
0081 #define SUN4I_I2S_RX_CNT_REG 0x2c
0082
0083 #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30
0084 #define SUN4I_I2S_CHAN_SEL_MASK GENMASK(2, 0)
0085 #define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0)
0086
0087 #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34
0088 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2))
0089
0090 #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38
0091 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c
0092
0093
0094 #define SUN8I_I2S_CTRL_BCLK_OUT BIT(18)
0095 #define SUN8I_I2S_CTRL_LRCK_OUT BIT(17)
0096
0097 #define SUN8I_I2S_CTRL_MODE_MASK GENMASK(5, 4)
0098 #define SUN8I_I2S_CTRL_MODE_RIGHT (2 << 4)
0099 #define SUN8I_I2S_CTRL_MODE_LEFT (1 << 4)
0100 #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4)
0101
0102 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19)
0103 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19)
0104 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19)
0105 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8)
0106 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
0107 #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7)
0108 #define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
0109 #define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
0110
0111 #define SUN8I_I2S_FMT1_REG_SEXT_MASK GENMASK(5, 4)
0112 #define SUN8I_I2S_FMT1_REG_SEXT(sext) ((sext) << 4)
0113
0114 #define SUN8I_I2S_INT_STA_REG 0x0c
0115 #define SUN8I_I2S_FIFO_TX_REG 0x20
0116
0117 #define SUN8I_I2S_CHAN_CFG_REG 0x30
0118 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(7, 4)
0119 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) ((chan - 1) << 4)
0120 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(3, 0)
0121 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1)
0122
0123 #define SUN8I_I2S_TX_CHAN_MAP_REG 0x44
0124 #define SUN8I_I2S_TX_CHAN_SEL_REG 0x34
0125 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 12)
0126 #define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12)
0127 #define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4)
0128 #define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4)
0129
0130 #define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
0131 #define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
0132
0133
0134 #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20)
0135 #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset) ((offset) << 20)
0136 #define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16)
0137 #define SUN50I_H6_I2S_TX_CHAN_SEL(chan) ((chan - 1) << 16)
0138 #define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(15, 0)
0139 #define SUN50I_H6_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1))
0140
0141 #define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin) (0x34 + 4 * (pin))
0142 #define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin) (0x44 + 8 * (pin))
0143 #define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin) (0x48 + 8 * (pin))
0144
0145 #define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64
0146 #define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68
0147 #define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C
0148
0149 #define SUN50I_R329_I2S_RX_CHAN_MAP0_REG 0x68
0150 #define SUN50I_R329_I2S_RX_CHAN_MAP1_REG 0x6c
0151 #define SUN50I_R329_I2S_RX_CHAN_MAP2_REG 0x70
0152 #define SUN50I_R329_I2S_RX_CHAN_MAP3_REG 0x74
0153
0154 struct sun4i_i2s;
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 struct sun4i_i2s_quirks {
0177 bool has_reset;
0178 unsigned int reg_offset_txdata;
0179 const struct regmap_config *sun4i_i2s_regmap;
0180
0181
0182 struct reg_field field_clkdiv_mclk_en;
0183 struct reg_field field_fmt_wss;
0184 struct reg_field field_fmt_sr;
0185
0186 unsigned int num_din_pins;
0187 unsigned int num_dout_pins;
0188
0189 const struct sun4i_i2s_clk_div *bclk_dividers;
0190 unsigned int num_bclk_dividers;
0191 const struct sun4i_i2s_clk_div *mclk_dividers;
0192 unsigned int num_mclk_dividers;
0193
0194 unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
0195 int (*get_sr)(unsigned int width);
0196 int (*get_wss)(unsigned int width);
0197
0198
0199
0200
0201
0202
0203 int (*set_chan_cfg)(const struct sun4i_i2s *i2s,
0204 unsigned int channels, unsigned int slots,
0205 unsigned int slot_width);
0206 int (*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
0207 };
0208
0209 struct sun4i_i2s {
0210 struct clk *bus_clk;
0211 struct clk *mod_clk;
0212 struct regmap *regmap;
0213 struct reset_control *rst;
0214
0215 unsigned int format;
0216 unsigned int mclk_freq;
0217 unsigned int slots;
0218 unsigned int slot_width;
0219
0220 struct snd_dmaengine_dai_dma_data capture_dma_data;
0221 struct snd_dmaengine_dai_dma_data playback_dma_data;
0222
0223
0224 struct regmap_field *field_clkdiv_mclk_en;
0225 struct regmap_field *field_fmt_wss;
0226 struct regmap_field *field_fmt_sr;
0227
0228 const struct sun4i_i2s_quirks *variant;
0229 };
0230
0231 struct sun4i_i2s_clk_div {
0232 u8 div;
0233 u8 val;
0234 };
0235
0236 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
0237 { .div = 2, .val = 0 },
0238 { .div = 4, .val = 1 },
0239 { .div = 6, .val = 2 },
0240 { .div = 8, .val = 3 },
0241 { .div = 12, .val = 4 },
0242 { .div = 16, .val = 5 },
0243
0244 };
0245
0246 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
0247 { .div = 1, .val = 0 },
0248 { .div = 2, .val = 1 },
0249 { .div = 4, .val = 2 },
0250 { .div = 6, .val = 3 },
0251 { .div = 8, .val = 4 },
0252 { .div = 12, .val = 5 },
0253 { .div = 16, .val = 6 },
0254 { .div = 24, .val = 7 },
0255
0256 };
0257
0258 static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
0259 { .div = 1, .val = 1 },
0260 { .div = 2, .val = 2 },
0261 { .div = 4, .val = 3 },
0262 { .div = 6, .val = 4 },
0263 { .div = 8, .val = 5 },
0264 { .div = 12, .val = 6 },
0265 { .div = 16, .val = 7 },
0266 { .div = 24, .val = 8 },
0267 { .div = 32, .val = 9 },
0268 { .div = 48, .val = 10 },
0269 { .div = 64, .val = 11 },
0270 { .div = 96, .val = 12 },
0271 { .div = 128, .val = 13 },
0272 { .div = 176, .val = 14 },
0273 { .div = 192, .val = 15 },
0274 };
0275
0276 static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
0277 {
0278 return i2s->mclk_freq;
0279 }
0280
0281 static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
0282 {
0283 return clk_get_rate(i2s->mod_clk);
0284 }
0285
0286 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
0287 unsigned long parent_rate,
0288 unsigned int sampling_rate,
0289 unsigned int channels,
0290 unsigned int word_size)
0291 {
0292 const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
0293 int div = parent_rate / sampling_rate / word_size / channels;
0294 int i;
0295
0296 for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
0297 const struct sun4i_i2s_clk_div *bdiv = ÷rs[i];
0298
0299 if (bdiv->div == div)
0300 return bdiv->val;
0301 }
0302
0303 return -EINVAL;
0304 }
0305
0306 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
0307 unsigned long parent_rate,
0308 unsigned long mclk_rate)
0309 {
0310 const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
0311 int div = parent_rate / mclk_rate;
0312 int i;
0313
0314 for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
0315 const struct sun4i_i2s_clk_div *mdiv = ÷rs[i];
0316
0317 if (mdiv->div == div)
0318 return mdiv->val;
0319 }
0320
0321 return -EINVAL;
0322 }
0323
0324 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
0325 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
0326 {
0327 int i;
0328
0329 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
0330 if (sun4i_i2s_oversample_rates[i] == oversample)
0331 return true;
0332
0333 return false;
0334 }
0335
0336 static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
0337 unsigned int rate,
0338 unsigned int slots,
0339 unsigned int slot_width)
0340 {
0341 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0342 unsigned int oversample_rate, clk_rate, bclk_parent_rate;
0343 int bclk_div, mclk_div;
0344 int ret;
0345
0346 switch (rate) {
0347 case 176400:
0348 case 88200:
0349 case 44100:
0350 case 22050:
0351 case 11025:
0352 clk_rate = 22579200;
0353 break;
0354
0355 case 192000:
0356 case 128000:
0357 case 96000:
0358 case 64000:
0359 case 48000:
0360 case 32000:
0361 case 24000:
0362 case 16000:
0363 case 12000:
0364 case 8000:
0365 clk_rate = 24576000;
0366 break;
0367
0368 default:
0369 dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
0370 return -EINVAL;
0371 }
0372
0373 ret = clk_set_rate(i2s->mod_clk, clk_rate);
0374 if (ret)
0375 return ret;
0376
0377 oversample_rate = i2s->mclk_freq / rate;
0378 if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
0379 dev_err(dai->dev, "Unsupported oversample rate: %d\n",
0380 oversample_rate);
0381 return -EINVAL;
0382 }
0383
0384 bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
0385 bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
0386 rate, slots, slot_width);
0387 if (bclk_div < 0) {
0388 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
0389 return -EINVAL;
0390 }
0391
0392 mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
0393 if (mclk_div < 0) {
0394 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
0395 return -EINVAL;
0396 }
0397
0398 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
0399 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
0400 SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
0401
0402 regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
0403
0404 return 0;
0405 }
0406
0407 static int sun4i_i2s_get_sr(unsigned int width)
0408 {
0409 switch (width) {
0410 case 16:
0411 return 0;
0412 case 20:
0413 return 1;
0414 case 24:
0415 return 2;
0416 }
0417
0418 return -EINVAL;
0419 }
0420
0421 static int sun4i_i2s_get_wss(unsigned int width)
0422 {
0423 switch (width) {
0424 case 16:
0425 return 0;
0426 case 20:
0427 return 1;
0428 case 24:
0429 return 2;
0430 case 32:
0431 return 3;
0432 }
0433
0434 return -EINVAL;
0435 }
0436
0437 static int sun8i_i2s_get_sr_wss(unsigned int width)
0438 {
0439 switch (width) {
0440 case 8:
0441 return 1;
0442 case 12:
0443 return 2;
0444 case 16:
0445 return 3;
0446 case 20:
0447 return 4;
0448 case 24:
0449 return 5;
0450 case 28:
0451 return 6;
0452 case 32:
0453 return 7;
0454 }
0455
0456 return -EINVAL;
0457 }
0458
0459 static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
0460 unsigned int channels, unsigned int slots,
0461 unsigned int slot_width)
0462 {
0463
0464 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
0465 regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
0466
0467
0468 regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
0469 SUN4I_I2S_CHAN_SEL_MASK,
0470 SUN4I_I2S_CHAN_SEL(channels));
0471 regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
0472 SUN4I_I2S_CHAN_SEL_MASK,
0473 SUN4I_I2S_CHAN_SEL(channels));
0474
0475 return 0;
0476 }
0477
0478 static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
0479 unsigned int channels, unsigned int slots,
0480 unsigned int slot_width)
0481 {
0482 unsigned int lrck_period;
0483
0484
0485 regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
0486 regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
0487
0488
0489 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
0490 SUN4I_I2S_CHAN_SEL_MASK,
0491 SUN4I_I2S_CHAN_SEL(channels));
0492 regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
0493 SUN4I_I2S_CHAN_SEL_MASK,
0494 SUN4I_I2S_CHAN_SEL(channels));
0495
0496 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
0497 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
0498 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
0499 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
0500 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
0501 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
0502
0503 switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
0504 case SND_SOC_DAIFMT_DSP_A:
0505 case SND_SOC_DAIFMT_DSP_B:
0506 lrck_period = slot_width * slots;
0507 break;
0508
0509 case SND_SOC_DAIFMT_LEFT_J:
0510 case SND_SOC_DAIFMT_RIGHT_J:
0511 case SND_SOC_DAIFMT_I2S:
0512 lrck_period = slot_width;
0513 break;
0514
0515 default:
0516 return -EINVAL;
0517 }
0518
0519 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0520 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
0521 SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
0522
0523 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
0524 SUN8I_I2S_TX_CHAN_EN_MASK,
0525 SUN8I_I2S_TX_CHAN_EN(channels));
0526
0527 return 0;
0528 }
0529
0530 static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
0531 unsigned int channels, unsigned int slots,
0532 unsigned int slot_width)
0533 {
0534 unsigned int lrck_period;
0535
0536
0537 regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
0538 regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
0539 if (i2s->variant->num_din_pins > 1) {
0540 regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 0x0F0E0D0C);
0541 regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 0x0B0A0908);
0542 regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 0x07060504);
0543 regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0x03020100);
0544 } else {
0545 regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
0546 regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
0547 }
0548
0549
0550 regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
0551 SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
0552 SUN50I_H6_I2S_TX_CHAN_SEL(channels));
0553 regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
0554 SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
0555 SUN50I_H6_I2S_TX_CHAN_SEL(channels));
0556
0557 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
0558 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
0559 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
0560 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
0561 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
0562 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
0563
0564 switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
0565 case SND_SOC_DAIFMT_DSP_A:
0566 case SND_SOC_DAIFMT_DSP_B:
0567 lrck_period = slot_width * slots;
0568 break;
0569
0570 case SND_SOC_DAIFMT_LEFT_J:
0571 case SND_SOC_DAIFMT_RIGHT_J:
0572 case SND_SOC_DAIFMT_I2S:
0573 lrck_period = slot_width;
0574 break;
0575
0576 default:
0577 return -EINVAL;
0578 }
0579
0580 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0581 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
0582 SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
0583
0584 regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
0585 SUN50I_H6_I2S_TX_CHAN_EN_MASK,
0586 SUN50I_H6_I2S_TX_CHAN_EN(channels));
0587
0588 return 0;
0589 }
0590
0591 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
0592 struct snd_pcm_hw_params *params,
0593 struct snd_soc_dai *dai)
0594 {
0595 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0596 unsigned int word_size = params_width(params);
0597 unsigned int slot_width = params_physical_width(params);
0598 unsigned int channels = params_channels(params);
0599
0600 unsigned int slots = channels;
0601
0602 int ret, sr, wss;
0603 u32 width;
0604
0605 if (i2s->slots)
0606 slots = i2s->slots;
0607
0608 if (i2s->slot_width)
0609 slot_width = i2s->slot_width;
0610
0611 ret = i2s->variant->set_chan_cfg(i2s, channels, slots, slot_width);
0612 if (ret < 0) {
0613 dev_err(dai->dev, "Invalid channel configuration\n");
0614 return ret;
0615 }
0616
0617
0618 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
0619 SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
0620 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
0621 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
0622 SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
0623
0624 switch (params_physical_width(params)) {
0625 case 16:
0626 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
0627 break;
0628 case 32:
0629 width = DMA_SLAVE_BUSWIDTH_4_BYTES;
0630 break;
0631 default:
0632 dev_err(dai->dev, "Unsupported physical sample width: %d\n",
0633 params_physical_width(params));
0634 return -EINVAL;
0635 }
0636 i2s->playback_dma_data.addr_width = width;
0637
0638 sr = i2s->variant->get_sr(word_size);
0639 if (sr < 0)
0640 return -EINVAL;
0641
0642 wss = i2s->variant->get_wss(slot_width);
0643 if (wss < 0)
0644 return -EINVAL;
0645
0646 regmap_field_write(i2s->field_fmt_wss, wss);
0647 regmap_field_write(i2s->field_fmt_sr, sr);
0648
0649 return sun4i_i2s_set_clk_rate(dai, params_rate(params),
0650 slots, slot_width);
0651 }
0652
0653 static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
0654 unsigned int fmt)
0655 {
0656 u32 val;
0657
0658
0659 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0660 case SND_SOC_DAIFMT_IB_IF:
0661
0662 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
0663 SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0664 break;
0665 case SND_SOC_DAIFMT_IB_NF:
0666
0667 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0668 break;
0669 case SND_SOC_DAIFMT_NB_IF:
0670
0671 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0672 break;
0673 case SND_SOC_DAIFMT_NB_NF:
0674 val = 0;
0675 break;
0676 default:
0677 return -EINVAL;
0678 }
0679
0680 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0681 SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
0682 SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
0683 val);
0684
0685
0686 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0687 case SND_SOC_DAIFMT_I2S:
0688 val = SUN4I_I2S_FMT0_FMT_I2S;
0689 break;
0690
0691 case SND_SOC_DAIFMT_LEFT_J:
0692 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
0693 break;
0694
0695 case SND_SOC_DAIFMT_RIGHT_J:
0696 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
0697 break;
0698
0699 default:
0700 return -EINVAL;
0701 }
0702
0703 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0704 SUN4I_I2S_FMT0_FMT_MASK, val);
0705
0706
0707 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0708 case SND_SOC_DAIFMT_BP_FP:
0709
0710 val = SUN4I_I2S_CTRL_MODE_MASTER;
0711 break;
0712
0713 case SND_SOC_DAIFMT_BC_FC:
0714
0715 val = SUN4I_I2S_CTRL_MODE_SLAVE;
0716 break;
0717
0718 default:
0719 return -EINVAL;
0720 }
0721 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0722 SUN4I_I2S_CTRL_MODE_MASK, val);
0723
0724 return 0;
0725 }
0726
0727 static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
0728 unsigned int fmt)
0729 {
0730 u32 mode, val;
0731 u8 offset;
0732
0733
0734
0735
0736
0737
0738
0739
0740 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0741 case SND_SOC_DAIFMT_IB_IF:
0742
0743 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0744 break;
0745 case SND_SOC_DAIFMT_IB_NF:
0746
0747 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
0748 SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0749 break;
0750 case SND_SOC_DAIFMT_NB_IF:
0751
0752 val = 0;
0753 break;
0754 case SND_SOC_DAIFMT_NB_NF:
0755 val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0756 break;
0757 default:
0758 return -EINVAL;
0759 }
0760
0761 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0762 SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
0763 SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
0764 val);
0765
0766
0767 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0768 case SND_SOC_DAIFMT_DSP_A:
0769 mode = SUN8I_I2S_CTRL_MODE_PCM;
0770 offset = 1;
0771 break;
0772
0773 case SND_SOC_DAIFMT_DSP_B:
0774 mode = SUN8I_I2S_CTRL_MODE_PCM;
0775 offset = 0;
0776 break;
0777
0778 case SND_SOC_DAIFMT_I2S:
0779 mode = SUN8I_I2S_CTRL_MODE_LEFT;
0780 offset = 1;
0781 break;
0782
0783 case SND_SOC_DAIFMT_LEFT_J:
0784 mode = SUN8I_I2S_CTRL_MODE_LEFT;
0785 offset = 0;
0786 break;
0787
0788 case SND_SOC_DAIFMT_RIGHT_J:
0789 mode = SUN8I_I2S_CTRL_MODE_RIGHT;
0790 offset = 0;
0791 break;
0792
0793 default:
0794 return -EINVAL;
0795 }
0796
0797 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0798 SUN8I_I2S_CTRL_MODE_MASK, mode);
0799 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
0800 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
0801 SUN8I_I2S_TX_CHAN_OFFSET(offset));
0802 regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
0803 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
0804 SUN8I_I2S_TX_CHAN_OFFSET(offset));
0805
0806
0807 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0808 case SND_SOC_DAIFMT_BP_FP:
0809
0810 val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
0811 break;
0812
0813 case SND_SOC_DAIFMT_BC_FC:
0814
0815 val = 0;
0816 break;
0817
0818 default:
0819 return -EINVAL;
0820 }
0821
0822 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0823 SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
0824 val);
0825
0826
0827 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
0828 SUN8I_I2S_FMT1_REG_SEXT_MASK,
0829 SUN8I_I2S_FMT1_REG_SEXT(0));
0830
0831 return 0;
0832 }
0833
0834 static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
0835 unsigned int fmt)
0836 {
0837 u32 mode, val;
0838 u8 offset;
0839
0840
0841
0842
0843
0844
0845
0846
0847 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0848 case SND_SOC_DAIFMT_IB_IF:
0849
0850 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0851 break;
0852 case SND_SOC_DAIFMT_IB_NF:
0853
0854 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
0855 SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0856 break;
0857 case SND_SOC_DAIFMT_NB_IF:
0858
0859 val = 0;
0860 break;
0861 case SND_SOC_DAIFMT_NB_NF:
0862 val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
0863 break;
0864 default:
0865 return -EINVAL;
0866 }
0867
0868 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
0869 SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
0870 SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
0871 val);
0872
0873
0874 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0875 case SND_SOC_DAIFMT_DSP_A:
0876 mode = SUN8I_I2S_CTRL_MODE_PCM;
0877 offset = 1;
0878 break;
0879
0880 case SND_SOC_DAIFMT_DSP_B:
0881 mode = SUN8I_I2S_CTRL_MODE_PCM;
0882 offset = 0;
0883 break;
0884
0885 case SND_SOC_DAIFMT_I2S:
0886 mode = SUN8I_I2S_CTRL_MODE_LEFT;
0887 offset = 1;
0888 break;
0889
0890 case SND_SOC_DAIFMT_LEFT_J:
0891 mode = SUN8I_I2S_CTRL_MODE_LEFT;
0892 offset = 0;
0893 break;
0894
0895 case SND_SOC_DAIFMT_RIGHT_J:
0896 mode = SUN8I_I2S_CTRL_MODE_RIGHT;
0897 offset = 0;
0898 break;
0899
0900 default:
0901 return -EINVAL;
0902 }
0903
0904 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0905 SUN8I_I2S_CTRL_MODE_MASK, mode);
0906 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
0907 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
0908 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
0909 regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
0910 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
0911 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
0912
0913
0914 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0915 case SND_SOC_DAIFMT_BP_FP:
0916
0917 val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
0918 break;
0919
0920 case SND_SOC_DAIFMT_BC_FC:
0921
0922 val = 0;
0923 break;
0924
0925 default:
0926 return -EINVAL;
0927 }
0928
0929 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0930 SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
0931 val);
0932
0933
0934 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
0935 SUN8I_I2S_FMT1_REG_SEXT_MASK,
0936 SUN8I_I2S_FMT1_REG_SEXT(0));
0937
0938 return 0;
0939 }
0940
0941 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0942 {
0943 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0944 int ret;
0945
0946 ret = i2s->variant->set_fmt(i2s, fmt);
0947 if (ret) {
0948 dev_err(dai->dev, "Unsupported format configuration\n");
0949 return ret;
0950 }
0951
0952 i2s->format = fmt;
0953
0954 return 0;
0955 }
0956
0957 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
0958 {
0959
0960 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
0961 SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
0962 SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
0963
0964
0965 regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
0966
0967
0968 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0969 SUN4I_I2S_CTRL_RX_EN,
0970 SUN4I_I2S_CTRL_RX_EN);
0971
0972
0973 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
0974 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
0975 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
0976 }
0977
0978 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
0979 {
0980
0981 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
0982 SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
0983 SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
0984
0985
0986 regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
0987
0988
0989 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0990 SUN4I_I2S_CTRL_TX_EN,
0991 SUN4I_I2S_CTRL_TX_EN);
0992
0993
0994 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
0995 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
0996 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
0997 }
0998
0999 static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
1000 {
1001
1002 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1003 SUN4I_I2S_CTRL_RX_EN,
1004 0);
1005
1006
1007 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1008 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
1009 0);
1010 }
1011
1012 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
1013 {
1014
1015 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1016 SUN4I_I2S_CTRL_TX_EN,
1017 0);
1018
1019
1020 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1021 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
1022 0);
1023 }
1024
1025 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
1026 struct snd_soc_dai *dai)
1027 {
1028 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1029
1030 switch (cmd) {
1031 case SNDRV_PCM_TRIGGER_START:
1032 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1033 case SNDRV_PCM_TRIGGER_RESUME:
1034 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1035 sun4i_i2s_start_playback(i2s);
1036 else
1037 sun4i_i2s_start_capture(i2s);
1038 break;
1039
1040 case SNDRV_PCM_TRIGGER_STOP:
1041 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1042 case SNDRV_PCM_TRIGGER_SUSPEND:
1043 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1044 sun4i_i2s_stop_playback(i2s);
1045 else
1046 sun4i_i2s_stop_capture(i2s);
1047 break;
1048
1049 default:
1050 return -EINVAL;
1051 }
1052
1053 return 0;
1054 }
1055
1056 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1057 unsigned int freq, int dir)
1058 {
1059 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1060
1061 if (clk_id != 0)
1062 return -EINVAL;
1063
1064 i2s->mclk_freq = freq;
1065
1066 return 0;
1067 }
1068
1069 static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
1070 unsigned int tx_mask, unsigned int rx_mask,
1071 int slots, int slot_width)
1072 {
1073 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1074
1075 if (slots > 8)
1076 return -EINVAL;
1077
1078 i2s->slots = slots;
1079 i2s->slot_width = slot_width;
1080
1081 return 0;
1082 }
1083
1084 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
1085 .hw_params = sun4i_i2s_hw_params,
1086 .set_fmt = sun4i_i2s_set_fmt,
1087 .set_sysclk = sun4i_i2s_set_sysclk,
1088 .set_tdm_slot = sun4i_i2s_set_tdm_slot,
1089 .trigger = sun4i_i2s_trigger,
1090 };
1091
1092 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
1093 {
1094 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1095
1096 snd_soc_dai_init_dma_data(dai,
1097 &i2s->playback_dma_data,
1098 &i2s->capture_dma_data);
1099
1100 return 0;
1101 }
1102
1103 #define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
1104 SNDRV_PCM_FMTBIT_S20_LE | \
1105 SNDRV_PCM_FMTBIT_S24_LE)
1106
1107 static struct snd_soc_dai_driver sun4i_i2s_dai = {
1108 .probe = sun4i_i2s_dai_probe,
1109 .capture = {
1110 .stream_name = "Capture",
1111 .channels_min = 1,
1112 .channels_max = 8,
1113 .rates = SNDRV_PCM_RATE_8000_192000,
1114 .formats = SUN4I_FORMATS,
1115 },
1116 .playback = {
1117 .stream_name = "Playback",
1118 .channels_min = 1,
1119 .channels_max = 8,
1120 .rates = SNDRV_PCM_RATE_8000_192000,
1121 .formats = SUN4I_FORMATS,
1122 },
1123 .ops = &sun4i_i2s_dai_ops,
1124 .symmetric_rate = 1,
1125 };
1126
1127 static const struct snd_soc_component_driver sun4i_i2s_component = {
1128 .name = "sun4i-dai",
1129 .legacy_dai_naming = 1,
1130 };
1131
1132 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
1133 {
1134 switch (reg) {
1135 case SUN4I_I2S_FIFO_TX_REG:
1136 return false;
1137
1138 default:
1139 return true;
1140 }
1141 }
1142
1143 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
1144 {
1145 switch (reg) {
1146 case SUN4I_I2S_FIFO_RX_REG:
1147 case SUN4I_I2S_FIFO_STA_REG:
1148 return false;
1149
1150 default:
1151 return true;
1152 }
1153 }
1154
1155 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1156 {
1157 switch (reg) {
1158 case SUN4I_I2S_FIFO_RX_REG:
1159 case SUN4I_I2S_INT_STA_REG:
1160 case SUN4I_I2S_RX_CNT_REG:
1161 case SUN4I_I2S_TX_CNT_REG:
1162 return true;
1163
1164 default:
1165 return false;
1166 }
1167 }
1168
1169 static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
1170 {
1171 switch (reg) {
1172 case SUN8I_I2S_FIFO_TX_REG:
1173 return false;
1174
1175 default:
1176 return true;
1177 }
1178 }
1179
1180 static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1181 {
1182 switch (reg) {
1183 case SUN4I_I2S_FIFO_CTRL_REG:
1184 case SUN4I_I2S_FIFO_RX_REG:
1185 case SUN4I_I2S_FIFO_STA_REG:
1186 case SUN4I_I2S_RX_CNT_REG:
1187 case SUN4I_I2S_TX_CNT_REG:
1188 case SUN8I_I2S_FIFO_TX_REG:
1189 case SUN8I_I2S_INT_STA_REG:
1190 return true;
1191
1192 default:
1193 return false;
1194 }
1195 }
1196
1197 static const struct reg_default sun4i_i2s_reg_defaults[] = {
1198 { SUN4I_I2S_CTRL_REG, 0x00000000 },
1199 { SUN4I_I2S_FMT0_REG, 0x0000000c },
1200 { SUN4I_I2S_FMT1_REG, 0x00004020 },
1201 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1202 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1203 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1204 { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
1205 { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
1206 { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
1207 { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
1208 };
1209
1210 static const struct reg_default sun8i_i2s_reg_defaults[] = {
1211 { SUN4I_I2S_CTRL_REG, 0x00060000 },
1212 { SUN4I_I2S_FMT0_REG, 0x00000033 },
1213 { SUN4I_I2S_FMT1_REG, 0x00000030 },
1214 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1215 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1216 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1217 { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1218 { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
1219 { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
1220 { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1221 { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
1222 };
1223
1224 static const struct reg_default sun50i_h6_i2s_reg_defaults[] = {
1225 { SUN4I_I2S_CTRL_REG, 0x00060000 },
1226 { SUN4I_I2S_FMT0_REG, 0x00000033 },
1227 { SUN4I_I2S_FMT1_REG, 0x00000030 },
1228 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1229 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1230 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1231 { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1232 { SUN50I_H6_I2S_TX_CHAN_SEL_REG(0), 0x00000000 },
1233 { SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0x00000000 },
1234 { SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x00000000 },
1235 { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1236 { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
1237 { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
1238 };
1239
1240 static const struct regmap_config sun4i_i2s_regmap_config = {
1241 .reg_bits = 32,
1242 .reg_stride = 4,
1243 .val_bits = 32,
1244 .max_register = SUN4I_I2S_RX_CHAN_MAP_REG,
1245
1246 .cache_type = REGCACHE_FLAT,
1247 .reg_defaults = sun4i_i2s_reg_defaults,
1248 .num_reg_defaults = ARRAY_SIZE(sun4i_i2s_reg_defaults),
1249 .writeable_reg = sun4i_i2s_wr_reg,
1250 .readable_reg = sun4i_i2s_rd_reg,
1251 .volatile_reg = sun4i_i2s_volatile_reg,
1252 };
1253
1254 static const struct regmap_config sun8i_i2s_regmap_config = {
1255 .reg_bits = 32,
1256 .reg_stride = 4,
1257 .val_bits = 32,
1258 .max_register = SUN8I_I2S_RX_CHAN_MAP_REG,
1259 .cache_type = REGCACHE_FLAT,
1260 .reg_defaults = sun8i_i2s_reg_defaults,
1261 .num_reg_defaults = ARRAY_SIZE(sun8i_i2s_reg_defaults),
1262 .writeable_reg = sun4i_i2s_wr_reg,
1263 .readable_reg = sun8i_i2s_rd_reg,
1264 .volatile_reg = sun8i_i2s_volatile_reg,
1265 };
1266
1267 static const struct regmap_config sun50i_h6_i2s_regmap_config = {
1268 .reg_bits = 32,
1269 .reg_stride = 4,
1270 .val_bits = 32,
1271 .max_register = SUN50I_R329_I2S_RX_CHAN_MAP3_REG,
1272 .cache_type = REGCACHE_FLAT,
1273 .reg_defaults = sun50i_h6_i2s_reg_defaults,
1274 .num_reg_defaults = ARRAY_SIZE(sun50i_h6_i2s_reg_defaults),
1275 .writeable_reg = sun4i_i2s_wr_reg,
1276 .readable_reg = sun8i_i2s_rd_reg,
1277 .volatile_reg = sun8i_i2s_volatile_reg,
1278 };
1279
1280 static int sun4i_i2s_runtime_resume(struct device *dev)
1281 {
1282 struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1283 int ret;
1284
1285 ret = clk_prepare_enable(i2s->bus_clk);
1286 if (ret) {
1287 dev_err(dev, "Failed to enable bus clock\n");
1288 return ret;
1289 }
1290
1291 regcache_cache_only(i2s->regmap, false);
1292 regcache_mark_dirty(i2s->regmap);
1293
1294 ret = regcache_sync(i2s->regmap);
1295 if (ret) {
1296 dev_err(dev, "Failed to sync regmap cache\n");
1297 goto err_disable_clk;
1298 }
1299
1300
1301 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1302 SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
1303
1304
1305 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1306 SUN4I_I2S_CTRL_SDO_EN_MASK,
1307 SUN4I_I2S_CTRL_SDO_EN(0));
1308
1309 ret = clk_prepare_enable(i2s->mod_clk);
1310 if (ret) {
1311 dev_err(dev, "Failed to enable module clock\n");
1312 goto err_disable_clk;
1313 }
1314
1315 return 0;
1316
1317 err_disable_clk:
1318 clk_disable_unprepare(i2s->bus_clk);
1319 return ret;
1320 }
1321
1322 static int sun4i_i2s_runtime_suspend(struct device *dev)
1323 {
1324 struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1325
1326 clk_disable_unprepare(i2s->mod_clk);
1327
1328
1329 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1330 SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
1331
1332
1333 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1334 SUN4I_I2S_CTRL_GL_EN, 0);
1335
1336 regcache_cache_only(i2s->regmap, true);
1337
1338 clk_disable_unprepare(i2s->bus_clk);
1339
1340 return 0;
1341 }
1342
1343 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
1344 .has_reset = false,
1345 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG,
1346 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
1347 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1348 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1349 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1350 .bclk_dividers = sun4i_i2s_bclk_div,
1351 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
1352 .mclk_dividers = sun4i_i2s_mclk_div,
1353 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
1354 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
1355 .get_sr = sun4i_i2s_get_sr,
1356 .get_wss = sun4i_i2s_get_wss,
1357 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1358 .set_fmt = sun4i_i2s_set_soc_fmt,
1359 };
1360
1361 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
1362 .has_reset = true,
1363 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG,
1364 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
1365 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1366 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1367 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1368 .bclk_dividers = sun4i_i2s_bclk_div,
1369 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
1370 .mclk_dividers = sun4i_i2s_mclk_div,
1371 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
1372 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
1373 .get_sr = sun4i_i2s_get_sr,
1374 .get_wss = sun4i_i2s_get_wss,
1375 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1376 .set_fmt = sun4i_i2s_set_soc_fmt,
1377 };
1378
1379
1380
1381
1382
1383
1384 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1385 .has_reset = true,
1386 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
1387 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
1388 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1389 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1390 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1391 .bclk_dividers = sun4i_i2s_bclk_div,
1392 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
1393 .mclk_dividers = sun4i_i2s_mclk_div,
1394 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
1395 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
1396 .get_sr = sun4i_i2s_get_sr,
1397 .get_wss = sun4i_i2s_get_wss,
1398 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1399 .set_fmt = sun4i_i2s_set_soc_fmt,
1400 };
1401
1402 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1403 .has_reset = true,
1404 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
1405 .sun4i_i2s_regmap = &sun8i_i2s_regmap_config,
1406 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1407 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1408 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1409 .bclk_dividers = sun8i_i2s_clk_div,
1410 .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1411 .mclk_dividers = sun8i_i2s_clk_div,
1412 .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1413 .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
1414 .get_sr = sun8i_i2s_get_sr_wss,
1415 .get_wss = sun8i_i2s_get_sr_wss,
1416 .set_chan_cfg = sun8i_i2s_set_chan_cfg,
1417 .set_fmt = sun8i_i2s_set_soc_fmt,
1418 };
1419
1420 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1421 .has_reset = true,
1422 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
1423 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
1424 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1425 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1426 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1427 .bclk_dividers = sun4i_i2s_bclk_div,
1428 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
1429 .mclk_dividers = sun4i_i2s_mclk_div,
1430 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
1431 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
1432 .get_sr = sun4i_i2s_get_sr,
1433 .get_wss = sun4i_i2s_get_wss,
1434 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1435 .set_fmt = sun4i_i2s_set_soc_fmt,
1436 };
1437
1438 static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
1439 .has_reset = true,
1440 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
1441 .sun4i_i2s_regmap = &sun50i_h6_i2s_regmap_config,
1442 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1443 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1444 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1445 .bclk_dividers = sun8i_i2s_clk_div,
1446 .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1447 .mclk_dividers = sun8i_i2s_clk_div,
1448 .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1449 .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
1450 .get_sr = sun8i_i2s_get_sr_wss,
1451 .get_wss = sun8i_i2s_get_sr_wss,
1452 .set_chan_cfg = sun50i_h6_i2s_set_chan_cfg,
1453 .set_fmt = sun50i_h6_i2s_set_soc_fmt,
1454 };
1455
1456 static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
1457 .has_reset = true,
1458 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
1459 .sun4i_i2s_regmap = &sun50i_h6_i2s_regmap_config,
1460 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1461 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1462 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1463 .num_din_pins = 4,
1464 .num_dout_pins = 4,
1465 .bclk_dividers = sun8i_i2s_clk_div,
1466 .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1467 .mclk_dividers = sun8i_i2s_clk_div,
1468 .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
1469 .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
1470 .get_sr = sun8i_i2s_get_sr_wss,
1471 .get_wss = sun8i_i2s_get_sr_wss,
1472 .set_chan_cfg = sun50i_h6_i2s_set_chan_cfg,
1473 .set_fmt = sun50i_h6_i2s_set_soc_fmt,
1474 };
1475
1476 static int sun4i_i2s_init_regmap_fields(struct device *dev,
1477 struct sun4i_i2s *i2s)
1478 {
1479 i2s->field_clkdiv_mclk_en =
1480 devm_regmap_field_alloc(dev, i2s->regmap,
1481 i2s->variant->field_clkdiv_mclk_en);
1482 if (IS_ERR(i2s->field_clkdiv_mclk_en))
1483 return PTR_ERR(i2s->field_clkdiv_mclk_en);
1484
1485 i2s->field_fmt_wss =
1486 devm_regmap_field_alloc(dev, i2s->regmap,
1487 i2s->variant->field_fmt_wss);
1488 if (IS_ERR(i2s->field_fmt_wss))
1489 return PTR_ERR(i2s->field_fmt_wss);
1490
1491 i2s->field_fmt_sr =
1492 devm_regmap_field_alloc(dev, i2s->regmap,
1493 i2s->variant->field_fmt_sr);
1494 if (IS_ERR(i2s->field_fmt_sr))
1495 return PTR_ERR(i2s->field_fmt_sr);
1496
1497 return 0;
1498 }
1499
1500 static int sun4i_i2s_probe(struct platform_device *pdev)
1501 {
1502 struct sun4i_i2s *i2s;
1503 struct resource *res;
1504 void __iomem *regs;
1505 int irq, ret;
1506
1507 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
1508 if (!i2s)
1509 return -ENOMEM;
1510 platform_set_drvdata(pdev, i2s);
1511
1512 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1513 if (IS_ERR(regs))
1514 return PTR_ERR(regs);
1515
1516 irq = platform_get_irq(pdev, 0);
1517 if (irq < 0)
1518 return irq;
1519
1520 i2s->variant = of_device_get_match_data(&pdev->dev);
1521 if (!i2s->variant) {
1522 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1523 return -ENODEV;
1524 }
1525
1526 i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
1527 if (IS_ERR(i2s->bus_clk)) {
1528 dev_err(&pdev->dev, "Can't get our bus clock\n");
1529 return PTR_ERR(i2s->bus_clk);
1530 }
1531
1532 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1533 i2s->variant->sun4i_i2s_regmap);
1534 if (IS_ERR(i2s->regmap)) {
1535 dev_err(&pdev->dev, "Regmap initialisation failed\n");
1536 return PTR_ERR(i2s->regmap);
1537 }
1538
1539 i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
1540 if (IS_ERR(i2s->mod_clk)) {
1541 dev_err(&pdev->dev, "Can't get our mod clock\n");
1542 return PTR_ERR(i2s->mod_clk);
1543 }
1544
1545 if (i2s->variant->has_reset) {
1546 i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
1547 if (IS_ERR(i2s->rst)) {
1548 dev_err(&pdev->dev, "Failed to get reset control\n");
1549 return PTR_ERR(i2s->rst);
1550 }
1551 }
1552
1553 if (!IS_ERR(i2s->rst)) {
1554 ret = reset_control_deassert(i2s->rst);
1555 if (ret) {
1556 dev_err(&pdev->dev,
1557 "Failed to deassert the reset control\n");
1558 return -EINVAL;
1559 }
1560 }
1561
1562 i2s->playback_dma_data.addr = res->start +
1563 i2s->variant->reg_offset_txdata;
1564 i2s->playback_dma_data.maxburst = 8;
1565
1566 i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
1567 i2s->capture_dma_data.maxburst = 8;
1568
1569 pm_runtime_enable(&pdev->dev);
1570 if (!pm_runtime_enabled(&pdev->dev)) {
1571 ret = sun4i_i2s_runtime_resume(&pdev->dev);
1572 if (ret)
1573 goto err_pm_disable;
1574 }
1575
1576 ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
1577 if (ret) {
1578 dev_err(&pdev->dev, "Could not initialise regmap fields\n");
1579 goto err_suspend;
1580 }
1581
1582 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1583 if (ret) {
1584 dev_err(&pdev->dev, "Could not register PCM\n");
1585 goto err_suspend;
1586 }
1587
1588 ret = devm_snd_soc_register_component(&pdev->dev,
1589 &sun4i_i2s_component,
1590 &sun4i_i2s_dai, 1);
1591 if (ret) {
1592 dev_err(&pdev->dev, "Could not register DAI\n");
1593 goto err_suspend;
1594 }
1595
1596 return 0;
1597
1598 err_suspend:
1599 if (!pm_runtime_status_suspended(&pdev->dev))
1600 sun4i_i2s_runtime_suspend(&pdev->dev);
1601 err_pm_disable:
1602 pm_runtime_disable(&pdev->dev);
1603 if (!IS_ERR(i2s->rst))
1604 reset_control_assert(i2s->rst);
1605
1606 return ret;
1607 }
1608
1609 static int sun4i_i2s_remove(struct platform_device *pdev)
1610 {
1611 struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1612
1613 pm_runtime_disable(&pdev->dev);
1614 if (!pm_runtime_status_suspended(&pdev->dev))
1615 sun4i_i2s_runtime_suspend(&pdev->dev);
1616
1617 if (!IS_ERR(i2s->rst))
1618 reset_control_assert(i2s->rst);
1619
1620 return 0;
1621 }
1622
1623 static const struct of_device_id sun4i_i2s_match[] = {
1624 {
1625 .compatible = "allwinner,sun4i-a10-i2s",
1626 .data = &sun4i_a10_i2s_quirks,
1627 },
1628 {
1629 .compatible = "allwinner,sun6i-a31-i2s",
1630 .data = &sun6i_a31_i2s_quirks,
1631 },
1632 {
1633 .compatible = "allwinner,sun8i-a83t-i2s",
1634 .data = &sun8i_a83t_i2s_quirks,
1635 },
1636 {
1637 .compatible = "allwinner,sun8i-h3-i2s",
1638 .data = &sun8i_h3_i2s_quirks,
1639 },
1640 {
1641 .compatible = "allwinner,sun50i-a64-codec-i2s",
1642 .data = &sun50i_a64_codec_i2s_quirks,
1643 },
1644 {
1645 .compatible = "allwinner,sun50i-h6-i2s",
1646 .data = &sun50i_h6_i2s_quirks,
1647 },
1648 {
1649 .compatible = "allwinner,sun50i-r329-i2s",
1650 .data = &sun50i_r329_i2s_quirks,
1651 },
1652 {}
1653 };
1654 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1655
1656 static const struct dev_pm_ops sun4i_i2s_pm_ops = {
1657 .runtime_resume = sun4i_i2s_runtime_resume,
1658 .runtime_suspend = sun4i_i2s_runtime_suspend,
1659 };
1660
1661 static struct platform_driver sun4i_i2s_driver = {
1662 .probe = sun4i_i2s_probe,
1663 .remove = sun4i_i2s_remove,
1664 .driver = {
1665 .name = "sun4i-i2s",
1666 .of_match_table = sun4i_i2s_match,
1667 .pm = &sun4i_i2s_pm_ops,
1668 },
1669 };
1670 module_platform_driver(sun4i_i2s_driver);
1671
1672 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1673 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1674 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1675 MODULE_LICENSE("GPL");