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