xref: /linux/sound/soc/atmel/atmel-i2s.c (revision 39175acd699ae73abd855748e05fb117dcc05a1f)
1caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b543e467SCyrille Pitchen /*
3b543e467SCyrille Pitchen  * Driver for Atmel I2S controller
4b543e467SCyrille Pitchen  *
5b543e467SCyrille Pitchen  * Copyright (C) 2015 Atmel Corporation
6b543e467SCyrille Pitchen  *
7b543e467SCyrille Pitchen  * Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
8b543e467SCyrille Pitchen  */
9b543e467SCyrille Pitchen 
10b543e467SCyrille Pitchen #include <linux/init.h>
11b543e467SCyrille Pitchen #include <linux/module.h>
12b543e467SCyrille Pitchen #include <linux/device.h>
13b543e467SCyrille Pitchen #include <linux/slab.h>
14b543e467SCyrille Pitchen #include <linux/delay.h>
15b543e467SCyrille Pitchen #include <linux/io.h>
16b543e467SCyrille Pitchen #include <linux/clk.h>
17b543e467SCyrille Pitchen #include <linux/mfd/syscon.h>
18b543e467SCyrille Pitchen 
19b543e467SCyrille Pitchen #include <sound/core.h>
20b543e467SCyrille Pitchen #include <sound/pcm.h>
21b543e467SCyrille Pitchen #include <sound/pcm_params.h>
22b543e467SCyrille Pitchen #include <sound/initval.h>
23b543e467SCyrille Pitchen #include <sound/soc.h>
24b543e467SCyrille Pitchen #include <sound/dmaengine_pcm.h>
25b543e467SCyrille Pitchen 
26b543e467SCyrille Pitchen #define ATMEL_I2SC_MAX_TDM_CHANNELS	8
27b543e467SCyrille Pitchen 
28b543e467SCyrille Pitchen /*
29b543e467SCyrille Pitchen  * ---- I2S Controller Register map ----
30b543e467SCyrille Pitchen  */
31b543e467SCyrille Pitchen #define ATMEL_I2SC_CR		0x0000	/* Control Register */
32b543e467SCyrille Pitchen #define ATMEL_I2SC_MR		0x0004	/* Mode Register */
33b543e467SCyrille Pitchen #define ATMEL_I2SC_SR		0x0008	/* Status Register */
34b543e467SCyrille Pitchen #define ATMEL_I2SC_SCR		0x000c	/* Status Clear Register */
35b543e467SCyrille Pitchen #define ATMEL_I2SC_SSR		0x0010	/* Status Set Register */
36b543e467SCyrille Pitchen #define ATMEL_I2SC_IER		0x0014	/* Interrupt Enable Register */
37b543e467SCyrille Pitchen #define ATMEL_I2SC_IDR		0x0018	/* Interrupt Disable Register */
38b543e467SCyrille Pitchen #define ATMEL_I2SC_IMR		0x001c	/* Interrupt Mask Register */
39b543e467SCyrille Pitchen #define ATMEL_I2SC_RHR		0x0020	/* Receiver Holding Register */
40b543e467SCyrille Pitchen #define ATMEL_I2SC_THR		0x0024	/* Transmitter Holding Register */
41b543e467SCyrille Pitchen #define ATMEL_I2SC_VERSION	0x0028	/* Version Register */
42b543e467SCyrille Pitchen 
43b543e467SCyrille Pitchen /*
44b543e467SCyrille Pitchen  * ---- Control Register (Write-only) ----
45b543e467SCyrille Pitchen  */
46b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_RXEN	BIT(0)	/* Receiver Enable */
47b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_RXDIS	BIT(1)	/* Receiver Disable */
48b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_CKEN	BIT(2)	/* Clock Enable */
49b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_CKDIS	BIT(3)	/* Clock Disable */
50b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_TXEN	BIT(4)	/* Transmitter Enable */
51b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_TXDIS	BIT(5)	/* Transmitter Disable */
52b543e467SCyrille Pitchen #define ATMEL_I2SC_CR_SWRST	BIT(7)	/* Software Reset */
53b543e467SCyrille Pitchen 
54b543e467SCyrille Pitchen /*
55b543e467SCyrille Pitchen  * ---- Mode Register (Read/Write) ----
56b543e467SCyrille Pitchen  */
57b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_MODE_MASK		GENMASK(0, 0)
58b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_MODE_SLAVE	(0 << 0)
59b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_MODE_MASTER	(1 << 0)
60b543e467SCyrille Pitchen 
61b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_MASK		GENMASK(4, 2)
62b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_32_BITS	(0 << 2)
63b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_24_BITS	(1 << 2)
64b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_20_BITS	(2 << 2)
65b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_18_BITS	(3 << 2)
66b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_16_BITS	(4 << 2)
67b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_16_BITS_COMPACT	(5 << 2)
68b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_8_BITS		(6 << 2)
69b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_DATALENGTH_8_BITS_COMPACT	(7 << 2)
70b543e467SCyrille Pitchen 
71b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_FORMAT_MASK	GENMASK(7, 6)
72b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_FORMAT_I2S	(0 << 6)
73b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_FORMAT_LJ		(1 << 6)  /* Left Justified */
74b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_FORMAT_TDM	(2 << 6)
75b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_FORMAT_TDMLJ	(3 << 6)
76b543e467SCyrille Pitchen 
77b543e467SCyrille Pitchen /* Left audio samples duplicated to right audio channel */
78b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_RXMONO		BIT(8)
79b543e467SCyrille Pitchen 
80b543e467SCyrille Pitchen /* Receiver uses one DMA channel ... */
81b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_RXDMA_MASK	GENMASK(9, 9)
82b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_RXDMA_SINGLE	(0 << 9)  /* for all audio channels */
83b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_RXDMA_MULTIPLE	(1 << 9)  /* per audio channel */
84b543e467SCyrille Pitchen 
85b543e467SCyrille Pitchen /* I2SDO output of I2SC is internally connected to I2SDI input */
86b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_RXLOOP		BIT(10)
87b543e467SCyrille Pitchen 
88b543e467SCyrille Pitchen /* Left audio samples duplicated to right audio channel */
89b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXMONO		BIT(12)
90b543e467SCyrille Pitchen 
91b543e467SCyrille Pitchen /* Transmitter uses one DMA channel ... */
92b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXDMA_MASK	GENMASK(13, 13)
93b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXDMA_SINGLE	(0 << 13)  /* for all audio channels */
94b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXDME_MULTIPLE	(1 << 13)  /* per audio channel */
95b543e467SCyrille Pitchen 
96b543e467SCyrille Pitchen /* x sample transmitted when underrun */
97b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXSAME_MASK	GENMASK(14, 14)
98b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXSAME_ZERO	(0 << 14)  /* Zero sample */
99b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_TXSAME_PREVIOUS	(1 << 14)  /* Previous sample */
100b543e467SCyrille Pitchen 
101b543e467SCyrille Pitchen /* Audio Clock to I2SC Master Clock ratio */
102b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKDIV_MASK	GENMASK(21, 16)
103b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKDIV(div) \
104b543e467SCyrille Pitchen 	(((div) << 16) & ATMEL_I2SC_MR_IMCKDIV_MASK)
105b543e467SCyrille Pitchen 
106b543e467SCyrille Pitchen /* Master Clock to fs ratio */
107b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKFS_MASK	GENMASK(29, 24)
108b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKFS(fs) \
109b543e467SCyrille Pitchen 	(((fs) << 24) & ATMEL_I2SC_MR_IMCKFS_MASK)
110b543e467SCyrille Pitchen 
111b543e467SCyrille Pitchen /* Master Clock mode */
112b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKMODE_MASK	GENMASK(30, 30)
113b543e467SCyrille Pitchen /* 0: No master clock generated (selected clock drives I2SCK pin) */
114b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKMODE_I2SCK	(0 << 30)
115b543e467SCyrille Pitchen /* 1: master clock generated (internally generated clock drives I2SMCK pin) */
116b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IMCKMODE_I2SMCK	(1 << 30)
117b543e467SCyrille Pitchen 
118b543e467SCyrille Pitchen /* Slot Width */
119b543e467SCyrille Pitchen /* 0: slot is 32 bits wide for DATALENGTH = 18/20/24 bits. */
120b543e467SCyrille Pitchen /* 1: slot is 24 bits wide for DATALENGTH = 18/20/24 bits. */
121b543e467SCyrille Pitchen #define ATMEL_I2SC_MR_IWS		BIT(31)
122b543e467SCyrille Pitchen 
123b543e467SCyrille Pitchen /*
124b543e467SCyrille Pitchen  * ---- Status Registers ----
125b543e467SCyrille Pitchen  */
126b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_RXEN	BIT(0)	/* Receiver Enabled */
127b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_RXRDY	BIT(1)	/* Receive Ready */
128b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_RXOR	BIT(2)	/* Receive Overrun */
129b543e467SCyrille Pitchen 
130b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_TXEN	BIT(4)	/* Transmitter Enabled */
131b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_TXRDY	BIT(5)	/* Transmit Ready */
132b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_TXUR	BIT(6)	/* Transmit Underrun */
133b543e467SCyrille Pitchen 
134b543e467SCyrille Pitchen /* Receive Overrun Channel */
135b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_RXORCH_MASK	GENMASK(15, 8)
136b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_RXORCH(ch)	(1 << (((ch) & 0x7) + 8))
137b543e467SCyrille Pitchen 
138b543e467SCyrille Pitchen /* Transmit Underrun Channel */
139b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_TXURCH_MASK	GENMASK(27, 20)
140b543e467SCyrille Pitchen #define ATMEL_I2SC_SR_TXURCH(ch)	(1 << (((ch) & 0x7) + 20))
141b543e467SCyrille Pitchen 
142b543e467SCyrille Pitchen /*
143b543e467SCyrille Pitchen  * ---- Interrupt Enable/Disable/Mask Registers ----
144b543e467SCyrille Pitchen  */
145b543e467SCyrille Pitchen #define ATMEL_I2SC_INT_RXRDY	ATMEL_I2SC_SR_RXRDY
146b543e467SCyrille Pitchen #define ATMEL_I2SC_INT_RXOR	ATMEL_I2SC_SR_RXOR
147b543e467SCyrille Pitchen #define ATMEL_I2SC_INT_TXRDY	ATMEL_I2SC_SR_TXRDY
148b543e467SCyrille Pitchen #define ATMEL_I2SC_INT_TXUR	ATMEL_I2SC_SR_TXUR
149b543e467SCyrille Pitchen 
150b543e467SCyrille Pitchen static const struct regmap_config atmel_i2s_regmap_config = {
151b543e467SCyrille Pitchen 	.reg_bits = 32,
152b543e467SCyrille Pitchen 	.reg_stride = 4,
153b543e467SCyrille Pitchen 	.val_bits = 32,
154b543e467SCyrille Pitchen 	.max_register = ATMEL_I2SC_VERSION,
155b543e467SCyrille Pitchen };
156b543e467SCyrille Pitchen 
157b543e467SCyrille Pitchen struct atmel_i2s_gck_param {
158b543e467SCyrille Pitchen 	int		fs;
159b543e467SCyrille Pitchen 	unsigned long	mck;
160b543e467SCyrille Pitchen 	int		imckdiv;
161b543e467SCyrille Pitchen 	int		imckfs;
162b543e467SCyrille Pitchen };
163b543e467SCyrille Pitchen 
164b543e467SCyrille Pitchen #define I2S_MCK_12M288		12288000UL
165b543e467SCyrille Pitchen #define I2S_MCK_11M2896		11289600UL
166b543e467SCyrille Pitchen 
167b543e467SCyrille Pitchen /* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */
168b543e467SCyrille Pitchen static const struct atmel_i2s_gck_param gck_params[] = {
169b543e467SCyrille Pitchen 	/* mck = 12.288MHz */
170b543e467SCyrille Pitchen 	{  8000, I2S_MCK_12M288, 0, 47},	/* mck = 1536 fs */
171b543e467SCyrille Pitchen 	{ 16000, I2S_MCK_12M288, 1, 47},	/* mck =  768 fs */
172b543e467SCyrille Pitchen 	{ 24000, I2S_MCK_12M288, 3, 63},	/* mck =  512 fs */
173b543e467SCyrille Pitchen 	{ 32000, I2S_MCK_12M288, 3, 47},	/* mck =  384 fs */
174b543e467SCyrille Pitchen 	{ 48000, I2S_MCK_12M288, 7, 63},	/* mck =  256 fs */
175b543e467SCyrille Pitchen 	{ 64000, I2S_MCK_12M288, 7, 47},	/* mck =  192 fs */
176b543e467SCyrille Pitchen 	{ 96000, I2S_MCK_12M288, 7, 31},	/* mck =  128 fs */
177b543e467SCyrille Pitchen 	{192000, I2S_MCK_12M288, 7, 15},	/* mck =   64 fs */
178b543e467SCyrille Pitchen 
179b543e467SCyrille Pitchen 	/* mck = 11.2896MHz */
180b543e467SCyrille Pitchen 	{ 11025, I2S_MCK_11M2896, 1, 63},	/* mck = 1024 fs */
181b543e467SCyrille Pitchen 	{ 22050, I2S_MCK_11M2896, 3, 63},	/* mck =  512 fs */
182b543e467SCyrille Pitchen 	{ 44100, I2S_MCK_11M2896, 7, 63},	/* mck =  256 fs */
183b543e467SCyrille Pitchen 	{ 88200, I2S_MCK_11M2896, 7, 31},	/* mck =  128 fs */
184b543e467SCyrille Pitchen 	{176400, I2S_MCK_11M2896, 7, 15},	/* mck =   64 fs */
185b543e467SCyrille Pitchen };
186b543e467SCyrille Pitchen 
187b543e467SCyrille Pitchen struct atmel_i2s_dev;
188b543e467SCyrille Pitchen 
189b543e467SCyrille Pitchen struct atmel_i2s_caps {
190b543e467SCyrille Pitchen 	int	(*mck_init)(struct atmel_i2s_dev *, struct device_node *np);
191b543e467SCyrille Pitchen };
192b543e467SCyrille Pitchen 
193b543e467SCyrille Pitchen struct atmel_i2s_dev {
194b543e467SCyrille Pitchen 	struct device				*dev;
195b543e467SCyrille Pitchen 	struct regmap				*regmap;
196b543e467SCyrille Pitchen 	struct clk				*pclk;
197b543e467SCyrille Pitchen 	struct clk				*gclk;
198b543e467SCyrille Pitchen 	struct snd_dmaengine_dai_dma_data	playback;
199b543e467SCyrille Pitchen 	struct snd_dmaengine_dai_dma_data	capture;
200b543e467SCyrille Pitchen 	unsigned int				fmt;
201b543e467SCyrille Pitchen 	const struct atmel_i2s_gck_param	*gck_param;
202b543e467SCyrille Pitchen 	const struct atmel_i2s_caps		*caps;
203b543e467SCyrille Pitchen };
204b543e467SCyrille Pitchen 
205b543e467SCyrille Pitchen static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
206b543e467SCyrille Pitchen {
207b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = dev_id;
208b543e467SCyrille Pitchen 	unsigned int sr, imr, pending, ch, mask;
209b543e467SCyrille Pitchen 	irqreturn_t ret = IRQ_NONE;
210b543e467SCyrille Pitchen 
211b543e467SCyrille Pitchen 	regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
212b543e467SCyrille Pitchen 	regmap_read(dev->regmap, ATMEL_I2SC_IMR, &imr);
213b543e467SCyrille Pitchen 	pending = sr & imr;
214b543e467SCyrille Pitchen 
215b543e467SCyrille Pitchen 	if (!pending)
216b543e467SCyrille Pitchen 		return IRQ_NONE;
217b543e467SCyrille Pitchen 
218b543e467SCyrille Pitchen 	if (pending & ATMEL_I2SC_INT_RXOR) {
219b543e467SCyrille Pitchen 		mask = ATMEL_I2SC_SR_RXOR;
220b543e467SCyrille Pitchen 
221b543e467SCyrille Pitchen 		for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
222b543e467SCyrille Pitchen 			if (sr & ATMEL_I2SC_SR_RXORCH(ch)) {
223b543e467SCyrille Pitchen 				mask |= ATMEL_I2SC_SR_RXORCH(ch);
224b543e467SCyrille Pitchen 				dev_err(dev->dev,
225b543e467SCyrille Pitchen 					"RX overrun on channel %d\n", ch);
226b543e467SCyrille Pitchen 			}
227b543e467SCyrille Pitchen 		}
228b543e467SCyrille Pitchen 		regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
229b543e467SCyrille Pitchen 		ret = IRQ_HANDLED;
230b543e467SCyrille Pitchen 	}
231b543e467SCyrille Pitchen 
232b543e467SCyrille Pitchen 	if (pending & ATMEL_I2SC_INT_TXUR) {
233b543e467SCyrille Pitchen 		mask = ATMEL_I2SC_SR_TXUR;
234b543e467SCyrille Pitchen 
235b543e467SCyrille Pitchen 		for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
236b543e467SCyrille Pitchen 			if (sr & ATMEL_I2SC_SR_TXURCH(ch)) {
237b543e467SCyrille Pitchen 				mask |= ATMEL_I2SC_SR_TXURCH(ch);
238b543e467SCyrille Pitchen 				dev_err(dev->dev,
239b543e467SCyrille Pitchen 					"TX underrun on channel %d\n", ch);
240b543e467SCyrille Pitchen 			}
241b543e467SCyrille Pitchen 		}
242b543e467SCyrille Pitchen 		regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
243b543e467SCyrille Pitchen 		ret = IRQ_HANDLED;
244b543e467SCyrille Pitchen 	}
245b543e467SCyrille Pitchen 
246b543e467SCyrille Pitchen 	return ret;
247b543e467SCyrille Pitchen }
248b543e467SCyrille Pitchen 
249b543e467SCyrille Pitchen #define ATMEL_I2S_RATES		SNDRV_PCM_RATE_8000_192000
250b543e467SCyrille Pitchen 
251b543e467SCyrille Pitchen #define ATMEL_I2S_FORMATS	(SNDRV_PCM_FMTBIT_S8 |		\
252b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S16_LE |	\
253b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S18_3LE |	\
254b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S20_3LE |	\
255b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S24_3LE |	\
256b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S24_LE |	\
257b543e467SCyrille Pitchen 				 SNDRV_PCM_FMTBIT_S32_LE)
258b543e467SCyrille Pitchen 
259b543e467SCyrille Pitchen static int atmel_i2s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
260b543e467SCyrille Pitchen {
261b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
262b543e467SCyrille Pitchen 
263b543e467SCyrille Pitchen 	dev->fmt = fmt;
264b543e467SCyrille Pitchen 	return 0;
265b543e467SCyrille Pitchen }
266b543e467SCyrille Pitchen 
267b543e467SCyrille Pitchen static int atmel_i2s_prepare(struct snd_pcm_substream *substream,
268b543e467SCyrille Pitchen 			     struct snd_soc_dai *dai)
269b543e467SCyrille Pitchen {
270b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
271b543e467SCyrille Pitchen 	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
272b543e467SCyrille Pitchen 	unsigned int rhr, sr = 0;
273b543e467SCyrille Pitchen 
274b543e467SCyrille Pitchen 	if (is_playback) {
275b543e467SCyrille Pitchen 		regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
276b543e467SCyrille Pitchen 		if (sr & ATMEL_I2SC_SR_RXRDY) {
277b543e467SCyrille Pitchen 			/*
278b543e467SCyrille Pitchen 			 * The RX Ready flag should not be set. However if here,
279b543e467SCyrille Pitchen 			 * we flush (read) the Receive Holding Register to start
280b543e467SCyrille Pitchen 			 * from a clean state.
281b543e467SCyrille Pitchen 			 */
282b543e467SCyrille Pitchen 			dev_dbg(dev->dev, "RXRDY is set\n");
283b543e467SCyrille Pitchen 			regmap_read(dev->regmap, ATMEL_I2SC_RHR, &rhr);
284b543e467SCyrille Pitchen 		}
285b543e467SCyrille Pitchen 	}
286b543e467SCyrille Pitchen 
287b543e467SCyrille Pitchen 	return 0;
288b543e467SCyrille Pitchen }
289b543e467SCyrille Pitchen 
290b543e467SCyrille Pitchen static int atmel_i2s_get_gck_param(struct atmel_i2s_dev *dev, int fs)
291b543e467SCyrille Pitchen {
292b543e467SCyrille Pitchen 	int i, best;
293b543e467SCyrille Pitchen 
29473ad0df5SCodrin Ciubotariu 	if (!dev->gclk) {
295b543e467SCyrille Pitchen 		dev_err(dev->dev, "cannot generate the I2S Master Clock\n");
296b543e467SCyrille Pitchen 		return -EINVAL;
297b543e467SCyrille Pitchen 	}
298b543e467SCyrille Pitchen 
299b543e467SCyrille Pitchen 	/*
300b543e467SCyrille Pitchen 	 * Find the best possible settings to generate the I2S Master Clock
301b543e467SCyrille Pitchen 	 * from the PLL Audio.
302b543e467SCyrille Pitchen 	 */
303b543e467SCyrille Pitchen 	dev->gck_param = NULL;
304b543e467SCyrille Pitchen 	best = INT_MAX;
305b543e467SCyrille Pitchen 	for (i = 0; i < ARRAY_SIZE(gck_params); ++i) {
306b543e467SCyrille Pitchen 		const struct atmel_i2s_gck_param *gck_param = &gck_params[i];
307b543e467SCyrille Pitchen 		int val = abs(fs - gck_param->fs);
308b543e467SCyrille Pitchen 
309b543e467SCyrille Pitchen 		if (val < best) {
310b543e467SCyrille Pitchen 			best = val;
311b543e467SCyrille Pitchen 			dev->gck_param = gck_param;
312b543e467SCyrille Pitchen 		}
313b543e467SCyrille Pitchen 	}
314b543e467SCyrille Pitchen 
315b543e467SCyrille Pitchen 	return 0;
316b543e467SCyrille Pitchen }
317b543e467SCyrille Pitchen 
318b543e467SCyrille Pitchen static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
319b543e467SCyrille Pitchen 			       struct snd_pcm_hw_params *params,
320b543e467SCyrille Pitchen 			       struct snd_soc_dai *dai)
321b543e467SCyrille Pitchen {
322b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
323b543e467SCyrille Pitchen 	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
324b543e467SCyrille Pitchen 	unsigned int mr = 0;
325b543e467SCyrille Pitchen 	int ret;
326b543e467SCyrille Pitchen 
327b543e467SCyrille Pitchen 	switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
328b543e467SCyrille Pitchen 	case SND_SOC_DAIFMT_I2S:
329b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_FORMAT_I2S;
330b543e467SCyrille Pitchen 		break;
331b543e467SCyrille Pitchen 
332b543e467SCyrille Pitchen 	default:
333b543e467SCyrille Pitchen 		dev_err(dev->dev, "unsupported bus format\n");
334b543e467SCyrille Pitchen 		return -EINVAL;
335b543e467SCyrille Pitchen 	}
336b543e467SCyrille Pitchen 
337b543e467SCyrille Pitchen 	switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
338b543e467SCyrille Pitchen 	case SND_SOC_DAIFMT_CBS_CFS:
339b543e467SCyrille Pitchen 		/* codec is slave, so cpu is master */
340b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_MODE_MASTER;
341b543e467SCyrille Pitchen 		ret = atmel_i2s_get_gck_param(dev, params_rate(params));
342b543e467SCyrille Pitchen 		if (ret)
343b543e467SCyrille Pitchen 			return ret;
344b543e467SCyrille Pitchen 		break;
345b543e467SCyrille Pitchen 
346b543e467SCyrille Pitchen 	case SND_SOC_DAIFMT_CBM_CFM:
347b543e467SCyrille Pitchen 		/* codec is master, so cpu is slave */
348b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_MODE_SLAVE;
349b543e467SCyrille Pitchen 		dev->gck_param = NULL;
350b543e467SCyrille Pitchen 		break;
351b543e467SCyrille Pitchen 
352b543e467SCyrille Pitchen 	default:
353b543e467SCyrille Pitchen 		dev_err(dev->dev, "unsupported master/slave mode\n");
354b543e467SCyrille Pitchen 		return -EINVAL;
355b543e467SCyrille Pitchen 	}
356b543e467SCyrille Pitchen 
357b543e467SCyrille Pitchen 	switch (params_channels(params)) {
358b543e467SCyrille Pitchen 	case 1:
359b543e467SCyrille Pitchen 		if (is_playback)
360b543e467SCyrille Pitchen 			mr |= ATMEL_I2SC_MR_TXMONO;
361b543e467SCyrille Pitchen 		else
362b543e467SCyrille Pitchen 			mr |= ATMEL_I2SC_MR_RXMONO;
363b543e467SCyrille Pitchen 		break;
364b543e467SCyrille Pitchen 	case 2:
365b543e467SCyrille Pitchen 		break;
366b543e467SCyrille Pitchen 	default:
367b543e467SCyrille Pitchen 		dev_err(dev->dev, "unsupported number of audio channels\n");
368b543e467SCyrille Pitchen 		return -EINVAL;
369b543e467SCyrille Pitchen 	}
370b543e467SCyrille Pitchen 
371b543e467SCyrille Pitchen 	switch (params_format(params)) {
372b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S8:
373b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_8_BITS;
374b543e467SCyrille Pitchen 		break;
375b543e467SCyrille Pitchen 
376b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S16_LE:
377b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_16_BITS;
378b543e467SCyrille Pitchen 		break;
379b543e467SCyrille Pitchen 
380b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S18_3LE:
381b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_18_BITS | ATMEL_I2SC_MR_IWS;
382b543e467SCyrille Pitchen 		break;
383b543e467SCyrille Pitchen 
384b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S20_3LE:
385b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_20_BITS | ATMEL_I2SC_MR_IWS;
386b543e467SCyrille Pitchen 		break;
387b543e467SCyrille Pitchen 
388b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S24_3LE:
389b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS | ATMEL_I2SC_MR_IWS;
390b543e467SCyrille Pitchen 		break;
391b543e467SCyrille Pitchen 
392b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S24_LE:
393b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS;
394b543e467SCyrille Pitchen 		break;
395b543e467SCyrille Pitchen 
396b543e467SCyrille Pitchen 	case SNDRV_PCM_FORMAT_S32_LE:
397b543e467SCyrille Pitchen 		mr |= ATMEL_I2SC_MR_DATALENGTH_32_BITS;
398b543e467SCyrille Pitchen 		break;
399b543e467SCyrille Pitchen 
400b543e467SCyrille Pitchen 	default:
401b543e467SCyrille Pitchen 		dev_err(dev->dev, "unsupported size/endianness for audio samples\n");
402b543e467SCyrille Pitchen 		return -EINVAL;
403b543e467SCyrille Pitchen 	}
404b543e467SCyrille Pitchen 
405b543e467SCyrille Pitchen 	return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
406b543e467SCyrille Pitchen }
407b543e467SCyrille Pitchen 
408b543e467SCyrille Pitchen static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
409b543e467SCyrille Pitchen 					  bool enabled)
410b543e467SCyrille Pitchen {
411b543e467SCyrille Pitchen 	unsigned int mr, mr_mask;
41273ad0df5SCodrin Ciubotariu 	unsigned long gclk_rate;
413b543e467SCyrille Pitchen 	int ret;
414b543e467SCyrille Pitchen 
415b543e467SCyrille Pitchen 	mr = 0;
416b543e467SCyrille Pitchen 	mr_mask = (ATMEL_I2SC_MR_IMCKDIV_MASK |
417b543e467SCyrille Pitchen 		   ATMEL_I2SC_MR_IMCKFS_MASK |
418b543e467SCyrille Pitchen 		   ATMEL_I2SC_MR_IMCKMODE_MASK);
419b543e467SCyrille Pitchen 
420b543e467SCyrille Pitchen 	if (!enabled) {
421b543e467SCyrille Pitchen 		/* Disable the I2S Master Clock generator. */
422b543e467SCyrille Pitchen 		ret = regmap_write(dev->regmap, ATMEL_I2SC_CR,
423b543e467SCyrille Pitchen 				   ATMEL_I2SC_CR_CKDIS);
424b543e467SCyrille Pitchen 		if (ret)
425b543e467SCyrille Pitchen 			return ret;
426b543e467SCyrille Pitchen 
427b543e467SCyrille Pitchen 		/* Reset the I2S Master Clock generator settings. */
428b543e467SCyrille Pitchen 		ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR,
429b543e467SCyrille Pitchen 					 mr_mask, mr);
430b543e467SCyrille Pitchen 		if (ret)
431b543e467SCyrille Pitchen 			return ret;
432b543e467SCyrille Pitchen 
433b543e467SCyrille Pitchen 		/* Disable/unprepare the PMC generated clock. */
434b543e467SCyrille Pitchen 		clk_disable_unprepare(dev->gclk);
435b543e467SCyrille Pitchen 
436b543e467SCyrille Pitchen 		return 0;
437b543e467SCyrille Pitchen 	}
438b543e467SCyrille Pitchen 
439b543e467SCyrille Pitchen 	if (!dev->gck_param)
440b543e467SCyrille Pitchen 		return -EINVAL;
441b543e467SCyrille Pitchen 
44273ad0df5SCodrin Ciubotariu 	gclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1);
443b543e467SCyrille Pitchen 
44473ad0df5SCodrin Ciubotariu 	ret = clk_set_rate(dev->gclk, gclk_rate);
445b543e467SCyrille Pitchen 	if (ret)
446b543e467SCyrille Pitchen 		return ret;
447b543e467SCyrille Pitchen 
448b543e467SCyrille Pitchen 	ret = clk_prepare_enable(dev->gclk);
449b543e467SCyrille Pitchen 	if (ret)
450b543e467SCyrille Pitchen 		return ret;
451b543e467SCyrille Pitchen 
452b543e467SCyrille Pitchen 	/* Update the Mode Register to generate the I2S Master Clock. */
453b543e467SCyrille Pitchen 	mr |= ATMEL_I2SC_MR_IMCKDIV(dev->gck_param->imckdiv);
454b543e467SCyrille Pitchen 	mr |= ATMEL_I2SC_MR_IMCKFS(dev->gck_param->imckfs);
455b543e467SCyrille Pitchen 	mr |= ATMEL_I2SC_MR_IMCKMODE_I2SMCK;
456b543e467SCyrille Pitchen 	ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
457b543e467SCyrille Pitchen 	if (ret)
458b543e467SCyrille Pitchen 		return ret;
459b543e467SCyrille Pitchen 
460b543e467SCyrille Pitchen 	/* Finally enable the I2S Master Clock generator. */
461b543e467SCyrille Pitchen 	return regmap_write(dev->regmap, ATMEL_I2SC_CR,
462b543e467SCyrille Pitchen 			    ATMEL_I2SC_CR_CKEN);
463b543e467SCyrille Pitchen }
464b543e467SCyrille Pitchen 
465b543e467SCyrille Pitchen static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
466b543e467SCyrille Pitchen 			     struct snd_soc_dai *dai)
467b543e467SCyrille Pitchen {
468b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
469b543e467SCyrille Pitchen 	bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
470b543e467SCyrille Pitchen 	bool is_master, mck_enabled;
471b543e467SCyrille Pitchen 	unsigned int cr, mr;
472b543e467SCyrille Pitchen 	int err;
473b543e467SCyrille Pitchen 
474b543e467SCyrille Pitchen 	switch (cmd) {
475b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_START:
476b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_RESUME:
477b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
478b543e467SCyrille Pitchen 		cr = is_playback ? ATMEL_I2SC_CR_TXEN : ATMEL_I2SC_CR_RXEN;
479b543e467SCyrille Pitchen 		mck_enabled = true;
480b543e467SCyrille Pitchen 		break;
481b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_STOP:
482b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_SUSPEND:
483b543e467SCyrille Pitchen 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
484b543e467SCyrille Pitchen 		cr = is_playback ? ATMEL_I2SC_CR_TXDIS : ATMEL_I2SC_CR_RXDIS;
485b543e467SCyrille Pitchen 		mck_enabled = false;
486b543e467SCyrille Pitchen 		break;
487b543e467SCyrille Pitchen 	default:
488b543e467SCyrille Pitchen 		return -EINVAL;
489b543e467SCyrille Pitchen 	}
490b543e467SCyrille Pitchen 
491b543e467SCyrille Pitchen 	/* Read the Mode Register to retrieve the master/slave state. */
492b543e467SCyrille Pitchen 	err = regmap_read(dev->regmap, ATMEL_I2SC_MR, &mr);
493b543e467SCyrille Pitchen 	if (err)
494b543e467SCyrille Pitchen 		return err;
495b543e467SCyrille Pitchen 	is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
496b543e467SCyrille Pitchen 
497b543e467SCyrille Pitchen 	/* If master starts, enable the audio clock. */
498b543e467SCyrille Pitchen 	if (is_master && mck_enabled)
499b543e467SCyrille Pitchen 		err = atmel_i2s_switch_mck_generator(dev, true);
500b543e467SCyrille Pitchen 	if (err)
501b543e467SCyrille Pitchen 		return err;
502b543e467SCyrille Pitchen 
503b543e467SCyrille Pitchen 	err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
504b543e467SCyrille Pitchen 	if (err)
505b543e467SCyrille Pitchen 		return err;
506b543e467SCyrille Pitchen 
507b543e467SCyrille Pitchen 	/* If master stops, disable the audio clock. */
508b543e467SCyrille Pitchen 	if (is_master && !mck_enabled)
509b543e467SCyrille Pitchen 		err = atmel_i2s_switch_mck_generator(dev, false);
510b543e467SCyrille Pitchen 
511b543e467SCyrille Pitchen 	return err;
512b543e467SCyrille Pitchen }
513b543e467SCyrille Pitchen 
514b543e467SCyrille Pitchen static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
515b543e467SCyrille Pitchen 	.prepare	= atmel_i2s_prepare,
516b543e467SCyrille Pitchen 	.trigger	= atmel_i2s_trigger,
517b543e467SCyrille Pitchen 	.hw_params	= atmel_i2s_hw_params,
518b543e467SCyrille Pitchen 	.set_fmt	= atmel_i2s_set_dai_fmt,
519b543e467SCyrille Pitchen };
520b543e467SCyrille Pitchen 
521b543e467SCyrille Pitchen static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)
522b543e467SCyrille Pitchen {
523b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
524b543e467SCyrille Pitchen 
525b543e467SCyrille Pitchen 	snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture);
526b543e467SCyrille Pitchen 	return 0;
527b543e467SCyrille Pitchen }
528b543e467SCyrille Pitchen 
529b543e467SCyrille Pitchen static struct snd_soc_dai_driver atmel_i2s_dai = {
530b543e467SCyrille Pitchen 	.probe	= atmel_i2s_dai_probe,
531b543e467SCyrille Pitchen 	.playback = {
532b543e467SCyrille Pitchen 		.channels_min = 1,
533b543e467SCyrille Pitchen 		.channels_max = 2,
534b543e467SCyrille Pitchen 		.rates = ATMEL_I2S_RATES,
535b543e467SCyrille Pitchen 		.formats = ATMEL_I2S_FORMATS,
536b543e467SCyrille Pitchen 	},
537b543e467SCyrille Pitchen 	.capture = {
538b543e467SCyrille Pitchen 		.channels_min = 1,
539b543e467SCyrille Pitchen 		.channels_max = 2,
540b543e467SCyrille Pitchen 		.rates = ATMEL_I2S_RATES,
541b543e467SCyrille Pitchen 		.formats = ATMEL_I2S_FORMATS,
542b543e467SCyrille Pitchen 	},
543b543e467SCyrille Pitchen 	.ops = &atmel_i2s_dai_ops,
544ba471f8dSKuninori Morimoto 	.symmetric_rate = 1,
545b543e467SCyrille Pitchen };
546b543e467SCyrille Pitchen 
547b543e467SCyrille Pitchen static const struct snd_soc_component_driver atmel_i2s_component = {
548b543e467SCyrille Pitchen 	.name	= "atmel-i2s",
549b543e467SCyrille Pitchen };
550b543e467SCyrille Pitchen 
551b543e467SCyrille Pitchen static int atmel_i2s_sama5d2_mck_init(struct atmel_i2s_dev *dev,
552b543e467SCyrille Pitchen 				      struct device_node *np)
553b543e467SCyrille Pitchen {
554b543e467SCyrille Pitchen 	struct clk *muxclk;
555b543e467SCyrille Pitchen 	int err;
556b543e467SCyrille Pitchen 
557b543e467SCyrille Pitchen 	if (!dev->gclk)
558b543e467SCyrille Pitchen 		return 0;
559b543e467SCyrille Pitchen 
560b543e467SCyrille Pitchen 	/* muxclk is optional, so we return error for probe defer only */
561b543e467SCyrille Pitchen 	muxclk = devm_clk_get(dev->dev, "muxclk");
562b543e467SCyrille Pitchen 	if (IS_ERR(muxclk)) {
563b543e467SCyrille Pitchen 		err = PTR_ERR(muxclk);
564b543e467SCyrille Pitchen 		if (err == -EPROBE_DEFER)
565b543e467SCyrille Pitchen 			return -EPROBE_DEFER;
566f4bf1f4dSCodrin Ciubotariu 		dev_dbg(dev->dev,
567b543e467SCyrille Pitchen 			"failed to get the I2S clock control: %d\n", err);
568b543e467SCyrille Pitchen 		return 0;
569b543e467SCyrille Pitchen 	}
570b543e467SCyrille Pitchen 
571b543e467SCyrille Pitchen 	return clk_set_parent(muxclk, dev->gclk);
572b543e467SCyrille Pitchen }
573b543e467SCyrille Pitchen 
574b543e467SCyrille Pitchen static const struct atmel_i2s_caps atmel_i2s_sama5d2_caps = {
575b543e467SCyrille Pitchen 	.mck_init = atmel_i2s_sama5d2_mck_init,
576b543e467SCyrille Pitchen };
577b543e467SCyrille Pitchen 
578b543e467SCyrille Pitchen static const struct of_device_id atmel_i2s_dt_ids[] = {
579b543e467SCyrille Pitchen 	{
580b543e467SCyrille Pitchen 		.compatible = "atmel,sama5d2-i2s",
581b543e467SCyrille Pitchen 		.data = (void *)&atmel_i2s_sama5d2_caps,
582b543e467SCyrille Pitchen 	},
583b543e467SCyrille Pitchen 
584b543e467SCyrille Pitchen 	{ /* sentinel */ }
585b543e467SCyrille Pitchen };
586b543e467SCyrille Pitchen 
587b543e467SCyrille Pitchen MODULE_DEVICE_TABLE(of, atmel_i2s_dt_ids);
588b543e467SCyrille Pitchen 
589b543e467SCyrille Pitchen static int atmel_i2s_probe(struct platform_device *pdev)
590b543e467SCyrille Pitchen {
591b543e467SCyrille Pitchen 	struct device_node *np = pdev->dev.of_node;
592b543e467SCyrille Pitchen 	const struct of_device_id *match;
593b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev;
594b543e467SCyrille Pitchen 	struct resource *mem;
595b543e467SCyrille Pitchen 	struct regmap *regmap;
596b543e467SCyrille Pitchen 	void __iomem *base;
597b543e467SCyrille Pitchen 	int irq;
5986692dc07SPierre-Louis Bossart 	int err;
599b543e467SCyrille Pitchen 	unsigned int pcm_flags = 0;
600b543e467SCyrille Pitchen 	unsigned int version;
601b543e467SCyrille Pitchen 
602b543e467SCyrille Pitchen 	/* Get memory for driver data. */
603b543e467SCyrille Pitchen 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
604b543e467SCyrille Pitchen 	if (!dev)
605b543e467SCyrille Pitchen 		return -ENOMEM;
606b543e467SCyrille Pitchen 
607b543e467SCyrille Pitchen 	/* Get hardware capabilities. */
608b543e467SCyrille Pitchen 	match = of_match_node(atmel_i2s_dt_ids, np);
609b543e467SCyrille Pitchen 	if (match)
610b543e467SCyrille Pitchen 		dev->caps = match->data;
611b543e467SCyrille Pitchen 
612b543e467SCyrille Pitchen 	/* Map I/O registers. */
613*39175acdSYang Yingliang 	base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
614b543e467SCyrille Pitchen 	if (IS_ERR(base))
615b543e467SCyrille Pitchen 		return PTR_ERR(base);
616b543e467SCyrille Pitchen 
617b543e467SCyrille Pitchen 	regmap = devm_regmap_init_mmio(&pdev->dev, base,
618b543e467SCyrille Pitchen 				       &atmel_i2s_regmap_config);
619b543e467SCyrille Pitchen 	if (IS_ERR(regmap))
620b543e467SCyrille Pitchen 		return PTR_ERR(regmap);
621b543e467SCyrille Pitchen 
622b543e467SCyrille Pitchen 	/* Request IRQ. */
623b543e467SCyrille Pitchen 	irq = platform_get_irq(pdev, 0);
624b543e467SCyrille Pitchen 	if (irq < 0)
625b543e467SCyrille Pitchen 		return irq;
626b543e467SCyrille Pitchen 
627b543e467SCyrille Pitchen 	err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0,
628b543e467SCyrille Pitchen 			       dev_name(&pdev->dev), dev);
629b543e467SCyrille Pitchen 	if (err)
630b543e467SCyrille Pitchen 		return err;
631b543e467SCyrille Pitchen 
632b543e467SCyrille Pitchen 	/* Get the peripheral clock. */
633b543e467SCyrille Pitchen 	dev->pclk = devm_clk_get(&pdev->dev, "pclk");
634b543e467SCyrille Pitchen 	if (IS_ERR(dev->pclk)) {
635b543e467SCyrille Pitchen 		err = PTR_ERR(dev->pclk);
636b543e467SCyrille Pitchen 		dev_err(&pdev->dev,
637b543e467SCyrille Pitchen 			"failed to get the peripheral clock: %d\n", err);
638b543e467SCyrille Pitchen 		return err;
639b543e467SCyrille Pitchen 	}
640b543e467SCyrille Pitchen 
64173ad0df5SCodrin Ciubotariu 	/* Get audio clock to generate the I2S Master Clock (I2S_MCK) */
642b543e467SCyrille Pitchen 	dev->gclk = devm_clk_get(&pdev->dev, "gclk");
64373ad0df5SCodrin Ciubotariu 	if (IS_ERR(dev->gclk)) {
64473ad0df5SCodrin Ciubotariu 		if (PTR_ERR(dev->gclk) == -EPROBE_DEFER)
645b543e467SCyrille Pitchen 			return -EPROBE_DEFER;
646b543e467SCyrille Pitchen 		/* Master Mode not supported */
647b543e467SCyrille Pitchen 		dev->gclk = NULL;
648b543e467SCyrille Pitchen 	}
649b543e467SCyrille Pitchen 	dev->dev = &pdev->dev;
650b543e467SCyrille Pitchen 	dev->regmap = regmap;
651b543e467SCyrille Pitchen 	platform_set_drvdata(pdev, dev);
652b543e467SCyrille Pitchen 
653b543e467SCyrille Pitchen 	/* Do hardware specific settings to initialize I2S_MCK generator */
654b543e467SCyrille Pitchen 	if (dev->caps && dev->caps->mck_init) {
655b543e467SCyrille Pitchen 		err = dev->caps->mck_init(dev, np);
656b543e467SCyrille Pitchen 		if (err)
657b543e467SCyrille Pitchen 			return err;
658b543e467SCyrille Pitchen 	}
659b543e467SCyrille Pitchen 
660b543e467SCyrille Pitchen 	/* Enable the peripheral clock. */
661b543e467SCyrille Pitchen 	err = clk_prepare_enable(dev->pclk);
662b543e467SCyrille Pitchen 	if (err)
663b543e467SCyrille Pitchen 		return err;
664b543e467SCyrille Pitchen 
665b543e467SCyrille Pitchen 	/* Get IP version. */
666b543e467SCyrille Pitchen 	regmap_read(dev->regmap, ATMEL_I2SC_VERSION, &version);
667b543e467SCyrille Pitchen 	dev_info(&pdev->dev, "hw version: %#x\n", version);
668b543e467SCyrille Pitchen 
669b543e467SCyrille Pitchen 	/* Enable error interrupts. */
670b543e467SCyrille Pitchen 	regmap_write(dev->regmap, ATMEL_I2SC_IER,
671b543e467SCyrille Pitchen 		     ATMEL_I2SC_INT_RXOR | ATMEL_I2SC_INT_TXUR);
672b543e467SCyrille Pitchen 
673b543e467SCyrille Pitchen 	err = devm_snd_soc_register_component(&pdev->dev,
674b543e467SCyrille Pitchen 					      &atmel_i2s_component,
675b543e467SCyrille Pitchen 					      &atmel_i2s_dai, 1);
676b543e467SCyrille Pitchen 	if (err) {
677b543e467SCyrille Pitchen 		dev_err(&pdev->dev, "failed to register DAI: %d\n", err);
678b543e467SCyrille Pitchen 		clk_disable_unprepare(dev->pclk);
679b543e467SCyrille Pitchen 		return err;
680b543e467SCyrille Pitchen 	}
681b543e467SCyrille Pitchen 
682b543e467SCyrille Pitchen 	/* Prepare DMA config. */
683b543e467SCyrille Pitchen 	dev->playback.addr	= (dma_addr_t)mem->start + ATMEL_I2SC_THR;
684b543e467SCyrille Pitchen 	dev->playback.maxburst	= 1;
685b543e467SCyrille Pitchen 	dev->capture.addr	= (dma_addr_t)mem->start + ATMEL_I2SC_RHR;
686b543e467SCyrille Pitchen 	dev->capture.maxburst	= 1;
687b543e467SCyrille Pitchen 
688b543e467SCyrille Pitchen 	if (of_property_match_string(np, "dma-names", "rx-tx") == 0)
689b543e467SCyrille Pitchen 		pcm_flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX;
690b543e467SCyrille Pitchen 	err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, pcm_flags);
691b543e467SCyrille Pitchen 	if (err) {
692b543e467SCyrille Pitchen 		dev_err(&pdev->dev, "failed to register PCM: %d\n", err);
693b543e467SCyrille Pitchen 		clk_disable_unprepare(dev->pclk);
694b543e467SCyrille Pitchen 		return err;
695b543e467SCyrille Pitchen 	}
696b543e467SCyrille Pitchen 
697b543e467SCyrille Pitchen 	return 0;
698b543e467SCyrille Pitchen }
699b543e467SCyrille Pitchen 
700b543e467SCyrille Pitchen static int atmel_i2s_remove(struct platform_device *pdev)
701b543e467SCyrille Pitchen {
702b543e467SCyrille Pitchen 	struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
703b543e467SCyrille Pitchen 
704b543e467SCyrille Pitchen 	clk_disable_unprepare(dev->pclk);
705b543e467SCyrille Pitchen 
706b543e467SCyrille Pitchen 	return 0;
707b543e467SCyrille Pitchen }
708b543e467SCyrille Pitchen 
709b543e467SCyrille Pitchen static struct platform_driver atmel_i2s_driver = {
710b543e467SCyrille Pitchen 	.driver		= {
711b543e467SCyrille Pitchen 		.name	= "atmel_i2s",
712b543e467SCyrille Pitchen 		.of_match_table	= of_match_ptr(atmel_i2s_dt_ids),
713b543e467SCyrille Pitchen 	},
714b543e467SCyrille Pitchen 	.probe		= atmel_i2s_probe,
715b543e467SCyrille Pitchen 	.remove		= atmel_i2s_remove,
716b543e467SCyrille Pitchen };
717b543e467SCyrille Pitchen module_platform_driver(atmel_i2s_driver);
718b543e467SCyrille Pitchen 
719b543e467SCyrille Pitchen MODULE_DESCRIPTION("Atmel I2S Controller driver");
720b543e467SCyrille Pitchen MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@atmel.com>");
721b543e467SCyrille Pitchen MODULE_LICENSE("GPL v2");
722