linux/sound/soc/kirkwood/kirkwood-i2s.c
<<
>>
Prefs
   1/*
   2 * kirkwood-i2s.c
   3 *
   4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
   5 * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
   6 *
   7 *  This program is free software; you can redistribute  it and/or modify it
   8 *  under  the terms of  the GNU General  Public License as published by the
   9 *  Free Software Foundation;  either version 2 of the  License, or (at your
  10 *  option) any later version.
  11 */
  12
  13#include <linux/init.h>
  14#include <linux/module.h>
  15#include <linux/platform_device.h>
  16#include <linux/io.h>
  17#include <linux/slab.h>
  18#include <linux/mbus.h>
  19#include <linux/delay.h>
  20#include <linux/clk.h>
  21#include <sound/pcm.h>
  22#include <sound/pcm_params.h>
  23#include <sound/soc.h>
  24#include <linux/platform_data/asoc-kirkwood.h>
  25#include <linux/of.h>
  26
  27#include "kirkwood.h"
  28
  29#define DRV_NAME        "mvebu-audio"
  30
  31#define KIRKWOOD_I2S_FORMATS \
  32        (SNDRV_PCM_FMTBIT_S16_LE | \
  33         SNDRV_PCM_FMTBIT_S24_LE | \
  34         SNDRV_PCM_FMTBIT_S32_LE)
  35
  36#define KIRKWOOD_SPDIF_FORMATS \
  37        (SNDRV_PCM_FMTBIT_S16_LE | \
  38         SNDRV_PCM_FMTBIT_S24_LE)
  39
  40static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
  41                unsigned int fmt)
  42{
  43        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai);
  44        unsigned long mask;
  45        unsigned long value;
  46
  47        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  48        case SND_SOC_DAIFMT_RIGHT_J:
  49                mask = KIRKWOOD_I2S_CTL_RJ;
  50                break;
  51        case SND_SOC_DAIFMT_LEFT_J:
  52                mask = KIRKWOOD_I2S_CTL_LJ;
  53                break;
  54        case SND_SOC_DAIFMT_I2S:
  55                mask = KIRKWOOD_I2S_CTL_I2S;
  56                break;
  57        default:
  58                return -EINVAL;
  59        }
  60
  61        /*
  62         * Set same format for playback and record
  63         * This avoids some troubles.
  64         */
  65        value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);
  66        value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
  67        value |= mask;
  68        writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);
  69
  70        value = readl(priv->io+KIRKWOOD_I2S_RECCTL);
  71        value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
  72        value |= mask;
  73        writel(value, priv->io+KIRKWOOD_I2S_RECCTL);
  74
  75        return 0;
  76}
  77
  78static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
  79{
  80        unsigned long value;
  81
  82        value = KIRKWOOD_DCO_CTL_OFFSET_0;
  83        switch (rate) {
  84        default:
  85        case 44100:
  86                value |= KIRKWOOD_DCO_CTL_FREQ_11;
  87                break;
  88        case 48000:
  89                value |= KIRKWOOD_DCO_CTL_FREQ_12;
  90                break;
  91        case 96000:
  92                value |= KIRKWOOD_DCO_CTL_FREQ_24;
  93                break;
  94        }
  95        writel(value, io + KIRKWOOD_DCO_CTL);
  96
  97        /* wait for dco locked */
  98        do {
  99                cpu_relax();
 100                value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
 101                value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK;
 102        } while (value == 0);
 103}
 104
 105static void kirkwood_set_rate(struct snd_soc_dai *dai,
 106        struct kirkwood_dma_data *priv, unsigned long rate)
 107{
 108        uint32_t clks_ctrl;
 109
 110        if (IS_ERR(priv->extclk)) {
 111                /* use internal dco for the supported rates
 112                 * defined in kirkwood_i2s_dai */
 113                dev_dbg(dai->dev, "%s: dco set rate = %lu\n",
 114                        __func__, rate);
 115                kirkwood_set_dco(priv->io, rate);
 116
 117                clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO;
 118        } else {
 119                /* use the external clock for the other rates
 120                 * defined in kirkwood_i2s_dai_extclk */
 121                dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n",
 122                        __func__, rate, 256 * rate);
 123                clk_set_rate(priv->extclk, 256 * rate);
 124
 125                clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK;
 126        }
 127        writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL);
 128}
 129
 130static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
 131                struct snd_soc_dai *dai)
 132{
 133        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
 134
 135        snd_soc_dai_set_dma_data(dai, substream, priv);
 136        return 0;
 137}
 138
 139static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
 140                                 struct snd_pcm_hw_params *params,
 141                                 struct snd_soc_dai *dai)
 142{
 143        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
 144        uint32_t ctl_play, ctl_rec;
 145        unsigned int i2s_reg;
 146        unsigned long i2s_value;
 147
 148        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 149                i2s_reg = KIRKWOOD_I2S_PLAYCTL;
 150        } else {
 151                i2s_reg = KIRKWOOD_I2S_RECCTL;
 152        }
 153
 154        kirkwood_set_rate(dai, priv, params_rate(params));
 155
 156        i2s_value = readl(priv->io+i2s_reg);
 157        i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
 158
 159        /*
 160         * Size settings in play/rec i2s control regs and play/rec control
 161         * regs must be the same.
 162         */
 163        switch (params_format(params)) {
 164        case SNDRV_PCM_FORMAT_S16_LE:
 165                i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
 166                ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C |
 167                           KIRKWOOD_PLAYCTL_I2S_EN |
 168                           KIRKWOOD_PLAYCTL_SPDIF_EN;
 169                ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
 170                          KIRKWOOD_RECCTL_I2S_EN |
 171                          KIRKWOOD_RECCTL_SPDIF_EN;
 172                break;
 173        /*
 174         * doesn't work... S20_3LE != kirkwood 20bit format ?
 175         *
 176        case SNDRV_PCM_FORMAT_S20_3LE:
 177                i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
 178                ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 |
 179                           KIRKWOOD_PLAYCTL_I2S_EN;
 180                ctl_rec = KIRKWOOD_RECCTL_SIZE_20 |
 181                          KIRKWOOD_RECCTL_I2S_EN;
 182                break;
 183        */
 184        case SNDRV_PCM_FORMAT_S24_LE:
 185                i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
 186                ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
 187                           KIRKWOOD_PLAYCTL_I2S_EN |
 188                           KIRKWOOD_PLAYCTL_SPDIF_EN;
 189                ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
 190                          KIRKWOOD_RECCTL_I2S_EN |
 191                          KIRKWOOD_RECCTL_SPDIF_EN;
 192                break;
 193        case SNDRV_PCM_FORMAT_S32_LE:
 194                i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
 195                ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 |
 196                           KIRKWOOD_PLAYCTL_I2S_EN;
 197                ctl_rec = KIRKWOOD_RECCTL_SIZE_32 |
 198                          KIRKWOOD_RECCTL_I2S_EN;
 199                break;
 200        default:
 201                return -EINVAL;
 202        }
 203
 204        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 205                if (params_channels(params) == 1)
 206                        ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH;
 207                else
 208                        ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
 209
 210                priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
 211                                    KIRKWOOD_PLAYCTL_ENABLE_MASK |
 212                                    KIRKWOOD_PLAYCTL_SIZE_MASK);
 213                priv->ctl_play |= ctl_play;
 214        } else {
 215                priv->ctl_rec &= ~(KIRKWOOD_RECCTL_ENABLE_MASK |
 216                                   KIRKWOOD_RECCTL_SIZE_MASK);
 217                priv->ctl_rec |= ctl_rec;
 218        }
 219
 220        writel(i2s_value, priv->io+i2s_reg);
 221
 222        return 0;
 223}
 224
 225static unsigned kirkwood_i2s_play_mute(unsigned ctl)
 226{
 227        if (!(ctl & KIRKWOOD_PLAYCTL_I2S_EN))
 228                ctl |= KIRKWOOD_PLAYCTL_I2S_MUTE;
 229        if (!(ctl & KIRKWOOD_PLAYCTL_SPDIF_EN))
 230                ctl |= KIRKWOOD_PLAYCTL_SPDIF_MUTE;
 231        return ctl;
 232}
 233
 234static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
 235                                int cmd, struct snd_soc_dai *dai)
 236{
 237        struct snd_pcm_runtime *runtime = substream->runtime;
 238        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
 239        uint32_t ctl, value;
 240
 241        ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
 242        if ((ctl & KIRKWOOD_PLAYCTL_ENABLE_MASK) == 0) {
 243                unsigned timeout = 5000;
 244                /*
 245                 * The Armada510 spec says that if we enter pause mode, the
 246                 * busy bit must be read back as clear _twice_.  Make sure
 247                 * we respect that otherwise we get DMA underruns.
 248                 */
 249                do {
 250                        value = ctl;
 251                        ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
 252                        if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
 253                                break;
 254                        udelay(1);
 255                } while (timeout--);
 256
 257                if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
 258                        dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
 259                                   ctl);
 260        }
 261
 262        switch (cmd) {
 263        case SNDRV_PCM_TRIGGER_START:
 264                /* configure */
 265                ctl = priv->ctl_play;
 266                if (dai->id == 0)
 267                        ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;      /* i2s */
 268                else
 269                        ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;        /* spdif */
 270                ctl = kirkwood_i2s_play_mute(ctl);
 271                value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
 272                writel(value, priv->io + KIRKWOOD_PLAYCTL);
 273
 274                /* enable interrupts */
 275                if (!runtime->no_period_wakeup) {
 276                        value = readl(priv->io + KIRKWOOD_INT_MASK);
 277                        value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
 278                        writel(value, priv->io + KIRKWOOD_INT_MASK);
 279                }
 280
 281                /* enable playback */
 282                writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 283                break;
 284
 285        case SNDRV_PCM_TRIGGER_STOP:
 286                /* stop audio, disable interrupts */
 287                ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
 288                                KIRKWOOD_PLAYCTL_SPDIF_MUTE;
 289                writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 290
 291                value = readl(priv->io + KIRKWOOD_INT_MASK);
 292                value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
 293                writel(value, priv->io + KIRKWOOD_INT_MASK);
 294
 295                /* disable all playbacks */
 296                ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
 297                writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 298                break;
 299
 300        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 301        case SNDRV_PCM_TRIGGER_SUSPEND:
 302                ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
 303                                KIRKWOOD_PLAYCTL_SPDIF_MUTE;
 304                writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 305                break;
 306
 307        case SNDRV_PCM_TRIGGER_RESUME:
 308        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 309                ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
 310                                KIRKWOOD_PLAYCTL_SPDIF_MUTE);
 311                ctl = kirkwood_i2s_play_mute(ctl);
 312                writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 313                break;
 314
 315        default:
 316                return -EINVAL;
 317        }
 318
 319        return 0;
 320}
 321
 322static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
 323                                int cmd, struct snd_soc_dai *dai)
 324{
 325        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
 326        uint32_t ctl, value;
 327
 328        value = readl(priv->io + KIRKWOOD_RECCTL);
 329
 330        switch (cmd) {
 331        case SNDRV_PCM_TRIGGER_START:
 332                /* configure */
 333                ctl = priv->ctl_rec;
 334                if (dai->id == 0)
 335                        ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN;       /* i2s */
 336                else
 337                        ctl &= ~KIRKWOOD_RECCTL_I2S_EN;         /* spdif */
 338
 339                value = ctl & ~KIRKWOOD_RECCTL_ENABLE_MASK;
 340                writel(value, priv->io + KIRKWOOD_RECCTL);
 341
 342                /* enable interrupts */
 343                value = readl(priv->io + KIRKWOOD_INT_MASK);
 344                value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
 345                writel(value, priv->io + KIRKWOOD_INT_MASK);
 346
 347                /* enable record */
 348                writel(ctl, priv->io + KIRKWOOD_RECCTL);
 349                break;
 350
 351        case SNDRV_PCM_TRIGGER_STOP:
 352                /* stop audio, disable interrupts */
 353                value = readl(priv->io + KIRKWOOD_RECCTL);
 354                value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
 355                writel(value, priv->io + KIRKWOOD_RECCTL);
 356
 357                value = readl(priv->io + KIRKWOOD_INT_MASK);
 358                value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
 359                writel(value, priv->io + KIRKWOOD_INT_MASK);
 360
 361                /* disable all records */
 362                value = readl(priv->io + KIRKWOOD_RECCTL);
 363                value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
 364                writel(value, priv->io + KIRKWOOD_RECCTL);
 365                break;
 366
 367        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 368        case SNDRV_PCM_TRIGGER_SUSPEND:
 369                value = readl(priv->io + KIRKWOOD_RECCTL);
 370                value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
 371                writel(value, priv->io + KIRKWOOD_RECCTL);
 372                break;
 373
 374        case SNDRV_PCM_TRIGGER_RESUME:
 375        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 376                value = readl(priv->io + KIRKWOOD_RECCTL);
 377                value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
 378                writel(value, priv->io + KIRKWOOD_RECCTL);
 379                break;
 380
 381        default:
 382                return -EINVAL;
 383        }
 384
 385        return 0;
 386}
 387
 388static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 389                               struct snd_soc_dai *dai)
 390{
 391        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 392                return kirkwood_i2s_play_trigger(substream, cmd, dai);
 393        else
 394                return kirkwood_i2s_rec_trigger(substream, cmd, dai);
 395
 396        return 0;
 397}
 398
 399static int kirkwood_i2s_init(struct kirkwood_dma_data *priv)
 400{
 401        unsigned long value;
 402        unsigned int reg_data;
 403
 404        /* put system in a "safe" state : */
 405        /* disable audio interrupts */
 406        writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
 407        writel(0, priv->io + KIRKWOOD_INT_MASK);
 408
 409        reg_data = readl(priv->io + 0x1200);
 410        reg_data &= (~(0x333FF8));
 411        reg_data |= 0x111D18;
 412        writel(reg_data, priv->io + 0x1200);
 413
 414        msleep(500);
 415
 416        reg_data = readl(priv->io + 0x1200);
 417        reg_data &= (~(0x333FF8));
 418        reg_data |= 0x111D18;
 419        writel(reg_data, priv->io + 0x1200);
 420
 421        /* disable playback/record */
 422        value = readl(priv->io + KIRKWOOD_PLAYCTL);
 423        value &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
 424        writel(value, priv->io + KIRKWOOD_PLAYCTL);
 425
 426        value = readl(priv->io + KIRKWOOD_RECCTL);
 427        value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
 428        writel(value, priv->io + KIRKWOOD_RECCTL);
 429
 430        return 0;
 431
 432}
 433
 434static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
 435        .startup        = kirkwood_i2s_startup,
 436        .trigger        = kirkwood_i2s_trigger,
 437        .hw_params      = kirkwood_i2s_hw_params,
 438        .set_fmt        = kirkwood_i2s_set_fmt,
 439};
 440
 441static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
 442    {
 443        .name = "i2s",
 444        .id = 0,
 445        .playback = {
 446                .channels_min = 1,
 447                .channels_max = 2,
 448                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
 449                                SNDRV_PCM_RATE_96000,
 450                .formats = KIRKWOOD_I2S_FORMATS,
 451        },
 452        .capture = {
 453                .channels_min = 1,
 454                .channels_max = 2,
 455                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
 456                                SNDRV_PCM_RATE_96000,
 457                .formats = KIRKWOOD_I2S_FORMATS,
 458        },
 459        .ops = &kirkwood_i2s_dai_ops,
 460    },
 461    {
 462        .name = "spdif",
 463        .id = 1,
 464        .playback = {
 465                .channels_min = 1,
 466                .channels_max = 2,
 467                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
 468                                SNDRV_PCM_RATE_96000,
 469                .formats = KIRKWOOD_SPDIF_FORMATS,
 470        },
 471        .capture = {
 472                .channels_min = 1,
 473                .channels_max = 2,
 474                .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
 475                                SNDRV_PCM_RATE_96000,
 476                .formats = KIRKWOOD_SPDIF_FORMATS,
 477        },
 478        .ops = &kirkwood_i2s_dai_ops,
 479    },
 480};
 481
 482static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
 483    {
 484        .name = "i2s",
 485        .id = 0,
 486        .playback = {
 487                .channels_min = 1,
 488                .channels_max = 2,
 489                .rates = SNDRV_PCM_RATE_CONTINUOUS,
 490                .rate_min = 5512,
 491                .rate_max = 192000,
 492                .formats = KIRKWOOD_I2S_FORMATS,
 493        },
 494        .capture = {
 495                .channels_min = 1,
 496                .channels_max = 2,
 497                .rates = SNDRV_PCM_RATE_CONTINUOUS,
 498                .rate_min = 5512,
 499                .rate_max = 192000,
 500                .formats = KIRKWOOD_I2S_FORMATS,
 501        },
 502        .ops = &kirkwood_i2s_dai_ops,
 503    },
 504    {
 505        .name = "spdif",
 506        .id = 1,
 507        .playback = {
 508                .channels_min = 1,
 509                .channels_max = 2,
 510                .rates = SNDRV_PCM_RATE_CONTINUOUS,
 511                .rate_min = 5512,
 512                .rate_max = 192000,
 513                .formats = KIRKWOOD_SPDIF_FORMATS,
 514        },
 515        .capture = {
 516                .channels_min = 1,
 517                .channels_max = 2,
 518                .rates = SNDRV_PCM_RATE_CONTINUOUS,
 519                .rate_min = 5512,
 520                .rate_max = 192000,
 521                .formats = KIRKWOOD_SPDIF_FORMATS,
 522        },
 523        .ops = &kirkwood_i2s_dai_ops,
 524    },
 525};
 526
 527static const struct snd_soc_component_driver kirkwood_i2s_component = {
 528        .name           = DRV_NAME,
 529};
 530
 531static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 532{
 533        struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
 534        struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
 535        struct kirkwood_dma_data *priv;
 536        struct resource *mem;
 537        struct device_node *np = pdev->dev.of_node;
 538        int err;
 539
 540        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 541        if (!priv) {
 542                dev_err(&pdev->dev, "allocation failed\n");
 543                return -ENOMEM;
 544        }
 545        dev_set_drvdata(&pdev->dev, priv);
 546
 547        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 548        priv->io = devm_ioremap_resource(&pdev->dev, mem);
 549        if (IS_ERR(priv->io))
 550                return PTR_ERR(priv->io);
 551
 552        priv->irq = platform_get_irq(pdev, 0);
 553        if (priv->irq <= 0) {
 554                dev_err(&pdev->dev, "platform_get_irq failed\n");
 555                return -ENXIO;
 556        }
 557
 558        if (np) {
 559                priv->burst = 128;              /* might be 32 or 128 */
 560        } else if (data) {
 561                priv->burst = data->burst;
 562        } else {
 563                dev_err(&pdev->dev, "no DT nor platform data ?!\n");
 564                return -EINVAL;
 565        }
 566
 567        priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
 568        if (IS_ERR(priv->clk)) {
 569                dev_err(&pdev->dev, "no clock\n");
 570                return PTR_ERR(priv->clk);
 571        }
 572
 573        err = clk_prepare_enable(priv->clk);
 574        if (err < 0)
 575                return err;
 576
 577        priv->extclk = devm_clk_get(&pdev->dev, "extclk");
 578        if (IS_ERR(priv->extclk)) {
 579                if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
 580                        return -EPROBE_DEFER;
 581        } else {
 582                if (clk_is_match(priv->extclk, priv->clk)) {
 583                        devm_clk_put(&pdev->dev, priv->extclk);
 584                        priv->extclk = ERR_PTR(-EINVAL);
 585                } else {
 586                        dev_info(&pdev->dev, "found external clock\n");
 587                        clk_prepare_enable(priv->extclk);
 588                        soc_dai = kirkwood_i2s_dai_extclk;
 589                }
 590        }
 591
 592        /* Some sensible defaults - this reflects the powerup values */
 593        priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
 594        priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
 595
 596        /* Select the burst size */
 597        if (priv->burst == 32) {
 598                priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
 599                priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
 600        } else {
 601                priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
 602                priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
 603        }
 604
 605        err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
 606                                         soc_dai, 2);
 607        if (err) {
 608                dev_err(&pdev->dev, "snd_soc_register_component failed\n");
 609                goto err_component;
 610        }
 611
 612        err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
 613        if (err) {
 614                dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
 615                goto err_platform;
 616        }
 617
 618        kirkwood_i2s_init(priv);
 619
 620        return 0;
 621 err_platform:
 622        snd_soc_unregister_component(&pdev->dev);
 623 err_component:
 624        if (!IS_ERR(priv->extclk))
 625                clk_disable_unprepare(priv->extclk);
 626        clk_disable_unprepare(priv->clk);
 627
 628        return err;
 629}
 630
 631static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 632{
 633        struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
 634
 635        snd_soc_unregister_platform(&pdev->dev);
 636        snd_soc_unregister_component(&pdev->dev);
 637
 638        if (!IS_ERR(priv->extclk))
 639                clk_disable_unprepare(priv->extclk);
 640        clk_disable_unprepare(priv->clk);
 641
 642        return 0;
 643}
 644
 645#ifdef CONFIG_OF
 646static const struct of_device_id mvebu_audio_of_match[] = {
 647        { .compatible = "marvell,kirkwood-audio" },
 648        { .compatible = "marvell,dove-audio" },
 649        { .compatible = "marvell,armada370-audio" },
 650        { }
 651};
 652MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
 653#endif
 654
 655static struct platform_driver kirkwood_i2s_driver = {
 656        .probe  = kirkwood_i2s_dev_probe,
 657        .remove = kirkwood_i2s_dev_remove,
 658        .driver = {
 659                .name = DRV_NAME,
 660                .of_match_table = of_match_ptr(mvebu_audio_of_match),
 661        },
 662};
 663
 664module_platform_driver(kirkwood_i2s_driver);
 665
 666/* Module information */
 667MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
 668MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
 669MODULE_LICENSE("GPL");
 670MODULE_ALIAS("platform:mvebu-audio");
 671