linux/sound/soc/samsung/i2s.c
<<
>>
Prefs
   1/* sound/soc/samsung/i2s.c
   2 *
   3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
   4 *
   5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
   6 *      Jaswinder Singh <jassi.brar@samsung.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/slab.h>
  15#include <linux/clk.h>
  16#include <linux/io.h>
  17#include <linux/module.h>
  18#include <linux/pm_runtime.h>
  19
  20#include <sound/soc.h>
  21#include <sound/pcm_params.h>
  22
  23#include <plat/audio.h>
  24
  25#include "dma.h"
  26#include "idma.h"
  27#include "i2s.h"
  28#include "i2s-regs.h"
  29
  30#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
  31
  32struct i2s_dai {
  33        /* Platform device for this DAI */
  34        struct platform_device *pdev;
  35        /* IOREMAP'd SFRs */
  36        void __iomem    *addr;
  37        /* Physical base address of SFRs */
  38        u32     base;
  39        /* Rate of RCLK source clock */
  40        unsigned long rclk_srcrate;
  41        /* Frame Clock */
  42        unsigned frmclk;
  43        /*
  44         * Specifically requested RCLK,BCLK by MACHINE Driver.
  45         * 0 indicates CPU driver is free to choose any value.
  46         */
  47        unsigned rfs, bfs;
  48        /* I2S Controller's core clock */
  49        struct clk *clk;
  50        /* Clock for generating I2S signals */
  51        struct clk *op_clk;
  52        /* Array of clock names for op_clk */
  53        const char **src_clk;
  54        /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
  55        struct i2s_dai *pri_dai;
  56        /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
  57        struct i2s_dai *sec_dai;
  58#define DAI_OPENED      (1 << 0) /* Dai is opened */
  59#define DAI_MANAGER     (1 << 1) /* Dai is the manager */
  60        unsigned mode;
  61        /* Driver for this DAI */
  62        struct snd_soc_dai_driver i2s_dai_drv;
  63        /* DMA parameters */
  64        struct s3c_dma_params dma_playback;
  65        struct s3c_dma_params dma_capture;
  66        struct s3c_dma_params idma_playback;
  67        u32     quirks;
  68        u32     suspend_i2smod;
  69        u32     suspend_i2scon;
  70        u32     suspend_i2spsr;
  71};
  72
  73/* Lock for cross i/f checks */
  74static DEFINE_SPINLOCK(lock);
  75
  76/* If this is the 'overlay' stereo DAI */
  77static inline bool is_secondary(struct i2s_dai *i2s)
  78{
  79        return i2s->pri_dai ? true : false;
  80}
  81
  82/* If operating in SoC-Slave mode */
  83static inline bool is_slave(struct i2s_dai *i2s)
  84{
  85        return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
  86}
  87
  88/* If this interface of the controller is transmitting data */
  89static inline bool tx_active(struct i2s_dai *i2s)
  90{
  91        u32 active;
  92
  93        if (!i2s)
  94                return false;
  95
  96        active = readl(i2s->addr + I2SCON);
  97
  98        if (is_secondary(i2s))
  99                active &= CON_TXSDMA_ACTIVE;
 100        else
 101                active &= CON_TXDMA_ACTIVE;
 102
 103        return active ? true : false;
 104}
 105
 106/* If the other interface of the controller is transmitting data */
 107static inline bool other_tx_active(struct i2s_dai *i2s)
 108{
 109        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 110
 111        return tx_active(other);
 112}
 113
 114/* If any interface of the controller is transmitting data */
 115static inline bool any_tx_active(struct i2s_dai *i2s)
 116{
 117        return tx_active(i2s) || other_tx_active(i2s);
 118}
 119
 120/* If this interface of the controller is receiving data */
 121static inline bool rx_active(struct i2s_dai *i2s)
 122{
 123        u32 active;
 124
 125        if (!i2s)
 126                return false;
 127
 128        active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE;
 129
 130        return active ? true : false;
 131}
 132
 133/* If the other interface of the controller is receiving data */
 134static inline bool other_rx_active(struct i2s_dai *i2s)
 135{
 136        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 137
 138        return rx_active(other);
 139}
 140
 141/* If any interface of the controller is receiving data */
 142static inline bool any_rx_active(struct i2s_dai *i2s)
 143{
 144        return rx_active(i2s) || other_rx_active(i2s);
 145}
 146
 147/* If the other DAI is transmitting or receiving data */
 148static inline bool other_active(struct i2s_dai *i2s)
 149{
 150        return other_rx_active(i2s) || other_tx_active(i2s);
 151}
 152
 153/* If this DAI is transmitting or receiving data */
 154static inline bool this_active(struct i2s_dai *i2s)
 155{
 156        return tx_active(i2s) || rx_active(i2s);
 157}
 158
 159/* If the controller is active anyway */
 160static inline bool any_active(struct i2s_dai *i2s)
 161{
 162        return this_active(i2s) || other_active(i2s);
 163}
 164
 165static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
 166{
 167        return snd_soc_dai_get_drvdata(dai);
 168}
 169
 170static inline bool is_opened(struct i2s_dai *i2s)
 171{
 172        if (i2s && (i2s->mode & DAI_OPENED))
 173                return true;
 174        else
 175                return false;
 176}
 177
 178static inline bool is_manager(struct i2s_dai *i2s)
 179{
 180        if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
 181                return true;
 182        else
 183                return false;
 184}
 185
 186/* Read RCLK of I2S (in multiples of LRCLK) */
 187static inline unsigned get_rfs(struct i2s_dai *i2s)
 188{
 189        u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
 190
 191        switch (rfs) {
 192        case 3: return 768;
 193        case 2: return 384;
 194        case 1: return 512;
 195        default: return 256;
 196        }
 197}
 198
 199/* Write RCLK of I2S (in multiples of LRCLK) */
 200static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
 201{
 202        u32 mod = readl(i2s->addr + I2SMOD);
 203
 204        mod &= ~MOD_RCLK_MASK;
 205
 206        switch (rfs) {
 207        case 768:
 208                mod |= MOD_RCLK_768FS;
 209                break;
 210        case 512:
 211                mod |= MOD_RCLK_512FS;
 212                break;
 213        case 384:
 214                mod |= MOD_RCLK_384FS;
 215                break;
 216        default:
 217                mod |= MOD_RCLK_256FS;
 218                break;
 219        }
 220
 221        writel(mod, i2s->addr + I2SMOD);
 222}
 223
 224/* Read Bit-Clock of I2S (in multiples of LRCLK) */
 225static inline unsigned get_bfs(struct i2s_dai *i2s)
 226{
 227        u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
 228
 229        switch (bfs) {
 230        case 3: return 24;
 231        case 2: return 16;
 232        case 1: return 48;
 233        default: return 32;
 234        }
 235}
 236
 237/* Write Bit-Clock of I2S (in multiples of LRCLK) */
 238static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
 239{
 240        u32 mod = readl(i2s->addr + I2SMOD);
 241
 242        mod &= ~MOD_BCLK_MASK;
 243
 244        switch (bfs) {
 245        case 48:
 246                mod |= MOD_BCLK_48FS;
 247                break;
 248        case 32:
 249                mod |= MOD_BCLK_32FS;
 250                break;
 251        case 24:
 252                mod |= MOD_BCLK_24FS;
 253                break;
 254        case 16:
 255                mod |= MOD_BCLK_16FS;
 256                break;
 257        default:
 258                dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
 259                return;
 260        }
 261
 262        writel(mod, i2s->addr + I2SMOD);
 263}
 264
 265/* Sample-Size */
 266static inline int get_blc(struct i2s_dai *i2s)
 267{
 268        int blc = readl(i2s->addr + I2SMOD);
 269
 270        blc = (blc >> 13) & 0x3;
 271
 272        switch (blc) {
 273        case 2: return 24;
 274        case 1: return 8;
 275        default: return 16;
 276        }
 277}
 278
 279/* TX Channel Control */
 280static void i2s_txctrl(struct i2s_dai *i2s, int on)
 281{
 282        void __iomem *addr = i2s->addr;
 283        u32 con = readl(addr + I2SCON);
 284        u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
 285
 286        if (on) {
 287                con |= CON_ACTIVE;
 288                con &= ~CON_TXCH_PAUSE;
 289
 290                if (is_secondary(i2s)) {
 291                        con |= CON_TXSDMA_ACTIVE;
 292                        con &= ~CON_TXSDMA_PAUSE;
 293                } else {
 294                        con |= CON_TXDMA_ACTIVE;
 295                        con &= ~CON_TXDMA_PAUSE;
 296                }
 297
 298                if (any_rx_active(i2s))
 299                        mod |= MOD_TXRX;
 300                else
 301                        mod |= MOD_TXONLY;
 302        } else {
 303                if (is_secondary(i2s)) {
 304                        con |=  CON_TXSDMA_PAUSE;
 305                        con &= ~CON_TXSDMA_ACTIVE;
 306                } else {
 307                        con |=  CON_TXDMA_PAUSE;
 308                        con &= ~CON_TXDMA_ACTIVE;
 309                }
 310
 311                if (other_tx_active(i2s)) {
 312                        writel(con, addr + I2SCON);
 313                        return;
 314                }
 315
 316                con |=  CON_TXCH_PAUSE;
 317
 318                if (any_rx_active(i2s))
 319                        mod |= MOD_RXONLY;
 320                else
 321                        con &= ~CON_ACTIVE;
 322        }
 323
 324        writel(mod, addr + I2SMOD);
 325        writel(con, addr + I2SCON);
 326}
 327
 328/* RX Channel Control */
 329static void i2s_rxctrl(struct i2s_dai *i2s, int on)
 330{
 331        void __iomem *addr = i2s->addr;
 332        u32 con = readl(addr + I2SCON);
 333        u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
 334
 335        if (on) {
 336                con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
 337                con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
 338
 339                if (any_tx_active(i2s))
 340                        mod |= MOD_TXRX;
 341                else
 342                        mod |= MOD_RXONLY;
 343        } else {
 344                con |=  CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
 345                con &= ~CON_RXDMA_ACTIVE;
 346
 347                if (any_tx_active(i2s))
 348                        mod |= MOD_TXONLY;
 349                else
 350                        con &= ~CON_ACTIVE;
 351        }
 352
 353        writel(mod, addr + I2SMOD);
 354        writel(con, addr + I2SCON);
 355}
 356
 357/* Flush FIFO of an interface */
 358static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
 359{
 360        void __iomem *fic;
 361        u32 val;
 362
 363        if (!i2s)
 364                return;
 365
 366        if (is_secondary(i2s))
 367                fic = i2s->addr + I2SFICS;
 368        else
 369                fic = i2s->addr + I2SFIC;
 370
 371        /* Flush the FIFO */
 372        writel(readl(fic) | flush, fic);
 373
 374        /* Be patient */
 375        val = msecs_to_loops(1) / 1000; /* 1 usec */
 376        while (--val)
 377                cpu_relax();
 378
 379        writel(readl(fic) & ~flush, fic);
 380}
 381
 382static int i2s_set_sysclk(struct snd_soc_dai *dai,
 383          int clk_id, unsigned int rfs, int dir)
 384{
 385        struct i2s_dai *i2s = to_info(dai);
 386        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 387        u32 mod = readl(i2s->addr + I2SMOD);
 388
 389        switch (clk_id) {
 390        case SAMSUNG_I2S_CDCLK:
 391                /* Shouldn't matter in GATING(CLOCK_IN) mode */
 392                if (dir == SND_SOC_CLOCK_IN)
 393                        rfs = 0;
 394
 395                if ((rfs && other->rfs && (other->rfs != rfs)) ||
 396                                (any_active(i2s) &&
 397                                (((dir == SND_SOC_CLOCK_IN)
 398                                        && !(mod & MOD_CDCLKCON)) ||
 399                                ((dir == SND_SOC_CLOCK_OUT)
 400                                        && (mod & MOD_CDCLKCON))))) {
 401                        dev_err(&i2s->pdev->dev,
 402                                "%s:%d Other DAI busy\n", __func__, __LINE__);
 403                        return -EAGAIN;
 404                }
 405
 406                if (dir == SND_SOC_CLOCK_IN)
 407                        mod |= MOD_CDCLKCON;
 408                else
 409                        mod &= ~MOD_CDCLKCON;
 410
 411                i2s->rfs = rfs;
 412                break;
 413
 414        case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
 415        case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
 416                if ((i2s->quirks & QUIRK_NO_MUXPSR)
 417                                || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
 418                        clk_id = 0;
 419                else
 420                        clk_id = 1;
 421
 422                if (!any_active(i2s)) {
 423                        if (i2s->op_clk) {
 424                                if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
 425                                        (!clk_id && (mod & MOD_IMS_SYSMUX))) {
 426                                        clk_disable(i2s->op_clk);
 427                                        clk_put(i2s->op_clk);
 428                                } else {
 429                                        i2s->rclk_srcrate =
 430                                                clk_get_rate(i2s->op_clk);
 431                                        return 0;
 432                                }
 433                        }
 434
 435                        i2s->op_clk = clk_get(&i2s->pdev->dev,
 436                                                i2s->src_clk[clk_id]);
 437                        clk_enable(i2s->op_clk);
 438                        i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
 439
 440                        /* Over-ride the other's */
 441                        if (other) {
 442                                other->op_clk = i2s->op_clk;
 443                                other->rclk_srcrate = i2s->rclk_srcrate;
 444                        }
 445                } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
 446                                || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
 447                        dev_err(&i2s->pdev->dev,
 448                                "%s:%d Other DAI busy\n", __func__, __LINE__);
 449                        return -EAGAIN;
 450                } else {
 451                        /* Call can't be on the active DAI */
 452                        i2s->op_clk = other->op_clk;
 453                        i2s->rclk_srcrate = other->rclk_srcrate;
 454                        return 0;
 455                }
 456
 457                if (clk_id == 0)
 458                        mod &= ~MOD_IMS_SYSMUX;
 459                else
 460                        mod |= MOD_IMS_SYSMUX;
 461                break;
 462
 463        default:
 464                dev_err(&i2s->pdev->dev, "We don't serve that!\n");
 465                return -EINVAL;
 466        }
 467
 468        writel(mod, i2s->addr + I2SMOD);
 469
 470        return 0;
 471}
 472
 473static int i2s_set_fmt(struct snd_soc_dai *dai,
 474        unsigned int fmt)
 475{
 476        struct i2s_dai *i2s = to_info(dai);
 477        u32 mod = readl(i2s->addr + I2SMOD);
 478        u32 tmp = 0;
 479
 480        /* Format is priority */
 481        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 482        case SND_SOC_DAIFMT_RIGHT_J:
 483                tmp |= MOD_LR_RLOW;
 484                tmp |= MOD_SDF_MSB;
 485                break;
 486        case SND_SOC_DAIFMT_LEFT_J:
 487                tmp |= MOD_LR_RLOW;
 488                tmp |= MOD_SDF_LSB;
 489                break;
 490        case SND_SOC_DAIFMT_I2S:
 491                tmp |= MOD_SDF_IIS;
 492                break;
 493        default:
 494                dev_err(&i2s->pdev->dev, "Format not supported\n");
 495                return -EINVAL;
 496        }
 497
 498        /*
 499         * INV flag is relative to the FORMAT flag - if set it simply
 500         * flips the polarity specified by the Standard
 501         */
 502        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 503        case SND_SOC_DAIFMT_NB_NF:
 504                break;
 505        case SND_SOC_DAIFMT_NB_IF:
 506                if (tmp & MOD_LR_RLOW)
 507                        tmp &= ~MOD_LR_RLOW;
 508                else
 509                        tmp |= MOD_LR_RLOW;
 510                break;
 511        default:
 512                dev_err(&i2s->pdev->dev, "Polarity not supported\n");
 513                return -EINVAL;
 514        }
 515
 516        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 517        case SND_SOC_DAIFMT_CBM_CFM:
 518                tmp |= MOD_SLAVE;
 519                break;
 520        case SND_SOC_DAIFMT_CBS_CFS:
 521                /* Set default source clock in Master mode */
 522                if (i2s->rclk_srcrate == 0)
 523                        i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
 524                                                        0, SND_SOC_CLOCK_IN);
 525                break;
 526        default:
 527                dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
 528                return -EINVAL;
 529        }
 530
 531        if (any_active(i2s) &&
 532                        ((mod & (MOD_SDF_MASK | MOD_LR_RLOW
 533                                | MOD_SLAVE)) != tmp)) {
 534                dev_err(&i2s->pdev->dev,
 535                                "%s:%d Other DAI busy\n", __func__, __LINE__);
 536                return -EAGAIN;
 537        }
 538
 539        mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
 540        mod |= tmp;
 541        writel(mod, i2s->addr + I2SMOD);
 542
 543        return 0;
 544}
 545
 546static int i2s_hw_params(struct snd_pcm_substream *substream,
 547        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 548{
 549        struct i2s_dai *i2s = to_info(dai);
 550        u32 mod = readl(i2s->addr + I2SMOD);
 551
 552        if (!is_secondary(i2s))
 553                mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
 554
 555        switch (params_channels(params)) {
 556        case 6:
 557                mod |= MOD_DC2_EN;
 558        case 4:
 559                mod |= MOD_DC1_EN;
 560                break;
 561        case 2:
 562                break;
 563        default:
 564                dev_err(&i2s->pdev->dev, "%d channels not supported\n",
 565                                params_channels(params));
 566                return -EINVAL;
 567        }
 568
 569        if (is_secondary(i2s))
 570                mod &= ~MOD_BLCS_MASK;
 571        else
 572                mod &= ~MOD_BLCP_MASK;
 573
 574        if (is_manager(i2s))
 575                mod &= ~MOD_BLC_MASK;
 576
 577        switch (params_format(params)) {
 578        case SNDRV_PCM_FORMAT_S8:
 579                if (is_secondary(i2s))
 580                        mod |= MOD_BLCS_8BIT;
 581                else
 582                        mod |= MOD_BLCP_8BIT;
 583                if (is_manager(i2s))
 584                        mod |= MOD_BLC_8BIT;
 585                break;
 586        case SNDRV_PCM_FORMAT_S16_LE:
 587                if (is_secondary(i2s))
 588                        mod |= MOD_BLCS_16BIT;
 589                else
 590                        mod |= MOD_BLCP_16BIT;
 591                if (is_manager(i2s))
 592                        mod |= MOD_BLC_16BIT;
 593                break;
 594        case SNDRV_PCM_FORMAT_S24_LE:
 595                if (is_secondary(i2s))
 596                        mod |= MOD_BLCS_24BIT;
 597                else
 598                        mod |= MOD_BLCP_24BIT;
 599                if (is_manager(i2s))
 600                        mod |= MOD_BLC_24BIT;
 601                break;
 602        default:
 603                dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
 604                                params_format(params));
 605                return -EINVAL;
 606        }
 607        writel(mod, i2s->addr + I2SMOD);
 608
 609        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 610                snd_soc_dai_set_dma_data(dai, substream,
 611                        (void *)&i2s->dma_playback);
 612        else
 613                snd_soc_dai_set_dma_data(dai, substream,
 614                        (void *)&i2s->dma_capture);
 615
 616        i2s->frmclk = params_rate(params);
 617
 618        return 0;
 619}
 620
 621/* We set constraints on the substream acc to the version of I2S */
 622static int i2s_startup(struct snd_pcm_substream *substream,
 623          struct snd_soc_dai *dai)
 624{
 625        struct i2s_dai *i2s = to_info(dai);
 626        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 627        unsigned long flags;
 628
 629        spin_lock_irqsave(&lock, flags);
 630
 631        i2s->mode |= DAI_OPENED;
 632
 633        if (is_manager(other))
 634                i2s->mode &= ~DAI_MANAGER;
 635        else
 636                i2s->mode |= DAI_MANAGER;
 637
 638        /* Enforce set_sysclk in Master mode */
 639        i2s->rclk_srcrate = 0;
 640
 641        spin_unlock_irqrestore(&lock, flags);
 642
 643        return 0;
 644}
 645
 646static void i2s_shutdown(struct snd_pcm_substream *substream,
 647        struct snd_soc_dai *dai)
 648{
 649        struct i2s_dai *i2s = to_info(dai);
 650        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 651        unsigned long flags;
 652
 653        spin_lock_irqsave(&lock, flags);
 654
 655        i2s->mode &= ~DAI_OPENED;
 656        i2s->mode &= ~DAI_MANAGER;
 657
 658        if (is_opened(other))
 659                other->mode |= DAI_MANAGER;
 660
 661        /* Reset any constraint on RFS and BFS */
 662        i2s->rfs = 0;
 663        i2s->bfs = 0;
 664
 665        spin_unlock_irqrestore(&lock, flags);
 666
 667        /* Gate CDCLK by default */
 668        if (!is_opened(other))
 669                i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
 670                                0, SND_SOC_CLOCK_IN);
 671}
 672
 673static int config_setup(struct i2s_dai *i2s)
 674{
 675        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 676        unsigned rfs, bfs, blc;
 677        u32 psr;
 678
 679        blc = get_blc(i2s);
 680
 681        bfs = i2s->bfs;
 682
 683        if (!bfs && other)
 684                bfs = other->bfs;
 685
 686        /* Select least possible multiple(2) if no constraint set */
 687        if (!bfs)
 688                bfs = blc * 2;
 689
 690        rfs = i2s->rfs;
 691
 692        if (!rfs && other)
 693                rfs = other->rfs;
 694
 695        if ((rfs == 256 || rfs == 512) && (blc == 24)) {
 696                dev_err(&i2s->pdev->dev,
 697                        "%d-RFS not supported for 24-blc\n", rfs);
 698                return -EINVAL;
 699        }
 700
 701        if (!rfs) {
 702                if (bfs == 16 || bfs == 32)
 703                        rfs = 256;
 704                else
 705                        rfs = 384;
 706        }
 707
 708        /* If already setup and running */
 709        if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
 710                dev_err(&i2s->pdev->dev,
 711                                "%s:%d Other DAI busy\n", __func__, __LINE__);
 712                return -EAGAIN;
 713        }
 714
 715        /* Don't bother RFS, BFS & PSR in Slave mode */
 716        if (is_slave(i2s))
 717                return 0;
 718
 719        set_bfs(i2s, bfs);
 720        set_rfs(i2s, rfs);
 721
 722        if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
 723                psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
 724                writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
 725                dev_dbg(&i2s->pdev->dev,
 726                        "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
 727                                i2s->rclk_srcrate, psr, rfs, bfs);
 728        }
 729
 730        return 0;
 731}
 732
 733static int i2s_trigger(struct snd_pcm_substream *substream,
 734        int cmd, struct snd_soc_dai *dai)
 735{
 736        int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 737        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 738        struct i2s_dai *i2s = to_info(rtd->cpu_dai);
 739        unsigned long flags;
 740
 741        switch (cmd) {
 742        case SNDRV_PCM_TRIGGER_START:
 743        case SNDRV_PCM_TRIGGER_RESUME:
 744        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 745                local_irq_save(flags);
 746
 747                if (config_setup(i2s)) {
 748                        local_irq_restore(flags);
 749                        return -EINVAL;
 750                }
 751
 752                if (capture)
 753                        i2s_rxctrl(i2s, 1);
 754                else
 755                        i2s_txctrl(i2s, 1);
 756
 757                local_irq_restore(flags);
 758                break;
 759        case SNDRV_PCM_TRIGGER_STOP:
 760        case SNDRV_PCM_TRIGGER_SUSPEND:
 761        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 762                local_irq_save(flags);
 763
 764                if (capture)
 765                        i2s_rxctrl(i2s, 0);
 766                else
 767                        i2s_txctrl(i2s, 0);
 768
 769                if (capture)
 770                        i2s_fifo(i2s, FIC_RXFLUSH);
 771                else
 772                        i2s_fifo(i2s, FIC_TXFLUSH);
 773
 774                local_irq_restore(flags);
 775                break;
 776        }
 777
 778        return 0;
 779}
 780
 781static int i2s_set_clkdiv(struct snd_soc_dai *dai,
 782        int div_id, int div)
 783{
 784        struct i2s_dai *i2s = to_info(dai);
 785        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 786
 787        switch (div_id) {
 788        case SAMSUNG_I2S_DIV_BCLK:
 789                if ((any_active(i2s) && div && (get_bfs(i2s) != div))
 790                        || (other && other->bfs && (other->bfs != div))) {
 791                        dev_err(&i2s->pdev->dev,
 792                                "%s:%d Other DAI busy\n", __func__, __LINE__);
 793                        return -EAGAIN;
 794                }
 795                i2s->bfs = div;
 796                break;
 797        default:
 798                dev_err(&i2s->pdev->dev,
 799                        "Invalid clock divider(%d)\n", div_id);
 800                return -EINVAL;
 801        }
 802
 803        return 0;
 804}
 805
 806static snd_pcm_sframes_t
 807i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 808{
 809        struct i2s_dai *i2s = to_info(dai);
 810        u32 reg = readl(i2s->addr + I2SFIC);
 811        snd_pcm_sframes_t delay;
 812
 813        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 814                delay = FIC_RXCOUNT(reg);
 815        else if (is_secondary(i2s))
 816                delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
 817        else
 818                delay = FIC_TXCOUNT(reg);
 819
 820        return delay;
 821}
 822
 823#ifdef CONFIG_PM
 824static int i2s_suspend(struct snd_soc_dai *dai)
 825{
 826        struct i2s_dai *i2s = to_info(dai);
 827
 828        if (dai->active) {
 829                i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
 830                i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
 831                i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
 832        }
 833
 834        return 0;
 835}
 836
 837static int i2s_resume(struct snd_soc_dai *dai)
 838{
 839        struct i2s_dai *i2s = to_info(dai);
 840
 841        if (dai->active) {
 842                writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
 843                writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
 844                writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
 845        }
 846
 847        return 0;
 848}
 849#else
 850#define i2s_suspend NULL
 851#define i2s_resume  NULL
 852#endif
 853
 854static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 855{
 856        struct i2s_dai *i2s = to_info(dai);
 857        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 858
 859        if (other && other->clk) /* If this is probe on secondary */
 860                goto probe_exit;
 861
 862        i2s->addr = ioremap(i2s->base, 0x100);
 863        if (i2s->addr == NULL) {
 864                dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
 865                return -ENXIO;
 866        }
 867
 868        i2s->clk = clk_get(&i2s->pdev->dev, "iis");
 869        if (IS_ERR(i2s->clk)) {
 870                dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
 871                iounmap(i2s->addr);
 872                return -ENOENT;
 873        }
 874        clk_enable(i2s->clk);
 875
 876        if (other) {
 877                other->addr = i2s->addr;
 878                other->clk = i2s->clk;
 879        }
 880
 881        if (i2s->quirks & QUIRK_NEED_RSTCLR)
 882                writel(CON_RSTCLR, i2s->addr + I2SCON);
 883
 884        if (i2s->quirks & QUIRK_SEC_DAI)
 885                idma_reg_addr_init(i2s->addr,
 886                                        i2s->sec_dai->idma_playback.dma_addr);
 887
 888probe_exit:
 889        /* Reset any constraint on RFS and BFS */
 890        i2s->rfs = 0;
 891        i2s->bfs = 0;
 892        i2s_txctrl(i2s, 0);
 893        i2s_rxctrl(i2s, 0);
 894        i2s_fifo(i2s, FIC_TXFLUSH);
 895        i2s_fifo(other, FIC_TXFLUSH);
 896        i2s_fifo(i2s, FIC_RXFLUSH);
 897
 898        /* Gate CDCLK by default */
 899        if (!is_opened(other))
 900                i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
 901                                0, SND_SOC_CLOCK_IN);
 902
 903        return 0;
 904}
 905
 906static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
 907{
 908        struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
 909        struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
 910
 911        if (!other || !other->clk) {
 912
 913                if (i2s->quirks & QUIRK_NEED_RSTCLR)
 914                        writel(0, i2s->addr + I2SCON);
 915
 916                clk_disable(i2s->clk);
 917                clk_put(i2s->clk);
 918
 919                iounmap(i2s->addr);
 920        }
 921
 922        i2s->clk = NULL;
 923
 924        return 0;
 925}
 926
 927static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
 928        .trigger = i2s_trigger,
 929        .hw_params = i2s_hw_params,
 930        .set_fmt = i2s_set_fmt,
 931        .set_clkdiv = i2s_set_clkdiv,
 932        .set_sysclk = i2s_set_sysclk,
 933        .startup = i2s_startup,
 934        .shutdown = i2s_shutdown,
 935        .delay = i2s_delay,
 936};
 937
 938#define SAMSUNG_I2S_RATES       SNDRV_PCM_RATE_8000_96000
 939
 940#define SAMSUNG_I2S_FMTS        (SNDRV_PCM_FMTBIT_S8 | \
 941                                        SNDRV_PCM_FMTBIT_S16_LE | \
 942                                        SNDRV_PCM_FMTBIT_S24_LE)
 943
 944static __devinit
 945struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
 946{
 947        struct i2s_dai *i2s;
 948
 949        i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
 950        if (i2s == NULL)
 951                return NULL;
 952
 953        i2s->pdev = pdev;
 954        i2s->pri_dai = NULL;
 955        i2s->sec_dai = NULL;
 956        i2s->i2s_dai_drv.symmetric_rates = 1;
 957        i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
 958        i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
 959        i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
 960        i2s->i2s_dai_drv.suspend = i2s_suspend;
 961        i2s->i2s_dai_drv.resume = i2s_resume;
 962        i2s->i2s_dai_drv.playback.channels_min = 2;
 963        i2s->i2s_dai_drv.playback.channels_max = 2;
 964        i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
 965        i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
 966
 967        if (!sec) {
 968                i2s->i2s_dai_drv.capture.channels_min = 2;
 969                i2s->i2s_dai_drv.capture.channels_max = 2;
 970                i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
 971                i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
 972        } else {        /* Create a new platform_device for Secondary */
 973                i2s->pdev = platform_device_register_resndata(NULL,
 974                                pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
 975                                NULL, 0, NULL, 0);
 976                if (IS_ERR(i2s->pdev))
 977                        return NULL;
 978        }
 979
 980        /* Pre-assign snd_soc_dai_set_drvdata */
 981        dev_set_drvdata(&i2s->pdev->dev, i2s);
 982
 983        return i2s;
 984}
 985
 986static __devinit int samsung_i2s_probe(struct platform_device *pdev)
 987{
 988        u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
 989        struct i2s_dai *pri_dai, *sec_dai = NULL;
 990        struct s3c_audio_pdata *i2s_pdata;
 991        struct samsung_i2s *i2s_cfg;
 992        struct resource *res;
 993        u32 regs_base, quirks;
 994        int ret = 0;
 995
 996        /* Call during Seconday interface registration */
 997        if (pdev->id >= SAMSUNG_I2S_SECOFF) {
 998                sec_dai = dev_get_drvdata(&pdev->dev);
 999                snd_soc_register_dai(&sec_dai->pdev->dev,
1000                        &sec_dai->i2s_dai_drv);
1001                return 0;
1002        }
1003
1004        i2s_pdata = pdev->dev.platform_data;
1005        if (i2s_pdata == NULL) {
1006                dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1007                return -EINVAL;
1008        }
1009
1010        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1011        if (!res) {
1012                dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
1013                return -ENXIO;
1014        }
1015        dma_pl_chan = res->start;
1016
1017        res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1018        if (!res) {
1019                dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
1020                return -ENXIO;
1021        }
1022        dma_cp_chan = res->start;
1023
1024        res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
1025        if (res)
1026                dma_pl_sec_chan = res->start;
1027        else
1028                dma_pl_sec_chan = 0;
1029
1030        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1031        if (!res) {
1032                dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
1033                return -ENXIO;
1034        }
1035
1036        if (!request_mem_region(res->start, resource_size(res),
1037                                                        "samsung-i2s")) {
1038                dev_err(&pdev->dev, "Unable to request SFR region\n");
1039                return -EBUSY;
1040        }
1041        regs_base = res->start;
1042
1043        i2s_cfg = &i2s_pdata->type.i2s;
1044        quirks = i2s_cfg->quirks;
1045
1046        pri_dai = i2s_alloc_dai(pdev, false);
1047        if (!pri_dai) {
1048                dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1049                ret = -ENOMEM;
1050                goto err;
1051        }
1052
1053        pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1054        pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1055        pri_dai->dma_playback.client =
1056                (struct s3c2410_dma_client *)&pri_dai->dma_playback;
1057        pri_dai->dma_capture.client =
1058                (struct s3c2410_dma_client *)&pri_dai->dma_capture;
1059        pri_dai->dma_playback.channel = dma_pl_chan;
1060        pri_dai->dma_capture.channel = dma_cp_chan;
1061        pri_dai->src_clk = i2s_cfg->src_clk;
1062        pri_dai->dma_playback.dma_size = 4;
1063        pri_dai->dma_capture.dma_size = 4;
1064        pri_dai->base = regs_base;
1065        pri_dai->quirks = quirks;
1066
1067        if (quirks & QUIRK_PRI_6CHAN)
1068                pri_dai->i2s_dai_drv.playback.channels_max = 6;
1069
1070        if (quirks & QUIRK_SEC_DAI) {
1071                sec_dai = i2s_alloc_dai(pdev, true);
1072                if (!sec_dai) {
1073                        dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
1074                        ret = -ENOMEM;
1075                        goto err;
1076                }
1077                sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
1078                sec_dai->dma_playback.client =
1079                        (struct s3c2410_dma_client *)&sec_dai->dma_playback;
1080                /* Use iDMA always if SysDMA not provided */
1081                sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
1082                sec_dai->src_clk = i2s_cfg->src_clk;
1083                sec_dai->dma_playback.dma_size = 4;
1084                sec_dai->base = regs_base;
1085                sec_dai->quirks = quirks;
1086                sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr;
1087                sec_dai->pri_dai = pri_dai;
1088                pri_dai->sec_dai = sec_dai;
1089        }
1090
1091        if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1092                dev_err(&pdev->dev, "Unable to configure gpio\n");
1093                ret = -EINVAL;
1094                goto err;
1095        }
1096
1097        snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
1098
1099        pm_runtime_enable(&pdev->dev);
1100
1101        return 0;
1102err:
1103        release_mem_region(regs_base, resource_size(res));
1104
1105        return ret;
1106}
1107
1108static __devexit int samsung_i2s_remove(struct platform_device *pdev)
1109{
1110        struct i2s_dai *i2s, *other;
1111        struct resource *res;
1112
1113        i2s = dev_get_drvdata(&pdev->dev);
1114        other = i2s->pri_dai ? : i2s->sec_dai;
1115
1116        if (other) {
1117                other->pri_dai = NULL;
1118                other->sec_dai = NULL;
1119        } else {
1120                pm_runtime_disable(&pdev->dev);
1121                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1122                if (res)
1123                        release_mem_region(res->start, resource_size(res));
1124        }
1125
1126        i2s->pri_dai = NULL;
1127        i2s->sec_dai = NULL;
1128
1129        snd_soc_unregister_dai(&pdev->dev);
1130
1131        return 0;
1132}
1133
1134static struct platform_driver samsung_i2s_driver = {
1135        .probe  = samsung_i2s_probe,
1136        .remove = __devexit_p(samsung_i2s_remove),
1137        .driver = {
1138                .name = "samsung-i2s",
1139                .owner = THIS_MODULE,
1140        },
1141};
1142
1143module_platform_driver(samsung_i2s_driver);
1144
1145/* Module information */
1146MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
1147MODULE_DESCRIPTION("Samsung I2S Interface");
1148MODULE_ALIAS("platform:samsung-i2s");
1149MODULE_LICENSE("GPL");
1150
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.