1// SPDX-License-Identifier: GPL-2.0
2//
3// Socionext UniPhier AIO ALSA common driver.
4//
5// Copyright (c) 2016-2018 Socionext Inc.
6
7#include <linux/bitfield.h>
8#include <linux/errno.h>
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <sound/core.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/soc.h>
15
16#include "aio.h"
17#include "aio-reg.h"
18
19static u64 rb_cnt(u64 wr, u64 rd, u64 len)
20{
21	if (rd <= wr)
22		return wr - rd;
23	else
24		return len - (rd - wr);
25}
26
27static u64 rb_cnt_to_end(u64 wr, u64 rd, u64 len)
28{
29	if (rd <= wr)
30		return wr - rd;
31	else
32		return len - rd;
33}
34
35static u64 rb_space(u64 wr, u64 rd, u64 len)
36{
37	if (rd <= wr)
38		return len - (wr - rd) - 8;
39	else
40		return rd - wr - 8;
41}
42
43static u64 rb_space_to_end(u64 wr, u64 rd, u64 len)
44{
45	if (rd > wr)
46		return rd - wr - 8;
47	else if (rd > 0)
48		return len - wr;
49	else
50		return len - wr - 8;
51}
52
53u64 aio_rb_cnt(struct uniphier_aio_sub *sub)
54{
55	return rb_cnt(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
56}
57
58u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub)
59{
60	return rb_cnt_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
61}
62
63u64 aio_rb_space(struct uniphier_aio_sub *sub)
64{
65	return rb_space(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
66}
67
68u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub)
69{
70	return rb_space_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
71}
72
73/**
74 * aio_iecout_set_enable - setup IEC output via SoC glue
75 * @chip: the AIO chip pointer
76 * @enable: false to stop the output, true to start
77 *
78 * Set enabled or disabled S/PDIF signal output to out of SoC via AOnIEC pins.
79 * This function need to call at driver startup.
80 *
81 * The regmap of SoC glue is specified by 'socionext,syscon' optional property
82 * of DT. This function has no effect if no property.
83 */
84void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable)
85{
86	struct regmap *r = chip->regmap_sg;
87
88	if (!r)
89		return;
90
91	regmap_write(r, SG_AOUTEN, (enable) ? ~0 : 0);
92}
93
94/**
95 * aio_chip_set_pll - set frequency to audio PLL
96 * @chip: the AIO chip pointer
97 * @pll_id: PLL
98 * @freq: frequency in Hz, 0 is ignored
99 *
100 * Sets frequency of audio PLL. This function can be called anytime,
101 * but it takes time till PLL is locked.
102 *
103 * Return: Zero if successful, otherwise a negative value on error.
104 */
105int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
106		     unsigned int freq)
107{
108	struct device *dev = &chip->pdev->dev;
109	struct regmap *r = chip->regmap;
110	int shift;
111	u32 v;
112
113	/* Not change */
114	if (freq == 0)
115		return 0;
116
117	switch (pll_id) {
118	case AUD_PLL_A1:
119		shift = 0;
120		break;
121	case AUD_PLL_F1:
122		shift = 1;
123		break;
124	case AUD_PLL_A2:
125		shift = 2;
126		break;
127	case AUD_PLL_F2:
128		shift = 3;
129		break;
130	default:
131		dev_err(dev, "PLL(%d) not supported\n", pll_id);
132		return -EINVAL;
133	}
134
135	switch (freq) {
136	case 36864000:
137		v = A2APLLCTR1_APLLX_36MHZ;
138		break;
139	case 33868800:
140		v = A2APLLCTR1_APLLX_33MHZ;
141		break;
142	default:
143		dev_err(dev, "PLL frequency not supported(%d)\n", freq);
144		return -EINVAL;
145	}
146	chip->plls[pll_id].freq = freq;
147
148	regmap_update_bits(r, A2APLLCTR1, A2APLLCTR1_APLLX_MASK << shift,
149			   v << shift);
150
151	return 0;
152}
153
154/**
155 * aio_chip_init - initialize AIO whole settings
156 * @chip: the AIO chip pointer
157 *
158 * Sets AIO fixed and whole device settings to AIO.
159 * This function need to call once at driver startup.
160 *
161 * The register area that is changed by this function is shared by all
162 * modules of AIO. But there is not race condition since this function
163 * has always set the same initialize values.
164 */
165void aio_chip_init(struct uniphier_aio_chip *chip)
166{
167	struct regmap *r = chip->regmap;
168
169	regmap_update_bits(r, A2APLLCTR0,
170			   A2APLLCTR0_APLLXPOW_MASK,
171			   A2APLLCTR0_APLLXPOW_PWON);
172
173	regmap_update_bits(r, A2EXMCLKSEL0,
174			   A2EXMCLKSEL0_EXMCLK_MASK,
175			   A2EXMCLKSEL0_EXMCLK_OUTPUT);
176
177	regmap_update_bits(r, A2AIOINPUTSEL, A2AIOINPUTSEL_RXSEL_MASK,
178			   A2AIOINPUTSEL_RXSEL_PCMI1_HDMIRX1 |
179			   A2AIOINPUTSEL_RXSEL_PCMI2_SIF |
180			   A2AIOINPUTSEL_RXSEL_PCMI3_EVEA |
181			   A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1);
182
183	if (chip->chip_spec->addr_ext)
184		regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
185				   CDA2D_TEST_DDR_MODE_EXTON0);
186	else
187		regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
188				   CDA2D_TEST_DDR_MODE_EXTOFF1);
189}
190
191/**
192 * aio_init - initialize AIO substream
193 * @sub: the AIO substream pointer
194 *
195 * Sets fixed settings of each AIO substreams.
196 * This function need to call once at substream startup.
197 *
198 * Return: Zero if successful, otherwise a negative value on error.
199 */
200int aio_init(struct uniphier_aio_sub *sub)
201{
202	struct device *dev = &sub->aio->chip->pdev->dev;
203	struct regmap *r = sub->aio->chip->regmap;
204
205	regmap_write(r, A2RBNMAPCTR0(sub->swm->rb.hw),
206		     MAPCTR0_EN | sub->swm->rb.map);
207	regmap_write(r, A2CHNMAPCTR0(sub->swm->ch.hw),
208		     MAPCTR0_EN | sub->swm->ch.map);
209
210	switch (sub->swm->type) {
211	case PORT_TYPE_I2S:
212	case PORT_TYPE_SPDIF:
213	case PORT_TYPE_EVE:
214		if (sub->swm->dir == PORT_DIR_INPUT) {
215			regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
216				     MAPCTR0_EN | sub->swm->iif.map);
217			regmap_write(r, A2IPORTNMAPCTR0(sub->swm->iport.hw),
218				     MAPCTR0_EN | sub->swm->iport.map);
219		} else {
220			regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
221				     MAPCTR0_EN | sub->swm->oif.map);
222			regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
223				     MAPCTR0_EN | sub->swm->oport.map);
224		}
225		break;
226	case PORT_TYPE_CONV:
227		regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
228			     MAPCTR0_EN | sub->swm->oif.map);
229		regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
230			     MAPCTR0_EN | sub->swm->oport.map);
231		regmap_write(r, A2CHNMAPCTR0(sub->swm->och.hw),
232			     MAPCTR0_EN | sub->swm->och.map);
233		regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
234			     MAPCTR0_EN | sub->swm->iif.map);
235		break;
236	default:
237		dev_err(dev, "Unknown port type %d.\n", sub->swm->type);
238		return -EINVAL;
239	}
240
241	return 0;
242}
243
244/**
245 * aio_port_reset - reset AIO port block
246 * @sub: the AIO substream pointer
247 *
248 * Resets the digital signal input/output port block of AIO.
249 */
250void aio_port_reset(struct uniphier_aio_sub *sub)
251{
252	struct regmap *r = sub->aio->chip->regmap;
253
254	if (sub->swm->dir == PORT_DIR_OUTPUT) {
255		regmap_write(r, AOUTRSTCTR0, BIT(sub->swm->oport.map));
256		regmap_write(r, AOUTRSTCTR1, BIT(sub->swm->oport.map));
257	} else {
258		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
259				   IPORTMXRSTCTR_RSTPI_MASK,
260				   IPORTMXRSTCTR_RSTPI_RESET);
261		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
262				   IPORTMXRSTCTR_RSTPI_MASK,
263				   IPORTMXRSTCTR_RSTPI_RELEASE);
264	}
265}
266
267/**
268 * aio_port_set_ch - set channels of LPCM
269 * @sub: the AIO substream pointer, PCM substream only
270 *
271 * Set suitable slot selecting to input/output port block of AIO.
272 *
273 * This function may return error if non-PCM substream.
274 *
275 * Return: Zero if successful, otherwise a negative value on error.
276 */
277static int aio_port_set_ch(struct uniphier_aio_sub *sub)
278{
279	struct regmap *r = sub->aio->chip->regmap;
280	u32 slotsel_2ch[] = {
281		0, 0, 0, 0, 0,
282	};
283	u32 slotsel_multi[] = {
284		OPORTMXTYSLOTCTR_SLOTSEL_SLOT0,
285		OPORTMXTYSLOTCTR_SLOTSEL_SLOT1,
286		OPORTMXTYSLOTCTR_SLOTSEL_SLOT2,
287		OPORTMXTYSLOTCTR_SLOTSEL_SLOT3,
288		OPORTMXTYSLOTCTR_SLOTSEL_SLOT4,
289	};
290	u32 mode, *slotsel;
291	int i;
292
293	switch (params_channels(&sub->params)) {
294	case 8:
295	case 6:
296		mode = OPORTMXTYSLOTCTR_MODE;
297		slotsel = slotsel_multi;
298		break;
299	case 2:
300		mode = 0;
301		slotsel = slotsel_2ch;
302		break;
303	default:
304		return -EINVAL;
305	}
306
307	for (i = 0; i < AUD_MAX_SLOTSEL; i++) {
308		regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i),
309				   OPORTMXTYSLOTCTR_MODE, mode);
310		regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i),
311				   OPORTMXTYSLOTCTR_SLOTSEL_MASK, slotsel[i]);
312	}
313
314	return 0;
315}
316
317/**
318 * aio_port_set_rate - set sampling rate of LPCM
319 * @sub: the AIO substream pointer, PCM substream only
320 * @rate: Sampling rate in Hz.
321 *
322 * Set suitable I2S format settings to input/output port block of AIO.
323 * Parameter is specified by hw_params().
324 *
325 * This function may return error if non-PCM substream.
326 *
327 * Return: Zero if successful, otherwise a negative value on error.
328 */
329static int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate)
330{
331	struct regmap *r = sub->aio->chip->regmap;
332	struct device *dev = &sub->aio->chip->pdev->dev;
333	u32 v;
334
335	if (sub->swm->dir == PORT_DIR_OUTPUT) {
336		switch (rate) {
337		case 8000:
338			v = OPORTMXCTR1_FSSEL_8;
339			break;
340		case 11025:
341			v = OPORTMXCTR1_FSSEL_11_025;
342			break;
343		case 12000:
344			v = OPORTMXCTR1_FSSEL_12;
345			break;
346		case 16000:
347			v = OPORTMXCTR1_FSSEL_16;
348			break;
349		case 22050:
350			v = OPORTMXCTR1_FSSEL_22_05;
351			break;
352		case 24000:
353			v = OPORTMXCTR1_FSSEL_24;
354			break;
355		case 32000:
356			v = OPORTMXCTR1_FSSEL_32;
357			break;
358		case 44100:
359			v = OPORTMXCTR1_FSSEL_44_1;
360			break;
361		case 48000:
362			v = OPORTMXCTR1_FSSEL_48;
363			break;
364		case 88200:
365			v = OPORTMXCTR1_FSSEL_88_2;
366			break;
367		case 96000:
368			v = OPORTMXCTR1_FSSEL_96;
369			break;
370		case 176400:
371			v = OPORTMXCTR1_FSSEL_176_4;
372			break;
373		case 192000:
374			v = OPORTMXCTR1_FSSEL_192;
375			break;
376		default:
377			dev_err(dev, "Rate not supported(%d)\n", rate);
378			return -EINVAL;
379		}
380
381		regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
382				   OPORTMXCTR1_FSSEL_MASK, v);
383	} else {
384		switch (rate) {
385		case 8000:
386			v = IPORTMXCTR1_FSSEL_8;
387			break;
388		case 11025:
389			v = IPORTMXCTR1_FSSEL_11_025;
390			break;
391		case 12000:
392			v = IPORTMXCTR1_FSSEL_12;
393			break;
394		case 16000:
395			v = IPORTMXCTR1_FSSEL_16;
396			break;
397		case 22050:
398			v = IPORTMXCTR1_FSSEL_22_05;
399			break;
400		case 24000:
401			v = IPORTMXCTR1_FSSEL_24;
402			break;
403		case 32000:
404			v = IPORTMXCTR1_FSSEL_32;
405			break;
406		case 44100:
407			v = IPORTMXCTR1_FSSEL_44_1;
408			break;
409		case 48000:
410			v = IPORTMXCTR1_FSSEL_48;
411			break;
412		case 88200:
413			v = IPORTMXCTR1_FSSEL_88_2;
414			break;
415		case 96000:
416			v = IPORTMXCTR1_FSSEL_96;
417			break;
418		case 176400:
419			v = IPORTMXCTR1_FSSEL_176_4;
420			break;
421		case 192000:
422			v = IPORTMXCTR1_FSSEL_192;
423			break;
424		default:
425			dev_err(dev, "Rate not supported(%d)\n", rate);
426			return -EINVAL;
427		}
428
429		regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
430				   IPORTMXCTR1_FSSEL_MASK, v);
431	}
432
433	return 0;
434}
435
436/**
437 * aio_port_set_fmt - set format of I2S data
438 * @sub: the AIO substream pointer, PCM substream only
439 * This parameter has no effect if substream is I2S or PCM.
440 *
441 * Set suitable I2S format settings to input/output port block of AIO.
442 * Parameter is specified by set_fmt().
443 *
444 * This function may return error if non-PCM substream.
445 *
446 * Return: Zero if successful, otherwise a negative value on error.
447 */
448static int aio_port_set_fmt(struct uniphier_aio_sub *sub)
449{
450	struct regmap *r = sub->aio->chip->regmap;
451	struct device *dev = &sub->aio->chip->pdev->dev;
452	u32 v;
453
454	if (sub->swm->dir == PORT_DIR_OUTPUT) {
455		switch (sub->aio->fmt) {
456		case SND_SOC_DAIFMT_LEFT_J:
457			v = OPORTMXCTR1_I2SLRSEL_LEFT;
458			break;
459		case SND_SOC_DAIFMT_RIGHT_J:
460			v = OPORTMXCTR1_I2SLRSEL_RIGHT;
461			break;
462		case SND_SOC_DAIFMT_I2S:
463			v = OPORTMXCTR1_I2SLRSEL_I2S;
464			break;
465		default:
466			dev_err(dev, "Format is not supported(%d)\n",
467				sub->aio->fmt);
468			return -EINVAL;
469		}
470
471		v |= OPORTMXCTR1_OUTBITSEL_24;
472		regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
473				   OPORTMXCTR1_I2SLRSEL_MASK |
474				   OPORTMXCTR1_OUTBITSEL_MASK, v);
475	} else {
476		switch (sub->aio->fmt) {
477		case SND_SOC_DAIFMT_LEFT_J:
478			v = IPORTMXCTR1_LRSEL_LEFT;
479			break;
480		case SND_SOC_DAIFMT_RIGHT_J:
481			v = IPORTMXCTR1_LRSEL_RIGHT;
482			break;
483		case SND_SOC_DAIFMT_I2S:
484			v = IPORTMXCTR1_LRSEL_I2S;
485			break;
486		default:
487			dev_err(dev, "Format is not supported(%d)\n",
488				sub->aio->fmt);
489			return -EINVAL;
490		}
491
492		v |= IPORTMXCTR1_OUTBITSEL_24 |
493			IPORTMXCTR1_CHSEL_ALL;
494		regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
495				   IPORTMXCTR1_LRSEL_MASK |
496				   IPORTMXCTR1_OUTBITSEL_MASK |
497				   IPORTMXCTR1_CHSEL_MASK, v);
498	}
499
500	return 0;
501}
502
503/**
504 * aio_port_set_clk - set clock and divider of AIO port block
505 * @sub: the AIO substream pointer
506 *
507 * Set suitable PLL clock divider and relational settings to
508 * input/output port block of AIO. Parameters are specified by
509 * set_sysclk() and set_pll().
510 *
511 * Return: Zero if successful, otherwise a negative value on error.
512 */
513static int aio_port_set_clk(struct uniphier_aio_sub *sub)
514{
515	struct uniphier_aio_chip *chip = sub->aio->chip;
516	struct device *dev = &sub->aio->chip->pdev->dev;
517	struct regmap *r = sub->aio->chip->regmap;
518	u32 v_pll[] = {
519		OPORTMXCTR2_ACLKSEL_A1, OPORTMXCTR2_ACLKSEL_F1,
520		OPORTMXCTR2_ACLKSEL_A2, OPORTMXCTR2_ACLKSEL_F2,
521		OPORTMXCTR2_ACLKSEL_A2PLL,
522		OPORTMXCTR2_ACLKSEL_RX1,
523	};
524	u32 v_div[] = {
525		OPORTMXCTR2_DACCKSEL_1_2, OPORTMXCTR2_DACCKSEL_1_3,
526		OPORTMXCTR2_DACCKSEL_1_1, OPORTMXCTR2_DACCKSEL_2_3,
527	};
528	u32 v;
529
530	if (sub->swm->dir == PORT_DIR_OUTPUT) {
531		if (sub->swm->type == PORT_TYPE_I2S) {
532			if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
533				dev_err(dev, "PLL(%d) is invalid\n",
534					sub->aio->pll_out);
535				return -EINVAL;
536			}
537			if (sub->aio->plldiv >= ARRAY_SIZE(v_div)) {
538				dev_err(dev, "PLL divider(%d) is invalid\n",
539					sub->aio->plldiv);
540				return -EINVAL;
541			}
542
543			v = v_pll[sub->aio->pll_out] |
544				OPORTMXCTR2_MSSEL_MASTER |
545				v_div[sub->aio->plldiv];
546
547			switch (chip->plls[sub->aio->pll_out].freq) {
548			case 0:
549			case 36864000:
550			case 33868800:
551				v |= OPORTMXCTR2_EXTLSIFSSEL_36;
552				break;
553			default:
554				v |= OPORTMXCTR2_EXTLSIFSSEL_24;
555				break;
556			}
557		} else if (sub->swm->type == PORT_TYPE_EVE) {
558			v = OPORTMXCTR2_ACLKSEL_A2PLL |
559				OPORTMXCTR2_MSSEL_MASTER |
560				OPORTMXCTR2_EXTLSIFSSEL_36 |
561				OPORTMXCTR2_DACCKSEL_1_2;
562		} else if (sub->swm->type == PORT_TYPE_SPDIF) {
563			if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
564				dev_err(dev, "PLL(%d) is invalid\n",
565					sub->aio->pll_out);
566				return -EINVAL;
567			}
568			v = v_pll[sub->aio->pll_out] |
569				OPORTMXCTR2_MSSEL_MASTER |
570				OPORTMXCTR2_DACCKSEL_1_2;
571
572			switch (chip->plls[sub->aio->pll_out].freq) {
573			case 0:
574			case 36864000:
575			case 33868800:
576				v |= OPORTMXCTR2_EXTLSIFSSEL_36;
577				break;
578			default:
579				v |= OPORTMXCTR2_EXTLSIFSSEL_24;
580				break;
581			}
582		} else {
583			v = OPORTMXCTR2_ACLKSEL_A1 |
584				OPORTMXCTR2_MSSEL_MASTER |
585				OPORTMXCTR2_EXTLSIFSSEL_36 |
586				OPORTMXCTR2_DACCKSEL_1_2;
587		}
588		regmap_write(r, OPORTMXCTR2(sub->swm->oport.map), v);
589	} else {
590		v = IPORTMXCTR2_ACLKSEL_A1 |
591			IPORTMXCTR2_MSSEL_SLAVE |
592			IPORTMXCTR2_EXTLSIFSSEL_36 |
593			IPORTMXCTR2_DACCKSEL_1_2;
594		regmap_write(r, IPORTMXCTR2(sub->swm->iport.map), v);
595	}
596
597	return 0;
598}
599
600/**
601 * aio_port_set_param - set parameters of AIO port block
602 * @sub: the AIO substream pointer
603 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
604 * This parameter has no effect if substream is I2S or PCM.
605 * @params: hardware parameters of ALSA
606 *
607 * Set suitable setting to input/output port block of AIO to process the
608 * specified in params.
609 *
610 * Return: Zero if successful, otherwise a negative value on error.
611 */
612int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
613		       const struct snd_pcm_hw_params *params)
614{
615	struct regmap *r = sub->aio->chip->regmap;
616	unsigned int rate;
617	u32 v;
618	int ret;
619
620	if (!pass_through) {
621		if (sub->swm->type == PORT_TYPE_EVE ||
622		    sub->swm->type == PORT_TYPE_CONV) {
623			rate = 48000;
624		} else {
625			rate = params_rate(params);
626		}
627
628		ret = aio_port_set_ch(sub);
629		if (ret)
630			return ret;
631
632		ret = aio_port_set_rate(sub, rate);
633		if (ret)
634			return ret;
635
636		ret = aio_port_set_fmt(sub);
637		if (ret)
638			return ret;
639	}
640
641	ret = aio_port_set_clk(sub);
642	if (ret)
643		return ret;
644
645	if (sub->swm->dir == PORT_DIR_OUTPUT) {
646		if (pass_through)
647			v = OPORTMXCTR3_SRCSEL_STREAM |
648				OPORTMXCTR3_VALID_STREAM;
649		else
650			v = OPORTMXCTR3_SRCSEL_PCM |
651				OPORTMXCTR3_VALID_PCM;
652
653		v |= OPORTMXCTR3_IECTHUR_IECOUT |
654			OPORTMXCTR3_PMSEL_PAUSE |
655			OPORTMXCTR3_PMSW_MUTE_OFF;
656		regmap_write(r, OPORTMXCTR3(sub->swm->oport.map), v);
657	} else {
658		regmap_write(r, IPORTMXACLKSEL0EX(sub->swm->iport.map),
659			     IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL);
660		regmap_write(r, IPORTMXEXNOE(sub->swm->iport.map),
661			     IPORTMXEXNOE_PCMINOE_INPUT);
662	}
663
664	return 0;
665}
666
667/**
668 * aio_port_set_enable - start or stop of AIO port block
669 * @sub: the AIO substream pointer
670 * @enable: zero to stop the block, otherwise to start
671 *
672 * Start or stop the signal input/output port block of AIO.
673 */
674void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable)
675{
676	struct regmap *r = sub->aio->chip->regmap;
677
678	if (sub->swm->dir == PORT_DIR_OUTPUT) {
679		regmap_write(r, OPORTMXPATH(sub->swm->oport.map),
680			     sub->swm->oif.map);
681
682		regmap_update_bits(r, OPORTMXMASK(sub->swm->oport.map),
683				   OPORTMXMASK_IUDXMSK_MASK |
684				   OPORTMXMASK_IUXCKMSK_MASK |
685				   OPORTMXMASK_DXMSK_MASK |
686				   OPORTMXMASK_XCKMSK_MASK,
687				   OPORTMXMASK_IUDXMSK_OFF |
688				   OPORTMXMASK_IUXCKMSK_OFF |
689				   OPORTMXMASK_DXMSK_OFF |
690				   OPORTMXMASK_XCKMSK_OFF);
691
692		if (enable)
693			regmap_write(r, AOUTENCTR0, BIT(sub->swm->oport.map));
694		else
695			regmap_write(r, AOUTENCTR1, BIT(sub->swm->oport.map));
696	} else {
697		regmap_update_bits(r, IPORTMXMASK(sub->swm->iport.map),
698				   IPORTMXMASK_IUXCKMSK_MASK |
699				   IPORTMXMASK_XCKMSK_MASK,
700				   IPORTMXMASK_IUXCKMSK_OFF |
701				   IPORTMXMASK_XCKMSK_OFF);
702
703		if (enable)
704			regmap_update_bits(r,
705					   IPORTMXCTR2(sub->swm->iport.map),
706					   IPORTMXCTR2_REQEN_MASK,
707					   IPORTMXCTR2_REQEN_ENABLE);
708		else
709			regmap_update_bits(r,
710					   IPORTMXCTR2(sub->swm->iport.map),
711					   IPORTMXCTR2_REQEN_MASK,
712					   IPORTMXCTR2_REQEN_DISABLE);
713	}
714}
715
716/**
717 * aio_port_get_volume - get volume of AIO port block
718 * @sub: the AIO substream pointer
719 *
720 * Return: current volume, range is 0x0000 - 0xffff
721 */
722int aio_port_get_volume(struct uniphier_aio_sub *sub)
723{
724	struct regmap *r = sub->aio->chip->regmap;
725	u32 v;
726
727	regmap_read(r, OPORTMXTYVOLGAINSTATUS(sub->swm->oport.map, 0), &v);
728
729	return FIELD_GET(OPORTMXTYVOLGAINSTATUS_CUR_MASK, v);
730}
731
732/**
733 * aio_port_set_volume - set volume of AIO port block
734 * @sub: the AIO substream pointer
735 * @vol: target volume, range is 0x0000 - 0xffff.
736 *
737 * Change digital volume and perfome fade-out/fade-in effect for specified
738 * output slot of port. Gained PCM value can calculate as the following:
739 *   Gained = Original * vol / 0x4000
740 */
741void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol)
742{
743	struct regmap *r = sub->aio->chip->regmap;
744	int oport_map = sub->swm->oport.map;
745	int cur, diff, slope = 0, fs;
746
747	if (sub->swm->dir == PORT_DIR_INPUT)
748		return;
749
750	cur = aio_port_get_volume(sub);
751	diff = abs(vol - cur);
752	fs = params_rate(&sub->params);
753	if (fs)
754		slope = diff / AUD_VOL_FADE_TIME * 1000 / fs;
755	slope = max(1, slope);
756
757	regmap_update_bits(r, OPORTMXTYVOLPARA1(oport_map, 0),
758			   OPORTMXTYVOLPARA1_SLOPEU_MASK, slope << 16);
759	regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
760			   OPORTMXTYVOLPARA2_TARGET_MASK, vol);
761
762	if (cur < vol)
763		regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
764				   OPORTMXTYVOLPARA2_FADE_MASK,
765				   OPORTMXTYVOLPARA2_FADE_FADEIN);
766	else
767		regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
768				   OPORTMXTYVOLPARA2_FADE_MASK,
769				   OPORTMXTYVOLPARA2_FADE_FADEOUT);
770
771	regmap_write(r, AOUTFADECTR0, BIT(oport_map));
772}
773
774/**
775 * aio_if_set_param - set parameters of AIO DMA I/F block
776 * @sub: the AIO substream pointer
777 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
778 * This parameter has no effect if substream is I2S or PCM.
779 *
780 * Set suitable setting to DMA interface block of AIO to process the
781 * specified in settings.
782 *
783 * Return: Zero if successful, otherwise a negative value on error.
784 */
785int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through)
786{
787	struct regmap *r = sub->aio->chip->regmap;
788	u32 memfmt, v;
789
790	if (sub->swm->dir == PORT_DIR_OUTPUT) {
791		if (pass_through) {
792			v = PBOUTMXCTR0_ENDIAN_0123 |
793				PBOUTMXCTR0_MEMFMT_STREAM;
794		} else {
795			switch (params_channels(&sub->params)) {
796			case 2:
797				memfmt = PBOUTMXCTR0_MEMFMT_2CH;
798				break;
799			case 6:
800				memfmt = PBOUTMXCTR0_MEMFMT_6CH;
801				break;
802			case 8:
803				memfmt = PBOUTMXCTR0_MEMFMT_8CH;
804				break;
805			default:
806				return -EINVAL;
807			}
808			v = PBOUTMXCTR0_ENDIAN_3210 | memfmt;
809		}
810
811		regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v);
812		regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0);
813	} else {
814		regmap_write(r, PBINMXCTR(sub->swm->iif.map),
815			     PBINMXCTR_NCONNECT_CONNECT |
816			     PBINMXCTR_INOUTSEL_IN |
817			     (sub->swm->iport.map << PBINMXCTR_PBINSEL_SHIFT) |
818			     PBINMXCTR_ENDIAN_3210 |
819			     PBINMXCTR_MEMFMT_D0);
820	}
821
822	return 0;
823}
824
825/**
826 * aio_oport_set_stream_type - set parameters of AIO playback port block
827 * @sub: the AIO substream pointer
828 * @pc: Pc type of IEC61937
829 *
830 * Set special setting to output port block of AIO to output the stream
831 * via S/PDIF.
832 *
833 * Return: Zero if successful, otherwise a negative value on error.
834 */
835int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
836			      enum IEC61937_PC pc)
837{
838	struct regmap *r = sub->aio->chip->regmap;
839	u32 repet = 0, pause = OPORTMXPAUDAT_PAUSEPC_CMN;
840
841	switch (pc) {
842	case IEC61937_PC_AC3:
843		repet = OPORTMXREPET_STRLENGTH_AC3 |
844			OPORTMXREPET_PMLENGTH_AC3;
845		pause |= OPORTMXPAUDAT_PAUSEPD_AC3;
846		break;
847	case IEC61937_PC_MPA:
848		repet = OPORTMXREPET_STRLENGTH_MPA |
849			OPORTMXREPET_PMLENGTH_MPA;
850		pause |= OPORTMXPAUDAT_PAUSEPD_MPA;
851		break;
852	case IEC61937_PC_MP3:
853		repet = OPORTMXREPET_STRLENGTH_MP3 |
854			OPORTMXREPET_PMLENGTH_MP3;
855		pause |= OPORTMXPAUDAT_PAUSEPD_MP3;
856		break;
857	case IEC61937_PC_DTS1:
858		repet = OPORTMXREPET_STRLENGTH_DTS1 |
859			OPORTMXREPET_PMLENGTH_DTS1;
860		pause |= OPORTMXPAUDAT_PAUSEPD_DTS1;
861		break;
862	case IEC61937_PC_DTS2:
863		repet = OPORTMXREPET_STRLENGTH_DTS2 |
864			OPORTMXREPET_PMLENGTH_DTS2;
865		pause |= OPORTMXPAUDAT_PAUSEPD_DTS2;
866		break;
867	case IEC61937_PC_DTS3:
868		repet = OPORTMXREPET_STRLENGTH_DTS3 |
869			OPORTMXREPET_PMLENGTH_DTS3;
870		pause |= OPORTMXPAUDAT_PAUSEPD_DTS3;
871		break;
872	case IEC61937_PC_AAC:
873		repet = OPORTMXREPET_STRLENGTH_AAC |
874			OPORTMXREPET_PMLENGTH_AAC;
875		pause |= OPORTMXPAUDAT_PAUSEPD_AAC;
876		break;
877	case IEC61937_PC_PAUSE:
878		/* Do nothing */
879		break;
880	}
881
882	regmap_write(r, OPORTMXREPET(sub->swm->oport.map), repet);
883	regmap_write(r, OPORTMXPAUDAT(sub->swm->oport.map), pause);
884
885	return 0;
886}
887
888/**
889 * aio_src_reset - reset AIO SRC block
890 * @sub: the AIO substream pointer
891 *
892 * Resets the digital signal input/output port with sampling rate converter
893 * block of AIO.
894 * This function has no effect if substream is not supported rate converter.
895 */
896void aio_src_reset(struct uniphier_aio_sub *sub)
897{
898	struct regmap *r = sub->aio->chip->regmap;
899
900	if (sub->swm->dir != PORT_DIR_OUTPUT)
901		return;
902
903	regmap_write(r, AOUTSRCRSTCTR0, BIT(sub->swm->oport.map));
904	regmap_write(r, AOUTSRCRSTCTR1, BIT(sub->swm->oport.map));
905}
906
907/**
908 * aio_src_set_param - set parameters of AIO SRC block
909 * @sub: the AIO substream pointer
910 * @params: hardware parameters of ALSA
911 *
912 * Set suitable setting to input/output port with sampling rate converter
913 * block of AIO to process the specified in params.
914 * This function has no effect if substream is not supported rate converter.
915 *
916 * Return: Zero if successful, otherwise a negative value on error.
917 */
918int aio_src_set_param(struct uniphier_aio_sub *sub,
919		      const struct snd_pcm_hw_params *params)
920{
921	struct regmap *r = sub->aio->chip->regmap;
922	u32 v;
923
924	if (sub->swm->dir != PORT_DIR_OUTPUT)
925		return 0;
926
927	regmap_write(r, OPORTMXSRC1CTR(sub->swm->oport.map),
928		     OPORTMXSRC1CTR_THMODE_SRC |
929		     OPORTMXSRC1CTR_SRCPATH_CALC |
930		     OPORTMXSRC1CTR_SYNC_ASYNC |
931		     OPORTMXSRC1CTR_FSIIPSEL_INNER |
932		     OPORTMXSRC1CTR_FSISEL_ACLK);
933
934	switch (params_rate(params)) {
935	default:
936	case 48000:
937		v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
938			OPORTMXRATE_I_MCKSEL_36 |
939			OPORTMXRATE_I_FSSEL_48;
940		break;
941	case 44100:
942		v = OPORTMXRATE_I_ACLKSEL_APLLA2 |
943			OPORTMXRATE_I_MCKSEL_33 |
944			OPORTMXRATE_I_FSSEL_44_1;
945		break;
946	case 32000:
947		v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
948			OPORTMXRATE_I_MCKSEL_36 |
949			OPORTMXRATE_I_FSSEL_32;
950		break;
951	}
952
953	regmap_write(r, OPORTMXRATE_I(sub->swm->oport.map),
954		     v | OPORTMXRATE_I_ACLKSRC_APLL |
955		     OPORTMXRATE_I_LRCKSTP_STOP);
956	regmap_update_bits(r, OPORTMXRATE_I(sub->swm->oport.map),
957			   OPORTMXRATE_I_LRCKSTP_MASK,
958			   OPORTMXRATE_I_LRCKSTP_START);
959
960	return 0;
961}
962
963int aio_srcif_set_param(struct uniphier_aio_sub *sub)
964{
965	struct regmap *r = sub->aio->chip->regmap;
966
967	regmap_write(r, PBINMXCTR(sub->swm->iif.map),
968		     PBINMXCTR_NCONNECT_CONNECT |
969		     PBINMXCTR_INOUTSEL_OUT |
970		     (sub->swm->oport.map << PBINMXCTR_PBINSEL_SHIFT) |
971		     PBINMXCTR_ENDIAN_3210 |
972		     PBINMXCTR_MEMFMT_D0);
973
974	return 0;
975}
976
977int aio_srcch_set_param(struct uniphier_aio_sub *sub)
978{
979	struct regmap *r = sub->aio->chip->regmap;
980
981	regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->och.map),
982		     CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
983
984	regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->och.map),
985		     CDA2D_CHMXAMODE_ENDIAN_3210 |
986		     CDA2D_CHMXAMODE_AUPDT_FIX |
987		     CDA2D_CHMXAMODE_TYPE_NORMAL);
988
989	regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->och.map),
990		     CDA2D_CHMXAMODE_ENDIAN_3210 |
991		     CDA2D_CHMXAMODE_AUPDT_INC |
992		     CDA2D_CHMXAMODE_TYPE_RING |
993		     (sub->swm->och.map << CDA2D_CHMXAMODE_RSSEL_SHIFT));
994
995	return 0;
996}
997
998void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable)
999{
1000	struct regmap *r = sub->aio->chip->regmap;
1001	u32 v;
1002
1003	if (enable)
1004		v = CDA2D_STRT0_STOP_START;
1005	else
1006		v = CDA2D_STRT0_STOP_STOP;
1007
1008	regmap_write(r, CDA2D_STRT0,
1009		     v | BIT(sub->swm->och.map));
1010}
1011
1012int aiodma_ch_set_param(struct uniphier_aio_sub *sub)
1013{
1014	struct regmap *r = sub->aio->chip->regmap;
1015	u32 v;
1016
1017	regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->ch.map),
1018		     CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
1019
1020	v = CDA2D_CHMXAMODE_ENDIAN_3210 |
1021		CDA2D_CHMXAMODE_AUPDT_INC |
1022		CDA2D_CHMXAMODE_TYPE_NORMAL |
1023		(sub->swm->rb.map << CDA2D_CHMXAMODE_RSSEL_SHIFT);
1024	if (sub->swm->dir == PORT_DIR_OUTPUT)
1025		regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->ch.map), v);
1026	else
1027		regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->ch.map), v);
1028
1029	return 0;
1030}
1031
1032void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable)
1033{
1034	struct regmap *r = sub->aio->chip->regmap;
1035
1036	if (enable) {
1037		regmap_write(r, CDA2D_STRT0,
1038			     CDA2D_STRT0_STOP_START | BIT(sub->swm->ch.map));
1039
1040		regmap_update_bits(r, INTRBIM(0),
1041				   BIT(sub->swm->rb.map),
1042				   BIT(sub->swm->rb.map));
1043	} else {
1044		regmap_write(r, CDA2D_STRT0,
1045			     CDA2D_STRT0_STOP_STOP | BIT(sub->swm->ch.map));
1046
1047		regmap_update_bits(r, INTRBIM(0),
1048				   BIT(sub->swm->rb.map),
1049				   0);
1050	}
1051}
1052
1053static u64 aiodma_rb_get_rp(struct uniphier_aio_sub *sub)
1054{
1055	struct regmap *r = sub->aio->chip->regmap;
1056	u32 pos_u, pos_l;
1057	int i;
1058
1059	regmap_write(r, CDA2D_RDPTRLOAD,
1060		     CDA2D_RDPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
1061	/* Wait for setup */
1062	for (i = 0; i < 6; i++)
1063		regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
1064
1065	regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
1066	regmap_read(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), &pos_u);
1067	pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
1068
1069	return ((u64)pos_u << 32) | pos_l;
1070}
1071
1072static void aiodma_rb_set_rp(struct uniphier_aio_sub *sub, u64 pos)
1073{
1074	struct regmap *r = sub->aio->chip->regmap;
1075	u32 tmp;
1076	int i;
1077
1078	regmap_write(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), (u32)pos);
1079	regmap_write(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), (u32)(pos >> 32));
1080	regmap_write(r, CDA2D_RDPTRLOAD, BIT(sub->swm->rb.map));
1081	/* Wait for setup */
1082	for (i = 0; i < 6; i++)
1083		regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &tmp);
1084}
1085
1086static u64 aiodma_rb_get_wp(struct uniphier_aio_sub *sub)
1087{
1088	struct regmap *r = sub->aio->chip->regmap;
1089	u32 pos_u, pos_l;
1090	int i;
1091
1092	regmap_write(r, CDA2D_WRPTRLOAD,
1093		     CDA2D_WRPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
1094	/* Wait for setup */
1095	for (i = 0; i < 6; i++)
1096		regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
1097
1098	regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
1099	regmap_read(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map), &pos_u);
1100	pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
1101
1102	return ((u64)pos_u << 32) | pos_l;
1103}
1104
1105static void aiodma_rb_set_wp(struct uniphier_aio_sub *sub, u64 pos)
1106{
1107	struct regmap *r = sub->aio->chip->regmap;
1108	u32 tmp;
1109	int i;
1110
1111	regmap_write(r, CDA2D_RBMXWRPTR(sub->swm->rb.map),
1112		     lower_32_bits(pos));
1113	regmap_write(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map),
1114		     upper_32_bits(pos));
1115	regmap_write(r, CDA2D_WRPTRLOAD, BIT(sub->swm->rb.map));
1116	/* Wait for setup */
1117	for (i = 0; i < 6; i++)
1118		regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &tmp);
1119}
1120
1121int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th)
1122{
1123	struct regmap *r = sub->aio->chip->regmap;
1124
1125	if (size <= th)
1126		return -EINVAL;
1127
1128	regmap_write(r, CDA2D_RBMXBTH(sub->swm->rb.map), th);
1129	regmap_write(r, CDA2D_RBMXRTH(sub->swm->rb.map), th);
1130
1131	return 0;
1132}
1133
1134int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
1135			 int period)
1136{
1137	struct regmap *r = sub->aio->chip->regmap;
1138	u64 size = end - start;
1139	int ret;
1140
1141	if (end < start || period < 0)
1142		return -EINVAL;
1143
1144	regmap_write(r, CDA2D_RBMXCNFG(sub->swm->rb.map), 0);
1145	regmap_write(r, CDA2D_RBMXBGNADRS(sub->swm->rb.map),
1146		     lower_32_bits(start));
1147	regmap_write(r, CDA2D_RBMXBGNADRSU(sub->swm->rb.map),
1148		     upper_32_bits(start));
1149	regmap_write(r, CDA2D_RBMXENDADRS(sub->swm->rb.map),
1150		     lower_32_bits(end));
1151	regmap_write(r, CDA2D_RBMXENDADRSU(sub->swm->rb.map),
1152		     upper_32_bits(end));
1153
1154	regmap_write(r, CDA2D_RBADRSLOAD, BIT(sub->swm->rb.map));
1155
1156	ret = aiodma_rb_set_threshold(sub, size, 2 * period);
1157	if (ret)
1158		return ret;
1159
1160	if (sub->swm->dir == PORT_DIR_OUTPUT) {
1161		aiodma_rb_set_rp(sub, start);
1162		aiodma_rb_set_wp(sub, end - period);
1163
1164		regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
1165				   CDA2D_RBMXIX_SPACE,
1166				   CDA2D_RBMXIX_SPACE);
1167	} else {
1168		aiodma_rb_set_rp(sub, end - period);
1169		aiodma_rb_set_wp(sub, start);
1170
1171		regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
1172				   CDA2D_RBMXIX_REMAIN,
1173				   CDA2D_RBMXIX_REMAIN);
1174	}
1175
1176	sub->threshold = 2 * period;
1177	sub->rd_offs = 0;
1178	sub->wr_offs = 0;
1179	sub->rd_org = 0;
1180	sub->wr_org = 0;
1181	sub->rd_total = 0;
1182	sub->wr_total = 0;
1183
1184	return 0;
1185}
1186
1187void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
1188		    int period)
1189{
1190	if (sub->swm->dir == PORT_DIR_OUTPUT) {
1191		sub->rd_offs = aiodma_rb_get_rp(sub) - start;
1192
1193		if (sub->use_mmap) {
1194			sub->threshold = 2 * period;
1195			aiodma_rb_set_threshold(sub, size, 2 * period);
1196
1197			sub->wr_offs = sub->rd_offs - period;
1198			if (sub->rd_offs < period)
1199				sub->wr_offs += size;
1200		}
1201		aiodma_rb_set_wp(sub, sub->wr_offs + start);
1202	} else {
1203		sub->wr_offs = aiodma_rb_get_wp(sub) - start;
1204
1205		if (sub->use_mmap) {
1206			sub->threshold = 2 * period;
1207			aiodma_rb_set_threshold(sub, size, 2 * period);
1208
1209			sub->rd_offs = sub->wr_offs - period;
1210			if (sub->wr_offs < period)
1211				sub->rd_offs += size;
1212		}
1213		aiodma_rb_set_rp(sub, sub->rd_offs + start);
1214	}
1215
1216	sub->rd_total += sub->rd_offs - sub->rd_org;
1217	if (sub->rd_offs < sub->rd_org)
1218		sub->rd_total += size;
1219	sub->wr_total += sub->wr_offs - sub->wr_org;
1220	if (sub->wr_offs < sub->wr_org)
1221		sub->wr_total += size;
1222
1223	sub->rd_org = sub->rd_offs;
1224	sub->wr_org = sub->wr_offs;
1225}
1226
1227bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub)
1228{
1229	struct regmap *r = sub->aio->chip->regmap;
1230	u32 ir;
1231
1232	regmap_read(r, CDA2D_RBMXIR(sub->swm->rb.map), &ir);
1233
1234	if (sub->swm->dir == PORT_DIR_OUTPUT)
1235		return !!(ir & CDA2D_RBMXIX_SPACE);
1236	else
1237		return !!(ir & CDA2D_RBMXIX_REMAIN);
1238}
1239
1240void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub)
1241{
1242	struct regmap *r = sub->aio->chip->regmap;
1243
1244	if (sub->swm->dir == PORT_DIR_OUTPUT)
1245		regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
1246			     CDA2D_RBMXIX_SPACE);
1247	else
1248		regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
1249			     CDA2D_RBMXIX_REMAIN);
1250}
1251