brintos

brintos / linux-shallow public Read only

0
0
Text · 22.9 KiB · 3763454 Raw
921 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * atmel_ssc_dai.c  --  ALSA SoC ATMEL SSC Audio Layer Platform driver4 *5 * Copyright (C) 2005 SAN People6 * Copyright (C) 2008 Atmel7 *8 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>9 *         ATMEL CORP.10 *11 * Based on at91-ssc.c by12 * Frank Mandarino <fmandarino@endrelia.com>13 * Based on pxa2xx Platform drivers by14 * Liam Girdwood <lrg@slimlogic.co.uk>15 */16 17#include <linux/init.h>18#include <linux/module.h>19#include <linux/interrupt.h>20#include <linux/device.h>21#include <linux/delay.h>22#include <linux/clk.h>23#include <linux/atmel_pdc.h>24 25#include <linux/atmel-ssc.h>26#include <sound/core.h>27#include <sound/pcm.h>28#include <sound/pcm_params.h>29#include <sound/initval.h>30#include <sound/soc.h>31 32#include "atmel-pcm.h"33#include "atmel_ssc_dai.h"34 35 36#define NUM_SSC_DEVICES		337 38/*39 * SSC PDC registers required by the PCM DMA engine.40 */41static struct atmel_pdc_regs pdc_tx_reg = {42	.xpr		= ATMEL_PDC_TPR,43	.xcr		= ATMEL_PDC_TCR,44	.xnpr		= ATMEL_PDC_TNPR,45	.xncr		= ATMEL_PDC_TNCR,46};47 48static struct atmel_pdc_regs pdc_rx_reg = {49	.xpr		= ATMEL_PDC_RPR,50	.xcr		= ATMEL_PDC_RCR,51	.xnpr		= ATMEL_PDC_RNPR,52	.xncr		= ATMEL_PDC_RNCR,53};54 55/*56 * SSC & PDC status bits for transmit and receive.57 */58static struct atmel_ssc_mask ssc_tx_mask = {59	.ssc_enable	= SSC_BIT(CR_TXEN),60	.ssc_disable	= SSC_BIT(CR_TXDIS),61	.ssc_endx	= SSC_BIT(SR_ENDTX),62	.ssc_endbuf	= SSC_BIT(SR_TXBUFE),63	.ssc_error	= SSC_BIT(SR_OVRUN),64	.pdc_enable	= ATMEL_PDC_TXTEN,65	.pdc_disable	= ATMEL_PDC_TXTDIS,66};67 68static struct atmel_ssc_mask ssc_rx_mask = {69	.ssc_enable	= SSC_BIT(CR_RXEN),70	.ssc_disable	= SSC_BIT(CR_RXDIS),71	.ssc_endx	= SSC_BIT(SR_ENDRX),72	.ssc_endbuf	= SSC_BIT(SR_RXBUFF),73	.ssc_error	= SSC_BIT(SR_OVRUN),74	.pdc_enable	= ATMEL_PDC_RXTEN,75	.pdc_disable	= ATMEL_PDC_RXTDIS,76};77 78 79/*80 * DMA parameters.81 */82static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {83	{{84	.name		= "SSC0 PCM out",85	.pdc		= &pdc_tx_reg,86	.mask		= &ssc_tx_mask,87	},88	{89	.name		= "SSC0 PCM in",90	.pdc		= &pdc_rx_reg,91	.mask		= &ssc_rx_mask,92	} },93	{{94	.name		= "SSC1 PCM out",95	.pdc		= &pdc_tx_reg,96	.mask		= &ssc_tx_mask,97	},98	{99	.name		= "SSC1 PCM in",100	.pdc		= &pdc_rx_reg,101	.mask		= &ssc_rx_mask,102	} },103	{{104	.name		= "SSC2 PCM out",105	.pdc		= &pdc_tx_reg,106	.mask		= &ssc_tx_mask,107	},108	{109	.name		= "SSC2 PCM in",110	.pdc		= &pdc_rx_reg,111	.mask		= &ssc_rx_mask,112	} },113};114 115 116static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {117	{118	.name		= "ssc0",119	.dir_mask	= SSC_DIR_MASK_UNUSED,120	.initialized	= 0,121	},122	{123	.name		= "ssc1",124	.dir_mask	= SSC_DIR_MASK_UNUSED,125	.initialized	= 0,126	},127	{128	.name		= "ssc2",129	.dir_mask	= SSC_DIR_MASK_UNUSED,130	.initialized	= 0,131	},132};133 134 135/*136 * SSC interrupt handler.  Passes PDC interrupts to the DMA137 * interrupt handler in the PCM driver.138 */139static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)140{141	struct atmel_ssc_info *ssc_p = dev_id;142	struct atmel_pcm_dma_params *dma_params;143	u32 ssc_sr;144	u32 ssc_substream_mask;145	int i;146 147	ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)148			& (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);149 150	/*151	 * Loop through the substreams attached to this SSC.  If152	 * a DMA-related interrupt occurred on that substream, call153	 * the DMA interrupt handler function, if one has been154	 * registered in the dma_params structure by the PCM driver.155	 */156	for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {157		dma_params = ssc_p->dma_params[i];158 159		if ((dma_params != NULL) &&160			(dma_params->dma_intr_handler != NULL)) {161			ssc_substream_mask = (dma_params->mask->ssc_endx |162					dma_params->mask->ssc_endbuf);163			if (ssc_sr & ssc_substream_mask) {164				dma_params->dma_intr_handler(ssc_sr,165						dma_params->166						substream);167			}168		}169	}170 171	return IRQ_HANDLED;172}173 174/*175 * When the bit clock is input, limit the maximum rate according to the176 * Serial Clock Ratio Considerations section from the SSC documentation:177 *178 *   The Transmitter and the Receiver can be programmed to operate179 *   with the clock signals provided on either the TK or RK pins.180 *   This allows the SSC to support many slave-mode data transfers.181 *   In this case, the maximum clock speed allowed on the RK pin is:182 *   - Peripheral clock divided by 2 if Receiver Frame Synchro is input183 *   - Peripheral clock divided by 3 if Receiver Frame Synchro is output184 *   In addition, the maximum clock speed allowed on the TK pin is:185 *   - Peripheral clock divided by 6 if Transmit Frame Synchro is input186 *   - Peripheral clock divided by 2 if Transmit Frame Synchro is output187 *188 * When the bit clock is output, limit the rate according to the189 * SSC divider restrictions.190 */191static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,192				  struct snd_pcm_hw_rule *rule)193{194	struct atmel_ssc_info *ssc_p = rule->private;195	struct ssc_device *ssc = ssc_p->ssc;196	struct snd_interval *i = hw_param_interval(params, rule->var);197	struct snd_interval t;198	struct snd_ratnum r = {199		.den_min = 1,200		.den_max = 4095,201		.den_step = 1,202	};203	unsigned int num = 0, den = 0;204	int frame_size;205	int mck_div = 2;206	int ret;207 208	frame_size = snd_soc_params_to_frame_size(params);209	if (frame_size < 0)210		return frame_size;211 212	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {213	case SND_SOC_DAIFMT_BC_FP:214		if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE)215		    && ssc->clk_from_rk_pin)216			/* Receiver Frame Synchro (i.e. capture)217			 * is output (format is _CFS) and the RK pin218			 * is used for input (format is _CBM_).219			 */220			mck_div = 3;221		break;222 223	case SND_SOC_DAIFMT_BC_FC:224		if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK)225		    && !ssc->clk_from_rk_pin)226			/* Transmit Frame Synchro (i.e. playback)227			 * is input (format is _CFM) and the TK pin228			 * is used for input (format _CBM_ but not229			 * using the RK pin).230			 */231			mck_div = 6;232		break;233	}234 235	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {236	case SND_SOC_DAIFMT_BP_FP:237		r.num = ssc_p->mck_rate / mck_div / frame_size;238 239		ret = snd_interval_ratnum(i, 1, &r, &num, &den);240		if (ret >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {241			params->rate_num = num;242			params->rate_den = den;243		}244		break;245 246	case SND_SOC_DAIFMT_BC_FP:247	case SND_SOC_DAIFMT_BC_FC:248		t.min = 8000;249		t.max = ssc_p->mck_rate / mck_div / frame_size;250		t.openmin = t.openmax = 0;251		t.integer = 0;252		ret = snd_interval_refine(i, &t);253		break;254 255	default:256		ret = -EINVAL;257		break;258	}259 260	return ret;261}262 263/*-------------------------------------------------------------------------*\264 * DAI functions265\*-------------------------------------------------------------------------*/266/*267 * Startup.  Only that one substream allowed in each direction.268 */269static int atmel_ssc_startup(struct snd_pcm_substream *substream,270			     struct snd_soc_dai *dai)271{272	struct platform_device *pdev = to_platform_device(dai->dev);273	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];274	struct atmel_pcm_dma_params *dma_params;275	int dir, dir_mask;276	int ret;277 278	pr_debug("atmel_ssc_startup: SSC_SR=0x%x\n",279		ssc_readl(ssc_p->ssc->regs, SR));280 281	/* Enable PMC peripheral clock for this SSC */282	pr_debug("atmel_ssc_dai: Starting clock\n");283	ret = clk_enable(ssc_p->ssc->clk);284	if (ret)285		return ret;286 287	ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);288 289	/* Reset the SSC unless initialized to keep it in a clean state */290	if (!ssc_p->initialized)291		ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));292 293	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {294		dir = 0;295		dir_mask = SSC_DIR_MASK_PLAYBACK;296	} else {297		dir = 1;298		dir_mask = SSC_DIR_MASK_CAPTURE;299	}300 301	ret = snd_pcm_hw_rule_add(substream->runtime, 0,302				  SNDRV_PCM_HW_PARAM_RATE,303				  atmel_ssc_hw_rule_rate,304				  ssc_p,305				  SNDRV_PCM_HW_PARAM_FRAME_BITS,306				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);307	if (ret < 0) {308		dev_err(dai->dev, "Failed to specify rate rule: %d\n", ret);309		return ret;310	}311 312	dma_params = &ssc_dma_params[pdev->id][dir];313	dma_params->ssc = ssc_p->ssc;314	dma_params->substream = substream;315 316	ssc_p->dma_params[dir] = dma_params;317 318	snd_soc_dai_set_dma_data(dai, substream, dma_params);319 320	if (ssc_p->dir_mask & dir_mask)321		return -EBUSY;322 323	ssc_p->dir_mask |= dir_mask;324 325	return 0;326}327 328/*329 * Shutdown.  Clear DMA parameters and shutdown the SSC if there330 * are no other substreams open.331 */332static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,333			       struct snd_soc_dai *dai)334{335	struct platform_device *pdev = to_platform_device(dai->dev);336	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];337	struct atmel_pcm_dma_params *dma_params;338	int dir, dir_mask;339 340	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)341		dir = 0;342	else343		dir = 1;344 345	dma_params = ssc_p->dma_params[dir];346 347	if (dma_params != NULL) {348		dma_params->ssc = NULL;349		dma_params->substream = NULL;350		ssc_p->dma_params[dir] = NULL;351	}352 353	dir_mask = 1 << dir;354 355	ssc_p->dir_mask &= ~dir_mask;356	if (!ssc_p->dir_mask) {357		if (ssc_p->initialized) {358			free_irq(ssc_p->ssc->irq, ssc_p);359			ssc_p->initialized = 0;360		}361 362		/* Reset the SSC */363		ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));364		/* Clear the SSC dividers */365		ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;366		ssc_p->forced_divider = 0;367	}368 369	/* Shutdown the SSC clock. */370	pr_debug("atmel_ssc_dai: Stopping clock\n");371	clk_disable(ssc_p->ssc->clk);372}373 374 375/*376 * Record the DAI format for use in hw_params().377 */378static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,379		unsigned int fmt)380{381	struct platform_device *pdev = to_platform_device(cpu_dai->dev);382	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];383 384	ssc_p->daifmt = fmt;385	return 0;386}387 388/*389 * Record SSC clock dividers for use in hw_params().390 */391static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,392	int div_id, int div)393{394	struct platform_device *pdev = to_platform_device(cpu_dai->dev);395	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];396 397	switch (div_id) {398	case ATMEL_SSC_CMR_DIV:399		/*400		 * The same master clock divider is used for both401		 * transmit and receive, so if a value has already402		 * been set, it must match this value.403		 */404		if (ssc_p->dir_mask !=405			(SSC_DIR_MASK_PLAYBACK | SSC_DIR_MASK_CAPTURE))406			ssc_p->cmr_div = div;407		else if (ssc_p->cmr_div == 0)408			ssc_p->cmr_div = div;409		else410			if (div != ssc_p->cmr_div)411				return -EBUSY;412		ssc_p->forced_divider |= BIT(ATMEL_SSC_CMR_DIV);413		break;414 415	case ATMEL_SSC_TCMR_PERIOD:416		ssc_p->tcmr_period = div;417		ssc_p->forced_divider |= BIT(ATMEL_SSC_TCMR_PERIOD);418		break;419 420	case ATMEL_SSC_RCMR_PERIOD:421		ssc_p->rcmr_period = div;422		ssc_p->forced_divider |= BIT(ATMEL_SSC_RCMR_PERIOD);423		break;424 425	default:426		return -EINVAL;427	}428 429	return 0;430}431 432/* Is the cpu-dai master of the frame clock? */433static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p)434{435	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {436	case SND_SOC_DAIFMT_BC_FP:437	case SND_SOC_DAIFMT_BP_FP:438		return 1;439	}440	return 0;441}442 443/* Is the cpu-dai master of the bit clock? */444static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p)445{446	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {447	case SND_SOC_DAIFMT_BP_FC:448	case SND_SOC_DAIFMT_BP_FP:449		return 1;450	}451	return 0;452}453 454/*455 * Configure the SSC.456 */457static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,458	struct snd_pcm_hw_params *params,459	struct snd_soc_dai *dai)460{461	struct platform_device *pdev = to_platform_device(dai->dev);462	int id = pdev->id;463	struct atmel_ssc_info *ssc_p = &ssc_info[id];464	struct ssc_device *ssc = ssc_p->ssc;465	struct atmel_pcm_dma_params *dma_params;466	int dir, channels, bits;467	u32 tfmr, rfmr, tcmr, rcmr;468	int ret;469	int fslen, fslen_ext, fs_osync, fs_edge;470	u32 cmr_div;471	u32 tcmr_period;472	u32 rcmr_period;473 474	/*475	 * Currently, there is only one set of dma params for476	 * each direction.  If more are added, this code will477	 * have to be changed to select the proper set.478	 */479	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)480		dir = 0;481	else482		dir = 1;483 484	/*485	 * If the cpu dai should provide BCLK, but noone has provided the486	 * divider needed for that to work, fall back to something sensible.487	 */488	cmr_div = ssc_p->cmr_div;489	if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_CMR_DIV)) &&490	    atmel_ssc_cbs(ssc_p)) {491		int bclk_rate = snd_soc_params_to_bclk(params);492 493		if (bclk_rate < 0) {494			dev_err(dai->dev, "unable to calculate cmr_div: %d\n",495				bclk_rate);496			return bclk_rate;497		}498 499		cmr_div = DIV_ROUND_CLOSEST(ssc_p->mck_rate, 2 * bclk_rate);500	}501 502	/*503	 * If the cpu dai should provide LRCLK, but noone has provided the504	 * dividers needed for that to work, fall back to something sensible.505	 */506	tcmr_period = ssc_p->tcmr_period;507	rcmr_period = ssc_p->rcmr_period;508	if (atmel_ssc_cfs(ssc_p)) {509		int frame_size = snd_soc_params_to_frame_size(params);510 511		if (frame_size < 0) {512			dev_err(dai->dev,513				"unable to calculate tx/rx cmr_period: %d\n",514				frame_size);515			return frame_size;516		}517 518		if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_TCMR_PERIOD)))519			tcmr_period = frame_size / 2 - 1;520		if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_RCMR_PERIOD)))521			rcmr_period = frame_size / 2 - 1;522	}523 524	dma_params = ssc_p->dma_params[dir];525 526	channels = params_channels(params);527 528	/*529	 * Determine sample size in bits and the PDC increment.530	 */531	switch (params_format(params)) {532	case SNDRV_PCM_FORMAT_S8:533		bits = 8;534		dma_params->pdc_xfer_size = 1;535		break;536	case SNDRV_PCM_FORMAT_S16_LE:537		bits = 16;538		dma_params->pdc_xfer_size = 2;539		break;540	case SNDRV_PCM_FORMAT_S24_LE:541		bits = 24;542		dma_params->pdc_xfer_size = 4;543		break;544	case SNDRV_PCM_FORMAT_S32_LE:545		bits = 32;546		dma_params->pdc_xfer_size = 4;547		break;548	default:549		printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");550		return -EINVAL;551	}552 553	/*554	 * Compute SSC register settings.555	 */556 557	fslen_ext = (bits - 1) / 16;558	fslen = (bits - 1) % 16;559 560	switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {561 562	case SND_SOC_DAIFMT_LEFT_J:563		fs_osync = SSC_FSOS_POSITIVE;564		fs_edge = SSC_START_RISING_RF;565 566		rcmr =	  SSC_BF(RCMR_STTDLY, 0);567		tcmr =	  SSC_BF(TCMR_STTDLY, 0);568 569		break;570 571	case SND_SOC_DAIFMT_I2S:572		fs_osync = SSC_FSOS_NEGATIVE;573		fs_edge = SSC_START_FALLING_RF;574 575		rcmr =	  SSC_BF(RCMR_STTDLY, 1);576		tcmr =	  SSC_BF(TCMR_STTDLY, 1);577 578		break;579 580	case SND_SOC_DAIFMT_DSP_A:581		/*582		 * DSP/PCM Mode A format583		 *584		 * Data is transferred on first BCLK after LRC pulse rising585		 * edge.If stereo, the right channel data is contiguous with586		 * the left channel data.587		 */588		fs_osync = SSC_FSOS_POSITIVE;589		fs_edge = SSC_START_RISING_RF;590		fslen = fslen_ext = 0;591 592		rcmr =	  SSC_BF(RCMR_STTDLY, 1);593		tcmr =	  SSC_BF(TCMR_STTDLY, 1);594 595		break;596 597	default:598		printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",599			ssc_p->daifmt);600		return -EINVAL;601	}602 603	if (!atmel_ssc_cfs(ssc_p)) {604		fslen = fslen_ext = 0;605		rcmr_period = tcmr_period = 0;606		fs_osync = SSC_FSOS_NONE;607	}608 609	rcmr |=	  SSC_BF(RCMR_START, fs_edge);610	tcmr |=	  SSC_BF(TCMR_START, fs_edge);611 612	if (atmel_ssc_cbs(ssc_p)) {613		/*614		 * SSC provides BCLK615		 *616		 * The SSC transmit and receive clocks are generated from the617		 * MCK divider, and the BCLK signal is output618		 * on the SSC TK line.619		 */620		rcmr |=	  SSC_BF(RCMR_CKS, SSC_CKS_DIV)621			| SSC_BF(RCMR_CKO, SSC_CKO_NONE);622 623		tcmr |=	  SSC_BF(TCMR_CKS, SSC_CKS_DIV)624			| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS);625	} else {626		rcmr |=	  SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?627					SSC_CKS_PIN : SSC_CKS_CLOCK)628			| SSC_BF(RCMR_CKO, SSC_CKO_NONE);629 630		tcmr |=	  SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?631					SSC_CKS_CLOCK : SSC_CKS_PIN)632			| SSC_BF(TCMR_CKO, SSC_CKO_NONE);633	}634 635	rcmr |=	  SSC_BF(RCMR_PERIOD, rcmr_period)636		| SSC_BF(RCMR_CKI, SSC_CKI_RISING);637 638	tcmr |=   SSC_BF(TCMR_PERIOD, tcmr_period)639		| SSC_BF(TCMR_CKI, SSC_CKI_FALLING);640 641	rfmr =    SSC_BF(RFMR_FSLEN_EXT, fslen_ext)642		| SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)643		| SSC_BF(RFMR_FSOS, fs_osync)644		| SSC_BF(RFMR_FSLEN, fslen)645		| SSC_BF(RFMR_DATNB, (channels - 1))646		| SSC_BIT(RFMR_MSBF)647		| SSC_BF(RFMR_LOOP, 0)648		| SSC_BF(RFMR_DATLEN, (bits - 1));649 650	tfmr =    SSC_BF(TFMR_FSLEN_EXT, fslen_ext)651		| SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)652		| SSC_BF(TFMR_FSDEN, 0)653		| SSC_BF(TFMR_FSOS, fs_osync)654		| SSC_BF(TFMR_FSLEN, fslen)655		| SSC_BF(TFMR_DATNB, (channels - 1))656		| SSC_BIT(TFMR_MSBF)657		| SSC_BF(TFMR_DATDEF, 0)658		| SSC_BF(TFMR_DATLEN, (bits - 1));659 660	if (fslen_ext && !ssc->pdata->has_fslen_ext) {661		dev_err(dai->dev, "sample size %d is too large for SSC device\n",662			bits);663		return -EINVAL;664	}665 666	pr_debug("atmel_ssc_hw_params: "667			"RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",668			rcmr, rfmr, tcmr, tfmr);669 670	if (!ssc_p->initialized) {671		if (!ssc_p->ssc->pdata->use_dma) {672			ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);673			ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);674			ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);675			ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);676 677			ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);678			ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);679			ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);680			ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);681		}682 683		ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,684				ssc_p->name, ssc_p);685		if (ret < 0) {686			printk(KERN_WARNING687					"atmel_ssc_dai: request_irq failure\n");688			pr_debug("Atmel_ssc_dai: Stopping clock\n");689			clk_disable(ssc_p->ssc->clk);690			return ret;691		}692 693		ssc_p->initialized = 1;694	}695 696	/* set SSC clock mode register */697	ssc_writel(ssc_p->ssc->regs, CMR, cmr_div);698 699	/* set receive clock mode and format */700	ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);701	ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);702 703	/* set transmit clock mode and format */704	ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);705	ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);706 707	pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");708	return 0;709}710 711 712static int atmel_ssc_prepare(struct snd_pcm_substream *substream,713			     struct snd_soc_dai *dai)714{715	struct platform_device *pdev = to_platform_device(dai->dev);716	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];717	struct atmel_pcm_dma_params *dma_params;718	int dir;719 720	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)721		dir = 0;722	else723		dir = 1;724 725	dma_params = ssc_p->dma_params[dir];726 727	ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);728	ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);729 730	pr_debug("%s enabled SSC_SR=0x%08x\n",731			dir ? "receive" : "transmit",732			ssc_readl(ssc_p->ssc->regs, SR));733	return 0;734}735 736static int atmel_ssc_trigger(struct snd_pcm_substream *substream,737			     int cmd, struct snd_soc_dai *dai)738{739	struct platform_device *pdev = to_platform_device(dai->dev);740	struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];741	struct atmel_pcm_dma_params *dma_params;742	int dir;743 744	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)745		dir = 0;746	else747		dir = 1;748 749	dma_params = ssc_p->dma_params[dir];750 751	switch (cmd) {752	case SNDRV_PCM_TRIGGER_START:753	case SNDRV_PCM_TRIGGER_RESUME:754	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:755		ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);756		break;757	default:758		ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);759		break;760	}761 762	return 0;763}764 765static int atmel_ssc_suspend(struct snd_soc_component *component)766{767	struct atmel_ssc_info *ssc_p;768	struct platform_device *pdev = to_platform_device(component->dev);769 770	if (!snd_soc_component_active(component))771		return 0;772 773	ssc_p = &ssc_info[pdev->id];774 775	/* Save the status register before disabling transmit and receive */776	ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);777	ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));778 779	/* Save the current interrupt mask, then disable unmasked interrupts */780	ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);781	ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);782 783	ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);784	ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);785	ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);786	ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);787	ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);788 789	return 0;790}791 792static int atmel_ssc_resume(struct snd_soc_component *component)793{794	struct atmel_ssc_info *ssc_p;795	struct platform_device *pdev = to_platform_device(component->dev);796	u32 cr;797 798	if (!snd_soc_component_active(component))799		return 0;800 801	ssc_p = &ssc_info[pdev->id];802 803	/* restore SSC register settings */804	ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);805	ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);806	ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);807	ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);808	ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);809 810	/* re-enable interrupts */811	ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);812 813	/* Re-enable receive and transmit as appropriate */814	cr = 0;815	cr |=816	    (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;817	cr |=818	    (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;819	ssc_writel(ssc_p->ssc->regs, CR, cr);820 821	return 0;822}823 824#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_LE |\825			  SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)826 827static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {828	.startup	= atmel_ssc_startup,829	.shutdown	= atmel_ssc_shutdown,830	.prepare	= atmel_ssc_prepare,831	.trigger	= atmel_ssc_trigger,832	.hw_params	= atmel_ssc_hw_params,833	.set_fmt	= atmel_ssc_set_dai_fmt,834	.set_clkdiv	= atmel_ssc_set_dai_clkdiv,835};836 837static struct snd_soc_dai_driver atmel_ssc_dai = {838		.playback = {839			.channels_min = 1,840			.channels_max = 2,841			.rates = SNDRV_PCM_RATE_CONTINUOUS,842			.rate_min = 8000,843			.rate_max = 384000,844			.formats = ATMEL_SSC_FORMATS,},845		.capture = {846			.channels_min = 1,847			.channels_max = 2,848			.rates = SNDRV_PCM_RATE_CONTINUOUS,849			.rate_min = 8000,850			.rate_max = 384000,851			.formats = ATMEL_SSC_FORMATS,},852		.ops = &atmel_ssc_dai_ops,853};854 855static const struct snd_soc_component_driver atmel_ssc_component = {856	.name			= "atmel-ssc",857	.suspend		= pm_ptr(atmel_ssc_suspend),858	.resume			= pm_ptr(atmel_ssc_resume),859	.legacy_dai_naming	= 1,860};861 862static int asoc_ssc_init(struct device *dev)863{864	struct ssc_device *ssc = dev_get_drvdata(dev);865	int ret;866 867	ret = devm_snd_soc_register_component(dev, &atmel_ssc_component,868					 &atmel_ssc_dai, 1);869	if (ret) {870		dev_err(dev, "Could not register DAI: %d\n", ret);871		return ret;872	}873 874	if (ssc->pdata->use_dma)875		ret = atmel_pcm_dma_platform_register(dev);876	else877		ret = atmel_pcm_pdc_platform_register(dev);878 879	if (ret) {880		dev_err(dev, "Could not register PCM: %d\n", ret);881		return ret;882	}883 884	return 0;885}886 887/**888 * atmel_ssc_set_audio - Allocate the specified SSC for audio use.889 * @ssc_id: SSD ID in [0, NUM_SSC_DEVICES[890 */891int atmel_ssc_set_audio(int ssc_id)892{893	struct ssc_device *ssc;894 895	/* If we can grab the SSC briefly to parent the DAI device off it */896	ssc = ssc_request(ssc_id);897	if (IS_ERR(ssc)) {898		pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",899			PTR_ERR(ssc));900		return PTR_ERR(ssc);901	} else {902		ssc_info[ssc_id].ssc = ssc;903	}904 905	return asoc_ssc_init(&ssc->pdev->dev);906}907EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);908 909void atmel_ssc_put_audio(int ssc_id)910{911	struct ssc_device *ssc = ssc_info[ssc_id].ssc;912 913	ssc_free(ssc);914}915EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);916 917/* Module information */918MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");919MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");920MODULE_LICENSE("GPL");921