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