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