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