linux/sound/soc/sunxi/sun4i-i2s.c
<<
>>
Prefs
   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
 127struct 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 */
 139struct 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
 162struct 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
 184struct sun4i_i2s_clk_div {
 185        u8      div;
 186        u8      val;
 187};
 188
 189static 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
 199static 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
 211static 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
 229static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 230{
 231        return i2s->mclk_freq;
 232}
 233
 234static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 235{
 236        return clk_get_rate(i2s->mod_clk);
 237}
 238
 239static 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
 259static 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
 277static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
 278static 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
 289static 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
 360static 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
 371static 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
 382static 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
 393static 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
 413static 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
 469static 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
 519static 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
 592static 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
 694static 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
 717static 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
 738static 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
 759static 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
 772static 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
 785static 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
 816static 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
 829static 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
 844static 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
 852static 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
 865static 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
 885static const struct snd_soc_component_driver sun4i_i2s_component = {
 886        .name   = "sun4i-dai",
 887};
 888
 889static 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
 900static 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
 912static 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
 926static 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
 937static 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
 947static 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
 960static 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
 974static 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
 988static 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
1001static 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
1038err_disable_clk:
1039        clk_disable_unprepare(i2s->bus_clk);
1040        return ret;
1041}
1042
1043static 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
1064static 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
1082static 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 */
1105static 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
1123static 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
1141static 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
1159static 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
1183static 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
1282err_suspend:
1283        if (!pm_runtime_status_suspended(&pdev->dev))
1284                sun4i_i2s_runtime_suspend(&pdev->dev);
1285err_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
1293static 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
1307static 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};
1330MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1331
1332static 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
1337static 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};
1346module_platform_driver(sun4i_i2s_driver);
1347
1348MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1349MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1350MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1351MODULE_LICENSE("GPL");
1352