1 // SPDX-License-Identifier: GPL-2.0
3 // Socionext UniPhier AIO ALSA common driver.
5 // Copyright (c) 2016-2018 Socionext Inc.
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>
19 static u64
rb_cnt(u64 wr
, u64 rd
, u64 len
)
24 return len
- (rd
- wr
);
27 static u64
rb_cnt_to_end(u64 wr
, u64 rd
, u64 len
)
35 static u64
rb_space(u64 wr
, u64 rd
, u64 len
)
38 return len
- (wr
- rd
) - 8;
43 static u64
rb_space_to_end(u64 wr
, u64 rd
, u64 len
)
53 u64
aio_rb_cnt(struct uniphier_aio_sub
*sub
)
55 return rb_cnt(sub
->wr_offs
, sub
->rd_offs
, sub
->compr_bytes
);
58 u64
aio_rbt_cnt_to_end(struct uniphier_aio_sub
*sub
)
60 return rb_cnt_to_end(sub
->wr_offs
, sub
->rd_offs
, sub
->compr_bytes
);
63 u64
aio_rb_space(struct uniphier_aio_sub
*sub
)
65 return rb_space(sub
->wr_offs
, sub
->rd_offs
, sub
->compr_bytes
);
68 u64
aio_rb_space_to_end(struct uniphier_aio_sub
*sub
)
70 return rb_space_to_end(sub
->wr_offs
, sub
->rd_offs
, sub
->compr_bytes
);
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
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.
81 * The regmap of SoC glue is specified by 'socionext,syscon' optional property
82 * of DT. This function has no effect if no property.
84 void aio_iecout_set_enable(struct uniphier_aio_chip
*chip
, bool enable
)
86 struct regmap
*r
= chip
->regmap_sg
;
91 regmap_write(r
, SG_AOUTEN
, (enable
) ? ~0 : 0);
95 * aio_chip_set_pll - set frequency to audio PLL
96 * @chip: the AIO chip pointer
98 * @freq: frequency in Hz, 0 is ignored
100 * Sets frequency of audio PLL. This function can be called anytime,
101 * but it takes time till PLL is locked.
103 * Return: Zero if successful, otherwise a negative value on error.
105 int aio_chip_set_pll(struct uniphier_aio_chip
*chip
, int pll_id
,
108 struct device
*dev
= &chip
->pdev
->dev
;
109 struct regmap
*r
= chip
->regmap
;
131 dev_err(dev
, "PLL(%d) not supported\n", pll_id
);
137 v
= A2APLLCTR1_APLLX_36MHZ
;
140 v
= A2APLLCTR1_APLLX_33MHZ
;
143 dev_err(dev
, "PLL frequency not supported(%d)\n", freq
);
146 chip
->plls
[pll_id
].freq
= freq
;
148 regmap_update_bits(r
, A2APLLCTR1
, A2APLLCTR1_APLLX_MASK
<< shift
,
155 * aio_chip_init - initialize AIO whole settings
156 * @chip: the AIO chip pointer
158 * Sets AIO fixed and whole device settings to AIO.
159 * This function need to call once at driver startup.
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.
165 void aio_chip_init(struct uniphier_aio_chip
*chip
)
167 struct regmap
*r
= chip
->regmap
;
169 regmap_update_bits(r
, A2APLLCTR0
,
170 A2APLLCTR0_APLLXPOW_MASK
,
171 A2APLLCTR0_APLLXPOW_PWON
);
173 regmap_update_bits(r
, A2EXMCLKSEL0
,
174 A2EXMCLKSEL0_EXMCLK_MASK
,
175 A2EXMCLKSEL0_EXMCLK_OUTPUT
);
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
);
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
);
187 regmap_update_bits(r
, CDA2D_TEST
, CDA2D_TEST_DDR_MODE_MASK
,
188 CDA2D_TEST_DDR_MODE_EXTOFF1
);
192 * aio_init - initialize AIO substream
193 * @sub: the AIO substream pointer
195 * Sets fixed settings of each AIO substreams.
196 * This function need to call once at substream startup.
198 * Return: Zero if successful, otherwise a negative value on error.
200 int aio_init(struct uniphier_aio_sub
*sub
)
202 struct device
*dev
= &sub
->aio
->chip
->pdev
->dev
;
203 struct regmap
*r
= sub
->aio
->chip
->regmap
;
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
);
210 switch (sub
->swm
->type
) {
212 case PORT_TYPE_SPDIF
:
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
);
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
);
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
);
237 dev_err(dev
, "Unknown port type %d.\n", sub
->swm
->type
);
245 * aio_port_reset - reset AIO port block
246 * @sub: the AIO substream pointer
248 * Resets the digital signal input/output port block of AIO.
250 void aio_port_reset(struct uniphier_aio_sub
*sub
)
252 struct regmap
*r
= sub
->aio
->chip
->regmap
;
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
));
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
);
268 * aio_port_set_ch - set channels of LPCM
269 * @sub: the AIO substream pointer, PCM substream only
271 * Set suitable slot selecting to input/output port block of AIO.
273 * This function may return error if non-PCM substream.
275 * Return: Zero if successful, otherwise a negative value on error.
277 static int aio_port_set_ch(struct uniphier_aio_sub
*sub
)
279 struct regmap
*r
= sub
->aio
->chip
->regmap
;
280 static const u32 slotsel_2ch
[] = {
283 static const u32 slotsel_multi
[] = {
284 OPORTMXTYSLOTCTR_SLOTSEL_SLOT0
,
285 OPORTMXTYSLOTCTR_SLOTSEL_SLOT1
,
286 OPORTMXTYSLOTCTR_SLOTSEL_SLOT2
,
287 OPORTMXTYSLOTCTR_SLOTSEL_SLOT3
,
288 OPORTMXTYSLOTCTR_SLOTSEL_SLOT4
,
294 switch (params_channels(&sub
->params
)) {
297 mode
= OPORTMXTYSLOTCTR_MODE
;
298 slotsel
= slotsel_multi
;
302 slotsel
= slotsel_2ch
;
308 for (i
= 0; i
< AUD_MAX_SLOTSEL
; i
++) {
309 regmap_update_bits(r
, OPORTMXTYSLOTCTR(sub
->swm
->oport
.map
, i
),
310 OPORTMXTYSLOTCTR_MODE
, mode
);
311 regmap_update_bits(r
, OPORTMXTYSLOTCTR(sub
->swm
->oport
.map
, i
),
312 OPORTMXTYSLOTCTR_SLOTSEL_MASK
, slotsel
[i
]);
319 * aio_port_set_rate - set sampling rate of LPCM
320 * @sub: the AIO substream pointer, PCM substream only
321 * @rate: Sampling rate in Hz.
323 * Set suitable I2S format settings to input/output port block of AIO.
324 * Parameter is specified by hw_params().
326 * This function may return error if non-PCM substream.
328 * Return: Zero if successful, otherwise a negative value on error.
330 static int aio_port_set_rate(struct uniphier_aio_sub
*sub
, int rate
)
332 struct regmap
*r
= sub
->aio
->chip
->regmap
;
333 struct device
*dev
= &sub
->aio
->chip
->pdev
->dev
;
336 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
339 v
= OPORTMXCTR1_FSSEL_8
;
342 v
= OPORTMXCTR1_FSSEL_11_025
;
345 v
= OPORTMXCTR1_FSSEL_12
;
348 v
= OPORTMXCTR1_FSSEL_16
;
351 v
= OPORTMXCTR1_FSSEL_22_05
;
354 v
= OPORTMXCTR1_FSSEL_24
;
357 v
= OPORTMXCTR1_FSSEL_32
;
360 v
= OPORTMXCTR1_FSSEL_44_1
;
363 v
= OPORTMXCTR1_FSSEL_48
;
366 v
= OPORTMXCTR1_FSSEL_88_2
;
369 v
= OPORTMXCTR1_FSSEL_96
;
372 v
= OPORTMXCTR1_FSSEL_176_4
;
375 v
= OPORTMXCTR1_FSSEL_192
;
378 dev_err(dev
, "Rate not supported(%d)\n", rate
);
382 regmap_update_bits(r
, OPORTMXCTR1(sub
->swm
->oport
.map
),
383 OPORTMXCTR1_FSSEL_MASK
, v
);
387 v
= IPORTMXCTR1_FSSEL_8
;
390 v
= IPORTMXCTR1_FSSEL_11_025
;
393 v
= IPORTMXCTR1_FSSEL_12
;
396 v
= IPORTMXCTR1_FSSEL_16
;
399 v
= IPORTMXCTR1_FSSEL_22_05
;
402 v
= IPORTMXCTR1_FSSEL_24
;
405 v
= IPORTMXCTR1_FSSEL_32
;
408 v
= IPORTMXCTR1_FSSEL_44_1
;
411 v
= IPORTMXCTR1_FSSEL_48
;
414 v
= IPORTMXCTR1_FSSEL_88_2
;
417 v
= IPORTMXCTR1_FSSEL_96
;
420 v
= IPORTMXCTR1_FSSEL_176_4
;
423 v
= IPORTMXCTR1_FSSEL_192
;
426 dev_err(dev
, "Rate not supported(%d)\n", rate
);
430 regmap_update_bits(r
, IPORTMXCTR1(sub
->swm
->iport
.map
),
431 IPORTMXCTR1_FSSEL_MASK
, v
);
438 * aio_port_set_fmt - set format of I2S data
439 * @sub: the AIO substream pointer, PCM substream only
440 * This parameter has no effect if substream is I2S or PCM.
442 * Set suitable I2S format settings to input/output port block of AIO.
443 * Parameter is specified by set_fmt().
445 * This function may return error if non-PCM substream.
447 * Return: Zero if successful, otherwise a negative value on error.
449 static int aio_port_set_fmt(struct uniphier_aio_sub
*sub
)
451 struct regmap
*r
= sub
->aio
->chip
->regmap
;
452 struct device
*dev
= &sub
->aio
->chip
->pdev
->dev
;
455 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
456 switch (sub
->aio
->fmt
) {
457 case SND_SOC_DAIFMT_LEFT_J
:
458 v
= OPORTMXCTR1_I2SLRSEL_LEFT
;
460 case SND_SOC_DAIFMT_RIGHT_J
:
461 v
= OPORTMXCTR1_I2SLRSEL_RIGHT
;
463 case SND_SOC_DAIFMT_I2S
:
464 v
= OPORTMXCTR1_I2SLRSEL_I2S
;
467 dev_err(dev
, "Format is not supported(%d)\n",
472 v
|= OPORTMXCTR1_OUTBITSEL_24
;
473 regmap_update_bits(r
, OPORTMXCTR1(sub
->swm
->oport
.map
),
474 OPORTMXCTR1_I2SLRSEL_MASK
|
475 OPORTMXCTR1_OUTBITSEL_MASK
, v
);
477 switch (sub
->aio
->fmt
) {
478 case SND_SOC_DAIFMT_LEFT_J
:
479 v
= IPORTMXCTR1_LRSEL_LEFT
;
481 case SND_SOC_DAIFMT_RIGHT_J
:
482 v
= IPORTMXCTR1_LRSEL_RIGHT
;
484 case SND_SOC_DAIFMT_I2S
:
485 v
= IPORTMXCTR1_LRSEL_I2S
;
488 dev_err(dev
, "Format is not supported(%d)\n",
493 v
|= IPORTMXCTR1_OUTBITSEL_24
|
494 IPORTMXCTR1_CHSEL_ALL
;
495 regmap_update_bits(r
, IPORTMXCTR1(sub
->swm
->iport
.map
),
496 IPORTMXCTR1_LRSEL_MASK
|
497 IPORTMXCTR1_OUTBITSEL_MASK
|
498 IPORTMXCTR1_CHSEL_MASK
, v
);
505 * aio_port_set_clk - set clock and divider of AIO port block
506 * @sub: the AIO substream pointer
508 * Set suitable PLL clock divider and relational settings to
509 * input/output port block of AIO. Parameters are specified by
510 * set_sysclk() and set_pll().
512 * Return: Zero if successful, otherwise a negative value on error.
514 static int aio_port_set_clk(struct uniphier_aio_sub
*sub
)
516 struct uniphier_aio_chip
*chip
= sub
->aio
->chip
;
517 struct device
*dev
= &sub
->aio
->chip
->pdev
->dev
;
518 struct regmap
*r
= sub
->aio
->chip
->regmap
;
519 static const u32 v_pll
[] = {
520 OPORTMXCTR2_ACLKSEL_A1
, OPORTMXCTR2_ACLKSEL_F1
,
521 OPORTMXCTR2_ACLKSEL_A2
, OPORTMXCTR2_ACLKSEL_F2
,
522 OPORTMXCTR2_ACLKSEL_A2PLL
,
523 OPORTMXCTR2_ACLKSEL_RX1
,
525 static const u32 v_div
[] = {
526 OPORTMXCTR2_DACCKSEL_1_2
, OPORTMXCTR2_DACCKSEL_1_3
,
527 OPORTMXCTR2_DACCKSEL_1_1
, OPORTMXCTR2_DACCKSEL_2_3
,
531 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
532 if (sub
->swm
->type
== PORT_TYPE_I2S
) {
533 if (sub
->aio
->pll_out
>= ARRAY_SIZE(v_pll
)) {
534 dev_err(dev
, "PLL(%d) is invalid\n",
538 if (sub
->aio
->plldiv
>= ARRAY_SIZE(v_div
)) {
539 dev_err(dev
, "PLL divider(%d) is invalid\n",
544 v
= v_pll
[sub
->aio
->pll_out
] |
545 OPORTMXCTR2_MSSEL_MASTER
|
546 v_div
[sub
->aio
->plldiv
];
548 switch (chip
->plls
[sub
->aio
->pll_out
].freq
) {
552 v
|= OPORTMXCTR2_EXTLSIFSSEL_36
;
555 v
|= OPORTMXCTR2_EXTLSIFSSEL_24
;
558 } else if (sub
->swm
->type
== PORT_TYPE_EVE
) {
559 v
= OPORTMXCTR2_ACLKSEL_A2PLL
|
560 OPORTMXCTR2_MSSEL_MASTER
|
561 OPORTMXCTR2_EXTLSIFSSEL_36
|
562 OPORTMXCTR2_DACCKSEL_1_2
;
563 } else if (sub
->swm
->type
== PORT_TYPE_SPDIF
) {
564 if (sub
->aio
->pll_out
>= ARRAY_SIZE(v_pll
)) {
565 dev_err(dev
, "PLL(%d) is invalid\n",
569 v
= v_pll
[sub
->aio
->pll_out
] |
570 OPORTMXCTR2_MSSEL_MASTER
|
571 OPORTMXCTR2_DACCKSEL_1_2
;
573 switch (chip
->plls
[sub
->aio
->pll_out
].freq
) {
577 v
|= OPORTMXCTR2_EXTLSIFSSEL_36
;
580 v
|= OPORTMXCTR2_EXTLSIFSSEL_24
;
584 v
= OPORTMXCTR2_ACLKSEL_A1
|
585 OPORTMXCTR2_MSSEL_MASTER
|
586 OPORTMXCTR2_EXTLSIFSSEL_36
|
587 OPORTMXCTR2_DACCKSEL_1_2
;
589 regmap_write(r
, OPORTMXCTR2(sub
->swm
->oport
.map
), v
);
591 v
= IPORTMXCTR2_ACLKSEL_A1
|
592 IPORTMXCTR2_MSSEL_SLAVE
|
593 IPORTMXCTR2_EXTLSIFSSEL_36
|
594 IPORTMXCTR2_DACCKSEL_1_2
;
595 regmap_write(r
, IPORTMXCTR2(sub
->swm
->iport
.map
), v
);
602 * aio_port_set_param - set parameters of AIO port block
603 * @sub: the AIO substream pointer
604 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
605 * This parameter has no effect if substream is I2S or PCM.
606 * @params: hardware parameters of ALSA
608 * Set suitable setting to input/output port block of AIO to process the
609 * specified in params.
611 * Return: Zero if successful, otherwise a negative value on error.
613 int aio_port_set_param(struct uniphier_aio_sub
*sub
, int pass_through
,
614 const struct snd_pcm_hw_params
*params
)
616 struct regmap
*r
= sub
->aio
->chip
->regmap
;
622 if (sub
->swm
->type
== PORT_TYPE_EVE
||
623 sub
->swm
->type
== PORT_TYPE_CONV
) {
626 rate
= params_rate(params
);
629 ret
= aio_port_set_ch(sub
);
633 ret
= aio_port_set_rate(sub
, rate
);
637 ret
= aio_port_set_fmt(sub
);
642 ret
= aio_port_set_clk(sub
);
646 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
648 v
= OPORTMXCTR3_SRCSEL_STREAM
|
649 OPORTMXCTR3_VALID_STREAM
;
651 v
= OPORTMXCTR3_SRCSEL_PCM
|
652 OPORTMXCTR3_VALID_PCM
;
654 v
|= OPORTMXCTR3_IECTHUR_IECOUT
|
655 OPORTMXCTR3_PMSEL_PAUSE
|
656 OPORTMXCTR3_PMSW_MUTE_OFF
;
657 regmap_write(r
, OPORTMXCTR3(sub
->swm
->oport
.map
), v
);
659 regmap_write(r
, IPORTMXACLKSEL0EX(sub
->swm
->iport
.map
),
660 IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL
);
661 regmap_write(r
, IPORTMXEXNOE(sub
->swm
->iport
.map
),
662 IPORTMXEXNOE_PCMINOE_INPUT
);
669 * aio_port_set_enable - start or stop of AIO port block
670 * @sub: the AIO substream pointer
671 * @enable: zero to stop the block, otherwise to start
673 * Start or stop the signal input/output port block of AIO.
675 void aio_port_set_enable(struct uniphier_aio_sub
*sub
, int enable
)
677 struct regmap
*r
= sub
->aio
->chip
->regmap
;
679 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
680 regmap_write(r
, OPORTMXPATH(sub
->swm
->oport
.map
),
683 regmap_update_bits(r
, OPORTMXMASK(sub
->swm
->oport
.map
),
684 OPORTMXMASK_IUDXMSK_MASK
|
685 OPORTMXMASK_IUXCKMSK_MASK
|
686 OPORTMXMASK_DXMSK_MASK
|
687 OPORTMXMASK_XCKMSK_MASK
,
688 OPORTMXMASK_IUDXMSK_OFF
|
689 OPORTMXMASK_IUXCKMSK_OFF
|
690 OPORTMXMASK_DXMSK_OFF
|
691 OPORTMXMASK_XCKMSK_OFF
);
694 regmap_write(r
, AOUTENCTR0
, BIT(sub
->swm
->oport
.map
));
696 regmap_write(r
, AOUTENCTR1
, BIT(sub
->swm
->oport
.map
));
698 regmap_update_bits(r
, IPORTMXMASK(sub
->swm
->iport
.map
),
699 IPORTMXMASK_IUXCKMSK_MASK
|
700 IPORTMXMASK_XCKMSK_MASK
,
701 IPORTMXMASK_IUXCKMSK_OFF
|
702 IPORTMXMASK_XCKMSK_OFF
);
705 regmap_update_bits(r
,
706 IPORTMXCTR2(sub
->swm
->iport
.map
),
707 IPORTMXCTR2_REQEN_MASK
,
708 IPORTMXCTR2_REQEN_ENABLE
);
710 regmap_update_bits(r
,
711 IPORTMXCTR2(sub
->swm
->iport
.map
),
712 IPORTMXCTR2_REQEN_MASK
,
713 IPORTMXCTR2_REQEN_DISABLE
);
718 * aio_port_get_volume - get volume of AIO port block
719 * @sub: the AIO substream pointer
721 * Return: current volume, range is 0x0000 - 0xffff
723 int aio_port_get_volume(struct uniphier_aio_sub
*sub
)
725 struct regmap
*r
= sub
->aio
->chip
->regmap
;
728 regmap_read(r
, OPORTMXTYVOLGAINSTATUS(sub
->swm
->oport
.map
, 0), &v
);
730 return FIELD_GET(OPORTMXTYVOLGAINSTATUS_CUR_MASK
, v
);
734 * aio_port_set_volume - set volume of AIO port block
735 * @sub: the AIO substream pointer
736 * @vol: target volume, range is 0x0000 - 0xffff.
738 * Change digital volume and perfome fade-out/fade-in effect for specified
739 * output slot of port. Gained PCM value can calculate as the following:
740 * Gained = Original * vol / 0x4000
742 void aio_port_set_volume(struct uniphier_aio_sub
*sub
, int vol
)
744 struct regmap
*r
= sub
->aio
->chip
->regmap
;
745 int oport_map
= sub
->swm
->oport
.map
;
746 int cur
, diff
, slope
= 0, fs
;
748 if (sub
->swm
->dir
== PORT_DIR_INPUT
)
751 cur
= aio_port_get_volume(sub
);
752 diff
= abs(vol
- cur
);
753 fs
= params_rate(&sub
->params
);
755 slope
= diff
/ AUD_VOL_FADE_TIME
* 1000 / fs
;
756 slope
= max(1, slope
);
758 regmap_update_bits(r
, OPORTMXTYVOLPARA1(oport_map
, 0),
759 OPORTMXTYVOLPARA1_SLOPEU_MASK
, slope
<< 16);
760 regmap_update_bits(r
, OPORTMXTYVOLPARA2(oport_map
, 0),
761 OPORTMXTYVOLPARA2_TARGET_MASK
, vol
);
764 regmap_update_bits(r
, OPORTMXTYVOLPARA2(oport_map
, 0),
765 OPORTMXTYVOLPARA2_FADE_MASK
,
766 OPORTMXTYVOLPARA2_FADE_FADEIN
);
768 regmap_update_bits(r
, OPORTMXTYVOLPARA2(oport_map
, 0),
769 OPORTMXTYVOLPARA2_FADE_MASK
,
770 OPORTMXTYVOLPARA2_FADE_FADEOUT
);
772 regmap_write(r
, AOUTFADECTR0
, BIT(oport_map
));
776 * aio_if_set_param - set parameters of AIO DMA I/F block
777 * @sub: the AIO substream pointer
778 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
779 * This parameter has no effect if substream is I2S or PCM.
781 * Set suitable setting to DMA interface block of AIO to process the
782 * specified in settings.
784 * Return: Zero if successful, otherwise a negative value on error.
786 int aio_if_set_param(struct uniphier_aio_sub
*sub
, int pass_through
)
788 struct regmap
*r
= sub
->aio
->chip
->regmap
;
791 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
793 v
= PBOUTMXCTR0_ENDIAN_0123
|
794 PBOUTMXCTR0_MEMFMT_STREAM
;
796 switch (params_channels(&sub
->params
)) {
798 memfmt
= PBOUTMXCTR0_MEMFMT_2CH
;
801 memfmt
= PBOUTMXCTR0_MEMFMT_6CH
;
804 memfmt
= PBOUTMXCTR0_MEMFMT_8CH
;
809 v
= PBOUTMXCTR0_ENDIAN_3210
| memfmt
;
812 regmap_write(r
, PBOUTMXCTR0(sub
->swm
->oif
.map
), v
);
813 regmap_write(r
, PBOUTMXCTR1(sub
->swm
->oif
.map
), 0);
815 regmap_write(r
, PBINMXCTR(sub
->swm
->iif
.map
),
816 PBINMXCTR_NCONNECT_CONNECT
|
817 PBINMXCTR_INOUTSEL_IN
|
818 (sub
->swm
->iport
.map
<< PBINMXCTR_PBINSEL_SHIFT
) |
819 PBINMXCTR_ENDIAN_3210
|
820 PBINMXCTR_MEMFMT_D0
);
827 * aio_oport_set_stream_type - set parameters of AIO playback port block
828 * @sub: the AIO substream pointer
829 * @pc: Pc type of IEC61937
831 * Set special setting to output port block of AIO to output the stream
834 * Return: Zero if successful, otherwise a negative value on error.
836 int aio_oport_set_stream_type(struct uniphier_aio_sub
*sub
,
839 struct regmap
*r
= sub
->aio
->chip
->regmap
;
840 u32 repet
= 0, pause
= OPORTMXPAUDAT_PAUSEPC_CMN
;
844 case IEC61937_PC_AC3
:
845 repet
= OPORTMXREPET_STRLENGTH_AC3
|
846 OPORTMXREPET_PMLENGTH_AC3
;
847 pause
|= OPORTMXPAUDAT_PAUSEPD_AC3
;
849 case IEC61937_PC_MPA
:
850 repet
= OPORTMXREPET_STRLENGTH_MPA
|
851 OPORTMXREPET_PMLENGTH_MPA
;
852 pause
|= OPORTMXPAUDAT_PAUSEPD_MPA
;
854 case IEC61937_PC_MP3
:
855 repet
= OPORTMXREPET_STRLENGTH_MP3
|
856 OPORTMXREPET_PMLENGTH_MP3
;
857 pause
|= OPORTMXPAUDAT_PAUSEPD_MP3
;
859 case IEC61937_PC_DTS1
:
860 repet
= OPORTMXREPET_STRLENGTH_DTS1
|
861 OPORTMXREPET_PMLENGTH_DTS1
;
862 pause
|= OPORTMXPAUDAT_PAUSEPD_DTS1
;
864 case IEC61937_PC_DTS2
:
865 repet
= OPORTMXREPET_STRLENGTH_DTS2
|
866 OPORTMXREPET_PMLENGTH_DTS2
;
867 pause
|= OPORTMXPAUDAT_PAUSEPD_DTS2
;
869 case IEC61937_PC_DTS3
:
870 repet
= OPORTMXREPET_STRLENGTH_DTS3
|
871 OPORTMXREPET_PMLENGTH_DTS3
;
872 pause
|= OPORTMXPAUDAT_PAUSEPD_DTS3
;
874 case IEC61937_PC_AAC
:
875 repet
= OPORTMXREPET_STRLENGTH_AAC
|
876 OPORTMXREPET_PMLENGTH_AAC
;
877 pause
|= OPORTMXPAUDAT_PAUSEPD_AAC
;
879 case IEC61937_PC_PAUSE
:
884 ret
= regmap_write(r
, OPORTMXREPET(sub
->swm
->oport
.map
), repet
);
888 ret
= regmap_write(r
, OPORTMXPAUDAT(sub
->swm
->oport
.map
), pause
);
896 * aio_src_reset - reset AIO SRC block
897 * @sub: the AIO substream pointer
899 * Resets the digital signal input/output port with sampling rate converter
901 * This function has no effect if substream is not supported rate converter.
903 void aio_src_reset(struct uniphier_aio_sub
*sub
)
905 struct regmap
*r
= sub
->aio
->chip
->regmap
;
907 if (sub
->swm
->dir
!= PORT_DIR_OUTPUT
)
910 regmap_write(r
, AOUTSRCRSTCTR0
, BIT(sub
->swm
->oport
.map
));
911 regmap_write(r
, AOUTSRCRSTCTR1
, BIT(sub
->swm
->oport
.map
));
915 * aio_src_set_param - set parameters of AIO SRC block
916 * @sub: the AIO substream pointer
917 * @params: hardware parameters of ALSA
919 * Set suitable setting to input/output port with sampling rate converter
920 * block of AIO to process the specified in params.
921 * This function has no effect if substream is not supported rate converter.
923 * Return: Zero if successful, otherwise a negative value on error.
925 int aio_src_set_param(struct uniphier_aio_sub
*sub
,
926 const struct snd_pcm_hw_params
*params
)
928 struct regmap
*r
= sub
->aio
->chip
->regmap
;
932 if (sub
->swm
->dir
!= PORT_DIR_OUTPUT
)
935 ret
= regmap_write(r
, OPORTMXSRC1CTR(sub
->swm
->oport
.map
),
936 OPORTMXSRC1CTR_THMODE_SRC
|
937 OPORTMXSRC1CTR_SRCPATH_CALC
|
938 OPORTMXSRC1CTR_SYNC_ASYNC
|
939 OPORTMXSRC1CTR_FSIIPSEL_INNER
|
940 OPORTMXSRC1CTR_FSISEL_ACLK
);
944 switch (params_rate(params
)) {
947 v
= OPORTMXRATE_I_ACLKSEL_APLLA1
|
948 OPORTMXRATE_I_MCKSEL_36
|
949 OPORTMXRATE_I_FSSEL_48
;
952 v
= OPORTMXRATE_I_ACLKSEL_APLLA2
|
953 OPORTMXRATE_I_MCKSEL_33
|
954 OPORTMXRATE_I_FSSEL_44_1
;
957 v
= OPORTMXRATE_I_ACLKSEL_APLLA1
|
958 OPORTMXRATE_I_MCKSEL_36
|
959 OPORTMXRATE_I_FSSEL_32
;
964 ret
= regmap_write(r
, OPORTMXRATE_I(sub
->swm
->oport
.map
),
965 v
| OPORTMXRATE_I_ACLKSRC_APLL
|
966 OPORTMXRATE_I_LRCKSTP_STOP
);
970 ret
= regmap_update_bits(r
, OPORTMXRATE_I(sub
->swm
->oport
.map
),
971 OPORTMXRATE_I_LRCKSTP_MASK
,
972 OPORTMXRATE_I_LRCKSTP_START
);
979 int aio_srcif_set_param(struct uniphier_aio_sub
*sub
)
981 struct regmap
*r
= sub
->aio
->chip
->regmap
;
983 regmap_write(r
, PBINMXCTR(sub
->swm
->iif
.map
),
984 PBINMXCTR_NCONNECT_CONNECT
|
985 PBINMXCTR_INOUTSEL_OUT
|
986 (sub
->swm
->oport
.map
<< PBINMXCTR_PBINSEL_SHIFT
) |
987 PBINMXCTR_ENDIAN_3210
|
988 PBINMXCTR_MEMFMT_D0
);
993 int aio_srcch_set_param(struct uniphier_aio_sub
*sub
)
995 struct regmap
*r
= sub
->aio
->chip
->regmap
;
997 regmap_write(r
, CDA2D_CHMXCTRL1(sub
->swm
->och
.map
),
998 CDA2D_CHMXCTRL1_INDSIZE_INFINITE
);
1000 regmap_write(r
, CDA2D_CHMXSRCAMODE(sub
->swm
->och
.map
),
1001 CDA2D_CHMXAMODE_ENDIAN_3210
|
1002 CDA2D_CHMXAMODE_AUPDT_FIX
|
1003 CDA2D_CHMXAMODE_TYPE_NORMAL
);
1005 regmap_write(r
, CDA2D_CHMXDSTAMODE(sub
->swm
->och
.map
),
1006 CDA2D_CHMXAMODE_ENDIAN_3210
|
1007 CDA2D_CHMXAMODE_AUPDT_INC
|
1008 CDA2D_CHMXAMODE_TYPE_RING
|
1009 (sub
->swm
->och
.map
<< CDA2D_CHMXAMODE_RSSEL_SHIFT
));
1014 void aio_srcch_set_enable(struct uniphier_aio_sub
*sub
, int enable
)
1016 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1020 v
= CDA2D_STRT0_STOP_START
;
1022 v
= CDA2D_STRT0_STOP_STOP
;
1024 regmap_write(r
, CDA2D_STRT0
,
1025 v
| BIT(sub
->swm
->och
.map
));
1028 int aiodma_ch_set_param(struct uniphier_aio_sub
*sub
)
1030 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1033 regmap_write(r
, CDA2D_CHMXCTRL1(sub
->swm
->ch
.map
),
1034 CDA2D_CHMXCTRL1_INDSIZE_INFINITE
);
1036 v
= CDA2D_CHMXAMODE_ENDIAN_3210
|
1037 CDA2D_CHMXAMODE_AUPDT_INC
|
1038 CDA2D_CHMXAMODE_TYPE_NORMAL
|
1039 (sub
->swm
->rb
.map
<< CDA2D_CHMXAMODE_RSSEL_SHIFT
);
1040 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
)
1041 regmap_write(r
, CDA2D_CHMXSRCAMODE(sub
->swm
->ch
.map
), v
);
1043 regmap_write(r
, CDA2D_CHMXDSTAMODE(sub
->swm
->ch
.map
), v
);
1048 void aiodma_ch_set_enable(struct uniphier_aio_sub
*sub
, int enable
)
1050 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1053 regmap_write(r
, CDA2D_STRT0
,
1054 CDA2D_STRT0_STOP_START
| BIT(sub
->swm
->ch
.map
));
1056 regmap_update_bits(r
, INTRBIM(0),
1057 BIT(sub
->swm
->rb
.map
),
1058 BIT(sub
->swm
->rb
.map
));
1060 regmap_write(r
, CDA2D_STRT0
,
1061 CDA2D_STRT0_STOP_STOP
| BIT(sub
->swm
->ch
.map
));
1063 regmap_update_bits(r
, INTRBIM(0),
1064 BIT(sub
->swm
->rb
.map
),
1069 static u64
aiodma_rb_get_rp(struct uniphier_aio_sub
*sub
)
1071 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1075 regmap_write(r
, CDA2D_RDPTRLOAD
,
1076 CDA2D_RDPTRLOAD_LSFLAG_STORE
| BIT(sub
->swm
->rb
.map
));
1077 /* Wait for setup */
1078 for (i
= 0; i
< 6; i
++)
1079 regmap_read(r
, CDA2D_RBMXRDPTR(sub
->swm
->rb
.map
), &pos_l
);
1081 regmap_read(r
, CDA2D_RBMXRDPTR(sub
->swm
->rb
.map
), &pos_l
);
1082 regmap_read(r
, CDA2D_RBMXRDPTRU(sub
->swm
->rb
.map
), &pos_u
);
1083 pos_u
= FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK
, pos_u
);
1085 return ((u64
)pos_u
<< 32) | pos_l
;
1088 static void aiodma_rb_set_rp(struct uniphier_aio_sub
*sub
, u64 pos
)
1090 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1094 regmap_write(r
, CDA2D_RBMXRDPTR(sub
->swm
->rb
.map
), (u32
)pos
);
1095 regmap_write(r
, CDA2D_RBMXRDPTRU(sub
->swm
->rb
.map
), (u32
)(pos
>> 32));
1096 regmap_write(r
, CDA2D_RDPTRLOAD
, BIT(sub
->swm
->rb
.map
));
1097 /* Wait for setup */
1098 for (i
= 0; i
< 6; i
++)
1099 regmap_read(r
, CDA2D_RBMXRDPTR(sub
->swm
->rb
.map
), &tmp
);
1102 static u64
aiodma_rb_get_wp(struct uniphier_aio_sub
*sub
)
1104 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1108 regmap_write(r
, CDA2D_WRPTRLOAD
,
1109 CDA2D_WRPTRLOAD_LSFLAG_STORE
| BIT(sub
->swm
->rb
.map
));
1110 /* Wait for setup */
1111 for (i
= 0; i
< 6; i
++)
1112 regmap_read(r
, CDA2D_RBMXWRPTR(sub
->swm
->rb
.map
), &pos_l
);
1114 regmap_read(r
, CDA2D_RBMXWRPTR(sub
->swm
->rb
.map
), &pos_l
);
1115 regmap_read(r
, CDA2D_RBMXWRPTRU(sub
->swm
->rb
.map
), &pos_u
);
1116 pos_u
= FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK
, pos_u
);
1118 return ((u64
)pos_u
<< 32) | pos_l
;
1121 static void aiodma_rb_set_wp(struct uniphier_aio_sub
*sub
, u64 pos
)
1123 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1127 regmap_write(r
, CDA2D_RBMXWRPTR(sub
->swm
->rb
.map
),
1128 lower_32_bits(pos
));
1129 regmap_write(r
, CDA2D_RBMXWRPTRU(sub
->swm
->rb
.map
),
1130 upper_32_bits(pos
));
1131 regmap_write(r
, CDA2D_WRPTRLOAD
, BIT(sub
->swm
->rb
.map
));
1132 /* Wait for setup */
1133 for (i
= 0; i
< 6; i
++)
1134 regmap_read(r
, CDA2D_RBMXWRPTR(sub
->swm
->rb
.map
), &tmp
);
1137 int aiodma_rb_set_threshold(struct uniphier_aio_sub
*sub
, u64 size
, u32 th
)
1139 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1144 regmap_write(r
, CDA2D_RBMXBTH(sub
->swm
->rb
.map
), th
);
1145 regmap_write(r
, CDA2D_RBMXRTH(sub
->swm
->rb
.map
), th
);
1150 int aiodma_rb_set_buffer(struct uniphier_aio_sub
*sub
, u64 start
, u64 end
,
1153 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1154 u64 size
= end
- start
;
1157 if (end
< start
|| period
< 0)
1160 regmap_write(r
, CDA2D_RBMXCNFG(sub
->swm
->rb
.map
), 0);
1161 regmap_write(r
, CDA2D_RBMXBGNADRS(sub
->swm
->rb
.map
),
1162 lower_32_bits(start
));
1163 regmap_write(r
, CDA2D_RBMXBGNADRSU(sub
->swm
->rb
.map
),
1164 upper_32_bits(start
));
1165 regmap_write(r
, CDA2D_RBMXENDADRS(sub
->swm
->rb
.map
),
1166 lower_32_bits(end
));
1167 regmap_write(r
, CDA2D_RBMXENDADRSU(sub
->swm
->rb
.map
),
1168 upper_32_bits(end
));
1170 regmap_write(r
, CDA2D_RBADRSLOAD
, BIT(sub
->swm
->rb
.map
));
1172 ret
= aiodma_rb_set_threshold(sub
, size
, 2 * period
);
1176 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
1177 aiodma_rb_set_rp(sub
, start
);
1178 aiodma_rb_set_wp(sub
, end
- period
);
1180 regmap_update_bits(r
, CDA2D_RBMXIE(sub
->swm
->rb
.map
),
1182 CDA2D_RBMXIX_SPACE
);
1184 aiodma_rb_set_rp(sub
, end
- period
);
1185 aiodma_rb_set_wp(sub
, start
);
1187 regmap_update_bits(r
, CDA2D_RBMXIE(sub
->swm
->rb
.map
),
1188 CDA2D_RBMXIX_REMAIN
,
1189 CDA2D_RBMXIX_REMAIN
);
1192 sub
->threshold
= 2 * period
;
1203 void aiodma_rb_sync(struct uniphier_aio_sub
*sub
, u64 start
, u64 size
,
1206 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
) {
1207 sub
->rd_offs
= aiodma_rb_get_rp(sub
) - start
;
1209 if (sub
->use_mmap
) {
1210 sub
->threshold
= 2 * period
;
1211 aiodma_rb_set_threshold(sub
, size
, 2 * period
);
1213 sub
->wr_offs
= sub
->rd_offs
- period
;
1214 if (sub
->rd_offs
< period
)
1215 sub
->wr_offs
+= size
;
1217 aiodma_rb_set_wp(sub
, sub
->wr_offs
+ start
);
1219 sub
->wr_offs
= aiodma_rb_get_wp(sub
) - start
;
1221 if (sub
->use_mmap
) {
1222 sub
->threshold
= 2 * period
;
1223 aiodma_rb_set_threshold(sub
, size
, 2 * period
);
1225 sub
->rd_offs
= sub
->wr_offs
- period
;
1226 if (sub
->wr_offs
< period
)
1227 sub
->rd_offs
+= size
;
1229 aiodma_rb_set_rp(sub
, sub
->rd_offs
+ start
);
1232 sub
->rd_total
+= sub
->rd_offs
- sub
->rd_org
;
1233 if (sub
->rd_offs
< sub
->rd_org
)
1234 sub
->rd_total
+= size
;
1235 sub
->wr_total
+= sub
->wr_offs
- sub
->wr_org
;
1236 if (sub
->wr_offs
< sub
->wr_org
)
1237 sub
->wr_total
+= size
;
1239 sub
->rd_org
= sub
->rd_offs
;
1240 sub
->wr_org
= sub
->wr_offs
;
1243 bool aiodma_rb_is_irq(struct uniphier_aio_sub
*sub
)
1245 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1248 regmap_read(r
, CDA2D_RBMXIR(sub
->swm
->rb
.map
), &ir
);
1250 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
)
1251 return !!(ir
& CDA2D_RBMXIX_SPACE
);
1253 return !!(ir
& CDA2D_RBMXIX_REMAIN
);
1256 void aiodma_rb_clear_irq(struct uniphier_aio_sub
*sub
)
1258 struct regmap
*r
= sub
->aio
->chip
->regmap
;
1260 if (sub
->swm
->dir
== PORT_DIR_OUTPUT
)
1261 regmap_write(r
, CDA2D_RBMXIR(sub
->swm
->rb
.map
),
1262 CDA2D_RBMXIX_SPACE
);
1264 regmap_write(r
, CDA2D_RBMXIR(sub
->swm
->rb
.map
),
1265 CDA2D_RBMXIX_REMAIN
);