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.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_FMT1_REG_SEXT_MASK            BIT(8)
  52#define SUN4I_I2S_FMT1_REG_SEXT(sext)                   ((sext) << 8)
  53
  54#define SUN4I_I2S_FIFO_TX_REG           0x0c
  55#define SUN4I_I2S_FIFO_RX_REG           0x10
  56
  57#define SUN4I_I2S_FIFO_CTRL_REG         0x14
  58#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX            BIT(25)
  59#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX            BIT(24)
  60#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK        BIT(2)
  61#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)               ((mode) << 2)
  62#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK        GENMASK(1, 0)
  63#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)               (mode)
  64
  65#define SUN4I_I2S_FIFO_STA_REG          0x18
  66
  67#define SUN4I_I2S_DMA_INT_CTRL_REG      0x1c
  68#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN        BIT(7)
  69#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN        BIT(3)
  70
  71#define SUN4I_I2S_INT_STA_REG           0x20
  72
  73#define SUN4I_I2S_CLK_DIV_REG           0x24
  74#define SUN4I_I2S_CLK_DIV_MCLK_EN               BIT(7)
  75#define SUN4I_I2S_CLK_DIV_BCLK_MASK             GENMASK(6, 4)
  76#define SUN4I_I2S_CLK_DIV_BCLK(bclk)                    ((bclk) << 4)
  77#define SUN4I_I2S_CLK_DIV_MCLK_MASK             GENMASK(3, 0)
  78#define SUN4I_I2S_CLK_DIV_MCLK(mclk)                    ((mclk) << 0)
  79
  80#define SUN4I_I2S_TX_CNT_REG            0x28
  81#define SUN4I_I2S_RX_CNT_REG            0x2c
  82
  83#define SUN4I_I2S_TX_CHAN_SEL_REG       0x30
  84#define SUN4I_I2S_CHAN_SEL_MASK                 GENMASK(2, 0)
  85#define SUN4I_I2S_CHAN_SEL(num_chan)            (((num_chan) - 1) << 0)
  86
  87#define SUN4I_I2S_TX_CHAN_MAP_REG       0x34
  88#define SUN4I_I2S_TX_CHAN_MAP(chan, sample)     ((sample) << (chan << 2))
  89
  90#define SUN4I_I2S_RX_CHAN_SEL_REG       0x38
  91#define SUN4I_I2S_RX_CHAN_MAP_REG       0x3c
  92
  93/* Defines required for sun8i-h3 support */
  94#define SUN8I_I2S_CTRL_BCLK_OUT                 BIT(18)
  95#define SUN8I_I2S_CTRL_LRCK_OUT                 BIT(17)
  96
  97#define SUN8I_I2S_CTRL_MODE_MASK                GENMASK(5, 4)
  98#define SUN8I_I2S_CTRL_MODE_RIGHT               (2 << 4)
  99#define SUN8I_I2S_CTRL_MODE_LEFT                (1 << 4)
 100#define SUN8I_I2S_CTRL_MODE_PCM                 (0 << 4)
 101
 102#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(19)
 103#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH        (1 << 19)
 104#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW         (0 << 19)
 105#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK         GENMASK(17, 8)
 106#define SUN8I_I2S_FMT0_LRCK_PERIOD(period)      ((period - 1) << 8)
 107#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(7)
 108#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 7)
 109#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 7)
 110
 111#define SUN8I_I2S_FMT1_REG_SEXT_MASK            GENMASK(5, 4)
 112#define SUN8I_I2S_FMT1_REG_SEXT(sext)                   ((sext) << 4)
 113
 114#define SUN8I_I2S_INT_STA_REG           0x0c
 115#define SUN8I_I2S_FIFO_TX_REG           0x20
 116
 117#define SUN8I_I2S_CHAN_CFG_REG          0x30
 118#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK     GENMASK(7, 4)
 119#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)    ((chan - 1) << 4)
 120#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK     GENMASK(3, 0)
 121#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)    (chan - 1)
 122
 123#define SUN8I_I2S_TX_CHAN_MAP_REG       0x44
 124#define SUN8I_I2S_TX_CHAN_SEL_REG       0x34
 125#define SUN8I_I2S_TX_CHAN_OFFSET_MASK           GENMASK(13, 12)
 126#define SUN8I_I2S_TX_CHAN_OFFSET(offset)        (offset << 12)
 127#define SUN8I_I2S_TX_CHAN_EN_MASK               GENMASK(11, 4)
 128#define SUN8I_I2S_TX_CHAN_EN(num_chan)          (((1 << num_chan) - 1) << 4)
 129
 130#define SUN8I_I2S_RX_CHAN_SEL_REG       0x54
 131#define SUN8I_I2S_RX_CHAN_MAP_REG       0x58
 132
 133/* Defines required for sun50i-h6 support */
 134#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK   GENMASK(21, 20)
 135#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)        ((offset) << 20)
 136#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK          GENMASK(19, 16)
 137#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)         ((chan - 1) << 16)
 138#define SUN50I_H6_I2S_TX_CHAN_EN_MASK           GENMASK(15, 0)
 139#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)      (((1 << num_chan) - 1))
 140
 141#define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin)      (0x34 + 4 * (pin))
 142#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin)     (0x44 + 8 * (pin))
 143#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin)     (0x48 + 8 * (pin))
 144
 145#define SUN50I_H6_I2S_RX_CHAN_SEL_REG   0x64
 146#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG  0x68
 147#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG  0x6C
 148
 149#define SUN50I_R329_I2S_RX_CHAN_MAP0_REG 0x68
 150#define SUN50I_R329_I2S_RX_CHAN_MAP1_REG 0x6c
 151#define SUN50I_R329_I2S_RX_CHAN_MAP2_REG 0x70
 152#define SUN50I_R329_I2S_RX_CHAN_MAP3_REG 0x74
 153
 154struct sun4i_i2s;
 155
 156/**
 157 * struct sun4i_i2s_quirks - Differences between SoC variants.
 158 * @has_reset: SoC needs reset deasserted.
 159 * @pcm_formats: available PCM formats.
 160 * @reg_offset_txdata: offset of the tx fifo.
 161 * @sun4i_i2s_regmap: regmap config to use.
 162 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
 163 * @field_fmt_wss: regmap field to set word select size.
 164 * @field_fmt_sr: regmap field to set sample resolution.
 165 * @num_din_pins: input pins
 166 * @num_dout_pins: output pins (currently set but unused)
 167 * @bclk_dividers: bit clock dividers array
 168 * @num_bclk_dividers: number of bit clock dividers
 169 * @mclk_dividers: mclk dividers array
 170 * @num_mclk_dividers: number of mclk dividers
 171 * @get_bclk_parent_rate: callback to get bclk parent rate
 172 * @get_sr: callback to get sample resolution
 173 * @get_wss: callback to get word select size
 174 * @set_chan_cfg: callback to set channel configuration
 175 * @set_fmt: callback to set format
 176 */
 177struct sun4i_i2s_quirks {
 178        bool                            has_reset;
 179        u64                             pcm_formats;
 180        unsigned int                    reg_offset_txdata;      /* TX FIFO */
 181        const struct regmap_config      *sun4i_i2s_regmap;
 182
 183        /* Register fields for i2s */
 184        struct reg_field                field_clkdiv_mclk_en;
 185        struct reg_field                field_fmt_wss;
 186        struct reg_field                field_fmt_sr;
 187
 188        unsigned int                    num_din_pins;
 189        unsigned int                    num_dout_pins;
 190
 191        const struct sun4i_i2s_clk_div  *bclk_dividers;
 192        unsigned int                    num_bclk_dividers;
 193        const struct sun4i_i2s_clk_div  *mclk_dividers;
 194        unsigned int                    num_mclk_dividers;
 195
 196        unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
 197        int     (*get_sr)(unsigned int width);
 198        int     (*get_wss)(unsigned int width);
 199
 200        /*
 201         * In the set_chan_cfg() function pointer:
 202         * @slots: channels per frame + padding slots, regardless of format
 203         * @slot_width: bits per sample + padding bits, regardless of format
 204         */
 205        int     (*set_chan_cfg)(const struct sun4i_i2s *i2s,
 206                                unsigned int channels,  unsigned int slots,
 207                                unsigned int slot_width);
 208        int     (*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
 209};
 210
 211struct sun4i_i2s {
 212        struct clk      *bus_clk;
 213        struct clk      *mod_clk;
 214        struct regmap   *regmap;
 215        struct reset_control *rst;
 216
 217        unsigned int    format;
 218        unsigned int    mclk_freq;
 219        unsigned int    slots;
 220        unsigned int    slot_width;
 221
 222        struct snd_dmaengine_dai_dma_data       capture_dma_data;
 223        struct snd_dmaengine_dai_dma_data       playback_dma_data;
 224
 225        /* Register fields for i2s */
 226        struct regmap_field     *field_clkdiv_mclk_en;
 227        struct regmap_field     *field_fmt_wss;
 228        struct regmap_field     *field_fmt_sr;
 229
 230        const struct sun4i_i2s_quirks   *variant;
 231};
 232
 233struct sun4i_i2s_clk_div {
 234        u8      div;
 235        u8      val;
 236};
 237
 238static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 239        { .div = 2, .val = 0 },
 240        { .div = 4, .val = 1 },
 241        { .div = 6, .val = 2 },
 242        { .div = 8, .val = 3 },
 243        { .div = 12, .val = 4 },
 244        { .div = 16, .val = 5 },
 245        /* TODO - extend divide ratio supported by newer SoCs */
 246};
 247
 248static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
 249        { .div = 1, .val = 0 },
 250        { .div = 2, .val = 1 },
 251        { .div = 4, .val = 2 },
 252        { .div = 6, .val = 3 },
 253        { .div = 8, .val = 4 },
 254        { .div = 12, .val = 5 },
 255        { .div = 16, .val = 6 },
 256        { .div = 24, .val = 7 },
 257        /* TODO - extend divide ratio supported by newer SoCs */
 258};
 259
 260static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
 261        { .div = 1, .val = 1 },
 262        { .div = 2, .val = 2 },
 263        { .div = 4, .val = 3 },
 264        { .div = 6, .val = 4 },
 265        { .div = 8, .val = 5 },
 266        { .div = 12, .val = 6 },
 267        { .div = 16, .val = 7 },
 268        { .div = 24, .val = 8 },
 269        { .div = 32, .val = 9 },
 270        { .div = 48, .val = 10 },
 271        { .div = 64, .val = 11 },
 272        { .div = 96, .val = 12 },
 273        { .div = 128, .val = 13 },
 274        { .div = 176, .val = 14 },
 275        { .div = 192, .val = 15 },
 276};
 277
 278static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 279{
 280        return i2s->mclk_freq;
 281}
 282
 283static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
 284{
 285        return clk_get_rate(i2s->mod_clk);
 286}
 287
 288static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
 289                                  unsigned long parent_rate,
 290                                  unsigned int sampling_rate,
 291                                  unsigned int channels,
 292                                  unsigned int word_size)
 293{
 294        const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
 295        int div = parent_rate / sampling_rate / word_size / channels;
 296        int i;
 297
 298        for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
 299                const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
 300
 301                if (bdiv->div == div)
 302                        return bdiv->val;
 303        }
 304
 305        return -EINVAL;
 306}
 307
 308static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
 309                                  unsigned long parent_rate,
 310                                  unsigned long mclk_rate)
 311{
 312        const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
 313        int div = parent_rate / mclk_rate;
 314        int i;
 315
 316        for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
 317                const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
 318
 319                if (mdiv->div == div)
 320                        return mdiv->val;
 321        }
 322
 323        return -EINVAL;
 324}
 325
 326static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
 327static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
 328{
 329        int i;
 330
 331        for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
 332                if (sun4i_i2s_oversample_rates[i] == oversample)
 333                        return true;
 334
 335        return false;
 336}
 337
 338static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
 339                                  unsigned int rate,
 340                                  unsigned int slots,
 341                                  unsigned int slot_width)
 342{
 343        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 344        unsigned int oversample_rate, clk_rate, bclk_parent_rate;
 345        int bclk_div, mclk_div;
 346        int ret;
 347
 348        switch (rate) {
 349        case 176400:
 350        case 88200:
 351        case 44100:
 352        case 22050:
 353        case 11025:
 354                clk_rate = 22579200;
 355                break;
 356
 357        case 192000:
 358        case 128000:
 359        case 96000:
 360        case 64000:
 361        case 48000:
 362        case 32000:
 363        case 24000:
 364        case 16000:
 365        case 12000:
 366        case 8000:
 367                clk_rate = 24576000;
 368                break;
 369
 370        default:
 371                dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
 372                return -EINVAL;
 373        }
 374
 375        ret = clk_set_rate(i2s->mod_clk, clk_rate);
 376        if (ret)
 377                return ret;
 378
 379        oversample_rate = i2s->mclk_freq / rate;
 380        if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
 381                dev_err(dai->dev, "Unsupported oversample rate: %d\n",
 382                        oversample_rate);
 383                return -EINVAL;
 384        }
 385
 386        bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
 387        bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
 388                                          rate, slots, slot_width);
 389        if (bclk_div < 0) {
 390                dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
 391                return -EINVAL;
 392        }
 393
 394        mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
 395        if (mclk_div < 0) {
 396                dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
 397                return -EINVAL;
 398        }
 399
 400        regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
 401                     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
 402                     SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
 403
 404        regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
 405
 406        return 0;
 407}
 408
 409static int sun4i_i2s_get_sr(unsigned int width)
 410{
 411        switch (width) {
 412        case 16:
 413                return 0;
 414        case 20:
 415                return 1;
 416        case 24:
 417                return 2;
 418        }
 419
 420        return -EINVAL;
 421}
 422
 423static int sun4i_i2s_get_wss(unsigned int width)
 424{
 425        switch (width) {
 426        case 16:
 427                return 0;
 428        case 20:
 429                return 1;
 430        case 24:
 431                return 2;
 432        case 32:
 433                return 3;
 434        }
 435
 436        return -EINVAL;
 437}
 438
 439static int sun8i_i2s_get_sr_wss(unsigned int width)
 440{
 441        switch (width) {
 442        case 8:
 443                return 1;
 444        case 12:
 445                return 2;
 446        case 16:
 447                return 3;
 448        case 20:
 449                return 4;
 450        case 24:
 451                return 5;
 452        case 28:
 453                return 6;
 454        case 32:
 455                return 7;
 456        }
 457
 458        return -EINVAL;
 459}
 460
 461static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
 462                                  unsigned int channels, unsigned int slots,
 463                                  unsigned int slot_width)
 464{
 465        /* Map the channels for playback and capture */
 466        regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
 467        regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
 468
 469        /* Configure the channels */
 470        regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
 471                           SUN4I_I2S_CHAN_SEL_MASK,
 472                           SUN4I_I2S_CHAN_SEL(channels));
 473        regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
 474                           SUN4I_I2S_CHAN_SEL_MASK,
 475                           SUN4I_I2S_CHAN_SEL(channels));
 476
 477        return 0;
 478}
 479
 480static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
 481                                  unsigned int channels, unsigned int slots,
 482                                  unsigned int slot_width)
 483{
 484        unsigned int lrck_period;
 485
 486        /* Map the channels for playback and capture */
 487        regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
 488        regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
 489
 490        /* Configure the channels */
 491        regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 492                           SUN4I_I2S_CHAN_SEL_MASK,
 493                           SUN4I_I2S_CHAN_SEL(channels));
 494        regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
 495                           SUN4I_I2S_CHAN_SEL_MASK,
 496                           SUN4I_I2S_CHAN_SEL(channels));
 497
 498        regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 499                           SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
 500                           SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
 501        regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 502                           SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
 503                           SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
 504
 505        switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 506        case SND_SOC_DAIFMT_DSP_A:
 507        case SND_SOC_DAIFMT_DSP_B:
 508                lrck_period = slot_width * slots;
 509                break;
 510
 511        case SND_SOC_DAIFMT_LEFT_J:
 512        case SND_SOC_DAIFMT_RIGHT_J:
 513        case SND_SOC_DAIFMT_I2S:
 514                lrck_period = slot_width;
 515                break;
 516
 517        default:
 518                return -EINVAL;
 519        }
 520
 521        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 522                           SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
 523                           SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
 524
 525        regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 526                           SUN8I_I2S_TX_CHAN_EN_MASK,
 527                           SUN8I_I2S_TX_CHAN_EN(channels));
 528
 529        return 0;
 530}
 531
 532static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
 533                                      unsigned int channels, unsigned int slots,
 534                                      unsigned int slot_width)
 535{
 536        unsigned int lrck_period;
 537
 538        /* Map the channels for playback and capture */
 539        regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
 540        regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
 541        if (i2s->variant->num_din_pins > 1) {
 542                regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 0x0F0E0D0C);
 543                regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 0x0B0A0908);
 544                regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 0x07060504);
 545                regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0x03020100);
 546        } else {
 547                regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
 548                regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
 549        }
 550
 551        /* Configure the channels */
 552        regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
 553                           SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
 554                           SUN50I_H6_I2S_TX_CHAN_SEL(channels));
 555        regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
 556                           SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
 557                           SUN50I_H6_I2S_TX_CHAN_SEL(channels));
 558
 559        regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 560                           SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
 561                           SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
 562        regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
 563                           SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
 564                           SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
 565
 566        switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 567        case SND_SOC_DAIFMT_DSP_A:
 568        case SND_SOC_DAIFMT_DSP_B:
 569                lrck_period = slot_width * slots;
 570                break;
 571
 572        case SND_SOC_DAIFMT_LEFT_J:
 573        case SND_SOC_DAIFMT_RIGHT_J:
 574        case SND_SOC_DAIFMT_I2S:
 575                lrck_period = slot_width;
 576                break;
 577
 578        default:
 579                return -EINVAL;
 580        }
 581
 582        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 583                           SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
 584                           SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
 585
 586        regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
 587                           SUN50I_H6_I2S_TX_CHAN_EN_MASK,
 588                           SUN50I_H6_I2S_TX_CHAN_EN(channels));
 589
 590        return 0;
 591}
 592
 593static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 594                               struct snd_pcm_hw_params *params,
 595                               struct snd_soc_dai *dai)
 596{
 597        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 598        unsigned int word_size = params_width(params);
 599        unsigned int slot_width = params_physical_width(params);
 600        unsigned int channels = params_channels(params);
 601
 602        unsigned int slots = channels;
 603
 604        int ret, sr, wss;
 605        u32 width;
 606
 607        if (i2s->slots)
 608                slots = i2s->slots;
 609
 610        if (i2s->slot_width)
 611                slot_width = i2s->slot_width;
 612
 613        ret = i2s->variant->set_chan_cfg(i2s, channels, slots, slot_width);
 614        if (ret < 0) {
 615                dev_err(dai->dev, "Invalid channel configuration\n");
 616                return ret;
 617        }
 618
 619        /* Set significant bits in our FIFOs */
 620        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 621                           SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
 622                           SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
 623                           SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
 624                           SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
 625
 626        switch (params_physical_width(params)) {
 627        case 16:
 628                width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 629                break;
 630        case 32:
 631                width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 632                break;
 633        default:
 634                dev_err(dai->dev, "Unsupported physical sample width: %d\n",
 635                        params_physical_width(params));
 636                return -EINVAL;
 637        }
 638        i2s->playback_dma_data.addr_width = width;
 639
 640        sr = i2s->variant->get_sr(word_size);
 641        if (sr < 0)
 642                return -EINVAL;
 643
 644        wss = i2s->variant->get_wss(slot_width);
 645        if (wss < 0)
 646                return -EINVAL;
 647
 648        regmap_field_write(i2s->field_fmt_wss, wss);
 649        regmap_field_write(i2s->field_fmt_sr, sr);
 650
 651        return sun4i_i2s_set_clk_rate(dai, params_rate(params),
 652                                      slots, slot_width);
 653}
 654
 655static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
 656                                 unsigned int fmt)
 657{
 658        u32 val;
 659
 660        /* DAI clock polarity */
 661        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 662        case SND_SOC_DAIFMT_IB_IF:
 663                /* Invert both clocks */
 664                val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
 665                      SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 666                break;
 667        case SND_SOC_DAIFMT_IB_NF:
 668                /* Invert bit clock */
 669                val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 670                break;
 671        case SND_SOC_DAIFMT_NB_IF:
 672                /* Invert frame clock */
 673                val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 674                break;
 675        case SND_SOC_DAIFMT_NB_NF:
 676                val = 0;
 677                break;
 678        default:
 679                return -EINVAL;
 680        }
 681
 682        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 683                           SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
 684                           SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
 685                           val);
 686
 687        /* DAI Mode */
 688        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 689        case SND_SOC_DAIFMT_I2S:
 690                val = SUN4I_I2S_FMT0_FMT_I2S;
 691                break;
 692
 693        case SND_SOC_DAIFMT_LEFT_J:
 694                val = SUN4I_I2S_FMT0_FMT_LEFT_J;
 695                break;
 696
 697        case SND_SOC_DAIFMT_RIGHT_J:
 698                val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
 699                break;
 700
 701        default:
 702                return -EINVAL;
 703        }
 704
 705        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 706                           SUN4I_I2S_FMT0_FMT_MASK, val);
 707
 708        /* DAI clock master masks */
 709        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 710        case SND_SOC_DAIFMT_BP_FP:
 711                /* BCLK and LRCLK master */
 712                val = SUN4I_I2S_CTRL_MODE_MASTER;
 713                break;
 714
 715        case SND_SOC_DAIFMT_BC_FC:
 716                /* BCLK and LRCLK slave */
 717                val = SUN4I_I2S_CTRL_MODE_SLAVE;
 718                break;
 719
 720        default:
 721                return -EINVAL;
 722        }
 723        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 724                           SUN4I_I2S_CTRL_MODE_MASK, val);
 725
 726        return 0;
 727}
 728
 729static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
 730                                 unsigned int fmt)
 731{
 732        u32 mode, lrclk_pol, bclk_pol, val;
 733        u8 offset;
 734
 735        /* DAI Mode */
 736        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 737        case SND_SOC_DAIFMT_DSP_A:
 738                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 739                mode = SUN8I_I2S_CTRL_MODE_PCM;
 740                offset = 1;
 741                break;
 742
 743        case SND_SOC_DAIFMT_DSP_B:
 744                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 745                mode = SUN8I_I2S_CTRL_MODE_PCM;
 746                offset = 0;
 747                break;
 748
 749        case SND_SOC_DAIFMT_I2S:
 750                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW;
 751                mode = SUN8I_I2S_CTRL_MODE_LEFT;
 752                offset = 1;
 753                break;
 754
 755        case SND_SOC_DAIFMT_LEFT_J:
 756                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 757                mode = SUN8I_I2S_CTRL_MODE_LEFT;
 758                offset = 0;
 759                break;
 760
 761        case SND_SOC_DAIFMT_RIGHT_J:
 762                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 763                mode = SUN8I_I2S_CTRL_MODE_RIGHT;
 764                offset = 0;
 765                break;
 766
 767        default:
 768                return -EINVAL;
 769        }
 770
 771        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 772                           SUN8I_I2S_CTRL_MODE_MASK, mode);
 773        regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 774                           SUN8I_I2S_TX_CHAN_OFFSET_MASK,
 775                           SUN8I_I2S_TX_CHAN_OFFSET(offset));
 776        regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
 777                           SUN8I_I2S_TX_CHAN_OFFSET_MASK,
 778                           SUN8I_I2S_TX_CHAN_OFFSET(offset));
 779
 780        /* DAI clock polarity */
 781        bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL;
 782
 783        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 784        case SND_SOC_DAIFMT_IB_IF:
 785                /* Invert both clocks */
 786                lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
 787                bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 788                break;
 789        case SND_SOC_DAIFMT_IB_NF:
 790                /* Invert bit clock */
 791                bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 792                break;
 793        case SND_SOC_DAIFMT_NB_IF:
 794                /* Invert frame clock */
 795                lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
 796                break;
 797        case SND_SOC_DAIFMT_NB_NF:
 798                /* No inversion */
 799                break;
 800        default:
 801                return -EINVAL;
 802        }
 803
 804        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 805                           SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
 806                           SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
 807                           lrclk_pol | bclk_pol);
 808
 809        /* DAI clock master masks */
 810        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 811        case SND_SOC_DAIFMT_BP_FP:
 812                /* BCLK and LRCLK master */
 813                val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
 814                break;
 815
 816        case SND_SOC_DAIFMT_BC_FC:
 817                /* BCLK and LRCLK slave */
 818                val = 0;
 819                break;
 820
 821        default:
 822                return -EINVAL;
 823        }
 824
 825        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 826                           SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
 827                           val);
 828
 829        /* Set sign extension to pad out LSB with 0 */
 830        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
 831                           SUN8I_I2S_FMT1_REG_SEXT_MASK,
 832                           SUN8I_I2S_FMT1_REG_SEXT(0));
 833
 834        return 0;
 835}
 836
 837static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
 838                                     unsigned int fmt)
 839{
 840        u32 mode, lrclk_pol, bclk_pol, val;
 841        u8 offset;
 842
 843        /* DAI Mode */
 844        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 845        case SND_SOC_DAIFMT_DSP_A:
 846                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 847                mode = SUN8I_I2S_CTRL_MODE_PCM;
 848                offset = 1;
 849                break;
 850
 851        case SND_SOC_DAIFMT_DSP_B:
 852                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 853                mode = SUN8I_I2S_CTRL_MODE_PCM;
 854                offset = 0;
 855                break;
 856
 857        case SND_SOC_DAIFMT_I2S:
 858                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW;
 859                mode = SUN8I_I2S_CTRL_MODE_LEFT;
 860                offset = 1;
 861                break;
 862
 863        case SND_SOC_DAIFMT_LEFT_J:
 864                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 865                mode = SUN8I_I2S_CTRL_MODE_LEFT;
 866                offset = 0;
 867                break;
 868
 869        case SND_SOC_DAIFMT_RIGHT_J:
 870                lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH;
 871                mode = SUN8I_I2S_CTRL_MODE_RIGHT;
 872                offset = 0;
 873                break;
 874
 875        default:
 876                return -EINVAL;
 877        }
 878
 879        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 880                           SUN8I_I2S_CTRL_MODE_MASK, mode);
 881        regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
 882                           SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
 883                           SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
 884        regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
 885                           SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
 886                           SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
 887
 888        /* DAI clock polarity */
 889        bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL;
 890
 891        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 892        case SND_SOC_DAIFMT_IB_IF:
 893                /* Invert both clocks */
 894                lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
 895                bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 896                break;
 897        case SND_SOC_DAIFMT_IB_NF:
 898                /* Invert bit clock */
 899                bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
 900                break;
 901        case SND_SOC_DAIFMT_NB_IF:
 902                /* Invert frame clock */
 903                lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK;
 904                break;
 905        case SND_SOC_DAIFMT_NB_NF:
 906                /* No inversion */
 907                break;
 908        default:
 909                return -EINVAL;
 910        }
 911
 912        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 913                           SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
 914                           SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
 915                           lrclk_pol | bclk_pol);
 916
 917
 918        /* DAI clock master masks */
 919        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 920        case SND_SOC_DAIFMT_BP_FP:
 921                /* BCLK and LRCLK master */
 922                val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
 923                break;
 924
 925        case SND_SOC_DAIFMT_BC_FC:
 926                /* BCLK and LRCLK slave */
 927                val = 0;
 928                break;
 929
 930        default:
 931                return -EINVAL;
 932        }
 933
 934        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 935                           SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
 936                           val);
 937
 938        /* Set sign extension to pad out LSB with 0 */
 939        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
 940                           SUN8I_I2S_FMT1_REG_SEXT_MASK,
 941                           SUN8I_I2S_FMT1_REG_SEXT(0));
 942
 943        return 0;
 944}
 945
 946static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 947{
 948        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 949        int ret;
 950
 951        ret = i2s->variant->set_fmt(i2s, fmt);
 952        if (ret) {
 953                dev_err(dai->dev, "Unsupported format configuration\n");
 954                return ret;
 955        }
 956
 957        i2s->format = fmt;
 958
 959        return 0;
 960}
 961
 962static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
 963{
 964        /* Flush RX FIFO */
 965        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 966                           SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
 967                           SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
 968
 969        /* Clear RX counter */
 970        regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
 971
 972        /* Enable RX Block */
 973        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 974                           SUN4I_I2S_CTRL_RX_EN,
 975                           SUN4I_I2S_CTRL_RX_EN);
 976
 977        /* Enable RX DRQ */
 978        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 979                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
 980                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
 981}
 982
 983static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 984{
 985        /* Flush TX FIFO */
 986        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 987                           SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
 988                           SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
 989
 990        /* Clear TX counter */
 991        regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
 992
 993        /* Enable TX Block */
 994        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 995                           SUN4I_I2S_CTRL_TX_EN,
 996                           SUN4I_I2S_CTRL_TX_EN);
 997
 998        /* Enable TX DRQ */
 999        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1000                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
