xref: /linux/sound/soc/sunxi/sun4i-i2s.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
1 /*
2  * Copyright (C) 2015 Andrea Venturi
3  * Andrea Venturi <be17068@iperbole.bo.it>
4  *
5  * Copyright (C) 2016 Maxime Ripard
6  * Maxime Ripard <maxime.ripard@free-electrons.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  */
13 
14 #include <linux/clk.h>
15 #include <linux/dmaengine.h>
16 #include <linux/module.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/reset.h>
22 
23 #include <sound/dmaengine_pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <sound/soc-dai.h>
27 
28 #define SUN4I_I2S_CTRL_REG		0x00
29 #define SUN4I_I2S_CTRL_SDO_EN_MASK		GENMASK(11, 8)
30 #define SUN4I_I2S_CTRL_SDO_EN(sdo)			BIT(8 + (sdo))
31 #define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
32 #define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
33 #define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
34 #define SUN4I_I2S_CTRL_TX_EN			BIT(2)
35 #define SUN4I_I2S_CTRL_RX_EN			BIT(1)
36 #define SUN4I_I2S_CTRL_GL_EN			BIT(0)
37 
38 #define SUN4I_I2S_FMT0_REG		0x04
39 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK	BIT(7)
40 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED		(1 << 7)
41 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL		(0 << 7)
42 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK	BIT(6)
43 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED		(1 << 6)
44 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL		(0 << 6)
45 #define SUN4I_I2S_FMT0_SR_MASK			GENMASK(5, 4)
46 #define SUN4I_I2S_FMT0_SR(sr)				((sr) << 4)
47 #define SUN4I_I2S_FMT0_WSS_MASK			GENMASK(3, 2)
48 #define SUN4I_I2S_FMT0_WSS(wss)				((wss) << 2)
49 #define SUN4I_I2S_FMT0_FMT_MASK			GENMASK(1, 0)
50 #define SUN4I_I2S_FMT0_FMT_RIGHT_J			(2 << 0)
51 #define SUN4I_I2S_FMT0_FMT_LEFT_J			(1 << 0)
52 #define SUN4I_I2S_FMT0_FMT_I2S				(0 << 0)
53 
54 #define SUN4I_I2S_FMT1_REG		0x08
55 #define SUN4I_I2S_FIFO_TX_REG		0x0c
56 #define SUN4I_I2S_FIFO_RX_REG		0x10
57 
58 #define SUN4I_I2S_FIFO_CTRL_REG		0x14
59 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX		BIT(25)
60 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX		BIT(24)
61 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK	BIT(2)
62 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)		((mode) << 2)
63 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK	GENMASK(1, 0)
64 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)		(mode)
65 
66 #define SUN4I_I2S_FIFO_STA_REG		0x18
67 
68 #define SUN4I_I2S_DMA_INT_CTRL_REG	0x1c
69 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN	BIT(7)
70 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN	BIT(3)
71 
72 #define SUN4I_I2S_INT_STA_REG		0x20
73 
74 #define SUN4I_I2S_CLK_DIV_REG		0x24
75 #define SUN4I_I2S_CLK_DIV_MCLK_EN		BIT(7)
76 #define SUN4I_I2S_CLK_DIV_BCLK_MASK		GENMASK(6, 4)
77 #define SUN4I_I2S_CLK_DIV_BCLK(bclk)			((bclk) << 4)
78 #define SUN4I_I2S_CLK_DIV_MCLK_MASK		GENMASK(3, 0)
79 #define SUN4I_I2S_CLK_DIV_MCLK(mclk)			((mclk) << 0)
80 
81 #define SUN4I_I2S_RX_CNT_REG		0x28
82 #define SUN4I_I2S_TX_CNT_REG		0x2c
83 
84 #define SUN4I_I2S_TX_CHAN_SEL_REG	0x30
85 #define SUN4I_I2S_TX_CHAN_SEL(num_chan)		(((num_chan) - 1) << 0)
86 
87 #define SUN4I_I2S_TX_CHAN_MAP_REG	0x34
88 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample)	((sample) << (chan << 2))
89 
90 #define SUN4I_I2S_RX_CHAN_SEL_REG	0x38
91 #define SUN4I_I2S_RX_CHAN_MAP_REG	0x3c
92 
93 struct sun4i_i2s {
94 	struct clk	*bus_clk;
95 	struct clk	*mod_clk;
96 	struct regmap	*regmap;
97 	struct reset_control *rst;
98 
99 	unsigned int	mclk_freq;
100 
101 	struct snd_dmaengine_dai_dma_data	capture_dma_data;
102 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
103 };
104 
105 struct sun4i_i2s_clk_div {
106 	u8	div;
107 	u8	val;
108 };
109 
110 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
111 	{ .div = 2, .val = 0 },
112 	{ .div = 4, .val = 1 },
113 	{ .div = 6, .val = 2 },
114 	{ .div = 8, .val = 3 },
115 	{ .div = 12, .val = 4 },
116 	{ .div = 16, .val = 5 },
117 };
118 
119 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
120 	{ .div = 1, .val = 0 },
121 	{ .div = 2, .val = 1 },
122 	{ .div = 4, .val = 2 },
123 	{ .div = 6, .val = 3 },
124 	{ .div = 8, .val = 4 },
125 	{ .div = 12, .val = 5 },
126 	{ .div = 16, .val = 6 },
127 	{ .div = 24, .val = 7 },
128 };
129 
130 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
131 				  unsigned int oversample_rate,
132 				  unsigned int word_size)
133 {
134 	int div = oversample_rate / word_size / 2;
135 	int i;
136 
137 	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
138 		const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i];
139 
140 		if (bdiv->div == div)
141 			return bdiv->val;
142 	}
143 
144 	return -EINVAL;
145 }
146 
147 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
148 				  unsigned int oversample_rate,
149 				  unsigned int module_rate,
150 				  unsigned int sampling_rate)
151 {
152 	int div = module_rate / sampling_rate / oversample_rate;
153 	int i;
154 
155 	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) {
156 		const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i];
157 
158 		if (mdiv->div == div)
159 			return mdiv->val;
160 	}
161 
162 	return -EINVAL;
163 }
164 
165 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
166 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
167 {
168 	int i;
169 
170 	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
171 		if (sun4i_i2s_oversample_rates[i] == oversample)
172 			return true;
173 
174 	return false;
175 }
176 
177 static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
178 				  unsigned int rate,
179 				  unsigned int word_size)
180 {
181 	unsigned int oversample_rate, clk_rate;
182 	int bclk_div, mclk_div;
183 	int ret;
184 
185 	switch (rate) {
186 	case 176400:
187 	case 88200:
188 	case 44100:
189 	case 22050:
190 	case 11025:
191 		clk_rate = 22579200;
192 		break;
193 
194 	case 192000:
195 	case 128000:
196 	case 96000:
197 	case 64000:
198 	case 48000:
199 	case 32000:
200 	case 24000:
201 	case 16000:
202 	case 12000:
203 	case 8000:
204 		clk_rate = 24576000;
205 		break;
206 
207 	default:
208 		return -EINVAL;
209 	}
210 
211 	ret = clk_set_rate(i2s->mod_clk, clk_rate);
212 	if (ret)
213 		return ret;
214 
215 	oversample_rate = i2s->mclk_freq / rate;
216 	if (!sun4i_i2s_oversample_is_valid(oversample_rate))
217 		return -EINVAL;
218 
219 	bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
220 					  word_size);
221 	if (bclk_div < 0)
222 		return -EINVAL;
223 
224 	mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
225 					  clk_rate, rate);
226 	if (mclk_div < 0)
227 		return -EINVAL;
228 
229 	regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
230 		     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
231 		     SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
232 		     SUN4I_I2S_CLK_DIV_MCLK_EN);
233 
234 	return 0;
235 }
236 
237 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
238 			       struct snd_pcm_hw_params *params,
239 			       struct snd_soc_dai *dai)
240 {
241 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
242 	int sr, wss;
243 	u32 width;
244 
245 	if (params_channels(params) != 2)
246 		return -EINVAL;
247 
248 	switch (params_physical_width(params)) {
249 	case 16:
250 		width = DMA_SLAVE_BUSWIDTH_2_BYTES;
251 		break;
252 	default:
253 		return -EINVAL;
254 	}
255 	i2s->playback_dma_data.addr_width = width;
256 
257 	switch (params_width(params)) {
258 	case 16:
259 		sr = 0;
260 		wss = 0;
261 		break;
262 
263 	default:
264 		return -EINVAL;
265 	}
266 
267 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
268 			   SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
269 			   SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
270 
271 	return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
272 				      params_width(params));
273 }
274 
275 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
276 {
277 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
278 	u32 val;
279 
280 	/* DAI Mode */
281 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
282 	case SND_SOC_DAIFMT_I2S:
283 		val = SUN4I_I2S_FMT0_FMT_I2S;
284 		break;
285 	case SND_SOC_DAIFMT_LEFT_J:
286 		val = SUN4I_I2S_FMT0_FMT_LEFT_J;
287 		break;
288 	case SND_SOC_DAIFMT_RIGHT_J:
289 		val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
290 		break;
291 	default:
292 		return -EINVAL;
293 	}
294 
295 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
296 			   SUN4I_I2S_FMT0_FMT_MASK,
297 			   val);
298 
299 	/* DAI clock polarity */
300 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
301 	case SND_SOC_DAIFMT_IB_IF:
302 		/* Invert both clocks */
303 		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
304 			SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
305 		break;
306 	case SND_SOC_DAIFMT_IB_NF:
307 		/* Invert bit clock */
308 		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
309 			SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
310 		break;
311 	case SND_SOC_DAIFMT_NB_IF:
312 		/* Invert frame clock */
313 		val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED |
314 			SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL;
315 		break;
316 	case SND_SOC_DAIFMT_NB_NF:
317 		/* Nothing to do for both normal cases */
318 		val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL |
319 			SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
320 		break;
321 	default:
322 		return -EINVAL;
323 	}
324 
325 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
326 			   SUN4I_I2S_FMT0_BCLK_POLARITY_MASK |
327 			   SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK,
328 			   val);
329 
330 	/* DAI clock master masks */
331 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
332 	case SND_SOC_DAIFMT_CBS_CFS:
333 		/* BCLK and LRCLK master */
334 		val = SUN4I_I2S_CTRL_MODE_MASTER;
335 		break;
336 	case SND_SOC_DAIFMT_CBM_CFM:
337 		/* BCLK and LRCLK slave */
338 		val = SUN4I_I2S_CTRL_MODE_SLAVE;
339 		break;
340 	default:
341 		return -EINVAL;
342 	}
343 
344 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
345 			   SUN4I_I2S_CTRL_MODE_MASK,
346 			   val);
347 
348 	/* Set significant bits in our FIFOs */
349 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
350 			   SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
351 			   SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
352 			   SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
353 			   SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
354 	return 0;
355 }
356 
357 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
358 {
359 	/* Flush RX FIFO */
360 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
361 			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
362 			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
363 
364 	/* Clear RX counter */
365 	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
366 
367 	/* Enable RX Block */
368 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
369 			   SUN4I_I2S_CTRL_RX_EN,
370 			   SUN4I_I2S_CTRL_RX_EN);
371 
372 	/* Enable RX DRQ */
373 	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
374 			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
375 			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
376 }
377 
378 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
379 {
380 	/* Flush TX FIFO */
381 	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
382 			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
383 			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
384 
385 	/* Clear TX counter */
386 	regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
387 
388 	/* Enable TX Block */
389 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
390 			   SUN4I_I2S_CTRL_TX_EN,
391 			   SUN4I_I2S_CTRL_TX_EN);
392 
393 	/* Enable TX DRQ */
394 	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
395 			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
396 			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
397 }
398 
399 static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
400 {
401 	/* Disable RX Block */
402 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
403 			   SUN4I_I2S_CTRL_RX_EN,
404 			   0);
405 
406 	/* Disable RX DRQ */
407 	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
408 			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
409 			   0);
410 }
411 
412 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
413 {
414 	/* Disable TX Block */
415 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
416 			   SUN4I_I2S_CTRL_TX_EN,
417 			   0);
418 
419 	/* Disable TX DRQ */
420 	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
421 			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
422 			   0);
423 }
424 
425 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
426 			     struct snd_soc_dai *dai)
427 {
428 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
429 
430 	switch (cmd) {
431 	case SNDRV_PCM_TRIGGER_START:
432 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
433 	case SNDRV_PCM_TRIGGER_RESUME:
434 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
435 			sun4i_i2s_start_playback(i2s);
436 		else
437 			sun4i_i2s_start_capture(i2s);
438 		break;
439 
440 	case SNDRV_PCM_TRIGGER_STOP:
441 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
442 	case SNDRV_PCM_TRIGGER_SUSPEND:
443 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
444 			sun4i_i2s_stop_playback(i2s);
445 		else
446 			sun4i_i2s_stop_capture(i2s);
447 		break;
448 
449 	default:
450 		return -EINVAL;
451 	}
452 
453 	return 0;
454 }
455 
456 static int sun4i_i2s_startup(struct snd_pcm_substream *substream,
457 			     struct snd_soc_dai *dai)
458 {
459 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
460 
461 	/* Enable the whole hardware block */
462 	regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG,
463 		     SUN4I_I2S_CTRL_GL_EN);
464 
465 	/* Enable the first output line */
466 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
467 			   SUN4I_I2S_CTRL_SDO_EN_MASK,
468 			   SUN4I_I2S_CTRL_SDO_EN(0));
469 
470 	/* Enable the first two channels */
471 	regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
472 		     SUN4I_I2S_TX_CHAN_SEL(2));
473 
474 	/* Map them to the two first samples coming in */
475 	regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG,
476 		     SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1));
477 
478 	return clk_prepare_enable(i2s->mod_clk);
479 }
480 
481 static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream,
482 			       struct snd_soc_dai *dai)
483 {
484 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
485 
486 	clk_disable_unprepare(i2s->mod_clk);
487 
488 	/* Disable our output lines */
489 	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
490 			   SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
491 
492 	/* Disable the whole hardware block */
493 	regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0);
494 }
495 
496 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
497 				unsigned int freq, int dir)
498 {
499 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
500 
501 	if (clk_id != 0)
502 		return -EINVAL;
503 
504 	i2s->mclk_freq = freq;
505 
506 	return 0;
507 }
508 
509 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
510 	.hw_params	= sun4i_i2s_hw_params,
511 	.set_fmt	= sun4i_i2s_set_fmt,
512 	.set_sysclk	= sun4i_i2s_set_sysclk,
513 	.shutdown	= sun4i_i2s_shutdown,
514 	.startup	= sun4i_i2s_startup,
515 	.trigger	= sun4i_i2s_trigger,
516 };
517 
518 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
519 {
520 	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
521 
522 	snd_soc_dai_init_dma_data(dai,
523 				  &i2s->playback_dma_data,
524 				  &i2s->capture_dma_data);
525 
526 	snd_soc_dai_set_drvdata(dai, i2s);
527 
528 	return 0;
529 }
530 
531 static struct snd_soc_dai_driver sun4i_i2s_dai = {
532 	.probe = sun4i_i2s_dai_probe,
533 	.capture = {
534 		.stream_name = "Capture",
535 		.channels_min = 2,
536 		.channels_max = 2,
537 		.rates = SNDRV_PCM_RATE_8000_192000,
538 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
539 	},
540 	.playback = {
541 		.stream_name = "Playback",
542 		.channels_min = 2,
543 		.channels_max = 2,
544 		.rates = SNDRV_PCM_RATE_8000_192000,
545 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
546 	},
547 	.ops = &sun4i_i2s_dai_ops,
548 	.symmetric_rates = 1,
549 };
550 
551 static const struct snd_soc_component_driver sun4i_i2s_component = {
552 	.name	= "sun4i-dai",
553 };
554 
555 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
556 {
557 	switch (reg) {
558 	case SUN4I_I2S_FIFO_TX_REG:
559 		return false;
560 
561 	default:
562 		return true;
563 	}
564 }
565 
566 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
567 {
568 	switch (reg) {
569 	case SUN4I_I2S_FIFO_RX_REG:
570 	case SUN4I_I2S_FIFO_STA_REG:
571 		return false;
572 
573 	default:
574 		return true;
575 	}
576 }
577 
578 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
579 {
580 	switch (reg) {
581 	case SUN4I_I2S_FIFO_RX_REG:
582 	case SUN4I_I2S_INT_STA_REG:
583 	case SUN4I_I2S_RX_CNT_REG:
584 	case SUN4I_I2S_TX_CNT_REG:
585 		return true;
586 
587 	default:
588 		return false;
589 	}
590 }
591 
592 static const struct reg_default sun4i_i2s_reg_defaults[] = {
593 	{ SUN4I_I2S_CTRL_REG, 0x00000000 },
594 	{ SUN4I_I2S_FMT0_REG, 0x0000000c },
595 	{ SUN4I_I2S_FMT1_REG, 0x00004020 },
596 	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
597 	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
598 	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
599 	{ SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
600 	{ SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
601 	{ SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
602 	{ SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
603 };
604 
605 static const struct regmap_config sun4i_i2s_regmap_config = {
606 	.reg_bits	= 32,
607 	.reg_stride	= 4,
608 	.val_bits	= 32,
609 	.max_register	= SUN4I_I2S_RX_CHAN_MAP_REG,
610 
611 	.cache_type	= REGCACHE_FLAT,
612 	.reg_defaults	= sun4i_i2s_reg_defaults,
613 	.num_reg_defaults	= ARRAY_SIZE(sun4i_i2s_reg_defaults),
614 	.writeable_reg	= sun4i_i2s_wr_reg,
615 	.readable_reg	= sun4i_i2s_rd_reg,
616 	.volatile_reg	= sun4i_i2s_volatile_reg,
617 };
618 
619 static int sun4i_i2s_runtime_resume(struct device *dev)
620 {
621 	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
622 	int ret;
623 
624 	ret = clk_prepare_enable(i2s->bus_clk);
625 	if (ret) {
626 		dev_err(dev, "Failed to enable bus clock\n");
627 		return ret;
628 	}
629 
630 	regcache_cache_only(i2s->regmap, false);
631 	regcache_mark_dirty(i2s->regmap);
632 
633 	ret = regcache_sync(i2s->regmap);
634 	if (ret) {
635 		dev_err(dev, "Failed to sync regmap cache\n");
636 		goto err_disable_clk;
637 	}
638 
639 	return 0;
640 
641 err_disable_clk:
642 	clk_disable_unprepare(i2s->bus_clk);
643 	return ret;
644 }
645 
646 static int sun4i_i2s_runtime_suspend(struct device *dev)
647 {
648 	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
649 
650 	regcache_cache_only(i2s->regmap, true);
651 
652 	clk_disable_unprepare(i2s->bus_clk);
653 
654 	return 0;
655 }
656 
657 struct sun4i_i2s_quirks {
658 	bool has_reset;
659 };
660 
661 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
662 	.has_reset	= false,
663 };
664 
665 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
666 	.has_reset	= true,
667 };
668 
669 static int sun4i_i2s_probe(struct platform_device *pdev)
670 {
671 	struct sun4i_i2s *i2s;
672 	const struct sun4i_i2s_quirks *quirks;
673 	struct resource *res;
674 	void __iomem *regs;
675 	int irq, ret;
676 
677 	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
678 	if (!i2s)
679 		return -ENOMEM;
680 	platform_set_drvdata(pdev, i2s);
681 
682 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
683 	regs = devm_ioremap_resource(&pdev->dev, res);
684 	if (IS_ERR(regs))
685 		return PTR_ERR(regs);
686 
687 	irq = platform_get_irq(pdev, 0);
688 	if (irq < 0) {
689 		dev_err(&pdev->dev, "Can't retrieve our interrupt\n");
690 		return irq;
691 	}
692 
693 	quirks = of_device_get_match_data(&pdev->dev);
694 	if (!quirks) {
695 		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
696 		return -ENODEV;
697 	}
698 
699 	i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
700 	if (IS_ERR(i2s->bus_clk)) {
701 		dev_err(&pdev->dev, "Can't get our bus clock\n");
702 		return PTR_ERR(i2s->bus_clk);
703 	}
704 
705 	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
706 					    &sun4i_i2s_regmap_config);
707 	if (IS_ERR(i2s->regmap)) {
708 		dev_err(&pdev->dev, "Regmap initialisation failed\n");
709 		return PTR_ERR(i2s->regmap);
710 	}
711 
712 	i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
713 	if (IS_ERR(i2s->mod_clk)) {
714 		dev_err(&pdev->dev, "Can't get our mod clock\n");
715 		return PTR_ERR(i2s->mod_clk);
716 	}
717 
718 	if (quirks->has_reset) {
719 		i2s->rst = devm_reset_control_get(&pdev->dev, NULL);
720 		if (IS_ERR(i2s->rst)) {
721 			dev_err(&pdev->dev, "Failed to get reset control\n");
722 			return PTR_ERR(i2s->rst);
723 		}
724 	}
725 
726 	if (!IS_ERR(i2s->rst)) {
727 		ret = reset_control_deassert(i2s->rst);
728 		if (ret) {
729 			dev_err(&pdev->dev,
730 				"Failed to deassert the reset control\n");
731 			return -EINVAL;
732 		}
733 	}
734 
735 	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
736 	i2s->playback_dma_data.maxburst = 8;
737 
738 	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
739 	i2s->capture_dma_data.maxburst = 8;
740 
741 	pm_runtime_enable(&pdev->dev);
742 	if (!pm_runtime_enabled(&pdev->dev)) {
743 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
744 		if (ret)
745 			goto err_pm_disable;
746 	}
747 
748 	ret = devm_snd_soc_register_component(&pdev->dev,
749 					      &sun4i_i2s_component,
750 					      &sun4i_i2s_dai, 1);
751 	if (ret) {
752 		dev_err(&pdev->dev, "Could not register DAI\n");
753 		goto err_suspend;
754 	}
755 
756 	ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
757 	if (ret) {
758 		dev_err(&pdev->dev, "Could not register PCM\n");
759 		goto err_suspend;
760 	}
761 
762 	return 0;
763 
764 err_suspend:
765 	if (!pm_runtime_status_suspended(&pdev->dev))
766 		sun4i_i2s_runtime_suspend(&pdev->dev);
767 err_pm_disable:
768 	pm_runtime_disable(&pdev->dev);
769 	if (!IS_ERR(i2s->rst))
770 		reset_control_assert(i2s->rst);
771 
772 	return ret;
773 }
774 
775 static int sun4i_i2s_remove(struct platform_device *pdev)
776 {
777 	struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
778 
779 	snd_dmaengine_pcm_unregister(&pdev->dev);
780 
781 	pm_runtime_disable(&pdev->dev);
782 	if (!pm_runtime_status_suspended(&pdev->dev))
783 		sun4i_i2s_runtime_suspend(&pdev->dev);
784 
785 	if (!IS_ERR(i2s->rst))
786 		reset_control_assert(i2s->rst);
787 
788 	return 0;
789 }
790 
791 static const struct of_device_id sun4i_i2s_match[] = {
792 	{
793 		.compatible = "allwinner,sun4i-a10-i2s",
794 		.data = &sun4i_a10_i2s_quirks,
795 	},
796 	{
797 		.compatible = "allwinner,sun6i-a31-i2s",
798 		.data = &sun6i_a31_i2s_quirks,
799 	},
800 	{}
801 };
802 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
803 
804 static const struct dev_pm_ops sun4i_i2s_pm_ops = {
805 	.runtime_resume		= sun4i_i2s_runtime_resume,
806 	.runtime_suspend	= sun4i_i2s_runtime_suspend,
807 };
808 
809 static struct platform_driver sun4i_i2s_driver = {
810 	.probe	= sun4i_i2s_probe,
811 	.remove	= sun4i_i2s_remove,
812 	.driver	= {
813 		.name		= "sun4i-i2s",
814 		.of_match_table	= sun4i_i2s_match,
815 		.pm		= &sun4i_i2s_pm_ops,
816 	},
817 };
818 module_platform_driver(sun4i_i2s_driver);
819 
820 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
821 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
822 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
823 MODULE_LICENSE("GPL");
824