linux/sound/soc/ux500/ux500_msp_i2s.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 *         Sandeep Kaushik <sandeep.kaushik@st.com>
   7 *         for ST-Ericsson.
   8 *
   9 * License terms:
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as published
  13 * by the Free Software Foundation.
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/platform_device.h>
  18#include <linux/delay.h>
  19#include <linux/slab.h>
  20#include <linux/io.h>
  21#include <linux/of.h>
  22#include <linux/platform_data/asoc-ux500-msp.h>
  23
  24#include <sound/soc.h>
  25
  26#include "ux500_msp_i2s.h"
  27
  28 /* Protocol desciptors */
  29static const struct msp_protdesc prot_descs[] = {
  30        { /* I2S */
  31                MSP_SINGLE_PHASE,
  32                MSP_SINGLE_PHASE,
  33                MSP_PHASE2_START_MODE_IMEDIATE,
  34                MSP_PHASE2_START_MODE_IMEDIATE,
  35                MSP_BTF_MS_BIT_FIRST,
  36                MSP_BTF_MS_BIT_FIRST,
  37                MSP_FRAME_LEN_1,
  38                MSP_FRAME_LEN_1,
  39                MSP_FRAME_LEN_1,
  40                MSP_FRAME_LEN_1,
  41                MSP_ELEM_LEN_32,
  42                MSP_ELEM_LEN_32,
  43                MSP_ELEM_LEN_32,
  44                MSP_ELEM_LEN_32,
  45                MSP_DELAY_1,
  46                MSP_DELAY_1,
  47                MSP_RISING_EDGE,
  48                MSP_FALLING_EDGE,
  49                MSP_FSYNC_POL_ACT_LO,
  50                MSP_FSYNC_POL_ACT_LO,
  51                MSP_SWAP_NONE,
  52                MSP_SWAP_NONE,
  53                MSP_COMPRESS_MODE_LINEAR,
  54                MSP_EXPAND_MODE_LINEAR,
  55                MSP_FSYNC_IGNORE,
  56                31,
  57                15,
  58                32,
  59        }, { /* PCM */
  60                MSP_DUAL_PHASE,
  61                MSP_DUAL_PHASE,
  62                MSP_PHASE2_START_MODE_FSYNC,
  63                MSP_PHASE2_START_MODE_FSYNC,
  64                MSP_BTF_MS_BIT_FIRST,
  65                MSP_BTF_MS_BIT_FIRST,
  66                MSP_FRAME_LEN_1,
  67                MSP_FRAME_LEN_1,
  68                MSP_FRAME_LEN_1,
  69                MSP_FRAME_LEN_1,
  70                MSP_ELEM_LEN_16,
  71                MSP_ELEM_LEN_16,
  72                MSP_ELEM_LEN_16,
  73                MSP_ELEM_LEN_16,
  74                MSP_DELAY_0,
  75                MSP_DELAY_0,
  76                MSP_RISING_EDGE,
  77                MSP_FALLING_EDGE,
  78                MSP_FSYNC_POL_ACT_HI,
  79                MSP_FSYNC_POL_ACT_HI,
  80                MSP_SWAP_NONE,
  81                MSP_SWAP_NONE,
  82                MSP_COMPRESS_MODE_LINEAR,
  83                MSP_EXPAND_MODE_LINEAR,
  84                MSP_FSYNC_IGNORE,
  85                255,
  86                0,
  87                256,
  88        }, { /* Companded PCM */
  89                MSP_SINGLE_PHASE,
  90                MSP_SINGLE_PHASE,
  91                MSP_PHASE2_START_MODE_FSYNC,
  92                MSP_PHASE2_START_MODE_FSYNC,
  93                MSP_BTF_MS_BIT_FIRST,
  94                MSP_BTF_MS_BIT_FIRST,
  95                MSP_FRAME_LEN_1,
  96                MSP_FRAME_LEN_1,
  97                MSP_FRAME_LEN_1,
  98                MSP_FRAME_LEN_1,
  99                MSP_ELEM_LEN_8,
 100                MSP_ELEM_LEN_8,
 101                MSP_ELEM_LEN_8,
 102                MSP_ELEM_LEN_8,
 103                MSP_DELAY_0,
 104                MSP_DELAY_0,
 105                MSP_RISING_EDGE,
 106                MSP_RISING_EDGE,
 107                MSP_FSYNC_POL_ACT_HI,
 108                MSP_FSYNC_POL_ACT_HI,
 109                MSP_SWAP_NONE,
 110                MSP_SWAP_NONE,
 111                MSP_COMPRESS_MODE_LINEAR,
 112                MSP_EXPAND_MODE_LINEAR,
 113                MSP_FSYNC_IGNORE,
 114                255,
 115                0,
 116                256,
 117        },
 118};
 119
 120static void set_prot_desc_tx(struct ux500_msp *msp,
 121                        struct msp_protdesc *protdesc,
 122                        enum msp_data_size data_size)
 123{
 124        u32 temp_reg = 0;
 125
 126        temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode);
 127        temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode);
 128        temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1);
 129        temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2);
 130        if (msp->def_elem_len) {
 131                temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1);
 132                temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2);
 133        } else {
 134                temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
 135                temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
 136        }
 137        temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay);
 138        temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order);
 139        temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol);
 140        temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap);
 141        temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode);
 142        temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
 143
 144        writel(temp_reg, msp->registers + MSP_TCF);
 145}
 146
 147static void set_prot_desc_rx(struct ux500_msp *msp,
 148                        struct msp_protdesc *protdesc,
 149                        enum msp_data_size data_size)
 150{
 151        u32 temp_reg = 0;
 152
 153        temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode);
 154        temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode);
 155        temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1);
 156        temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2);
 157        if (msp->def_elem_len) {
 158                temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1);
 159                temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2);
 160        } else {
 161                temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
 162                temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
 163        }
 164
 165        temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay);
 166        temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order);
 167        temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol);
 168        temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap);
 169        temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode);
 170        temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
 171
 172        writel(temp_reg, msp->registers + MSP_RCF);
 173}
 174
 175static int configure_protocol(struct ux500_msp *msp,
 176                        struct ux500_msp_config *config)
 177{
 178        struct msp_protdesc *protdesc;
 179        enum msp_data_size data_size;
 180        u32 temp_reg = 0;
 181
 182        data_size = config->data_size;
 183        msp->def_elem_len = config->def_elem_len;
 184        if (config->default_protdesc == 1) {
 185                if (config->protocol >= MSP_INVALID_PROTOCOL) {
 186                        dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
 187                                __func__);
 188                        return -EINVAL;
 189                }
 190                protdesc =
 191                    (struct msp_protdesc *)&prot_descs[config->protocol];
 192        } else {
 193                protdesc = (struct msp_protdesc *)&config->protdesc;
 194        }
 195
 196        if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
 197                dev_err(msp->dev,
 198                        "%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
 199                        __func__, data_size);
 200                return -EINVAL;
 201        }
 202
 203        if (config->direction & MSP_DIR_TX)
 204                set_prot_desc_tx(msp, protdesc, data_size);
 205        if (config->direction & MSP_DIR_RX)
 206                set_prot_desc_rx(msp, protdesc, data_size);
 207
 208        /* The code below should not be separated. */
 209        temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
 210        temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
 211        writel(temp_reg, msp->registers + MSP_GCR);
 212        temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
 213        temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
 214        writel(temp_reg, msp->registers + MSP_GCR);
 215
 216        return 0;
 217}
 218
 219static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
 220{
 221        u32 reg_val_GCR;
 222        u32 frame_per = 0;
 223        u32 sck_div = 0;
 224        u32 frame_width = 0;
 225        u32 temp_reg = 0;
 226        struct msp_protdesc *protdesc = NULL;
 227
 228        reg_val_GCR = readl(msp->registers + MSP_GCR);
 229        writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
 230
 231        if (config->default_protdesc)
 232                protdesc =
 233                        (struct msp_protdesc *)&prot_descs[config->protocol];
 234        else
 235                protdesc = (struct msp_protdesc *)&config->protdesc;
 236
 237        switch (config->protocol) {
 238        case MSP_PCM_PROTOCOL:
 239        case MSP_PCM_COMPAND_PROTOCOL:
 240                frame_width = protdesc->frame_width;
 241                sck_div = config->f_inputclk / (config->frame_freq *
 242                        (protdesc->clocks_per_frame));
 243                frame_per = protdesc->frame_period;
 244                break;
 245        case MSP_I2S_PROTOCOL:
 246                frame_width = protdesc->frame_width;
 247                sck_div = config->f_inputclk / (config->frame_freq *
 248                        (protdesc->clocks_per_frame));
 249                frame_per = protdesc->frame_period;
 250                break;
 251        default:
 252                dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
 253                        __func__,
 254                        config->protocol);
 255                return -EINVAL;
 256        }
 257
 258        temp_reg = (sck_div - 1) & SCK_DIV_MASK;
 259        temp_reg |= FRAME_WIDTH_BITS(frame_width);
 260        temp_reg |= FRAME_PERIOD_BITS(frame_per);
 261        writel(temp_reg, msp->registers + MSP_SRG);
 262
 263        msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
 264
 265        /* Enable bit-clock */
 266        udelay(100);
 267        reg_val_GCR = readl(msp->registers + MSP_GCR);
 268        writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
 269        udelay(100);
 270
 271        return 0;
 272}
 273
 274static int configure_multichannel(struct ux500_msp *msp,
 275                                struct ux500_msp_config *config)
 276{
 277        struct msp_protdesc *protdesc;
 278        struct msp_multichannel_config *mcfg;
 279        u32 reg_val_MCR;
 280
 281        if (config->default_protdesc == 1) {
 282                if (config->protocol >= MSP_INVALID_PROTOCOL) {
 283                        dev_err(msp->dev,
 284                                "%s: ERROR: Invalid protocol (%d)!\n",
 285                                __func__, config->protocol);
 286                        return -EINVAL;
 287                }
 288                protdesc = (struct msp_protdesc *)
 289                                &prot_descs[config->protocol];
 290        } else {
 291                protdesc = (struct msp_protdesc *)&config->protdesc;
 292        }
 293
 294        mcfg = &config->multichannel_config;
 295        if (mcfg->tx_multichannel_enable) {
 296                if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) {
 297                        reg_val_MCR = readl(msp->registers + MSP_MCR);
 298                        writel(reg_val_MCR | (mcfg->tx_multichannel_enable ?
 299                                                1 << TMCEN_BIT : 0),
 300                                msp->registers + MSP_MCR);
 301                        writel(mcfg->tx_channel_0_enable,
 302                                msp->registers + MSP_TCE0);
 303                        writel(mcfg->tx_channel_1_enable,
 304                                msp->registers + MSP_TCE1);
 305                        writel(mcfg->tx_channel_2_enable,
 306                                msp->registers + MSP_TCE2);
 307                        writel(mcfg->tx_channel_3_enable,
 308                                msp->registers + MSP_TCE3);
 309                } else {
 310                        dev_err(msp->dev,
 311                                "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n",
 312                                __func__, protdesc->tx_phase_mode);
 313                        return -EINVAL;
 314                }
 315        }
 316        if (mcfg->rx_multichannel_enable) {
 317                if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) {
 318                        reg_val_MCR = readl(msp->registers + MSP_MCR);
 319                        writel(reg_val_MCR | (mcfg->rx_multichannel_enable ?
 320                                                1 << RMCEN_BIT : 0),
 321                                msp->registers + MSP_MCR);
 322                        writel(mcfg->rx_channel_0_enable,
 323                                        msp->registers + MSP_RCE0);
 324                        writel(mcfg->rx_channel_1_enable,
 325                                        msp->registers + MSP_RCE1);
 326                        writel(mcfg->rx_channel_2_enable,
 327                                        msp->registers + MSP_RCE2);
 328                        writel(mcfg->rx_channel_3_enable,
 329                                        msp->registers + MSP_RCE3);
 330                } else {
 331                        dev_err(msp->dev,
 332                                "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n",
 333                                __func__, protdesc->rx_phase_mode);
 334                        return -EINVAL;
 335                }
 336                if (mcfg->rx_comparison_enable_mode) {
 337                        reg_val_MCR = readl(msp->registers + MSP_MCR);
 338                        writel(reg_val_MCR |
 339                                (mcfg->rx_comparison_enable_mode << RCMPM_BIT),
 340                                msp->registers + MSP_MCR);
 341
 342                        writel(mcfg->comparison_mask,
 343                                        msp->registers + MSP_RCM);
 344                        writel(mcfg->comparison_value,
 345                                        msp->registers + MSP_RCV);
 346
 347                }
 348        }
 349
 350        return 0;
 351}
 352
 353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
 354{
 355        int status = 0;
 356        u32 reg_val_DMACR, reg_val_GCR;
 357
 358        /* Configure msp with protocol dependent settings */
 359        configure_protocol(msp, config);
 360        setup_bitclk(msp, config);
 361        if (config->multichannel_configured == 1) {
 362                status = configure_multichannel(msp, config);
 363                if (status)
 364                        dev_warn(msp->dev,
 365                                "%s: WARN: configure_multichannel failed (%d)!\n",
 366                                __func__, status);
 367        }
 368
 369        /* Make sure the correct DMA-directions are configured */
 370        if ((config->direction & MSP_DIR_RX) &&
 371                        !msp->capture_dma_data.dma_cfg) {
 372                dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
 373                        __func__);
 374                return -EINVAL;
 375        }
 376        if ((config->direction == MSP_DIR_TX) &&
 377                        !msp->playback_dma_data.dma_cfg) {
 378                dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
 379                        __func__);
 380                return -EINVAL;
 381        }
 382
 383        reg_val_DMACR = readl(msp->registers + MSP_DMACR);
 384        if (config->direction & MSP_DIR_RX)
 385                reg_val_DMACR |= RX_DMA_ENABLE;
 386        if (config->direction & MSP_DIR_TX)
 387                reg_val_DMACR |= TX_DMA_ENABLE;
 388        writel(reg_val_DMACR, msp->registers + MSP_DMACR);
 389
 390        writel(config->iodelay, msp->registers + MSP_IODLY);
 391
 392        /* Enable frame generation logic */
 393        reg_val_GCR = readl(msp->registers + MSP_GCR);
 394        writel(reg_val_GCR | FRAME_GEN_ENABLE, msp->registers + MSP_GCR);
 395
 396        return status;
 397}
 398
 399static void flush_fifo_rx(struct ux500_msp *msp)
 400{
 401        u32 reg_val_DR, reg_val_GCR, reg_val_FLR;
 402        u32 limit = 32;
 403
 404        reg_val_GCR = readl(msp->registers + MSP_GCR);
 405        writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR);
 406
 407        reg_val_FLR = readl(msp->registers + MSP_FLR);
 408        while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) {
 409                reg_val_DR = readl(msp->registers + MSP_DR);
 410                reg_val_FLR = readl(msp->registers + MSP_FLR);
 411        }
 412
 413        writel(reg_val_GCR, msp->registers + MSP_GCR);
 414}
 415
 416static void flush_fifo_tx(struct ux500_msp *msp)
 417{
 418        u32 reg_val_TSTDR, reg_val_GCR, reg_val_FLR;
 419        u32 limit = 32;
 420
 421        reg_val_GCR = readl(msp->registers + MSP_GCR);
 422        writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR);
 423        writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR);
 424
 425        reg_val_FLR = readl(msp->registers + MSP_FLR);
 426        while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) {
 427                reg_val_TSTDR = readl(msp->registers + MSP_TSTDR);
 428                reg_val_FLR = readl(msp->registers + MSP_FLR);
 429        }
 430        writel(0x0, msp->registers + MSP_ITCR);
 431        writel(reg_val_GCR, msp->registers + MSP_GCR);
 432}
 433
 434int ux500_msp_i2s_open(struct ux500_msp *msp,
 435                struct ux500_msp_config *config)
 436{
 437        u32 old_reg, new_reg, mask;
 438        int res;
 439        unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
 440
 441        if (in_interrupt()) {
 442                dev_err(msp->dev,
 443                        "%s: ERROR: Open called in interrupt context!\n",
 444                        __func__);
 445                return -1;
 446        }
 447
 448        tx_sel = (config->direction & MSP_DIR_TX) > 0;
 449        rx_sel = (config->direction & MSP_DIR_RX) > 0;
 450        if (!tx_sel && !rx_sel) {
 451                dev_err(msp->dev, "%s: Error: No direction selected!\n",
 452                        __func__);
 453                return -EINVAL;
 454        }
 455
 456        tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0;
 457        rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0;
 458        if (tx_busy && tx_sel) {
 459                dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__);
 460                return -EBUSY;
 461        }
 462        if (rx_busy && rx_sel) {
 463                dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__);
 464                return -EBUSY;
 465        }
 466
 467        msp->dir_busy |= (tx_sel ? MSP_DIR_TX : 0) | (rx_sel ? MSP_DIR_RX : 0);
 468
 469        /* First do the global config register */
 470        mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
 471            TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
 472            RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK |
 473            LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
 474
 475        new_reg = (config->tx_clk_sel | config->rx_clk_sel |
 476                config->rx_fsync_pol | config->tx_fsync_pol |
 477                config->rx_fsync_sel | config->tx_fsync_sel |
 478                config->rx_fifo_config | config->tx_fifo_config |
 479                config->srg_clk_sel | config->loopback_enable |
 480                config->tx_data_enable);
 481
 482        old_reg = readl(msp->registers + MSP_GCR);
 483        old_reg &= ~mask;
 484        new_reg |= old_reg;
 485        writel(new_reg, msp->registers + MSP_GCR);
 486
 487        res = enable_msp(msp, config);
 488        if (res < 0) {
 489                dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
 490                        __func__, res);
 491                return -EBUSY;
 492        }
 493        if (config->loopback_enable & 0x80)
 494                msp->loopback_enable = 1;
 495
 496        /* Flush FIFOs */
 497        flush_fifo_tx(msp);
 498        flush_fifo_rx(msp);
 499
 500        msp->msp_state = MSP_STATE_CONFIGURED;
 501        return 0;
 502}
 503
 504static void disable_msp_rx(struct ux500_msp *msp)
 505{
 506        u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
 507
 508        reg_val_GCR = readl(msp->registers + MSP_GCR);
 509        writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR);
 510        reg_val_DMACR = readl(msp->registers + MSP_DMACR);
 511        writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR);
 512        reg_val_IMSC = readl(msp->registers + MSP_IMSC);
 513        writel(reg_val_IMSC &
 514                        ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
 515                        msp->registers + MSP_IMSC);
 516
 517        msp->dir_busy &= ~MSP_DIR_RX;
 518}
 519
 520static void disable_msp_tx(struct ux500_msp *msp)
 521{
 522        u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
 523
 524        reg_val_GCR = readl(msp->registers + MSP_GCR);
 525        writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR);
 526        reg_val_DMACR = readl(msp->registers + MSP_DMACR);
 527        writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR);
 528        reg_val_IMSC = readl(msp->registers + MSP_IMSC);
 529        writel(reg_val_IMSC &
 530                        ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
 531                        msp->registers + MSP_IMSC);
 532
 533        msp->dir_busy &= ~MSP_DIR_TX;
 534}
 535
 536static int disable_msp(struct ux500_msp *msp, unsigned int dir)
 537{
 538        u32 reg_val_GCR;
 539        int status = 0;
 540        unsigned int disable_tx, disable_rx;
 541
 542        reg_val_GCR = readl(msp->registers + MSP_GCR);
 543        disable_tx = dir & MSP_DIR_TX;
 544        disable_rx = dir & MSP_DIR_TX;
 545        if (disable_tx && disable_rx) {
 546                reg_val_GCR = readl(msp->registers + MSP_GCR);
 547                writel(reg_val_GCR | LOOPBACK_MASK,
 548                                msp->registers + MSP_GCR);
 549
 550                /* Flush TX-FIFO */
 551                flush_fifo_tx(msp);
 552
 553                /* Disable TX-channel */
 554                writel((readl(msp->registers + MSP_GCR) &
 555                               (~TX_ENABLE)), msp->registers + MSP_GCR);
 556
 557                /* Flush RX-FIFO */
 558                flush_fifo_rx(msp);
 559
 560                /* Disable Loopback and Receive channel */
 561                writel((readl(msp->registers + MSP_GCR) &
 562                                (~(RX_ENABLE | LOOPBACK_MASK))),
 563                                msp->registers + MSP_GCR);
 564
 565                disable_msp_tx(msp);
 566                disable_msp_rx(msp);
 567        } else if (disable_tx)
 568                disable_msp_tx(msp);
 569        else if (disable_rx)
 570                disable_msp_rx(msp);
 571
 572        return status;
 573}
 574
 575int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
 576{
 577        u32 reg_val_GCR, enable_bit;
 578
 579        if (msp->msp_state == MSP_STATE_IDLE) {
 580                dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
 581                        __func__);
 582                return -EINVAL;
 583        }
 584
 585        switch (cmd) {
 586        case SNDRV_PCM_TRIGGER_START:
 587        case SNDRV_PCM_TRIGGER_RESUME:
 588        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 589                if (direction == SNDRV_PCM_STREAM_PLAYBACK)
 590                        enable_bit = TX_ENABLE;
 591                else
 592                        enable_bit = RX_ENABLE;
 593                reg_val_GCR = readl(msp->registers + MSP_GCR);
 594                writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
 595                break;
 596
 597        case SNDRV_PCM_TRIGGER_STOP:
 598        case SNDRV_PCM_TRIGGER_SUSPEND:
 599        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 600                if (direction == SNDRV_PCM_STREAM_PLAYBACK)
 601                        disable_msp_tx(msp);
 602                else
 603                        disable_msp_rx(msp);
 604                break;
 605        default:
 606                return -EINVAL;
 607                break;
 608        }
 609
 610        return 0;
 611}
 612
 613int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
 614{
 615        int status = 0;
 616
 617        dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
 618
 619        status = disable_msp(msp, dir);
 620        if (msp->dir_busy == 0) {
 621                /* disable sample rate and frame generators */
 622                msp->msp_state = MSP_STATE_IDLE;
 623                writel((readl(msp->registers + MSP_GCR) &
 624                               (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
 625                              msp->registers + MSP_GCR);
 626
 627                writel(0, msp->registers + MSP_GCR);
 628                writel(0, msp->registers + MSP_TCF);
 629                writel(0, msp->registers + MSP_RCF);
 630                writel(0, msp->registers + MSP_DMACR);
 631                writel(0, msp->registers + MSP_SRG);
 632                writel(0, msp->registers + MSP_MCR);
 633                writel(0, msp->registers + MSP_RCM);
 634                writel(0, msp->registers + MSP_RCV);
 635                writel(0, msp->registers + MSP_TCE0);
 636                writel(0, msp->registers + MSP_TCE1);
 637                writel(0, msp->registers + MSP_TCE2);
 638                writel(0, msp->registers + MSP_TCE3);
 639                writel(0, msp->registers + MSP_RCE0);
 640                writel(0, msp->registers + MSP_RCE1);
 641                writel(0, msp->registers + MSP_RCE2);
 642                writel(0, msp->registers + MSP_RCE3);
 643        }
 644
 645        return status;
 646
 647}
 648
 649static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
 650                                struct ux500_msp *msp,
 651                                struct msp_i2s_platform_data **platform_data)
 652{
 653        struct msp_i2s_platform_data *pdata;
 654
 655        *platform_data = devm_kzalloc(&pdev->dev,
 656                                     sizeof(struct msp_i2s_platform_data),
 657                                     GFP_KERNEL);
 658        pdata = *platform_data;
 659        if (!pdata)
 660                return -ENOMEM;
 661
 662        msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
 663                                        sizeof(struct stedma40_chan_cfg),
 664                                        GFP_KERNEL);
 665        if (!msp->playback_dma_data.dma_cfg)
 666                return -ENOMEM;
 667
 668        msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
 669                                        sizeof(struct stedma40_chan_cfg),
 670                                        GFP_KERNEL);
 671        if (!msp->capture_dma_data.dma_cfg)
 672                return -ENOMEM;
 673
 674        return 0;
 675}
 676
 677int ux500_msp_i2s_init_msp(struct platform_device *pdev,
 678                        struct ux500_msp **msp_p,
 679                        struct msp_i2s_platform_data *platform_data)
 680{
 681        struct resource *res = NULL;
 682        struct device_node *np = pdev->dev.of_node;
 683        struct ux500_msp *msp;
 684        int ret;
 685
 686        *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
 687        msp = *msp_p;
 688        if (!msp)
 689                return -ENOMEM;
 690
 691        if (!platform_data) {
 692                if (np) {
 693                        ret = ux500_msp_i2s_of_init_msp(pdev, msp,
 694                                                        &platform_data);
 695                        if (ret)
 696                                return ret;
 697                } else
 698                        return -EINVAL;
 699        } else {
 700                msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
 701                msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
 702                msp->id = platform_data->id;
 703        }
 704
 705        msp->dev = &pdev->dev;
 706
 707        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 708        if (res == NULL) {
 709                dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
 710                        __func__);
 711                return -ENOMEM;
 712        }
 713
 714        msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
 715        msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
 716
 717        msp->registers = devm_ioremap(&pdev->dev, res->start,
 718                                      resource_size(res));
 719        if (msp->registers == NULL) {
 720                dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
 721                return -ENOMEM;
 722        }
 723
 724        msp->msp_state = MSP_STATE_IDLE;
 725        msp->loopback_enable = 0;
 726
 727        return 0;
 728}
 729
 730void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
 731                        struct ux500_msp *msp)
 732{
 733        dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
 734}
 735
 736MODULE_LICENSE("GPL v2");
 737