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

mxs-saif.c (20562B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2011 Freescale Semiconductor, Inc.
      4 */
      5
      6#include <linux/module.h>
      7#include <linux/init.h>
      8#include <linux/of.h>
      9#include <linux/of_device.h>
     10#include <linux/platform_device.h>
     11#include <linux/slab.h>
     12#include <linux/dma-mapping.h>
     13#include <linux/clk.h>
     14#include <linux/clk-provider.h>
     15#include <linux/delay.h>
     16#include <linux/io.h>
     17#include <linux/time.h>
     18#include <sound/core.h>
     19#include <sound/pcm.h>
     20#include <sound/pcm_params.h>
     21#include <sound/soc.h>
     22
     23#include "mxs-saif.h"
     24
     25#define MXS_SET_ADDR	0x4
     26#define MXS_CLR_ADDR	0x8
     27
     28static struct mxs_saif *mxs_saif[2];
     29
     30/*
     31 * SAIF is a little different with other normal SOC DAIs on clock using.
     32 *
     33 * For MXS, two SAIF modules are instantiated on-chip.
     34 * Each SAIF has a set of clock pins and can be operating in master
     35 * mode simultaneously if they are connected to different off-chip codecs.
     36 * Also, one of the two SAIFs can master or drive the clock pins while the
     37 * other SAIF, in slave mode, receives clocking from the master SAIF.
     38 * This also means that both SAIFs must operate at the same sample rate.
     39 *
     40 * We abstract this as each saif has a master, the master could be
     41 * itself or other saifs. In the generic saif driver, saif does not need
     42 * to know the different clkmux. Saif only needs to know who is its master
     43 * and operating its master to generate the proper clock rate for it.
     44 * The master id is provided in mach-specific layer according to different
     45 * clkmux setting.
     46 */
     47
     48static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
     49			int clk_id, unsigned int freq, int dir)
     50{
     51	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
     52
     53	switch (clk_id) {
     54	case MXS_SAIF_MCLK:
     55		saif->mclk = freq;
     56		break;
     57	default:
     58		return -EINVAL;
     59	}
     60	return 0;
     61}
     62
     63/*
     64 * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK
     65 * is provided by other SAIF, we provide a interface here to get its master
     66 * from its master_id.
     67 * Note that the master could be itself.
     68 */
     69static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif)
     70{
     71	return mxs_saif[saif->master_id];
     72}
     73
     74/*
     75 * Set SAIF clock and MCLK
     76 */
     77static int mxs_saif_set_clk(struct mxs_saif *saif,
     78				  unsigned int mclk,
     79				  unsigned int rate)
     80{
     81	u32 scr;
     82	int ret;
     83	struct mxs_saif *master_saif;
     84
     85	dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate);
     86
     87	/* Set master saif to generate proper clock */
     88	master_saif = mxs_saif_get_master(saif);
     89	if (!master_saif)
     90		return -EINVAL;
     91
     92	dev_dbg(saif->dev, "master saif%d\n", master_saif->id);
     93
     94	/* Checking if can playback and capture simutaneously */
     95	if (master_saif->ongoing && rate != master_saif->cur_rate) {
     96		dev_err(saif->dev,
     97			"can not change clock, master saif%d(rate %d) is ongoing\n",
     98			master_saif->id, master_saif->cur_rate);
     99		return -EINVAL;
    100	}
    101
    102	scr = __raw_readl(master_saif->base + SAIF_CTRL);
    103	scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
    104	scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
    105
    106	/*
    107	 * Set SAIF clock
    108	 *
    109	 * The SAIF clock should be either 384*fs or 512*fs.
    110	 * If MCLK is used, the SAIF clk ratio needs to match mclk ratio.
    111	 *  For 256x, 128x, 64x, and 32x sub-rates, set saif clk as 512*fs.
    112	 *  For 192x, 96x, and 48x sub-rates, set saif clk as 384*fs.
    113	 *
    114	 * If MCLK is not used, we just set saif clk to 512*fs.
    115	 */
    116	ret = clk_prepare_enable(master_saif->clk);
    117	if (ret)
    118		return ret;
    119
    120	if (master_saif->mclk_in_use) {
    121		switch (mclk / rate) {
    122		case 32:
    123		case 64:
    124		case 128:
    125		case 256:
    126		case 512:
    127			scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
    128			ret = clk_set_rate(master_saif->clk, 512 * rate);
    129			break;
    130		case 48:
    131		case 96:
    132		case 192:
    133		case 384:
    134			scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
    135			ret = clk_set_rate(master_saif->clk, 384 * rate);
    136			break;
    137		default:
    138			/* SAIF MCLK should be a sub-rate of 512x or 384x */
    139			clk_disable_unprepare(master_saif->clk);
    140			return -EINVAL;
    141		}
    142	} else {
    143		ret = clk_set_rate(master_saif->clk, 512 * rate);
    144		scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
    145	}
    146
    147	clk_disable_unprepare(master_saif->clk);
    148
    149	if (ret)
    150		return ret;
    151
    152	master_saif->cur_rate = rate;
    153
    154	if (!master_saif->mclk_in_use) {
    155		__raw_writel(scr, master_saif->base + SAIF_CTRL);
    156		return 0;
    157	}
    158
    159	/*
    160	 * Program the over-sample rate for MCLK output
    161	 *
    162	 * The available MCLK range is 32x, 48x... 512x. The rate
    163	 * could be from 8kHz to 192kH.
    164	 */
    165	switch (mclk / rate) {
    166	case 32:
    167		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
    168		break;
    169	case 64:
    170		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
    171		break;
    172	case 128:
    173		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
    174		break;
    175	case 256:
    176		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
    177		break;
    178	case 512:
    179		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
    180		break;
    181	case 48:
    182		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
    183		break;
    184	case 96:
    185		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
    186		break;
    187	case 192:
    188		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
    189		break;
    190	case 384:
    191		scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
    192		break;
    193	default:
    194		return -EINVAL;
    195	}
    196
    197	__raw_writel(scr, master_saif->base + SAIF_CTRL);
    198
    199	return 0;
    200}
    201
    202/*
    203 * Put and disable MCLK.
    204 */
    205int mxs_saif_put_mclk(unsigned int saif_id)
    206{
    207	struct mxs_saif *saif = mxs_saif[saif_id];
    208	u32 stat;
    209
    210	if (!saif)
    211		return -EINVAL;
    212
    213	stat = __raw_readl(saif->base + SAIF_STAT);
    214	if (stat & BM_SAIF_STAT_BUSY) {
    215		dev_err(saif->dev, "error: busy\n");
    216		return -EBUSY;
    217	}
    218
    219	clk_disable_unprepare(saif->clk);
    220
    221	/* disable MCLK output */
    222	__raw_writel(BM_SAIF_CTRL_CLKGATE,
    223		saif->base + SAIF_CTRL + MXS_SET_ADDR);
    224	__raw_writel(BM_SAIF_CTRL_RUN,
    225		saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    226
    227	saif->mclk_in_use = 0;
    228	return 0;
    229}
    230EXPORT_SYMBOL_GPL(mxs_saif_put_mclk);
    231
    232/*
    233 * Get MCLK and set clock rate, then enable it
    234 *
    235 * This interface is used for codecs who are using MCLK provided
    236 * by saif.
    237 */
    238int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
    239					unsigned int rate)
    240{
    241	struct mxs_saif *saif = mxs_saif[saif_id];
    242	u32 stat;
    243	int ret;
    244	struct mxs_saif *master_saif;
    245
    246	if (!saif)
    247		return -EINVAL;
    248
    249	/* Clear Reset */
    250	__raw_writel(BM_SAIF_CTRL_SFTRST,
    251		saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    252
    253	/* FIXME: need clear clk gate for register r/w */
    254	__raw_writel(BM_SAIF_CTRL_CLKGATE,
    255		saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    256
    257	master_saif = mxs_saif_get_master(saif);
    258	if (saif != master_saif) {
    259		dev_err(saif->dev, "can not get mclk from a non-master saif\n");
    260		return -EINVAL;
    261	}
    262
    263	stat = __raw_readl(saif->base + SAIF_STAT);
    264	if (stat & BM_SAIF_STAT_BUSY) {
    265		dev_err(saif->dev, "error: busy\n");
    266		return -EBUSY;
    267	}
    268
    269	saif->mclk_in_use = 1;
    270	ret = mxs_saif_set_clk(saif, mclk, rate);
    271	if (ret)
    272		return ret;
    273
    274	ret = clk_prepare_enable(saif->clk);
    275	if (ret)
    276		return ret;
    277
    278	/* enable MCLK output */
    279	__raw_writel(BM_SAIF_CTRL_RUN,
    280		saif->base + SAIF_CTRL + MXS_SET_ADDR);
    281
    282	return 0;
    283}
    284EXPORT_SYMBOL_GPL(mxs_saif_get_mclk);
    285
    286/*
    287 * SAIF DAI format configuration.
    288 * Should only be called when port is inactive.
    289 */
    290static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
    291{
    292	u32 scr, stat;
    293	u32 scr0;
    294	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    295
    296	stat = __raw_readl(saif->base + SAIF_STAT);
    297	if (stat & BM_SAIF_STAT_BUSY) {
    298		dev_err(cpu_dai->dev, "error: busy\n");
    299		return -EBUSY;
    300	}
    301
    302	/* If SAIF1 is configured as slave, the clk gate needs to be cleared
    303	 * before the register can be written.
    304	 */
    305	if (saif->id != saif->master_id) {
    306		__raw_writel(BM_SAIF_CTRL_SFTRST,
    307			saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    308		__raw_writel(BM_SAIF_CTRL_CLKGATE,
    309			saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    310	}
    311
    312	scr0 = __raw_readl(saif->base + SAIF_CTRL);
    313	scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
    314		& ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
    315	scr = 0;
    316
    317	/* DAI mode */
    318	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    319	case SND_SOC_DAIFMT_I2S:
    320		/* data frame low 1clk before data */
    321		scr |= BM_SAIF_CTRL_DELAY;
    322		scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
    323		break;
    324	case SND_SOC_DAIFMT_LEFT_J:
    325		/* data frame high with data */
    326		scr &= ~BM_SAIF_CTRL_DELAY;
    327		scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
    328		scr &= ~BM_SAIF_CTRL_JUSTIFY;
    329		break;
    330	default:
    331		return -EINVAL;
    332	}
    333
    334	/* DAI clock inversion */
    335	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    336	case SND_SOC_DAIFMT_IB_IF:
    337		scr |= BM_SAIF_CTRL_BITCLK_EDGE;
    338		scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
    339		break;
    340	case SND_SOC_DAIFMT_IB_NF:
    341		scr |= BM_SAIF_CTRL_BITCLK_EDGE;
    342		scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
    343		break;
    344	case SND_SOC_DAIFMT_NB_IF:
    345		scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
    346		scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
    347		break;
    348	case SND_SOC_DAIFMT_NB_NF:
    349		scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
    350		scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
    351		break;
    352	}
    353
    354	/*
    355	 * Note: We simply just support master mode since SAIF TX can only
    356	 * work as master.
    357	 * Here the master is relative to codec side.
    358	 * Saif internally could be slave when working on EXTMASTER mode.
    359	 * We just hide this to machine driver.
    360	 */
    361	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    362	case SND_SOC_DAIFMT_CBS_CFS:
    363		if (saif->id == saif->master_id)
    364			scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
    365		else
    366			scr |= BM_SAIF_CTRL_SLAVE_MODE;
    367
    368		__raw_writel(scr | scr0, saif->base + SAIF_CTRL);
    369		break;
    370	default:
    371		return -EINVAL;
    372	}
    373
    374	return 0;
    375}
    376
    377static int mxs_saif_startup(struct snd_pcm_substream *substream,
    378			   struct snd_soc_dai *cpu_dai)
    379{
    380	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    381	int ret;
    382
    383	/* clear error status to 0 for each re-open */
    384	saif->fifo_underrun = 0;
    385	saif->fifo_overrun = 0;
    386
    387	/* Clear Reset for normal operations */
    388	__raw_writel(BM_SAIF_CTRL_SFTRST,
    389		saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    390
    391	/* clear clock gate */
    392	__raw_writel(BM_SAIF_CTRL_CLKGATE,
    393		saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    394
    395	ret = clk_prepare(saif->clk);
    396	if (ret)
    397		return ret;
    398
    399	return 0;
    400}
    401
    402static void mxs_saif_shutdown(struct snd_pcm_substream *substream,
    403			      struct snd_soc_dai *cpu_dai)
    404{
    405	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    406
    407	clk_unprepare(saif->clk);
    408}
    409
    410/*
    411 * Should only be called when port is inactive.
    412 * although can be called multiple times by upper layers.
    413 */
    414static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
    415			     struct snd_pcm_hw_params *params,
    416			     struct snd_soc_dai *cpu_dai)
    417{
    418	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    419	struct mxs_saif *master_saif;
    420	u32 scr, stat;
    421	int ret;
    422
    423	master_saif = mxs_saif_get_master(saif);
    424	if (!master_saif)
    425		return -EINVAL;
    426
    427	/* mclk should already be set */
    428	if (!saif->mclk && saif->mclk_in_use) {
    429		dev_err(cpu_dai->dev, "set mclk first\n");
    430		return -EINVAL;
    431	}
    432
    433	stat = __raw_readl(saif->base + SAIF_STAT);
    434	if (!saif->mclk_in_use && (stat & BM_SAIF_STAT_BUSY)) {
    435		dev_err(cpu_dai->dev, "error: busy\n");
    436		return -EBUSY;
    437	}
    438
    439	/*
    440	 * Set saif clk based on sample rate.
    441	 * If mclk is used, we also set mclk, if not, saif->mclk is
    442	 * default 0, means not used.
    443	 */
    444	ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
    445	if (ret) {
    446		dev_err(cpu_dai->dev, "unable to get proper clk\n");
    447		return ret;
    448	}
    449
    450	if (saif != master_saif) {
    451		/*
    452		* Set an initial clock rate for the saif internal logic to work
    453		* properly. This is important when working in EXTMASTER mode
    454		* that uses the other saif's BITCLK&LRCLK but it still needs a
    455		* basic clock which should be fast enough for the internal
    456		* logic.
    457		*/
    458		ret = clk_enable(saif->clk);
    459		if (ret)
    460			return ret;
    461
    462		ret = clk_set_rate(saif->clk, 24000000);
    463		clk_disable(saif->clk);
    464		if (ret)
    465			return ret;
    466
    467		ret = clk_prepare(master_saif->clk);
    468		if (ret)
    469			return ret;
    470	}
    471
    472	scr = __raw_readl(saif->base + SAIF_CTRL);
    473
    474	scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
    475	scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
    476	switch (params_format(params)) {
    477	case SNDRV_PCM_FORMAT_S16_LE:
    478		scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
    479		break;
    480	case SNDRV_PCM_FORMAT_S20_3LE:
    481		scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
    482		scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
    483		break;
    484	case SNDRV_PCM_FORMAT_S24_LE:
    485		scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
    486		scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
    487		break;
    488	default:
    489		return -EINVAL;
    490	}
    491
    492	/* Tx/Rx config */
    493	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    494		/* enable TX mode */
    495		scr &= ~BM_SAIF_CTRL_READ_MODE;
    496	} else {
    497		/* enable RX mode */
    498		scr |= BM_SAIF_CTRL_READ_MODE;
    499	}
    500
    501	__raw_writel(scr, saif->base + SAIF_CTRL);
    502	return 0;
    503}
    504
    505static int mxs_saif_prepare(struct snd_pcm_substream *substream,
    506			   struct snd_soc_dai *cpu_dai)
    507{
    508	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    509
    510	/* enable FIFO error irqs */
    511	__raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
    512		saif->base + SAIF_CTRL + MXS_SET_ADDR);
    513
    514	return 0;
    515}
    516
    517static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
    518				struct snd_soc_dai *cpu_dai)
    519{
    520	struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
    521	struct mxs_saif *master_saif;
    522	u32 delay;
    523	int ret;
    524
    525	master_saif = mxs_saif_get_master(saif);
    526	if (!master_saif)
    527		return -EINVAL;
    528
    529	switch (cmd) {
    530	case SNDRV_PCM_TRIGGER_START:
    531	case SNDRV_PCM_TRIGGER_RESUME:
    532	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
    533		if (saif->state == MXS_SAIF_STATE_RUNNING)
    534			return 0;
    535
    536		dev_dbg(cpu_dai->dev, "start\n");
    537
    538		ret = clk_enable(master_saif->clk);
    539		if (ret) {
    540			dev_err(saif->dev, "Failed to enable master clock\n");
    541			return ret;
    542		}
    543
    544		/*
    545		 * If the saif's master is not itself, we also need to enable
    546		 * itself clk for its internal basic logic to work.
    547		 */
    548		if (saif != master_saif) {
    549			ret = clk_enable(saif->clk);
    550			if (ret) {
    551				dev_err(saif->dev, "Failed to enable master clock\n");
    552				clk_disable(master_saif->clk);
    553				return ret;
    554			}
    555
    556			__raw_writel(BM_SAIF_CTRL_RUN,
    557				saif->base + SAIF_CTRL + MXS_SET_ADDR);
    558		}
    559
    560		if (!master_saif->mclk_in_use)
    561			__raw_writel(BM_SAIF_CTRL_RUN,
    562				master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
    563
    564		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    565			/*
    566			 * write data to saif data register to trigger
    567			 * the transfer.
    568			 * For 24-bit format the 32-bit FIFO register stores
    569			 * only one channel, so we need to write twice.
    570			 * This is also safe for the other non 24-bit formats.
    571			 */
    572			__raw_writel(0, saif->base + SAIF_DATA);
    573			__raw_writel(0, saif->base + SAIF_DATA);
    574		} else {
    575			/*
    576			 * read data from saif data register to trigger
    577			 * the receive.
    578			 * For 24-bit format the 32-bit FIFO register stores
    579			 * only one channel, so we need to read twice.
    580			 * This is also safe for the other non 24-bit formats.
    581			 */
    582			__raw_readl(saif->base + SAIF_DATA);
    583			__raw_readl(saif->base + SAIF_DATA);
    584		}
    585
    586		master_saif->ongoing = 1;
    587		saif->state = MXS_SAIF_STATE_RUNNING;
    588
    589		dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
    590			__raw_readl(saif->base + SAIF_CTRL),
    591			__raw_readl(saif->base + SAIF_STAT));
    592
    593		dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n",
    594			__raw_readl(master_saif->base + SAIF_CTRL),
    595			__raw_readl(master_saif->base + SAIF_STAT));
    596		break;
    597	case SNDRV_PCM_TRIGGER_SUSPEND:
    598	case SNDRV_PCM_TRIGGER_STOP:
    599	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
    600		if (saif->state == MXS_SAIF_STATE_STOPPED)
    601			return 0;
    602
    603		dev_dbg(cpu_dai->dev, "stop\n");
    604
    605		/* wait a while for the current sample to complete */
    606		delay = USEC_PER_SEC / master_saif->cur_rate;
    607
    608		if (!master_saif->mclk_in_use) {
    609			__raw_writel(BM_SAIF_CTRL_RUN,
    610				master_saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    611			udelay(delay);
    612		}
    613		clk_disable(master_saif->clk);
    614
    615		if (saif != master_saif) {
    616			__raw_writel(BM_SAIF_CTRL_RUN,
    617				saif->base + SAIF_CTRL + MXS_CLR_ADDR);
    618			udelay(delay);
    619			clk_disable(saif->clk);
    620		}
    621
    622		master_saif->ongoing = 0;
    623		saif->state = MXS_SAIF_STATE_STOPPED;
    624
    625		break;
    626	default:
    627		return -EINVAL;
    628	}
    629
    630	return 0;
    631}
    632
    633#define MXS_SAIF_RATES		SNDRV_PCM_RATE_8000_192000
    634#define MXS_SAIF_FORMATS \
    635	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
    636	SNDRV_PCM_FMTBIT_S24_LE)
    637
    638static const struct snd_soc_dai_ops mxs_saif_dai_ops = {
    639	.startup = mxs_saif_startup,
    640	.shutdown = mxs_saif_shutdown,
    641	.trigger = mxs_saif_trigger,
    642	.prepare = mxs_saif_prepare,
    643	.hw_params = mxs_saif_hw_params,
    644	.set_sysclk = mxs_saif_set_dai_sysclk,
    645	.set_fmt = mxs_saif_set_dai_fmt,
    646};
    647
    648static struct snd_soc_dai_driver mxs_saif_dai = {
    649	.name = "mxs-saif",
    650	.playback = {
    651		.channels_min = 2,
    652		.channels_max = 2,
    653		.rates = MXS_SAIF_RATES,
    654		.formats = MXS_SAIF_FORMATS,
    655	},
    656	.capture = {
    657		.channels_min = 2,
    658		.channels_max = 2,
    659		.rates = MXS_SAIF_RATES,
    660		.formats = MXS_SAIF_FORMATS,
    661	},
    662	.ops = &mxs_saif_dai_ops,
    663};
    664
    665static const struct snd_soc_component_driver mxs_saif_component = {
    666	.name		= "mxs-saif",
    667};
    668
    669static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
    670{
    671	struct mxs_saif *saif = dev_id;
    672	unsigned int stat;
    673
    674	stat = __raw_readl(saif->base + SAIF_STAT);
    675	if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
    676			BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
    677		return IRQ_NONE;
    678
    679	if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
    680		dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
    681		__raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
    682				saif->base + SAIF_STAT + MXS_CLR_ADDR);
    683	}
    684
    685	if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
    686		dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
    687		__raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
    688				saif->base + SAIF_STAT + MXS_CLR_ADDR);
    689	}
    690
    691	dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
    692	       __raw_readl(saif->base + SAIF_CTRL),
    693	       __raw_readl(saif->base + SAIF_STAT));
    694
    695	return IRQ_HANDLED;
    696}
    697
    698static int mxs_saif_mclk_init(struct platform_device *pdev)
    699{
    700	struct mxs_saif *saif = platform_get_drvdata(pdev);
    701	struct device_node *np = pdev->dev.of_node;
    702	struct clk *clk;
    703	int ret;
    704
    705	clk = clk_register_divider(&pdev->dev, "mxs_saif_mclk",
    706				   __clk_get_name(saif->clk), 0,
    707				   saif->base + SAIF_CTRL,
    708				   BP_SAIF_CTRL_BITCLK_MULT_RATE, 3,
    709				   0, NULL);
    710	if (IS_ERR(clk)) {
    711		ret = PTR_ERR(clk);
    712		if (ret == -EEXIST)
    713			return 0;
    714		dev_err(&pdev->dev, "failed to register mclk: %d\n", ret);
    715		return PTR_ERR(clk);
    716	}
    717
    718	ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
    719	if (ret)
    720		return ret;
    721
    722	return 0;
    723}
    724
    725static int mxs_saif_probe(struct platform_device *pdev)
    726{
    727	struct device_node *np = pdev->dev.of_node;
    728	struct mxs_saif *saif;
    729	int irq, ret;
    730	struct device_node *master;
    731
    732	saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
    733	if (!saif)
    734		return -ENOMEM;
    735
    736	ret = of_alias_get_id(np, "saif");
    737	if (ret < 0)
    738		return ret;
    739	else
    740		saif->id = ret;
    741
    742	if (saif->id >= ARRAY_SIZE(mxs_saif)) {
    743		dev_err(&pdev->dev, "get wrong saif id\n");
    744		return -EINVAL;
    745	}
    746
    747	/*
    748	 * If there is no "fsl,saif-master" phandle, it's a saif
    749	 * master.  Otherwise, it's a slave and its phandle points
    750	 * to the master.
    751	 */
    752	master = of_parse_phandle(np, "fsl,saif-master", 0);
    753	if (!master) {
    754		saif->master_id = saif->id;
    755	} else {
    756		ret = of_alias_get_id(master, "saif");
    757		of_node_put(master);
    758		if (ret < 0)
    759			return ret;
    760		else
    761			saif->master_id = ret;
    762
    763		if (saif->master_id >= ARRAY_SIZE(mxs_saif)) {
    764			dev_err(&pdev->dev, "get wrong master id\n");
    765			return -EINVAL;
    766		}
    767	}
    768
    769	mxs_saif[saif->id] = saif;
    770
    771	saif->clk = devm_clk_get(&pdev->dev, NULL);
    772	if (IS_ERR(saif->clk)) {
    773		ret = PTR_ERR(saif->clk);
    774		dev_err(&pdev->dev, "Cannot get the clock: %d\n",
    775			ret);
    776		return ret;
    777	}
    778
    779	saif->base = devm_platform_ioremap_resource(pdev, 0);
    780	if (IS_ERR(saif->base))
    781		return PTR_ERR(saif->base);
    782
    783	irq = platform_get_irq(pdev, 0);
    784	if (irq < 0)
    785		return irq;
    786
    787	saif->dev = &pdev->dev;
    788	ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0,
    789			       dev_name(&pdev->dev), saif);
    790	if (ret) {
    791		dev_err(&pdev->dev, "failed to request irq\n");
    792		return ret;
    793	}
    794
    795	platform_set_drvdata(pdev, saif);
    796
    797	/* We only support saif0 being tx and clock master */
    798	if (saif->id == 0) {
    799		ret = mxs_saif_mclk_init(pdev);
    800		if (ret)
    801			dev_warn(&pdev->dev, "failed to init clocks\n");
    802	}
    803
    804	ret = devm_snd_soc_register_component(&pdev->dev, &mxs_saif_component,
    805					      &mxs_saif_dai, 1);
    806	if (ret) {
    807		dev_err(&pdev->dev, "register DAI failed\n");
    808		return ret;
    809	}
    810
    811	ret = mxs_pcm_platform_register(&pdev->dev);
    812	if (ret) {
    813		dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
    814		return ret;
    815	}
    816
    817	return 0;
    818}
    819
    820static const struct of_device_id mxs_saif_dt_ids[] = {
    821	{ .compatible = "fsl,imx28-saif", },
    822	{ /* sentinel */ }
    823};
    824MODULE_DEVICE_TABLE(of, mxs_saif_dt_ids);
    825
    826static struct platform_driver mxs_saif_driver = {
    827	.probe = mxs_saif_probe,
    828
    829	.driver = {
    830		.name = "mxs-saif",
    831		.of_match_table = mxs_saif_dt_ids,
    832	},
    833};
    834
    835module_platform_driver(mxs_saif_driver);
    836
    837MODULE_AUTHOR("Freescale Semiconductor, Inc.");
    838MODULE_DESCRIPTION("MXS ASoC SAIF driver");
    839MODULE_LICENSE("GPL");
    840MODULE_ALIAS("platform:mxs-saif");