linux/sound/soc/fsl/fsl_ssi.c
<<
>>
Prefs
   1/*
   2 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
   3 *
   4 * Author: Timur Tabi <timur@freescale.com>
   5 *
   6 * Copyright 2007-2008 Freescale Semiconductor, Inc.  This file is licensed
   7 * under the terms of the GNU General Public License version 2.  This
   8 * program is licensed "as is" without any warranty of any kind, whether
   9 * express or implied.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/module.h>
  14#include <linux/interrupt.h>
  15#include <linux/device.h>
  16#include <linux/delay.h>
  17
  18#include <sound/core.h>
  19#include <sound/pcm.h>
  20#include <sound/pcm_params.h>
  21#include <sound/initval.h>
  22#include <sound/soc.h>
  23
  24#include <asm/immap_86xx.h>
  25
  26#include "fsl_ssi.h"
  27
  28/**
  29 * FSLSSI_I2S_RATES: sample rates supported by the I2S
  30 *
  31 * This driver currently only supports the SSI running in I2S slave mode,
  32 * which means the codec determines the sample rate.  Therefore, we tell
  33 * ALSA that we support all rates and let the codec driver decide what rates
  34 * are really supported.
  35 */
  36#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
  37                          SNDRV_PCM_RATE_CONTINUOUS)
  38
  39/**
  40 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
  41 *
  42 * This driver currently only supports the SSI running in I2S slave mode.
  43 *
  44 * The SSI has a limitation in that the samples must be in the same byte
  45 * order as the host CPU.  This is because when multiple bytes are written
  46 * to the STX register, the bytes and bits must be written in the same
  47 * order.  The STX is a shift register, so all the bits need to be aligned
  48 * (bit-endianness must match byte-endianness).  Processors typically write
  49 * the bits within a byte in the same order that the bytes of a word are
  50 * written in.  So if the host CPU is big-endian, then only big-endian
  51 * samples will be written to STX properly.
  52 */
  53#ifdef __BIG_ENDIAN
  54#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
  55         SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \
  56         SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE)
  57#else
  58#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
  59         SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
  60         SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
  61#endif
  62
  63/* SIER bitflag of interrupts to enable */
  64#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
  65                    CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
  66                    CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
  67                    CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
  68                    CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
  69
  70/**
  71 * fsl_ssi_private: per-SSI private data
  72 *
  73 * @name: short name for this device ("SSI0", "SSI1", etc)
  74 * @ssi: pointer to the SSI's registers
  75 * @ssi_phys: physical address of the SSI registers
  76 * @irq: IRQ of this SSI
  77 * @first_stream: pointer to the stream that was opened first
  78 * @second_stream: pointer to second stream
  79 * @dev: struct device pointer
  80 * @playback: the number of playback streams opened
  81 * @capture: the number of capture streams opened
  82 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
  83 * @cpu_dai: the CPU DAI for this device
  84 * @dev_attr: the sysfs device attribute structure
  85 * @stats: SSI statistics
  86 */
  87struct fsl_ssi_private {
  88        char name[8];
  89        struct ccsr_ssi __iomem *ssi;
  90        dma_addr_t ssi_phys;
  91        unsigned int irq;
  92        struct snd_pcm_substream *first_stream;
  93        struct snd_pcm_substream *second_stream;
  94        struct device *dev;
  95        unsigned int playback;
  96        unsigned int capture;
  97        int asynchronous;
  98        struct snd_soc_dai cpu_dai;
  99        struct device_attribute dev_attr;
 100
 101        struct {
 102                unsigned int rfrc;
 103                unsigned int tfrc;
 104                unsigned int cmdau;
 105                unsigned int cmddu;
 106                unsigned int rxt;
 107                unsigned int rdr1;
 108                unsigned int rdr0;
 109                unsigned int tde1;
 110                unsigned int tde0;
 111                unsigned int roe1;
 112                unsigned int roe0;
 113                unsigned int tue1;
 114                unsigned int tue0;
 115                unsigned int tfs;
 116                unsigned int rfs;
 117                unsigned int tls;
 118                unsigned int rls;
 119                unsigned int rff1;
 120                unsigned int rff0;
 121                unsigned int tfe1;
 122                unsigned int tfe0;
 123        } stats;
 124};
 125
 126/**
 127 * fsl_ssi_isr: SSI interrupt handler
 128 *
 129 * Although it's possible to use the interrupt handler to send and receive
 130 * data to/from the SSI, we use the DMA instead.  Programming is more
 131 * complicated, but the performance is much better.
 132 *
 133 * This interrupt handler is used only to gather statistics.
 134 *
 135 * @irq: IRQ of the SSI device
 136 * @dev_id: pointer to the ssi_private structure for this SSI device
 137 */
 138static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 139{
 140        struct fsl_ssi_private *ssi_private = dev_id;
 141        struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 142        irqreturn_t ret = IRQ_NONE;
 143        __be32 sisr;
 144        __be32 sisr2 = 0;
 145
 146        /* We got an interrupt, so read the status register to see what we
 147           were interrupted for.  We mask it with the Interrupt Enable register
 148           so that we only check for events that we're interested in.
 149         */
 150        sisr = in_be32(&ssi->sisr) & SIER_FLAGS;
 151
 152        if (sisr & CCSR_SSI_SISR_RFRC) {
 153                ssi_private->stats.rfrc++;
 154                sisr2 |= CCSR_SSI_SISR_RFRC;
 155                ret = IRQ_HANDLED;
 156        }
 157
 158        if (sisr & CCSR_SSI_SISR_TFRC) {
 159                ssi_private->stats.tfrc++;
 160                sisr2 |= CCSR_SSI_SISR_TFRC;
 161                ret = IRQ_HANDLED;
 162        }
 163
 164        if (sisr & CCSR_SSI_SISR_CMDAU) {
 165                ssi_private->stats.cmdau++;
 166                ret = IRQ_HANDLED;
 167        }
 168
 169        if (sisr & CCSR_SSI_SISR_CMDDU) {
 170                ssi_private->stats.cmddu++;
 171                ret = IRQ_HANDLED;
 172        }
 173
 174        if (sisr & CCSR_SSI_SISR_RXT) {
 175                ssi_private->stats.rxt++;
 176                ret = IRQ_HANDLED;
 177        }
 178
 179        if (sisr & CCSR_SSI_SISR_RDR1) {
 180                ssi_private->stats.rdr1++;
 181                ret = IRQ_HANDLED;
 182        }
 183
 184        if (sisr & CCSR_SSI_SISR_RDR0) {
 185                ssi_private->stats.rdr0++;
 186                ret = IRQ_HANDLED;
 187        }
 188
 189        if (sisr & CCSR_SSI_SISR_TDE1) {
 190                ssi_private->stats.tde1++;
 191                ret = IRQ_HANDLED;
 192        }
 193
 194        if (sisr & CCSR_SSI_SISR_TDE0) {
 195                ssi_private->stats.tde0++;
 196                ret = IRQ_HANDLED;
 197        }
 198
 199        if (sisr & CCSR_SSI_SISR_ROE1) {
 200                ssi_private->stats.roe1++;
 201                sisr2 |= CCSR_SSI_SISR_ROE1;
 202                ret = IRQ_HANDLED;
 203        }
 204
 205        if (sisr & CCSR_SSI_SISR_ROE0) {
 206                ssi_private->stats.roe0++;
 207                sisr2 |= CCSR_SSI_SISR_ROE0;
 208                ret = IRQ_HANDLED;
 209        }
 210
 211        if (sisr & CCSR_SSI_SISR_TUE1) {
 212                ssi_private->stats.tue1++;
 213                sisr2 |= CCSR_SSI_SISR_TUE1;
 214                ret = IRQ_HANDLED;
 215        }
 216
 217        if (sisr & CCSR_SSI_SISR_TUE0) {
 218                ssi_private->stats.tue0++;
 219                sisr2 |= CCSR_SSI_SISR_TUE0;
 220                ret = IRQ_HANDLED;
 221        }
 222
 223        if (sisr & CCSR_SSI_SISR_TFS) {
 224                ssi_private->stats.tfs++;
 225                ret = IRQ_HANDLED;
 226        }
 227
 228        if (sisr & CCSR_SSI_SISR_RFS) {
 229                ssi_private->stats.rfs++;
 230                ret = IRQ_HANDLED;
 231        }
 232
 233        if (sisr & CCSR_SSI_SISR_TLS) {
 234                ssi_private->stats.tls++;
 235                ret = IRQ_HANDLED;
 236        }
 237
 238        if (sisr & CCSR_SSI_SISR_RLS) {
 239                ssi_private->stats.rls++;
 240                ret = IRQ_HANDLED;
 241        }
 242
 243        if (sisr & CCSR_SSI_SISR_RFF1) {
 244                ssi_private->stats.rff1++;
 245                ret = IRQ_HANDLED;
 246        }
 247
 248        if (sisr & CCSR_SSI_SISR_RFF0) {
 249                ssi_private->stats.rff0++;
 250                ret = IRQ_HANDLED;
 251        }
 252
 253        if (sisr & CCSR_SSI_SISR_TFE1) {
 254                ssi_private->stats.tfe1++;
 255                ret = IRQ_HANDLED;
 256        }
 257
 258        if (sisr & CCSR_SSI_SISR_TFE0) {
 259                ssi_private->stats.tfe0++;
 260                ret = IRQ_HANDLED;
 261        }
 262
 263        /* Clear the bits that we set */
 264        if (sisr2)
 265                out_be32(&ssi->sisr, sisr2);
 266
 267        return ret;
 268}
 269
 270/**
 271 * fsl_ssi_startup: create a new substream
 272 *
 273 * This is the first function called when a stream is opened.
 274 *
 275 * If this is the first stream open, then grab the IRQ and program most of
 276 * the SSI registers.
 277 */
 278static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 279                           struct snd_soc_dai *dai)
 280{
 281        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 282        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
 283
 284        /*
 285         * If this is the first stream opened, then request the IRQ
 286         * and initialize the SSI registers.
 287         */
 288        if (!ssi_private->playback && !ssi_private->capture) {
 289                struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 290                int ret;
 291
 292                ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
 293                                  ssi_private->name, ssi_private);
 294                if (ret < 0) {
 295                        dev_err(substream->pcm->card->dev,
 296                                "could not claim irq %u\n", ssi_private->irq);
 297                        return ret;
 298                }
 299
 300                /*
 301                 * Section 16.5 of the MPC8610 reference manual says that the
 302                 * SSI needs to be disabled before updating the registers we set
 303                 * here.
 304                 */
 305                clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
 306
 307                /*
 308                 * Program the SSI into I2S Slave Non-Network Synchronous mode.
 309                 * Also enable the transmit and receive FIFO.
 310                 *
 311                 * FIXME: Little-endian samples require a different shift dir
 312                 */
 313                clrsetbits_be32(&ssi->scr,
 314                        CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
 315                        CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
 316                        | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN));
 317
 318                out_be32(&ssi->stcr,
 319                         CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
 320                         CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
 321                         CCSR_SSI_STCR_TSCKP);
 322
 323                out_be32(&ssi->srcr,
 324                         CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
 325                         CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
 326                         CCSR_SSI_SRCR_RSCKP);
 327
 328                /*
 329                 * The DC and PM bits are only used if the SSI is the clock
 330                 * master.
 331                 */
 332
 333                /* 4. Enable the interrupts and DMA requests */
 334                out_be32(&ssi->sier, SIER_FLAGS);
 335
 336                /*
 337                 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
 338                 * don't use FIFO 1.  Since the SSI only supports stereo, the
 339                 * watermark should never be an odd number.
 340                 */
 341                out_be32(&ssi->sfcsr,
 342                         CCSR_SSI_SFCSR_TFWM0(6) | CCSR_SSI_SFCSR_RFWM0(2));
 343
 344                /*
 345                 * We keep the SSI disabled because if we enable it, then the
 346                 * DMA controller will start.  It's not supposed to start until
 347                 * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
 348                 * DMA controller will transfer one "BWC" of data (i.e. the
 349                 * amount of data that the MR.BWC bits are set to).  The reason
 350                 * this is bad is because at this point, the PCM driver has not
 351                 * finished initializing the DMA controller.
 352                 */
 353        }
 354
 355        if (!ssi_private->first_stream)
 356                ssi_private->first_stream = substream;
 357        else {
 358                /* This is the second stream open, so we need to impose sample
 359                 * rate and maybe sample size constraints.  Note that this can
 360                 * cause a race condition if the second stream is opened before
 361                 * the first stream is fully initialized.
 362                 *
 363                 * We provide some protection by checking to make sure the first
 364                 * stream is initialized, but it's not perfect.  ALSA sometimes
 365                 * re-initializes the driver with a different sample rate or
 366                 * size.  If the second stream is opened before the first stream
 367                 * has received its final parameters, then the second stream may
 368                 * be constrained to the wrong sample rate or size.
 369                 *
 370                 * FIXME: This code does not handle opening and closing streams
 371                 * repeatedly.  If you open two streams and then close the first
 372                 * one, you may not be able to open another stream until you
 373                 * close the second one as well.
 374                 */
 375                struct snd_pcm_runtime *first_runtime =
 376                        ssi_private->first_stream->runtime;
 377
 378                if (!first_runtime->sample_bits) {
 379                        dev_err(substream->pcm->card->dev,
 380                                "set sample size in %s stream first\n",
 381                                substream->stream == SNDRV_PCM_STREAM_PLAYBACK
 382                                ? "capture" : "playback");
 383                        return -EAGAIN;
 384                }
 385
 386                /* If we're in synchronous mode, then we need to constrain
 387                 * the sample size as well.  We don't support independent sample
 388                 * rates in asynchronous mode.
 389                 */
 390                if (!ssi_private->asynchronous)
 391                        snd_pcm_hw_constraint_minmax(substream->runtime,
 392                                SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
 393                                first_runtime->sample_bits,
 394                                first_runtime->sample_bits);
 395
 396                ssi_private->second_stream = substream;
 397        }
 398
 399        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 400                ssi_private->playback++;
 401
 402        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 403                ssi_private->capture++;
 404
 405        return 0;
 406}
 407
 408/**
 409 * fsl_ssi_hw_params - program the sample size
 410 *
 411 * Most of the SSI registers have been programmed in the startup function,
 412 * but the word length must be programmed here.  Unfortunately, programming
 413 * the SxCCR.WL bits requires the SSI to be temporarily disabled.  This can
 414 * cause a problem with supporting simultaneous playback and capture.  If
 415 * the SSI is already playing a stream, then that stream may be temporarily
 416 * stopped when you start capture.
 417 *
 418 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
 419 * clock master.
 420 */
 421static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 422        struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
 423{
 424        struct fsl_ssi_private *ssi_private = cpu_dai->private_data;
 425
 426        if (substream == ssi_private->first_stream) {
 427                struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 428                unsigned int sample_size =
 429                        snd_pcm_format_width(params_format(hw_params));
 430                u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
 431
 432                /* The SSI should always be disabled at this points (SSIEN=0) */
 433
 434                /* In synchronous mode, the SSI uses STCCR for capture */
 435                if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
 436                    !ssi_private->asynchronous)
 437                        clrsetbits_be32(&ssi->stccr,
 438                                        CCSR_SSI_SxCCR_WL_MASK, wl);
 439                else
 440                        clrsetbits_be32(&ssi->srccr,
 441                                        CCSR_SSI_SxCCR_WL_MASK, wl);
 442        }
 443
 444        return 0;
 445}
 446
 447/**
 448 * fsl_ssi_trigger: start and stop the DMA transfer.
 449 *
 450 * This function is called by ALSA to start, stop, pause, and resume the DMA
 451 * transfer of data.
 452 *
 453 * The DMA channel is in external master start and pause mode, which
 454 * means the SSI completely controls the flow of data.
 455 */
 456static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 457                           struct snd_soc_dai *dai)
 458{
 459        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 460        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
 461        struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 462
 463        switch (cmd) {
 464        case SNDRV_PCM_TRIGGER_START:
 465                clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
 466        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 467                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 468                        setbits32(&ssi->scr,
 469                                CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
 470                else
 471                        setbits32(&ssi->scr,
 472                                CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
 473                break;
 474
 475        case SNDRV_PCM_TRIGGER_STOP:
 476        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 477                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 478                        clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
 479                else
 480                        clrbits32(&ssi->scr, CCSR_SSI_SCR_RE);
 481                break;
 482
 483        default:
 484                return -EINVAL;
 485        }
 486
 487        return 0;
 488}
 489
 490/**
 491 * fsl_ssi_shutdown: shutdown the SSI
 492 *
 493 * Shutdown the SSI if there are no other substreams open.
 494 */
 495static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
 496                             struct snd_soc_dai *dai)
 497{
 498        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 499        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
 500
 501        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 502                ssi_private->playback--;
 503
 504        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 505                ssi_private->capture--;
 506
 507        if (ssi_private->first_stream == substream)
 508                ssi_private->first_stream = ssi_private->second_stream;
 509
 510        ssi_private->second_stream = NULL;
 511
 512        /*
 513         * If this is the last active substream, disable the SSI and release
 514         * the IRQ.
 515         */
 516        if (!ssi_private->playback && !ssi_private->capture) {
 517                struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 518
 519                clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
 520
 521                free_irq(ssi_private->irq, ssi_private);
 522        }
 523}
 524
 525/**
 526 * fsl_ssi_set_sysclk: set the clock frequency and direction
 527 *
 528 * This function is called by the machine driver to tell us what the clock
 529 * frequency and direction are.
 530 *
 531 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
 532 * and we don't care about the frequency.  Return an error if the direction
 533 * is not SND_SOC_CLOCK_IN.
 534 *
 535 * @clk_id: reserved, should be zero
 536 * @freq: the frequency of the given clock ID, currently ignored
 537 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
 538 */
 539static int fsl_ssi_set_sysclk(struct snd_soc_dai *cpu_dai,
 540                              int clk_id, unsigned int freq, int dir)
 541{
 542
 543        return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
 544}
 545
 546/**
 547 * fsl_ssi_set_fmt: set the serial format.
 548 *
 549 * This function is called by the machine driver to tell us what serial
 550 * format to use.
 551 *
 552 * Currently, we only support I2S mode.  Return an error if the format is
 553 * not SND_SOC_DAIFMT_I2S.
 554 *
 555 * @format: one of SND_SOC_DAIFMT_xxx
 556 */
 557static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
 558{
 559        return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
 560}
 561
 562/**
 563 * fsl_ssi_dai_template: template CPU DAI for the SSI
 564 */
 565static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
 566        .startup        = fsl_ssi_startup,
 567        .hw_params      = fsl_ssi_hw_params,
 568        .shutdown       = fsl_ssi_shutdown,
 569        .trigger        = fsl_ssi_trigger,
 570        .set_sysclk     = fsl_ssi_set_sysclk,
 571        .set_fmt        = fsl_ssi_set_fmt,
 572};
 573
 574static struct snd_soc_dai fsl_ssi_dai_template = {
 575        .playback = {
 576                /* The SSI does not support monaural audio. */
 577                .channels_min = 2,
 578                .channels_max = 2,
 579                .rates = FSLSSI_I2S_RATES,
 580                .formats = FSLSSI_I2S_FORMATS,
 581        },
 582        .capture = {
 583                .channels_min = 2,
 584                .channels_max = 2,
 585                .rates = FSLSSI_I2S_RATES,
 586                .formats = FSLSSI_I2S_FORMATS,
 587        },
 588        .ops = &fsl_ssi_dai_ops,
 589};
 590
 591/* Show the statistics of a flag only if its interrupt is enabled.  The
 592 * compiler will optimze this code to a no-op if the interrupt is not
 593 * enabled.
 594 */
 595#define SIER_SHOW(flag, name) \
 596        do { \
 597                if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
 598                        length += sprintf(buf + length, #name "=%u\n", \
 599                                ssi_private->stats.name); \
 600        } while (0)
 601
 602
 603/**
 604 * fsl_sysfs_ssi_show: display SSI statistics
 605 *
 606 * Display the statistics for the current SSI device.  To avoid confusion,
 607 * we only show those counts that are enabled.
 608 */
 609static ssize_t fsl_sysfs_ssi_show(struct device *dev,
 610        struct device_attribute *attr, char *buf)
 611{
 612        struct fsl_ssi_private *ssi_private =
 613                container_of(attr, struct fsl_ssi_private, dev_attr);
 614        ssize_t length = 0;
 615
 616        SIER_SHOW(RFRC_EN, rfrc);
 617        SIER_SHOW(TFRC_EN, tfrc);
 618        SIER_SHOW(CMDAU_EN, cmdau);
 619        SIER_SHOW(CMDDU_EN, cmddu);
 620        SIER_SHOW(RXT_EN, rxt);
 621        SIER_SHOW(RDR1_EN, rdr1);
 622        SIER_SHOW(RDR0_EN, rdr0);
 623        SIER_SHOW(TDE1_EN, tde1);
 624        SIER_SHOW(TDE0_EN, tde0);
 625        SIER_SHOW(ROE1_EN, roe1);
 626        SIER_SHOW(ROE0_EN, roe0);
 627        SIER_SHOW(TUE1_EN, tue1);
 628        SIER_SHOW(TUE0_EN, tue0);
 629        SIER_SHOW(TFS_EN, tfs);
 630        SIER_SHOW(RFS_EN, rfs);
 631        SIER_SHOW(TLS_EN, tls);
 632        SIER_SHOW(RLS_EN, rls);
 633        SIER_SHOW(RFF1_EN, rff1);
 634        SIER_SHOW(RFF0_EN, rff0);
 635        SIER_SHOW(TFE1_EN, tfe1);
 636        SIER_SHOW(TFE0_EN, tfe0);
 637
 638        return length;
 639}
 640
 641/**
 642 * fsl_ssi_create_dai: create a snd_soc_dai structure
 643 *
 644 * This function is called by the machine driver to create a snd_soc_dai
 645 * structure.  The function creates an ssi_private object, which contains
 646 * the snd_soc_dai.  It also creates the sysfs statistics device.
 647 */
 648struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
 649{
 650        struct snd_soc_dai *fsl_ssi_dai;
 651        struct fsl_ssi_private *ssi_private;
 652        int ret = 0;
 653        struct device_attribute *dev_attr;
 654
 655        ssi_private = kzalloc(sizeof(struct fsl_ssi_private), GFP_KERNEL);
 656        if (!ssi_private) {
 657                dev_err(ssi_info->dev, "could not allocate DAI object\n");
 658                return NULL;
 659        }
 660        memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template,
 661               sizeof(struct snd_soc_dai));
 662
 663        fsl_ssi_dai = &ssi_private->cpu_dai;
 664        dev_attr = &ssi_private->dev_attr;
 665
 666        sprintf(ssi_private->name, "ssi%u", (u8) ssi_info->id);
 667        ssi_private->ssi = ssi_info->ssi;
 668        ssi_private->ssi_phys = ssi_info->ssi_phys;
 669        ssi_private->irq = ssi_info->irq;
 670        ssi_private->dev = ssi_info->dev;
 671        ssi_private->asynchronous = ssi_info->asynchronous;
 672
 673        dev_set_drvdata(ssi_private->dev, fsl_ssi_dai);
 674
 675        /* Initialize the the device_attribute structure */
 676        dev_attr->attr.name = "ssi-stats";
 677        dev_attr->attr.mode = S_IRUGO;
 678        dev_attr->show = fsl_sysfs_ssi_show;
 679
 680        ret = device_create_file(ssi_private->dev, dev_attr);
 681        if (ret) {
 682                dev_err(ssi_info->dev, "could not create sysfs %s file\n",
 683                        ssi_private->dev_attr.attr.name);
 684                kfree(fsl_ssi_dai);
 685                return NULL;
 686        }
 687
 688        fsl_ssi_dai->private_data = ssi_private;
 689        fsl_ssi_dai->name = ssi_private->name;
 690        fsl_ssi_dai->id = ssi_info->id;
 691        fsl_ssi_dai->dev = ssi_info->dev;
 692        fsl_ssi_dai->symmetric_rates = 1;
 693
 694        ret = snd_soc_register_dai(fsl_ssi_dai);
 695        if (ret != 0) {
 696                dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
 697                kfree(fsl_ssi_dai);
 698                return NULL;
 699        }
 700
 701        return fsl_ssi_dai;
 702}
 703EXPORT_SYMBOL_GPL(fsl_ssi_create_dai);
 704
 705/**
 706 * fsl_ssi_destroy_dai: destroy the snd_soc_dai object
 707 *
 708 * This function undoes the operations of fsl_ssi_create_dai()
 709 */
 710void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
 711{
 712        struct fsl_ssi_private *ssi_private =
 713        container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai);
 714
 715        device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
 716
 717        snd_soc_unregister_dai(&ssi_private->cpu_dai);
 718
 719        kfree(ssi_private);
 720}
 721EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
 722
 723static int __init fsl_ssi_init(void)
 724{
 725        printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
 726
 727        return 0;
 728}
 729module_init(fsl_ssi_init);
 730
 731MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 732MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
 733MODULE_LICENSE("GPL");
 734