linux/sound/soc/hisilicon/hi6210-i2s.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/sound/soc/m8m/hi6210_i2s.c - I2S IP driver
   4 *
   5 * Copyright (C) 2015 Linaro, Ltd
   6 * Author: Andy Green <andy.green@linaro.org>
   7 *
   8 * This driver only deals with S2 interface (BT)
   9 */
  10
  11#include <linux/init.h>
  12#include <linux/module.h>
  13#include <linux/device.h>
  14#include <linux/delay.h>
  15#include <linux/clk.h>
  16#include <linux/jiffies.h>
  17#include <linux/io.h>
  18#include <sound/core.h>
  19#include <sound/pcm.h>
  20#include <sound/pcm_params.h>
  21#include <sound/dmaengine_pcm.h>
  22#include <sound/initval.h>
  23#include <sound/soc.h>
  24#include <linux/interrupt.h>
  25#include <linux/reset.h>
  26#include <linux/of_address.h>
  27#include <linux/of_irq.h>
  28#include <linux/mfd/syscon.h>
  29#include <linux/reset-controller.h>
  30
  31#include "hi6210-i2s.h"
  32
  33struct hi6210_i2s {
  34        struct device *dev;
  35        struct reset_control *rc;
  36        struct clk *clk[8];
  37        int clocks;
  38        struct snd_soc_dai_driver dai;
  39        void __iomem *base;
  40        struct regmap *sysctrl;
  41        phys_addr_t base_phys;
  42        struct snd_dmaengine_dai_dma_data dma_data[2];
  43        int clk_rate;
  44        spinlock_t lock;
  45        int rate;
  46        int format;
  47        u8 bits;
  48        u8 channels;
  49        u8 id;
  50        u8 channel_length;
  51        u8 use;
  52        u32 master:1;
  53        u32 status:1;
  54};
  55
  56#define SC_PERIPH_CLKEN1        0x210
  57#define SC_PERIPH_CLKDIS1       0x214
  58
  59#define SC_PERIPH_CLKEN3        0x230
  60#define SC_PERIPH_CLKDIS3       0x234
  61
  62#define SC_PERIPH_CLKEN12       0x270
  63#define SC_PERIPH_CLKDIS12      0x274
  64
  65#define SC_PERIPH_RSTEN1        0x310
  66#define SC_PERIPH_RSTDIS1       0x314
  67#define SC_PERIPH_RSTSTAT1      0x318
  68
  69#define SC_PERIPH_RSTEN2        0x320
  70#define SC_PERIPH_RSTDIS2       0x324
  71#define SC_PERIPH_RSTSTAT2      0x328
  72
  73#define SOC_PMCTRL_BBPPLLALIAS  0x48
  74
  75enum {
  76        CLK_DACODEC,
  77        CLK_I2S_BASE,
  78};
  79
  80static inline void hi6210_write_reg(struct hi6210_i2s *i2s, int reg, u32 val)
  81{
  82        writel(val, i2s->base + reg);
  83}
  84
  85static inline u32 hi6210_read_reg(struct hi6210_i2s *i2s, int reg)
  86{
  87        return readl(i2s->base + reg);
  88}
  89
  90static int hi6210_i2s_startup(struct snd_pcm_substream *substream,
  91                              struct snd_soc_dai *cpu_dai)
  92{
  93        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  94        int ret, n;
  95        u32 val;
  96
  97        /* deassert reset on ABB */
  98        regmap_read(i2s->sysctrl, SC_PERIPH_RSTSTAT2, &val);
  99        if (val & BIT(4))
 100                regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS2, BIT(4));
 101
 102        for (n = 0; n < i2s->clocks; n++) {
 103                ret = clk_prepare_enable(i2s->clk[n]);
 104                if (ret)
 105                        goto err_unprepare_clk;
 106        }
 107
 108        ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
 109        if (ret) {
 110                dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
 111                        __func__, ret);
 112                goto err_unprepare_clk;
 113        }
 114
 115        /* enable clock before frequency division */
 116        regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN12, BIT(9));
 117
 118        /* enable codec working clock / == "codec bus clock" */
 119        regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN1, BIT(5));
 120
 121        /* deassert reset on codec / interface clock / working clock */
 122        regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
 123        regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS1, BIT(5));
 124
 125        /* not interested in i2s irqs */
 126        val = hi6210_read_reg(i2s, HII2S_CODEC_IRQ_MASK);
 127        val |= 0x3f;
 128        hi6210_write_reg(i2s, HII2S_CODEC_IRQ_MASK, val);
 129
 130
 131        /* reset the stereo downlink fifo */
 132        val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
 133        val |= (BIT(5) | BIT(4));
 134        hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
 135
 136        val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
 137        val &= ~(BIT(5) | BIT(4));
 138        hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
 139
 140
 141        val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
 142        val &= ~(HII2S_SW_RST_N__ST_DL_WORDLEN_MASK <<
 143                        HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
 144        val |= (HII2S_BITS_16 << HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
 145        hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
 146
 147        val = hi6210_read_reg(i2s, HII2S_MISC_CFG);
 148        /* mux 11/12 = APB not i2s */
 149        val &= ~HII2S_MISC_CFG__ST_DL_TEST_SEL;
 150        /* BT R ch  0 = mixer op of DACR ch */
 151        val &= ~HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
 152        val &= ~HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
 153
 154        val |= HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
 155        /* BT L ch = 1 = mux 7 = "mixer output of DACL */
 156        val |= HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
 157        hi6210_write_reg(i2s, HII2S_MISC_CFG, val);
 158
 159        val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
 160        val |= HII2S_SW_RST_N__SW_RST_N;
 161        hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
 162
 163        return 0;
 164
 165err_unprepare_clk:
 166        while (n--)
 167                clk_disable_unprepare(i2s->clk[n]);
 168        return ret;
 169}
 170
 171static void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
 172                                struct snd_soc_dai *cpu_dai)
 173{
 174        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
 175        int n;
 176
 177        for (n = 0; n < i2s->clocks; n++)
 178                clk_disable_unprepare(i2s->clk[n]);
 179
 180        regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
 181}
 182
 183static void hi6210_i2s_txctrl(struct snd_soc_dai *cpu_dai, int on)
 184{
 185        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
 186        u32 val;
 187
 188        spin_lock(&i2s->lock);
 189        if (on) {
 190                /* enable S2 TX */
 191                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 192                val |= HII2S_I2S_CFG__S2_IF_TX_EN;
 193                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 194        } else {
 195                /* disable S2 TX */
 196                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 197                val &= ~HII2S_I2S_CFG__S2_IF_TX_EN;
 198                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 199        }
 200        spin_unlock(&i2s->lock);
 201}
 202
 203static void hi6210_i2s_rxctrl(struct snd_soc_dai *cpu_dai, int on)
 204{
 205        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
 206        u32 val;
 207
 208        spin_lock(&i2s->lock);
 209        if (on) {
 210                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 211                val |= HII2S_I2S_CFG__S2_IF_RX_EN;
 212                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 213        } else {
 214                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 215                val &= ~HII2S_I2S_CFG__S2_IF_RX_EN;
 216                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 217        }
 218        spin_unlock(&i2s->lock);
 219}
 220
 221static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 222{
 223        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
 224
 225        /*
 226         * We don't actually set the hardware until the hw_params
 227         * call, but we need to validate the user input here.
 228         */
 229        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 230        case SND_SOC_DAIFMT_BC_FC:
 231        case SND_SOC_DAIFMT_BP_FP:
 232                break;
 233        default:
 234                return -EINVAL;
 235        }
 236
 237        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 238        case SND_SOC_DAIFMT_I2S:
 239        case SND_SOC_DAIFMT_LEFT_J:
 240        case SND_SOC_DAIFMT_RIGHT_J:
 241                break;
 242        default:
 243                return -EINVAL;
 244        }
 245
 246        i2s->format = fmt;
 247        i2s->master = (i2s->format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) ==
 248                      SND_SOC_DAIFMT_BP_FP;
 249
 250        return 0;
 251}
 252
 253static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream,
 254                            struct snd_pcm_hw_params *params,
 255                            struct snd_soc_dai *cpu_dai)
 256{
 257        struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
 258        u32 bits = 0, rate = 0, signed_data = 0, fmt = 0;
 259        u32 val;
 260        struct snd_dmaengine_dai_dma_data *dma_data;
 261
 262        switch (params_format(params)) {
 263        case SNDRV_PCM_FORMAT_U16_LE:
 264                signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
 265                fallthrough;
 266        case SNDRV_PCM_FORMAT_S16_LE:
 267                bits = HII2S_BITS_16;
 268                break;
 269        case SNDRV_PCM_FORMAT_U24_LE:
 270                signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
 271                fallthrough;
 272        case SNDRV_PCM_FORMAT_S24_LE:
 273                bits = HII2S_BITS_24;
 274                break;
 275        default:
 276                dev_err(cpu_dai->dev, "Bad format\n");
 277                return -EINVAL;
 278        }
 279
 280
 281        switch (params_rate(params)) {
 282        case 8000:
 283                rate = HII2S_FS_RATE_8KHZ;
 284                break;
 285        case 16000:
 286                rate = HII2S_FS_RATE_16KHZ;
 287                break;
 288        case 32000:
 289                rate = HII2S_FS_RATE_32KHZ;
 290                break;
 291        case 48000:
 292                rate = HII2S_FS_RATE_48KHZ;
 293                break;
 294        case 96000:
 295                rate = HII2S_FS_RATE_96KHZ;
 296                break;
 297        case 192000:
 298                rate = HII2S_FS_RATE_192KHZ;
 299                break;
 300        default:
 301                dev_err(cpu_dai->dev, "Bad rate: %d\n", params_rate(params));
 302                return -EINVAL;
 303        }
 304
 305        if (!(params_channels(params))) {
 306                dev_err(cpu_dai->dev, "Bad channels\n");
 307                return -EINVAL;
 308        }
 309
 310        dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
 311
 312        switch (bits) {
 313        case HII2S_BITS_24:
 314                i2s->bits = 32;
 315                dma_data->addr_width = 3;
 316                break;
 317        default:
 318                i2s->bits = 16;
 319                dma_data->addr_width = 2;
 320                break;
 321        }
 322        i2s->rate = params_rate(params);
 323        i2s->channels = params_channels(params);
 324        i2s->channel_length = i2s->channels * i2s->bits;
 325
 326        val = hi6210_read_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG);
 327        val &= ~((HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK <<
 328                        HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
 329                (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK <<
 330                        HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
 331                (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK <<
 332                        HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
 333                (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK <<
 334                        HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
 335        val |= ((16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
 336                (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
 337                (16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
 338                (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
 339        hi6210_write_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG, val);
 340
 341
 342        val = hi6210_read_reg(i2s, HII2S_IF_CLK_EN_CFG);
 343        val |= (BIT(19) | BIT(18) | BIT(17) |
 344                HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN |
 345                HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN |
 346                HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN |
 347                HII2S_IF_CLK_EN_CFG__ST_DL_R_EN |
 348                HII2S_IF_CLK_EN_CFG__ST_DL_L_EN);
 349        hi6210_write_reg(i2s, HII2S_IF_CLK_EN_CFG, val);
 350
 351
 352        val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG);
 353        val &= ~(HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN |
 354                 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN |
 355                 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN |
 356                 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN |
 357                 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN |
 358                 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN);
 359        val |= (HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN |
 360                HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN);
 361        hi6210_write_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG, val);
 362
 363
 364        val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG);
 365        val &= ~(HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE |
 366                 HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE);
 367        hi6210_write_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG, val);
 368
 369        val = hi6210_read_reg(i2s, HII2S_MUX_TOP_MODULE_CFG);
 370        val &= ~(HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE |
 371                 HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE |
 372                 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE |
 373                 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE);
 374        hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val);
 375
 376
 377        switch (i2s->format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 378        case SND_SOC_DAIFMT_BC_FC:
 379                i2s->master = false;
 380                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 381                val |= HII2S_I2S_CFG__S2_MST_SLV;
 382                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 383                break;
 384        case SND_SOC_DAIFMT_BP_FP:
 385                i2s->master = true;
 386                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 387                val &= ~HII2S_I2S_CFG__S2_MST_SLV;
 388                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 389                break;
 390        default:
 391                WARN_ONCE(1, "Invalid i2s->fmt CLOCK_PROVIDER_MASK. This shouldn't happen\n");
 392                return -EINVAL;
 393        }
 394
 395        switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 396        case SND_SOC_DAIFMT_I2S:
 397                fmt = HII2S_FORMAT_I2S;
 398                break;
 399        case SND_SOC_DAIFMT_LEFT_J:
 400                fmt = HII2S_FORMAT_LEFT_JUST;
 401                break;
 402        case SND_SOC_DAIFMT_RIGHT_J:
 403                fmt = HII2S_FORMAT_RIGHT_JUST;
 404                break;
 405        default:
 406                WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
 407                return -EINVAL;
 408        }
 409
 410        val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 411        val &= ~(HII2S_I2S_CFG__S2_FUNC_MODE_MASK <<
 412                        HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT);
 413        val |= fmt << HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT;
 414        hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 415
 416
 417        val = hi6210_read_reg(i2s, HII2S_CLK_SEL);
 418        val &= ~(HII2S_CLK_SEL__I2S_BT_FM_SEL | /* BT gets the I2S */
 419                        HII2S_CLK_SEL__EXT_12_288MHZ_SEL);
 420        hi6210_write_reg(i2s, HII2S_CLK_SEL, val);
 421
 422        dma_data->maxburst = 2;
 423
 424        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 425                dma_data->addr = i2s->base_phys + HII2S_ST_DL_CHANNEL;
 426        else
 427                dma_data->addr = i2s->base_phys + HII2S_STEREO_UPLINK_CHANNEL;
 428
 429        switch (i2s->channels) {
 430        case 1:
 431                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 432                val |= HII2S_I2S_CFG__S2_FRAME_MODE;
 433                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 434                break;
 435        default:
 436                val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 437                val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
 438                hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 439                break;
 440        }
 441
 442        /* clear loopback, set signed type and word length */
 443        val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
 444        val &= ~HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
 445        val &= ~(HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK <<
 446                        HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
 447        val &= ~(HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK <<
 448                        HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT);
 449        val |= signed_data;
 450        val |= (bits << HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
 451        hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
 452
 453
 454        if (!i2s->master)
 455                return 0;
 456
 457        /* set DAC and related units to correct rate */
 458        val = hi6210_read_reg(i2s, HII2S_FS_CFG);
 459        val &= ~(HII2S_FS_CFG__FS_S2_MASK << HII2S_FS_CFG__FS_S2_SHIFT);
 460        val &= ~(HII2S_FS_CFG__FS_DACLR_MASK << HII2S_FS_CFG__FS_DACLR_SHIFT);
 461        val &= ~(HII2S_FS_CFG__FS_ST_DL_R_MASK <<
 462                                        HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
 463        val &= ~(HII2S_FS_CFG__FS_ST_DL_L_MASK <<
 464                                        HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
 465        val |= (rate << HII2S_FS_CFG__FS_S2_SHIFT);
 466        val |= (rate << HII2S_FS_CFG__FS_DACLR_SHIFT);
 467        val |= (rate << HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
 468        val |= (rate << HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
 469        hi6210_write_reg(i2s, HII2S_FS_CFG, val);
 470
 471        return 0;
 472}
 473
 474static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 475                          struct snd_soc_dai *cpu_dai)
 476{
 477        pr_debug("%s\n", __func__);
 478        switch (cmd) {
 479        case SNDRV_PCM_TRIGGER_START:
 480        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 481                if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 482                        hi6210_i2s_rxctrl(cpu_dai, 1);
 483                else
 484                        hi6210_i2s_txctrl(cpu_dai, 1);
 485                break;
 486        case SNDRV_PCM_TRIGGER_STOP:
 487        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 488                if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 489                        hi6210_i2s_rxctrl(cpu_dai, 0);
 490                else
 491                        hi6210_i2s_txctrl(cpu_dai, 0);
 492                break;
 493        default:
 494                dev_err(cpu_dai->dev, "unknown cmd\n");
 495                return -EINVAL;
 496        }
 497        return 0;
 498}
 499
 500static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai)
 501{
 502        struct hi6210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 503
 504        snd_soc_dai_init_dma_data(dai,
 505                                  &i2s->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
 506                                  &i2s->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
 507
 508        return 0;
 509}
 510
 511
 512static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = {
 513        .probe          = hi6210_i2s_dai_probe,
 514        .trigger        = hi6210_i2s_trigger,
 515        .hw_params      = hi6210_i2s_hw_params,
 516        .set_fmt        = hi6210_i2s_set_fmt,
 517        .startup        = hi6210_i2s_startup,
 518        .shutdown       = hi6210_i2s_shutdown,
 519};
 520
 521static const struct snd_soc_dai_driver hi6210_i2s_dai_init = {
 522        .playback = {
 523                .channels_min = 2,
 524                .channels_max = 2,
 525                .formats = SNDRV_PCM_FMTBIT_S16_LE |
 526                           SNDRV_PCM_FMTBIT_U16_LE,
 527                .rates = SNDRV_PCM_RATE_48000,
 528        },
 529        .capture = {
 530                .channels_min = 2,
 531                .channels_max = 2,
 532                .formats = SNDRV_PCM_FMTBIT_S16_LE |
 533                           SNDRV_PCM_FMTBIT_U16_LE,
 534                .rates = SNDRV_PCM_RATE_48000,
 535        },
 536        .ops = &hi6210_i2s_dai_ops,
 537};
 538
 539static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = {
 540        .name = "hi6210_i2s-i2s",
 541        .legacy_dai_naming = 1,
 542};
 543
 544static int hi6210_i2s_probe(struct platform_device *pdev)
 545{
 546        struct device_node *node = pdev->dev.of_node;
 547        struct device *dev = &pdev->dev;
 548        struct hi6210_i2s *i2s;
 549        struct resource *res;
 550        int ret;
 551
 552        i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
 553        if (!i2s)
 554                return -ENOMEM;
 555
 556        i2s->dev = dev;
 557        spin_lock_init(&i2s->lock);
 558
 559        i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 560        if (IS_ERR(i2s->base))
 561                return PTR_ERR(i2s->base);
 562
 563        i2s->base_phys = (phys_addr_t)res->start;
 564        i2s->dai = hi6210_i2s_dai_init;
 565
 566        dev_set_drvdata(dev, i2s);
 567
 568        i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
 569                                                "hisilicon,sysctrl-syscon");
 570        if (IS_ERR(i2s->sysctrl))
 571                return PTR_ERR(i2s->sysctrl);
 572
 573        i2s->clk[CLK_DACODEC] = devm_clk_get(dev, "dacodec");
 574        if (IS_ERR(i2s->clk[CLK_DACODEC]))
 575                return PTR_ERR(i2s->clk[CLK_DACODEC]);
 576        i2s->clocks++;
 577
 578        i2s->clk[CLK_I2S_BASE] = devm_clk_get(dev, "i2s-base");
 579        if (IS_ERR(i2s->clk[CLK_I2S_BASE]))
 580                return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
 581        i2s->clocks++;
 582
 583        ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
 584        if (ret)
 585                return ret;
 586
 587        ret = devm_snd_soc_register_component(dev, &hi6210_i2s_i2s_comp,
 588                                         &i2s->dai, 1);
 589        return ret;
 590}
 591
 592static const struct of_device_id hi6210_i2s_dt_ids[] = {
 593        { .compatible = "hisilicon,hi6210-i2s" },
 594        { /* sentinel */ }
 595};
 596
 597MODULE_DEVICE_TABLE(of, hi6210_i2s_dt_ids);
 598
 599static struct platform_driver hi6210_i2s_driver = {
 600        .probe = hi6210_i2s_probe,
 601        .driver = {
 602                .name = "hi6210_i2s",
 603                .of_match_table = hi6210_i2s_dt_ids,
 604        },
 605};
 606
 607module_platform_driver(hi6210_i2s_driver);
 608
 609MODULE_DESCRIPTION("Hisilicon HI6210 I2S driver");
 610MODULE_AUTHOR("Andy Green <andy.green@linaro.org>");
 611MODULE_LICENSE("GPL");
 612