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