xref: /linux/sound/soc/renesas/rcar/msiof.c (revision a9e6060bb2a6cae6d43a98ec0794844ad01273d3)
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