1001                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
1002}
1003
1004static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
1005{
1006        /* Disable RX Block */
1007        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1008                           SUN4I_I2S_CTRL_RX_EN,
1009                           0);
1010
1011        /* Disable RX DRQ */
1012        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1013                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
1014                           0);
1015}
1016
1017static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
1018{
1019        /* Disable TX Block */
1020        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1021                           SUN4I_I2S_CTRL_TX_EN,
1022                           0);
1023
1024        /* Disable TX DRQ */
1025        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1026                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
1027                           0);
1028}
1029
1030static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
1031                             struct snd_soc_dai *dai)
1032{
1033        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1034
1035        switch (cmd) {
1036        case SNDRV_PCM_TRIGGER_START:
1037        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1038        case SNDRV_PCM_TRIGGER_RESUME:
1039                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1040                        sun4i_i2s_start_playback(i2s);
1041                else
1042                        sun4i_i2s_start_capture(i2s);
1043                break;
1044
1045        case SNDRV_PCM_TRIGGER_STOP:
1046        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1047        case SNDRV_PCM_TRIGGER_SUSPEND:
1048                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1049                        sun4i_i2s_stop_playback(i2s);
1050                else
1051                        sun4i_i2s_stop_capture(i2s);
1052                break;
1053
1054        default:
1055                return -EINVAL;
1056        }
1057
1058        return 0;
1059}
1060
1061static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1062                                unsigned int freq, int dir)
1063{
1064        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1065
1066        if (clk_id != 0)
1067                return -EINVAL;
1068
1069        i2s->mclk_freq = freq;
1070
1071        return 0;
1072}
1073
1074static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
1075                                  unsigned int tx_mask, unsigned int rx_mask,
1076                                  int slots, int slot_width)
1077{
1078        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1079
1080        if (slots > 8)
1081                return -EINVAL;
1082
1083        i2s->slots = slots;
1084        i2s->slot_width = slot_width;
1085
1086        return 0;
1087}
1088
1089static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
1090{
1091        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1092
1093        snd_soc_dai_init_dma_data(dai,
1094                                  &i2s->playback_dma_data,
1095                                  &i2s->capture_dma_data);
1096
1097        return 0;
1098}
1099
1100static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
1101{
1102        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1103        struct snd_pcm_runtime *runtime = sub->runtime;
1104
1105        return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
1106                                            i2s->variant->pcm_formats);
1107}
1108
1109static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
1110        .probe          = sun4i_i2s_dai_probe,
1111        .startup        = sun4i_i2s_dai_startup,
1112        .hw_params      = sun4i_i2s_hw_params,
1113        .set_fmt        = sun4i_i2s_set_fmt,
1114        .set_sysclk     = sun4i_i2s_set_sysclk,
1115        .set_tdm_slot   = sun4i_i2s_set_tdm_slot,
1116        .trigger        = sun4i_i2s_trigger,
1117};
1118
1119#define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
1120                           SNDRV_PCM_FMTBIT_S20_LE | \
1121                           SNDRV_PCM_FMTBIT_S24_LE | \
1122                           SNDRV_PCM_FMTBIT_S32_LE)
1123
1124static struct snd_soc_dai_driver sun4i_i2s_dai = {
1125        .capture = {
1126                .stream_name = "Capture",
1127                .channels_min = 1,
1128                .channels_max = 8,
1129                .rates = SNDRV_PCM_RATE_8000_192000,
1130                .formats = SUN4I_FORMATS_ALL,
1131        },
1132        .playback = {
1133                .stream_name = "Playback",
1134                .channels_min = 1,
1135                .channels_max = 8,
1136                .rates = SNDRV_PCM_RATE_8000_192000,
1137                .formats = SUN4I_FORMATS_ALL,
1138        },
1139        .ops = &sun4i_i2s_dai_ops,
1140        .symmetric_rate = 1,
1141};
1142
1143static const struct snd_soc_component_driver sun4i_i2s_component = {
1144        .name                   = "sun4i-dai",
1145        .legacy_dai_naming      = 1,
1146};
1147
1148static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
1149{
1150        switch (reg) {
1151        case SUN4I_I2S_FIFO_TX_REG:
1152                return false;
1153
1154        default:
1155                return true;
1156        }
1157}
1158
1159static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
1160{
1161        switch (reg) {
1162        case SUN4I_I2S_FIFO_RX_REG:
1163        case SUN4I_I2S_FIFO_STA_REG:
1164                return false;
1165
1166        default:
1167                return true;
1168        }
1169}
1170
1171static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1172{
1173        switch (reg) {
1174        case SUN4I_I2S_FIFO_RX_REG:
1175        case SUN4I_I2S_INT_STA_REG:
1176        case SUN4I_I2S_RX_CNT_REG:
1177        case SUN4I_I2S_TX_CNT_REG:
1178                return true;
1179
1180        default:
1181                return false;
1182        }
1183}
1184
1185static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
1186{
1187        switch (reg) {
1188        case SUN8I_I2S_FIFO_TX_REG:
1189                return false;
1190
1191        default:
1192                return true;
1193        }
1194}
1195
1196static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1197{
1198        switch (reg) {
1199        case SUN4I_I2S_FIFO_CTRL_REG:
1200        case SUN4I_I2S_FIFO_RX_REG:
1201        case SUN4I_I2S_FIFO_STA_REG:
1202        case SUN4I_I2S_RX_CNT_REG:
1203        case SUN4I_I2S_TX_CNT_REG:
1204        case SUN8I_I2S_FIFO_TX_REG:
1205        case SUN8I_I2S_INT_STA_REG:
1206                return true;
1207
1208        default:
1209                return false;
1210        }
1211}
1212
1213static const struct reg_default sun4i_i2s_reg_defaults[] = {
1214        { SUN4I_I2S_CTRL_REG, 0x00000000 },
1215        { SUN4I_I2S_FMT0_REG, 0x0000000c },
1216        { SUN4I_I2S_FMT1_REG, 0x00004020 },
1217        { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1218        { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1219        { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1220        { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
1221        { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
1222        { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
1223        { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
1224};
1225
1226static const struct reg_default sun8i_i2s_reg_defaults[] = {
1227        { SUN4I_I2S_CTRL_REG, 0x00060000 },
1228        { SUN4I_I2S_FMT0_REG, 0x00000033 },
1229        { SUN4I_I2S_FMT1_REG, 0x00000030 },
1230        { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1231        { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1232        { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1233        { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1234        { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
1235        { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
1236        { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1237        { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
1238};
1239
1240static const struct reg_default sun50i_h6_i2s_reg_defaults[] = {
1241        { SUN4I_I2S_CTRL_REG, 0x00060000 },
1242        { SUN4I_I2S_FMT0_REG, 0x00000033 },
1243        { SUN4I_I2S_FMT1_REG, 0x00000030 },
1244        { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1245        { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1246        { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1247        { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1248        { SUN50I_H6_I2S_TX_CHAN_SEL_REG(0), 0x00000000 },
1249        { SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0x00000000 },
1250        { SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x00000000 },
1251        { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1252        { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
1253        { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
1254};
1255
1256static const struct regmap_config sun4i_i2s_regmap_config = {
1257        .reg_bits       = 32,
1258        .reg_stride     = 4,
1259        .val_bits       = 32,
1260        .max_register   = SUN4I_I2S_RX_CHAN_MAP_REG,
1261
1262        .cache_type     = REGCACHE_FLAT,
1263        .reg_defaults   = sun4i_i2s_reg_defaults,
1264        .num_reg_defaults       = ARRAY_SIZE(sun4i_i2s_reg_defaults),
1265        .writeable_reg  = sun4i_i2s_wr_reg,
1266        .readable_reg   = sun4i_i2s_rd_reg,
1267        .volatile_reg   = sun4i_i2s_volatile_reg,
1268};
1269
1270static const struct regmap_config sun8i_i2s_regmap_config = {
1271        .reg_bits       = 32,
1272        .reg_stride     = 4,
1273        .val_bits       = 32,
1274        .max_register   = SUN8I_I2S_RX_CHAN_MAP_REG,
1275        .cache_type     = REGCACHE_FLAT,
1276        .reg_defaults   = sun8i_i2s_reg_defaults,
1277        .num_reg_defaults       = ARRAY_SIZE(sun8i_i2s_reg_defaults),
1278        .writeable_reg  = sun4i_i2s_wr_reg,
1279        .readable_reg   = sun8i_i2s_rd_reg,
1280        .volatile_reg   = sun8i_i2s_volatile_reg,
1281};
1282
1283static const struct regmap_config sun50i_h6_i2s_regmap_config = {
1284        .reg_bits       = 32,
1285        .reg_stride     = 4,
1286        .val_bits       = 32,
1287        .max_register   = SUN50I_R329_I2S_RX_CHAN_MAP3_REG,
1288        .cache_type     = REGCACHE_FLAT,
1289        .reg_defaults   = sun50i_h6_i2s_reg_defaults,
1290        .num_reg_defaults       = ARRAY_SIZE(sun50i_h6_i2s_reg_defaults),
1291        .writeable_reg  = sun4i_i2s_wr_reg,
1292        .readable_reg   = sun8i_i2s_rd_reg,
1293        .volatile_reg   = sun8i_i2s_volatile_reg,
1294};
1295
1296static int sun4i_i2s_runtime_resume(struct device *dev)
1297{
1298        struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1299        int ret;
1300
1301        ret = clk_prepare_enable(i2s->bus_clk);
1302        if (ret) {
1303                dev_err(dev, "Failed to enable bus clock\n");
1304                return ret;
1305        }
1306
1307        regcache_cache_only(i2s->regmap, false);
1308        regcache_mark_dirty(i2s->regmap);
1309
1310        ret = regcache_sync(i2s->regmap);
1311        if (ret) {
1312                dev_err(dev, "Failed to sync regmap cache\n");
1313                goto err_disable_clk;
1314        }
1315
1316        /* Enable the whole hardware block */
1317        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1318                           SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
1319
1320        /* Enable the first output line */
1321        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1322                           SUN4I_I2S_CTRL_SDO_EN_MASK,
1323                           SUN4I_I2S_CTRL_SDO_EN(0));
1324
1325        ret = clk_prepare_enable(i2s->mod_clk);
1326        if (ret) {
1327                dev_err(dev, "Failed to enable module clock\n");
1328                goto err_disable_clk;
1329        }
1330
1331        return 0;
1332
1333err_disable_clk:
1334        clk_disable_unprepare(i2s->bus_clk);
1335        return ret;
1336}
1337
1338static int sun4i_i2s_runtime_suspend(struct device *dev)
1339{
1340        struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1341
1342        clk_disable_unprepare(i2s->mod_clk);
1343
1344        /* Disable our output lines */
1345        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1346                           SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
1347
1348        /* Disable the whole hardware block */
1349        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1350                           SUN4I_I2S_CTRL_GL_EN, 0);
1351
1352        regcache_cache_only(i2s->regmap, true);
1353
1354        clk_disable_unprepare(i2s->bus_clk);
1355
1356        return 0;
1357}
1358
1359#define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
1360#define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
1361
1362static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
1363        .has_reset              = false,
1364        .pcm_formats            = SUN4I_FORMATS_A10,
1365        .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1366        .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1367        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1368        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1369        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1370        .bclk_dividers          = sun4i_i2s_bclk_div,
1371        .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1372        .mclk_dividers          = sun4i_i2s_mclk_div,
1373        .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1374        .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1375        .get_sr                 = sun4i_i2s_get_sr,
1376        .get_wss                = sun4i_i2s_get_wss,
1377        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1378        .set_fmt                = sun4i_i2s_set_soc_fmt,
1379};
1380
1381static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
1382        .has_reset              = true,
1383        .pcm_formats            = SUN4I_FORMATS_A10,
1384        .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1385        .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1386        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1387        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1388        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1389        .bclk_dividers          = sun4i_i2s_bclk_div,
1390        .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1391        .mclk_dividers          = sun4i_i2s_mclk_div,
1392        .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1393        .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1394        .get_sr                 = sun4i_i2s_get_sr,
1395        .get_wss                = sun4i_i2s_get_wss,
1396        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1397        .set_fmt                = sun4i_i2s_set_soc_fmt,
1398};
1399
1400/*
1401 * This doesn't describe the TDM controller documented in the A83t
1402 * datasheet, but the three undocumented I2S controller that use the
1403 * older design.
1404 */
1405static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1406        .has_reset              = true,
1407        .pcm_formats            = SUN4I_FORMATS_A10,
1408        .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1409        .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1410        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1411        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1412        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1413        .bclk_dividers          = sun4i_i2s_bclk_div,
1414        .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1415        .mclk_dividers          = sun4i_i2s_mclk_div,
1416        .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1417        .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1418        .get_sr                 = sun4i_i2s_get_sr,
1419        .get_wss                = sun4i_i2s_get_wss,
1420        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1421        .set_fmt                = sun4i_i2s_set_soc_fmt,
1422};
1423
1424static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1425        .has_reset              = true,
1426        .pcm_formats            = SUN4I_FORMATS_H3,
1427        .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1428        .sun4i_i2s_regmap       = &sun8i_i2s_regmap_config,
1429        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1430        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1431        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1432        .bclk_dividers          = sun8i_i2s_clk_div,
1433        .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1434        .mclk_dividers          = sun8i_i2s_clk_div,
1435        .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1436        .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1437        .get_sr                 = sun8i_i2s_get_sr_wss,
1438        .get_wss                = sun8i_i2s_get_sr_wss,
1439        .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
1440        .set_fmt                = sun8i_i2s_set_soc_fmt,
1441};
1442
1443static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1444        .has_reset              = true,
1445        .pcm_formats            = SUN4I_FORMATS_H3,
1446        .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1447        .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1448        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1449        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1450        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1451        .bclk_dividers          = sun4i_i2s_bclk_div,
1452        .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1453        .mclk_dividers          = sun4i_i2s_mclk_div,
1454        .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1455        .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1456        .get_sr                 = sun4i_i2s_get_sr,
1457        .get_wss                = sun4i_i2s_get_wss,
1458        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1459        .set_fmt                = sun4i_i2s_set_soc_fmt,
1460};
1461
1462static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
1463        .has_reset              = true,
1464        .pcm_formats            = SUN4I_FORMATS_H3,
1465        .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1466        .sun4i_i2s_regmap       = &sun50i_h6_i2s_regmap_config,
1467        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1468        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1469        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1470        .bclk_dividers          = sun8i_i2s_clk_div,
1471        .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1472        .mclk_dividers          = sun8i_i2s_clk_div,
1473        .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1474        .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1475        .get_sr                 = sun8i_i2s_get_sr_wss,
1476        .get_wss                = sun8i_i2s_get_sr_wss,
1477        .set_chan_cfg           = sun50i_h6_i2s_set_chan_cfg,
1478        .set_fmt                = sun50i_h6_i2s_set_soc_fmt,
1479};
1480
1481static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
1482        .has_reset              = true,
1483        .pcm_formats            = SUN4I_FORMATS_H3,
1484        .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1485        .sun4i_i2s_regmap       = &sun50i_h6_i2s_regmap_config,
1486        .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1487        .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1488        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1489        .num_din_pins           = 4,
1490        .num_dout_pins          = 4,
1491        .bclk_dividers          = sun8i_i2s_clk_div,
1492        .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1493        .mclk_dividers          = sun8i_i2s_clk_div,
1494        .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1495        .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1496        .get_sr                 = sun8i_i2s_get_sr_wss,
1497        .get_wss                = sun8i_i2s_get_sr_wss,
1498        .set_chan_cfg           = sun50i_h6_i2s_set_chan_cfg,
1499        .set_fmt                = sun50i_h6_i2s_set_soc_fmt,
1500};
1501
1502static int sun4i_i2s_init_regmap_fields(struct device *dev,
1503                                        struct sun4i_i2s *i2s)
1504{
1505        i2s->field_clkdiv_mclk_en =
1506                devm_regmap_field_alloc(dev, i2s->regmap,
1507                                        i2s->variant->field_clkdiv_mclk_en);
1508        if (IS_ERR(i2s->field_clkdiv_mclk_en))
1509                return PTR_ERR(i2s->field_clkdiv_mclk_en);
1510
1511        i2s->field_fmt_wss =
1512                        devm_regmap_field_alloc(dev, i2s->regmap,
1513                                                i2s->variant->field_fmt_wss);
1514        if (IS_ERR(i2s->field_fmt_wss))
1515                return PTR_ERR(i2s->field_fmt_wss);
1516
1517        i2s->field_fmt_sr =
1518                        devm_regmap_field_alloc(dev, i2s->regmap,
1519                                                i2s->variant->field_fmt_sr);
1520        if (IS_ERR(i2s->field_fmt_sr))
1521                return PTR_ERR(i2s->field_fmt_sr);
1522
1523        return 0;
1524}
1525
1526static int sun4i_i2s_probe(struct platform_device *pdev)
1527{
1528        struct sun4i_i2s *i2s;
1529        struct resource *res;
1530        void __iomem *regs;
1531        int irq, ret;
1532
1533        i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
1534        if (!i2s)
1535                return -ENOMEM;
1536        platform_set_drvdata(pdev, i2s);
1537
1538        regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1539        if (IS_ERR(regs))
1540                return PTR_ERR(regs);
1541
1542        irq = platform_get_irq(pdev, 0);
1543        if (irq < 0)
1544                return irq;
1545
1546        i2s->variant = of_device_get_match_data(&pdev->dev);
1547        if (!i2s->variant) {
1548                dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1549                return -ENODEV;
1550        }
1551
1552        i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
1553        if (IS_ERR(i2s->bus_clk)) {
1554                dev_err(&pdev->dev, "Can't get our bus clock\n");
1555                return PTR_ERR(i2s->bus_clk);
1556        }
1557
1558        i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1559                                            i2s->variant->sun4i_i2s_regmap);
1560        if (IS_ERR(i2s->regmap)) {
1561                dev_err(&pdev->dev, "Regmap initialisation failed\n");
1562                return PTR_ERR(i2s->regmap);
1563        }
1564
1565        i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
1566        if (IS_ERR(i2s->mod_clk)) {
1567                dev_err(&pdev->dev, "Can't get our mod clock\n");
1568                return PTR_ERR(i2s->mod_clk);
1569        }
1570
1571        if (i2s->variant->has_reset) {
1572                i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
1573                if (IS_ERR(i2s->rst)) {
1574                        dev_err(&pdev->dev, "Failed to get reset control\n");
1575                        return PTR_ERR(i2s->rst);
1576                }
1577        }
1578
1579        if (!IS_ERR(i2s->rst)) {
1580                ret = reset_control_deassert(i2s->rst);
1581                if (ret) {
1582                        dev_err(&pdev->dev,
1583                                "Failed to deassert the reset control\n");
1584                        return -EINVAL;
1585                }
1586        }
1587
1588        i2s->playback_dma_data.addr = res->start +
1589                                        i2s->variant->reg_offset_txdata;
1590        i2s->playback_dma_data.maxburst = 8;
1591
1592        i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
1593        i2s->capture_dma_data.maxburst = 8;
1594
1595        pm_runtime_enable(&pdev->dev);
1596        if (!pm_runtime_enabled(&pdev->dev)) {
1597                ret = sun4i_i2s_runtime_resume(&pdev->dev);
1598                if (ret)
1599                        goto err_pm_disable;
1600        }
1601
1602        ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
1603        if (ret) {
1604                dev_err(&pdev->dev, "Could not initialise regmap fields\n");
1605                goto err_suspend;
1606        }
1607
1608        ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1609        if (ret) {
1610                dev_err(&pdev->dev, "Could not register PCM\n");
1611                goto err_suspend;
1612        }
1613
1614        ret = devm_snd_soc_register_component(&pdev->dev,
1615                                              &sun4i_i2s_component,
1616                                              &sun4i_i2s_dai, 1);
1617        if (ret) {
1618                dev_err(&pdev->dev, "Could not register DAI\n");
1619                goto err_suspend;
1620        }
1621
1622        return 0;
1623
1624err_suspend:
1625        if (!pm_runtime_status_suspended(&pdev->dev))
1626                sun4i_i2s_runtime_suspend(&pdev->dev);
1627err_pm_disable:
1628        pm_runtime_disable(&pdev->dev);
1629        if (!IS_ERR(i2s->rst))
1630                reset_control_assert(i2s->rst);
1631
1632        return ret;
1633}
1634
1635static void sun4i_i2s_remove(struct platform_device *pdev)
1636{
1637        struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1638
1639        pm_runtime_disable(&pdev->dev);
1640        if (!pm_runtime_status_suspended(&pdev->dev))
1641                sun4i_i2s_runtime_suspend(&pdev->dev);
1642
1643        if (!IS_ERR(i2s->rst))
1644                reset_control_assert(i2s->rst);
1645}
1646
1647static const struct of_device_id sun4i_i2s_match[] = {
1648        {
1649                .compatible = "allwinner,sun4i-a10-i2s",
1650                .data = &sun4i_a10_i2s_quirks,
1651        },
1652        {
1653                .compatible = "allwinner,sun6i-a31-i2s",
1654                .data = &sun6i_a31_i2s_quirks,
1655        },
1656        {
1657                .compatible = "allwinner,sun8i-a83t-i2s",
1658                .data = &sun8i_a83t_i2s_quirks,
1659        },
1660        {
1661                .compatible = "allwinner,sun8i-h3-i2s",
1662                .data = &sun8i_h3_i2s_quirks,
1663        },
1664        {
1665                .compatible = "allwinner,sun50i-a64-codec-i2s",
1666                .data = &sun50i_a64_codec_i2s_quirks,
1667        },
1668        {
1669                .compatible = "allwinner,sun50i-h6-i2s",
1670                .data = &sun50i_h6_i2s_quirks,
1671        },
1672        {
1673                .compatible = "allwinner,sun50i-r329-i2s",
1674                .data = &sun50i_r329_i2s_quirks,
1675        },
1676        {}
1677};
1678MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1679
1680static const struct dev_pm_ops sun4i_i2s_pm_ops = {
1681        .runtime_resume         = sun4i_i2s_runtime_resume,
1682        .runtime_suspend        = sun4i_i2s_runtime_suspend,
1683};
1684
1685static struct platform_driver sun4i_i2s_driver = {
1686        .probe  = sun4i_i2s_probe,
1687        .remove = sun4i_i2s_remove,
1688        .driver = {
1689                .name           = "sun4i-i2s",
1690                .of_match_table = sun4i_i2s_match,
1691                .pm             = &sun4i_i2s_pm_ops,
1692        },
1693};
1694module_platform_driver(sun4i_i2s_driver);
1695
1696MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1697MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1698MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1699MODULE_LICENSE("GPL");
1700