xref: /linux/sound/soc/intel/keembay/kmb_platform.c (revision 6c8c1406)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright (C) 2020 Intel Corporation.
4 //
5 // Intel KeemBay Platform driver.
6 //
7 
8 #include <linux/bitrev.h>
9 #include <linux/clk.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/io.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_device.h>
15 #include <sound/dmaengine_pcm.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include "kmb_platform.h"
20 
21 #define PERIODS_MIN		2
22 #define PERIODS_MAX		48
23 #define PERIOD_BYTES_MIN	4096
24 #define BUFFER_BYTES_MAX	(PERIODS_MAX * PERIOD_BYTES_MIN)
25 #define TDM_OPERATION		5
26 #define I2S_OPERATION		0
27 #define DATA_WIDTH_CONFIG_BIT	6
28 #define TDM_CHANNEL_CONFIG_BIT	3
29 
30 static const struct snd_pcm_hardware kmb_pcm_hardware = {
31 	.info = SNDRV_PCM_INFO_INTERLEAVED |
32 		SNDRV_PCM_INFO_MMAP |
33 		SNDRV_PCM_INFO_MMAP_VALID |
34 		SNDRV_PCM_INFO_BATCH |
35 		SNDRV_PCM_INFO_BLOCK_TRANSFER,
36 	.rates = SNDRV_PCM_RATE_8000 |
37 		 SNDRV_PCM_RATE_16000 |
38 		 SNDRV_PCM_RATE_48000,
39 	.rate_min = 8000,
40 	.rate_max = 48000,
41 	.formats = SNDRV_PCM_FMTBIT_S16_LE |
42 		   SNDRV_PCM_FMTBIT_S24_LE |
43 		   SNDRV_PCM_FMTBIT_S32_LE |
44 		   SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
45 	.channels_min = 2,
46 	.channels_max = 2,
47 	.buffer_bytes_max = BUFFER_BYTES_MAX,
48 	.period_bytes_min = PERIOD_BYTES_MIN,
49 	.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
50 	.periods_min = PERIODS_MIN,
51 	.periods_max = PERIODS_MAX,
52 	.fifo_size = 16,
53 };
54 
55 /*
56  * Convert to ADV7511 HDMI hardware format.
57  * ADV7511 HDMI chip need parity bit replaced by block start bit and
58  * with the preamble bits left out.
59  * ALSA IEC958 subframe format:
60  * bit 0-3  = preamble (0x8 = block start)
61  *     4-7  = AUX (=0)
62  *     8-27 = audio data (without AUX if 24bit sample)
63  *     28   = validity
64  *     29   = user data
65  *     30   = channel status
66  *     31   = parity
67  *
68  * ADV7511 IEC958 subframe format:
69  * bit 0-23  = audio data
70  *     24    = validity
71  *     25    = user data
72  *     26    = channel status
73  *     27    = block start
74  *     28-31 = 0
75  * MSB to LSB bit reverse by software as hardware not supporting it.
76  */
77 static void hdmi_reformat_iec958(struct snd_pcm_runtime *runtime,
78 				 struct kmb_i2s_info *kmb_i2s,
79 				 unsigned int tx_ptr)
80 {
81 	u32(*buf)[2] = (void *)runtime->dma_area;
82 	unsigned long temp;
83 	u32 i, j, sample;
84 
85 	for (i = 0; i < kmb_i2s->fifo_th; i++) {
86 		j = 0;
87 		do {
88 			temp = buf[tx_ptr][j];
89 			/* Replace parity with block start*/
90 			assign_bit(31, &temp, (BIT(3) & temp));
91 			sample = bitrev32(temp);
92 			buf[tx_ptr][j] = sample << 4;
93 			j++;
94 		} while (j < 2);
95 		tx_ptr++;
96 	}
97 }
98 
99 static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s,
100 				  struct snd_pcm_runtime *runtime,
101 				  unsigned int tx_ptr, bool *period_elapsed)
102 {
103 	unsigned int period_pos = tx_ptr % runtime->period_size;
104 	void __iomem *i2s_base = kmb_i2s->i2s_base;
105 	void *buf = runtime->dma_area;
106 	int i;
107 
108 	if (kmb_i2s->iec958_fmt)
109 		hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr);
110 
111 	/* KMB i2s uses two separate L/R FIFO */
112 	for (i = 0; i < kmb_i2s->fifo_th; i++) {
113 		if (kmb_i2s->config.data_width == 16) {
114 			writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
115 			writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
116 		} else {
117 			writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
118 			writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
119 		}
120 
121 		period_pos++;
122 
123 		if (++tx_ptr >= runtime->buffer_size)
124 			tx_ptr = 0;
125 	}
126 
127 	*period_elapsed = period_pos >= runtime->period_size;
128 
129 	return tx_ptr;
130 }
131 
132 static unsigned int kmb_pcm_rx_fn(struct kmb_i2s_info *kmb_i2s,
133 				  struct snd_pcm_runtime *runtime,
134 				  unsigned int rx_ptr, bool *period_elapsed)
135 {
136 	unsigned int period_pos = rx_ptr % runtime->period_size;
137 	void __iomem *i2s_base = kmb_i2s->i2s_base;
138 	int chan = kmb_i2s->config.chan_nr;
139 	void *buf = runtime->dma_area;
140 	int i, j;
141 
142 	/* KMB i2s uses two separate L/R FIFO */
143 	for (i = 0; i < kmb_i2s->fifo_th; i++) {
144 		for (j = 0; j < chan / 2; j++) {
145 			if (kmb_i2s->config.data_width == 16) {
146 				((u16 *)buf)[rx_ptr * chan + (j * 2)] =
147 						readl(i2s_base + LRBR_LTHR(j));
148 				((u16 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
149 						readl(i2s_base + RRBR_RTHR(j));
150 			} else {
151 				((u32 *)buf)[rx_ptr * chan + (j * 2)] =
152 						readl(i2s_base + LRBR_LTHR(j));
153 				((u32 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
154 						readl(i2s_base + RRBR_RTHR(j));
155 			}
156 		}
157 		period_pos++;
158 
159 		if (++rx_ptr >= runtime->buffer_size)
160 			rx_ptr = 0;
161 	}
162 
163 	*period_elapsed = period_pos >= runtime->period_size;
164 
165 	return rx_ptr;
166 }
167 
168 static inline void kmb_i2s_disable_channels(struct kmb_i2s_info *kmb_i2s,
169 					    u32 stream)
170 {
171 	u32 i;
172 
173 	/* Disable all channels regardless of configuration*/
174 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
175 		for (i = 0; i < MAX_ISR; i++)
176 			writel(0, kmb_i2s->i2s_base + TER(i));
177 	} else {
178 		for (i = 0; i < MAX_ISR; i++)
179 			writel(0, kmb_i2s->i2s_base + RER(i));
180 	}
181 }
182 
183 static inline void kmb_i2s_clear_irqs(struct kmb_i2s_info *kmb_i2s, u32 stream)
184 {
185 	struct i2s_clk_config_data *config = &kmb_i2s->config;
186 	u32 i;
187 
188 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
189 		for (i = 0; i < config->chan_nr / 2; i++)
190 			readl(kmb_i2s->i2s_base + TOR(i));
191 	} else {
192 		for (i = 0; i < config->chan_nr / 2; i++)
193 			readl(kmb_i2s->i2s_base + ROR(i));
194 	}
195 }
196 
197 static inline void kmb_i2s_irq_trigger(struct kmb_i2s_info *kmb_i2s,
198 				       u32 stream, int chan_nr, bool trigger)
199 {
200 	u32 i, irq;
201 	u32 flag;
202 
203 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
204 		flag = TX_INT_FLAG;
205 	else
206 		flag = RX_INT_FLAG;
207 
208 	for (i = 0; i < chan_nr / 2; i++) {
209 		irq = readl(kmb_i2s->i2s_base + IMR(i));
210 
211 		if (trigger)
212 			irq = irq & ~flag;
213 		else
214 			irq = irq | flag;
215 
216 		writel(irq, kmb_i2s->i2s_base + IMR(i));
217 	}
218 }
219 
220 static void kmb_pcm_operation(struct kmb_i2s_info *kmb_i2s, bool playback)
221 {
222 	struct snd_pcm_substream *substream;
223 	bool period_elapsed;
224 	unsigned int new_ptr;
225 	unsigned int ptr;
226 
227 	if (playback)
228 		substream = kmb_i2s->tx_substream;
229 	else
230 		substream = kmb_i2s->rx_substream;
231 
232 	if (!substream || !snd_pcm_running(substream))
233 		return;
234 
235 	if (playback) {
236 		ptr = kmb_i2s->tx_ptr;
237 		new_ptr = kmb_pcm_tx_fn(kmb_i2s, substream->runtime,
238 					ptr, &period_elapsed);
239 		cmpxchg(&kmb_i2s->tx_ptr, ptr, new_ptr);
240 	} else {
241 		ptr = kmb_i2s->rx_ptr;
242 		new_ptr = kmb_pcm_rx_fn(kmb_i2s, substream->runtime,
243 					ptr, &period_elapsed);
244 		cmpxchg(&kmb_i2s->rx_ptr, ptr, new_ptr);
245 	}
246 
247 	if (period_elapsed)
248 		snd_pcm_period_elapsed(substream);
249 }
250 
251 static int kmb_pcm_open(struct snd_soc_component *component,
252 			struct snd_pcm_substream *substream)
253 {
254 	struct snd_pcm_runtime *runtime = substream->runtime;
255 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
256 	struct kmb_i2s_info *kmb_i2s;
257 
258 	kmb_i2s = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
259 	snd_soc_set_runtime_hwparams(substream, &kmb_pcm_hardware);
260 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
261 	runtime->private_data = kmb_i2s;
262 
263 	return 0;
264 }
265 
266 static int kmb_pcm_trigger(struct snd_soc_component *component,
267 			   struct snd_pcm_substream *substream, int cmd)
268 {
269 	struct snd_pcm_runtime *runtime = substream->runtime;
270 	struct kmb_i2s_info *kmb_i2s = runtime->private_data;
271 
272 	switch (cmd) {
273 	case SNDRV_PCM_TRIGGER_START:
274 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
275 			kmb_i2s->tx_ptr = 0;
276 			kmb_i2s->tx_substream = substream;
277 		} else {
278 			kmb_i2s->rx_ptr = 0;
279 			kmb_i2s->rx_substream = substream;
280 		}
281 		break;
282 	case SNDRV_PCM_TRIGGER_STOP:
283 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
284 			kmb_i2s->tx_substream = NULL;
285 		else
286 			kmb_i2s->rx_substream = NULL;
287 		kmb_i2s->iec958_fmt = false;
288 		break;
289 	default:
290 		return -EINVAL;
291 	}
292 
293 	return 0;
294 }
295 
296 static irqreturn_t kmb_i2s_irq_handler(int irq, void *dev_id)
297 {
298 	struct kmb_i2s_info *kmb_i2s = dev_id;
299 	struct i2s_clk_config_data *config = &kmb_i2s->config;
300 	irqreturn_t ret = IRQ_NONE;
301 	u32 tx_enabled = 0;
302 	u32 isr[4];
303 	int i;
304 
305 	for (i = 0; i < config->chan_nr / 2; i++)
306 		isr[i] = readl(kmb_i2s->i2s_base + ISR(i));
307 
308 	kmb_i2s_clear_irqs(kmb_i2s, SNDRV_PCM_STREAM_PLAYBACK);
309 	kmb_i2s_clear_irqs(kmb_i2s, SNDRV_PCM_STREAM_CAPTURE);
310 	/* Only check TX interrupt if TX is active */
311 	tx_enabled = readl(kmb_i2s->i2s_base + ITER);
312 
313 	/*
314 	 * Data available. Retrieve samples from FIFO
315 	 */
316 
317 	/*
318 	 * 8 channel audio will have isr[0..2] triggered,
319 	 * reading the specific isr based on the audio configuration,
320 	 * to avoid reading the buffers too early.
321 	 */
322 	switch (config->chan_nr) {
323 	case 2:
324 		if (isr[0] & ISR_RXDA)
325 			kmb_pcm_operation(kmb_i2s, false);
326 		ret = IRQ_HANDLED;
327 		break;
328 	case 4:
329 		if (isr[1] & ISR_RXDA)
330 			kmb_pcm_operation(kmb_i2s, false);
331 		ret = IRQ_HANDLED;
332 		break;
333 	case 8:
334 		if (isr[3] & ISR_RXDA)
335 			kmb_pcm_operation(kmb_i2s, false);
336 		ret = IRQ_HANDLED;
337 		break;
338 	}
339 
340 	for (i = 0; i < config->chan_nr / 2; i++) {
341 		/*
342 		 * Check if TX fifo is empty. If empty fill FIFO with samples
343 		 */
344 		if ((isr[i] & ISR_TXFE) && tx_enabled) {
345 			kmb_pcm_operation(kmb_i2s, true);
346 			ret = IRQ_HANDLED;
347 		}
348 
349 		/* Error Handling: TX */
350 		if (isr[i] & ISR_TXFO) {
351 			dev_dbg(kmb_i2s->dev, "TX overrun (ch_id=%d)\n", i);
352 			ret = IRQ_HANDLED;
353 		}
354 		/* Error Handling: RX */
355 		if (isr[i] & ISR_RXFO) {
356 			dev_dbg(kmb_i2s->dev, "RX overrun (ch_id=%d)\n", i);
357 			ret = IRQ_HANDLED;
358 		}
359 	}
360 
361 	return ret;
362 }
363 
364 static int kmb_platform_pcm_new(struct snd_soc_component *component,
365 				struct snd_soc_pcm_runtime *soc_runtime)
366 {
367 	size_t size = kmb_pcm_hardware.buffer_bytes_max;
368 	/* Use SNDRV_DMA_TYPE_CONTINUOUS as KMB doesn't use PCI sg buffer */
369 	snd_pcm_set_managed_buffer_all(soc_runtime->pcm,
370 				       SNDRV_DMA_TYPE_CONTINUOUS,
371 				       NULL, size, size);
372 	return 0;
373 }
374 
375 static snd_pcm_uframes_t kmb_pcm_pointer(struct snd_soc_component *component,
376 					 struct snd_pcm_substream *substream)
377 {
378 	struct snd_pcm_runtime *runtime = substream->runtime;
379 	struct kmb_i2s_info *kmb_i2s = runtime->private_data;
380 	snd_pcm_uframes_t pos;
381 
382 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
383 		pos = kmb_i2s->tx_ptr;
384 	else
385 		pos = kmb_i2s->rx_ptr;
386 
387 	return pos < runtime->buffer_size ? pos : 0;
388 }
389 
390 static const struct snd_soc_component_driver kmb_component = {
391 	.name			= "kmb",
392 	.pcm_construct		= kmb_platform_pcm_new,
393 	.open			= kmb_pcm_open,
394 	.trigger		= kmb_pcm_trigger,
395 	.pointer		= kmb_pcm_pointer,
396 	.legacy_dai_naming	= 1,
397 };
398 
399 static const struct snd_soc_component_driver kmb_component_dma = {
400 	.name			= "kmb",
401 	.legacy_dai_naming	= 1,
402 };
403 
404 static int kmb_probe(struct snd_soc_dai *cpu_dai)
405 {
406 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
407 
408 	if (kmb_i2s->use_pio)
409 		return 0;
410 
411 	snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data,
412 				  &kmb_i2s->capture_dma_data);
413 
414 	return 0;
415 }
416 
417 static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
418 {
419 	u32 dma_reg;
420 
421 	dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR);
422 	/* Enable DMA handshake for stream */
423 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
424 		dma_reg |= I2S_DMAEN_TXBLOCK;
425 	else
426 		dma_reg |= I2S_DMAEN_RXBLOCK;
427 
428 	writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
429 }
430 
431 static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
432 {
433 	u32 dma_reg;
434 
435 	dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR);
436 	/* Disable DMA handshake for stream */
437 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
438 		dma_reg &= ~I2S_DMAEN_TXBLOCK;
439 		writel(1, kmb_i2s->i2s_base + I2S_RTXDMA);
440 	} else {
441 		dma_reg &= ~I2S_DMAEN_RXBLOCK;
442 		writel(1, kmb_i2s->i2s_base + I2S_RRXDMA);
443 	}
444 	writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
445 }
446 
447 static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s,
448 			  struct snd_pcm_substream *substream)
449 {
450 	struct i2s_clk_config_data *config = &kmb_i2s->config;
451 
452 	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
453 	writel(1, kmb_i2s->i2s_base + IER);
454 
455 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
456 		writel(1, kmb_i2s->i2s_base + ITER);
457 	else
458 		writel(1, kmb_i2s->i2s_base + IRER);
459 
460 	if (kmb_i2s->use_pio)
461 		kmb_i2s_irq_trigger(kmb_i2s, substream->stream,
462 				    config->chan_nr, true);
463 	else
464 		kmb_i2s_enable_dma(kmb_i2s, substream->stream);
465 
466 	if (kmb_i2s->clock_provider)
467 		writel(1, kmb_i2s->i2s_base + CER);
468 	else
469 		writel(0, kmb_i2s->i2s_base + CER);
470 }
471 
472 static void kmb_i2s_stop(struct kmb_i2s_info *kmb_i2s,
473 			 struct snd_pcm_substream *substream)
474 {
475 	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
476 	kmb_i2s_clear_irqs(kmb_i2s, substream->stream);
477 
478 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 		writel(0, kmb_i2s->i2s_base + ITER);
480 	else
481 		writel(0, kmb_i2s->i2s_base + IRER);
482 
483 	kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
484 
485 	if (!kmb_i2s->active) {
486 		writel(0, kmb_i2s->i2s_base + CER);
487 		writel(0, kmb_i2s->i2s_base + IER);
488 	}
489 }
490 
491 static void kmb_disable_clk(void *clk)
492 {
493 	clk_disable_unprepare(clk);
494 }
495 
496 static int kmb_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
497 {
498 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
499 	int ret;
500 
501 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
502 	case SND_SOC_DAIFMT_BC_FC:
503 		kmb_i2s->clock_provider = false;
504 		ret = 0;
505 		break;
506 	case SND_SOC_DAIFMT_BP_FP:
507 		writel(CLOCK_PROVIDER_MODE, kmb_i2s->pss_base + I2S_GEN_CFG_0);
508 
509 		ret = clk_prepare_enable(kmb_i2s->clk_i2s);
510 		if (ret < 0)
511 			return ret;
512 
513 		ret = devm_add_action_or_reset(kmb_i2s->dev, kmb_disable_clk,
514 					       kmb_i2s->clk_i2s);
515 		if (ret)
516 			return ret;
517 
518 		kmb_i2s->clock_provider = true;
519 		break;
520 	default:
521 		return -EINVAL;
522 	}
523 
524 	return ret;
525 }
526 
527 static int kmb_dai_trigger(struct snd_pcm_substream *substream,
528 			   int cmd, struct snd_soc_dai *cpu_dai)
529 {
530 	struct kmb_i2s_info *kmb_i2s  = snd_soc_dai_get_drvdata(cpu_dai);
531 
532 	switch (cmd) {
533 	case SNDRV_PCM_TRIGGER_START:
534 		/* Keep track of i2s activity before turn off
535 		 * the i2s interface
536 		 */
537 		kmb_i2s->active++;
538 		kmb_i2s_start(kmb_i2s, substream);
539 		break;
540 	case SNDRV_PCM_TRIGGER_STOP:
541 		kmb_i2s->active--;
542 		if (kmb_i2s->use_pio)
543 			kmb_i2s_stop(kmb_i2s, substream);
544 		break;
545 	default:
546 		return  -EINVAL;
547 	}
548 
549 	return 0;
550 }
551 
552 static void kmb_i2s_config(struct kmb_i2s_info *kmb_i2s, int stream)
553 {
554 	struct i2s_clk_config_data *config = &kmb_i2s->config;
555 	u32 ch_reg;
556 
557 	kmb_i2s_disable_channels(kmb_i2s, stream);
558 
559 	for (ch_reg = 0; ch_reg < config->chan_nr / 2; ch_reg++) {
560 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
561 			writel(kmb_i2s->xfer_resolution,
562 			       kmb_i2s->i2s_base + TCR(ch_reg));
563 
564 			writel(kmb_i2s->fifo_th - 1,
565 			       kmb_i2s->i2s_base + TFCR(ch_reg));
566 
567 			writel(1, kmb_i2s->i2s_base + TER(ch_reg));
568 		} else {
569 			writel(kmb_i2s->xfer_resolution,
570 			       kmb_i2s->i2s_base + RCR(ch_reg));
571 
572 			writel(kmb_i2s->fifo_th - 1,
573 			       kmb_i2s->i2s_base + RFCR(ch_reg));
574 
575 			writel(1, kmb_i2s->i2s_base + RER(ch_reg));
576 		}
577 	}
578 }
579 
580 static int kmb_dai_hw_params(struct snd_pcm_substream *substream,
581 			     struct snd_pcm_hw_params *hw_params,
582 			     struct snd_soc_dai *cpu_dai)
583 {
584 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
585 	struct i2s_clk_config_data *config = &kmb_i2s->config;
586 	u32 write_val;
587 	int ret;
588 
589 	switch (params_format(hw_params)) {
590 	case SNDRV_PCM_FORMAT_S16_LE:
591 		config->data_width = 16;
592 		kmb_i2s->ccr = 0x00;
593 		kmb_i2s->xfer_resolution = 0x02;
594 		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
595 		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
596 		break;
597 	case SNDRV_PCM_FORMAT_S24_LE:
598 		config->data_width = 32;
599 		kmb_i2s->ccr = 0x14;
600 		kmb_i2s->xfer_resolution = 0x05;
601 		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
602 		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
603 		break;
604 	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
605 		kmb_i2s->iec958_fmt = true;
606 		fallthrough;
607 	case SNDRV_PCM_FORMAT_S32_LE:
608 		config->data_width = 32;
609 		kmb_i2s->ccr = 0x10;
610 		kmb_i2s->xfer_resolution = 0x05;
611 		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
612 		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
613 		break;
614 	default:
615 		dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt");
616 		return -EINVAL;
617 	}
618 
619 	config->chan_nr = params_channels(hw_params);
620 
621 	switch (config->chan_nr) {
622 	case 8:
623 	case 4:
624 		/*
625 		 * Platform is not capable of providing clocks for
626 		 * multi channel audio
627 		 */
628 		if (kmb_i2s->clock_provider)
629 			return -EINVAL;
630 
631 		write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
632 				(config->data_width << DATA_WIDTH_CONFIG_BIT) |
633 				TDM_OPERATION;
634 
635 		writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
636 		break;
637 	case 2:
638 		/*
639 		 * Platform is only capable of providing clocks need for
640 		 * 2 channel master mode
641 		 */
642 		if (!(kmb_i2s->clock_provider))
643 			return -EINVAL;
644 
645 		write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
646 				(config->data_width << DATA_WIDTH_CONFIG_BIT) |
647 				CLOCK_PROVIDER_MODE | I2S_OPERATION;
648 
649 		writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
650 		break;
651 	default:
652 		dev_dbg(kmb_i2s->dev, "channel not supported\n");
653 		return -EINVAL;
654 	}
655 
656 	kmb_i2s_config(kmb_i2s, substream->stream);
657 
658 	writel(kmb_i2s->ccr, kmb_i2s->i2s_base + CCR);
659 
660 	config->sample_rate = params_rate(hw_params);
661 
662 	if (kmb_i2s->clock_provider) {
663 		/* Only 2 ch supported in Master mode */
664 		u32 bitclk = config->sample_rate * config->data_width * 2;
665 
666 		ret = clk_set_rate(kmb_i2s->clk_i2s, bitclk);
667 		if (ret) {
668 			dev_err(kmb_i2s->dev,
669 				"Can't set I2S clock rate: %d\n", ret);
670 			return ret;
671 		}
672 	}
673 
674 	return 0;
675 }
676 
677 static int kmb_dai_prepare(struct snd_pcm_substream *substream,
678 			   struct snd_soc_dai *cpu_dai)
679 {
680 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
681 
682 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
683 		writel(1, kmb_i2s->i2s_base + TXFFR);
684 	else
685 		writel(1, kmb_i2s->i2s_base + RXFFR);
686 
687 	return 0;
688 }
689 
690 static int kmb_dai_startup(struct snd_pcm_substream *substream,
691 			   struct snd_soc_dai *cpu_dai)
692 {
693 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
694 	struct snd_dmaengine_dai_dma_data *dma_data;
695 
696 	if (kmb_i2s->use_pio)
697 		return 0;
698 
699 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
700 		dma_data = &kmb_i2s->play_dma_data;
701 	else
702 		dma_data = &kmb_i2s->capture_dma_data;
703 
704 	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
705 
706 	return 0;
707 }
708 
709 static int kmb_dai_hw_free(struct snd_pcm_substream *substream,
710 			   struct snd_soc_dai *cpu_dai)
711 {
712 	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
713 	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
714 	if (kmb_i2s->use_pio)
715 		kmb_i2s_clear_irqs(kmb_i2s, substream->stream);
716 
717 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 		writel(0, kmb_i2s->i2s_base + ITER);
719 	else
720 		writel(0, kmb_i2s->i2s_base + IRER);
721 
722 	if (kmb_i2s->use_pio)
723 		kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
724 	else
725 		kmb_i2s_disable_dma(kmb_i2s, substream->stream);
726 
727 	if (!kmb_i2s->active) {
728 		writel(0, kmb_i2s->i2s_base + CER);
729 		writel(0, kmb_i2s->i2s_base + IER);
730 	}
731 
732 	return 0;
733 }
734 
735 static const struct snd_soc_dai_ops kmb_dai_ops = {
736 	.startup	= kmb_dai_startup,
737 	.trigger	= kmb_dai_trigger,
738 	.hw_params	= kmb_dai_hw_params,
739 	.hw_free	= kmb_dai_hw_free,
740 	.prepare	= kmb_dai_prepare,
741 	.set_fmt	= kmb_set_dai_fmt,
742 };
743 
744 static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = {
745 	{
746 		.name = "intel_kmb_hdmi_i2s",
747 		.playback = {
748 			.channels_min = 2,
749 			.channels_max = 2,
750 			.rates = SNDRV_PCM_RATE_48000,
751 			.rate_min = 48000,
752 			.rate_max = 48000,
753 			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
754 				    SNDRV_PCM_FMTBIT_S24_LE |
755 				    SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
756 		},
757 		.ops = &kmb_dai_ops,
758 		.probe = kmb_probe,
759 	},
760 };
761 
762 static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = {
763 	{
764 		.name = "intel_kmb_i2s",
765 		.playback = {
766 			.channels_min = 2,
767 			.channels_max = 2,
768 			.rates = SNDRV_PCM_RATE_8000 |
769 				 SNDRV_PCM_RATE_16000 |
770 				 SNDRV_PCM_RATE_48000,
771 			.rate_min = 8000,
772 			.rate_max = 48000,
773 			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
774 				    SNDRV_PCM_FMTBIT_S24_LE |
775 				    SNDRV_PCM_FMTBIT_S16_LE),
776 		},
777 		.capture = {
778 			.channels_min = 2,
779 			.channels_max = 2,
780 			.rates = SNDRV_PCM_RATE_8000 |
781 				 SNDRV_PCM_RATE_16000 |
782 				 SNDRV_PCM_RATE_48000,
783 			.rate_min = 8000,
784 			.rate_max = 48000,
785 			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
786 				    SNDRV_PCM_FMTBIT_S24_LE |
787 				    SNDRV_PCM_FMTBIT_S16_LE),
788 		},
789 		.ops = &kmb_dai_ops,
790 		.probe = kmb_probe,
791 	},
792 };
793 
794 static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = {
795 	{
796 		.name = "intel_kmb_tdm",
797 		.capture = {
798 			.channels_min = 4,
799 			.channels_max = 8,
800 			.rates = SNDRV_PCM_RATE_8000 |
801 				 SNDRV_PCM_RATE_16000 |
802 				 SNDRV_PCM_RATE_48000,
803 			.rate_min = 8000,
804 			.rate_max = 48000,
805 			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
806 				    SNDRV_PCM_FMTBIT_S24_LE |
807 				    SNDRV_PCM_FMTBIT_S16_LE),
808 		},
809 		.ops = &kmb_dai_ops,
810 		.probe = kmb_probe,
811 	},
812 };
813 
814 static const struct of_device_id kmb_plat_of_match[] = {
815 	{ .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai},
816 	{ .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai},
817 	{ .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai},
818 	{}
819 };
820 
821 static int kmb_plat_dai_probe(struct platform_device *pdev)
822 {
823 	struct device_node *np = pdev->dev.of_node;
824 	struct snd_soc_dai_driver *kmb_i2s_dai;
825 	const struct of_device_id *match;
826 	struct device *dev = &pdev->dev;
827 	struct kmb_i2s_info *kmb_i2s;
828 	struct resource *res;
829 	int ret, irq;
830 	u32 comp1_reg;
831 
832 	kmb_i2s = devm_kzalloc(dev, sizeof(*kmb_i2s), GFP_KERNEL);
833 	if (!kmb_i2s)
834 		return -ENOMEM;
835 
836 	kmb_i2s_dai = devm_kzalloc(dev, sizeof(*kmb_i2s_dai), GFP_KERNEL);
837 	if (!kmb_i2s_dai)
838 		return -ENOMEM;
839 
840 	match = of_match_device(kmb_plat_of_match, &pdev->dev);
841 	if (!match) {
842 		dev_err(&pdev->dev, "Error: No device match found\n");
843 		return -ENODEV;
844 	}
845 	kmb_i2s_dai = (struct snd_soc_dai_driver *) match->data;
846 
847 	/* Prepare the related clocks */
848 	kmb_i2s->clk_apb = devm_clk_get(dev, "apb_clk");
849 	if (IS_ERR(kmb_i2s->clk_apb)) {
850 		dev_err(dev, "Failed to get apb clock\n");
851 		return PTR_ERR(kmb_i2s->clk_apb);
852 	}
853 
854 	ret = clk_prepare_enable(kmb_i2s->clk_apb);
855 	if (ret < 0)
856 		return ret;
857 
858 	ret = devm_add_action_or_reset(dev, kmb_disable_clk, kmb_i2s->clk_apb);
859 	if (ret) {
860 		dev_err(dev, "Failed to add clk_apb reset action\n");
861 		return ret;
862 	}
863 
864 	kmb_i2s->clk_i2s = devm_clk_get(dev, "osc");
865 	if (IS_ERR(kmb_i2s->clk_i2s)) {
866 		dev_err(dev, "Failed to get osc clock\n");
867 		return PTR_ERR(kmb_i2s->clk_i2s);
868 	}
869 
870 	kmb_i2s->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
871 	if (IS_ERR(kmb_i2s->i2s_base))
872 		return PTR_ERR(kmb_i2s->i2s_base);
873 
874 	kmb_i2s->pss_base = devm_platform_ioremap_resource(pdev, 1);
875 	if (IS_ERR(kmb_i2s->pss_base))
876 		return PTR_ERR(kmb_i2s->pss_base);
877 
878 	kmb_i2s->dev = &pdev->dev;
879 
880 	comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1);
881 
882 	kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2;
883 
884 	kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));
885 
886 	if (kmb_i2s->use_pio) {
887 		irq = platform_get_irq_optional(pdev, 0);
888 		if (irq > 0) {
889 			ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
890 					       pdev->name, kmb_i2s);
891 			if (ret < 0) {
892 				dev_err(dev, "failed to request irq\n");
893 				return ret;
894 			}
895 		}
896 		ret = devm_snd_soc_register_component(dev, &kmb_component,
897 						      kmb_i2s_dai, 1);
898 	} else {
899 		kmb_i2s->play_dma_data.addr = res->start + I2S_TXDMA;
900 		kmb_i2s->capture_dma_data.addr = res->start + I2S_RXDMA;
901 		ret = snd_dmaengine_pcm_register(&pdev->dev,
902 						 NULL, 0);
903 		if (ret) {
904 			dev_err(&pdev->dev, "could not register dmaengine: %d\n",
905 				ret);
906 			return ret;
907 		}
908 		ret = devm_snd_soc_register_component(dev, &kmb_component_dma,
909 						      kmb_i2s_dai, 1);
910 	}
911 
912 	if (ret) {
913 		dev_err(dev, "not able to register dai\n");
914 		return ret;
915 	}
916 
917 	/* To ensure none of the channels are enabled at boot up */
918 	kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_PLAYBACK);
919 	kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_CAPTURE);
920 
921 	dev_set_drvdata(dev, kmb_i2s);
922 
923 	return ret;
924 }
925 
926 static struct platform_driver kmb_plat_dai_driver = {
927 	.driver		= {
928 		.name		= "kmb-plat-dai",
929 		.of_match_table = kmb_plat_of_match,
930 	},
931 	.probe		= kmb_plat_dai_probe,
932 };
933 
934 module_platform_driver(kmb_plat_dai_driver);
935 
936 MODULE_DESCRIPTION("ASoC Intel KeemBay Platform driver");
937 MODULE_AUTHOR("Sia Jee Heng <jee.heng.sia@intel.com>");
938 MODULE_AUTHOR("Sit, Michael Wei Hong <michael.wei.hong.sit@intel.com>");
939 MODULE_LICENSE("GPL v2");
940 MODULE_ALIAS("platform:kmb_platform");
941