1
2
3
4
5
6
7
8
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_address.h>
14#include <linux/of_irq.h>
15#include <linux/platform_device.h>
16#include <linux/sizes.h>
17
18#include <sound/asoundef.h>
19#include <sound/soc.h>
20#include <sound/pcm_params.h>
21
22#include "xlnx_snd_common.h"
23
24#define DRV_NAME "xlnx_formatter_pcm"
25
26#define XLNX_S2MM_OFFSET 0
27#define XLNX_MM2S_OFFSET 0x100
28
29#define XLNX_AUD_CORE_CONFIG 0x4
30#define XLNX_AUD_CTRL 0x10
31#define XLNX_AUD_STS 0x14
32
33#define AUD_CTRL_RESET_MASK BIT(1)
34#define AUD_CFG_MM2S_MASK BIT(15)
35#define AUD_CFG_S2MM_MASK BIT(31)
36
37#define XLNX_AUD_FS_MULTIPLIER 0x18
38#define XLNX_AUD_PERIOD_CONFIG 0x1C
39#define XLNX_AUD_BUFF_ADDR_LSB 0x20
40#define XLNX_AUD_BUFF_ADDR_MSB 0x24
41#define XLNX_AUD_XFER_COUNT 0x28
42#define XLNX_AUD_CH_STS_START 0x2C
43#define XLNX_BYTES_PER_CH 0x44
44#define XLNX_AUD_ALIGN_BYTES 64
45
46#define AUD_STS_IOC_IRQ_MASK BIT(31)
47#define AUD_STS_CH_STS_MASK BIT(29)
48#define AUD_CTRL_IOC_IRQ_MASK BIT(13)
49#define AUD_CTRL_TOUT_IRQ_MASK BIT(14)
50#define AUD_CTRL_DMA_EN_MASK BIT(0)
51
52#define CFG_MM2S_CH_MASK GENMASK(11, 8)
53#define CFG_MM2S_CH_SHIFT 8
54#define CFG_MM2S_XFER_MASK GENMASK(14, 13)
55#define CFG_MM2S_XFER_SHIFT 13
56#define CFG_MM2S_PKG_MASK BIT(12)
57
58#define CFG_S2MM_CH_MASK GENMASK(27, 24)
59#define CFG_S2MM_CH_SHIFT 24
60#define CFG_S2MM_XFER_MASK GENMASK(30, 29)
61#define CFG_S2MM_XFER_SHIFT 29
62#define CFG_S2MM_PKG_MASK BIT(28)
63
64#define AUD_CTRL_DATA_WIDTH_MASK GENMASK(18, 16)
65#define AUD_CTRL_DATA_WIDTH_SHIFT 16
66#define AUD_CTRL_ACTIVE_CH_MASK GENMASK(22, 19)
67#define AUD_CTRL_ACTIVE_CH_SHIFT 19
68#define PERIOD_CFG_PERIODS_SHIFT 16
69
70#define PERIODS_MIN 2
71#define PERIODS_MAX 6
72#define PERIOD_BYTES_MIN 192
73#define PERIOD_BYTES_MAX (50 * 1024)
74#define XLNX_PARAM_UNKNOWN 0
75
76static const struct snd_pcm_hardware xlnx_pcm_hardware = {
77 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
78 SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_PAUSE |
79 SNDRV_PCM_INFO_RESUME,
80 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
81 SNDRV_PCM_FMTBIT_S24_LE,
82 .channels_min = 2,
83 .channels_max = 2,
84 .rates = SNDRV_PCM_RATE_8000_192000,
85 .rate_min = 8000,
86 .rate_max = 192000,
87 .buffer_bytes_max = PERIODS_MAX * PERIOD_BYTES_MAX,
88 .period_bytes_min = PERIOD_BYTES_MIN,
89 .period_bytes_max = PERIOD_BYTES_MAX,
90 .periods_min = PERIODS_MIN,
91 .periods_max = PERIODS_MAX,
92};
93
94struct xlnx_pcm_drv_data {
95 void __iomem *mmio;
96 bool s2mm_presence;
97 bool mm2s_presence;
98 int s2mm_irq;
99 int mm2s_irq;
100 struct snd_pcm_substream *play_stream;
101 struct snd_pcm_substream *capture_stream;
102 struct platform_device *pdev;
103 struct device_node *nodes[XLNX_MAX_PATHS];
104 struct clk *axi_clk;
105 struct clk *mm2s_axis_clk;
106 struct clk *s2mm_axis_clk;
107 struct clk *aud_mclk;
108};
109
110
111
112
113
114
115
116
117
118struct xlnx_pcm_stream_param {
119 void __iomem *mmio;
120 bool interleaved;
121 u32 xfer_mode;
122 u32 ch_limit;
123 u64 buffer_size;
124};
125
126enum bit_depth {
127 BIT_DEPTH_8,
128 BIT_DEPTH_16,
129 BIT_DEPTH_20,
130 BIT_DEPTH_24,
131 BIT_DEPTH_32,
132};
133
134enum {
135 AES_TO_AES,
136 AES_TO_PCM,
137 PCM_TO_PCM,
138 PCM_TO_AES
139};
140
141static void xlnx_parse_aes_params(u32 chsts_reg1_val, u32 chsts_reg2_val,
142 struct device *dev)
143{
144 u32 padded, srate, bit_depth, status[2];
145
146 if (chsts_reg1_val & IEC958_AES0_PROFESSIONAL) {
147 status[0] = chsts_reg1_val & 0xff;
148 status[1] = (chsts_reg1_val >> 16) & 0xff;
149
150 switch (status[0] & IEC958_AES0_PRO_FS) {
151 case IEC958_AES0_PRO_FS_44100:
152 srate = 44100;
153 break;
154 case IEC958_AES0_PRO_FS_48000:
155 srate = 48000;
156 break;
157 case IEC958_AES0_PRO_FS_32000:
158 srate = 32000;
159 break;
160 case IEC958_AES0_PRO_FS_NOTID:
161 default:
162 srate = XLNX_PARAM_UNKNOWN;
163 break;
164 }
165
166 switch (status[1] & IEC958_AES2_PRO_SBITS) {
167 case IEC958_AES2_PRO_WORDLEN_NOTID:
168 case IEC958_AES2_PRO_SBITS_20:
169 padded = 0;
170 break;
171 case IEC958_AES2_PRO_SBITS_24:
172 padded = 4;
173 break;
174 default:
175 bit_depth = XLNX_PARAM_UNKNOWN;
176 goto log_params;
177 }
178
179 switch (status[1] & IEC958_AES2_PRO_WORDLEN) {
180 case IEC958_AES2_PRO_WORDLEN_20_16:
181 bit_depth = 16 + padded;
182 break;
183 case IEC958_AES2_PRO_WORDLEN_22_18:
184 bit_depth = 18 + padded;
185 break;
186 case IEC958_AES2_PRO_WORDLEN_23_19:
187 bit_depth = 19 + padded;
188 break;
189 case IEC958_AES2_PRO_WORDLEN_24_20:
190 bit_depth = 20 + padded;
191 break;
192 case IEC958_AES2_PRO_WORDLEN_NOTID:
193 default:
194 bit_depth = XLNX_PARAM_UNKNOWN;
195 break;
196 }
197
198 } else {
199 status[0] = (chsts_reg1_val >> 24) & 0xff;
200 status[1] = chsts_reg2_val & 0xff;
201
202 switch (status[0] & IEC958_AES3_CON_FS) {
203 case IEC958_AES3_CON_FS_44100:
204 srate = 44100;
205 break;
206 case IEC958_AES3_CON_FS_48000:
207 srate = 48000;
208 break;
209 case IEC958_AES3_CON_FS_32000:
210 srate = 32000;
211 break;
212 default:
213 srate = XLNX_PARAM_UNKNOWN;
214 break;
215 }
216
217 if (status[1] & IEC958_AES4_CON_MAX_WORDLEN_24)
218 padded = 4;
219 else
220 padded = 0;
221
222 switch (status[1] & IEC958_AES4_CON_WORDLEN) {
223 case IEC958_AES4_CON_WORDLEN_20_16:
224 bit_depth = 16 + padded;
225 break;
226 case IEC958_AES4_CON_WORDLEN_22_18:
227 bit_depth = 18 + padded;
228 break;
229 case IEC958_AES4_CON_WORDLEN_23_19:
230 bit_depth = 19 + padded;
231 break;
232 case IEC958_AES4_CON_WORDLEN_24_20:
233 bit_depth = 20 + padded;
234 break;
235 case IEC958_AES4_CON_WORDLEN_21_17:
236 bit_depth = 17 + padded;
237 break;
238 case IEC958_AES4_CON_WORDLEN_NOTID:
239 default:
240 bit_depth = XLNX_PARAM_UNKNOWN;
241 break;
242 }
243 }
244
245log_params:
246 if (srate != XLNX_PARAM_UNKNOWN)
247 dev_info(dev, "sample rate = %d\n", srate);
248 else
249 dev_info(dev, "sample rate = unknown\n");
250
251 if (bit_depth != XLNX_PARAM_UNKNOWN)
252 dev_info(dev, "bit_depth = %d\n", bit_depth);
253 else
254 dev_info(dev, "bit_depth = unknown\n");
255}
256
257static int xlnx_formatter_pcm_reset(void __iomem *mmio_base)
258{
259 u32 val, retries = 0;
260
261 val = ioread32(mmio_base + XLNX_AUD_CTRL);
262 val |= AUD_CTRL_RESET_MASK;
263 iowrite32(val, mmio_base + XLNX_AUD_CTRL);
264
265 val = ioread32(mmio_base + XLNX_AUD_CTRL);
266
267 while ((val & AUD_CTRL_RESET_MASK) && (retries < 100)) {
268 mdelay(1);
269 retries++;
270 val = ioread32(mmio_base + XLNX_AUD_CTRL);
271 }
272 if (val & AUD_CTRL_RESET_MASK)
273 return -ENODEV;
274
275 return 0;
276}
277
278static void xlnx_formatter_disable_irqs(void __iomem *mmio_base, int stream)
279{
280 u32 val;
281
282 val = ioread32(mmio_base + XLNX_AUD_CTRL);
283 val &= ~AUD_CTRL_IOC_IRQ_MASK;
284 if (stream == SNDRV_PCM_STREAM_CAPTURE)
285 val &= ~AUD_CTRL_TOUT_IRQ_MASK;
286
287 iowrite32(val, mmio_base + XLNX_AUD_CTRL);
288}
289
290static irqreturn_t xlnx_mm2s_irq_handler(int irq, void *arg)
291{
292 u32 val;
293 void __iomem *reg;
294 struct device *dev = arg;
295 struct xlnx_pcm_drv_data *adata = dev_get_drvdata(dev);
296
297 reg = adata->mmio + XLNX_MM2S_OFFSET + XLNX_AUD_STS;
298 val = ioread32(reg);
299 if (val & AUD_STS_IOC_IRQ_MASK) {
300 iowrite32(val & AUD_STS_IOC_IRQ_MASK, reg);
301 if (adata->play_stream)
302 snd_pcm_period_elapsed(adata->play_stream);
303 return IRQ_HANDLED;
304 }
305
306 return IRQ_NONE;
307}
308
309static irqreturn_t xlnx_s2mm_irq_handler(int irq, void *arg)
310{
311 u32 val;
312 void __iomem *reg;
313 struct device *dev = arg;
314 struct xlnx_pcm_drv_data *adata = dev_get_drvdata(dev);
315
316 reg = adata->mmio + XLNX_S2MM_OFFSET + XLNX_AUD_STS;
317 val = ioread32(reg);
318 if (val & AUD_STS_IOC_IRQ_MASK) {
319 iowrite32(val & AUD_STS_IOC_IRQ_MASK, reg);
320 if (adata->capture_stream)
321 snd_pcm_period_elapsed(adata->capture_stream);
322 return IRQ_HANDLED;
323 }
324
325 return IRQ_NONE;
326}
327
328static int xlnx_formatter_pcm_open(struct snd_soc_component *component,
329 struct snd_pcm_substream *substream)
330{
331 int err;
332 u32 val, data_format_mode;
333 u32 ch_count_mask, ch_count_shift, data_xfer_mode, data_xfer_shift;
334 struct xlnx_pcm_stream_param *stream_data;
335 struct snd_pcm_runtime *runtime = substream->runtime;
336 struct xlnx_pcm_drv_data *adata;
337
338 if (!component)
339 return -ENODEV;
340
341 adata = dev_get_drvdata(component->dev);
342
343 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
344 !adata->mm2s_presence)
345 return -ENODEV;
346 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
347 !adata->s2mm_presence)
348 return -ENODEV;
349
350 stream_data = kzalloc(sizeof(*stream_data), GFP_KERNEL);
351 if (!stream_data)
352 return -ENOMEM;
353
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
355 ch_count_mask = CFG_MM2S_CH_MASK;
356 ch_count_shift = CFG_MM2S_CH_SHIFT;
357 data_xfer_mode = CFG_MM2S_XFER_MASK;
358 data_xfer_shift = CFG_MM2S_XFER_SHIFT;
359 data_format_mode = CFG_MM2S_PKG_MASK;
360 stream_data->mmio = adata->mmio + XLNX_MM2S_OFFSET;
361 adata->play_stream = substream;
362
363 } else {
364 ch_count_mask = CFG_S2MM_CH_MASK;
365 ch_count_shift = CFG_S2MM_CH_SHIFT;
366 data_xfer_mode = CFG_S2MM_XFER_MASK;
367 data_xfer_shift = CFG_S2MM_XFER_SHIFT;
368 data_format_mode = CFG_S2MM_PKG_MASK;
369 stream_data->mmio = adata->mmio + XLNX_S2MM_OFFSET;
370 adata->capture_stream = substream;
371 }
372
373 val = ioread32(adata->mmio + XLNX_AUD_CORE_CONFIG);
374
375 if (!(val & data_format_mode))
376 stream_data->interleaved = true;
377 else
378 stream_data->interleaved = false;
379
380 stream_data->xfer_mode = (val & data_xfer_mode) >> data_xfer_shift;
381 stream_data->ch_limit = (val & ch_count_mask) >> ch_count_shift;
382 dev_info(component->dev,
383 "stream %d : format = %d mode = %d ch_limit = %d\n",
384 substream->stream, stream_data->interleaved,
385 stream_data->xfer_mode, stream_data->ch_limit);
386
387 snd_soc_set_runtime_hwparams(substream, &xlnx_pcm_hardware);
388 runtime->private_data = stream_data;
389
390
391 err = snd_pcm_hw_constraint_step(runtime, 0,
392 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
393 XLNX_AUD_ALIGN_BYTES);
394 if (err) {
395 dev_err(component->dev,
396 "Unable to set constraint on period bytes\n");
397 return err;
398 }
399
400 err = snd_pcm_hw_constraint_step(runtime, 0,
401 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
402 XLNX_AUD_ALIGN_BYTES);
403 if (err) {
404 dev_err(component->dev,
405 "Unable to set constraint on buffer bytes\n");
406 return err;
407 }
408
409 err = snd_pcm_hw_constraint_integer(runtime,
410 SNDRV_PCM_HW_PARAM_PERIODS);
411 if (err < 0) {
412 dev_err(component->dev,
413 "Unable to set constraint on periods to be integer\n");
414 return err;
415 }
416
417
418 val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
419 val |= AUD_CTRL_IOC_IRQ_MASK;
420 iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
421
422 return 0;
423}
424
425static int xlnx_formatter_pcm_close(struct snd_soc_component *component,
426 struct snd_pcm_substream *substream)
427{
428 int ret;
429 struct xlnx_pcm_stream_param *stream_data =
430 substream->runtime->private_data;
431
432 if (!component)
433 return -ENODEV;
434
435 ret = xlnx_formatter_pcm_reset(stream_data->mmio);
436 if (ret) {
437 dev_err(component->dev, "audio formatter reset failed\n");
438 goto err_reset;
439 }
440 xlnx_formatter_disable_irqs(stream_data->mmio, substream->stream);
441
442err_reset:
443 kfree(stream_data);
444 return 0;
445}
446
447static snd_pcm_uframes_t
448xlnx_formatter_pcm_pointer(struct snd_soc_component *component,
449 struct snd_pcm_substream *substream)
450{
451 u32 pos;
452 struct snd_pcm_runtime *runtime = substream->runtime;
453 struct xlnx_pcm_stream_param *stream_data = runtime->private_data;
454
455 pos = ioread32(stream_data->mmio + XLNX_AUD_XFER_COUNT);
456
457 if (pos >= stream_data->buffer_size)
458 pos = 0;
459
460 return bytes_to_frames(runtime, pos);
461}
462
463static int xlnx_formatter_pcm_hw_params(struct snd_soc_component *component,
464 struct snd_pcm_substream *substream,
465 struct snd_pcm_hw_params *params)
466{
467 u32 low, high, active_ch, val, bits_per_sample, bytes_per_ch;
468 u32 aes_reg1_val, aes_reg2_val;
469 int status;
470 u64 size;
471 struct pl_card_data *prv;
472 struct snd_pcm_runtime *runtime = substream->runtime;
473 struct xlnx_pcm_stream_param *stream_data = runtime->private_data;
474 struct xlnx_pcm_drv_data *adata;
475 struct snd_soc_pcm_runtime *rtd = substream->private_data;
476
477 if (!component)
478 return -ENODEV;
479
480 adata = dev_get_drvdata(component->dev);
481
482 active_ch = params_channels(params);
483 if (active_ch > stream_data->ch_limit)
484 return -EINVAL;
485
486 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
487 stream_data->xfer_mode == AES_TO_PCM &&
488 ((strstr(adata->nodes[XLNX_CAPTURE]->name, "hdmi")) ||
489 (strstr(adata->nodes[XLNX_CAPTURE]->name, "sdi")))) {
490
491
492
493
494 val = ioread32(stream_data->mmio + XLNX_AUD_STS);
495 if (val & AUD_STS_CH_STS_MASK) {
496 aes_reg1_val = ioread32(stream_data->mmio +
497 XLNX_AUD_CH_STS_START);
498 aes_reg2_val = ioread32(stream_data->mmio +
499 XLNX_AUD_CH_STS_START + 0x4);
500
501 xlnx_parse_aes_params(aes_reg1_val, aes_reg2_val,
502 component->dev);
503 }
504 }
505
506 size = params_buffer_bytes(params);
507 status = snd_pcm_lib_malloc_pages(substream, size);
508 if (status < 0)
509 return status;
510
511 stream_data->buffer_size = size;
512
513 low = lower_32_bits(substream->dma_buffer.addr);
514 high = upper_32_bits(substream->dma_buffer.addr);
515 iowrite32(low, stream_data->mmio + XLNX_AUD_BUFF_ADDR_LSB);
516 iowrite32(high, stream_data->mmio + XLNX_AUD_BUFF_ADDR_MSB);
517
518 val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
519 val &= ~AUD_CTRL_DATA_WIDTH_MASK;
520 bits_per_sample = params_width(params);
521 switch (bits_per_sample) {
522 case 8:
523 val |= (BIT_DEPTH_8 << AUD_CTRL_DATA_WIDTH_SHIFT);
524 break;
525 case 16:
526 val |= (BIT_DEPTH_16 << AUD_CTRL_DATA_WIDTH_SHIFT);
527 break;
528 case 20:
529 val |= (BIT_DEPTH_20 << AUD_CTRL_DATA_WIDTH_SHIFT);
530 break;
531 case 24:
532 val |= (BIT_DEPTH_24 << AUD_CTRL_DATA_WIDTH_SHIFT);
533 break;
534 case 32:
535 val |= (BIT_DEPTH_32 << AUD_CTRL_DATA_WIDTH_SHIFT);
536 break;
537 }
538
539 val &= ~AUD_CTRL_ACTIVE_CH_MASK;
540 val |= active_ch << AUD_CTRL_ACTIVE_CH_SHIFT;
541 iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
542
543 val = (params_periods(params) << PERIOD_CFG_PERIODS_SHIFT)
544 | params_period_bytes(params);
545 iowrite32(val, stream_data->mmio + XLNX_AUD_PERIOD_CONFIG);
546 bytes_per_ch = DIV_ROUND_UP(params_period_bytes(params), active_ch);
547 iowrite32(bytes_per_ch, stream_data->mmio + XLNX_BYTES_PER_CH);
548
549 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
550 prv = snd_soc_card_get_drvdata(rtd->card);
551 iowrite32(prv->mclk_ratio,
552 stream_data->mmio + XLNX_AUD_FS_MULTIPLIER);
553 }
554
555 return 0;
556}
557
558static int xlnx_formatter_pcm_hw_free(struct snd_soc_component *component,
559 struct snd_pcm_substream *substream)
560{
561 return snd_pcm_lib_free_pages(substream);
562}
563
564static int xlnx_formatter_pcm_trigger(struct snd_soc_component *component,
565 struct snd_pcm_substream *substream, int cmd)
566{
567 u32 val;
568 struct xlnx_pcm_stream_param *stream_data =
569 substream->runtime->private_data;
570
571 switch (cmd) {
572 case SNDRV_PCM_TRIGGER_START:
573 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
574 case SNDRV_PCM_TRIGGER_RESUME:
575 val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
576 val |= AUD_CTRL_DMA_EN_MASK;
577 iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
578 break;
579 case SNDRV_PCM_TRIGGER_STOP:
580 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
581 case SNDRV_PCM_TRIGGER_SUSPEND:
582 val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
583 val &= ~AUD_CTRL_DMA_EN_MASK;
584 iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
585 break;
586 }
587
588 return 0;
589}
590
591static int xlnx_formatter_pcm_new(struct snd_soc_component *component,
592 struct snd_soc_pcm_runtime *rtd)
593{
594 if (!component)
595 return -ENODEV;
596
597 snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
598 SNDRV_DMA_TYPE_DEV, component->dev,
599 xlnx_pcm_hardware.buffer_bytes_max,
600 xlnx_pcm_hardware.buffer_bytes_max);
601 return 0;
602}
603
604static struct snd_soc_component_driver xlnx_asoc_component = {
605 .name = DRV_NAME,
606 .open = xlnx_formatter_pcm_open,
607 .close = xlnx_formatter_pcm_close,
608 .hw_params = xlnx_formatter_pcm_hw_params,
609 .hw_free = xlnx_formatter_pcm_hw_free,
610 .trigger = xlnx_formatter_pcm_trigger,
611 .pointer = xlnx_formatter_pcm_pointer,
612 .pcm_construct = xlnx_formatter_pcm_new,
613};
614
615static int configure_mm2s(struct xlnx_pcm_drv_data *aud_drv_data,
616 struct platform_device *pdev)
617{
618 int ret;
619 struct device *dev = &pdev->dev;
620
621 aud_drv_data->mm2s_axis_clk = devm_clk_get(dev, "m_axis_mm2s_aclk");
622 if (IS_ERR(aud_drv_data->mm2s_axis_clk)) {
623 ret = PTR_ERR(aud_drv_data->mm2s_axis_clk);
624 dev_err(dev, "failed to get m_axis_mm2s_aclk(%d)\n", ret);
625 return ret;
626 }
627 ret = clk_prepare_enable(aud_drv_data->mm2s_axis_clk);
628 if (ret) {
629 dev_err(dev, "failed to enable m_axis_mm2s_aclk(%d)\n", ret);
630 return ret;
631 }
632
633 aud_drv_data->aud_mclk = devm_clk_get(dev, "aud_mclk");
634 if (IS_ERR(aud_drv_data->aud_mclk)) {
635 ret = PTR_ERR(aud_drv_data->aud_mclk);
636 dev_err(dev, "failed to get aud_mclk(%d)\n", ret);
637 goto axis_clk_err;
638 }
639 ret = clk_prepare_enable(aud_drv_data->aud_mclk);
640 if (ret) {
641 dev_err(dev, "failed to enable aud_mclk(%d)\n", ret);
642 goto axis_clk_err;
643 }
644
645 aud_drv_data->mm2s_irq = platform_get_irq_byname(pdev,
646 "irq_mm2s");
647 if (aud_drv_data->mm2s_irq < 0) {
648 ret = aud_drv_data->mm2s_irq;
649 goto mm2s_err;
650 }
651 ret = devm_request_irq(dev, aud_drv_data->mm2s_irq,
652 xlnx_mm2s_irq_handler, 0,
653 "xlnx_formatter_pcm_mm2s_irq",
654 dev);
655 if (ret) {
656 dev_err(dev, "xlnx audio mm2s irq request failed\n");
657 goto mm2s_err;
658 }
659 ret = xlnx_formatter_pcm_reset(aud_drv_data->mmio +
660 XLNX_MM2S_OFFSET);
661 if (ret) {
662 dev_err(dev, "audio formatter reset failed\n");
663 goto mm2s_err;
664 }
665 xlnx_formatter_disable_irqs(aud_drv_data->mmio +
666 XLNX_MM2S_OFFSET,
667 SNDRV_PCM_STREAM_PLAYBACK);
668
669 aud_drv_data->nodes[XLNX_PLAYBACK] =
670 of_parse_phandle(dev->of_node, "xlnx,tx", 0);
671 if (!aud_drv_data->nodes[XLNX_PLAYBACK])
672 dev_err(dev, "tx node not found\n");
673 else
674 dev_info(dev,
675 "sound card device will use DAI link: %s\n",
676 (aud_drv_data->nodes[XLNX_PLAYBACK])->name);
677 of_node_put(aud_drv_data->nodes[XLNX_PLAYBACK]);
678
679 aud_drv_data->mm2s_presence = true;
680 return 0;
681
682mm2s_err:
683 clk_disable_unprepare(aud_drv_data->aud_mclk);
684axis_clk_err:
685 clk_disable_unprepare(aud_drv_data->mm2s_axis_clk);
686
687 return ret;
688}
689
690static int configure_s2mm(struct xlnx_pcm_drv_data *aud_drv_data,
691 struct platform_device *pdev)
692{
693 int ret;
694 struct device *dev = &pdev->dev;
695
696 aud_drv_data->s2mm_axis_clk = devm_clk_get(dev, "s_axis_s2mm_aclk");
697 if (IS_ERR(aud_drv_data->s2mm_axis_clk)) {
698 ret = PTR_ERR(aud_drv_data->s2mm_axis_clk);
699 dev_err(dev, "failed to get s_axis_s2mm_aclk(%d)\n", ret);
700 return ret;
701 }
702 ret = clk_prepare_enable(aud_drv_data->s2mm_axis_clk);
703 if (ret) {
704 dev_err(dev, "failed to enable s_axis_s2mm_aclk(%d)\n", ret);
705 return ret;
706 }
707
708 aud_drv_data->s2mm_irq = platform_get_irq_byname(pdev, "irq_s2mm");
709 if (aud_drv_data->s2mm_irq < 0) {
710 ret = aud_drv_data->s2mm_irq;
711 goto s2mm_err;
712 }
713 ret = devm_request_irq(dev, aud_drv_data->s2mm_irq,
714 xlnx_s2mm_irq_handler, 0,
715 "xlnx_formatter_pcm_s2mm_irq",
716 dev);
717 if (ret) {
718 dev_err(dev, "xlnx audio s2mm irq request failed\n");
719 goto s2mm_err;
720 }
721 ret = xlnx_formatter_pcm_reset(aud_drv_data->mmio +
722 XLNX_S2MM_OFFSET);
723 if (ret) {
724 dev_err(dev, "audio formatter reset failed\n");
725 goto s2mm_err;
726 }
727 xlnx_formatter_disable_irqs(aud_drv_data->mmio +
728 XLNX_S2MM_OFFSET,
729 SNDRV_PCM_STREAM_CAPTURE);
730
731 aud_drv_data->nodes[XLNX_CAPTURE] =
732 of_parse_phandle(dev->of_node, "xlnx,rx", 0);
733 if (!aud_drv_data->nodes[XLNX_CAPTURE])
734 dev_err(dev, "rx node not found\n");
735 else
736 dev_info(dev, "sound card device will use DAI link: %s\n",
737 (aud_drv_data->nodes[XLNX_CAPTURE])->name);
738 of_node_put(aud_drv_data->nodes[XLNX_CAPTURE]);
739
740 aud_drv_data->s2mm_presence = true;
741 return 0;
742
743s2mm_err:
744 clk_disable_unprepare(aud_drv_data->s2mm_axis_clk);
745 return ret;
746}
747
748static int xlnx_formatter_pcm_probe(struct platform_device *pdev)
749{
750 int ret;
751 u32 val;
752 size_t pdata_size;
753 struct xlnx_pcm_drv_data *aud_drv_data;
754 struct device *dev = &pdev->dev;
755
756 aud_drv_data = devm_kzalloc(dev, sizeof(*aud_drv_data), GFP_KERNEL);
757 if (!aud_drv_data)
758 return -ENOMEM;
759
760 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
761 if (ret) {
762 dev_err(dev, "higher dma address mapping failed %d\n", ret);
763 return ret;
764 }
765
766 aud_drv_data->axi_clk = devm_clk_get(dev, "s_axi_lite_aclk");
767 if (IS_ERR(aud_drv_data->axi_clk)) {
768 ret = PTR_ERR(aud_drv_data->axi_clk);
769 dev_err(dev, "failed to get s_axi_lite_aclk(%d)\n", ret);
770 return ret;
771 }
772 ret = clk_prepare_enable(aud_drv_data->axi_clk);
773 if (ret) {
774 dev_err(dev, "failed to enable s_axi_lite_aclk(%d)\n", ret);
775 return ret;
776 }
777
778 aud_drv_data->mmio = devm_platform_ioremap_resource(pdev, 0);
779 if (IS_ERR(aud_drv_data->mmio)) {
780 dev_err(dev, "audio formatter ioremap failed\n");
781 ret = PTR_ERR(aud_drv_data->mmio);
782 goto clk_err;
783 }
784
785 val = ioread32(aud_drv_data->mmio + XLNX_AUD_CORE_CONFIG);
786 if (val & AUD_CFG_MM2S_MASK) {
787 ret = configure_mm2s(aud_drv_data, pdev);
788 if (ret)
789 goto clk_err;
790 }
791
792 if (val & AUD_CFG_S2MM_MASK) {
793 ret = configure_s2mm(aud_drv_data, pdev);
794 if (ret)
795 goto clk_err;
796 }
797
798 dev_set_drvdata(dev, aud_drv_data);
799
800 ret = devm_snd_soc_register_component(dev, &xlnx_asoc_component,
801 NULL, 0);
802 if (ret) {
803 dev_err(dev, "pcm platform device register failed\n");
804 goto clk_err;
805 }
806
807 pdata_size = sizeof(aud_drv_data->nodes);
808 if (aud_drv_data->nodes[XLNX_PLAYBACK] ||
809 aud_drv_data->nodes[XLNX_CAPTURE])
810 aud_drv_data->pdev =
811 platform_device_register_resndata(dev, "xlnx_snd_card",
812 PLATFORM_DEVID_AUTO,
813 NULL, 0,
814 &aud_drv_data->nodes,
815 pdata_size);
816 if (!aud_drv_data->pdev)
817 dev_err(dev, "sound card device creation failed\n");
818
819 dev_info(dev, "pcm platform device registered\n");
820 return 0;
821
822clk_err:
823 clk_disable_unprepare(aud_drv_data->axi_clk);
824 return ret;
825}
826
827static int xlnx_formatter_pcm_remove(struct platform_device *pdev)
828{
829 int ret = 0;
830 struct xlnx_pcm_drv_data *adata = dev_get_drvdata(&pdev->dev);
831
832 platform_device_unregister(adata->pdev);
833
834 if (adata->s2mm_presence)
835 ret = xlnx_formatter_pcm_reset(adata->mmio + XLNX_S2MM_OFFSET);
836
837
838 if (adata->mm2s_presence)
839 ret = xlnx_formatter_pcm_reset(adata->mmio + XLNX_MM2S_OFFSET);
840
841 if (ret)
842 dev_err(&pdev->dev, "audio formatter reset failed\n");
843
844 clk_disable_unprepare(adata->axi_clk);
845 return ret;
846}
847
848static const struct of_device_id xlnx_formatter_pcm_of_match[] = {
849 { .compatible = "xlnx,audio-formatter-1.0"},
850 {},
851};
852MODULE_DEVICE_TABLE(of, xlnx_formatter_pcm_of_match);
853
854static struct platform_driver xlnx_formatter_pcm_driver = {
855 .probe = xlnx_formatter_pcm_probe,
856 .remove = xlnx_formatter_pcm_remove,
857 .driver = {
858 .name = DRV_NAME,
859 .of_match_table = xlnx_formatter_pcm_of_match,
860 },
861};
862
863module_platform_driver(xlnx_formatter_pcm_driver);
864MODULE_AUTHOR("Maruthi Srinivas Bayyavarapu");
865MODULE_LICENSE("GPL v2");
866