root/sound/soc/kirkwood/kirkwood-i2s.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kirkwood_i2s_set_fmt
  2. kirkwood_set_dco
  3. kirkwood_set_rate
  4. kirkwood_i2s_startup
  5. kirkwood_i2s_hw_params
  6. kirkwood_i2s_play_mute
  7. kirkwood_i2s_play_trigger
  8. kirkwood_i2s_rec_trigger
  9. kirkwood_i2s_trigger
  10. kirkwood_i2s_init
  11. kirkwood_i2s_dev_probe
  12. kirkwood_i2s_dev_remove

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

/* [<][>][^][v][top][bottom][index][help] */