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