linux/sound/soc/omap/omap-mcbsp.c
<<
>>
Prefs
   1/*
   2 * omap-mcbsp.c  --  OMAP ALSA SoC DAI driver using McBSP port
   3 *
   4 * Copyright (C) 2008 Nokia Corporation
   5 *
   6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
   7 *          Peter Ujfalusi <peter.ujfalusi@ti.com>
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License
  11 * version 2 as published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21 * 02110-1301 USA
  22 *
  23 */
  24
  25#include <linux/init.h>
  26#include <linux/module.h>
  27#include <linux/device.h>
  28#include <linux/pm_runtime.h>
  29#include <linux/of.h>
  30#include <linux/of_device.h>
  31#include <sound/core.h>
  32#include <sound/pcm.h>
  33#include <sound/pcm_params.h>
  34#include <sound/initval.h>
  35#include <sound/soc.h>
  36#include <sound/dmaengine_pcm.h>
  37#include <sound/omap-pcm.h>
  38
  39#include <linux/platform_data/asoc-ti-mcbsp.h>
  40#include "mcbsp.h"
  41#include "omap-mcbsp.h"
  42
  43#define OMAP_MCBSP_RATES        (SNDRV_PCM_RATE_8000_96000)
  44
  45#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
  46        xhandler_get, xhandler_put) \
  47{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  48        .info = omap_mcbsp_st_info_volsw, \
  49        .get = xhandler_get, .put = xhandler_put, \
  50        .private_value = (unsigned long) &(struct soc_mixer_control) \
  51        {.min = xmin, .max = xmax} }
  52
  53enum {
  54        OMAP_MCBSP_WORD_8 = 0,
  55        OMAP_MCBSP_WORD_12,
  56        OMAP_MCBSP_WORD_16,
  57        OMAP_MCBSP_WORD_20,
  58        OMAP_MCBSP_WORD_24,
  59        OMAP_MCBSP_WORD_32,
  60};
  61
  62/*
  63 * Stream DMA parameters. DMA request line and port address are set runtime
  64 * since they are different between OMAP1 and later OMAPs
  65 */
  66static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream,
  67                unsigned int packet_size)
  68{
  69        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  70        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  71        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
  72        int words;
  73
  74        /*
  75         * Configure McBSP threshold based on either:
  76         * packet_size, when the sDMA is in packet mode, or based on the
  77         * period size in THRESHOLD mode, otherwise use McBSP threshold = 1
  78         * for mono streams.
  79         */
  80        if (packet_size)
  81                words = packet_size;
  82        else
  83                words = 1;
  84
  85        /* Configure McBSP internal buffer usage */
  86        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  87                omap_mcbsp_set_tx_threshold(mcbsp, words);
  88        else
  89                omap_mcbsp_set_rx_threshold(mcbsp, words);
  90}
  91
  92static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
  93                                    struct snd_pcm_hw_rule *rule)
  94{
  95        struct snd_interval *buffer_size = hw_param_interval(params,
  96                                        SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
  97        struct snd_interval *channels = hw_param_interval(params,
  98                                        SNDRV_PCM_HW_PARAM_CHANNELS);
  99        struct omap_mcbsp *mcbsp = rule->private;
 100        struct snd_interval frames;
 101        int size;
 102
 103        snd_interval_any(&frames);
 104        size = mcbsp->pdata->buffer_size;
 105
 106        frames.min = size / channels->min;
 107        frames.integer = 1;
 108        return snd_interval_refine(buffer_size, &frames);
 109}
 110
 111static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
 112                                  struct snd_soc_dai *cpu_dai)
 113{
 114        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 115        int err = 0;
 116
 117        if (!cpu_dai->active)
 118                err = omap_mcbsp_request(mcbsp);
 119
 120        /*
 121         * OMAP3 McBSP FIFO is word structured.
 122         * McBSP2 has 1024 + 256 = 1280 word long buffer,
 123         * McBSP1,3,4,5 has 128 word long buffer
 124         * This means that the size of the FIFO depends on the sample format.
 125         * For example on McBSP3:
 126         * 16bit samples: size is 128 * 2 = 256 bytes
 127         * 32bit samples: size is 128 * 4 = 512 bytes
 128         * It is simpler to place constraint for buffer and period based on
 129         * channels.
 130         * McBSP3 as example again (16 or 32 bit samples):
 131         * 1 channel (mono): size is 128 frames (128 words)
 132         * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
 133         * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
 134         */
 135        if (mcbsp->pdata->buffer_size) {
 136                /*
 137                * Rule for the buffer size. We should not allow
 138                * smaller buffer than the FIFO size to avoid underruns.
 139                * This applies only for the playback stream.
 140                */
 141                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 142                        snd_pcm_hw_rule_add(substream->runtime, 0,
 143                                            SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
 144                                            omap_mcbsp_hwrule_min_buffersize,
 145                                            mcbsp,
 146                                            SNDRV_PCM_HW_PARAM_CHANNELS, -1);
 147
 148                /* Make sure, that the period size is always even */
 149                snd_pcm_hw_constraint_step(substream->runtime, 0,
 150                                           SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
 151        }
 152
 153        return err;
 154}
 155
 156static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
 157                                    struct snd_soc_dai *cpu_dai)
 158{
 159        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 160        int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 161        int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 162        int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 163
 164        if (mcbsp->latency[stream2])
 165                pm_qos_update_request(&mcbsp->pm_qos_req,
 166                                      mcbsp->latency[stream2]);
 167        else if (mcbsp->latency[stream1])
 168                pm_qos_remove_request(&mcbsp->pm_qos_req);
 169
 170        mcbsp->latency[stream1] = 0;
 171
 172        if (!cpu_dai->active) {
 173                omap_mcbsp_free(mcbsp);
 174                mcbsp->configured = 0;
 175        }
 176}
 177
 178static int omap_mcbsp_dai_prepare(struct snd_pcm_substream *substream,
 179                                  struct snd_soc_dai *cpu_dai)
 180{
 181        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 182        struct pm_qos_request *pm_qos_req = &mcbsp->pm_qos_req;
 183        int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 184        int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 185        int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 186        int latency = mcbsp->latency[stream2];
 187
 188        /* Prevent omap hardware from hitting off between FIFO fills */
 189        if (!latency || mcbsp->latency[stream1] < latency)
 190                latency = mcbsp->latency[stream1];
 191
 192        if (pm_qos_request_active(pm_qos_req))
 193                pm_qos_update_request(pm_qos_req, latency);
 194        else if (latency)
 195                pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency);
 196
 197        return 0;
 198}
 199
 200static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 201                                  struct snd_soc_dai *cpu_dai)
 202{
 203        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 204        int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 205
 206        switch (cmd) {
 207        case SNDRV_PCM_TRIGGER_START:
 208        case SNDRV_PCM_TRIGGER_RESUME:
 209        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 210                mcbsp->active++;
 211                omap_mcbsp_start(mcbsp, play, !play);
 212                break;
 213
 214        case SNDRV_PCM_TRIGGER_STOP:
 215        case SNDRV_PCM_TRIGGER_SUSPEND:
 216        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 217                omap_mcbsp_stop(mcbsp, play, !play);
 218                mcbsp->active--;
 219                break;
 220        default:
 221                err = -EINVAL;
 222        }
 223
 224        return err;
 225}
 226
 227static snd_pcm_sframes_t omap_mcbsp_dai_delay(
 228                        struct snd_pcm_substream *substream,
 229                        struct snd_soc_dai *dai)
 230{
 231        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 232        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 233        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 234        u16 fifo_use;
 235        snd_pcm_sframes_t delay;
 236
 237        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 238                fifo_use = omap_mcbsp_get_tx_delay(mcbsp);
 239        else
 240                fifo_use = omap_mcbsp_get_rx_delay(mcbsp);
 241
 242        /*
 243         * Divide the used locations with the channel count to get the
 244         * FIFO usage in samples (don't care about partial samples in the
 245         * buffer).
 246         */
 247        delay = fifo_use / substream->runtime->channels;
 248
 249        return delay;
 250}
 251
 252static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
 253                                    struct snd_pcm_hw_params *params,
 254                                    struct snd_soc_dai *cpu_dai)
 255{
 256        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 257        struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
 258        struct snd_dmaengine_dai_dma_data *dma_data;
 259        int wlen, channels, wpf;
 260        int pkt_size = 0;
 261        unsigned int format, div, framesize, master;
 262        unsigned int buffer_size = mcbsp->pdata->buffer_size;
 263
 264        dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
 265        channels = params_channels(params);
 266
 267        switch (params_format(params)) {
 268        case SNDRV_PCM_FORMAT_S16_LE:
 269                wlen = 16;
 270                break;
 271        case SNDRV_PCM_FORMAT_S32_LE:
 272                wlen = 32;
 273                break;
 274        default:
 275                return -EINVAL;
 276        }
 277        if (buffer_size) {
 278                int latency;
 279
 280                if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 281                        int period_words, max_thrsh;
 282                        int divider = 0;
 283
 284                        period_words = params_period_bytes(params) / (wlen / 8);
 285                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 286                                max_thrsh = mcbsp->max_tx_thres;
 287                        else
 288                                max_thrsh = mcbsp->max_rx_thres;
 289                        /*
 290                         * Use sDMA packet mode if McBSP is in threshold mode:
 291                         * If period words less than the FIFO size the packet
 292                         * size is set to the number of period words, otherwise
 293                         * Look for the biggest threshold value which divides
 294                         * the period size evenly.
 295                         */
 296                        divider = period_words / max_thrsh;
 297                        if (period_words % max_thrsh)
 298                                divider++;
 299                        while (period_words % divider &&
 300                                divider < period_words)
 301                                divider++;
 302                        if (divider == period_words)
 303                                return -EINVAL;
 304
 305                        pkt_size = period_words / divider;
 306                } else if (channels > 1) {
 307                        /* Use packet mode for non mono streams */
 308                        pkt_size = channels;
 309                }
 310
 311                latency = ((((buffer_size - pkt_size) / channels) * 1000)
 312                                 / (params->rate_num / params->rate_den));
 313
 314                mcbsp->latency[substream->stream] = latency;
 315
 316                omap_mcbsp_set_threshold(substream, pkt_size);
 317        }
 318
 319        dma_data->maxburst = pkt_size;
 320
 321        if (mcbsp->configured) {
 322                /* McBSP already configured by another stream */
 323                return 0;
 324        }
 325
 326        regs->rcr2      &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7));
 327        regs->xcr2      &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
 328        regs->rcr1      &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
 329        regs->xcr1      &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
 330        format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 331        wpf = channels;
 332        if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
 333                              format == SND_SOC_DAIFMT_LEFT_J)) {
 334                /* Use dual-phase frames */
 335                regs->rcr2      |= RPHASE;
 336                regs->xcr2      |= XPHASE;
 337                /* Set 1 word per (McBSP) frame for phase1 and phase2 */
 338                wpf--;
 339                regs->rcr2      |= RFRLEN2(wpf - 1);
 340                regs->xcr2      |= XFRLEN2(wpf - 1);
 341        }
 342
 343        regs->rcr1      |= RFRLEN1(wpf - 1);
 344        regs->xcr1      |= XFRLEN1(wpf - 1);
 345
 346        switch (params_format(params)) {
 347        case SNDRV_PCM_FORMAT_S16_LE:
 348                /* Set word lengths */
 349                regs->rcr2      |= RWDLEN2(OMAP_MCBSP_WORD_16);
 350                regs->rcr1      |= RWDLEN1(OMAP_MCBSP_WORD_16);
 351                regs->xcr2      |= XWDLEN2(OMAP_MCBSP_WORD_16);
 352                regs->xcr1      |= XWDLEN1(OMAP_MCBSP_WORD_16);
 353                break;
 354        case SNDRV_PCM_FORMAT_S32_LE:
 355                /* Set word lengths */
 356                regs->rcr2      |= RWDLEN2(OMAP_MCBSP_WORD_32);
 357                regs->rcr1      |= RWDLEN1(OMAP_MCBSP_WORD_32);
 358                regs->xcr2      |= XWDLEN2(OMAP_MCBSP_WORD_32);
 359                regs->xcr1      |= XWDLEN1(OMAP_MCBSP_WORD_32);
 360                break;
 361        default:
 362                /* Unsupported PCM format */
 363                return -EINVAL;
 364        }
 365
 366        /* In McBSP master modes, FRAME (i.e. sample rate) is generated
 367         * by _counting_ BCLKs. Calculate frame size in BCLKs */
 368        master = mcbsp->fmt & SND_SOC_DAIFMT_MASTER_MASK;
 369        if (master ==   SND_SOC_DAIFMT_CBS_CFS) {
 370                div = mcbsp->clk_div ? mcbsp->clk_div : 1;
 371                framesize = (mcbsp->in_freq / div) / params_rate(params);
 372
 373                if (framesize < wlen * channels) {
 374                        printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
 375                                        "channels\n", __func__);
 376                        return -EINVAL;
 377                }
 378        } else
 379                framesize = wlen * channels;
 380
 381        /* Set FS period and length in terms of bit clock periods */
 382        regs->srgr2     &= ~FPER(0xfff);
 383        regs->srgr1     &= ~FWID(0xff);
 384        switch (format) {
 385        case SND_SOC_DAIFMT_I2S:
 386        case SND_SOC_DAIFMT_LEFT_J:
 387                regs->srgr2     |= FPER(framesize - 1);
 388                regs->srgr1     |= FWID((framesize >> 1) - 1);
 389                break;
 390        case SND_SOC_DAIFMT_DSP_A:
 391        case SND_SOC_DAIFMT_DSP_B:
 392                regs->srgr2     |= FPER(framesize - 1);
 393                regs->srgr1     |= FWID(0);
 394                break;
 395        }
 396
 397        omap_mcbsp_config(mcbsp, &mcbsp->cfg_regs);
 398        mcbsp->wlen = wlen;
 399        mcbsp->configured = 1;
 400
 401        return 0;
 402}
 403
 404/*
 405 * This must be called before _set_clkdiv and _set_sysclk since McBSP register
 406 * cache is initialized here
 407 */
 408static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 409                                      unsigned int fmt)
 410{
 411        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 412        struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
 413        bool inv_fs = false;
 414
 415        if (mcbsp->configured)
 416                return 0;
 417
 418        mcbsp->fmt = fmt;
 419        memset(regs, 0, sizeof(*regs));
 420        /* Generic McBSP register settings */
 421        regs->spcr2     |= XINTM(3) | FREE;
 422        regs->spcr1     |= RINTM(3);
 423        /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */
 424        if (!mcbsp->pdata->has_ccr) {
 425                regs->rcr2      |= RFIG;
 426                regs->xcr2      |= XFIG;
 427        }
 428
 429        /* Configure XCCR/RCCR only for revisions which have ccr registers */
 430        if (mcbsp->pdata->has_ccr) {
 431                regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
 432                regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
 433        }
 434
 435        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 436        case SND_SOC_DAIFMT_I2S:
 437                /* 1-bit data delay */
 438                regs->rcr2      |= RDATDLY(1);
 439                regs->xcr2      |= XDATDLY(1);
 440                break;
 441        case SND_SOC_DAIFMT_LEFT_J:
 442                /* 0-bit data delay */
 443                regs->rcr2      |= RDATDLY(0);
 444                regs->xcr2      |= XDATDLY(0);
 445                regs->spcr1     |= RJUST(2);
 446                /* Invert FS polarity configuration */
 447                inv_fs = true;
 448                break;
 449        case SND_SOC_DAIFMT_DSP_A:
 450                /* 1-bit data delay */
 451                regs->rcr2      |= RDATDLY(1);
 452                regs->xcr2      |= XDATDLY(1);
 453                /* Invert FS polarity configuration */
 454                inv_fs = true;
 455                break;
 456        case SND_SOC_DAIFMT_DSP_B:
 457                /* 0-bit data delay */
 458                regs->rcr2      |= RDATDLY(0);
 459                regs->xcr2      |= XDATDLY(0);
 460                /* Invert FS polarity configuration */
 461                inv_fs = true;
 462                break;
 463        default:
 464                /* Unsupported data format */
 465                return -EINVAL;
 466        }
 467
 468        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 469        case SND_SOC_DAIFMT_CBS_CFS:
 470                /* McBSP master. Set FS and bit clocks as outputs */
 471                regs->pcr0      |= FSXM | FSRM |
 472                                   CLKXM | CLKRM;
 473                /* Sample rate generator drives the FS */
 474                regs->srgr2     |= FSGM;
 475                break;
 476        case SND_SOC_DAIFMT_CBM_CFS:
 477                /* McBSP slave. FS clock as output */
 478                regs->srgr2     |= FSGM;
 479                regs->pcr0      |= FSXM | FSRM;
 480                break;
 481        case SND_SOC_DAIFMT_CBM_CFM:
 482                /* McBSP slave */
 483                break;
 484        default:
 485                /* Unsupported master/slave configuration */
 486                return -EINVAL;
 487        }
 488
 489        /* Set bit clock (CLKX/CLKR) and FS polarities */
 490        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 491        case SND_SOC_DAIFMT_NB_NF:
 492                /*
 493                 * Normal BCLK + FS.
 494                 * FS active low. TX data driven on falling edge of bit clock
 495                 * and RX data sampled on rising edge of bit clock.
 496                 */
 497                regs->pcr0      |= FSXP | FSRP |
 498                                   CLKXP | CLKRP;
 499                break;
 500        case SND_SOC_DAIFMT_NB_IF:
 501                regs->pcr0      |= CLKXP | CLKRP;
 502                break;
 503        case SND_SOC_DAIFMT_IB_NF:
 504                regs->pcr0      |= FSXP | FSRP;
 505                break;
 506        case SND_SOC_DAIFMT_IB_IF:
 507                break;
 508        default:
 509                return -EINVAL;
 510        }
 511        if (inv_fs == true)
 512                regs->pcr0 ^= FSXP | FSRP;
 513
 514        return 0;
 515}
 516
 517static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
 518                                     int div_id, int div)
 519{
 520        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 521        struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
 522
 523        if (div_id != OMAP_MCBSP_CLKGDV)
 524                return -ENODEV;
 525
 526        mcbsp->clk_div = div;
 527        regs->srgr1     &= ~CLKGDV(0xff);
 528        regs->srgr1     |= CLKGDV(div - 1);
 529
 530        return 0;
 531}
 532
 533static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 534                                         int clk_id, unsigned int freq,
 535                                         int dir)
 536{
 537        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 538        struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
 539        int err = 0;
 540
 541        if (mcbsp->active) {
 542                if (freq == mcbsp->in_freq)
 543                        return 0;
 544                else
 545                        return -EBUSY;
 546        }
 547
 548        mcbsp->in_freq = freq;
 549        regs->srgr2 &= ~CLKSM;
 550        regs->pcr0 &= ~SCLKME;
 551
 552        switch (clk_id) {
 553        case OMAP_MCBSP_SYSCLK_CLK:
 554                regs->srgr2     |= CLKSM;
 555                break;
 556        case OMAP_MCBSP_SYSCLK_CLKS_FCLK:
 557                if (mcbsp_omap1()) {
 558                        err = -EINVAL;
 559                        break;
 560                }
 561                err = omap2_mcbsp_set_clks_src(mcbsp,
 562                                               MCBSP_CLKS_PRCM_SRC);
 563                break;
 564        case OMAP_MCBSP_SYSCLK_CLKS_EXT:
 565                if (mcbsp_omap1()) {
 566                        err = 0;
 567                        break;
 568                }
 569                err = omap2_mcbsp_set_clks_src(mcbsp,
 570                                               MCBSP_CLKS_PAD_SRC);
 571                break;
 572
 573        case OMAP_MCBSP_SYSCLK_CLKX_EXT:
 574                regs->srgr2     |= CLKSM;
 575                regs->pcr0      |= SCLKME;
 576                /*
 577                 * If McBSP is master but yet the CLKX/CLKR pin drives the SRG,
 578                 * disable output on those pins. This enables to inject the
 579                 * reference clock through CLKX/CLKR. For this to work
 580                 * set_dai_sysclk() _needs_ to be called after set_dai_fmt().
 581                 */
 582                regs->pcr0      &= ~CLKXM;
 583                break;
 584        case OMAP_MCBSP_SYSCLK_CLKR_EXT:
 585                regs->pcr0      |= SCLKME;
 586                /* Disable ouput on CLKR pin in master mode */
 587                regs->pcr0      &= ~CLKRM;
 588                break;
 589        default:
 590                err = -ENODEV;
 591        }
 592
 593        return err;
 594}
 595
 596static const struct snd_soc_dai_ops mcbsp_dai_ops = {
 597        .startup        = omap_mcbsp_dai_startup,
 598        .shutdown       = omap_mcbsp_dai_shutdown,
 599        .prepare        = omap_mcbsp_dai_prepare,
 600        .trigger        = omap_mcbsp_dai_trigger,
 601        .delay          = omap_mcbsp_dai_delay,
 602        .hw_params      = omap_mcbsp_dai_hw_params,
 603        .set_fmt        = omap_mcbsp_dai_set_dai_fmt,
 604        .set_clkdiv     = omap_mcbsp_dai_set_clkdiv,
 605        .set_sysclk     = omap_mcbsp_dai_set_dai_sysclk,
 606};
 607
 608static int omap_mcbsp_probe(struct snd_soc_dai *dai)
 609{
 610        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
 611
 612        pm_runtime_enable(mcbsp->dev);
 613
 614        snd_soc_dai_init_dma_data(dai,
 615                                  &mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
 616                                  &mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
 617
 618        return 0;
 619}
 620
 621static int omap_mcbsp_remove(struct snd_soc_dai *dai)
 622{
 623        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
 624
 625        pm_runtime_disable(mcbsp->dev);
 626
 627        return 0;
 628}
 629
 630static struct snd_soc_dai_driver omap_mcbsp_dai = {
 631        .probe = omap_mcbsp_probe,
 632        .remove = omap_mcbsp_remove,
 633        .playback = {
 634                .channels_min = 1,
 635                .channels_max = 16,
 636                .rates = OMAP_MCBSP_RATES,
 637                .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
 638        },
 639        .capture = {
 640                .channels_min = 1,
 641                .channels_max = 16,
 642                .rates = OMAP_MCBSP_RATES,
 643                .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
 644        },
 645        .ops = &mcbsp_dai_ops,
 646};
 647
 648static const struct snd_soc_component_driver omap_mcbsp_component = {
 649        .name           = "omap-mcbsp",
 650};
 651
 652static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
 653                        struct snd_ctl_elem_info *uinfo)
 654{
 655        struct soc_mixer_control *mc =
 656                (struct soc_mixer_control *)kcontrol->private_value;
 657        int max = mc->max;
 658        int min = mc->min;
 659
 660        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 661        uinfo->count = 1;
 662        uinfo->value.integer.min = min;
 663        uinfo->value.integer.max = max;
 664        return 0;
 665}
 666
 667#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel)                           \
 668static int                                                              \
 669omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc,         \
 670                                        struct snd_ctl_elem_value *uc)  \
 671{                                                                       \
 672        struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc);            \
 673        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);    \
 674        struct soc_mixer_control *mc =                                  \
 675                (struct soc_mixer_control *)kc->private_value;          \
 676        int max = mc->max;                                              \
 677        int min = mc->min;                                              \
 678        int val = uc->value.integer.value[0];                           \
 679                                                                        \
 680        if (val < min || val > max)                                     \
 681                return -EINVAL;                                         \
 682                                                                        \
 683        /* OMAP McBSP implementation uses index values 0..4 */          \
 684        return omap_st_set_chgain(mcbsp, channel, val);                 \
 685}                                                                       \
 686                                                                        \
 687static int                                                              \
 688omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc,         \
 689                                        struct snd_ctl_elem_value *uc)  \
 690{                                                                       \
 691        struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc);            \
 692        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);    \
 693        s16 chgain;                                                     \
 694                                                                        \
 695        if (omap_st_get_chgain(mcbsp, channel, &chgain))                \
 696                return -EAGAIN;                                         \
 697                                                                        \
 698        uc->value.integer.value[0] = chgain;                            \
 699        return 0;                                                       \
 700}
 701
 702OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
 703OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
 704
 705static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
 706                                struct snd_ctl_elem_value *ucontrol)
 707{
 708        struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
 709        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 710        u8 value = ucontrol->value.integer.value[0];
 711
 712        if (value == omap_st_is_enabled(mcbsp))
 713                return 0;
 714
 715        if (value)
 716                omap_st_enable(mcbsp);
 717        else
 718                omap_st_disable(mcbsp);
 719
 720        return 1;
 721}
 722
 723static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
 724                                struct snd_ctl_elem_value *ucontrol)
 725{
 726        struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
 727        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 728
 729        ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp);
 730        return 0;
 731}
 732
 733#define OMAP_MCBSP_ST_CONTROLS(port)                                      \
 734static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
 735SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0,              \
 736               omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),           \
 737OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
 738                              -32768, 32767,                              \
 739                              omap_mcbsp_get_st_ch0_volume,               \
 740                              omap_mcbsp_set_st_ch0_volume),              \
 741OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
 742                              -32768, 32767,                              \
 743                              omap_mcbsp_get_st_ch1_volume,               \
 744                              omap_mcbsp_set_st_ch1_volume),              \
 745}
 746
 747OMAP_MCBSP_ST_CONTROLS(2);
 748OMAP_MCBSP_ST_CONTROLS(3);
 749
 750int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id)
 751{
 752        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 753        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 754
 755        if (!mcbsp->st_data) {
 756                dev_warn(mcbsp->dev, "No sidetone data for port\n");
 757                return 0;
 758        }
 759
 760        switch (port_id) {
 761        case 2: /* McBSP 2 */
 762                return snd_soc_add_dai_controls(cpu_dai,
 763                                        omap_mcbsp2_st_controls,
 764                                        ARRAY_SIZE(omap_mcbsp2_st_controls));
 765        case 3: /* McBSP 3 */
 766                return snd_soc_add_dai_controls(cpu_dai,
 767                                        omap_mcbsp3_st_controls,
 768                                        ARRAY_SIZE(omap_mcbsp3_st_controls));
 769        default:
 770                dev_err(mcbsp->dev, "Port %d not supported\n", port_id);
 771                break;
 772        }
 773
 774        return -EINVAL;
 775}
 776EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
 777
 778static struct omap_mcbsp_platform_data omap2420_pdata = {
 779        .reg_step = 4,
 780        .reg_size = 2,
 781};
 782
 783static struct omap_mcbsp_platform_data omap2430_pdata = {
 784        .reg_step = 4,
 785        .reg_size = 4,
 786        .has_ccr = true,
 787};
 788
 789static struct omap_mcbsp_platform_data omap3_pdata = {
 790        .reg_step = 4,
 791        .reg_size = 4,
 792        .has_ccr = true,
 793        .has_wakeup = true,
 794};
 795
 796static struct omap_mcbsp_platform_data omap4_pdata = {
 797        .reg_step = 4,
 798        .reg_size = 4,
 799        .has_ccr = true,
 800        .has_wakeup = true,
 801};
 802
 803static const struct of_device_id omap_mcbsp_of_match[] = {
 804        {
 805                .compatible = "ti,omap2420-mcbsp",
 806                .data = &omap2420_pdata,
 807        },
 808        {
 809                .compatible = "ti,omap2430-mcbsp",
 810                .data = &omap2430_pdata,
 811        },
 812        {
 813                .compatible = "ti,omap3-mcbsp",
 814                .data = &omap3_pdata,
 815        },
 816        {
 817                .compatible = "ti,omap4-mcbsp",
 818                .data = &omap4_pdata,
 819        },
 820        { },
 821};
 822MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
 823
 824static int asoc_mcbsp_probe(struct platform_device *pdev)
 825{
 826        struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
 827        struct omap_mcbsp *mcbsp;
 828        const struct of_device_id *match;
 829        int ret;
 830
 831        match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
 832        if (match) {
 833                struct device_node *node = pdev->dev.of_node;
 834                struct omap_mcbsp_platform_data *pdata_quirk = pdata;
 835                int buffer_size;
 836
 837                pdata = devm_kzalloc(&pdev->dev,
 838                                     sizeof(struct omap_mcbsp_platform_data),
 839                                     GFP_KERNEL);
 840                if (!pdata)
 841                        return -ENOMEM;
 842
 843                memcpy(pdata, match->data, sizeof(*pdata));
 844                if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
 845                        pdata->buffer_size = buffer_size;
 846                if (pdata_quirk)
 847                        pdata->force_ick_on = pdata_quirk->force_ick_on;
 848        } else if (!pdata) {
 849                dev_err(&pdev->dev, "missing platform data.\n");
 850                return -EINVAL;
 851        }
 852        mcbsp = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcbsp), GFP_KERNEL);
 853        if (!mcbsp)
 854                return -ENOMEM;
 855
 856        mcbsp->id = pdev->id;
 857        mcbsp->pdata = pdata;
 858        mcbsp->dev = &pdev->dev;
 859        platform_set_drvdata(pdev, mcbsp);
 860
 861        ret = omap_mcbsp_init(pdev);
 862        if (ret)
 863                return ret;
 864
 865        ret = devm_snd_soc_register_component(&pdev->dev,
 866                                              &omap_mcbsp_component,
 867                                              &omap_mcbsp_dai, 1);
 868        if (ret)
 869                return ret;
 870
 871        return omap_pcm_platform_register(&pdev->dev);
 872}
 873
 874static int asoc_mcbsp_remove(struct platform_device *pdev)
 875{
 876        struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
 877
 878        if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
 879                mcbsp->pdata->ops->free(mcbsp->id);
 880
 881        if (pm_qos_request_active(&mcbsp->pm_qos_req))
 882                pm_qos_remove_request(&mcbsp->pm_qos_req);
 883
 884        omap_mcbsp_cleanup(mcbsp);
 885
 886        clk_put(mcbsp->fclk);
 887
 888        return 0;
 889}
 890
 891static struct platform_driver asoc_mcbsp_driver = {
 892        .driver = {
 893                        .name = "omap-mcbsp",
 894                        .of_match_table = omap_mcbsp_of_match,
 895        },
 896
 897        .probe = asoc_mcbsp_probe,
 898        .remove = asoc_mcbsp_remove,
 899};
 900
 901module_platform_driver(asoc_mcbsp_driver);
 902
 903MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
 904MODULE_DESCRIPTION("OMAP I2S SoC Interface");
 905MODULE_LICENSE("GPL");
 906MODULE_ALIAS("platform:omap-mcbsp");
 907