linux/sound/soc/sunxi/sun4i-i2s.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Andrea Venturi
   3 * Andrea Venturi <be17068@iperbole.bo.it>
   4 *
   5 * Copyright (C) 2016 Maxime Ripard
   6 * Maxime Ripard <maxime.ripard@free-electrons.com>
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/dmaengine.h>
  16#include <linux/module.h>
  17#include <linux/of_device.h>
  18#include <linux/platform_device.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/regmap.h>
  21#include <linux/reset.h>
  22
  23#include <sound/dmaengine_pcm.h>
  24#include <sound/pcm_params.h>
  25#include <sound/soc.h>
  26#include <sound/soc-dai.h>
  27
  28#define SUN4I_I2S_CTRL_REG              0x00
  29#define SUN4I_I2S_CTRL_SDO_EN_MASK              GENMASK(11, 8)
  30#define SUN4I_I2S_CTRL_SDO_EN(sdo)                      BIT(8 + (sdo))
  31#define SUN4I_I2S_CTRL_MODE_MASK                BIT(5)
  32#define SUN4I_I2S_CTRL_MODE_SLAVE                       (1 << 5)
  33#define SUN4I_I2S_CTRL_MODE_MASTER                      (0 << 5)
  34#define SUN4I_I2S_CTRL_TX_EN                    BIT(2)
  35#define SUN4I_I2S_CTRL_RX_EN                    BIT(1)
  36#define SUN4I_I2S_CTRL_GL_EN                    BIT(0)
  37
  38#define SUN4I_I2S_FMT0_REG              0x04
  39#define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(7)
  40#define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED          (1 << 7)
  41#define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL            (0 << 7)
  42#define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(6)
  43#define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 6)
  44#define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 6)
  45#define SUN4I_I2S_FMT0_SR_MASK                  GENMASK(5, 4)
  46#define SUN4I_I2S_FMT0_SR(sr)                           ((sr) << 4)
  47#define SUN4I_I2S_FMT0_WSS_MASK                 GENMASK(3, 2)
  48#define SUN4I_I2S_FMT0_WSS(wss)                         ((wss) << 2)
  49#define SUN4I_I2S_FMT0_FMT_MASK                 GENMASK(1, 0)
  50#define SUN4I_I2S_FMT0_FMT_RIGHT_J                      (2 << 0)
  51#define SUN4I_I2S_FMT0_FMT_LEFT_J                       (1 << 0)
  52#define SUN4I_I2S_FMT0_FMT_I2S                          (0 << 0)
  53
  54#define SUN4I_I2S_FMT1_REG              0x08
  55#define SUN4I_I2S_FIFO_TX_REG           0x0c
  56#define SUN4I_I2S_FIFO_RX_REG           0x10
  57
  58#define SUN4I_I2S_FIFO_CTRL_REG         0x14
  59#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX            BIT(25)
  60#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX            BIT(24)
  61#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK        BIT(2)
  62#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)               ((mode) << 2)
  63#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK        GENMASK(1, 0)
  64#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)               (mode)
  65
  66#define SUN4I_I2S_FIFO_STA_REG          0x18
  67
  68#define SUN4I_I2S_DMA_INT_CTRL_REG      0x1c
  69#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN        BIT(7)
  70#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN        BIT(3)
  71
  72#define SUN4I_I2S_INT_STA_REG           0x20
  73
  74#define SUN4I_I2S_CLK_DIV_REG           0x24
  75#define SUN4I_I2S_CLK_DIV_MCLK_EN               BIT(7)
  76#define SUN4I_I2S_CLK_DIV_BCLK_MASK             GENMASK(6, 4)
  77#define SUN4I_I2S_CLK_DIV_BCLK(bclk)                    ((bclk) << 4)
  78#define SUN4I_I2S_CLK_DIV_MCLK_MASK             GENMASK(3, 0)
  79#define SUN4I_I2S_CLK_DIV_MCLK(mclk)                    ((mclk) << 0)
  80
  81#define SUN4I_I2S_RX_CNT_REG            0x28
  82#define SUN4I_I2S_TX_CNT_REG            0x2c
  83
  84#define SUN4I_I2S_TX_CHAN_SEL_REG       0x30
  85#define SUN4I_I2S_TX_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
  93struct sun4i_i2s {
  94        struct clk      *bus_clk;
  95        struct clk      *mod_clk;
  96        struct regmap   *regmap;
  97        struct reset_control *rst;
  98
  99        unsigned int    mclk_freq;
 100
 101        struct snd_dmaengine_dai_dma_data       capture_dma_data;
 102        struct snd_dmaengine_dai_dma_data       playback_dma_data;
 103};
 104
 105struct sun4i_i2s_clk_div {
 106        u8      div;
 107        u8      val;
 108};
 109
 110static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 111        { .div = 2, .val = 0 },
 112        { .div = 4, .val = 1 },
 113        { .div = 6, .val = 2 },
 114        { .div = 8, .val = 3 },
 115        { .div = 12, .val = 4 },
 116        { .div = 16, .val = 5 },
 117};
 118
 119static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
 120        { .div = 1, .val = 0 },
 121        { .div = 2, .val = 1 },
 122        { .div = 4, .val = 2 },
 123        { .div = 6, .val = 3 },
 124        { .div = 8, .val = 4 },
 125        { .div = 12, .val = 5 },
 126        { .div = 16, .val = 6 },
 127        { .div = 24, .val = 7 },
 128};
 129
 130static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
 131                                  unsigned int oversample_rate,
 132                                  unsigned int word_size)
 133{
 134        int div = oversample_rate / word_size / 2;
 135        int i;
 136
 137        for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
 138                const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i];
 139
 140                if (bdiv->div == div)
 141                        return bdiv->val;
 142        }
 143
 144        return -EINVAL;
 145}
 146
 147static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
 148                                  unsigned int oversample_rate,
 149                                  unsigned int module_rate,
 150                                  unsigned int sampling_rate)
 151{
 152        int div = module_rate / sampling_rate / oversample_rate;
 153        int i;
 154
 155        for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) {
 156                const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i];
 157
 158                if (mdiv->div == div)
 159                        return mdiv->val;
 160        }
 161
 162        return -EINVAL;
 163}
 164
 165static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
 166static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
 167{
 168        int i;
 169
 170        for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
 171                if (sun4i_i2s_oversample_rates[i] == oversample)
 172                        return true;
 173
 174        return false;
 175}
 176
 177static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
 178                                  unsigned int rate,
 179                                  unsigned int word_size)
 180{
 181        unsigned int oversample_rate, clk_rate;
 182        int bclk_div, mclk_div;
 183        int ret;
 184
 185        switch (rate) {
 186        case 176400:
 187        case 88200:
 188        case 44100:
 189        case 22050:
 190        case 11025:
 191                clk_rate = 22579200;
 192                break;
 193
 194        case 192000:
 195        case 128000:
 196        case 96000:
 197        case 64000:
 198        case 48000:
 199        case 32000:
 200        case 24000:
 201        case 16000:
 202        case 12000:
 203        case 8000:
 204                clk_rate = 24576000;
 205                break;
 206
 207        default:
 208                return -EINVAL;
 209        }
 210
 211        ret = clk_set_rate(i2s->mod_clk, clk_rate);
 212        if (ret)
 213                return ret;
 214
 215        oversample_rate = i2s->mclk_freq / rate;
 216        if (!sun4i_i2s_oversample_is_valid(oversample_rate))
 217                return -EINVAL;
 218
 219        bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
 220                                          word_size);
 221        if (bclk_div < 0)
 222                return -EINVAL;
 223
 224        mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
 225                                          clk_rate, rate);
 226        if (mclk_div < 0)
 227                return -EINVAL;
 228
 229        regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
 230                     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
 231                     SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
 232                     SUN4I_I2S_CLK_DIV_MCLK_EN);
 233
 234        return 0;
 235}
 236
 237static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
 238                               struct snd_pcm_hw_params *params,
 239                               struct snd_soc_dai *dai)
 240{
 241        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 242        int sr, wss;
 243        u32 width;
 244
 245        if (params_channels(params) != 2)
 246                return -EINVAL;
 247
 248        switch (params_physical_width(params)) {
 249        case 16:
 250                width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 251                break;
 252        default:
 253                return -EINVAL;
 254        }
 255        i2s->playback_dma_data.addr_width = width;
 256
 257        switch (params_width(params)) {
 258        case 16:
 259                sr = 0;
 260                wss = 0;
 261                break;
 262
 263        default:
 264                return -EINVAL;
 265        }
 266
 267        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 268                           SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
 269                           SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
 270
 271        return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
 272                                      params_width(params));
 273}
 274
 275static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 276{
 277        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 278        u32 val;
 279
 280        /* DAI Mode */
 281        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 282        case SND_SOC_DAIFMT_I2S:
 283                val = SUN4I_I2S_FMT0_FMT_I2S;
 284                break;
 285        case SND_SOC_DAIFMT_LEFT_J:
 286                val = SUN4I_I2S_FMT0_FMT_LEFT_J;
 287                break;
 288        case SND_SOC_DAIFMT_RIGHT_J:
 289                val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
 290                break;
 291        default:
 292                return -EINVAL;
 293        }
 294
 295        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 296                           SUN4I_I2S_FMT0_FMT_MASK,
 297                           val);
 298
 299        /* DAI clock polarity */
 300        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 301        case SND_SOC_DAIFMT_IB_IF:
 302                /* Invert both clocks */
 303                val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
 304                        SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
 305                break;
 306        case SND_SOC_DAIFMT_IB_NF:
 307                /* Invert bit clock */
 308                val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
 309                        SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
 310                break;
 311        case SND_SOC_DAIFMT_NB_IF:
 312                /* Invert frame clock */
 313                val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED |
 314                        SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL;
 315                break;
 316        case SND_SOC_DAIFMT_NB_NF:
 317                /* Nothing to do for both normal cases */
 318                val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL |
 319                        SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
 320                break;
 321        default:
 322                return -EINVAL;
 323        }
 324
 325        regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
 326                           SUN4I_I2S_FMT0_BCLK_POLARITY_MASK |
 327                           SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK,
 328                           val);
 329
 330        /* DAI clock master masks */
 331        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 332        case SND_SOC_DAIFMT_CBS_CFS:
 333                /* BCLK and LRCLK master */
 334                val = SUN4I_I2S_CTRL_MODE_MASTER;
 335                break;
 336        case SND_SOC_DAIFMT_CBM_CFM:
 337                /* BCLK and LRCLK slave */
 338                val = SUN4I_I2S_CTRL_MODE_SLAVE;
 339                break;
 340        default:
 341                return -EINVAL;
 342        }
 343
 344        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 345                           SUN4I_I2S_CTRL_MODE_MASK,
 346                           val);
 347
 348        /* Set significant bits in our FIFOs */
 349        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 350                           SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
 351                           SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
 352                           SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
 353                           SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
 354        return 0;
 355}
 356
 357static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
 358{
 359        /* Flush RX FIFO */
 360        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 361                           SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
 362                           SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
 363
 364        /* Clear RX counter */
 365        regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
 366
 367        /* Enable RX Block */
 368        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 369                           SUN4I_I2S_CTRL_RX_EN,
 370                           SUN4I_I2S_CTRL_RX_EN);
 371
 372        /* Enable RX DRQ */
 373        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 374                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
 375                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
 376}
 377
 378static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
 379{
 380        /* Flush TX FIFO */
 381        regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
 382                           SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
 383                           SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
 384
 385        /* Clear TX counter */
 386        regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
 387
 388        /* Enable TX Block */
 389        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 390                           SUN4I_I2S_CTRL_TX_EN,
 391                           SUN4I_I2S_CTRL_TX_EN);
 392
 393        /* Enable TX DRQ */
 394        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 395                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
 396                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
 397}
 398
 399static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
 400{
 401        /* Disable RX Block */
 402        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 403                           SUN4I_I2S_CTRL_RX_EN,
 404                           0);
 405
 406        /* Disable RX DRQ */
 407        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 408                           SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
 409                           0);
 410}
 411
 412static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
 413{
 414        /* Disable TX Block */
 415        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 416                           SUN4I_I2S_CTRL_TX_EN,
 417                           0);
 418
 419        /* Disable TX DRQ */
 420        regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
 421                           SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
 422                           0);
 423}
 424
 425static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 426                             struct snd_soc_dai *dai)
 427{
 428        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 429
 430        switch (cmd) {
 431        case SNDRV_PCM_TRIGGER_START:
 432        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 433        case SNDRV_PCM_TRIGGER_RESUME:
 434                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 435                        sun4i_i2s_start_playback(i2s);
 436                else
 437                        sun4i_i2s_start_capture(i2s);
 438                break;
 439
 440        case SNDRV_PCM_TRIGGER_STOP:
 441        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 442        case SNDRV_PCM_TRIGGER_SUSPEND:
 443                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 444                        sun4i_i2s_stop_playback(i2s);
 445                else
 446                        sun4i_i2s_stop_capture(i2s);
 447                break;
 448
 449        default:
 450                return -EINVAL;
 451        }
 452
 453        return 0;
 454}
 455
 456static int sun4i_i2s_startup(struct snd_pcm_substream *substream,
 457                             struct snd_soc_dai *dai)
 458{
 459        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 460
 461        /* Enable the whole hardware block */
 462        regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG,
 463                     SUN4I_I2S_CTRL_GL_EN);
 464
 465        /* Enable the first output line */
 466        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 467                           SUN4I_I2S_CTRL_SDO_EN_MASK,
 468                           SUN4I_I2S_CTRL_SDO_EN(0));
 469
 470        /* Enable the first two channels */
 471        regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
 472                     SUN4I_I2S_TX_CHAN_SEL(2));
 473
 474        /* Map them to the two first samples coming in */
 475        regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG,
 476                     SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1));
 477
 478        return clk_prepare_enable(i2s->mod_clk);
 479}
 480
 481static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream,
 482                               struct snd_soc_dai *dai)
 483{
 484        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 485
 486        clk_disable_unprepare(i2s->mod_clk);
 487
 488        /* Disable our output lines */
 489        regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
 490                           SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
 491
 492        /* Disable the whole hardware block */
 493        regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0);
 494}
 495
 496static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 497                                unsigned int freq, int dir)
 498{
 499        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 500
 501        if (clk_id != 0)
 502                return -EINVAL;
 503
 504        i2s->mclk_freq = freq;
 505
 506        return 0;
 507}
 508
 509static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 510        .hw_params      = sun4i_i2s_hw_params,
 511        .set_fmt        = sun4i_i2s_set_fmt,
 512        .set_sysclk     = sun4i_i2s_set_sysclk,
 513        .shutdown       = sun4i_i2s_shutdown,
 514        .startup        = sun4i_i2s_startup,
 515        .trigger        = sun4i_i2s_trigger,
 516};
 517
 518static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 519{
 520        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 521
 522        snd_soc_dai_init_dma_data(dai,
 523                                  &i2s->playback_dma_data,
 524                                  &i2s->capture_dma_data);
 525
 526        snd_soc_dai_set_drvdata(dai, i2s);
 527
 528        return 0;
 529}
 530
 531static struct snd_soc_dai_driver sun4i_i2s_dai = {
 532        .probe = sun4i_i2s_dai_probe,
 533        .capture = {
 534                .stream_name = "Capture",
 535                .channels_min = 2,
 536                .channels_max = 2,
 537                .rates = SNDRV_PCM_RATE_8000_192000,
 538                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 539        },
 540        .playback = {
 541                .stream_name = "Playback",
 542                .channels_min = 2,
 543                .channels_max = 2,
 544                .rates = SNDRV_PCM_RATE_8000_192000,
 545                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 546        },
 547        .ops = &sun4i_i2s_dai_ops,
 548        .symmetric_rates = 1,
 549};
 550
 551static const struct snd_soc_component_driver sun4i_i2s_component = {
 552        .name   = "sun4i-dai",
 553};
 554
 555static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
 556{
 557        switch (reg) {
 558        case SUN4I_I2S_FIFO_TX_REG:
 559                return false;
 560
 561        default:
 562                return true;
 563        }
 564}
 565
 566static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
 567{
 568        switch (reg) {
 569        case SUN4I_I2S_FIFO_RX_REG:
 570        case SUN4I_I2S_FIFO_STA_REG:
 571                return false;
 572
 573        default:
 574                return true;
 575        }
 576}
 577
 578static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
 579{
 580        switch (reg) {
 581        case SUN4I_I2S_FIFO_RX_REG:
 582        case SUN4I_I2S_INT_STA_REG:
 583        case SUN4I_I2S_RX_CNT_REG:
 584        case SUN4I_I2S_TX_CNT_REG:
 585                return true;
 586
 587        default:
 588                return false;
 589        }
 590}
 591
 592static const struct reg_default sun4i_i2s_reg_defaults[] = {
 593        { SUN4I_I2S_CTRL_REG, 0x00000000 },
 594        { SUN4I_I2S_FMT0_REG, 0x0000000c },
 595        { SUN4I_I2S_FMT1_REG, 0x00004020 },
 596        { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
 597        { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
 598        { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
 599        { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
 600        { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
 601        { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
 602        { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
 603};
 604
 605static const struct regmap_config sun4i_i2s_regmap_config = {
 606        .reg_bits       = 32,
 607        .reg_stride     = 4,
 608        .val_bits       = 32,
 609        .max_register   = SUN4I_I2S_RX_CHAN_MAP_REG,
 610
 611        .cache_type     = REGCACHE_FLAT,
 612        .reg_defaults   = sun4i_i2s_reg_defaults,
 613        .num_reg_defaults       = ARRAY_SIZE(sun4i_i2s_reg_defaults),
 614        .writeable_reg  = sun4i_i2s_wr_reg,
 615        .readable_reg   = sun4i_i2s_rd_reg,
 616        .volatile_reg   = sun4i_i2s_volatile_reg,
 617};
 618
 619static int sun4i_i2s_runtime_resume(struct device *dev)
 620{
 621        struct sun4i_i2s *i2s = dev_get_drvdata(dev);
 622        int ret;
 623
 624        ret = clk_prepare_enable(i2s->bus_clk);
 625        if (ret) {
 626                dev_err(dev, "Failed to enable bus clock\n");
 627                return ret;
 628        }
 629
 630        regcache_cache_only(i2s->regmap, false);
 631        regcache_mark_dirty(i2s->regmap);
 632
 633        ret = regcache_sync(i2s->regmap);
 634        if (ret) {
 635                dev_err(dev, "Failed to sync regmap cache\n");
 636                goto err_disable_clk;
 637        }
 638
 639        return 0;
 640
 641err_disable_clk:
 642        clk_disable_unprepare(i2s->bus_clk);
 643        return ret;
 644}
 645
 646static int sun4i_i2s_runtime_suspend(struct device *dev)
 647{
 648        struct sun4i_i2s *i2s = dev_get_drvdata(dev);
 649
 650        regcache_cache_only(i2s->regmap, true);
 651
 652        clk_disable_unprepare(i2s->bus_clk);
 653
 654        return 0;
 655}
 656
 657struct sun4i_i2s_quirks {
 658        bool has_reset;
 659};
 660
 661static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 662        .has_reset      = false,
 663};
 664
 665static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 666        .has_reset      = true,
 667};
 668
 669static int sun4i_i2s_probe(struct platform_device *pdev)
 670{
 671        struct sun4i_i2s *i2s;
 672        const struct sun4i_i2s_quirks *quirks;
 673        struct resource *res;
 674        void __iomem *regs;
 675        int irq, ret;
 676
 677        i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
 678        if (!i2s)
 679                return -ENOMEM;
 680        platform_set_drvdata(pdev, i2s);
 681
 682        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 683        regs = devm_ioremap_resource(&pdev->dev, res);
 684        if (IS_ERR(regs))
 685                return PTR_ERR(regs);
 686
 687        irq = platform_get_irq(pdev, 0);
 688        if (irq < 0) {
 689                dev_err(&pdev->dev, "Can't retrieve our interrupt\n");
 690                return irq;
 691        }
 692
 693        quirks = of_device_get_match_data(&pdev->dev);
 694        if (!quirks) {
 695                dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
 696                return -ENODEV;
 697        }
 698
 699        i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
 700        if (IS_ERR(i2s->bus_clk)) {
 701                dev_err(&pdev->dev, "Can't get our bus clock\n");
 702                return PTR_ERR(i2s->bus_clk);
 703        }
 704
 705        i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
 706                                            &sun4i_i2s_regmap_config);
 707        if (IS_ERR(i2s->regmap)) {
 708                dev_err(&pdev->dev, "Regmap initialisation failed\n");
 709                return PTR_ERR(i2s->regmap);
 710        }
 711
 712        i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
 713        if (IS_ERR(i2s->mod_clk)) {
 714                dev_err(&pdev->dev, "Can't get our mod clock\n");
 715                return PTR_ERR(i2s->mod_clk);
 716        }
 717
 718        if (quirks->has_reset) {
 719                i2s->rst = devm_reset_control_get(&pdev->dev, NULL);
 720                if (IS_ERR(i2s->rst)) {
 721                        dev_err(&pdev->dev, "Failed to get reset control\n");
 722                        return PTR_ERR(i2s->rst);
 723                }
 724        }
 725
 726        if (!IS_ERR(i2s->rst)) {
 727                ret = reset_control_deassert(i2s->rst);
 728                if (ret) {
 729                        dev_err(&pdev->dev,
 730                                "Failed to deassert the reset control\n");
 731                        return -EINVAL;
 732                }
 733        }
 734
 735        i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
 736        i2s->playback_dma_data.maxburst = 8;
 737
 738        i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 739        i2s->capture_dma_data.maxburst = 8;
 740
 741        pm_runtime_enable(&pdev->dev);
 742        if (!pm_runtime_enabled(&pdev->dev)) {
 743                ret = sun4i_i2s_runtime_resume(&pdev->dev);
 744                if (ret)
 745                        goto err_pm_disable;
 746        }
 747
 748        ret = devm_snd_soc_register_component(&pdev->dev,
 749                                              &sun4i_i2s_component,
 750                                              &sun4i_i2s_dai, 1);
 751        if (ret) {
 752                dev_err(&pdev->dev, "Could not register DAI\n");
 753                goto err_suspend;
 754        }
 755
 756        ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 757        if (ret) {
 758                dev_err(&pdev->dev, "Could not register PCM\n");
 759                goto err_suspend;
 760        }
 761
 762        return 0;
 763
 764err_suspend:
 765        if (!pm_runtime_status_suspended(&pdev->dev))
 766                sun4i_i2s_runtime_suspend(&pdev->dev);
 767err_pm_disable:
 768        pm_runtime_disable(&pdev->dev);
 769        if (!IS_ERR(i2s->rst))
 770                reset_control_assert(i2s->rst);
 771
 772        return ret;
 773}
 774
 775static int sun4i_i2s_remove(struct platform_device *pdev)
 776{
 777        struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
 778
 779        snd_dmaengine_pcm_unregister(&pdev->dev);
 780
 781        pm_runtime_disable(&pdev->dev);
 782        if (!pm_runtime_status_suspended(&pdev->dev))
 783                sun4i_i2s_runtime_suspend(&pdev->dev);
 784
 785        if (!IS_ERR(i2s->rst))
 786                reset_control_assert(i2s->rst);
 787
 788        return 0;
 789}
 790
 791static const struct of_device_id sun4i_i2s_match[] = {
 792        {
 793                .compatible = "allwinner,sun4i-a10-i2s",
 794                .data = &sun4i_a10_i2s_quirks,
 795        },
 796        {
 797                .compatible = "allwinner,sun6i-a31-i2s",
 798                .data = &sun6i_a31_i2s_quirks,
 799        },
 800        {}
 801};
 802MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
 803
 804static const struct dev_pm_ops sun4i_i2s_pm_ops = {
 805        .runtime_resume         = sun4i_i2s_runtime_resume,
 806        .runtime_suspend        = sun4i_i2s_runtime_suspend,
 807};
 808
 809static struct platform_driver sun4i_i2s_driver = {
 810        .probe  = sun4i_i2s_probe,
 811        .remove = sun4i_i2s_remove,
 812        .driver = {
 813                .name           = "sun4i-i2s",
 814                .of_match_table = sun4i_i2s_match,
 815                .pm             = &sun4i_i2s_pm_ops,
 816        },
 817};
 818module_platform_driver(sun4i_i2s_driver);
 819
 820MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
 821MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
 822MODULE_DESCRIPTION("Allwinner A10 I2S driver");
 823MODULE_LICENSE("GPL");
 824