1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright (C) 2020 Intel Corporation.
5 // Intel KeemBay Platform driver.
8 #include <linux/bitrev.h>
10 #include <linux/dma-mapping.h>
12 #include <linux/module.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"
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
30 static const struct snd_pcm_hardware kmb_pcm_hardware = {
31 .info = SNDRV_PCM_INFO_INTERLEAVED |
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 |
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,
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,
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)
62 * 8-27 = audio data (without AUX if 24bit sample)
68 * ADV7511 IEC958 subframe format:
69 * bit 0-23 = audio data
75 * MSB to LSB bit reverse by software as hardware not supporting it.
77 static void hdmi_reformat_iec958(struct snd_pcm_runtime *runtime,
78 struct kmb_i2s_info *kmb_i2s,
81 u32(*buf)[2] = (void *)runtime->dma_area;
85 for (i = 0; i < kmb_i2s->fifo_th; i++) {
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;
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)
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;
108 if (kmb_i2s->iec958_fmt)
109 hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr);
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));
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));
123 if (++tx_ptr >= runtime->buffer_size)
127 *period_elapsed = period_pos >= runtime->period_size;
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)
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;
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));
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));
159 if (++rx_ptr >= runtime->buffer_size)
163 *period_elapsed = period_pos >= runtime->period_size;
168 static inline void kmb_i2s_disable_channels(struct kmb_i2s_info *kmb_i2s,
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));
178 for (i = 0; i < MAX_ISR; i++)
179 writel(0, kmb_i2s->i2s_base + RER(i));
183 static inline void kmb_i2s_clear_irqs(struct kmb_i2s_info *kmb_i2s, u32 stream)
185 struct i2s_clk_config_data *config = &kmb_i2s->config;
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));
192 for (i = 0; i < config->chan_nr / 2; i++)
193 readl(kmb_i2s->i2s_base + ROR(i));
197 static inline void kmb_i2s_irq_trigger(struct kmb_i2s_info *kmb_i2s,
198 u32 stream, int chan_nr, bool trigger)
203 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
208 for (i = 0; i < chan_nr / 2; i++) {
209 irq = readl(kmb_i2s->i2s_base + IMR(i));
216 writel(irq, kmb_i2s->i2s_base + IMR(i));
220 static void kmb_pcm_operation(struct kmb_i2s_info *kmb_i2s, bool playback)
222 struct snd_pcm_substream *substream;
224 unsigned int new_ptr;
228 substream = kmb_i2s->tx_substream;
230 substream = kmb_i2s->rx_substream;
232 if (!substream || !snd_pcm_running(substream))
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);
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);
248 snd_pcm_period_elapsed(substream);
251 static int kmb_pcm_open(struct snd_soc_component *component,
252 struct snd_pcm_substream *substream)
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;
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;
266 static int kmb_pcm_trigger(struct snd_soc_component *component,
267 struct snd_pcm_substream *substream, int cmd)
269 struct snd_pcm_runtime *runtime = substream->runtime;
270 struct kmb_i2s_info *kmb_i2s = runtime->private_data;
273 case SNDRV_PCM_TRIGGER_START:
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
276 kmb_i2s->tx_substream = substream;
279 kmb_i2s->rx_substream = substream;
282 case SNDRV_PCM_TRIGGER_STOP:
283 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
284 kmb_i2s->tx_substream = NULL;
286 kmb_i2s->rx_substream = NULL;
287 kmb_i2s->iec958_fmt = false;
296 static irqreturn_t kmb_i2s_irq_handler(int irq, void *dev_id)
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;
305 for (i = 0; i < config->chan_nr / 2; i++)
306 isr[i] = readl(kmb_i2s->i2s_base + ISR(i));
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);
314 * Data available. Retrieve samples from FIFO
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.
322 switch (config->chan_nr) {
324 if (isr[0] & ISR_RXDA)
325 kmb_pcm_operation(kmb_i2s, false);
329 if (isr[1] & ISR_RXDA)
330 kmb_pcm_operation(kmb_i2s, false);
334 if (isr[3] & ISR_RXDA)
335 kmb_pcm_operation(kmb_i2s, false);
340 for (i = 0; i < config->chan_nr / 2; i++) {
342 * Check if TX fifo is empty. If empty fill FIFO with samples
344 if ((isr[i] & ISR_TXFE) && tx_enabled) {
345 kmb_pcm_operation(kmb_i2s, true);
349 /* Error Handling: TX */
350 if (isr[i] & ISR_TXFO) {
351 dev_dbg(kmb_i2s->dev, "TX overrun (ch_id=%d)\n", i);
354 /* Error Handling: RX */
355 if (isr[i] & ISR_RXFO) {
356 dev_dbg(kmb_i2s->dev, "RX overrun (ch_id=%d)\n", i);
364 static int kmb_platform_pcm_new(struct snd_soc_component *component,
365 struct snd_soc_pcm_runtime *soc_runtime)
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,
375 static snd_pcm_uframes_t kmb_pcm_pointer(struct snd_soc_component *component,
376 struct snd_pcm_substream *substream)
378 struct snd_pcm_runtime *runtime = substream->runtime;
379 struct kmb_i2s_info *kmb_i2s = runtime->private_data;
380 snd_pcm_uframes_t pos;
382 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
383 pos = kmb_i2s->tx_ptr;
385 pos = kmb_i2s->rx_ptr;
387 return pos < runtime->buffer_size ? pos : 0;
390 static const struct snd_soc_component_driver kmb_component = {
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,
399 static const struct snd_soc_component_driver kmb_component_dma = {
401 .legacy_dai_naming = 1,
404 static int kmb_probe(struct snd_soc_dai *cpu_dai)
406 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
408 if (kmb_i2s->use_pio)
411 snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data,
412 &kmb_i2s->capture_dma_data);
417 static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
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;
426 dma_reg |= I2S_DMAEN_RXBLOCK;
428 writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
431 static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
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);
441 dma_reg &= ~I2S_DMAEN_RXBLOCK;
442 writel(1, kmb_i2s->i2s_base + I2S_RRXDMA);
444 writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
447 static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s,
448 struct snd_pcm_substream *substream)
450 struct i2s_clk_config_data *config = &kmb_i2s->config;
452 /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
453 writel(1, kmb_i2s->i2s_base + IER);
455 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
456 writel(1, kmb_i2s->i2s_base + ITER);
458 writel(1, kmb_i2s->i2s_base + IRER);
460 if (kmb_i2s->use_pio)
461 kmb_i2s_irq_trigger(kmb_i2s, substream->stream,
462 config->chan_nr, true);
464 kmb_i2s_enable_dma(kmb_i2s, substream->stream);
466 if (kmb_i2s->clock_provider)
467 writel(1, kmb_i2s->i2s_base + CER);
469 writel(0, kmb_i2s->i2s_base + CER);
472 static void kmb_i2s_stop(struct kmb_i2s_info *kmb_i2s,
473 struct snd_pcm_substream *substream)
475 /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
476 kmb_i2s_clear_irqs(kmb_i2s, substream->stream);
478 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 writel(0, kmb_i2s->i2s_base + ITER);
481 writel(0, kmb_i2s->i2s_base + IRER);
483 kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
485 if (!kmb_i2s->active) {
486 writel(0, kmb_i2s->i2s_base + CER);
487 writel(0, kmb_i2s->i2s_base + IER);
491 static void kmb_disable_clk(void *clk)
493 clk_disable_unprepare(clk);
496 static int kmb_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
498 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
501 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
502 case SND_SOC_DAIFMT_BC_FC:
503 kmb_i2s->clock_provider = false;
506 case SND_SOC_DAIFMT_BP_FP:
507 writel(CLOCK_PROVIDER_MODE, kmb_i2s->pss_base + I2S_GEN_CFG_0);
509 ret = clk_prepare_enable(kmb_i2s->clk_i2s);
513 ret = devm_add_action_or_reset(kmb_i2s->dev, kmb_disable_clk,
518 kmb_i2s->clock_provider = true;
527 static int kmb_dai_trigger(struct snd_pcm_substream *substream,
528 int cmd, struct snd_soc_dai *cpu_dai)
530 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
533 case SNDRV_PCM_TRIGGER_START:
534 /* Keep track of i2s activity before turn off
538 kmb_i2s_start(kmb_i2s, substream);
540 case SNDRV_PCM_TRIGGER_STOP:
542 if (kmb_i2s->use_pio)
543 kmb_i2s_stop(kmb_i2s, substream);
552 static void kmb_i2s_config(struct kmb_i2s_info *kmb_i2s, int stream)
554 struct i2s_clk_config_data *config = &kmb_i2s->config;
557 kmb_i2s_disable_channels(kmb_i2s, stream);
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));
564 writel(kmb_i2s->fifo_th - 1,
565 kmb_i2s->i2s_base + TFCR(ch_reg));
567 writel(1, kmb_i2s->i2s_base + TER(ch_reg));
569 writel(kmb_i2s->xfer_resolution,
570 kmb_i2s->i2s_base + RCR(ch_reg));
572 writel(kmb_i2s->fifo_th - 1,
573 kmb_i2s->i2s_base + RFCR(ch_reg));
575 writel(1, kmb_i2s->i2s_base + RER(ch_reg));
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)
584 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
585 struct i2s_clk_config_data *config = &kmb_i2s->config;
589 switch (params_format(hw_params)) {
590 case SNDRV_PCM_FORMAT_S16_LE:
591 config->data_width = 16;
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;
597 case SNDRV_PCM_FORMAT_S24_LE:
598 config->data_width = 32;
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;
604 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
605 kmb_i2s->iec958_fmt = true;
607 case SNDRV_PCM_FORMAT_S32_LE:
608 config->data_width = 32;
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;
615 dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt");
619 config->chan_nr = params_channels(hw_params);
621 switch (config->chan_nr) {
625 * Platform is not capable of providing clocks for
626 * multi channel audio
628 if (kmb_i2s->clock_provider)
631 write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
632 (config->data_width << DATA_WIDTH_CONFIG_BIT) |
635 writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
639 * Platform is only capable of providing clocks need for
640 * 2 channel master mode
642 if (!(kmb_i2s->clock_provider))
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;
649 writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
652 dev_dbg(kmb_i2s->dev, "channel not supported\n");
656 kmb_i2s_config(kmb_i2s, substream->stream);
658 writel(kmb_i2s->ccr, kmb_i2s->i2s_base + CCR);
660 config->sample_rate = params_rate(hw_params);
662 if (kmb_i2s->clock_provider) {
663 /* Only 2 ch supported in Master mode */
664 u32 bitclk = config->sample_rate * config->data_width * 2;
666 ret = clk_set_rate(kmb_i2s->clk_i2s, bitclk);
668 dev_err(kmb_i2s->dev,
669 "Can't set I2S clock rate: %d\n", ret);
677 static int kmb_dai_prepare(struct snd_pcm_substream *substream,
678 struct snd_soc_dai *cpu_dai)
680 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
682 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
683 writel(1, kmb_i2s->i2s_base + TXFFR);
685 writel(1, kmb_i2s->i2s_base + RXFFR);
690 static int kmb_dai_startup(struct snd_pcm_substream *substream,
691 struct snd_soc_dai *cpu_dai)
693 struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
694 struct snd_dmaengine_dai_dma_data *dma_data;
696 if (kmb_i2s->use_pio)
699 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
700 dma_data = &kmb_i2s->play_dma_data;
702 dma_data = &kmb_i2s->capture_dma_data;
704 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
709 static int kmb_dai_hw_free(struct snd_pcm_substream *substream,
710 struct snd_soc_dai *cpu_dai)
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);
717 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 writel(0, kmb_i2s->i2s_base + ITER);
720 writel(0, kmb_i2s->i2s_base + IRER);
722 if (kmb_i2s->use_pio)
723 kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
725 kmb_i2s_disable_dma(kmb_i2s, substream->stream);
727 if (!kmb_i2s->active) {
728 writel(0, kmb_i2s->i2s_base + CER);
729 writel(0, kmb_i2s->i2s_base + IER);
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,
744 static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = {
746 .name = "intel_kmb_hdmi_i2s",
750 .rates = SNDRV_PCM_RATE_48000,
753 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
754 SNDRV_PCM_FMTBIT_S24_LE |
755 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
762 static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = {
764 .name = "intel_kmb_i2s",
768 .rates = SNDRV_PCM_RATE_8000 |
769 SNDRV_PCM_RATE_16000 |
770 SNDRV_PCM_RATE_48000,
773 .formats = (SNDRV_PCM_FMTBIT_S32_LE |
774 SNDRV_PCM_FMTBIT_S24_LE |
775 SNDRV_PCM_FMTBIT_S16_LE),
780 .rates = SNDRV_PCM_RATE_8000 |
781 SNDRV_PCM_RATE_16000 |
782 SNDRV_PCM_RATE_48000,
785 .formats = (SNDRV_PCM_FMTBIT_S32_LE |
786 SNDRV_PCM_FMTBIT_S24_LE |
787 SNDRV_PCM_FMTBIT_S16_LE),
794 static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = {
796 .name = "intel_kmb_tdm",
800 .rates = SNDRV_PCM_RATE_8000 |
801 SNDRV_PCM_RATE_16000 |
802 SNDRV_PCM_RATE_48000,
805 .formats = (SNDRV_PCM_FMTBIT_S32_LE |
806 SNDRV_PCM_FMTBIT_S24_LE |
807 SNDRV_PCM_FMTBIT_S16_LE),
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},
821 static int kmb_plat_dai_probe(struct platform_device *pdev)
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;
832 kmb_i2s = devm_kzalloc(dev, sizeof(*kmb_i2s), GFP_KERNEL);
836 kmb_i2s_dai = devm_kzalloc(dev, sizeof(*kmb_i2s_dai), GFP_KERNEL);
840 match = of_match_device(kmb_plat_of_match, &pdev->dev);
842 dev_err(&pdev->dev, "Error: No device match found\n");
845 kmb_i2s_dai = (struct snd_soc_dai_driver *) match->data;
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);
854 ret = clk_prepare_enable(kmb_i2s->clk_apb);
858 ret = devm_add_action_or_reset(dev, kmb_disable_clk, kmb_i2s->clk_apb);
860 dev_err(dev, "Failed to add clk_apb reset action\n");
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);
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);
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);
878 kmb_i2s->dev = &pdev->dev;
880 comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1);
882 kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2;
884 kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));
886 if (kmb_i2s->use_pio) {
887 irq = platform_get_irq_optional(pdev, 0);
889 ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
890 pdev->name, kmb_i2s);
892 dev_err(dev, "failed to request irq\n");
896 ret = devm_snd_soc_register_component(dev, &kmb_component,
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,
904 dev_err(&pdev->dev, "could not register dmaengine: %d\n",
908 ret = devm_snd_soc_register_component(dev, &kmb_component_dma,
913 dev_err(dev, "not able to register dai\n");
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);
921 dev_set_drvdata(dev, kmb_i2s);
926 static struct platform_driver kmb_plat_dai_driver = {
928 .name = "kmb-plat-dai",
929 .of_match_table = kmb_plat_of_match,
931 .probe = kmb_plat_dai_probe,
934 module_platform_driver(kmb_plat_dai_driver);
936 MODULE_DESCRIPTION("ASoC Intel KeemBay Platform driver");
939 MODULE_LICENSE("GPL v2");
940 MODULE_ALIAS("platform:kmb_platform");