root/sound/soc/sunxi/sun4i-i2s.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sun4i_i2s_get_bclk_parent_rate
  2. sun8i_i2s_get_bclk_parent_rate
  3. sun4i_i2s_get_bclk_div
  4. sun4i_i2s_get_mclk_div
  5. sun4i_i2s_oversample_is_valid
  6. sun4i_i2s_set_clk_rate
  7. sun4i_i2s_get_sr
  8. sun4i_i2s_get_wss
  9. sun8i_i2s_get_sr_wss
  10. sun4i_i2s_set_chan_cfg
  11. sun8i_i2s_set_chan_cfg
  12. sun4i_i2s_hw_params
  13. sun4i_i2s_set_soc_fmt
  14. sun8i_i2s_set_soc_fmt
  15. sun4i_i2s_set_fmt
  16. sun4i_i2s_start_capture
  17. sun4i_i2s_start_playback
  18. sun4i_i2s_stop_capture
  19. sun4i_i2s_stop_playback
  20. sun4i_i2s_trigger
  21. sun4i_i2s_set_sysclk
  22. sun4i_i2s_set_tdm_slot
  23. sun4i_i2s_dai_probe
  24. sun4i_i2s_rd_reg
  25. sun4i_i2s_wr_reg
  26. sun4i_i2s_volatile_reg
  27. sun8i_i2s_rd_reg
  28. sun8i_i2s_volatile_reg
  29. sun4i_i2s_runtime_resume
  30. sun4i_i2s_runtime_suspend
  31. sun4i_i2s_init_regmap_fields
  32. sun4i_i2s_probe
  33. sun4i_i2s_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2015 Andrea Venturi
   4  * Andrea Venturi <be17068@iperbole.bo.it>
   5  *
   6  * Copyright (C) 2016 Maxime Ripard
   7  * Maxime Ripard <maxime.ripard@free-electrons.com>
   8  */
   9 
  10 #include <linux/clk.h>
  11 #include <linux/dmaengine.h>
  12 #include <linux/module.h>
  13 #include <linux/of_device.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/pm_runtime.h>
  16 #include <linux/regmap.h>
  17 #include <linux/reset.h>
  18 
  19 #include <sound/dmaengine_pcm.h>
  20 #include <sound/pcm_params.h>
  21 #include <sound/soc.h>
  22 #include <sound/soc-dai.h>
  23 
  24 #define SUN4I_I2S_CTRL_REG              0x00
  25 #define SUN4I_I2S_CTRL_SDO_EN_MASK              GENMASK(11, 8)
  26 #define SUN4I_I2S_CTRL_SDO_EN(sdo)                      BIT(8 + (sdo))
  27 #define SUN4I_I2S_CTRL_MODE_MASK                BIT(5)
  28 #define SUN4I_I2S_CTRL_MODE_SLAVE                       (1 << 5)
  29 #define SUN4I_I2S_CTRL_MODE_MASTER                      (0 << 5)
  30 #define SUN4I_I2S_CTRL_TX_EN                    BIT(2)
  31 #define SUN4I_I2S_CTRL_RX_EN                    BIT(1)
  32 #define SUN4I_I2S_CTRL_GL_EN                    BIT(0)
  33 
  34 #define SUN4I_I2S_FMT0_REG              0x04
  35 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(7)
  36 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED          (1 << 7)
  37 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL            (0 << 7)
  38 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(6)
  39 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 6)
  40 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 6)
  41 #define SUN4I_I2S_FMT0_SR_MASK                  GENMASK(5, 4)
  42 #define SUN4I_I2S_FMT0_SR(sr)                           ((sr) << 4)
  43 #define SUN4I_I2S_FMT0_WSS_MASK                 GENMASK(3, 2)
  44 #define SUN4I_I2S_FMT0_WSS(wss)                         ((wss) << 2)
  45 #define SUN4I_I2S_FMT0_FMT_MASK                 GENMASK(1, 0)
  46 #define SUN4I_I2S_FMT0_FMT_RIGHT_J                      (2 << 0)
  47 #define SUN4I_I2S_FMT0_FMT_LEFT_J                       (1 << 0)
  48 #define SUN4I_I2S_FMT0_FMT_I2S                          (0 << 0)
  49 
  50 #define SUN4I_I2S_FMT1_REG              0x08
  51 #define SUN4I_I2S_FIFO_TX_REG           0x0c
  52 #define SUN4I_I2S_FIFO_RX_REG           0x10
  53 
  54 #define SUN4I_I2S_FIFO_CTRL_REG         0x14
  55 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX            BIT(25)
  56 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX            BIT(24)
  57 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK        BIT(2)
  58 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)               ((mode) << 2)
  59 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK        GENMASK(1, 0)
  60 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)               (mode)
  61 
  62 #define SUN4I_I2S_FIFO_STA_REG          0x18
  63 
  64 #define SUN4I_I2S_DMA_INT_CTRL_REG      0x1c
  65 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN        BIT(7)
  66 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN        BIT(3)
  67 
  68 #define SUN4I_I2S_INT_STA_REG           0x20
  69 
  70 #define SUN4I_I2S_CLK_DIV_REG           0x24
  71 #define SUN4I_I2S_CLK_DIV_MCLK_EN               BIT(7)
  72 #define SUN4I_I2S_CLK_DIV_BCLK_MASK             GENMASK(6, 4)
  73 #define SUN4I_I2S_CLK_DIV_BCLK(bclk)                    ((bclk) << 4)
  74 #define SUN4I_I2S_CLK_DIV_MCLK_MASK             GENMASK(3, 0)
  75 #define SUN4I_I2S_CLK_DIV_MCLK(mclk)                    ((mclk) << 0)
  76 
  77 #define SUN4I_I2S_TX_CNT_REG            0x28
  78 #define SUN4I_I2S_RX_CNT_REG            0x2c
  79 
  80 #define SUN4I_I2S_TX_CHAN_SEL_REG       0x30
  81 #define SUN4I_I2S_CHAN_SEL_MASK                 GENMASK(2, 0)
  82 #define SUN4I_I2S_CHAN_SEL(num_chan)            (((num_chan) - 1) << 0)
  83 
  84 #define SUN4I_I2S_TX_CHAN_MAP_REG       0x34
  85 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample)     ((sample) << (chan << 2))
  86 
  87 #define SUN4I_I2S_RX_CHAN_SEL_REG       0x38
  88 #define SUN4I_I2S_RX_CHAN_MAP_REG       0x3c
  89 
  90 /* Defines required for sun8i-h3 support */
  91 #define SUN8I_I2S_CTRL_BCLK_OUT                 BIT(18)
  92 #define SUN8I_I2S_CTRL_LRCK_OUT                 BIT(17)
  93 
  94 #define SUN8I_I2S_CTRL_MODE_MASK                GENMASK(5, 4)
  95 #define SUN8I_I2S_CTRL_MODE_RIGHT               (2 << 4)
  96 #define SUN8I_I2S_CTRL_MODE_LEFT                (1 << 4)
  97 #define SUN8I_I2S_CTRL_MODE_PCM                 (0 << 4)
  98 
  99 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(19)
 100 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED          (1 << 19)
 101 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL            (0 << 19)
 102 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK         GENMASK(17, 8)
 103 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)      ((period - 1) << 8)
 104 #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(7)
 105 #define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 7)
 106 #define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 7)
 107 
 108 #define SUN8I_I2S_INT_STA_REG           0x0c
 109 #define SUN8I_I2S_FIFO_TX_REG           0x20
 110 
 111 #define SUN8I_I2S_CHAN_CFG_REG          0x30
 112 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK     GENMASK(6, 4)
 113 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)    ((chan - 1) << 4)
 114 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK     GENMASK(2, 0)
 115 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)    (chan - 1)
 116 
 117 #define SUN8I_I2S_TX_CHAN_MAP_REG       0x44
 118 #define SUN8I_I2S_TX_CHAN_SEL_REG       0x34
 119 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK           GENMASK(13, 12)
 120 #define SUN8I_I2S_TX_CHAN_OFFSET(offset)        (offset << 12)
 121 #define SUN8I_I2S_TX_CHAN_EN_MASK               GENMASK(11, 4)
 122 #define SUN8I_I2S_TX_CHAN_EN(num_chan)          (((1 << num_chan) - 1) << 4)
 123 
 124 #define SUN8I_I2S_RX_CHAN_SEL_REG       0x54
 125 #define SUN8I_I2S_RX_CHAN_MAP_REG       0x58
 126 
 127 struct sun4i_i2s;
 128 
 129 /**
 130  * struct sun4i_i2s_quirks - Differences between SoC variants.
 131  *
 132  * @has_reset: SoC needs reset deasserted.
 133  * @reg_offset_txdata: offset of the tx fifo.
 134  * @sun4i_i2s_regmap: regmap config to use.
 135  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
 136  * @field_fmt_wss: regmap field to set word select size.
 137  * @field_fmt_sr: regmap field to set sample resolution.
 138  */
 139 struct sun4i_i2s_quirks {
 140         bool                            has_reset;
 141         unsigned int                    reg_offset_txdata;      /* TX FIFO */
 142         const struct regmap_config      *sun4i_i2s_regmap;
 143 
 144         /* Register fields for i2s */
 145         struct reg_field                field_clkdiv_mclk_en;
 146         struct reg_field                field_fmt_wss;
 147         struct reg_field                field_fmt_sr;
 148 
 149         const struct sun4i_i2s_clk_div  *bclk_dividers;
 150         unsigned int                    num_bclk_dividers;
 151         const struct sun4i_i2s_clk_div  *mclk_dividers;
 152         unsigned int                    num_mclk_dividers;
 153 
 154         unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
 155         s8      (*get_sr)(const struct sun4i_i2s *, int);
 156         s8      (*get_wss)(const struct sun4i_i2s *, int);
 157         int     (*set_chan_cfg)(const struct sun4i_i2s *,
 158                                 const struct snd_pcm_hw_params *);
 159         int     (*set_fmt)(const struct sun4i_i2s *, unsigned int);
 160 };
 161 
 162 struct sun4i_i2s {
 163         struct clk      *bus_clk;
 164         struct clk      *mod_clk;
 165         struct regmap   *regmap;
 166         struct reset_control *rst;
 167 
 168         unsigned int    format;
 169         unsigned int    mclk_freq;
 170         unsigned int    slots;
 171         unsigned int    slot_width;
 172 
 173         struct snd_dmaengine_dai_dma_data       capture_dma_data;
 174         struct snd_dmaengine_dai_dma_data       playback_dma_data;
 175 
 176         /* Register fields for i2s */
 177         struct regmap_field     *field_clkdiv_mclk_en;
 178         struct regmap_field     *field_fmt_wss;
 179         struct regmap_field     *field_fmt_sr;
 180 
 181         const struct sun4i_i2s_quirks   *variant;
 182 };
 183 
 184 struct sun4i_i2s_clk_div {
 185         u8      div;
 186         u8      val;
 187 };
 188 
 189 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 190         { .div = 2, .val = 0 },
 191         { .div = 4, .val = 1 },
 192         { .div = 6, .val = 2 },
 193         { .div = 8, .val = 3 },
 194         { .div = 12, .val = 4 },
 195         { .div = 16, .val = 5 },
 196         /* TODO - extend divide ratio supported by newer SoCs */
 197 };
 198 
 199 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
 200         { .div = 1, .val = 0 },
 201         { .div = 2, .val = 1 },
 202         { .div = 4, .val = 2 },
 203         { .div = 6, .val = 3 },
 204         { .div = 8, .val = 4 },
 205         { .div = 12, .val = 5 },
 206         { .div = 16, .val = 6 },
 207         { .div = 24, .val = 7 },
 208         /* TODO - extend divide ratio supported by newer SoCs */
 209 };
 210 
 211 static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
 212         { .div = 1, .val = 1 },
 213         { .div = 2, .val = 2 },
 214         { .div = 4, .val = 3 },
 215         { .div = 6, .val = 4 },
 216         { .div = 8, .val = 5 },
 217         { .div = 12, .val = 6 },
 218         { .div = 16, .val = 7 },
 219         { .div = 24, .val = 8 },
 220         { .div = 32, .val = 9 },
 221         { .div = 48, .val = 10 },
 222         { .div = 64, .val = 11 },
 223         { .div = 96, .val = 12 },
 224         { .div = 128, .val = 13 },
 225         { .div = 176, .val = 14 },
 226         { .div = 192, .val = 15 },
 227 };
 228 
 229 static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 230 {
 231         return i2s->mclk_freq;
 232 }
 233 
 234 static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 235 {
 236         return clk_get_rate(i2s->mod_clk);
 237 }
 238 
 239 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
 240                                   unsigned long parent_rate,
 241                                   unsigned int sampling_rate,
 242                                   unsigned int channels,
 243                                   unsigned int word_size)
 244 {
 245         const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
 246         int div = parent_rate / sampling_rate / word_size / channels;
 247         int i;
 248 
 249         for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
 250                 const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
 251 
 252                 if (bdiv->div == div)
 253                         return bdiv->val;
 254         }
 255 
 256         return -EINVAL;
 257 }
 258 
 259 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
 260                                   unsigned long parent_rate,
 261                                   unsigned long mclk_rate)
 262 {
 263         const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
 264         int div = parent_rate / mclk_rate;
 265         int i;
 266 
 267         for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
 268                 const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
 269 
 270                 if (mdiv->div == div)
 271                         return mdiv->val;
 272         }
 273 
 274         return -EINVAL;
 275 }
 276 
 277 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
 278 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
 279 {
 280         int i;
 281 
 282         for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
 283                 if (sun4i_i2s_oversample_rates[i] == oversample)
 284                         return true;
 285 
 286         return false;
 287 }
 288 
 289 static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 290                                   unsigned int rate,
 291                                   unsigned int slots,
 292                                   unsigned int slot_width)
 293 {
 294         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 295         unsigned int oversample_rate, clk_rate, bclk_parent_rate;
 296         int bclk_div, mclk_div;
 297         int ret;
 298 
 299         switch (rate) {
 300         case 176400:
 301         case 88200:
 302         case 44100:
 303         case 22050:
 304         case 11025:
 305                 clk_rate = 22579200;
 306                 break;
 307 
 308         case 192000:
 309         case 128000:
 310         case 96000:
 311         case 64000:
 312         case 48000:
 313         case 32000:
 314         case 24000:
 315         case 16000:
 316         case 12000:
 317         case 8000:
 318                 clk_rate = 24576000;
 319                 break;
 320 
 321         default:
 322                 dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
 323                 return -EINVAL;
 324         }
 325 
 326         ret = clk_set_rate(i2s->mod_clk, clk_rate);
 327         if (ret)
 328                 return ret;
 329 
 330         oversample_rate = i2s->mclk_freq / rate;
 331         if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
 332                 dev_err(dai->dev, "Unsupported oversample rate: %d\n",
 333                         oversample_rate);
 334                 return -EINVAL;
 335         }
 336 
 337         bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
 338         bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
 339                                           rate, slots, slot_width);
 340         if (bclk_div < 0) {
 341                 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
 342                 return -EINVAL;
 343         }
 344 
 345         mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
 346         if (mclk_div < 0) {
 347                 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
 348                 return -EINVAL;
 349         }
 350 
 351         regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
 352                      SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
 353                      SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
 354 
 355         regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 356 
 357         return 0;
 358 }
 359 
 360 static s8 sun4i_i2s_get_sr(const struct sun4i_i2s *i2s, int width)
 361 {
 362         if (width < 16 || width > 24)
 363                 return -EINVAL;
 364 
 365         if (width % 4)
 366                 return -EINVAL;
 367 
 368         return (width - 16) / 4;
 369 }
 370 
 371 static s8 sun4i_i2s_get_wss(const struct sun4i_i2s *i2s, int width)
 372 {
 373         if (width < 16 || width > 32)
 374                 return -EINVAL;
 375 
 376         if (width % 4)
 377                 return -EINVAL;
 378 
 379         return (width - 16) / 4;
 380 }
 381 
 382 static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width)
 383 {
 384         if (width % 4)
 385                 return -EINVAL;
 386 
 387         if (width < 8 || width > 32)
 388                 return -EINVAL;
 389 
 390         return (width - 8) / 4 + 1;
 391 }
 392 
 393 static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
 394                                   const struct snd_pcm_hw_params *params)
 395 {
 396         unsigned int channels = params_channels(params);
 397 
 398         /* Map the channels for playback and capture */
 399         regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
 400         regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
 401 
 402         /* Configure the channels */
 403         regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
 404                            SUN4I_I2S_CHAN_SEL_MASK,
 405                            SUN4I_I2S_CHAN_SEL(channels));
 406         regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
 407                            SUN4I_I2S_CHAN_SEL_MASK,
 408                            SUN4I_I2S_CHAN_SEL(channels));
 409 
 410         return 0;
 411 }
 412 
 413 static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
 414                                   const struct snd_pcm_hw_params *params)
 415 {
 416         unsigned int channels = params_channels(params);
 417         unsigned int slots = channels;
 418         unsigned int lrck_period;
 419 
 420         if (i2s->slots)
 421                 slots = i2s->slots;
 422 
 423         /* Map the channels for playback and capture */
 424         regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
 425         regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
 426 
 427         /* Configure the channels */
 428         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 429                            SUN4I_I2S_CHAN_SEL_MASK,
 430                            SUN4I_I2S_CHAN_SEL(channels));
 431         regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
 432                            SUN4I_I2S_CHAN_SEL_MASK,
 433                            SUN4I_I2S_CHAN_SEL(channels));
 434 
 435         regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 436                            SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
 437                            SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
 438         regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 439                            SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
 440                            SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
 441 
 442         switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 443         case SND_SOC_DAIFMT_DSP_A:
 444         case SND_SOC_DAIFMT_DSP_B:
 445         case SND_SOC_DAIFMT_LEFT_J:
 446         case SND_SOC_DAIFMT_RIGHT_J:
 447                 lrck_period = params_physical_width(params) * slots;
 448                 break;
 449 
 450         case SND_SOC_DAIFMT_I2S:
 451                 lrck_period = params_physical_width(params);
 452                 break;
 453 
 454         default:
 455                 return -EINVAL;
 456         }
 457 
 458         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 459                            SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
 460                            SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
 461 
 462         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 463                            SUN8I_I2S_TX_CHAN_EN_MASK,
 464                            SUN8I_I2S_TX_CHAN_EN(channels));
 465 
 466         return 0;
 467 }
 468 
 469 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 470                                struct snd_pcm_hw_params *params,
 471                                struct snd_soc_dai *dai)
 472 {
 473         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 474         unsigned int word_size = params_width(params);
 475         unsigned int slot_width = params_physical_width(params);
 476         unsigned int channels = params_channels(params);
 477         unsigned int slots = channels;
 478         int ret, sr, wss;
 479         u32 width;
 480 
 481         if (i2s->slots)
 482                 slots = i2s->slots;
 483 
 484         if (i2s->slot_width)
 485                 slot_width = i2s->slot_width;
 486 
 487         ret = i2s->variant->set_chan_cfg(i2s, params);
 488         if (ret < 0) {
 489                 dev_err(dai->dev, "Invalid channel configuration\n");
 490                 return ret;
 491         }
 492 
 493         switch (params_physical_width(params)) {
 494         case 16:
 495                 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 496                 break;
 497         default:
 498                 dev_err(dai->dev, "Unsupported physical sample width: %d\n",
 499                         params_physical_width(params));
 500                 return -EINVAL;
 501         }
 502         i2s->playback_dma_data.addr_width = width;
 503 
 504         sr = i2s->variant->get_sr(i2s, word_size);
 505         if (sr < 0)
 506                 return -EINVAL;
 507 
 508         wss = i2s->variant->get_wss(i2s, slot_width);
 509         if (wss < 0)
 510                 return -EINVAL;
 511 
 512         regmap_field_write(i2s->field_fmt_wss, wss);
 513         regmap_field_write(i2s->field_fmt_sr, sr);
 514 
 515         return sun4i_i2s_set_clk_rate(dai, params_rate(params),
 516                                       slots, slot_width);
 517 }
 518 
 519 static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
 520                                  unsigned int fmt)
 521 {
 522         u32 val;
 523 
 524         /* DAI clock polarity */
 525         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 526         case SND_SOC_DAIFMT_IB_IF:
 527                 /* Invert both clocks */
 528                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
 529                       SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 530                 break;
 531         case SND_SOC_DAIFMT_IB_NF:
 532                 /* Invert bit clock */
 533                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 534                 break;
 535         case SND_SOC_DAIFMT_NB_IF:
 536                 /* Invert frame clock */
 537                 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 538                 break;
 539         case SND_SOC_DAIFMT_NB_NF:
 540                 val = 0;
 541                 break;
 542         default:
 543                 return -EINVAL;
 544         }
 545 
 546         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 547                            SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
 548                            SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
 549                            val);
 550 
 551         /* DAI Mode */
 552         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 553         case SND_SOC_DAIFMT_I2S:
 554                 val = SUN4I_I2S_FMT0_FMT_I2S;
 555                 break;
 556 
 557         case SND_SOC_DAIFMT_LEFT_J:
 558                 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
 559                 break;
 560 
 561         case SND_SOC_DAIFMT_RIGHT_J:
 562                 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
 563                 break;
 564 
 565         default:
 566                 return -EINVAL;
 567         }
 568 
 569         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 570                            SUN4I_I2S_FMT0_FMT_MASK, val);
 571 
 572         /* DAI clock master masks */
 573         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 574         case SND_SOC_DAIFMT_CBS_CFS:
 575                 /* BCLK and LRCLK master */
 576                 val = SUN4I_I2S_CTRL_MODE_MASTER;
 577                 break;
 578 
 579         case SND_SOC_DAIFMT_CBM_CFM:
 580                 /* BCLK and LRCLK slave */
 581                 val = SUN4I_I2S_CTRL_MODE_SLAVE;
 582                 break;
 583 
 584         default:
 585                 return -EINVAL;
 586         }
 587         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 588                            SUN4I_I2S_CTRL_MODE_MASK, val);
 589         return 0;
 590 }
 591 
 592 static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
 593                                  unsigned int fmt)
 594 {
 595         u32 mode, val;
 596         u8 offset;
 597 
 598         /*
 599          * DAI clock polarity
 600          *
 601          * The setup for LRCK contradicts the datasheet, but under a
 602          * scope it's clear that the LRCK polarity is reversed
 603          * compared to the expected polarity on the bus.
 604          */
 605         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 606         case SND_SOC_DAIFMT_IB_IF:
 607                 /* Invert both clocks */
 608                 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 609                 break;
 610         case SND_SOC_DAIFMT_IB_NF:
 611                 /* Invert bit clock */
 612                 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
 613                       SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 614                 break;
 615         case SND_SOC_DAIFMT_NB_IF:
 616                 /* Invert frame clock */
 617                 val = 0;
 618                 break;
 619         case SND_SOC_DAIFMT_NB_NF:
 620                 val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 621                 break;
 622         default:
 623                 return -EINVAL;
 624         }
 625 
 626         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 627                            SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
 628                            SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
 629                            val);
 630 
 631         /* DAI Mode */
 632         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 633         case SND_SOC_DAIFMT_DSP_A:
 634                 mode = SUN8I_I2S_CTRL_MODE_PCM;
 635                 offset = 1;
 636                 break;
 637 
 638         case SND_SOC_DAIFMT_DSP_B:
 639                 mode = SUN8I_I2S_CTRL_MODE_PCM;
 640                 offset = 0;
 641                 break;
 642 
 643         case SND_SOC_DAIFMT_I2S:
 644                 mode = SUN8I_I2S_CTRL_MODE_LEFT;
 645                 offset = 1;
 646                 break;
 647 
 648         case SND_SOC_DAIFMT_LEFT_J:
 649                 mode = SUN8I_I2S_CTRL_MODE_LEFT;
 650                 offset = 0;
 651                 break;
 652 
 653         case SND_SOC_DAIFMT_RIGHT_J:
 654                 mode = SUN8I_I2S_CTRL_MODE_RIGHT;
 655                 offset = 0;
 656                 break;
 657 
 658         default:
 659                 return -EINVAL;
 660         }
 661 
 662         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 663                            SUN8I_I2S_CTRL_MODE_MASK, mode);
 664         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 665                            SUN8I_I2S_TX_CHAN_OFFSET_MASK,
 666                            SUN8I_I2S_TX_CHAN_OFFSET(offset));
 667         regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
 668                            SUN8I_I2S_TX_CHAN_OFFSET_MASK,
 669                            SUN8I_I2S_TX_CHAN_OFFSET(offset));
 670 
 671         /* DAI clock master masks */
 672         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 673         case SND_SOC_DAIFMT_CBS_CFS:
 674                 /* BCLK and LRCLK master */
 675                 val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
 676                 break;
 677 
 678         case SND_SOC_DAIFMT_CBM_CFM:
 679                 /* BCLK and LRCLK slave */
 680                 val = 0;
 681                 break;
 682 
 683         default:
 684                 return -EINVAL;
 685         }
 686 
 687         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 688                            SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
 689                            val);
 690 
 691         return 0;
 692 }
 693 
 694 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 695 {
 696         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 697         int ret;
 698 
 699         ret = i2s->variant->set_fmt(i2s, fmt);
 700         if (ret) {
 701                 dev_err(dai->dev, "Unsupported format configuration\n");
 702                 return ret;
 703         }
 704 
 705         /* Set significant bits in our FIFOs */
 706         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 707                            SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
 708                            SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
 709                            SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
 710                            SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
 711 
 712         i2s->format = fmt;
 713 
 714         return 0;
 715 }
 716 
 717 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
 718 {
 719         /* Flush RX FIFO */
 720         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 721                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
 722                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
 723 
 724         /* Clear RX counter */
 725         regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
 726 
 727         /* Enable RX Block */
 728         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 729                            SUN4I_I2S_CTRL_RX_EN,
 730                            SUN4I_I2S_CTRL_RX_EN);
 731 
 732         /* Enable RX DRQ */
 733         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 734                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
 735                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
 736 }
 737 
 738 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 739 {
 740         /* Flush TX FIFO */
 741         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 742                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
 743                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
 744 
 745         /* Clear TX counter */
 746         regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
 747 
 748         /* Enable TX Block */
 749         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 750                            SUN4I_I2S_CTRL_TX_EN,
 751                            SUN4I_I2S_CTRL_TX_EN);
 752 
 753         /* Enable TX DRQ */
 754         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 755                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
 756                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
 757 }
 758 
 759 static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
 760 {
 761         /* Disable RX Block */
 762         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 763                            SUN4I_I2S_CTRL_RX_EN,
 764                            0);
 765 
 766         /* Disable RX DRQ */
 767         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 768                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
 769                            0);
 770 }
 771 
 772 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
 773 {
 774         /* Disable TX Block */
 775         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 776                            SUN4I_I2S_CTRL_TX_EN,
 777                            0);
 778 
 779         /* Disable TX DRQ */
 780         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 781                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
 782                            0);
 783 }
 784 
 785 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 786                              struct snd_soc_dai *dai)
 787 {
 788         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 789 
 790         switch (cmd) {
 791         case SNDRV_PCM_TRIGGER_START:
 792         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 793         case SNDRV_PCM_TRIGGER_RESUME:
 794                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 795                         sun4i_i2s_start_playback(i2s);
 796                 else
 797                         sun4i_i2s_start_capture(i2s);
 798                 break;
 799 
 800         case SNDRV_PCM_TRIGGER_STOP:
 801         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 802         case SNDRV_PCM_TRIGGER_SUSPEND:
 803                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 804                         sun4i_i2s_stop_playback(i2s);
 805                 else
 806                         sun4i_i2s_stop_capture(i2s);
 807                 break;
 808 
 809         default:
 810                 return -EINVAL;
 811         }
 812 
 813         return 0;
 814 }
 815 
 816 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 817                                 unsigned int freq, int dir)
 818 {
 819         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 820 
 821         if (clk_id != 0)
 822                 return -EINVAL;
 823 
 824         i2s->mclk_freq = freq;
 825 
 826         return 0;
 827 }
 828 
 829 static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
 830                                   unsigned int tx_mask, unsigned int rx_mask,
 831                                   int slots, int slot_width)
 832 {
 833         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 834 
 835         if (slots > 8)
 836                 return -EINVAL;
 837 
 838         i2s->slots = slots;
 839         i2s->slot_width = slot_width;
 840 
 841         return 0;
 842 }
 843 
 844 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 845         .hw_params      = sun4i_i2s_hw_params,
 846         .set_fmt        = sun4i_i2s_set_fmt,
 847         .set_sysclk     = sun4i_i2s_set_sysclk,
 848         .set_tdm_slot   = sun4i_i2s_set_tdm_slot,
 849         .trigger        = sun4i_i2s_trigger,
 850 };
 851 
 852 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 853 {
 854         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 855 
 856         snd_soc_dai_init_dma_data(dai,
 857                                   &i2s->playback_dma_data,
 858                                   &i2s->capture_dma_data);
 859 
 860         snd_soc_dai_set_drvdata(dai, i2s);
 861 
 862         return 0;
 863 }
 864 
 865 static struct snd_soc_dai_driver sun4i_i2s_dai = {
 866         .probe = sun4i_i2s_dai_probe,
 867         .capture = {
 868                 .stream_name = "Capture",
 869                 .channels_min = 1,
 870                 .channels_max = 8,
 871                 .rates = SNDRV_PCM_RATE_8000_192000,
 872                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
 873         },
 874         .playback = {
 875                 .stream_name = "Playback",
 876                 .channels_min = 1,
 877                 .channels_max = 8,
 878                 .rates = SNDRV_PCM_RATE_8000_192000,
 879                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
 880         },
 881         .ops = &sun4i_i2s_dai_ops,
 882         .symmetric_rates = 1,
 883 };
 884 
 885 static const struct snd_soc_component_driver sun4i_i2s_component = {
 886         .name   = "sun4i-dai",
 887 };
 888 
 889 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
 890 {
 891         switch (reg) {
 892         case SUN4I_I2S_FIFO_TX_REG:
 893                 return false;
 894 
 895         default:
 896                 return true;
 897         }
 898 }
 899 
 900 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
 901 {
 902         switch (reg) {
 903         case SUN4I_I2S_FIFO_RX_REG:
 904         case SUN4I_I2S_FIFO_STA_REG:
 905                 return false;
 906 
 907         default:
 908                 return true;
 909         }
 910 }
 911 
 912 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 913 {
 914         switch (reg) {
 915         case SUN4I_I2S_FIFO_RX_REG:
 916         case SUN4I_I2S_INT_STA_REG:
 917         case SUN4I_I2S_RX_CNT_REG:
 918         case SUN4I_I2S_TX_CNT_REG:
 919                 return true;
 920 
 921         default:
 922                 return false;
 923         }
 924 }
 925 
 926 static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
 927 {
 928         switch (reg) {
 929         case SUN8I_I2S_FIFO_TX_REG:
 930                 return false;
 931 
 932         default:
 933                 return true;
 934         }
 935 }
 936 
 937 static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 938 {
 939         if (reg == SUN8I_I2S_INT_STA_REG)
 940                 return true;
 941         if (reg == SUN8I_I2S_FIFO_TX_REG)
 942                 return false;
 943 
 944         return sun4i_i2s_volatile_reg(dev, reg);
 945 }
 946 
 947 static const struct reg_default sun4i_i2s_reg_defaults[] = {
 948         { SUN4I_I2S_CTRL_REG, 0x00000000 },
 949         { SUN4I_I2S_FMT0_REG, 0x0000000c },
 950         { SUN4I_I2S_FMT1_REG, 0x00004020 },
 951         { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
 952         { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
 953         { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
 954         { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
 955         { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
 956         { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
 957         { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
 958 };
 959 
 960 static const struct reg_default sun8i_i2s_reg_defaults[] = {
 961         { SUN4I_I2S_CTRL_REG, 0x00060000 },
 962         { SUN4I_I2S_FMT0_REG, 0x00000033 },
 963         { SUN4I_I2S_FMT1_REG, 0x00000030 },
 964         { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
 965         { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
 966         { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
 967         { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
 968         { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
 969         { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
 970         { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
 971         { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
 972 };
 973 
 974 static const struct regmap_config sun4i_i2s_regmap_config = {
 975         .reg_bits       = 32,
 976         .reg_stride     = 4,
 977         .val_bits       = 32,
 978         .max_register   = SUN4I_I2S_RX_CHAN_MAP_REG,
 979 
 980         .cache_type     = REGCACHE_FLAT,
 981         .reg_defaults   = sun4i_i2s_reg_defaults,
 982         .num_reg_defaults       = ARRAY_SIZE(sun4i_i2s_reg_defaults),
 983         .writeable_reg  = sun4i_i2s_wr_reg,
 984         .readable_reg   = sun4i_i2s_rd_reg,
 985         .volatile_reg   = sun4i_i2s_volatile_reg,
 986 };
 987 
 988 static const struct regmap_config sun8i_i2s_regmap_config = {
 989         .reg_bits       = 32,
 990         .reg_stride     = 4,
 991         .val_bits       = 32,
 992         .max_register   = SUN8I_I2S_RX_CHAN_MAP_REG,
 993         .cache_type     = REGCACHE_FLAT,
 994         .reg_defaults   = sun8i_i2s_reg_defaults,
 995         .num_reg_defaults       = ARRAY_SIZE(sun8i_i2s_reg_defaults),
 996         .writeable_reg  = sun4i_i2s_wr_reg,
 997         .readable_reg   = sun8i_i2s_rd_reg,
 998         .volatile_reg   = sun8i_i2s_volatile_reg,
 999 };
1000 
1001 static int sun4i_i2s_runtime_resume(struct device *dev)
1002 {
1003         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1004         int ret;
1005 
1006         ret = clk_prepare_enable(i2s->bus_clk);
1007         if (ret) {
1008                 dev_err(dev, "Failed to enable bus clock\n");
1009                 return ret;
1010         }
1011 
1012         regcache_cache_only(i2s->regmap, false);
1013         regcache_mark_dirty(i2s->regmap);
1014 
1015         ret = regcache_sync(i2s->regmap);
1016         if (ret) {
1017                 dev_err(dev, "Failed to sync regmap cache\n");
1018                 goto err_disable_clk;
1019         }
1020 
1021         /* Enable the whole hardware block */
1022         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1023                            SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
1024 
1025         /* Enable the first output line */
1026         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1027                            SUN4I_I2S_CTRL_SDO_EN_MASK,
1028                            SUN4I_I2S_CTRL_SDO_EN(0));
1029 
1030         ret = clk_prepare_enable(i2s->mod_clk);
1031         if (ret) {
1032                 dev_err(dev, "Failed to enable module clock\n");
1033                 goto err_disable_clk;
1034         }
1035 
1036         return 0;
1037 
1038 err_disable_clk:
1039         clk_disable_unprepare(i2s->bus_clk);
1040         return ret;
1041 }
1042 
1043 static int sun4i_i2s_runtime_suspend(struct device *dev)
1044 {
1045         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1046 
1047         clk_disable_unprepare(i2s->mod_clk);
1048 
1049         /* Disable our output lines */
1050         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1051                            SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
1052 
1053         /* Disable the whole hardware block */
1054         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1055                            SUN4I_I2S_CTRL_GL_EN, 0);
1056 
1057         regcache_cache_only(i2s->regmap, true);
1058 
1059         clk_disable_unprepare(i2s->bus_clk);
1060 
1061         return 0;
1062 }
1063 
1064 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
1065         .has_reset              = false,
1066         .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1067         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1068         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1069         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1070         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1071         .bclk_dividers          = sun4i_i2s_bclk_div,
1072         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1073         .mclk_dividers          = sun4i_i2s_mclk_div,
1074         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1075         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1076         .get_sr                 = sun4i_i2s_get_sr,
1077         .get_wss                = sun4i_i2s_get_wss,
1078         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1079         .set_fmt                = sun4i_i2s_set_soc_fmt,
1080 };
1081 
1082 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
1083         .has_reset              = true,
1084         .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1085         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1086         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1087         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1088         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1089         .bclk_dividers          = sun4i_i2s_bclk_div,
1090         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1091         .mclk_dividers          = sun4i_i2s_mclk_div,
1092         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1093         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1094         .get_sr                 = sun4i_i2s_get_sr,
1095         .get_wss                = sun4i_i2s_get_wss,
1096         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1097         .set_fmt                = sun4i_i2s_set_soc_fmt,
1098 };
1099 
1100 /*
1101  * This doesn't describe the TDM controller documented in the A83t
1102  * datasheet, but the three undocumented I2S controller that use the
1103  * older design.
1104  */
1105 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1106         .has_reset              = true,
1107         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1108         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1109         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1110         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1111         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1112         .bclk_dividers          = sun4i_i2s_bclk_div,
1113         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1114         .mclk_dividers          = sun4i_i2s_mclk_div,
1115         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1116         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1117         .get_sr                 = sun4i_i2s_get_sr,
1118         .get_wss                = sun4i_i2s_get_wss,
1119         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1120         .set_fmt                = sun4i_i2s_set_soc_fmt,
1121 };
1122 
1123 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1124         .has_reset              = true,
1125         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1126         .sun4i_i2s_regmap       = &sun8i_i2s_regmap_config,
1127         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1128         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1129         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1130         .bclk_dividers          = sun8i_i2s_clk_div,
1131         .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1132         .mclk_dividers          = sun8i_i2s_clk_div,
1133         .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1134         .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1135         .get_sr                 = sun8i_i2s_get_sr_wss,
1136         .get_wss                = sun8i_i2s_get_sr_wss,
1137         .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
1138         .set_fmt                = sun8i_i2s_set_soc_fmt,
1139 };
1140 
1141 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1142         .has_reset              = true,
1143         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1144         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1145         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1146         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1147         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1148         .bclk_dividers          = sun4i_i2s_bclk_div,
1149         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1150         .mclk_dividers          = sun4i_i2s_mclk_div,
1151         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1152         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1153         .get_sr                 = sun4i_i2s_get_sr,
1154         .get_wss                = sun4i_i2s_get_wss,
1155         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1156         .set_fmt                = sun4i_i2s_set_soc_fmt,
1157 };
1158 
1159 static int sun4i_i2s_init_regmap_fields(struct device *dev,
1160                                         struct sun4i_i2s *i2s)
1161 {
1162         i2s->field_clkdiv_mclk_en =
1163                 devm_regmap_field_alloc(dev, i2s->regmap,
1164                                         i2s->variant->field_clkdiv_mclk_en);
1165         if (IS_ERR(i2s->field_clkdiv_mclk_en))
1166                 return PTR_ERR(i2s->field_clkdiv_mclk_en);
1167 
1168         i2s->field_fmt_wss =
1169                         devm_regmap_field_alloc(dev, i2s->regmap,
1170                                                 i2s->variant->field_fmt_wss);
1171         if (IS_ERR(i2s->field_fmt_wss))
1172                 return PTR_ERR(i2s->field_fmt_wss);
1173 
1174         i2s->field_fmt_sr =
1175                         devm_regmap_field_alloc(dev, i2s->regmap,
1176                                                 i2s->variant->field_fmt_sr);
1177         if (IS_ERR(i2s->field_fmt_sr))
1178                 return PTR_ERR(i2s->field_fmt_sr);
1179 
1180         return 0;
1181 }
1182 
1183 static int sun4i_i2s_probe(struct platform_device *pdev)
1184 {
1185         struct sun4i_i2s *i2s;
1186         struct resource *res;
1187         void __iomem *regs;
1188         int irq, ret;
1189 
1190         i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
1191         if (!i2s)
1192                 return -ENOMEM;
1193         platform_set_drvdata(pdev, i2s);
1194 
1195         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1196         regs = devm_ioremap_resource(&pdev->dev, res);
1197         if (IS_ERR(regs))
1198                 return PTR_ERR(regs);
1199 
1200         irq = platform_get_irq(pdev, 0);
1201         if (irq < 0)
1202                 return irq;
1203 
1204         i2s->variant = of_device_get_match_data(&pdev->dev);
1205         if (!i2s->variant) {
1206                 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1207                 return -ENODEV;
1208         }
1209 
1210         i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
1211         if (IS_ERR(i2s->bus_clk)) {
1212                 dev_err(&pdev->dev, "Can't get our bus clock\n");
1213                 return PTR_ERR(i2s->bus_clk);
1214         }
1215 
1216         i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1217                                             i2s->variant->sun4i_i2s_regmap);
1218         if (IS_ERR(i2s->regmap)) {
1219                 dev_err(&pdev->dev, "Regmap initialisation failed\n");
1220                 return PTR_ERR(i2s->regmap);
1221         }
1222 
1223         i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
1224         if (IS_ERR(i2s->mod_clk)) {
1225                 dev_err(&pdev->dev, "Can't get our mod clock\n");
1226                 return PTR_ERR(i2s->mod_clk);
1227         }
1228 
1229         if (i2s->variant->has_reset) {
1230                 i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
1231                 if (IS_ERR(i2s->rst)) {
1232                         dev_err(&pdev->dev, "Failed to get reset control\n");
1233                         return PTR_ERR(i2s->rst);
1234                 }
1235         }
1236 
1237         if (!IS_ERR(i2s->rst)) {
1238                 ret = reset_control_deassert(i2s->rst);
1239                 if (ret) {
1240                         dev_err(&pdev->dev,
1241                                 "Failed to deassert the reset control\n");
1242                         return -EINVAL;
1243                 }
1244         }
1245 
1246         i2s->playback_dma_data.addr = res->start +
1247                                         i2s->variant->reg_offset_txdata;
1248         i2s->playback_dma_data.maxburst = 8;
1249 
1250         i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
1251         i2s->capture_dma_data.maxburst = 8;
1252 
1253         pm_runtime_enable(&pdev->dev);
1254         if (!pm_runtime_enabled(&pdev->dev)) {
1255                 ret = sun4i_i2s_runtime_resume(&pdev->dev);
1256                 if (ret)
1257                         goto err_pm_disable;
1258         }
1259 
1260         ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
1261         if (ret) {
1262                 dev_err(&pdev->dev, "Could not initialise regmap fields\n");
1263                 goto err_suspend;
1264         }
1265 
1266         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1267         if (ret) {
1268                 dev_err(&pdev->dev, "Could not register PCM\n");
1269                 goto err_suspend;
1270         }
1271 
1272         ret = devm_snd_soc_register_component(&pdev->dev,
1273                                               &sun4i_i2s_component,
1274                                               &sun4i_i2s_dai, 1);
1275         if (ret) {
1276                 dev_err(&pdev->dev, "Could not register DAI\n");
1277                 goto err_suspend;
1278         }
1279 
1280         return 0;
1281 
1282 err_suspend:
1283         if (!pm_runtime_status_suspended(&pdev->dev))
1284                 sun4i_i2s_runtime_suspend(&pdev->dev);
1285 err_pm_disable:
1286         pm_runtime_disable(&pdev->dev);
1287         if (!IS_ERR(i2s->rst))
1288                 reset_control_assert(i2s->rst);
1289 
1290         return ret;
1291 }
1292 
1293 static int sun4i_i2s_remove(struct platform_device *pdev)
1294 {
1295         struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1296 
1297         pm_runtime_disable(&pdev->dev);
1298         if (!pm_runtime_status_suspended(&pdev->dev))
1299                 sun4i_i2s_runtime_suspend(&pdev->dev);
1300 
1301         if (!IS_ERR(i2s->rst))
1302                 reset_control_assert(i2s->rst);
1303 
1304         return 0;
1305 }
1306 
1307 static const struct of_device_id sun4i_i2s_match[] = {
1308         {
1309                 .compatible = "allwinner,sun4i-a10-i2s",
1310                 .data = &sun4i_a10_i2s_quirks,
1311         },
1312         {
1313                 .compatible = "allwinner,sun6i-a31-i2s",
1314                 .data = &sun6i_a31_i2s_quirks,
1315         },
1316         {
1317                 .compatible = "allwinner,sun8i-a83t-i2s",
1318                 .data = &sun8i_a83t_i2s_quirks,
1319         },
1320         {
1321                 .compatible = "allwinner,sun8i-h3-i2s",
1322                 .data = &sun8i_h3_i2s_quirks,
1323         },
1324         {
1325                 .compatible = "allwinner,sun50i-a64-codec-i2s",
1326                 .data = &sun50i_a64_codec_i2s_quirks,
1327         },
1328         {}
1329 };
1330 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1331 
1332 static const struct dev_pm_ops sun4i_i2s_pm_ops = {
1333         .runtime_resume         = sun4i_i2s_runtime_resume,
1334         .runtime_suspend        = sun4i_i2s_runtime_suspend,
1335 };
1336 
1337 static struct platform_driver sun4i_i2s_driver = {
1338         .probe  = sun4i_i2s_probe,
1339         .remove = sun4i_i2s_remove,
1340         .driver = {
1341                 .name           = "sun4i-i2s",
1342                 .of_match_table = sun4i_i2s_match,
1343                 .pm             = &sun4i_i2s_pm_ops,
1344         },
1345 };
1346 module_platform_driver(sun4i_i2s_driver);
1347 
1348 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1349 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1350 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1351 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */