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