1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Renesas R-Car MSIOF (Clock-Synchronized Serial Interface with FIFO) I2S driver
4 //
5 // Copyright (C) 2025 Renesas Solutions Corp.
6 // Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 //
8
9 /*
10 * [NOTE]
11 *
12 * This driver doesn't support Clock/Frame Provider Mode
13 *
14 * Basically MSIOF is created for SPI, but we can use it as I2S (Sound), etc. Because of it, when
15 * we use it as I2S (Sound) with Provider Mode, we need to send dummy TX data even though it was
16 * used for RX. Because SPI HW needs TX Clock/Frame output for RX purpose.
17 * But it makes driver code complex in I2S (Sound).
18 *
19 * And when we use it as I2S (Sound) as Provider Mode, the clock source is [MSO clock] (= 133.33MHz)
20 * SoC internal clock. It is not for 48kHz/44.1kHz base clock. Thus the output/input will not be
21 * accurate sound.
22 *
23 * Because of these reasons, this driver doesn't support Clock/Frame Provider Mode. Use it as
24 * Clock/Frame Consumer Mode.
25 */
26
27 #include <linux/module.h>
28 #include <linux/of.h>
29 #include <linux/of_dma.h>
30 #include <linux/of_graph.h>
31 #include <linux/platform_device.h>
32 #include <linux/pm_runtime.h>
33 #include <sound/dmaengine_pcm.h>
34 #include <sound/soc.h>
35
36 /* register */
37 #define SITMDR1 0x00
38 #define SITMDR2 0x04
39 #define SITMDR3 0x08
40 #define SIRMDR1 0x10
41 #define SIRMDR2 0x14
42 #define SIRMDR3 0x18
43 #define SICTR 0x28
44 #define SISTR 0x40
45 #define SIIER 0x44
46 #define SITFDR 0x50
47 #define SIRFDR 0x60
48
49 /* SITMDR1/ SIRMDR1 */
50 #define PCON (1 << 30) /* Transfer Signal Connection */
51 #define SYNCMD_LR (3 << 28) /* L/R mode */
52 #define SYNCAC (1 << 25) /* Sync Polarity (Active-low) */
53 #define DTDL_1 (1 << 20) /* 1-clock-cycle delay */
54 #define TXSTP (1 << 0) /* Transmission/Reception Stop on FIFO */
55
56 /* SITMDR2 and SIRMDR2 */
57 #define BITLEN1(x) (((x) - 1) << 24) /* Data Size (8-32 bits) */
58 #define GRP (1 << 30) /* Group count */
59
60 /* SICTR */
61 #define TEDG (1 << 27) /* Transmit Timing (1 = falling edge) */
62 #define REDG (1 << 26) /* Receive Timing (1 = rising edge) */
63 #define TXE (1 << 9) /* Transmit Enable */
64 #define RXE (1 << 8) /* Receive Enable */
65
66 /* SISTR */
67 #define TFSERR (1 << 21) /* Transmit Frame Synchronization Error */
68 #define TFOVF (1 << 20) /* Transmit FIFO Overflow */
69 #define TFUDF (1 << 19) /* Transmit FIFO Underflow */
70 #define RFSERR (1 << 5) /* Receive Frame Synchronization Error */
71 #define RFUDF (1 << 4) /* Receive FIFO Underflow */
72 #define RFOVF (1 << 3) /* Receive FIFO Overflow */
73 #define SISTR_ERR_TX (TFSERR | TFOVF | TFUDF)
74 #define SISTR_ERR_RX (RFSERR | RFOVF | RFUDF)
75 #define SISTR_ERR (SISTR_ERR_TX | SISTR_ERR_RX)
76
77 /* SIIER */
78 #define TDMAE (1 << 31) /* Transmit Data DMA Transfer Req. Enable */
79 #define TDREQE (1 << 28) /* Transmit Data Transfer Request Enable */
80 #define RDMAE (1 << 15) /* Receive Data DMA Transfer Req. Enable */
81 #define RDREQE (1 << 12) /* Receive Data Transfer Request Enable */
82
83 /*
84 * The data on memory in 24bit case is located at <right> side
85 * [ xxxxxx]
86 * [ xxxxxx]
87 * [ xxxxxx]
88 *
89 * HW assuming signal in 24bit case is located at <left> side
90 * ---+ +---------+
91 * +---------+ +---------+...
92 * [xxxxxx ][xxxxxx ][xxxxxx ]
93 *
94 * When we use 24bit data, it will be transferred via 32bit width via DMA,
95 * and MSIOF/DMA doesn't support data shift, we can't use 24bit data correctly.
96 * There is no such issue on 16/32bit data case.
97 */
98 #define MSIOF_RATES SNDRV_PCM_RATE_8000_192000
99 #define MSIOF_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\
100 SNDRV_PCM_FMTBIT_S32_LE)
101
102 struct msiof_priv {
103 struct device *dev;
104 struct snd_pcm_substream *substream[SNDRV_PCM_STREAM_LAST + 1];
105 spinlock_t lock;
106 void __iomem *base;
107 resource_size_t phy_addr;
108
109 /* for error */
110 int err_syc[SNDRV_PCM_STREAM_LAST + 1];
111 int err_ovf[SNDRV_PCM_STREAM_LAST + 1];
112 int err_udf[SNDRV_PCM_STREAM_LAST + 1];
113
114 /* bit field */
115 u32 flags;
116 #define MSIOF_FLAGS_NEED_DELAY (1 << 0)
117 };
118 #define msiof_flag_has(priv, flag) (priv->flags & flag)
119 #define msiof_flag_set(priv, flag) (priv->flags |= flag)
120
121 #define msiof_is_play(substream) ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 #define msiof_read(priv, reg) ioread32((priv)->base + reg)
123 #define msiof_write(priv, reg, val) iowrite32(val, (priv)->base + reg)
124 #define msiof_status_clear(priv) msiof_write(priv, SISTR, SISTR_ERR)
125
msiof_update(struct msiof_priv * priv,u32 reg,u32 mask,u32 val)126 static void msiof_update(struct msiof_priv *priv, u32 reg, u32 mask, u32 val)
127 {
128 u32 old = msiof_read(priv, reg);
129 u32 new = (old & ~mask) | (val & mask);
130
131 if (old != new)
132 msiof_write(priv, reg, new);
133 }
134
msiof_update_and_wait(struct msiof_priv * priv,u32 reg,u32 mask,u32 val,u32 expect)135 static void msiof_update_and_wait(struct msiof_priv *priv, u32 reg, u32 mask, u32 val, u32 expect)
136 {
137 u32 data;
138 int ret;
139
140 msiof_update(priv, reg, mask, val);
141
142 ret = readl_poll_timeout_atomic(priv->base + reg, data,
143 (data & mask) == expect, 1, 128);
144 if (ret)
145 dev_warn(priv->dev, "write timeout [0x%02x] 0x%08x / 0x%08x\n",
146 reg, data, expect);
147 }
148
msiof_hw_start(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)149 static int msiof_hw_start(struct snd_soc_component *component,
150 struct snd_pcm_substream *substream, int cmd)
151 {
152 struct msiof_priv *priv = snd_soc_component_get_drvdata(component);
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 int is_play = msiof_is_play(substream);
155 int width = snd_pcm_format_width(runtime->format);
156 u32 val;
157
158 /*
159 * see
160 * [NOTE] on top of this driver
161 */
162 /*
163 * see
164 * Datasheet 109.3.6 [Transmit and Receive Procedures]
165 *
166 * TX: Fig 109.14 - Fig 109.23
167 * RX: Fig 109.15
168 */
169
170 /* reset errors */
171 priv->err_syc[substream->stream] =
172 priv->err_ovf[substream->stream] =
173 priv->err_udf[substream->stream] = 0;
174
175 /* SITMDRx */
176 if (is_play) {
177 val = PCON | SYNCMD_LR | SYNCAC | TXSTP;
178 if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
179 val |= DTDL_1;
180
181 msiof_write(priv, SITMDR1, val);
182
183 val = BITLEN1(width);
184 msiof_write(priv, SITMDR2, val | GRP);
185 msiof_write(priv, SITMDR3, val);
186
187 }
188 /* SIRMDRx */
189 else {
190 val = SYNCMD_LR | SYNCAC;
191 if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
192 val |= DTDL_1;
193
194 msiof_write(priv, SIRMDR1, val);
195
196 val = BITLEN1(width);
197 msiof_write(priv, SIRMDR2, val | GRP);
198 msiof_write(priv, SIRMDR3, val);
199 }
200
201 /* SIIER */
202 if (is_play)
203 val = TDREQE | TDMAE | SISTR_ERR_TX;
204 else
205 val = RDREQE | RDMAE | SISTR_ERR_RX;
206 msiof_update(priv, SIIER, val, val);
207
208 /* SICTR */
209 if (is_play)
210 val = TXE | TEDG;
211 else
212 val = RXE | REDG;
213 msiof_update_and_wait(priv, SICTR, val, val, val);
214
215 msiof_status_clear(priv);
216
217 /* Start DMAC */
218 snd_dmaengine_pcm_trigger(substream, cmd);
219
220 return 0;
221 }
222
msiof_hw_stop(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)223 static int msiof_hw_stop(struct snd_soc_component *component,
224 struct snd_pcm_substream *substream, int cmd)
225 {
226 struct msiof_priv *priv = snd_soc_component_get_drvdata(component);
227 struct device *dev = component->dev;
228 int is_play = msiof_is_play(substream);
229 u32 val;
230
231 /* SIIER */
232 if (is_play)
233 val = TDREQE | TDMAE | SISTR_ERR_TX;
234 else
235 val = RDREQE | RDMAE | SISTR_ERR_RX;
236 msiof_update(priv, SIIER, val, 0);
237
238 /* Stop DMAC */
239 snd_dmaengine_pcm_trigger(substream, cmd);
240
241 /* SICTR */
242 if (is_play)
243 val = TXE;
244 else
245 val = RXE;
246 msiof_update_and_wait(priv, SICTR, val, 0, 0);
247
248 /* indicate error status if exist */
249 if (priv->err_syc[substream->stream] ||
250 priv->err_ovf[substream->stream] ||
251 priv->err_udf[substream->stream])
252 dev_warn(dev, "FSERR(%s) = %d, FOVF = %d, FUDF = %d\n",
253 snd_pcm_direction_name(substream->stream),
254 priv->err_syc[substream->stream],
255 priv->err_ovf[substream->stream],
256 priv->err_udf[substream->stream]);
257
258 return 0;
259 }
260
msiof_dai_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)261 static int msiof_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
262 {
263 struct msiof_priv *priv = snd_soc_dai_get_drvdata(dai);
264
265 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
266 /*
267 * It supports Clock/Frame Consumer Mode only
268 * see
269 * [NOTE] on top of this driver
270 */
271 case SND_SOC_DAIFMT_BC_FC:
272 break;
273 /* others are error */
274 default:
275 return -EINVAL;
276 }
277
278 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
279 /* it supports NB_NF only */
280 case SND_SOC_DAIFMT_NB_NF:
281 default:
282 break;
283 /* others are error */
284 case SND_SOC_DAIFMT_NB_IF:
285 case SND_SOC_DAIFMT_IB_NF:
286 case SND_SOC_DAIFMT_IB_IF:
287 return -EINVAL;
288 }
289
290 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
291 case SND_SOC_DAIFMT_I2S:
292 msiof_flag_set(priv, MSIOF_FLAGS_NEED_DELAY);
293 break;
294 case SND_SOC_DAIFMT_LEFT_J:
295 break;
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301 }
302
303 /*
304 * Select below from Sound Card, not auto
305 * SND_SOC_DAIFMT_CBC_CFC
306 * SND_SOC_DAIFMT_CBP_CFP
307 */
308 static const u64 msiof_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S |
309 SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
310 SND_SOC_POSSIBLE_DAIFMT_NB_NF;
311
312 static const struct snd_soc_dai_ops msiof_dai_ops = {
313 .set_fmt = msiof_dai_set_fmt,
314 .auto_selectable_formats = &msiof_dai_formats,
315 .num_auto_selectable_formats = 1,
316 };
317
318 static struct snd_soc_dai_driver msiof_dai_driver = {
319 .name = "msiof-dai",
320 .playback = {
321 .rates = MSIOF_RATES,
322 .formats = MSIOF_FMTS,
323 .channels_min = 2,
324 .channels_max = 2,
325 },
326 .capture = {
327 .rates = MSIOF_RATES,
328 .formats = MSIOF_FMTS,
329 .channels_min = 2,
330 .channels_max = 2,
331 },
332 .ops = &msiof_dai_ops,
333 };
334
335 static struct snd_pcm_hardware msiof_pcm_hardware = {
336 .info = SNDRV_PCM_INFO_INTERLEAVED |
337 SNDRV_PCM_INFO_MMAP |
338 SNDRV_PCM_INFO_MMAP_VALID,
339 .buffer_bytes_max = 64 * 1024,
340 .period_bytes_min = 32,
341 .period_bytes_max = 8192,
342 .periods_min = 1,
343 .periods_max = 32,
344 .fifo_size = 64,
345 };
346
msiof_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)347 static int msiof_open(struct snd_soc_component *component,
348 struct snd_pcm_substream *substream)
349 {
350 struct device *dev = component->dev;
351 struct dma_chan *chan;
352 static const char * const dma_names[] = {"rx", "tx"};
353 int is_play = msiof_is_play(substream);
354 int ret;
355
356 chan = of_dma_request_slave_channel(dev->of_node, dma_names[is_play]);
357 if (IS_ERR(chan))
358 return PTR_ERR(chan);
359
360 ret = snd_dmaengine_pcm_open(substream, chan);
361 if (ret < 0)
362 goto open_err_dma;
363
364 snd_soc_set_runtime_hwparams(substream, &msiof_pcm_hardware);
365
366 ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS);
367
368 open_err_dma:
369 if (ret < 0)
370 dma_release_channel(chan);
371
372 return ret;
373 }
374
msiof_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)375 static int msiof_close(struct snd_soc_component *component,
376 struct snd_pcm_substream *substream)
377 {
378 return snd_dmaengine_pcm_close_release_chan(substream);
379 }
380
msiof_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)381 static snd_pcm_uframes_t msiof_pointer(struct snd_soc_component *component,
382 struct snd_pcm_substream *substream)
383 {
384 return snd_dmaengine_pcm_pointer(substream);
385 }
386
387 #define PREALLOC_BUFFER (32 * 1024)
388 #define PREALLOC_BUFFER_MAX (32 * 1024)
msiof_new(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)389 static int msiof_new(struct snd_soc_component *component,
390 struct snd_soc_pcm_runtime *rtd)
391 {
392 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
393 rtd->card->snd_card->dev,
394 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
395 return 0;
396 }
397
msiof_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)398 static int msiof_trigger(struct snd_soc_component *component,
399 struct snd_pcm_substream *substream, int cmd)
400 {
401 struct device *dev = component->dev;
402 struct msiof_priv *priv = dev_get_drvdata(dev);
403 unsigned long flags;
404 int ret = -EINVAL;
405
406 spin_lock_irqsave(&priv->lock, flags);
407
408 switch (cmd) {
409 case SNDRV_PCM_TRIGGER_START:
410 priv->substream[substream->stream] = substream;
411 fallthrough;
412 case SNDRV_PCM_TRIGGER_RESUME:
413 ret = msiof_hw_start(component, substream, cmd);
414 break;
415 case SNDRV_PCM_TRIGGER_STOP:
416 priv->substream[substream->stream] = NULL;
417 fallthrough;
418 case SNDRV_PCM_TRIGGER_SUSPEND:
419 ret = msiof_hw_stop(component, substream, cmd);
420 break;
421 }
422
423 spin_unlock_irqrestore(&priv->lock, flags);
424
425 return ret;
426 }
427
msiof_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)428 static int msiof_hw_params(struct snd_soc_component *component,
429 struct snd_pcm_substream *substream,
430 struct snd_pcm_hw_params *params)
431 {
432 struct msiof_priv *priv = dev_get_drvdata(component->dev);
433 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
434 struct dma_slave_config cfg = {};
435 unsigned long flags;
436 int ret;
437
438 spin_lock_irqsave(&priv->lock, flags);
439
440 ret = snd_hwparams_to_dma_slave_config(substream, params, &cfg);
441 if (ret < 0)
442 goto hw_params_out;
443
444 cfg.dst_addr = priv->phy_addr + SITFDR;
445 cfg.src_addr = priv->phy_addr + SIRFDR;
446
447 ret = dmaengine_slave_config(chan, &cfg);
448 hw_params_out:
449 spin_unlock_irqrestore(&priv->lock, flags);
450
451 return ret;
452 }
453
454 static const struct snd_soc_component_driver msiof_component_driver = {
455 .name = "msiof",
456 .open = msiof_open,
457 .close = msiof_close,
458 .pointer = msiof_pointer,
459 .pcm_construct = msiof_new,
460 .trigger = msiof_trigger,
461 .hw_params = msiof_hw_params,
462 };
463
msiof_interrupt(int irq,void * data)464 static irqreturn_t msiof_interrupt(int irq, void *data)
465 {
466 struct msiof_priv *priv = data;
467 struct snd_pcm_substream *substream;
468 u32 sistr;
469
470 spin_lock(&priv->lock);
471
472 sistr = msiof_read(priv, SISTR);
473 msiof_status_clear(priv);
474
475 spin_unlock(&priv->lock);
476
477 /* overflow/underflow error */
478 substream = priv->substream[SNDRV_PCM_STREAM_PLAYBACK];
479 if (substream && (sistr & SISTR_ERR_TX)) {
480 // snd_pcm_stop_xrun(substream);
481 if (sistr & TFSERR)
482 priv->err_syc[SNDRV_PCM_STREAM_PLAYBACK]++;
483 if (sistr & TFOVF)
484 priv->err_ovf[SNDRV_PCM_STREAM_PLAYBACK]++;
485 if (sistr & TFUDF)
486 priv->err_udf[SNDRV_PCM_STREAM_PLAYBACK]++;
487 }
488
489 substream = priv->substream[SNDRV_PCM_STREAM_CAPTURE];
490 if (substream && (sistr & SISTR_ERR_RX)) {
491 // snd_pcm_stop_xrun(substream);
492 if (sistr & RFSERR)
493 priv->err_syc[SNDRV_PCM_STREAM_CAPTURE]++;
494 if (sistr & RFOVF)
495 priv->err_ovf[SNDRV_PCM_STREAM_CAPTURE]++;
496 if (sistr & RFUDF)
497 priv->err_udf[SNDRV_PCM_STREAM_CAPTURE]++;
498 }
499
500 return IRQ_HANDLED;
501 }
502
msiof_probe(struct platform_device * pdev)503 static int msiof_probe(struct platform_device *pdev)
504 {
505 struct msiof_priv *priv;
506 struct device *dev = &pdev->dev;
507 struct resource *res;
508 int irq, ret;
509
510 /* Check MSIOF as Sound mode or SPI mode */
511 struct device_node *port __free(device_node) = of_graph_get_next_port(dev->of_node, NULL);
512 if (!port)
513 return -ENODEV;
514
515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
516 if (!res)
517 return -ENODEV;
518
519 irq = platform_get_irq(pdev, 0);
520 if (irq <= 0)
521 return irq;
522
523 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
524 if (!priv)
525 return -ENOMEM;
526
527 priv->base = devm_ioremap_resource(dev, res);
528 if (IS_ERR(priv->base))
529 return PTR_ERR(priv->base);
530
531 ret = devm_request_irq(dev, irq, msiof_interrupt, 0, dev_name(dev), priv);
532 if (ret)
533 return ret;
534
535 priv->dev = dev;
536 priv->phy_addr = res->start;
537
538 spin_lock_init(&priv->lock);
539 platform_set_drvdata(pdev, priv);
540
541 devm_pm_runtime_enable(dev);
542
543 ret = devm_snd_soc_register_component(dev, &msiof_component_driver,
544 &msiof_dai_driver, 1);
545
546 return ret;
547 }
548
549 static const struct of_device_id msiof_of_match[] = {
550 { .compatible = "renesas,rcar-gen4-msiof", },
551 {},
552 };
553 MODULE_DEVICE_TABLE(of, msiof_of_match);
554
555 static struct platform_driver msiof_driver = {
556 .driver = {
557 .name = "msiof-pcm-audio",
558 .of_match_table = msiof_of_match,
559 },
560 .probe = msiof_probe,
561 };
562 module_platform_driver(msiof_driver);
563
564 MODULE_LICENSE("GPL");
565 MODULE_DESCRIPTION("Renesas R-Car MSIOF I2S audio driver");
566 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
567