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 */
hdmi_reformat_iec958(struct snd_pcm_runtime * runtime,struct kmb_i2s_info * kmb_i2s,unsigned int tx_ptr)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
kmb_pcm_tx_fn(struct kmb_i2s_info * kmb_i2s,struct snd_pcm_runtime * runtime,unsigned int tx_ptr,bool * period_elapsed)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
kmb_pcm_rx_fn(struct kmb_i2s_info * kmb_i2s,struct snd_pcm_runtime * runtime,unsigned int rx_ptr,bool * period_elapsed)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
kmb_i2s_disable_channels(struct kmb_i2s_info * kmb_i2s,u32 stream)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
kmb_i2s_clear_irqs(struct kmb_i2s_info * kmb_i2s,u32 stream)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
kmb_i2s_irq_trigger(struct kmb_i2s_info * kmb_i2s,u32 stream,int chan_nr,bool trigger)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
kmb_pcm_operation(struct kmb_i2s_info * kmb_i2s,bool playback)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
kmb_pcm_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)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
kmb_pcm_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)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
kmb_i2s_irq_handler(int irq,void * dev_id)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
kmb_platform_pcm_new(struct snd_soc_component * component,struct snd_soc_pcm_runtime * soc_runtime)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
kmb_pcm_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)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 };
397
398 static const struct snd_soc_component_driver kmb_component_dma = {
399 .name = "kmb",
400 };
401
kmb_probe(struct snd_soc_dai * cpu_dai)402 static int kmb_probe(struct snd_soc_dai *cpu_dai)
403 {
404 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
405
406 if (kmb_i2s->use_pio)
407 return 0;
408
409 snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data,
410 &kmb_i2s->capture_dma_data);
411
412 return 0;
413 }
414
kmb_i2s_enable_dma(struct kmb_i2s_info * kmb_i2s,u32 stream)415 static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
416 {
417 u32 dma_reg;
418
419 dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR);
420 /* Enable DMA handshake for stream */
421 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
422 dma_reg |= I2S_DMAEN_TXBLOCK;
423 else
424 dma_reg |= I2S_DMAEN_RXBLOCK;
425
426 writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
427 }
428
kmb_i2s_disable_dma(struct kmb_i2s_info * kmb_i2s,u32 stream)429 static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
430 {
431 u32 dma_reg;
432
433 dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR);
434 /* Disable DMA handshake for stream */
435 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
436 dma_reg &= ~I2S_DMAEN_TXBLOCK;
437 writel(1, kmb_i2s->i2s_base + I2S_RTXDMA);
438 } else {
439 dma_reg &= ~I2S_DMAEN_RXBLOCK;
440 writel(1, kmb_i2s->i2s_base + I2S_RRXDMA);
441 }
442 writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
443 }
444
kmb_i2s_start(struct kmb_i2s_info * kmb_i2s,struct snd_pcm_substream * substream)445 static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s,
446 struct snd_pcm_substream *substream)
447 {
448 struct i2s_clk_config_data *config = &kmb_i2s->config;
449
450 /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
451 writel(1, kmb_i2s->i2s_base + IER);
452
453 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
454 writel(1, kmb_i2s->i2s_base + ITER);
455 else
456 writel(1, kmb_i2s->i2s_base + IRER);
457
458 if (kmb_i2s->use_pio)
459 kmb_i2s_irq_trigger(kmb_i2s, substream->stream,
460 config->chan_nr, true);
461 else
462 kmb_i2s_enable_dma(kmb_i2s, substream->stream);
463
464 if (kmb_i2s->clock_provider)
465 writel(1, kmb_i2s->i2s_base + CER);
466 else
467 writel(0, kmb_i2s->i2s_base + CER);
468 }
469
kmb_i2s_stop(struct kmb_i2s_info * kmb_i2s,struct snd_pcm_substream * substream)470 static void kmb_i2s_stop(struct kmb_i2s_info *kmb_i2s,
471 struct snd_pcm_substream *substream)
472 {
473 /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
474 kmb_i2s_clear_irqs(kmb_i2s, substream->stream);
475
476 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
477 writel(0, kmb_i2s->i2s_base + ITER);
478 else
479 writel(0, kmb_i2s->i2s_base + IRER);
480
481 kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
482
483 if (!kmb_i2s->active) {
484 writel(0, kmb_i2s->i2s_base + CER);
485 writel(0, kmb_i2s->i2s_base + IER);
486 }
487 }
488
kmb_disable_clk(void * clk)489 static void kmb_disable_clk(void *clk)
490 {
491 clk_disable_unprepare(clk);
492 }
493
kmb_set_dai_fmt(struct snd_soc_dai * cpu_dai,unsigned int fmt)494 static int kmb_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
495 {
496 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
497 int ret;
498
499 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
500 case SND_SOC_DAIFMT_CBP_CFP:
501 kmb_i2s->clock_provider = false;
502 ret = 0;
503 break;
504 case SND_SOC_DAIFMT_CBC_CFC:
505 writel(CLOCK_PROVIDER_MODE, kmb_i2s->pss_base + I2S_GEN_CFG_0);
506
507 ret = clk_prepare_enable(kmb_i2s->clk_i2s);
508 if (ret < 0)
509 return ret;
510
511 ret = devm_add_action_or_reset(kmb_i2s->dev, kmb_disable_clk,
512 kmb_i2s->clk_i2s);
513 if (ret)
514 return ret;
515
516 kmb_i2s->clock_provider = true;
517 break;
518 default:
519 return -EINVAL;
520 }
521
522 return ret;
523 }
524
kmb_dai_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * cpu_dai)525 static int kmb_dai_trigger(struct snd_pcm_substream *substream,
526 int cmd, struct snd_soc_dai *cpu_dai)
527 {
528 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
529
530 switch (cmd) {
531 case SNDRV_PCM_TRIGGER_START:
532 /* Keep track of i2s activity before turn off
533 * the i2s interface
534 */
535 kmb_i2s->active++;
536 kmb_i2s_start(kmb_i2s, substream);
537 break;
538 case SNDRV_PCM_TRIGGER_STOP:
539 kmb_i2s->active--;
540 if (kmb_i2s->use_pio)
541 kmb_i2s_stop(kmb_i2s, substream);
542 break;
543 default:
544 return -EINVAL;
545 }
546
547 return 0;
548 }
549
kmb_i2s_config(struct kmb_i2s_info * kmb_i2s,int stream)550 static void kmb_i2s_config(struct kmb_i2s_info *kmb_i2s, int stream)
551 {
552 struct i2s_clk_config_data *config = &kmb_i2s->config;
553 u32 ch_reg;
554
555 kmb_i2s_disable_channels(kmb_i2s, stream);
556
557 for (ch_reg = 0; ch_reg < config->chan_nr / 2; ch_reg++) {
558 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
559 writel(kmb_i2s->xfer_resolution,
560 kmb_i2s->i2s_base + TCR(ch_reg));
561
562 writel(kmb_i2s->fifo_th - 1,
563 kmb_i2s->i2s_base + TFCR(ch_reg));
564
565 writel(1, kmb_i2s->i2s_base + TER(ch_reg));
566 } else {
567 writel(kmb_i2s->xfer_resolution,
568 kmb_i2s->i2s_base + RCR(ch_reg));
569
570 writel(kmb_i2s->fifo_th - 1,
571 kmb_i2s->i2s_base + RFCR(ch_reg));
572
573 writel(1, kmb_i2s->i2s_base + RER(ch_reg));
574 }
575 }
576 }
577
kmb_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * cpu_dai)578 static int kmb_dai_hw_params(struct snd_pcm_substream *substream,
579 struct snd_pcm_hw_params *hw_params,
580 struct snd_soc_dai *cpu_dai)
581 {
582 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
583 struct i2s_clk_config_data *config = &kmb_i2s->config;
584 u32 write_val;
585 int ret;
586
587 switch (params_format(hw_params)) {
588 case SNDRV_PCM_FORMAT_S16_LE:
589 config->data_width = 16;
590 kmb_i2s->ccr = 0x00;
591 kmb_i2s->xfer_resolution = 0x02;
592 kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
593 kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
594 break;
595 case SNDRV_PCM_FORMAT_S24_LE:
596 config->data_width = 32;
597 kmb_i2s->ccr = 0x14;
598 kmb_i2s->xfer_resolution = 0x05;
599 kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
600 kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
601 break;
602 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
603 kmb_i2s->iec958_fmt = true;
604 fallthrough;
605 case SNDRV_PCM_FORMAT_S32_LE:
606 config->data_width = 32;
607 kmb_i2s->ccr = 0x10;
608 kmb_i2s->xfer_resolution = 0x05;
609 kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
610 kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
611 break;
612 default:
613 dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt");
614 return -EINVAL;
615 }
616
617 config->chan_nr = params_channels(hw_params);
618
619 switch (config->chan_nr) {
620 case 8:
621 case 4:
622 /*
623 * Platform is not capable of providing clocks for
624 * multi channel audio
625 */
626 if (kmb_i2s->clock_provider)
627 return -EINVAL;
628
629 write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
630 (config->data_width << DATA_WIDTH_CONFIG_BIT) |
631 TDM_OPERATION;
632
633 writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
634 break;
635 case 2:
636 /*
637 * Platform is only capable of providing clocks need for
638 * 2 channel master mode
639 */
640 if (!(kmb_i2s->clock_provider))
641 return -EINVAL;
642
643 write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
644 (config->data_width << DATA_WIDTH_CONFIG_BIT) |
645 CLOCK_PROVIDER_MODE | I2S_OPERATION;
646
647 writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
648 break;
649 default:
650 dev_dbg(kmb_i2s->dev, "channel not supported\n");
651 return -EINVAL;
652 }
653
654 kmb_i2s_config(kmb_i2s, substream->stream);
655
656 writel(kmb_i2s->ccr, kmb_i2s->i2s_base + CCR);
657
658 config->sample_rate = params_rate(hw_params);
659
660 if (kmb_i2s->clock_provider) {
661 /* Only 2 ch supported in Master mode */
662 u32 bitclk = config->sample_rate * config->data_width * 2;
663
664 ret = clk_set_rate(kmb_i2s->clk_i2s, bitclk);
665 if (ret) {
666 dev_err(kmb_i2s->dev,
667 "Can't set I2S clock rate: %d\n", ret);
668 return ret;
669 }
670 }
671
672 return 0;
673 }
674
kmb_dai_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)675 static int kmb_dai_prepare(struct snd_pcm_substream *substream,
676 struct snd_soc_dai *cpu_dai)
677 {
678 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
679
680 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
681 writel(1, kmb_i2s->i2s_base + TXFFR);
682 else
683 writel(1, kmb_i2s->i2s_base + RXFFR);
684
685 return 0;
686 }
687
kmb_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)688 static int kmb_dai_startup(struct snd_pcm_substream *substream,
689 struct snd_soc_dai *cpu_dai)
690 {
691 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
692 struct snd_dmaengine_dai_dma_data *dma_data;
693
694 if (kmb_i2s->use_pio)
695 return 0;
696
697 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
698 dma_data = &kmb_i2s->play_dma_data;
699 else
700 dma_data = &kmb_i2s->capture_dma_data;
701
702 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
703
704 return 0;
705 }
706
kmb_dai_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)707 static int kmb_dai_hw_free(struct snd_pcm_substream *substream,
708 struct snd_soc_dai *cpu_dai)
709 {
710 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
711 /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
712 if (kmb_i2s->use_pio)
713 kmb_i2s_clear_irqs(kmb_i2s, substream->stream);
714
715 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
716 writel(0, kmb_i2s->i2s_base + ITER);
717 else
718 writel(0, kmb_i2s->i2s_base + IRER);
719
720 if (kmb_i2s->use_pio)
721 kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
722 else
723 kmb_i2s_disable_dma(kmb_i2s, substream->stream);
724
725 if (!kmb_i2s->active) {
726 writel(0, kmb_i2s->i2s_base + CER);
727 writel(0, kmb_i2s->i2s_base + IER);
728 }
729
730 return 0;
731 }
732
733 static const struct snd_soc_dai_ops kmb_dai_ops = {
734 .startup = kmb_dai_startup,
735 .trigger = kmb_dai_trigger,
736 .hw_params = kmb_dai_hw_params,
737 .hw_free = kmb_dai_hw_free,
738 .prepare = kmb_dai_prepare,
739 .set_fmt = kmb_set_dai_fmt,
740 };
741
742 static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = {
743 {
744 .name = "intel_kmb_hdmi_i2s",
745 .playback = {
746 .channels_min = 2,
747 .channels_max = 2,
748 .rates = SNDRV_PCM_RATE_48000,
749 .rate_min = 48000,
750 .rate_max = 48000,
751 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
752 SNDRV_PCM_FMTBIT_S24_LE |
753 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
754 },
755 .ops = &kmb_dai_ops,
756 .probe = kmb_probe,
757 },
758 };
759
760 static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = {
761 {
762 .name = "intel_kmb_i2s",
763 .playback = {
764 .channels_min = 2,
765 .channels_max = 2,
766 .rates = SNDRV_PCM_RATE_8000 |
767 SNDRV_PCM_RATE_16000 |
768 SNDRV_PCM_RATE_48000,
769 .rate_min = 8000,
770 .rate_max = 48000,
771 .formats = (SNDRV_PCM_FMTBIT_S32_LE |
772 SNDRV_PCM_FMTBIT_S24_LE |
773 SNDRV_PCM_FMTBIT_S16_LE),
774 },
775 .capture = {
776 .channels_min = 2,
777 .channels_max = 2,
778 .rates = SNDRV_PCM_RATE_8000 |
779 SNDRV_PCM_RATE_16000 |
780 SNDRV_PCM_RATE_48000,
781 .rate_min = 8000,
782 .rate_max = 48000,
783 .formats = (SNDRV_PCM_FMTBIT_S32_LE |
784 SNDRV_PCM_FMTBIT_S24_LE |
785 SNDRV_PCM_FMTBIT_S16_LE),
786 },
787 .ops = &kmb_dai_ops,
788 .probe = kmb_probe,
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 .probe = kmb_probe,
809 },
810 };
811
812 static const struct of_device_id kmb_plat_of_match[] = {
813 { .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai},
814 { .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai},
815 { .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai},
816 {}
817 };
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 const struct of_device_id *match;
824 struct device *dev = &pdev->dev;
825 struct kmb_i2s_info *kmb_i2s;
826 struct resource *res;
827 int ret, irq;
828 u32 comp1_reg;
829
830 kmb_i2s = devm_kzalloc(dev, sizeof(*kmb_i2s), GFP_KERNEL);
831 if (!kmb_i2s)
832 return -ENOMEM;
833
834 kmb_i2s_dai = devm_kzalloc(dev, sizeof(*kmb_i2s_dai), GFP_KERNEL);
835 if (!kmb_i2s_dai)
836 return -ENOMEM;
837
838 match = of_match_device(kmb_plat_of_match, &pdev->dev);
839 if (!match) {
840 dev_err(&pdev->dev, "Error: No device match found\n");
841 return -ENODEV;
842 }
843 kmb_i2s_dai = (struct snd_soc_dai_driver *) match->data;
844
845 /* Prepare the related clocks */
846 kmb_i2s->clk_apb = devm_clk_get(dev, "apb_clk");
847 if (IS_ERR(kmb_i2s->clk_apb)) {
848 dev_err(dev, "Failed to get apb clock\n");
849 return PTR_ERR(kmb_i2s->clk_apb);
850 }
851
852 ret = clk_prepare_enable(kmb_i2s->clk_apb);
853 if (ret < 0)
854 return ret;
855
856 ret = devm_add_action_or_reset(dev, kmb_disable_clk, kmb_i2s->clk_apb);
857 if (ret) {
858 dev_err(dev, "Failed to add clk_apb reset action\n");
859 return ret;
860 }
861
862 kmb_i2s->clk_i2s = devm_clk_get(dev, "osc");
863 if (IS_ERR(kmb_i2s->clk_i2s)) {
864 dev_err(dev, "Failed to get osc clock\n");
865 return PTR_ERR(kmb_i2s->clk_i2s);
866 }
867
868 kmb_i2s->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
869 if (IS_ERR(kmb_i2s->i2s_base))
870 return PTR_ERR(kmb_i2s->i2s_base);
871
872 kmb_i2s->pss_base = devm_platform_ioremap_resource(pdev, 1);
873 if (IS_ERR(kmb_i2s->pss_base))
874 return PTR_ERR(kmb_i2s->pss_base);
875
876 kmb_i2s->dev = &pdev->dev;
877
878 comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1);
879
880 kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2;
881
882 kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));
883
884 if (kmb_i2s->use_pio) {
885 irq = platform_get_irq_optional(pdev, 0);
886 if (irq > 0) {
887 ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
888 pdev->name, kmb_i2s);
889 if (ret < 0) {
890 dev_err(dev, "failed to request irq\n");
891 return ret;
892 }
893 }
894 ret = devm_snd_soc_register_component(dev, &kmb_component,
895 kmb_i2s_dai, 1);
896 } else {
897 kmb_i2s->play_dma_data.addr = res->start + I2S_TXDMA;
898 kmb_i2s->capture_dma_data.addr = res->start + I2S_RXDMA;
899 ret = snd_dmaengine_pcm_register(&pdev->dev,
900 NULL, 0);
901 if (ret) {
902 dev_err(&pdev->dev, "could not register dmaengine: %d\n",
903 ret);
904 return ret;
905 }
906 ret = devm_snd_soc_register_component(dev, &kmb_component_dma,
907 kmb_i2s_dai, 1);
908 }
909
910 if (ret) {
911 dev_err(dev, "not able to register dai\n");
912 return ret;
913 }
914
915 /* To ensure none of the channels are enabled at boot up */
916 kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_PLAYBACK);
917 kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_CAPTURE);
918
919 dev_set_drvdata(dev, kmb_i2s);
920
921 return ret;
922 }
923
924 static struct platform_driver kmb_plat_dai_driver = {
925 .driver = {
926 .name = "kmb-plat-dai",
927 .of_match_table = kmb_plat_of_match,
928 },
929 .probe = kmb_plat_dai_probe,
930 };
931
932 module_platform_driver(kmb_plat_dai_driver);
933
934 MODULE_DESCRIPTION("ASoC Intel KeemBay Platform driver");
935 MODULE_AUTHOR("Sia Jee Heng <jee.heng.sia@intel.com>");
936 MODULE_AUTHOR("Sit, Michael Wei Hong <michael.wei.hong.sit@intel.com>");
937 MODULE_LICENSE("GPL v2");
938 MODULE_ALIAS("platform:kmb_platform");
939