cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ux500_msp_i2s.c (19896B)


      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");