linux/sound/soc/ux500/ux500_msp_dai.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) ST-Ericsson SA 2012
   3 *
   4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
   5 *         Roger Nilsson <roger.xr.nilsson@stericsson.com>
   6 *         for ST-Ericsson.
   7 *
   8 * License terms:
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as published
  12 * by the Free Software Foundation.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/slab.h>
  17#include <linux/bitops.h>
  18#include <linux/platform_device.h>
  19#include <linux/clk.h>
  20#include <linux/of.h>
  21#include <linux/regulator/consumer.h>
  22#include <linux/mfd/dbx500-prcmu.h>
  23#include <linux/platform_data/asoc-ux500-msp.h>
  24
  25#include <sound/soc.h>
  26#include <sound/soc-dai.h>
  27#include <sound/dmaengine_pcm.h>
  28
  29#include "ux500_msp_i2s.h"
  30#include "ux500_msp_dai.h"
  31#include "ux500_pcm.h"
  32
  33static int setup_pcm_multichan(struct snd_soc_dai *dai,
  34                        struct ux500_msp_config *msp_config)
  35{
  36        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
  37        struct msp_multichannel_config *multi =
  38                                        &msp_config->multichannel_config;
  39
  40        if (drvdata->slots > 1) {
  41                msp_config->multichannel_configured = 1;
  42
  43                multi->tx_multichannel_enable = true;
  44                multi->rx_multichannel_enable = true;
  45                multi->rx_comparison_enable_mode = MSP_COMPARISON_DISABLED;
  46
  47                multi->tx_channel_0_enable = drvdata->tx_mask;
  48                multi->tx_channel_1_enable = 0;
  49                multi->tx_channel_2_enable = 0;
  50                multi->tx_channel_3_enable = 0;
  51
  52                multi->rx_channel_0_enable = drvdata->rx_mask;
  53                multi->rx_channel_1_enable = 0;
  54                multi->rx_channel_2_enable = 0;
  55                multi->rx_channel_3_enable = 0;
  56
  57                dev_dbg(dai->dev,
  58                        "%s: Multichannel enabled. Slots: %d, TX: %u, RX: %u\n",
  59                        __func__, drvdata->slots, multi->tx_channel_0_enable,
  60                        multi->rx_channel_0_enable);
  61        }
  62
  63        return 0;
  64}
  65
  66static int setup_frameper(struct snd_soc_dai *dai, unsigned int rate,
  67                        struct msp_protdesc *prot_desc)
  68{
  69        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
  70
  71        switch (drvdata->slots) {
  72        case 1:
  73                switch (rate) {
  74                case 8000:
  75                        prot_desc->frame_period =
  76                                FRAME_PER_SINGLE_SLOT_8_KHZ;
  77                        break;
  78
  79                case 16000:
  80                        prot_desc->frame_period =
  81                                FRAME_PER_SINGLE_SLOT_16_KHZ;
  82                        break;
  83
  84                case 44100:
  85                        prot_desc->frame_period =
  86                                FRAME_PER_SINGLE_SLOT_44_1_KHZ;
  87                        break;
  88
  89                case 48000:
  90                        prot_desc->frame_period =
  91                                FRAME_PER_SINGLE_SLOT_48_KHZ;
  92                        break;
  93
  94                default:
  95                        dev_err(dai->dev,
  96                                "%s: Error: Unsupported sample-rate (freq = %d)!\n",
  97                                __func__, rate);
  98                        return -EINVAL;
  99                }
 100                break;
 101
 102        case 2:
 103                prot_desc->frame_period = FRAME_PER_2_SLOTS;
 104                break;
 105
 106        case 8:
 107                prot_desc->frame_period = FRAME_PER_8_SLOTS;
 108                break;
 109
 110        case 16:
 111                prot_desc->frame_period = FRAME_PER_16_SLOTS;
 112                break;
 113        default:
 114                dev_err(dai->dev,
 115                        "%s: Error: Unsupported slot-count (slots = %d)!\n",
 116                        __func__, drvdata->slots);
 117                return -EINVAL;
 118        }
 119
 120        prot_desc->clocks_per_frame =
 121                        prot_desc->frame_period+1;
 122
 123        dev_dbg(dai->dev, "%s: Clocks per frame: %u\n",
 124                __func__,
 125                prot_desc->clocks_per_frame);
 126
 127        return 0;
 128}
 129
 130static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
 131                        struct msp_protdesc *prot_desc)
 132{
 133        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 134
 135        u32 frame_length = MSP_FRAME_LEN_1;
 136        prot_desc->frame_width = 0;
 137
 138        switch (drvdata->slots) {
 139        case 1:
 140                frame_length = MSP_FRAME_LEN_1;
 141                break;
 142
 143        case 2:
 144                frame_length = MSP_FRAME_LEN_2;
 145                break;
 146
 147        case 8:
 148                frame_length = MSP_FRAME_LEN_8;
 149                break;
 150
 151        case 16:
 152                frame_length = MSP_FRAME_LEN_16;
 153                break;
 154        default:
 155                dev_err(dai->dev,
 156                        "%s: Error: Unsupported slot-count (slots = %d)!\n",
 157                        __func__, drvdata->slots);
 158                return -EINVAL;
 159        }
 160
 161        prot_desc->tx_frame_len_1 = frame_length;
 162        prot_desc->rx_frame_len_1 = frame_length;
 163        prot_desc->tx_frame_len_2 = frame_length;
 164        prot_desc->rx_frame_len_2 = frame_length;
 165
 166        prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16;
 167        prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16;
 168        prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16;
 169        prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16;
 170
 171        return setup_frameper(dai, rate, prot_desc);
 172}
 173
 174static int setup_clocking(struct snd_soc_dai *dai,
 175                        unsigned int fmt,
 176                        struct ux500_msp_config *msp_config)
 177{
 178        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 179        case SND_SOC_DAIFMT_NB_NF:
 180                break;
 181
 182        case SND_SOC_DAIFMT_NB_IF:
 183                msp_config->tx_fsync_pol ^= 1 << TFSPOL_SHIFT;
 184                msp_config->rx_fsync_pol ^= 1 << RFSPOL_SHIFT;
 185
 186                break;
 187
 188        default:
 189                dev_err(dai->dev,
 190                        "%s: Error: Unsopported inversion (fmt = 0x%x)!\n",
 191                        __func__, fmt);
 192
 193                return -EINVAL;
 194        }
 195
 196        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 197        case SND_SOC_DAIFMT_CBM_CFM:
 198                dev_dbg(dai->dev, "%s: Codec is master.\n", __func__);
 199
 200                msp_config->iodelay = 0x20;
 201                msp_config->rx_fsync_sel = 0;
 202                msp_config->tx_fsync_sel = 1 << TFSSEL_SHIFT;
 203                msp_config->tx_clk_sel = 0;
 204                msp_config->rx_clk_sel = 0;
 205                msp_config->srg_clk_sel = 0x2 << SCKSEL_SHIFT;
 206
 207                break;
 208
 209        case SND_SOC_DAIFMT_CBS_CFS:
 210                dev_dbg(dai->dev, "%s: Codec is slave.\n", __func__);
 211
 212                msp_config->tx_clk_sel = TX_CLK_SEL_SRG;
 213                msp_config->tx_fsync_sel = TX_SYNC_SRG_PROG;
 214                msp_config->rx_clk_sel = RX_CLK_SEL_SRG;
 215                msp_config->rx_fsync_sel = RX_SYNC_SRG;
 216                msp_config->srg_clk_sel = 1 << SCKSEL_SHIFT;
 217
 218                break;
 219
 220        default:
 221                dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n",
 222                        __func__, fmt);
 223
 224                return -EINVAL;
 225        }
 226
 227        return 0;
 228}
 229
 230static int setup_pcm_protdesc(struct snd_soc_dai *dai,
 231                                unsigned int fmt,
 232                                struct msp_protdesc *prot_desc)
 233{
 234        prot_desc->rx_phase_mode = MSP_SINGLE_PHASE;
 235        prot_desc->tx_phase_mode = MSP_SINGLE_PHASE;
 236        prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
 237        prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
 238        prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST;
 239        prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST;
 240        prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_HI);
 241        prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_HI << RFSPOL_SHIFT;
 242
 243        if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) {
 244                dev_dbg(dai->dev, "%s: DSP_A.\n", __func__);
 245                prot_desc->rx_clk_pol = MSP_RISING_EDGE;
 246                prot_desc->tx_clk_pol = MSP_FALLING_EDGE;
 247
 248                prot_desc->rx_data_delay = MSP_DELAY_1;
 249                prot_desc->tx_data_delay = MSP_DELAY_1;
 250        } else {
 251                dev_dbg(dai->dev, "%s: DSP_B.\n", __func__);
 252                prot_desc->rx_clk_pol = MSP_FALLING_EDGE;
 253                prot_desc->tx_clk_pol = MSP_RISING_EDGE;
 254
 255                prot_desc->rx_data_delay = MSP_DELAY_0;
 256                prot_desc->tx_data_delay = MSP_DELAY_0;
 257        }
 258
 259        prot_desc->rx_half_word_swap = MSP_SWAP_NONE;
 260        prot_desc->tx_half_word_swap = MSP_SWAP_NONE;
 261        prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
 262        prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
 263        prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE;
 264
 265        return 0;
 266}
 267
 268static int setup_i2s_protdesc(struct msp_protdesc *prot_desc)
 269{
 270        prot_desc->rx_phase_mode = MSP_DUAL_PHASE;
 271        prot_desc->tx_phase_mode = MSP_DUAL_PHASE;
 272        prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC;
 273        prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC;
 274        prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST;
 275        prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST;
 276        prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_LO);
 277        prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_LO << RFSPOL_SHIFT;
 278
 279        prot_desc->rx_frame_len_1 = MSP_FRAME_LEN_1;
 280        prot_desc->rx_frame_len_2 = MSP_FRAME_LEN_1;
 281        prot_desc->tx_frame_len_1 = MSP_FRAME_LEN_1;
 282        prot_desc->tx_frame_len_2 = MSP_FRAME_LEN_1;
 283        prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16;
 284        prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16;
 285        prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16;
 286        prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16;
 287
 288        prot_desc->rx_clk_pol = MSP_RISING_EDGE;
 289        prot_desc->tx_clk_pol = MSP_FALLING_EDGE;
 290
 291        prot_desc->rx_data_delay = MSP_DELAY_0;
 292        prot_desc->tx_data_delay = MSP_DELAY_0;
 293
 294        prot_desc->tx_half_word_swap = MSP_SWAP_NONE;
 295        prot_desc->rx_half_word_swap = MSP_SWAP_NONE;
 296        prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
 297        prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
 298        prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE;
 299
 300        return 0;
 301}
 302
 303static int setup_msp_config(struct snd_pcm_substream *substream,
 304                        struct snd_soc_dai *dai,
 305                        struct ux500_msp_config *msp_config)
 306{
 307        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 308        struct msp_protdesc *prot_desc = &msp_config->protdesc;
 309        struct snd_pcm_runtime *runtime = substream->runtime;
 310        unsigned int fmt = drvdata->fmt;
 311        int ret;
 312
 313        memset(msp_config, 0, sizeof(*msp_config));
 314
 315        msp_config->f_inputclk = drvdata->master_clk;
 316
 317        msp_config->tx_fifo_config = TX_FIFO_ENABLE;
 318        msp_config->rx_fifo_config = RX_FIFO_ENABLE;
 319        msp_config->def_elem_len = 1;
 320        msp_config->direction = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 321                                MSP_DIR_TX : MSP_DIR_RX;
 322        msp_config->data_size = MSP_DATA_BITS_32;
 323        msp_config->frame_freq = runtime->rate;
 324
 325        dev_dbg(dai->dev, "%s: f_inputclk = %u, frame_freq = %u.\n",
 326               __func__, msp_config->f_inputclk, msp_config->frame_freq);
 327        /* To avoid division by zero */
 328        prot_desc->clocks_per_frame = 1;
 329
 330        dev_dbg(dai->dev, "%s: rate: %u, channels: %d.\n", __func__,
 331                runtime->rate, runtime->channels);
 332        switch (fmt &
 333                (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
 334        case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
 335                dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__);
 336
 337                msp_config->default_protdesc = 1;
 338                msp_config->protocol = MSP_I2S_PROTOCOL;
 339                break;
 340
 341        case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
 342                dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__);
 343
 344                msp_config->data_size = MSP_DATA_BITS_16;
 345                msp_config->protocol = MSP_I2S_PROTOCOL;
 346
 347                ret = setup_i2s_protdesc(prot_desc);
 348                if (ret < 0)
 349                        return ret;
 350
 351                break;
 352
 353        case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
 354        case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
 355        case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
 356        case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
 357                dev_dbg(dai->dev, "%s: PCM format.\n", __func__);
 358
 359                msp_config->data_size = MSP_DATA_BITS_16;
 360                msp_config->protocol = MSP_PCM_PROTOCOL;
 361
 362                ret = setup_pcm_protdesc(dai, fmt, prot_desc);
 363                if (ret < 0)
 364                        return ret;
 365
 366                ret = setup_pcm_multichan(dai, msp_config);
 367                if (ret < 0)
 368                        return ret;
 369
 370                ret = setup_pcm_framing(dai, runtime->rate, prot_desc);
 371                if (ret < 0)
 372                        return ret;
 373
 374                break;
 375
 376        default:
 377                dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n",
 378                        __func__, fmt);
 379                return -EINVAL;
 380        }
 381
 382        return setup_clocking(dai, fmt, msp_config);
 383}
 384
 385static int ux500_msp_dai_startup(struct snd_pcm_substream *substream,
 386                                struct snd_soc_dai *dai)
 387{
 388        int ret = 0;
 389        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 390
 391        dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
 392                snd_pcm_stream_str(substream));
 393
 394        /* Enable regulator */
 395        ret = regulator_enable(drvdata->reg_vape);
 396        if (ret != 0) {
 397                dev_err(drvdata->msp->dev,
 398                        "%s: Failed to enable regulator!\n", __func__);
 399                return ret;
 400        }
 401
 402        /* Prepare and enable clocks */
 403        dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__);
 404        ret = clk_prepare_enable(drvdata->pclk);
 405        if (ret) {
 406                dev_err(drvdata->msp->dev,
 407                        "%s: Failed to prepare/enable pclk!\n", __func__);
 408                goto err_pclk;
 409        }
 410
 411        ret = clk_prepare_enable(drvdata->clk);
 412        if (ret) {
 413                dev_err(drvdata->msp->dev,
 414                        "%s: Failed to prepare/enable clk!\n", __func__);
 415                goto err_clk;
 416        }
 417
 418        return ret;
 419err_clk:
 420        clk_disable_unprepare(drvdata->pclk);
 421err_pclk:
 422        regulator_disable(drvdata->reg_vape);
 423        return ret;
 424}
 425
 426static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
 427                                struct snd_soc_dai *dai)
 428{
 429        int ret;
 430        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 431        bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 432
 433        dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
 434                snd_pcm_stream_str(substream));
 435
 436        if (drvdata->vape_opp_constraint == 1) {
 437                prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
 438                                        "ux500_msp_i2s", 50);
 439                drvdata->vape_opp_constraint = 0;
 440        }
 441
 442        if (ux500_msp_i2s_close(drvdata->msp,
 443                                is_playback ? MSP_DIR_TX : MSP_DIR_RX)) {
 444                dev_err(dai->dev,
 445                        "%s: Error: MSP %d (%s): Unable to close i2s.\n",
 446                        __func__, dai->id, snd_pcm_stream_str(substream));
 447        }
 448
 449        /* Disable and unprepare clocks */
 450        clk_disable_unprepare(drvdata->clk);
 451        clk_disable_unprepare(drvdata->pclk);
 452
 453        /* Disable regulator */
 454        ret = regulator_disable(drvdata->reg_vape);
 455        if (ret < 0)
 456                dev_err(dai->dev,
 457                        "%s: ERROR: Failed to disable regulator (%d)!\n",
 458                        __func__, ret);
 459}
 460
 461static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
 462                                struct snd_soc_dai *dai)
 463{
 464        int ret = 0;
 465        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 466        struct snd_pcm_runtime *runtime = substream->runtime;
 467        struct ux500_msp_config msp_config;
 468
 469        dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (rate = %d).\n", __func__,
 470                dai->id, snd_pcm_stream_str(substream), runtime->rate);
 471
 472        setup_msp_config(substream, dai, &msp_config);
 473
 474        ret = ux500_msp_i2s_open(drvdata->msp, &msp_config);
 475        if (ret < 0) {
 476                dev_err(dai->dev, "%s: Error: msp_setup failed (ret = %d)!\n",
 477                        __func__, ret);
 478                return ret;
 479        }
 480
 481        /* Set OPP-level */
 482        if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) &&
 483                (drvdata->msp->f_bitclk > 19200000)) {
 484                /* If the bit-clock is higher than 19.2MHz, Vape should be
 485                 * run in 100% OPP. Only when bit-clock is used (MSP master) */
 486                prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
 487                                        "ux500-msp-i2s", 100);
 488                drvdata->vape_opp_constraint = 1;
 489        } else {
 490                prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
 491                                        "ux500-msp-i2s", 50);
 492                drvdata->vape_opp_constraint = 0;
 493        }
 494
 495        return ret;
 496}
 497
 498static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
 499                                struct snd_pcm_hw_params *params,
 500                                struct snd_soc_dai *dai)
 501{
 502        unsigned int mask, slots_active;
 503        struct snd_pcm_runtime *runtime = substream->runtime;
 504        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 505
 506        dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n",
 507                        __func__, dai->id, snd_pcm_stream_str(substream));
 508
 509        switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 510        case SND_SOC_DAIFMT_I2S:
 511                snd_pcm_hw_constraint_minmax(runtime,
 512                                SNDRV_PCM_HW_PARAM_CHANNELS,
 513                                1, 2);
 514                break;
 515
 516        case SND_SOC_DAIFMT_DSP_B:
 517        case SND_SOC_DAIFMT_DSP_A:
 518                mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 519                        drvdata->tx_mask :
 520                        drvdata->rx_mask;
 521
 522                slots_active = hweight32(mask);
 523                dev_dbg(dai->dev, "TDM-slots active: %d", slots_active);
 524
 525                snd_pcm_hw_constraint_minmax(runtime,
 526                                SNDRV_PCM_HW_PARAM_CHANNELS,
 527                                slots_active, slots_active);
 528                break;
 529
 530        default:
 531                dev_err(dai->dev,
 532                        "%s: Error: Unsupported protocol (fmt = 0x%x)!\n",
 533                        __func__, drvdata->fmt);
 534                return -EINVAL;
 535        }
 536
 537        return 0;
 538}
 539
 540static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai,
 541                                unsigned int fmt)
 542{
 543        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 544
 545        dev_dbg(dai->dev, "%s: MSP %d: Enter.\n", __func__, dai->id);
 546
 547        switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
 548                SND_SOC_DAIFMT_MASTER_MASK)) {
 549        case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
 550        case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
 551        case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
 552        case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
 553        case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
 554        case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
 555                break;
 556
 557        default:
 558                dev_err(dai->dev,
 559                        "%s: Error: Unsupported protocol/master (fmt = 0x%x)!\n",
 560                        __func__, drvdata->fmt);
 561                return -EINVAL;
 562        }
 563
 564        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 565        case SND_SOC_DAIFMT_NB_NF:
 566        case SND_SOC_DAIFMT_NB_IF:
 567        case SND_SOC_DAIFMT_IB_IF:
 568                break;
 569
 570        default:
 571                dev_err(dai->dev,
 572                        "%s: Error: Unsupported inversion (fmt = 0x%x)!\n",
 573                        __func__, drvdata->fmt);
 574                return -EINVAL;
 575        }
 576
 577        drvdata->fmt = fmt;
 578        return 0;
 579}
 580
 581static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai,
 582                                unsigned int tx_mask,
 583                                unsigned int rx_mask,
 584                                int slots, int slot_width)
 585{
 586        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 587        unsigned int cap;
 588
 589        switch (slots) {
 590        case 1:
 591                cap = 0x01;
 592                break;
 593        case 2:
 594                cap = 0x03;
 595                break;
 596        case 8:
 597                cap = 0xFF;
 598                break;
 599        case 16:
 600                cap = 0xFFFF;
 601                break;
 602        default:
 603                dev_err(dai->dev, "%s: Error: Unsupported slot-count (%d)!\n",
 604                        __func__, slots);
 605                return -EINVAL;
 606        }
 607        drvdata->slots = slots;
 608
 609        if (!(slot_width == 16)) {
 610                dev_err(dai->dev, "%s: Error: Unsupported slot-width (%d)!\n",
 611                        __func__, slot_width);
 612                return -EINVAL;
 613        }
 614        drvdata->slot_width = slot_width;
 615
 616        drvdata->tx_mask = tx_mask & cap;
 617        drvdata->rx_mask = rx_mask & cap;
 618
 619        return 0;
 620}
 621
 622static int ux500_msp_dai_set_dai_sysclk(struct snd_soc_dai *dai,
 623                                        int clk_id, unsigned int freq, int dir)
 624{
 625        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 626
 627        dev_dbg(dai->dev, "%s: MSP %d: Enter. clk-id: %d, freq: %u.\n",
 628                __func__, dai->id, clk_id, freq);
 629
 630        switch (clk_id) {
 631        case UX500_MSP_MASTER_CLOCK:
 632                drvdata->master_clk = freq;
 633                break;
 634
 635        default:
 636                dev_err(dai->dev, "%s: MSP %d: Invalid clk-id (%d)!\n",
 637                        __func__, dai->id, clk_id);
 638                return -EINVAL;
 639        }
 640
 641        return 0;
 642}
 643
 644static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
 645                                int cmd, struct snd_soc_dai *dai)
 646{
 647        int ret = 0;
 648        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 649
 650        dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (msp->id = %d, cmd = %d).\n",
 651                __func__, dai->id, snd_pcm_stream_str(substream),
 652                (int)drvdata->msp->id, cmd);
 653
 654        ret = ux500_msp_i2s_trigger(drvdata->msp, cmd, substream->stream);
 655
 656        return ret;
 657}
 658
 659static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai)
 660{
 661        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 662        struct snd_dmaengine_dai_dma_data *playback_dma_data;
 663        struct snd_dmaengine_dai_dma_data *capture_dma_data;
 664
 665        playback_dma_data = devm_kzalloc(dai->dev,
 666                                         sizeof(*playback_dma_data),
 667                                         GFP_KERNEL);
 668        if (!playback_dma_data)
 669                return -ENOMEM;
 670
 671        capture_dma_data = devm_kzalloc(dai->dev,
 672                                        sizeof(*capture_dma_data),
 673                                        GFP_KERNEL);
 674        if (!capture_dma_data)
 675                return -ENOMEM;
 676
 677        playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr;
 678        capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr;
 679
 680        playback_dma_data->maxburst = 4;
 681        capture_dma_data->maxburst = 4;
 682
 683        snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data);
 684
 685        return 0;
 686}
 687
 688static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
 689{
 690        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 691        struct msp_i2s_platform_data *pdata = dai->dev->platform_data;
 692        int ret;
 693
 694        if (!pdata) {
 695                ret = ux500_msp_dai_of_probe(dai);
 696                return ret;
 697        }
 698
 699        drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
 700        drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
 701
 702        snd_soc_dai_init_dma_data(dai,
 703                                  &drvdata->msp->playback_dma_data,
 704                                  &drvdata->msp->capture_dma_data);
 705        return 0;
 706}
 707
 708static struct snd_soc_dai_ops ux500_msp_dai_ops[] = {
 709        {
 710                .set_sysclk = ux500_msp_dai_set_dai_sysclk,
 711                .set_fmt = ux500_msp_dai_set_dai_fmt,
 712                .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
 713                .startup = ux500_msp_dai_startup,
 714                .shutdown = ux500_msp_dai_shutdown,
 715                .prepare = ux500_msp_dai_prepare,
 716                .trigger = ux500_msp_dai_trigger,
 717                .hw_params = ux500_msp_dai_hw_params,
 718        }
 719};
 720
 721static struct snd_soc_dai_driver ux500_msp_dai_drv = {
 722        .probe                 = ux500_msp_dai_probe,
 723        .suspend               = NULL,
 724        .resume                = NULL,
 725        .playback.channels_min = UX500_MSP_MIN_CHANNELS,
 726        .playback.channels_max = UX500_MSP_MAX_CHANNELS,
 727        .playback.rates        = UX500_I2S_RATES,
 728        .playback.formats      = UX500_I2S_FORMATS,
 729        .capture.channels_min  = UX500_MSP_MIN_CHANNELS,
 730        .capture.channels_max  = UX500_MSP_MAX_CHANNELS,
 731        .capture.rates         = UX500_I2S_RATES,
 732        .capture.formats       = UX500_I2S_FORMATS,
 733        .ops                   = ux500_msp_dai_ops,
 734};
 735
 736static const struct snd_soc_component_driver ux500_msp_component = {
 737        .name           = "ux500-msp",
 738};
 739
 740
 741static int ux500_msp_drv_probe(struct platform_device *pdev)
 742{
 743        struct ux500_msp_i2s_drvdata *drvdata;
 744        struct msp_i2s_platform_data *pdata = pdev->dev.platform_data;
 745        struct device_node *np = pdev->dev.of_node;
 746        int ret = 0;
 747
 748        if (!pdata && !np) {
 749                dev_err(&pdev->dev, "No platform data or Device Tree found\n");
 750                return -ENODEV;
 751        }
 752
 753        drvdata = devm_kzalloc(&pdev->dev,
 754                                sizeof(struct ux500_msp_i2s_drvdata),
 755                                GFP_KERNEL);
 756        if (!drvdata)
 757                return -ENOMEM;
 758
 759        drvdata->fmt = 0;
 760        drvdata->slots = 1;
 761        drvdata->tx_mask = 0x01;
 762        drvdata->rx_mask = 0x01;
 763        drvdata->slot_width = 16;
 764        drvdata->master_clk = MSP_INPUT_FREQ_APB;
 765
 766        drvdata->reg_vape = devm_regulator_get(&pdev->dev, "v-ape");
 767        if (IS_ERR(drvdata->reg_vape)) {
 768                ret = (int)PTR_ERR(drvdata->reg_vape);
 769                dev_err(&pdev->dev,
 770                        "%s: ERROR: Failed to get Vape supply (%d)!\n",
 771                        __func__, ret);
 772                return ret;
 773        }
 774        prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);
 775
 776        drvdata->pclk = clk_get(&pdev->dev, "apb_pclk");
 777        if (IS_ERR(drvdata->pclk)) {
 778                ret = (int)PTR_ERR(drvdata->pclk);
 779                dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n",
 780                        __func__, ret);
 781                goto err_pclk;
 782        }
 783
 784        drvdata->clk = clk_get(&pdev->dev, NULL);
 785        if (IS_ERR(drvdata->clk)) {
 786                ret = (int)PTR_ERR(drvdata->clk);
 787                dev_err(&pdev->dev, "%s: ERROR: clk_get failed (%d)!\n",
 788                        __func__, ret);
 789                goto err_clk;
 790        }
 791
 792        ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp,
 793                                pdev->dev.platform_data);
 794        if (!drvdata->msp) {
 795                dev_err(&pdev->dev,
 796                        "%s: ERROR: Failed to init MSP-struct (%d)!",
 797                        __func__, ret);
 798                goto err_init_msp;
 799        }
 800        dev_set_drvdata(&pdev->dev, drvdata);
 801
 802        ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component,
 803                                         &ux500_msp_dai_drv, 1);
 804        if (ret < 0) {
 805                dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
 806                        __func__, drvdata->msp->id);
 807                goto err_init_msp;
 808        }
 809
 810        ret = ux500_pcm_register_platform(pdev);
 811        if (ret < 0) {
 812                dev_err(&pdev->dev,
 813                        "Error: %s: Failed to register PCM platform device!\n",
 814                        __func__);
 815                goto err_reg_plat;
 816        }
 817
 818        return 0;
 819
 820err_reg_plat:
 821        snd_soc_unregister_component(&pdev->dev);
 822err_init_msp:
 823        clk_put(drvdata->clk);
 824err_clk:
 825        clk_put(drvdata->pclk);
 826err_pclk:
 827        devm_regulator_put(drvdata->reg_vape);
 828
 829        return ret;
 830}
 831
 832static int ux500_msp_drv_remove(struct platform_device *pdev)
 833{
 834        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
 835
 836        ux500_pcm_unregister_platform(pdev);
 837
 838        snd_soc_unregister_component(&pdev->dev);
 839
 840        devm_regulator_put(drvdata->reg_vape);
 841        prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
 842
 843        clk_put(drvdata->clk);
 844        clk_put(drvdata->pclk);
 845
 846        ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
 847
 848        return 0;
 849}
 850
 851static const struct of_device_id ux500_msp_i2s_match[] = {
 852        { .compatible = "stericsson,ux500-msp-i2s", },
 853        {},
 854};
 855
 856static struct platform_driver msp_i2s_driver = {
 857        .driver = {
 858                .name = "ux500-msp-i2s",
 859                .of_match_table = ux500_msp_i2s_match,
 860        },
 861        .probe = ux500_msp_drv_probe,
 862        .remove = ux500_msp_drv_remove,
 863};
 864module_platform_driver(msp_i2s_driver);
 865
 866MODULE_LICENSE("GPL v2");
 867