1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2015 Andrea Venturi
4 * Andrea Venturi <be17068@iperbole.bo.it>
5 *
6 * Copyright (C) 2016 Maxime Ripard
7 * Maxime Ripard <maxime.ripard@free-electrons.com>
8 */
9
10#include <linux/clk.h>
11#include <linux/dmaengine.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/pm_runtime.h>
16#include <linux/regmap.h>
17#include <linux/reset.h>
18
19#include <sound/dmaengine_pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23
24#define SUN4I_I2S_CTRL_REG		0x00
25#define SUN4I_I2S_CTRL_SDO_EN_MASK		GENMASK(11, 8)
26#define SUN4I_I2S_CTRL_SDO_EN(sdo)			BIT(8 + (sdo))
27#define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
28#define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
29#define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
30#define SUN4I_I2S_CTRL_TX_EN			BIT(2)
31#define SUN4I_I2S_CTRL_RX_EN			BIT(1)
32#define SUN4I_I2S_CTRL_GL_EN			BIT(0)
33
34#define SUN4I_I2S_FMT0_REG		0x04
35#define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK	BIT(7)
36#define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED		(1 << 7)
37#define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL		(0 << 7)
38#define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK	BIT(6)
39#define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED		(1 << 6)
40#define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL		(0 << 6)
41#define SUN4I_I2S_FMT0_SR_MASK			GENMASK(5, 4)
42#define SUN4I_I2S_FMT0_SR(sr)				((sr) << 4)
43#define SUN4I_I2S_FMT0_WSS_MASK			GENMASK(3, 2)
44#define SUN4I_I2S_FMT0_WSS(wss)				((wss) << 2)
45#define SUN4I_I2S_FMT0_FMT_MASK			GENMASK(1, 0)
46#define SUN4I_I2S_FMT0_FMT_RIGHT_J			(2 << 0)
47#define SUN4I_I2S_FMT0_FMT_LEFT_J			(1 << 0)
48#define SUN4I_I2S_FMT0_FMT_I2S				(0 << 0)
49
50#define SUN4I_I2S_FMT1_REG		0x08
51#define SUN4I_I2S_FMT1_REG_SEXT_MASK		BIT(8)
52#define SUN4I_I2S_FMT1_REG_SEXT(sext)			((sext) << 8)
53
54#define SUN4I_I2S_FIFO_TX_REG		0x0c
55#define SUN4I_I2S_FIFO_RX_REG		0x10
56
57#define SUN4I_I2S_FIFO_CTRL_REG		0x14
58#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX		BIT(25)
59#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX		BIT(24)
60#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK	BIT(2)
61#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)		((mode) << 2)
62#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK	GENMASK(1, 0)
63#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)		(mode)
64
65#define SUN4I_I2S_FIFO_STA_REG		0x18
66
67#define SUN4I_I2S_DMA_INT_CTRL_REG	0x1c
68#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN	BIT(7)
69#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN	BIT(3)
70
71#define SUN4I_I2S_INT_STA_REG		0x20
72
73#define SUN4I_I2S_CLK_DIV_REG		0x24
74#define SUN4I_I2S_CLK_DIV_MCLK_EN		BIT(7)
75#define SUN4I_I2S_CLK_DIV_BCLK_MASK		GENMASK(6, 4)
76#define SUN4I_I2S_CLK_DIV_BCLK(bclk)			((bclk) << 4)
77#define SUN4I_I2S_CLK_DIV_MCLK_MASK		GENMASK(3, 0)
78#define SUN4I_I2S_CLK_DIV_MCLK(mclk)			((mclk) << 0)
79
80#define SUN4I_I2S_TX_CNT_REG		0x28
81#define SUN4I_I2S_RX_CNT_REG		0x2c
82
83#define SUN4I_I2S_TX_CHAN_SEL_REG	0x30
84#define SUN4I_I2S_CHAN_SEL_MASK			GENMASK(2, 0)
85#define SUN4I_I2S_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/* Defines required for sun8i-h3 support */
94#define SUN8I_I2S_CTRL_BCLK_OUT			BIT(18)
95#define SUN8I_I2S_CTRL_LRCK_OUT			BIT(17)
96
97#define SUN8I_I2S_CTRL_MODE_MASK		GENMASK(5, 4)
98#define SUN8I_I2S_CTRL_MODE_RIGHT		(2 << 4)
99#define SUN8I_I2S_CTRL_MODE_LEFT		(1 << 4)
100#define SUN8I_I2S_CTRL_MODE_PCM			(0 << 4)
101
102#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK	BIT(19)
103#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED		(1 << 19)
104#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL		(0 << 19)
105#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK		GENMASK(17, 8)
106#define SUN8I_I2S_FMT0_LRCK_PERIOD(period)	((period - 1) << 8)
107#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK	BIT(7)
108#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED		(1 << 7)
109#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL		(0 << 7)
110
111#define SUN8I_I2S_FMT1_REG_SEXT_MASK		GENMASK(5, 4)
112#define SUN8I_I2S_FMT1_REG_SEXT(sext)			((sext) << 4)
113
114#define SUN8I_I2S_INT_STA_REG		0x0c
115#define SUN8I_I2S_FIFO_TX_REG		0x20
116
117#define SUN8I_I2S_CHAN_CFG_REG		0x30
118#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK	GENMASK(7, 4)
119#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)	((chan - 1) << 4)
120#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK	GENMASK(3, 0)
121#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)	(chan - 1)
122
123#define SUN8I_I2S_TX_CHAN_MAP_REG	0x44
124#define SUN8I_I2S_TX_CHAN_SEL_REG	0x34
125#define SUN8I_I2S_TX_CHAN_OFFSET_MASK		GENMASK(13, 12)
126#define SUN8I_I2S_TX_CHAN_OFFSET(offset)	(offset << 12)
127#define SUN8I_I2S_TX_CHAN_EN_MASK		GENMASK(11, 4)
128#define SUN8I_I2S_TX_CHAN_EN(num_chan)		(((1 << num_chan) - 1) << 4)
129
130#define SUN8I_I2S_RX_CHAN_SEL_REG	0x54
131#define SUN8I_I2S_RX_CHAN_MAP_REG	0x58
132
133/* Defines required for sun50i-h6 support */
134#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK	GENMASK(21, 20)
135#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)	((offset) << 20)
136#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK		GENMASK(19, 16)
137#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)		((chan - 1) << 16)
138#define SUN50I_H6_I2S_TX_CHAN_EN_MASK		GENMASK(15, 0)
139#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)	(((1 << num_chan) - 1))
140
141#define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin)	(0x34 + 4 * (pin))
142#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin)	(0x44 + 8 * (pin))
143#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin)	(0x48 + 8 * (pin))
144
145#define SUN50I_H6_I2S_RX_CHAN_SEL_REG	0x64
146#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG	0x68
147#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG	0x6C
148
149#define SUN50I_R329_I2S_RX_CHAN_MAP0_REG 0x68
150#define SUN50I_R329_I2S_RX_CHAN_MAP1_REG 0x6c
151#define SUN50I_R329_I2S_RX_CHAN_MAP2_REG 0x70
152#define SUN50I_R329_I2S_RX_CHAN_MAP3_REG 0x74
153
154struct sun4i_i2s;
155
156/**
157 * struct sun4i_i2s_quirks - Differences between SoC variants.
158 * @has_reset: SoC needs reset deasserted.
159 * @reg_offset_txdata: offset of the tx fifo.
160 * @sun4i_i2s_regmap: regmap config to use.
161 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
162 * @field_fmt_wss: regmap field to set word select size.
163 * @field_fmt_sr: regmap field to set sample resolution.
164 * @num_din_pins: input pins
165 * @num_dout_pins: output pins (currently set but unused)
166 * @bclk_dividers: bit clock dividers array
167 * @num_bclk_dividers: number of bit clock dividers
168 * @mclk_dividers: mclk dividers array
169 * @num_mclk_dividers: number of mclk dividers
170 * @get_bclk_parent_rate: callback to get bclk parent rate
171 * @get_sr: callback to get sample resolution
172 * @get_wss: callback to get word select size
173 * @set_chan_cfg: callback to set channel configuration
174 * @set_fmt: callback to set format
175 */
176struct sun4i_i2s_quirks {
177	bool				has_reset;
178	unsigned int			reg_offset_txdata;	/* TX FIFO */
179	const struct regmap_config	*sun4i_i2s_regmap;
180
181	/* Register fields for i2s */
182	struct reg_field		field_clkdiv_mclk_en;
183	struct reg_field		field_fmt_wss;
184	struct reg_field		field_fmt_sr;
185
186	unsigned int			num_din_pins;
187	unsigned int			num_dout_pins;
188
189	const struct sun4i_i2s_clk_div	*bclk_dividers;
190	unsigned int			num_bclk_dividers;
191	const struct sun4i_i2s_clk_div	*mclk_dividers;
192	unsigned int			num_mclk_dividers;
193
194	unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
195	int	(*get_sr)(unsigned int width);
196	int	(*get_wss)(unsigned int width);
197
198	/*
199	 * In the set_chan_cfg() function pointer:
200	 * @slots: channels per frame + padding slots, regardless of format
201	 * @slot_width: bits per sample + padding bits, regardless of format
202	 */
203	int	(*set_chan_cfg)(const struct sun4i_i2s *i2s,
204				unsigned int channels,	unsigned int slots,
205				unsigned int slot_width);
206	int	(*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
207};
208
209struct sun4i_i2s {
210	struct clk	*bus_clk;
211	struct clk	*mod_clk;
212	struct regmap	*regmap;
213	struct reset_control *rst;
214
215	unsigned int	format;
216	unsigned int	mclk_freq;
217	unsigned int	slots;
218	unsigned int	slot_width;
219
220	struct snd_dmaengine_dai_dma_data	capture_dma_data;
221	struct snd_dmaengine_dai_dma_data	playback_dma_data;
222
223	/* Register fields for i2s */
224	struct regmap_field	*field_clkdiv_mclk_en;
225	struct regmap_field	*field_fmt_wss;
226	struct regmap_field	*field_fmt_sr;
227
228	const struct sun4i_i2s_quirks	*variant;
229};
230
231struct sun4i_i2s_clk_div {
232	u8	div;
233	u8	val;
234};
235
236static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
237	{ .div = 2, .val = 0 },
238	{ .div = 4, .val = 1 },
239	{ .div = 6, .val = 2 },
240	{ .div = 8, .val = 3 },
241	{ .div = 12, .val = 4 },
242	{ .div = 16, .val = 5 },
243	/* TODO - extend divide ratio supported by newer SoCs */
244};
245
246static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
247	{ .div = 1, .val = 0 },
248	{ .div = 2, .val = 1 },
249	{ .div = 4, .val = 2 },
250	{ .div = 6, .val = 3 },
251	{ .div = 8, .val = 4 },
252	{ .div = 12, .val = 5 },
253	{ .div = 16, .val = 6 },
254	{ .div = 24, .val = 7 },
255	/* TODO - extend divide ratio supported by newer SoCs */
256};
257
258static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
259	{ .div = 1, .val = 1 },
260	{ .div = 2, .val = 2 },
261	{ .div = 4, .val = 3 },
262	{ .div = 6, .val = 4 },
263	{ .div = 8, .val = 5 },
264	{ .div = 12, .val = 6 },
265	{ .div = 16, .val = 7 },
266	{ .div = 24, .val = 8 },
267	{ .div = 32, .val = 9 },
268	{ .div = 48, .val = 10 },
269	{ .div = 64, .val = 11 },
270	{ .div = 96, .val = 12 },
271	{ .div = 128, .val = 13 },
272	{ .div = 176, .val = 14 },
273	{ .div = 192, .val = 15 },
274};
275
276static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
277{
278	return i2s->mclk_freq;
279}
280
281static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
282{
283	return clk_get_rate(i2s->mod_clk);
284}
285
286static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
287				  unsigned long parent_rate,
288				  unsigned int sampling_rate,
289				  unsigned int channels,
290				  unsigned int word_size)
291{
292	const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
293	int div = parent_rate / sampling_rate / word_size / channels;
294	int i;
295
296	for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
297		const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
298
299		if (bdiv->div == div)
300			return bdiv->val;
301	}
302
303	return -EINVAL;
304}
305
306static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
307				  unsigned long parent_rate,
308				  unsigned long mclk_rate)
309{
310	const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
311	int div = parent_rate / mclk_rate;
312	int i;
313
314	for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
315		const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
316
317		if (mdiv->div == div)
318			return mdiv->val;
319	}
320
321	return -EINVAL;
322}
323
324static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
325static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
326{
327	int i;
328
329	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
330		if (sun4i_i2s_oversample_rates[i] == oversample)
331			return true;
332
333	return false;
334}
335
336static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
337				  unsigned int rate,
338				  unsigned int slots,
339				  unsigned int slot_width)
340{
341	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
342	unsigned int oversample_rate, clk_rate, bclk_parent_rate;
343	int bclk_div, mclk_div;
344	int ret;
345
346	switch (rate) {
347	case 176400:
348	case 88200:
349	case 44100:
350	case 22050:
351	case 11025:
352		clk_rate = 22579200;
353		break;
354
355	case 192000:
356	case 128000:
357	case 96000:
358	case 64000:
359	case 48000:
360	case 32000:
361	case 24000:
362	case 16000:
363	case 12000:
364	case 8000:
365		clk_rate = 24576000;
366		break;
367
368	default:
369		dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
370		return -EINVAL;
371	}
372
373	ret = clk_set_rate(i2s->mod_clk, clk_rate);
374	if (ret)
375		return ret;
376
377	oversample_rate = i2s->mclk_freq / rate;
378	if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
379		dev_err(dai->dev, "Unsupported oversample rate: %d\n",
380			oversample_rate);
381		return -EINVAL;
382	}
383
384	bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
385	bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
386					  rate, slots, slot_width);
387	if (bclk_div < 0) {
388		dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
389		return -EINVAL;
390	}
391
392	mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
393	if (mclk_div < 0) {
394		dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
395		return -EINVAL;
396	}
397
398	regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
399		     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
400		     SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
401
402	regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
403
404	return 0;
405}
406
407static int sun4i_i2s_get_sr(unsigned int width)
408{
409	switch (width) {
410	case 16:
411		return 0;
412	case 20:
413		return 1;
414	case 24:
415		return 2;
416	}
417
418	return -EINVAL;
419}
420
421static int sun4i_i2s_get_wss(unsigned int width)
422{
423	switch (width) {
424	case 16:
425		return 0;
426	case 20:
427		return 1;
428	case 24:
429		return 2;
430	case 32:
431		return 3;
432	}
433
434	return -EINVAL;
435}
436
437static int sun8i_i2s_get_sr_wss(unsigned int width)
438{
439	switch (width) {
440	case 8:
441		return 1;
442	case 12:
443		return 2;
444	case 16:
445		return 3;
446	case 20:
447		return 4;
448	case 24:
449		return 5;
450	case 28:
451		return 6;
452	case 32:
453		return 7;
454	}
455
456	return -EINVAL;
457}
458
459static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
460				  unsigned int channels, unsigned int slots,
461				  unsigned int slot_width)
462{
463	/* Map the channels for playback and capture */
464	regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
465	regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
466
467	/* Configure the channels */
468	regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
469			   SUN4I_I2S_CHAN_SEL_MASK,
470			   SUN4I_I2S_CHAN_SEL(channels));
471	regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
472			   SUN4I_I2S_CHAN_SEL_MASK,
473			   SUN4I_I2S_CHAN_SEL(channels));
474
475	return 0;
476}
477
478static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
479				  unsigned int channels, unsigned int slots,
480				  unsigned int slot_width)
481{
482	unsigned int lrck_period;
483
484	/* Map the channels for playback and capture */
485	regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
486	regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
487
488	/* Configure the channels */
489	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
490			   SUN4I_I2S_CHAN_SEL_MASK,
491			   SUN4I_I2S_CHAN_SEL(channels));
492	regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
493			   SUN4I_I2S_CHAN_SEL_MASK,
494			   SUN4I_I2S_CHAN_SEL(channels));
495
496	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
497			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
498			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
499	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
500			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
501			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
502
503	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
504	case SND_SOC_DAIFMT_DSP_A:
505	case SND_SOC_DAIFMT_DSP_B:
506		lrck_period = slot_width * slots;
507		break;
508
509	case SND_SOC_DAIFMT_LEFT_J:
510	case SND_SOC_DAIFMT_RIGHT_J:
511	case SND_SOC_DAIFMT_I2S:
512		lrck_period = slot_width;
513		break;
514
515	default:
516		return -EINVAL;
517	}
518
519	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
520			   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
521			   SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
522
523	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
524			   SUN8I_I2S_TX_CHAN_EN_MASK,
525			   SUN8I_I2S_TX_CHAN_EN(channels));
526
527	return 0;
528}
529
530static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
531				      unsigned int channels, unsigned int slots,
532				      unsigned int slot_width)
533{
534	unsigned int lrck_period;
535
536	/* Map the channels for playback and capture */
537	regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
538	regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
539	if (i2s->variant->num_din_pins > 1) {
540		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 0x0F0E0D0C);
541		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 0x0B0A0908);
542		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 0x07060504);
543		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0x03020100);
544	} else {
545		regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
546		regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
547	}
548
549	/* Configure the channels */
550	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
551			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
552			   SUN50I_H6_I2S_TX_CHAN_SEL(channels));
553	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
554			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
555			   SUN50I_H6_I2S_TX_CHAN_SEL(channels));
556
557	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
558			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
559			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
560	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
561			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
562			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
563
564	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
565	case SND_SOC_DAIFMT_DSP_A:
566	case SND_SOC_DAIFMT_DSP_B:
567		lrck_period = slot_width * slots;
568		break;
569
570	case SND_SOC_DAIFMT_LEFT_J:
571	case SND_SOC_DAIFMT_RIGHT_J:
572	case SND_SOC_DAIFMT_I2S:
573		lrck_period = slot_width;
574		break;
575
576	default:
577		return -EINVAL;
578	}
579
580	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
581			   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
582			   SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
583
584	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
585			   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
586			   SUN50I_H6_I2S_TX_CHAN_EN(channels));
587
588	return 0;
589}
590
591static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
592			       struct snd_pcm_hw_params *params,
593			       struct snd_soc_dai *dai)
594{
595	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
596	unsigned int word_size = params_width(params);
597	unsigned int slot_width = params_physical_width(params);
598	unsigned int channels = params_channels(params);
599
600	unsigned int slots = channels;
601
602	int ret, sr, wss;
603	u32 width;
604
605	if (i2s->slots)
606		slots = i2s->slots;
607
608	if (i2s->slot_width)
609		slot_width = i2s->slot_width;
610
611	ret = i2s->variant->set_chan_cfg(i2s, channels, slots, slot_width);
612	if (ret < 0) {
613		dev_err(dai->dev, "Invalid channel configuration\n");
614		return ret;
615	}
616
617	/* Set significant bits in our FIFOs */
618	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
619			   SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
620			   SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
621			   SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
622			   SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
623
624	switch (params_physical_width(params)) {
625	case 16:
626		width = DMA_SLAVE_BUSWIDTH_2_BYTES;
627		break;
628	case 32:
629		width = DMA_SLAVE_BUSWIDTH_4_BYTES;
630		break;
631	default:
632		dev_err(dai->dev, "Unsupported physical sample width: %d\n",
633			params_physical_width(params));
634		return -EINVAL;
635	}
636	i2s->playback_dma_data.addr_width = width;
637
638	sr = i2s->variant->get_sr(word_size);
639	if (sr < 0)
640		return -EINVAL;
641
642	wss = i2s->variant->get_wss(slot_width);
643	if (wss < 0)
644		return -EINVAL;
645
646	regmap_field_write(i2s->field_fmt_wss, wss);
647	regmap_field_write(i2s->field_fmt_sr, sr);
648
649	return sun4i_i2s_set_clk_rate(dai, params_rate(params),
650				      slots, slot_width);
651}
652
653static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
654				 unsigned int fmt)
655{
656	u32 val;
657
658	/* DAI clock polarity */
659	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
660	case SND_SOC_DAIFMT_IB_IF:
661		/* Invert both clocks */
662		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
663		      SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
664		break;
665	case SND_SOC_DAIFMT_IB_NF:
666		/* Invert bit clock */
667		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
668		break;
669	case SND_SOC_DAIFMT_NB_IF:
670		/* Invert frame clock */
671		val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
672		break;
673	case SND_SOC_DAIFMT_NB_NF:
674		val = 0;
675		break;
676	default:
677		return -EINVAL;
678	}
679
680	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
681			   SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
682			   SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
683			   val);
684
685	/* DAI Mode */
686	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
687	case SND_SOC_DAIFMT_I2S:
688		val = SUN4I_I2S_FMT0_FMT_I2S;
689		break;
690
691	case SND_SOC_DAIFMT_LEFT_J:
692		val = SUN4I_I2S_FMT0_FMT_LEFT_J;
693		break;
694
695	case SND_SOC_DAIFMT_RIGHT_J:
696		val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
697		break;
698
699	default:
700		return -EINVAL;
701	}
702
703	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
704			   SUN4I_I2S_FMT0_FMT_MASK, val);
705
706	/* DAI clock master masks */
707	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
708	case SND_SOC_DAIFMT_BP_FP:
709		/* BCLK and LRCLK master */
710		val = SUN4I_I2S_CTRL_MODE_MASTER;
711		break;
712
713	case SND_SOC_DAIFMT_BC_FC:
714		/* BCLK and LRCLK slave */
715		val = SUN4I_I2S_CTRL_MODE_SLAVE;
716		break;
717
718	default:
719		return -EINVAL;
720	}
721	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
722			   SUN4I_I2S_CTRL_MODE_MASK, val);
723
724	return 0;
725}
726
727static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
728				 unsigned int fmt)
729{
730	u32 mode, val;
731	u8 offset;
732
733	/*
734	 * DAI clock polarity
735	 *
736	 * The setup for LRCK contradicts the datasheet, but under a
737	 * scope it's clear that the LRCK polarity is reversed
738	 * compared to the expected polarity on the bus.
739	 */
740	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
741	case SND_SOC_DAIFMT_IB_IF:
742		/* Invert both clocks */
743		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
744		break;
745	case SND_SOC_DAIFMT_IB_NF:
746		/* Invert bit clock */
747		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
748		      SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
749		break;
750	case SND_SOC_DAIFMT_NB_IF:
751		/* Invert frame clock */
752		val = 0;
753		break;
754	case SND_SOC_DAIFMT_NB_NF:
755		val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
756		break;
757	default:
758		return -EINVAL;
759	}
760
761	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
762			   SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
763			   SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
764			   val);
765
766	/* DAI Mode */
767	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
768	case SND_SOC_DAIFMT_DSP_A:
769		mode = SUN8I_I2S_CTRL_MODE_PCM;
770		offset = 1;
771		break;
772
773	case SND_SOC_DAIFMT_DSP_B:
774		mode = SUN8I_I2S_CTRL_MODE_PCM;
775		offset = 0;
776		break;
777
778	case SND_SOC_DAIFMT_I2S:
779		mode = SUN8I_I2S_CTRL_MODE_LEFT;
780		offset = 1;
781		break;
782
783	case SND_SOC_DAIFMT_LEFT_J:
784		mode = SUN8I_I2S_CTRL_MODE_LEFT;
785		offset = 0;
786		break;
787
788	case SND_SOC_DAIFMT_RIGHT_J:
789		mode = SUN8I_I2S_CTRL_MODE_RIGHT;
790		offset = 0;
791		break;
792
793	default:
794		return -EINVAL;
795	}
796
797	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
798			   SUN8I_I2S_CTRL_MODE_MASK, mode);
799	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
800			   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
801			   SUN8I_I2S_TX_CHAN_OFFSET(offset));
802	regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
803			   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
804			   SUN8I_I2S_TX_CHAN_OFFSET(offset));
805
806	/* DAI clock master masks */
807	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
808	case SND_SOC_DAIFMT_BP_FP:
809		/* BCLK and LRCLK master */
810		val = SUN8I_I2S_CTRL_BCLK_OUT |	SUN8I_I2S_CTRL_LRCK_OUT;
811		break;
812
813	case SND_SOC_DAIFMT_BC_FC:
814		/* BCLK and LRCLK slave */
815		val = 0;
816		break;
817
818	default:
819		return -EINVAL;
820	}
821
822	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
823			   SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
824			   val);
825
826	/* Set sign extension to pad out LSB with 0 */
827	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
828			   SUN8I_I2S_FMT1_REG_SEXT_MASK,
829			   SUN8I_I2S_FMT1_REG_SEXT(0));
830
831	return 0;
832}
833
834static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
835				     unsigned int fmt)
836{
837	u32 mode, val;
838	u8 offset;
839
840	/*
841	 * DAI clock polarity
842	 *
843	 * The setup for LRCK contradicts the datasheet, but under a
844	 * scope it's clear that the LRCK polarity is reversed
845	 * compared to the expected polarity on the bus.
846	 */
847	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
848	case SND_SOC_DAIFMT_IB_IF:
849		/* Invert both clocks */
850		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
851		break;
852	case SND_SOC_DAIFMT_IB_NF:
853		/* Invert bit clock */
854		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
855		      SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
856		break;
857	case SND_SOC_DAIFMT_NB_IF:
858		/* Invert frame clock */
859		val = 0;
860		break;
861	case SND_SOC_DAIFMT_NB_NF:
862		val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
863		break;
864	default:
865		return -EINVAL;
866	}
867
868	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
869			   SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
870			   SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
871			   val);
872
873	/* DAI Mode */
874	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
875	case SND_SOC_DAIFMT_DSP_A:
876		mode = SUN8I_I2S_CTRL_MODE_PCM;
877		offset = 1;
878		break;
879
880	case SND_SOC_DAIFMT_DSP_B:
881		mode = SUN8I_I2S_CTRL_MODE_PCM;
882		offset = 0;
883		break;
884
885	case SND_SOC_DAIFMT_I2S:
886		mode = SUN8I_I2S_CTRL_MODE_LEFT;
887		offset = 1;
888		break;
889
890	case SND_SOC_DAIFMT_LEFT_J:
891		mode = SUN8I_I2S_CTRL_MODE_LEFT;
892		offset = 0;
893		break;
894
895	case SND_SOC_DAIFMT_RIGHT_J:
896		mode = SUN8I_I2S_CTRL_MODE_RIGHT;
897		offset = 0;
898		break;
899
900	default:
901		return -EINVAL;
902	}
903
904	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
905			   SUN8I_I2S_CTRL_MODE_MASK, mode);
906	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
907			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
908			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
909	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
910			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
911			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
912
913	/* DAI clock master masks */
914	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
915	case SND_SOC_DAIFMT_BP_FP:
916		/* BCLK and LRCLK master */
917		val = SUN8I_I2S_CTRL_BCLK_OUT |	SUN8I_I2S_CTRL_LRCK_OUT;
918		break;
919
920	case SND_SOC_DAIFMT_BC_FC:
921		/* BCLK and LRCLK slave */
922		val = 0;
923		break;
924
925	default:
926		return -EINVAL;
927	}
928
929	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
930			   SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
931			   val);
932
933	/* Set sign extension to pad out LSB with 0 */
934	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
935			   SUN8I_I2S_FMT1_REG_SEXT_MASK,
936			   SUN8I_I2S_FMT1_REG_SEXT(0));
937
938	return 0;
939}
940
941static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
942{
943	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
944	int ret;
945
946	ret = i2s->variant->set_fmt(i2s, fmt);
947	if (ret) {
948		dev_err(dai->dev, "Unsupported format configuration\n");
949		return ret;
950	}
951
952	i2s->format = fmt;
953
954	return 0;
955}
956
957static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
958{
959	/* Flush RX FIFO */
960	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
961			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
962			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
963
964	/* Clear RX counter */
965	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
966
967	/* Enable RX Block */
968	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
969			   SUN4I_I2S_CTRL_RX_EN,
970			   SUN4I_I2S_CTRL_RX_EN);
971
972	/* Enable RX DRQ */
973	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
974			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
975			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
976}
977
978static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
979{
980	/* Flush TX FIFO */
981	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
982			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
983			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
984
985	/* Clear TX counter */
986	regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
987
988	/* Enable TX Block */
989	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
990			   SUN4I_I2S_CTRL_TX_EN,
991			   SUN4I_I2S_CTRL_TX_EN);
992
993	/* Enable TX DRQ */
994	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
995			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
996			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
997}
998
999static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
1000{
1001	/* Disable RX Block */
1002	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1003			   SUN4I_I2S_CTRL_RX_EN,
1004			   0);
1005
1006	/* Disable RX DRQ */
1007	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1008			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
1009			   0);
1010}
1011
1012static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
1013{
1014	/* Disable TX Block */
1015	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1016			   SUN4I_I2S_CTRL_TX_EN,
1017			   0);
1018
1019	/* Disable TX DRQ */
1020	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
1021			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
1022			   0);
1023}
1024
1025static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
1026			     struct snd_soc_dai *dai)
1027{
1028	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1029
1030	switch (cmd) {
1031	case SNDRV_PCM_TRIGGER_START:
1032	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1033	case SNDRV_PCM_TRIGGER_RESUME:
1034		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1035			sun4i_i2s_start_playback(i2s);
1036		else
1037			sun4i_i2s_start_capture(i2s);
1038		break;
1039
1040	case SNDRV_PCM_TRIGGER_STOP:
1041	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1042	case SNDRV_PCM_TRIGGER_SUSPEND:
1043		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1044			sun4i_i2s_stop_playback(i2s);
1045		else
1046			sun4i_i2s_stop_capture(i2s);
1047		break;
1048
1049	default:
1050		return -EINVAL;
1051	}
1052
1053	return 0;
1054}
1055
1056static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1057				unsigned int freq, int dir)
1058{
1059	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1060
1061	if (clk_id != 0)
1062		return -EINVAL;
1063
1064	i2s->mclk_freq = freq;
1065
1066	return 0;
1067}
1068
1069static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
1070				  unsigned int tx_mask, unsigned int rx_mask,
1071				  int slots, int slot_width)
1072{
1073	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1074
1075	if (slots > 8)
1076		return -EINVAL;
1077
1078	i2s->slots = slots;
1079	i2s->slot_width = slot_width;
1080
1081	return 0;
1082}
1083
1084static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
1085{
1086	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
1087
1088	snd_soc_dai_init_dma_data(dai,
1089				  &i2s->playback_dma_data,
1090				  &i2s->capture_dma_data);
1091
1092	return 0;
1093}
1094
1095static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
1096	.probe		= sun4i_i2s_dai_probe,
1097	.hw_params	= sun4i_i2s_hw_params,
1098	.set_fmt	= sun4i_i2s_set_fmt,
1099	.set_sysclk	= sun4i_i2s_set_sysclk,
1100	.set_tdm_slot	= sun4i_i2s_set_tdm_slot,
1101	.trigger	= sun4i_i2s_trigger,
1102};
1103
1104#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
1105			 SNDRV_PCM_FMTBIT_S20_LE | \
1106			 SNDRV_PCM_FMTBIT_S24_LE)
1107
1108static struct snd_soc_dai_driver sun4i_i2s_dai = {
1109	.capture = {
1110		.stream_name = "Capture",
1111		.channels_min = 1,
1112		.channels_max = 8,
1113		.rates = SNDRV_PCM_RATE_8000_192000,
1114		.formats = SUN4I_FORMATS,
1115	},
1116	.playback = {
1117		.stream_name = "Playback",
1118		.channels_min = 1,
1119		.channels_max = 8,
1120		.rates = SNDRV_PCM_RATE_8000_192000,
1121		.formats = SUN4I_FORMATS,
1122	},
1123	.ops = &sun4i_i2s_dai_ops,
1124	.symmetric_rate = 1,
1125};
1126
1127static const struct snd_soc_component_driver sun4i_i2s_component = {
1128	.name			= "sun4i-dai",
1129	.legacy_dai_naming	= 1,
1130};
1131
1132static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
1133{
1134	switch (reg) {
1135	case SUN4I_I2S_FIFO_TX_REG:
1136		return false;
1137
1138	default:
1139		return true;
1140	}
1141}
1142
1143static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
1144{
1145	switch (reg) {
1146	case SUN4I_I2S_FIFO_RX_REG:
1147	case SUN4I_I2S_FIFO_STA_REG:
1148		return false;
1149
1150	default:
1151		return true;
1152	}
1153}
1154
1155static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1156{
1157	switch (reg) {
1158	case SUN4I_I2S_FIFO_RX_REG:
1159	case SUN4I_I2S_INT_STA_REG:
1160	case SUN4I_I2S_RX_CNT_REG:
1161	case SUN4I_I2S_TX_CNT_REG:
1162		return true;
1163
1164	default:
1165		return false;
1166	}
1167}
1168
1169static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
1170{
1171	switch (reg) {
1172	case SUN8I_I2S_FIFO_TX_REG:
1173		return false;
1174
1175	default:
1176		return true;
1177	}
1178}
1179
1180static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
1181{
1182	switch (reg) {
1183	case SUN4I_I2S_FIFO_CTRL_REG:
1184	case SUN4I_I2S_FIFO_RX_REG:
1185	case SUN4I_I2S_FIFO_STA_REG:
1186	case SUN4I_I2S_RX_CNT_REG:
1187	case SUN4I_I2S_TX_CNT_REG:
1188	case SUN8I_I2S_FIFO_TX_REG:
1189	case SUN8I_I2S_INT_STA_REG:
1190		return true;
1191
1192	default:
1193		return false;
1194	}
1195}
1196
1197static const struct reg_default sun4i_i2s_reg_defaults[] = {
1198	{ SUN4I_I2S_CTRL_REG, 0x00000000 },
1199	{ SUN4I_I2S_FMT0_REG, 0x0000000c },
1200	{ SUN4I_I2S_FMT1_REG, 0x00004020 },
1201	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1202	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1203	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1204	{ SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
1205	{ SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
1206	{ SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
1207	{ SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
1208};
1209
1210static const struct reg_default sun8i_i2s_reg_defaults[] = {
1211	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
1212	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
1213	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
1214	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1215	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1216	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1217	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1218	{ SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
1219	{ SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
1220	{ SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1221	{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
1222};
1223
1224static const struct reg_default sun50i_h6_i2s_reg_defaults[] = {
1225	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
1226	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
1227	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
1228	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
1229	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
1230	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
1231	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
1232	{ SUN50I_H6_I2S_TX_CHAN_SEL_REG(0), 0x00000000 },
1233	{ SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0x00000000 },
1234	{ SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x00000000 },
1235	{ SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
1236	{ SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
1237	{ SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
1238};
1239
1240static const struct regmap_config sun4i_i2s_regmap_config = {
1241	.reg_bits	= 32,
1242	.reg_stride	= 4,
1243	.val_bits	= 32,
1244	.max_register	= SUN4I_I2S_RX_CHAN_MAP_REG,
1245
1246	.cache_type	= REGCACHE_FLAT,
1247	.reg_defaults	= sun4i_i2s_reg_defaults,
1248	.num_reg_defaults	= ARRAY_SIZE(sun4i_i2s_reg_defaults),
1249	.writeable_reg	= sun4i_i2s_wr_reg,
1250	.readable_reg	= sun4i_i2s_rd_reg,
1251	.volatile_reg	= sun4i_i2s_volatile_reg,
1252};
1253
1254static const struct regmap_config sun8i_i2s_regmap_config = {
1255	.reg_bits	= 32,
1256	.reg_stride	= 4,
1257	.val_bits	= 32,
1258	.max_register	= SUN8I_I2S_RX_CHAN_MAP_REG,
1259	.cache_type	= REGCACHE_FLAT,
1260	.reg_defaults	= sun8i_i2s_reg_defaults,
1261	.num_reg_defaults	= ARRAY_SIZE(sun8i_i2s_reg_defaults),
1262	.writeable_reg	= sun4i_i2s_wr_reg,
1263	.readable_reg	= sun8i_i2s_rd_reg,
1264	.volatile_reg	= sun8i_i2s_volatile_reg,
1265};
1266
1267static const struct regmap_config sun50i_h6_i2s_regmap_config = {
1268	.reg_bits	= 32,
1269	.reg_stride	= 4,
1270	.val_bits	= 32,
1271	.max_register	= SUN50I_R329_I2S_RX_CHAN_MAP3_REG,
1272	.cache_type	= REGCACHE_FLAT,
1273	.reg_defaults	= sun50i_h6_i2s_reg_defaults,
1274	.num_reg_defaults	= ARRAY_SIZE(sun50i_h6_i2s_reg_defaults),
1275	.writeable_reg	= sun4i_i2s_wr_reg,
1276	.readable_reg	= sun8i_i2s_rd_reg,
1277	.volatile_reg	= sun8i_i2s_volatile_reg,
1278};
1279
1280static int sun4i_i2s_runtime_resume(struct device *dev)
1281{
1282	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1283	int ret;
1284
1285	ret = clk_prepare_enable(i2s->bus_clk);
1286	if (ret) {
1287		dev_err(dev, "Failed to enable bus clock\n");
1288		return ret;
1289	}
1290
1291	regcache_cache_only(i2s->regmap, false);
1292	regcache_mark_dirty(i2s->regmap);
1293
1294	ret = regcache_sync(i2s->regmap);
1295	if (ret) {
1296		dev_err(dev, "Failed to sync regmap cache\n");
1297		goto err_disable_clk;
1298	}
1299
1300	/* Enable the whole hardware block */
1301	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1302			   SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
1303
1304	/* Enable the first output line */
1305	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1306			   SUN4I_I2S_CTRL_SDO_EN_MASK,
1307			   SUN4I_I2S_CTRL_SDO_EN(0));
1308
1309	ret = clk_prepare_enable(i2s->mod_clk);
1310	if (ret) {
1311		dev_err(dev, "Failed to enable module clock\n");
1312		goto err_disable_clk;
1313	}
1314
1315	return 0;
1316
1317err_disable_clk:
1318	clk_disable_unprepare(i2s->bus_clk);
1319	return ret;
1320}
1321
1322static int sun4i_i2s_runtime_suspend(struct device *dev)
1323{
1324	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
1325
1326	clk_disable_unprepare(i2s->mod_clk);
1327
1328	/* Disable our output lines */
1329	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1330			   SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
1331
1332	/* Disable the whole hardware block */
1333	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1334			   SUN4I_I2S_CTRL_GL_EN, 0);
1335
1336	regcache_cache_only(i2s->regmap, true);
1337
1338	clk_disable_unprepare(i2s->bus_clk);
1339
1340	return 0;
1341}
1342
1343static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
1344	.has_reset		= false,
1345	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
1346	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
1347	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1348	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1349	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1350	.bclk_dividers		= sun4i_i2s_bclk_div,
1351	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
1352	.mclk_dividers		= sun4i_i2s_mclk_div,
1353	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
1354	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
1355	.get_sr			= sun4i_i2s_get_sr,
1356	.get_wss		= sun4i_i2s_get_wss,
1357	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
1358	.set_fmt		= sun4i_i2s_set_soc_fmt,
1359};
1360
1361static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
1362	.has_reset		= true,
1363	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
1364	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
1365	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1366	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1367	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1368	.bclk_dividers		= sun4i_i2s_bclk_div,
1369	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
1370	.mclk_dividers		= sun4i_i2s_mclk_div,
1371	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
1372	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
1373	.get_sr			= sun4i_i2s_get_sr,
1374	.get_wss		= sun4i_i2s_get_wss,
1375	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
1376	.set_fmt		= sun4i_i2s_set_soc_fmt,
1377};
1378
1379/*
1380 * This doesn't describe the TDM controller documented in the A83t
1381 * datasheet, but the three undocumented I2S controller that use the
1382 * older design.
1383 */
1384static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1385	.has_reset		= true,
1386	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
1387	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
1388	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1389	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1390	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1391	.bclk_dividers		= sun4i_i2s_bclk_div,
1392	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
1393	.mclk_dividers		= sun4i_i2s_mclk_div,
1394	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
1395	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
1396	.get_sr			= sun4i_i2s_get_sr,
1397	.get_wss		= sun4i_i2s_get_wss,
1398	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
1399	.set_fmt		= sun4i_i2s_set_soc_fmt,
1400};
1401
1402static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1403	.has_reset		= true,
1404	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
1405	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
1406	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1407	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1408	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1409	.bclk_dividers		= sun8i_i2s_clk_div,
1410	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1411	.mclk_dividers		= sun8i_i2s_clk_div,
1412	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1413	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
1414	.get_sr			= sun8i_i2s_get_sr_wss,
1415	.get_wss		= sun8i_i2s_get_sr_wss,
1416	.set_chan_cfg		= sun8i_i2s_set_chan_cfg,
1417	.set_fmt		= sun8i_i2s_set_soc_fmt,
1418};
1419
1420static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1421	.has_reset		= true,
1422	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
1423	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
1424	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1425	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1426	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1427	.bclk_dividers		= sun4i_i2s_bclk_div,
1428	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
1429	.mclk_dividers		= sun4i_i2s_mclk_div,
1430	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
1431	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
1432	.get_sr			= sun4i_i2s_get_sr,
1433	.get_wss		= sun4i_i2s_get_wss,
1434	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
1435	.set_fmt		= sun4i_i2s_set_soc_fmt,
1436};
1437
1438static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
1439	.has_reset		= true,
1440	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
1441	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
1442	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1443	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1444	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1445	.bclk_dividers		= sun8i_i2s_clk_div,
1446	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1447	.mclk_dividers		= sun8i_i2s_clk_div,
1448	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1449	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
1450	.get_sr			= sun8i_i2s_get_sr_wss,
1451	.get_wss		= sun8i_i2s_get_sr_wss,
1452	.set_chan_cfg		= sun50i_h6_i2s_set_chan_cfg,
1453	.set_fmt		= sun50i_h6_i2s_set_soc_fmt,
1454};
1455
1456static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
1457	.has_reset		= true,
1458	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
1459	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
1460	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1461	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1462	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1463	.num_din_pins		= 4,
1464	.num_dout_pins		= 4,
1465	.bclk_dividers		= sun8i_i2s_clk_div,
1466	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1467	.mclk_dividers		= sun8i_i2s_clk_div,
1468	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
1469	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
1470	.get_sr			= sun8i_i2s_get_sr_wss,
1471	.get_wss		= sun8i_i2s_get_sr_wss,
1472	.set_chan_cfg		= sun50i_h6_i2s_set_chan_cfg,
1473	.set_fmt		= sun50i_h6_i2s_set_soc_fmt,
1474};
1475
1476static int sun4i_i2s_init_regmap_fields(struct device *dev,
1477					struct sun4i_i2s *i2s)
1478{
1479	i2s->field_clkdiv_mclk_en =
1480		devm_regmap_field_alloc(dev, i2s->regmap,
1481					i2s->variant->field_clkdiv_mclk_en);
1482	if (IS_ERR(i2s->field_clkdiv_mclk_en))
1483		return PTR_ERR(i2s->field_clkdiv_mclk_en);
1484
1485	i2s->field_fmt_wss =
1486			devm_regmap_field_alloc(dev, i2s->regmap,
1487						i2s->variant->field_fmt_wss);
1488	if (IS_ERR(i2s->field_fmt_wss))
1489		return PTR_ERR(i2s->field_fmt_wss);
1490
1491	i2s->field_fmt_sr =
1492			devm_regmap_field_alloc(dev, i2s->regmap,
1493						i2s->variant->field_fmt_sr);
1494	if (IS_ERR(i2s->field_fmt_sr))
1495		return PTR_ERR(i2s->field_fmt_sr);
1496
1497	return 0;
1498}
1499
1500static int sun4i_i2s_probe(struct platform_device *pdev)
1501{
1502	struct sun4i_i2s *i2s;
1503	struct resource *res;
1504	void __iomem *regs;
1505	int irq, ret;
1506
1507	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
1508	if (!i2s)
1509		return -ENOMEM;
1510	platform_set_drvdata(pdev, i2s);
1511
1512	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1513	if (IS_ERR(regs))
1514		return PTR_ERR(regs);
1515
1516	irq = platform_get_irq(pdev, 0);
1517	if (irq < 0)
1518		return irq;
1519
1520	i2s->variant = of_device_get_match_data(&pdev->dev);
1521	if (!i2s->variant) {
1522		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1523		return -ENODEV;
1524	}
1525
1526	i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
1527	if (IS_ERR(i2s->bus_clk)) {
1528		dev_err(&pdev->dev, "Can't get our bus clock\n");
1529		return PTR_ERR(i2s->bus_clk);
1530	}
1531
1532	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1533					    i2s->variant->sun4i_i2s_regmap);
1534	if (IS_ERR(i2s->regmap)) {
1535		dev_err(&pdev->dev, "Regmap initialisation failed\n");
1536		return PTR_ERR(i2s->regmap);
1537	}
1538
1539	i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
1540	if (IS_ERR(i2s->mod_clk)) {
1541		dev_err(&pdev->dev, "Can't get our mod clock\n");
1542		return PTR_ERR(i2s->mod_clk);
1543	}
1544
1545	if (i2s->variant->has_reset) {
1546		i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
1547		if (IS_ERR(i2s->rst)) {
1548			dev_err(&pdev->dev, "Failed to get reset control\n");
1549			return PTR_ERR(i2s->rst);
1550		}
1551	}
1552
1553	if (!IS_ERR(i2s->rst)) {
1554		ret = reset_control_deassert(i2s->rst);
1555		if (ret) {
1556			dev_err(&pdev->dev,
1557				"Failed to deassert the reset control\n");
1558			return -EINVAL;
1559		}
1560	}
1561
1562	i2s->playback_dma_data.addr = res->start +
1563					i2s->variant->reg_offset_txdata;
1564	i2s->playback_dma_data.maxburst = 8;
1565
1566	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
1567	i2s->capture_dma_data.maxburst = 8;
1568
1569	pm_runtime_enable(&pdev->dev);
1570	if (!pm_runtime_enabled(&pdev->dev)) {
1571		ret = sun4i_i2s_runtime_resume(&pdev->dev);
1572		if (ret)
1573			goto err_pm_disable;
1574	}
1575
1576	ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
1577	if (ret) {
1578		dev_err(&pdev->dev, "Could not initialise regmap fields\n");
1579		goto err_suspend;
1580	}
1581
1582	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1583	if (ret) {
1584		dev_err(&pdev->dev, "Could not register PCM\n");
1585		goto err_suspend;
1586	}
1587
1588	ret = devm_snd_soc_register_component(&pdev->dev,
1589					      &sun4i_i2s_component,
1590					      &sun4i_i2s_dai, 1);
1591	if (ret) {
1592		dev_err(&pdev->dev, "Could not register DAI\n");
1593		goto err_suspend;
1594	}
1595
1596	return 0;
1597
1598err_suspend:
1599	if (!pm_runtime_status_suspended(&pdev->dev))
1600		sun4i_i2s_runtime_suspend(&pdev->dev);
1601err_pm_disable:
1602	pm_runtime_disable(&pdev->dev);
1603	if (!IS_ERR(i2s->rst))
1604		reset_control_assert(i2s->rst);
1605
1606	return ret;
1607}
1608
1609static void sun4i_i2s_remove(struct platform_device *pdev)
1610{
1611	struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1612
1613	pm_runtime_disable(&pdev->dev);
1614	if (!pm_runtime_status_suspended(&pdev->dev))
1615		sun4i_i2s_runtime_suspend(&pdev->dev);
1616
1617	if (!IS_ERR(i2s->rst))
1618		reset_control_assert(i2s->rst);
1619}
1620
1621static const struct of_device_id sun4i_i2s_match[] = {
1622	{
1623		.compatible = "allwinner,sun4i-a10-i2s",
1624		.data = &sun4i_a10_i2s_quirks,
1625	},
1626	{
1627		.compatible = "allwinner,sun6i-a31-i2s",
1628		.data = &sun6i_a31_i2s_quirks,
1629	},
1630	{
1631		.compatible = "allwinner,sun8i-a83t-i2s",
1632		.data = &sun8i_a83t_i2s_quirks,
1633	},
1634	{
1635		.compatible = "allwinner,sun8i-h3-i2s",
1636		.data = &sun8i_h3_i2s_quirks,
1637	},
1638	{
1639		.compatible = "allwinner,sun50i-a64-codec-i2s",
1640		.data = &sun50i_a64_codec_i2s_quirks,
1641	},
1642	{
1643		.compatible = "allwinner,sun50i-h6-i2s",
1644		.data = &sun50i_h6_i2s_quirks,
1645	},
1646	{
1647		.compatible = "allwinner,sun50i-r329-i2s",
1648		.data = &sun50i_r329_i2s_quirks,
1649	},
1650	{}
1651};
1652MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1653
1654static const struct dev_pm_ops sun4i_i2s_pm_ops = {
1655	.runtime_resume		= sun4i_i2s_runtime_resume,
1656	.runtime_suspend	= sun4i_i2s_runtime_suspend,
1657};
1658
1659static struct platform_driver sun4i_i2s_driver = {
1660	.probe	= sun4i_i2s_probe,
1661	.remove_new = sun4i_i2s_remove,
1662	.driver	= {
1663		.name		= "sun4i-i2s",
1664		.of_match_table	= sun4i_i2s_match,
1665		.pm		= &sun4i_i2s_pm_ops,
1666	},
1667};
1668module_platform_driver(sun4i_i2s_driver);
1669
1670MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1671MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1672MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1673MODULE_LICENSE("GPL");
1674