Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2015 Andrea Venturi
0004  * Andrea Venturi <be17068@iperbole.bo.it>
0005  *
0006  * Copyright (C) 2016 Maxime Ripard
0007  * Maxime Ripard <maxime.ripard@free-electrons.com>
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 /* Defines required for sun8i-h3 support */
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 /* Defines required for sun50i-h6 support */
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  * struct sun4i_i2s_quirks - Differences between SoC variants.
0158  * @has_reset: SoC needs reset deasserted.
0159  * @reg_offset_txdata: offset of the tx fifo.
0160  * @sun4i_i2s_regmap: regmap config to use.
0161  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
0162  * @field_fmt_wss: regmap field to set word select size.
0163  * @field_fmt_sr: regmap field to set sample resolution.
0164  * @num_din_pins: input pins
0165  * @num_dout_pins: output pins (currently set but unused)
0166  * @bclk_dividers: bit clock dividers array
0167  * @num_bclk_dividers: number of bit clock dividers
0168  * @mclk_dividers: mclk dividers array
0169  * @num_mclk_dividers: number of mclk dividers
0170  * @get_bclk_parent_rate: callback to get bclk parent rate
0171  * @get_sr: callback to get sample resolution
0172  * @get_wss: callback to get word select size
0173  * @set_chan_cfg: callback to set channel configuration
0174  * @set_fmt: callback to set format
0175  */
0176 struct sun4i_i2s_quirks {
0177     bool                has_reset;
0178     unsigned int            reg_offset_txdata;  /* TX FIFO */
0179     const struct regmap_config  *sun4i_i2s_regmap;
0180 
0181     /* Register fields for i2s */
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      * In the set_chan_cfg() function pointer:
0200      * @slots: channels per frame + padding slots, regardless of format
0201      * @slot_width: bits per sample + padding bits, regardless of format
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     /* Register fields for i2s */
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     /* TODO - extend divide ratio supported by newer SoCs */
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     /* TODO - extend divide ratio supported by newer SoCs */
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 = &dividers[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 = &dividers[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     /* Map the channels for playback and capture */
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     /* Configure the channels */
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     /* Map the channels for playback and capture */
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     /* Configure the channels */
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     /* Map the channels for playback and capture */
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     /* Configure the channels */
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     /* Set significant bits in our FIFOs */
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     /* DAI clock polarity */
0659     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0660     case SND_SOC_DAIFMT_IB_IF:
0661         /* Invert both clocks */
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         /* Invert bit clock */
0667         val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0668         break;
0669     case SND_SOC_DAIFMT_NB_IF:
0670         /* Invert frame clock */
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     /* DAI Mode */
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     /* DAI clock master masks */
0707     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0708     case SND_SOC_DAIFMT_BP_FP:
0709         /* BCLK and LRCLK master */
0710         val = SUN4I_I2S_CTRL_MODE_MASTER;
0711         break;
0712 
0713     case SND_SOC_DAIFMT_BC_FC:
0714         /* BCLK and LRCLK slave */
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      * DAI clock polarity
0735      *
0736      * The setup for LRCK contradicts the datasheet, but under a
0737      * scope it's clear that the LRCK polarity is reversed
0738      * compared to the expected polarity on the bus.
0739      */
0740     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0741     case SND_SOC_DAIFMT_IB_IF:
0742         /* Invert both clocks */
0743         val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0744         break;
0745     case SND_SOC_DAIFMT_IB_NF:
0746         /* Invert bit clock */
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         /* Invert frame clock */
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     /* DAI Mode */
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     /* DAI clock master masks */
0807     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0808     case SND_SOC_DAIFMT_BP_FP:
0809         /* BCLK and LRCLK master */
0810         val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
0811         break;
0812 
0813     case SND_SOC_DAIFMT_BC_FC:
0814         /* BCLK and LRCLK slave */
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     /* Set sign extension to pad out LSB with 0 */
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      * DAI clock polarity
0842      *
0843      * The setup for LRCK contradicts the datasheet, but under a
0844      * scope it's clear that the LRCK polarity is reversed
0845      * compared to the expected polarity on the bus.
0846      */
0847     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0848     case SND_SOC_DAIFMT_IB_IF:
0849         /* Invert both clocks */
0850         val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
0851         break;
0852     case SND_SOC_DAIFMT_IB_NF:
0853         /* Invert bit clock */
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         /* Invert frame clock */
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     /* DAI Mode */
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     /* DAI clock master masks */
0914     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0915     case SND_SOC_DAIFMT_BP_FP:
0916         /* BCLK and LRCLK master */
0917         val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
0918         break;
0919 
0920     case SND_SOC_DAIFMT_BC_FC:
0921         /* BCLK and LRCLK slave */
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     /* Set sign extension to pad out LSB with 0 */
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     /* Flush RX FIFO */
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     /* Clear RX counter */
0965     regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
0966 
0967     /* Enable RX Block */
0968     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0969                SUN4I_I2S_CTRL_RX_EN,
0970                SUN4I_I2S_CTRL_RX_EN);
0971 
0972     /* Enable RX DRQ */
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     /* Flush TX FIFO */
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     /* Clear TX counter */
0986     regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
0987 
0988     /* Enable TX Block */
0989     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
0990                SUN4I_I2S_CTRL_TX_EN,
0991                SUN4I_I2S_CTRL_TX_EN);
0992 
0993     /* Enable TX DRQ */
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     /* Disable RX Block */
1002     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1003                SUN4I_I2S_CTRL_RX_EN,
1004                0);
1005 
1006     /* Disable RX DRQ */
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     /* Disable TX Block */
1015     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1016                SUN4I_I2S_CTRL_TX_EN,
1017                0);
1018 
1019     /* Disable TX DRQ */
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     /* Enable the whole hardware block */
1301     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1302                SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
1303 
1304     /* Enable the first output line */
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     /* Disable our output lines */
1329     regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1330                SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
1331 
1332     /* Disable the whole hardware block */
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  * This doesn't describe the TDM controller documented in the A83t
1381  * datasheet, but the three undocumented I2S controller that use the
1382  * older design.
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");