Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) ST-Ericsson SA 2012
0004  *
0005  * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
0006  *         Roger Nilsson <roger.xr.nilsson@stericsson.com>,
0007  *         Sandeep Kaushik <sandeep.kaushik@st.com>
0008  *         for ST-Ericsson.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/delay.h>
0014 #include <linux/slab.h>
0015 #include <linux/io.h>
0016 #include <linux/of.h>
0017 #include <linux/platform_data/asoc-ux500-msp.h>
0018 
0019 #include <sound/soc.h>
0020 
0021 #include "ux500_msp_i2s.h"
0022 
0023  /* Protocol desciptors */
0024 static const struct msp_protdesc prot_descs[] = {
0025     { /* I2S */
0026         MSP_SINGLE_PHASE,
0027         MSP_SINGLE_PHASE,
0028         MSP_PHASE2_START_MODE_IMEDIATE,
0029         MSP_PHASE2_START_MODE_IMEDIATE,
0030         MSP_BTF_MS_BIT_FIRST,
0031         MSP_BTF_MS_BIT_FIRST,
0032         MSP_FRAME_LEN_1,
0033         MSP_FRAME_LEN_1,
0034         MSP_FRAME_LEN_1,
0035         MSP_FRAME_LEN_1,
0036         MSP_ELEM_LEN_32,
0037         MSP_ELEM_LEN_32,
0038         MSP_ELEM_LEN_32,
0039         MSP_ELEM_LEN_32,
0040         MSP_DELAY_1,
0041         MSP_DELAY_1,
0042         MSP_RISING_EDGE,
0043         MSP_FALLING_EDGE,
0044         MSP_FSYNC_POL_ACT_LO,
0045         MSP_FSYNC_POL_ACT_LO,
0046         MSP_SWAP_NONE,
0047         MSP_SWAP_NONE,
0048         MSP_COMPRESS_MODE_LINEAR,
0049         MSP_EXPAND_MODE_LINEAR,
0050         MSP_FSYNC_IGNORE,
0051         31,
0052         15,
0053         32,
0054     }, { /* PCM */
0055         MSP_DUAL_PHASE,
0056         MSP_DUAL_PHASE,
0057         MSP_PHASE2_START_MODE_FSYNC,
0058         MSP_PHASE2_START_MODE_FSYNC,
0059         MSP_BTF_MS_BIT_FIRST,
0060         MSP_BTF_MS_BIT_FIRST,
0061         MSP_FRAME_LEN_1,
0062         MSP_FRAME_LEN_1,
0063         MSP_FRAME_LEN_1,
0064         MSP_FRAME_LEN_1,
0065         MSP_ELEM_LEN_16,
0066         MSP_ELEM_LEN_16,
0067         MSP_ELEM_LEN_16,
0068         MSP_ELEM_LEN_16,
0069         MSP_DELAY_0,
0070         MSP_DELAY_0,
0071         MSP_RISING_EDGE,
0072         MSP_FALLING_EDGE,
0073         MSP_FSYNC_POL_ACT_HI,
0074         MSP_FSYNC_POL_ACT_HI,
0075         MSP_SWAP_NONE,
0076         MSP_SWAP_NONE,
0077         MSP_COMPRESS_MODE_LINEAR,
0078         MSP_EXPAND_MODE_LINEAR,
0079         MSP_FSYNC_IGNORE,
0080         255,
0081         0,
0082         256,
0083     }, { /* Companded PCM */
0084         MSP_SINGLE_PHASE,
0085         MSP_SINGLE_PHASE,
0086         MSP_PHASE2_START_MODE_FSYNC,
0087         MSP_PHASE2_START_MODE_FSYNC,
0088         MSP_BTF_MS_BIT_FIRST,
0089         MSP_BTF_MS_BIT_FIRST,
0090         MSP_FRAME_LEN_1,
0091         MSP_FRAME_LEN_1,
0092         MSP_FRAME_LEN_1,
0093         MSP_FRAME_LEN_1,
0094         MSP_ELEM_LEN_8,
0095         MSP_ELEM_LEN_8,
0096         MSP_ELEM_LEN_8,
0097         MSP_ELEM_LEN_8,
0098         MSP_DELAY_0,
0099         MSP_DELAY_0,
0100         MSP_RISING_EDGE,
0101         MSP_RISING_EDGE,
0102         MSP_FSYNC_POL_ACT_HI,
0103         MSP_FSYNC_POL_ACT_HI,
0104         MSP_SWAP_NONE,
0105         MSP_SWAP_NONE,
0106         MSP_COMPRESS_MODE_LINEAR,
0107         MSP_EXPAND_MODE_LINEAR,
0108         MSP_FSYNC_IGNORE,
0109         255,
0110         0,
0111         256,
0112     },
0113 };
0114 
0115 static void set_prot_desc_tx(struct ux500_msp *msp,
0116             struct msp_protdesc *protdesc,
0117             enum msp_data_size data_size)
0118 {
0119     u32 temp_reg = 0;
0120 
0121     temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode);
0122     temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode);
0123     temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1);
0124     temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2);
0125     if (msp->def_elem_len) {
0126         temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1);
0127         temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2);
0128     } else {
0129         temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
0130         temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
0131     }
0132     temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay);
0133     temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order);
0134     temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol);
0135     temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap);
0136     temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode);
0137     temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
0138 
0139     writel(temp_reg, msp->registers + MSP_TCF);
0140 }
0141 
0142 static void set_prot_desc_rx(struct ux500_msp *msp,
0143             struct msp_protdesc *protdesc,
0144             enum msp_data_size data_size)
0145 {
0146     u32 temp_reg = 0;
0147 
0148     temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode);
0149     temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode);
0150     temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1);
0151     temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2);
0152     if (msp->def_elem_len) {
0153         temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1);
0154         temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2);
0155     } else {
0156         temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
0157         temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
0158     }
0159 
0160     temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay);
0161     temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order);
0162     temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol);
0163     temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap);
0164     temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode);
0165     temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
0166 
0167     writel(temp_reg, msp->registers + MSP_RCF);
0168 }
0169 
0170 static int configure_protocol(struct ux500_msp *msp,
0171             struct ux500_msp_config *config)
0172 {
0173     struct msp_protdesc *protdesc;
0174     enum msp_data_size data_size;
0175     u32 temp_reg = 0;
0176 
0177     data_size = config->data_size;
0178     msp->def_elem_len = config->def_elem_len;
0179     if (config->default_protdesc == 1) {
0180         if (config->protocol >= MSP_INVALID_PROTOCOL) {
0181             dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
0182                 __func__);
0183             return -EINVAL;
0184         }
0185         protdesc =
0186             (struct msp_protdesc *)&prot_descs[config->protocol];
0187     } else {
0188         protdesc = (struct msp_protdesc *)&config->protdesc;
0189     }
0190 
0191     if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
0192         dev_err(msp->dev,
0193             "%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
0194             __func__, data_size);
0195         return -EINVAL;
0196     }
0197 
0198     if (config->direction & MSP_DIR_TX)
0199         set_prot_desc_tx(msp, protdesc, data_size);
0200     if (config->direction & MSP_DIR_RX)
0201         set_prot_desc_rx(msp, protdesc, data_size);
0202 
0203     /* The code below should not be separated. */
0204     temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
0205     temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
0206     writel(temp_reg, msp->registers + MSP_GCR);
0207     temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
0208     temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
0209     writel(temp_reg, msp->registers + MSP_GCR);
0210 
0211     return 0;
0212 }
0213 
0214 static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
0215 {
0216     u32 reg_val_GCR;
0217     u32 frame_per = 0;
0218     u32 sck_div = 0;
0219     u32 frame_width = 0;
0220     u32 temp_reg = 0;
0221     struct msp_protdesc *protdesc = NULL;
0222 
0223     reg_val_GCR = readl(msp->registers + MSP_GCR);
0224     writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
0225 
0226     if (config->default_protdesc)
0227         protdesc =
0228             (struct msp_protdesc *)&prot_descs[config->protocol];
0229     else
0230         protdesc = (struct msp_protdesc *)&config->protdesc;
0231 
0232     switch (config->protocol) {
0233     case MSP_PCM_PROTOCOL:
0234     case MSP_PCM_COMPAND_PROTOCOL:
0235         frame_width = protdesc->frame_width;
0236         sck_div = config->f_inputclk / (config->frame_freq *
0237             (protdesc->clocks_per_frame));
0238         frame_per = protdesc->frame_period;
0239         break;
0240     case MSP_I2S_PROTOCOL:
0241         frame_width = protdesc->frame_width;
0242         sck_div = config->f_inputclk / (config->frame_freq *
0243             (protdesc->clocks_per_frame));
0244         frame_per = protdesc->frame_period;
0245         break;
0246     default:
0247         dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
0248             __func__,
0249             config->protocol);
0250         return -EINVAL;
0251     }
0252 
0253     temp_reg = (sck_div - 1) & SCK_DIV_MASK;
0254     temp_reg |= FRAME_WIDTH_BITS(frame_width);
0255     temp_reg |= FRAME_PERIOD_BITS(frame_per);
0256     writel(temp_reg, msp->registers + MSP_SRG);
0257 
0258     msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
0259 
0260     /* Enable bit-clock */
0261     udelay(100);
0262     reg_val_GCR = readl(msp->registers + MSP_GCR);
0263     writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
0264     udelay(100);
0265 
0266     return 0;
0267 }
0268 
0269 static int configure_multichannel(struct ux500_msp *msp,
0270                 struct ux500_msp_config *config)
0271 {
0272     struct msp_protdesc *protdesc;
0273     struct msp_multichannel_config *mcfg;
0274     u32 reg_val_MCR;
0275 
0276     if (config->default_protdesc == 1) {
0277         if (config->protocol >= MSP_INVALID_PROTOCOL) {
0278             dev_err(msp->dev,
0279                 "%s: ERROR: Invalid protocol (%d)!\n",
0280                 __func__, config->protocol);
0281             return -EINVAL;
0282         }
0283         protdesc = (struct msp_protdesc *)
0284                 &prot_descs[config->protocol];
0285     } else {
0286         protdesc = (struct msp_protdesc *)&config->protdesc;
0287     }
0288 
0289     mcfg = &config->multichannel_config;
0290     if (mcfg->tx_multichannel_enable) {
0291         if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) {
0292             reg_val_MCR = readl(msp->registers + MSP_MCR);
0293             writel(reg_val_MCR | (mcfg->tx_multichannel_enable ?
0294                         1 << TMCEN_BIT : 0),
0295                 msp->registers + MSP_MCR);
0296             writel(mcfg->tx_channel_0_enable,
0297                 msp->registers + MSP_TCE0);
0298             writel(mcfg->tx_channel_1_enable,
0299                 msp->registers + MSP_TCE1);
0300             writel(mcfg->tx_channel_2_enable,
0301                 msp->registers + MSP_TCE2);
0302             writel(mcfg->tx_channel_3_enable,
0303                 msp->registers + MSP_TCE3);
0304         } else {
0305             dev_err(msp->dev,
0306                 "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n",
0307                 __func__, protdesc->tx_phase_mode);
0308             return -EINVAL;
0309         }
0310     }
0311     if (mcfg->rx_multichannel_enable) {
0312         if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) {
0313             reg_val_MCR = readl(msp->registers + MSP_MCR);
0314             writel(reg_val_MCR | (mcfg->rx_multichannel_enable ?
0315                         1 << RMCEN_BIT : 0),
0316                 msp->registers + MSP_MCR);
0317             writel(mcfg->rx_channel_0_enable,
0318                     msp->registers + MSP_RCE0);
0319             writel(mcfg->rx_channel_1_enable,
0320                     msp->registers + MSP_RCE1);
0321             writel(mcfg->rx_channel_2_enable,
0322                     msp->registers + MSP_RCE2);
0323             writel(mcfg->rx_channel_3_enable,
0324                     msp->registers + MSP_RCE3);
0325         } else {
0326             dev_err(msp->dev,
0327                 "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n",
0328                 __func__, protdesc->rx_phase_mode);
0329             return -EINVAL;
0330         }
0331         if (mcfg->rx_comparison_enable_mode) {
0332             reg_val_MCR = readl(msp->registers + MSP_MCR);
0333             writel(reg_val_MCR |
0334                 (mcfg->rx_comparison_enable_mode << RCMPM_BIT),
0335                 msp->registers + MSP_MCR);
0336 
0337             writel(mcfg->comparison_mask,
0338                     msp->registers + MSP_RCM);
0339             writel(mcfg->comparison_value,
0340                     msp->registers + MSP_RCV);
0341 
0342         }
0343     }
0344 
0345     return 0;
0346 }
0347 
0348 static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
0349 {
0350     int status = 0;
0351     u32 reg_val_DMACR, reg_val_GCR;
0352 
0353     /* Configure msp with protocol dependent settings */
0354     configure_protocol(msp, config);
0355     setup_bitclk(msp, config);
0356     if (config->multichannel_configured == 1) {
0357         status = configure_multichannel(msp, config);
0358         if (status)
0359             dev_warn(msp->dev,
0360                 "%s: WARN: configure_multichannel failed (%d)!\n",
0361                 __func__, status);
0362     }
0363 
0364     /* Make sure the correct DMA-directions are configured */
0365     if ((config->direction & MSP_DIR_RX) &&
0366             !msp->capture_dma_data.dma_cfg) {
0367         dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
0368             __func__);
0369         return -EINVAL;
0370     }
0371     if ((config->direction == MSP_DIR_TX) &&
0372             !msp->playback_dma_data.dma_cfg) {
0373         dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
0374             __func__);
0375         return -EINVAL;
0376     }
0377 
0378     reg_val_DMACR = readl(msp->registers + MSP_DMACR);
0379     if (config->direction & MSP_DIR_RX)
0380         reg_val_DMACR |= RX_DMA_ENABLE;
0381     if (config->direction & MSP_DIR_TX)
0382         reg_val_DMACR |= TX_DMA_ENABLE;
0383     writel(reg_val_DMACR, msp->registers + MSP_DMACR);
0384 
0385     writel(config->iodelay, msp->registers + MSP_IODLY);
0386 
0387     /* Enable frame generation logic */
0388     reg_val_GCR = readl(msp->registers + MSP_GCR);
0389     writel(reg_val_GCR | FRAME_GEN_ENABLE, msp->registers + MSP_GCR);
0390 
0391     return status;
0392 }
0393 
0394 static void flush_fifo_rx(struct ux500_msp *msp)
0395 {
0396     u32 reg_val_GCR, reg_val_FLR;
0397     u32 limit = 32;
0398 
0399     reg_val_GCR = readl(msp->registers + MSP_GCR);
0400     writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR);
0401 
0402     reg_val_FLR = readl(msp->registers + MSP_FLR);
0403     while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) {
0404         readl(msp->registers + MSP_DR);
0405         reg_val_FLR = readl(msp->registers + MSP_FLR);
0406     }
0407 
0408     writel(reg_val_GCR, msp->registers + MSP_GCR);
0409 }
0410 
0411 static void flush_fifo_tx(struct ux500_msp *msp)
0412 {
0413     u32 reg_val_GCR, reg_val_FLR;
0414     u32 limit = 32;
0415 
0416     reg_val_GCR = readl(msp->registers + MSP_GCR);
0417     writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR);
0418     writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR);
0419 
0420     reg_val_FLR = readl(msp->registers + MSP_FLR);
0421     while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) {
0422         readl(msp->registers + MSP_TSTDR);
0423         reg_val_FLR = readl(msp->registers + MSP_FLR);
0424     }
0425     writel(0x0, msp->registers + MSP_ITCR);
0426     writel(reg_val_GCR, msp->registers + MSP_GCR);
0427 }
0428 
0429 int ux500_msp_i2s_open(struct ux500_msp *msp,
0430         struct ux500_msp_config *config)
0431 {
0432     u32 old_reg, new_reg, mask;
0433     int res;
0434     unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
0435 
0436     if (in_interrupt()) {
0437         dev_err(msp->dev,
0438             "%s: ERROR: Open called in interrupt context!\n",
0439             __func__);
0440         return -1;
0441     }
0442 
0443     tx_sel = (config->direction & MSP_DIR_TX) > 0;
0444     rx_sel = (config->direction & MSP_DIR_RX) > 0;
0445     if (!tx_sel && !rx_sel) {
0446         dev_err(msp->dev, "%s: Error: No direction selected!\n",
0447             __func__);
0448         return -EINVAL;
0449     }
0450 
0451     tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0;
0452     rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0;
0453     if (tx_busy && tx_sel) {
0454         dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__);
0455         return -EBUSY;
0456     }
0457     if (rx_busy && rx_sel) {
0458         dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__);
0459         return -EBUSY;
0460     }
0461 
0462     msp->dir_busy |= (tx_sel ? MSP_DIR_TX : 0) | (rx_sel ? MSP_DIR_RX : 0);
0463 
0464     /* First do the global config register */
0465     mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
0466         TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
0467         RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK |
0468         LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
0469 
0470     new_reg = (config->tx_clk_sel | config->rx_clk_sel |
0471         config->rx_fsync_pol | config->tx_fsync_pol |
0472         config->rx_fsync_sel | config->tx_fsync_sel |
0473         config->rx_fifo_config | config->tx_fifo_config |
0474         config->srg_clk_sel | config->loopback_enable |
0475         config->tx_data_enable);
0476 
0477     old_reg = readl(msp->registers + MSP_GCR);
0478     old_reg &= ~mask;
0479     new_reg |= old_reg;
0480     writel(new_reg, msp->registers + MSP_GCR);
0481 
0482     res = enable_msp(msp, config);
0483     if (res < 0) {
0484         dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
0485             __func__, res);
0486         return -EBUSY;
0487     }
0488     if (config->loopback_enable & 0x80)
0489         msp->loopback_enable = 1;
0490 
0491     /* Flush FIFOs */
0492     flush_fifo_tx(msp);
0493     flush_fifo_rx(msp);
0494 
0495     msp->msp_state = MSP_STATE_CONFIGURED;
0496     return 0;
0497 }
0498 
0499 static void disable_msp_rx(struct ux500_msp *msp)
0500 {
0501     u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
0502 
0503     reg_val_GCR = readl(msp->registers + MSP_GCR);
0504     writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR);
0505     reg_val_DMACR = readl(msp->registers + MSP_DMACR);
0506     writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR);
0507     reg_val_IMSC = readl(msp->registers + MSP_IMSC);
0508     writel(reg_val_IMSC &
0509             ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
0510             msp->registers + MSP_IMSC);
0511 
0512     msp->dir_busy &= ~MSP_DIR_RX;
0513 }
0514 
0515 static void disable_msp_tx(struct ux500_msp *msp)
0516 {
0517     u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
0518 
0519     reg_val_GCR = readl(msp->registers + MSP_GCR);
0520     writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR);
0521     reg_val_DMACR = readl(msp->registers + MSP_DMACR);
0522     writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR);
0523     reg_val_IMSC = readl(msp->registers + MSP_IMSC);
0524     writel(reg_val_IMSC &
0525             ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
0526             msp->registers + MSP_IMSC);
0527 
0528     msp->dir_busy &= ~MSP_DIR_TX;
0529 }
0530 
0531 static int disable_msp(struct ux500_msp *msp, unsigned int dir)
0532 {
0533     u32 reg_val_GCR;
0534     unsigned int disable_tx, disable_rx;
0535 
0536     reg_val_GCR = readl(msp->registers + MSP_GCR);
0537     disable_tx = dir & MSP_DIR_TX;
0538     disable_rx = dir & MSP_DIR_TX;
0539     if (disable_tx && disable_rx) {
0540         reg_val_GCR = readl(msp->registers + MSP_GCR);
0541         writel(reg_val_GCR | LOOPBACK_MASK,
0542                 msp->registers + MSP_GCR);
0543 
0544         /* Flush TX-FIFO */
0545         flush_fifo_tx(msp);
0546 
0547         /* Disable TX-channel */
0548         writel((readl(msp->registers + MSP_GCR) &
0549                    (~TX_ENABLE)), msp->registers + MSP_GCR);
0550 
0551         /* Flush RX-FIFO */
0552         flush_fifo_rx(msp);
0553 
0554         /* Disable Loopback and Receive channel */
0555         writel((readl(msp->registers + MSP_GCR) &
0556                 (~(RX_ENABLE | LOOPBACK_MASK))),
0557                 msp->registers + MSP_GCR);
0558 
0559         disable_msp_tx(msp);
0560         disable_msp_rx(msp);
0561     } else if (disable_tx)
0562         disable_msp_tx(msp);
0563     else if (disable_rx)
0564         disable_msp_rx(msp);
0565 
0566     return 0;
0567 }
0568 
0569 int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
0570 {
0571     u32 reg_val_GCR, enable_bit;
0572 
0573     if (msp->msp_state == MSP_STATE_IDLE) {
0574         dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
0575             __func__);
0576         return -EINVAL;
0577     }
0578 
0579     switch (cmd) {
0580     case SNDRV_PCM_TRIGGER_START:
0581     case SNDRV_PCM_TRIGGER_RESUME:
0582     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0583         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
0584             enable_bit = TX_ENABLE;
0585         else
0586             enable_bit = RX_ENABLE;
0587         reg_val_GCR = readl(msp->registers + MSP_GCR);
0588         writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
0589         break;
0590 
0591     case SNDRV_PCM_TRIGGER_STOP:
0592     case SNDRV_PCM_TRIGGER_SUSPEND:
0593     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0594         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
0595             disable_msp_tx(msp);
0596         else
0597             disable_msp_rx(msp);
0598         break;
0599     default:
0600         return -EINVAL;
0601     }
0602 
0603     return 0;
0604 }
0605 
0606 int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
0607 {
0608     int status = 0;
0609 
0610     dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
0611 
0612     status = disable_msp(msp, dir);
0613     if (msp->dir_busy == 0) {
0614         /* disable sample rate and frame generators */
0615         msp->msp_state = MSP_STATE_IDLE;
0616         writel((readl(msp->registers + MSP_GCR) &
0617                    (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
0618                   msp->registers + MSP_GCR);
0619 
0620         writel(0, msp->registers + MSP_GCR);
0621         writel(0, msp->registers + MSP_TCF);
0622         writel(0, msp->registers + MSP_RCF);
0623         writel(0, msp->registers + MSP_DMACR);
0624         writel(0, msp->registers + MSP_SRG);
0625         writel(0, msp->registers + MSP_MCR);
0626         writel(0, msp->registers + MSP_RCM);
0627         writel(0, msp->registers + MSP_RCV);
0628         writel(0, msp->registers + MSP_TCE0);
0629         writel(0, msp->registers + MSP_TCE1);
0630         writel(0, msp->registers + MSP_TCE2);
0631         writel(0, msp->registers + MSP_TCE3);
0632         writel(0, msp->registers + MSP_RCE0);
0633         writel(0, msp->registers + MSP_RCE1);
0634         writel(0, msp->registers + MSP_RCE2);
0635         writel(0, msp->registers + MSP_RCE3);
0636     }
0637 
0638     return status;
0639 
0640 }
0641 
0642 static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
0643                 struct ux500_msp *msp,
0644                 struct msp_i2s_platform_data **platform_data)
0645 {
0646     struct msp_i2s_platform_data *pdata;
0647 
0648     *platform_data = devm_kzalloc(&pdev->dev,
0649                      sizeof(struct msp_i2s_platform_data),
0650                      GFP_KERNEL);
0651     pdata = *platform_data;
0652     if (!pdata)
0653         return -ENOMEM;
0654 
0655     msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
0656                     sizeof(struct stedma40_chan_cfg),
0657                     GFP_KERNEL);
0658     if (!msp->playback_dma_data.dma_cfg)
0659         return -ENOMEM;
0660 
0661     msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
0662                     sizeof(struct stedma40_chan_cfg),
0663                     GFP_KERNEL);
0664     if (!msp->capture_dma_data.dma_cfg)
0665         return -ENOMEM;
0666 
0667     return 0;
0668 }
0669 
0670 int ux500_msp_i2s_init_msp(struct platform_device *pdev,
0671             struct ux500_msp **msp_p,
0672             struct msp_i2s_platform_data *platform_data)
0673 {
0674     struct resource *res = NULL;
0675     struct device_node *np = pdev->dev.of_node;
0676     struct ux500_msp *msp;
0677     int ret;
0678 
0679     *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
0680     msp = *msp_p;
0681     if (!msp)
0682         return -ENOMEM;
0683 
0684     if (!platform_data) {
0685         if (np) {
0686             ret = ux500_msp_i2s_of_init_msp(pdev, msp,
0687                             &platform_data);
0688             if (ret)
0689                 return ret;
0690         } else
0691             return -EINVAL;
0692     } else {
0693         msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
0694         msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
0695         msp->id = platform_data->id;
0696     }
0697 
0698     msp->dev = &pdev->dev;
0699 
0700     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0701     if (res == NULL) {
0702         dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
0703             __func__);
0704         return -ENOMEM;
0705     }
0706 
0707     msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
0708     msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
0709 
0710     msp->registers = devm_ioremap(&pdev->dev, res->start,
0711                       resource_size(res));
0712     if (msp->registers == NULL) {
0713         dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
0714         return -ENOMEM;
0715     }
0716 
0717     msp->msp_state = MSP_STATE_IDLE;
0718     msp->loopback_enable = 0;
0719 
0720     return 0;
0721 }
0722 
0723 void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
0724             struct ux500_msp *msp)
0725 {
0726     dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
0727 }
0728 
0729 MODULE_LICENSE("GPL v2");