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