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 19 static 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 27 static 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 35 static 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 43 static 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 53 u64 aio_rb_cnt(struct uniphier_aio_sub *sub) 54 { 55 return rb_cnt(sub->wr_offs, sub->rd_offs, sub->compr_bytes); 56 } 57 58 u64 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 63 u64 aio_rb_space(struct uniphier_aio_sub *sub) 64 { 65 return rb_space(sub->wr_offs, sub->rd_offs, sub->compr_bytes); 66 } 67 68 u64 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 */ 84 void 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 * @source: 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 */ 105 int 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 */ 165 void 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 */ 200 int 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 */ 250 void 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_rate - set sampling rate of LPCM 269 * @sub: the AIO substream pointer, PCM substream only 270 * @rate: Sampling rate in Hz. 271 * 272 * Set suitable I2S format settings to input/output port block of AIO. 273 * Parameter is specified by hw_params(). 274 * 275 * This function may return error if non-PCM substream. 276 * 277 * Return: Zero if successful, otherwise a negative value on error. 278 */ 279 int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate) 280 { 281 struct regmap *r = sub->aio->chip->regmap; 282 struct device *dev = &sub->aio->chip->pdev->dev; 283 u32 v; 284 285 if (sub->swm->dir == PORT_DIR_OUTPUT) { 286 switch (rate) { 287 case 8000: 288 v = OPORTMXCTR1_FSSEL_8; 289 break; 290 case 11025: 291 v = OPORTMXCTR1_FSSEL_11_025; 292 break; 293 case 12000: 294 v = OPORTMXCTR1_FSSEL_12; 295 break; 296 case 16000: 297 v = OPORTMXCTR1_FSSEL_16; 298 break; 299 case 22050: 300 v = OPORTMXCTR1_FSSEL_22_05; 301 break; 302 case 24000: 303 v = OPORTMXCTR1_FSSEL_24; 304 break; 305 case 32000: 306 v = OPORTMXCTR1_FSSEL_32; 307 break; 308 case 44100: 309 v = OPORTMXCTR1_FSSEL_44_1; 310 break; 311 case 48000: 312 v = OPORTMXCTR1_FSSEL_48; 313 break; 314 case 88200: 315 v = OPORTMXCTR1_FSSEL_88_2; 316 break; 317 case 96000: 318 v = OPORTMXCTR1_FSSEL_96; 319 break; 320 case 176400: 321 v = OPORTMXCTR1_FSSEL_176_4; 322 break; 323 case 192000: 324 v = OPORTMXCTR1_FSSEL_192; 325 break; 326 default: 327 dev_err(dev, "Rate not supported(%d)\n", rate); 328 return -EINVAL; 329 } 330 331 regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map), 332 OPORTMXCTR1_FSSEL_MASK, v); 333 } else { 334 switch (rate) { 335 case 8000: 336 v = IPORTMXCTR1_FSSEL_8; 337 break; 338 case 11025: 339 v = IPORTMXCTR1_FSSEL_11_025; 340 break; 341 case 12000: 342 v = IPORTMXCTR1_FSSEL_12; 343 break; 344 case 16000: 345 v = IPORTMXCTR1_FSSEL_16; 346 break; 347 case 22050: 348 v = IPORTMXCTR1_FSSEL_22_05; 349 break; 350 case 24000: 351 v = IPORTMXCTR1_FSSEL_24; 352 break; 353 case 32000: 354 v = IPORTMXCTR1_FSSEL_32; 355 break; 356 case 44100: 357 v = IPORTMXCTR1_FSSEL_44_1; 358 break; 359 case 48000: 360 v = IPORTMXCTR1_FSSEL_48; 361 break; 362 case 88200: 363 v = IPORTMXCTR1_FSSEL_88_2; 364 break; 365 case 96000: 366 v = IPORTMXCTR1_FSSEL_96; 367 break; 368 case 176400: 369 v = IPORTMXCTR1_FSSEL_176_4; 370 break; 371 case 192000: 372 v = IPORTMXCTR1_FSSEL_192; 373 break; 374 default: 375 dev_err(dev, "Rate not supported(%d)\n", rate); 376 return -EINVAL; 377 } 378 379 regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map), 380 IPORTMXCTR1_FSSEL_MASK, v); 381 } 382 383 return 0; 384 } 385 386 /** 387 * aio_port_set_fmt - set format of I2S data 388 * @sub: the AIO substream pointer, PCM substream only 389 * This parameter has no effect if substream is I2S or PCM. 390 * 391 * Set suitable I2S format settings to input/output port block of AIO. 392 * Parameter is specified by set_fmt(). 393 * 394 * This function may return error if non-PCM substream. 395 * 396 * Return: Zero if successful, otherwise a negative value on error. 397 */ 398 int aio_port_set_fmt(struct uniphier_aio_sub *sub) 399 { 400 struct regmap *r = sub->aio->chip->regmap; 401 struct device *dev = &sub->aio->chip->pdev->dev; 402 u32 v; 403 404 if (sub->swm->dir == PORT_DIR_OUTPUT) { 405 switch (sub->aio->fmt) { 406 case SND_SOC_DAIFMT_LEFT_J: 407 v = OPORTMXCTR1_I2SLRSEL_LEFT; 408 break; 409 case SND_SOC_DAIFMT_RIGHT_J: 410 v = OPORTMXCTR1_I2SLRSEL_RIGHT; 411 break; 412 case SND_SOC_DAIFMT_I2S: 413 v = OPORTMXCTR1_I2SLRSEL_I2S; 414 break; 415 default: 416 dev_err(dev, "Format is not supported(%d)\n", 417 sub->aio->fmt); 418 return -EINVAL; 419 } 420 421 v |= OPORTMXCTR1_OUTBITSEL_24; 422 regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map), 423 OPORTMXCTR1_I2SLRSEL_MASK | 424 OPORTMXCTR1_OUTBITSEL_MASK, v); 425 } else { 426 switch (sub->aio->fmt) { 427 case SND_SOC_DAIFMT_LEFT_J: 428 v = IPORTMXCTR1_LRSEL_LEFT; 429 break; 430 case SND_SOC_DAIFMT_RIGHT_J: 431 v = IPORTMXCTR1_LRSEL_RIGHT; 432 break; 433 case SND_SOC_DAIFMT_I2S: 434 v = IPORTMXCTR1_LRSEL_I2S; 435 break; 436 default: 437 dev_err(dev, "Format is not supported(%d)\n", 438 sub->aio->fmt); 439 return -EINVAL; 440 } 441 442 v |= IPORTMXCTR1_OUTBITSEL_24 | 443 IPORTMXCTR1_CHSEL_ALL; 444 regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map), 445 IPORTMXCTR1_LRSEL_MASK | 446 IPORTMXCTR1_OUTBITSEL_MASK | 447 IPORTMXCTR1_CHSEL_MASK, v); 448 } 449 450 return 0; 451 } 452 453 /** 454 * aio_port_set_clk - set clock and divider of AIO port block 455 * @sub: the AIO substream pointer 456 * 457 * Set suitable PLL clock divider and relational settings to 458 * input/output port block of AIO. Parameters are specified by 459 * set_sysclk() and set_pll(). 460 * 461 * Return: Zero if successful, otherwise a negative value on error. 462 */ 463 int aio_port_set_clk(struct uniphier_aio_sub *sub) 464 { 465 struct uniphier_aio_chip *chip = sub->aio->chip; 466 struct device *dev = &sub->aio->chip->pdev->dev; 467 struct regmap *r = sub->aio->chip->regmap; 468 u32 v_pll[] = { 469 OPORTMXCTR2_ACLKSEL_A1, OPORTMXCTR2_ACLKSEL_F1, 470 OPORTMXCTR2_ACLKSEL_A2, OPORTMXCTR2_ACLKSEL_F2, 471 OPORTMXCTR2_ACLKSEL_A2PLL, 472 OPORTMXCTR2_ACLKSEL_RX1, 473 }; 474 u32 v_div[] = { 475 OPORTMXCTR2_DACCKSEL_1_2, OPORTMXCTR2_DACCKSEL_1_3, 476 OPORTMXCTR2_DACCKSEL_1_1, OPORTMXCTR2_DACCKSEL_2_3, 477 }; 478 u32 v; 479 480 if (sub->swm->dir == PORT_DIR_OUTPUT) { 481 if (sub->swm->type == PORT_TYPE_I2S) { 482 if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) { 483 dev_err(dev, "PLL(%d) is invalid\n", 484 sub->aio->pll_out); 485 return -EINVAL; 486 } 487 if (sub->aio->plldiv >= ARRAY_SIZE(v_div)) { 488 dev_err(dev, "PLL divider(%d) is invalid\n", 489 sub->aio->plldiv); 490 return -EINVAL; 491 } 492 493 v = v_pll[sub->aio->pll_out] | 494 OPORTMXCTR2_MSSEL_MASTER | 495 v_div[sub->aio->plldiv]; 496 497 switch (chip->plls[sub->aio->pll_out].freq) { 498 case 0: 499 case 36864000: 500 case 33868800: 501 v |= OPORTMXCTR2_EXTLSIFSSEL_36; 502 break; 503 default: 504 v |= OPORTMXCTR2_EXTLSIFSSEL_24; 505 break; 506 } 507 } else if (sub->swm->type == PORT_TYPE_EVE) { 508 v = OPORTMXCTR2_ACLKSEL_A2PLL | 509 OPORTMXCTR2_MSSEL_MASTER | 510 OPORTMXCTR2_EXTLSIFSSEL_36 | 511 OPORTMXCTR2_DACCKSEL_1_2; 512 } else if (sub->swm->type == PORT_TYPE_SPDIF) { 513 if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) { 514 dev_err(dev, "PLL(%d) is invalid\n", 515 sub->aio->pll_out); 516 return -EINVAL; 517 } 518 v = v_pll[sub->aio->pll_out] | 519 OPORTMXCTR2_MSSEL_MASTER | 520 OPORTMXCTR2_DACCKSEL_1_2; 521 522 switch (chip->plls[sub->aio->pll_out].freq) { 523 case 0: 524 case 36864000: 525 case 33868800: 526 v |= OPORTMXCTR2_EXTLSIFSSEL_36; 527 break; 528 default: 529 v |= OPORTMXCTR2_EXTLSIFSSEL_24; 530 break; 531 } 532 } else { 533 v = OPORTMXCTR2_ACLKSEL_A1 | 534 OPORTMXCTR2_MSSEL_MASTER | 535 OPORTMXCTR2_EXTLSIFSSEL_36 | 536 OPORTMXCTR2_DACCKSEL_1_2; 537 } 538 regmap_write(r, OPORTMXCTR2(sub->swm->oport.map), v); 539 } else { 540 v = IPORTMXCTR2_ACLKSEL_A1 | 541 IPORTMXCTR2_MSSEL_SLAVE | 542 IPORTMXCTR2_EXTLSIFSSEL_36 | 543 IPORTMXCTR2_DACCKSEL_1_2; 544 regmap_write(r, IPORTMXCTR2(sub->swm->iport.map), v); 545 } 546 547 return 0; 548 } 549 550 /** 551 * aio_port_set_param - set parameters of AIO port block 552 * @sub: the AIO substream pointer 553 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM. 554 * This parameter has no effect if substream is I2S or PCM. 555 * @params: hardware parameters of ALSA 556 * 557 * Set suitable setting to input/output port block of AIO to process the 558 * specified in params. 559 * 560 * Return: Zero if successful, otherwise a negative value on error. 561 */ 562 int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through, 563 const struct snd_pcm_hw_params *params) 564 { 565 struct regmap *r = sub->aio->chip->regmap; 566 unsigned int rate; 567 u32 v; 568 int ret; 569 570 if (!pass_through) { 571 if (sub->swm->type == PORT_TYPE_EVE || 572 sub->swm->type == PORT_TYPE_CONV) { 573 rate = 48000; 574 } else { 575 rate = params_rate(params); 576 } 577 578 ret = aio_port_set_rate(sub, rate); 579 if (ret) 580 return ret; 581 582 ret = aio_port_set_fmt(sub); 583 if (ret) 584 return ret; 585 } 586 587 ret = aio_port_set_clk(sub); 588 if (ret) 589 return ret; 590 591 if (sub->swm->dir == PORT_DIR_OUTPUT) { 592 if (pass_through) 593 v = OPORTMXCTR3_SRCSEL_STREAM | 594 OPORTMXCTR3_VALID_STREAM; 595 else 596 v = OPORTMXCTR3_SRCSEL_PCM | 597 OPORTMXCTR3_VALID_PCM; 598 599 v |= OPORTMXCTR3_IECTHUR_IECOUT | 600 OPORTMXCTR3_PMSEL_PAUSE | 601 OPORTMXCTR3_PMSW_MUTE_OFF; 602 regmap_write(r, OPORTMXCTR3(sub->swm->oport.map), v); 603 } else { 604 regmap_write(r, IPORTMXACLKSEL0EX(sub->swm->iport.map), 605 IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL); 606 regmap_write(r, IPORTMXEXNOE(sub->swm->iport.map), 607 IPORTMXEXNOE_PCMINOE_INPUT); 608 } 609 610 return 0; 611 } 612 613 /** 614 * aio_port_set_enable - start or stop of AIO port block 615 * @sub: the AIO substream pointer 616 * @enable: zero to stop the block, otherwise to start 617 * 618 * Start or stop the signal input/output port block of AIO. 619 */ 620 void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable) 621 { 622 struct regmap *r = sub->aio->chip->regmap; 623 624 if (sub->swm->dir == PORT_DIR_OUTPUT) { 625 regmap_write(r, OPORTMXPATH(sub->swm->oport.map), 626 sub->swm->oif.map); 627 628 regmap_update_bits(r, OPORTMXMASK(sub->swm->oport.map), 629 OPORTMXMASK_IUDXMSK_MASK | 630 OPORTMXMASK_IUXCKMSK_MASK | 631 OPORTMXMASK_DXMSK_MASK | 632 OPORTMXMASK_XCKMSK_MASK, 633 OPORTMXMASK_IUDXMSK_OFF | 634 OPORTMXMASK_IUXCKMSK_OFF | 635 OPORTMXMASK_DXMSK_OFF | 636 OPORTMXMASK_XCKMSK_OFF); 637 638 if (enable) 639 regmap_write(r, AOUTENCTR0, BIT(sub->swm->oport.map)); 640 else 641 regmap_write(r, AOUTENCTR1, BIT(sub->swm->oport.map)); 642 } else { 643 regmap_update_bits(r, IPORTMXMASK(sub->swm->iport.map), 644 IPORTMXMASK_IUXCKMSK_MASK | 645 IPORTMXMASK_XCKMSK_MASK, 646 IPORTMXMASK_IUXCKMSK_OFF | 647 IPORTMXMASK_XCKMSK_OFF); 648 649 if (enable) 650 regmap_update_bits(r, 651 IPORTMXCTR2(sub->swm->iport.map), 652 IPORTMXCTR2_REQEN_MASK, 653 IPORTMXCTR2_REQEN_ENABLE); 654 else 655 regmap_update_bits(r, 656 IPORTMXCTR2(sub->swm->iport.map), 657 IPORTMXCTR2_REQEN_MASK, 658 IPORTMXCTR2_REQEN_DISABLE); 659 } 660 } 661 662 /** 663 * aio_port_get_volume - get volume of AIO port block 664 * @sub: the AIO substream pointer 665 * 666 * Return: current volume, range is 0x0000 - 0xffff 667 */ 668 int aio_port_get_volume(struct uniphier_aio_sub *sub) 669 { 670 struct regmap *r = sub->aio->chip->regmap; 671 u32 v; 672 673 regmap_read(r, OPORTMXTYVOLGAINSTATUS(sub->swm->oport.map, 0), &v); 674 675 return FIELD_GET(OPORTMXTYVOLGAINSTATUS_CUR_MASK, v); 676 } 677 678 /** 679 * aio_port_set_volume - set volume of AIO port block 680 * @sub: the AIO substream pointer 681 * @vol: target volume, range is 0x0000 - 0xffff. 682 * 683 * Change digital volume and perfome fade-out/fade-in effect for specified 684 * output slot of port. Gained PCM value can calculate as the following: 685 * Gained = Original * vol / 0x4000 686 */ 687 void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol) 688 { 689 struct regmap *r = sub->aio->chip->regmap; 690 int oport_map = sub->swm->oport.map; 691 int cur, diff, slope = 0, fs; 692 693 if (sub->swm->dir == PORT_DIR_INPUT) 694 return; 695 696 cur = aio_port_get_volume(sub); 697 diff = abs(vol - cur); 698 fs = params_rate(&sub->params); 699 if (fs) 700 slope = diff / AUD_VOL_FADE_TIME * 1000 / fs; 701 slope = max(1, slope); 702 703 regmap_update_bits(r, OPORTMXTYVOLPARA1(oport_map, 0), 704 OPORTMXTYVOLPARA1_SLOPEU_MASK, slope << 16); 705 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0), 706 OPORTMXTYVOLPARA2_TARGET_MASK, vol); 707 708 if (cur < vol) 709 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0), 710 OPORTMXTYVOLPARA2_FADE_MASK, 711 OPORTMXTYVOLPARA2_FADE_FADEIN); 712 else 713 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0), 714 OPORTMXTYVOLPARA2_FADE_MASK, 715 OPORTMXTYVOLPARA2_FADE_FADEOUT); 716 717 regmap_write(r, AOUTFADECTR0, BIT(oport_map)); 718 } 719 720 /** 721 * aio_if_set_param - set parameters of AIO DMA I/F block 722 * @sub: the AIO substream pointer 723 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM. 724 * This parameter has no effect if substream is I2S or PCM. 725 * 726 * Set suitable setting to DMA interface block of AIO to process the 727 * specified in settings. 728 * 729 * Return: Zero if successful, otherwise a negative value on error. 730 */ 731 int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through) 732 { 733 struct regmap *r = sub->aio->chip->regmap; 734 u32 v; 735 736 if (sub->swm->dir == PORT_DIR_OUTPUT) { 737 if (pass_through) 738 v = PBOUTMXCTR0_ENDIAN_0123 | 739 PBOUTMXCTR0_MEMFMT_STREAM; 740 else 741 v = PBOUTMXCTR0_ENDIAN_3210 | 742 PBOUTMXCTR0_MEMFMT_2CH; 743 744 regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v); 745 regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0); 746 } else { 747 regmap_write(r, PBINMXCTR(sub->swm->iif.map), 748 PBINMXCTR_NCONNECT_CONNECT | 749 PBINMXCTR_INOUTSEL_IN | 750 (sub->swm->iport.map << PBINMXCTR_PBINSEL_SHIFT) | 751 PBINMXCTR_ENDIAN_3210 | 752 PBINMXCTR_MEMFMT_D0); 753 } 754 755 return 0; 756 } 757 758 /** 759 * aio_oport_set_stream_type - set parameters of AIO playback port block 760 * @sub: the AIO substream pointer 761 * @pc: Pc type of IEC61937 762 * 763 * Set special setting to output port block of AIO to output the stream 764 * via S/PDIF. 765 * 766 * Return: Zero if successful, otherwise a negative value on error. 767 */ 768 int aio_oport_set_stream_type(struct uniphier_aio_sub *sub, 769 enum IEC61937_PC pc) 770 { 771 struct regmap *r = sub->aio->chip->regmap; 772 u32 repet = 0, pause = OPORTMXPAUDAT_PAUSEPC_CMN; 773 774 switch (pc) { 775 case IEC61937_PC_AC3: 776 repet = OPORTMXREPET_STRLENGTH_AC3 | 777 OPORTMXREPET_PMLENGTH_AC3; 778 pause |= OPORTMXPAUDAT_PAUSEPD_AC3; 779 break; 780 case IEC61937_PC_MPA: 781 repet = OPORTMXREPET_STRLENGTH_MPA | 782 OPORTMXREPET_PMLENGTH_MPA; 783 pause |= OPORTMXPAUDAT_PAUSEPD_MPA; 784 break; 785 case IEC61937_PC_MP3: 786 repet = OPORTMXREPET_STRLENGTH_MP3 | 787 OPORTMXREPET_PMLENGTH_MP3; 788 pause |= OPORTMXPAUDAT_PAUSEPD_MP3; 789 break; 790 case IEC61937_PC_DTS1: 791 repet = OPORTMXREPET_STRLENGTH_DTS1 | 792 OPORTMXREPET_PMLENGTH_DTS1; 793 pause |= OPORTMXPAUDAT_PAUSEPD_DTS1; 794 break; 795 case IEC61937_PC_DTS2: 796 repet = OPORTMXREPET_STRLENGTH_DTS2 | 797 OPORTMXREPET_PMLENGTH_DTS2; 798 pause |= OPORTMXPAUDAT_PAUSEPD_DTS2; 799 break; 800 case IEC61937_PC_DTS3: 801 repet = OPORTMXREPET_STRLENGTH_DTS3 | 802 OPORTMXREPET_PMLENGTH_DTS3; 803 pause |= OPORTMXPAUDAT_PAUSEPD_DTS3; 804 break; 805 case IEC61937_PC_AAC: 806 repet = OPORTMXREPET_STRLENGTH_AAC | 807 OPORTMXREPET_PMLENGTH_AAC; 808 pause |= OPORTMXPAUDAT_PAUSEPD_AAC; 809 break; 810 case IEC61937_PC_PAUSE: 811 /* Do nothing */ 812 break; 813 } 814 815 regmap_write(r, OPORTMXREPET(sub->swm->oport.map), repet); 816 regmap_write(r, OPORTMXPAUDAT(sub->swm->oport.map), pause); 817 818 return 0; 819 } 820 821 /** 822 * aio_src_reset - reset AIO SRC block 823 * @sub: the AIO substream pointer 824 * 825 * Resets the digital signal input/output port with sampling rate converter 826 * block of AIO. 827 * This function has no effect if substream is not supported rate converter. 828 */ 829 void aio_src_reset(struct uniphier_aio_sub *sub) 830 { 831 struct regmap *r = sub->aio->chip->regmap; 832 833 if (sub->swm->dir != PORT_DIR_OUTPUT) 834 return; 835 836 regmap_write(r, AOUTSRCRSTCTR0, BIT(sub->swm->oport.map)); 837 regmap_write(r, AOUTSRCRSTCTR1, BIT(sub->swm->oport.map)); 838 } 839 840 /** 841 * aio_src_set_param - set parameters of AIO SRC block 842 * @sub: the AIO substream pointer 843 * @params: hardware parameters of ALSA 844 * 845 * Set suitable setting to input/output port with sampling rate converter 846 * block of AIO to process the specified in params. 847 * This function has no effect if substream is not supported rate converter. 848 * 849 * Return: Zero if successful, otherwise a negative value on error. 850 */ 851 int aio_src_set_param(struct uniphier_aio_sub *sub, 852 const struct snd_pcm_hw_params *params) 853 { 854 struct regmap *r = sub->aio->chip->regmap; 855 u32 v; 856 857 if (sub->swm->dir != PORT_DIR_OUTPUT) 858 return 0; 859 860 regmap_write(r, OPORTMXSRC1CTR(sub->swm->oport.map), 861 OPORTMXSRC1CTR_THMODE_SRC | 862 OPORTMXSRC1CTR_SRCPATH_CALC | 863 OPORTMXSRC1CTR_SYNC_ASYNC | 864 OPORTMXSRC1CTR_FSIIPSEL_INNER | 865 OPORTMXSRC1CTR_FSISEL_ACLK); 866 867 switch (params_rate(params)) { 868 default: 869 case 48000: 870 v = OPORTMXRATE_I_ACLKSEL_APLLA1 | 871 OPORTMXRATE_I_MCKSEL_36 | 872 OPORTMXRATE_I_FSSEL_48; 873 break; 874 case 44100: 875 v = OPORTMXRATE_I_ACLKSEL_APLLA2 | 876 OPORTMXRATE_I_MCKSEL_33 | 877 OPORTMXRATE_I_FSSEL_44_1; 878 break; 879 case 32000: 880 v = OPORTMXRATE_I_ACLKSEL_APLLA1 | 881 OPORTMXRATE_I_MCKSEL_36 | 882 OPORTMXRATE_I_FSSEL_32; 883 break; 884 } 885 886 regmap_write(r, OPORTMXRATE_I(sub->swm->oport.map), 887 v | OPORTMXRATE_I_ACLKSRC_APLL | 888 OPORTMXRATE_I_LRCKSTP_STOP); 889 regmap_update_bits(r, OPORTMXRATE_I(sub->swm->oport.map), 890 OPORTMXRATE_I_LRCKSTP_MASK, 891 OPORTMXRATE_I_LRCKSTP_START); 892 893 return 0; 894 } 895 896 int aio_srcif_set_param(struct uniphier_aio_sub *sub) 897 { 898 struct regmap *r = sub->aio->chip->regmap; 899 900 regmap_write(r, PBINMXCTR(sub->swm->iif.map), 901 PBINMXCTR_NCONNECT_CONNECT | 902 PBINMXCTR_INOUTSEL_OUT | 903 (sub->swm->oport.map << PBINMXCTR_PBINSEL_SHIFT) | 904 PBINMXCTR_ENDIAN_3210 | 905 PBINMXCTR_MEMFMT_D0); 906 907 return 0; 908 } 909 910 int aio_srcch_set_param(struct uniphier_aio_sub *sub) 911 { 912 struct regmap *r = sub->aio->chip->regmap; 913 914 regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->och.map), 915 CDA2D_CHMXCTRL1_INDSIZE_INFINITE); 916 917 regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->och.map), 918 CDA2D_CHMXAMODE_ENDIAN_3210 | 919 CDA2D_CHMXAMODE_AUPDT_FIX | 920 CDA2D_CHMXAMODE_TYPE_NORMAL); 921 922 regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->och.map), 923 CDA2D_CHMXAMODE_ENDIAN_3210 | 924 CDA2D_CHMXAMODE_AUPDT_INC | 925 CDA2D_CHMXAMODE_TYPE_RING | 926 (sub->swm->och.map << CDA2D_CHMXAMODE_RSSEL_SHIFT)); 927 928 return 0; 929 } 930 931 void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable) 932 { 933 struct regmap *r = sub->aio->chip->regmap; 934 u32 v; 935 936 if (enable) 937 v = CDA2D_STRT0_STOP_START; 938 else 939 v = CDA2D_STRT0_STOP_STOP; 940 941 regmap_write(r, CDA2D_STRT0, 942 v | BIT(sub->swm->och.map)); 943 } 944 945 int aiodma_ch_set_param(struct uniphier_aio_sub *sub) 946 { 947 struct regmap *r = sub->aio->chip->regmap; 948 u32 v; 949 950 regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->ch.map), 951 CDA2D_CHMXCTRL1_INDSIZE_INFINITE); 952 953 v = CDA2D_CHMXAMODE_ENDIAN_3210 | 954 CDA2D_CHMXAMODE_AUPDT_INC | 955 CDA2D_CHMXAMODE_TYPE_NORMAL | 956 (sub->swm->rb.map << CDA2D_CHMXAMODE_RSSEL_SHIFT); 957 if (sub->swm->dir == PORT_DIR_OUTPUT) 958 regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->ch.map), v); 959 else 960 regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->ch.map), v); 961 962 return 0; 963 } 964 965 void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable) 966 { 967 struct regmap *r = sub->aio->chip->regmap; 968 969 if (enable) { 970 regmap_write(r, CDA2D_STRT0, 971 CDA2D_STRT0_STOP_START | BIT(sub->swm->ch.map)); 972 973 regmap_update_bits(r, INTRBIM(0), 974 BIT(sub->swm->rb.map), 975 BIT(sub->swm->rb.map)); 976 } else { 977 regmap_write(r, CDA2D_STRT0, 978 CDA2D_STRT0_STOP_STOP | BIT(sub->swm->ch.map)); 979 980 regmap_update_bits(r, INTRBIM(0), 981 BIT(sub->swm->rb.map), 982 0); 983 } 984 } 985 986 static u64 aiodma_rb_get_rp(struct uniphier_aio_sub *sub) 987 { 988 struct regmap *r = sub->aio->chip->regmap; 989 u32 pos_u, pos_l; 990 int i; 991 992 regmap_write(r, CDA2D_RDPTRLOAD, 993 CDA2D_RDPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map)); 994 /* Wait for setup */ 995 for (i = 0; i < 6; i++) 996 regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l); 997 998 regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l); 999 regmap_read(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), &pos_u); 1000 pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u); 1001 1002 return ((u64)pos_u << 32) | pos_l; 1003 } 1004 1005 static void aiodma_rb_set_rp(struct uniphier_aio_sub *sub, u64 pos) 1006 { 1007 struct regmap *r = sub->aio->chip->regmap; 1008 u32 tmp; 1009 int i; 1010 1011 regmap_write(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), (u32)pos); 1012 regmap_write(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), (u32)(pos >> 32)); 1013 regmap_write(r, CDA2D_RDPTRLOAD, BIT(sub->swm->rb.map)); 1014 /* Wait for setup */ 1015 for (i = 0; i < 6; i++) 1016 regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &tmp); 1017 } 1018 1019 static u64 aiodma_rb_get_wp(struct uniphier_aio_sub *sub) 1020 { 1021 struct regmap *r = sub->aio->chip->regmap; 1022 u32 pos_u, pos_l; 1023 int i; 1024 1025 regmap_write(r, CDA2D_WRPTRLOAD, 1026 CDA2D_WRPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map)); 1027 /* Wait for setup */ 1028 for (i = 0; i < 6; i++) 1029 regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l); 1030 1031 regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l); 1032 regmap_read(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map), &pos_u); 1033 pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u); 1034 1035 return ((u64)pos_u << 32) | pos_l; 1036 } 1037 1038 static void aiodma_rb_set_wp(struct uniphier_aio_sub *sub, u64 pos) 1039 { 1040 struct regmap *r = sub->aio->chip->regmap; 1041 u32 tmp; 1042 int i; 1043 1044 regmap_write(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), 1045 lower_32_bits(pos)); 1046 regmap_write(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map), 1047 upper_32_bits(pos)); 1048 regmap_write(r, CDA2D_WRPTRLOAD, BIT(sub->swm->rb.map)); 1049 /* Wait for setup */ 1050 for (i = 0; i < 6; i++) 1051 regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &tmp); 1052 } 1053 1054 int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th) 1055 { 1056 struct regmap *r = sub->aio->chip->regmap; 1057 1058 if (size <= th) 1059 return -EINVAL; 1060 1061 regmap_write(r, CDA2D_RBMXBTH(sub->swm->rb.map), th); 1062 regmap_write(r, CDA2D_RBMXRTH(sub->swm->rb.map), th); 1063 1064 return 0; 1065 } 1066 1067 int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end, 1068 int period) 1069 { 1070 struct regmap *r = sub->aio->chip->regmap; 1071 u64 size = end - start; 1072 int ret; 1073 1074 if (end < start || period < 0) 1075 return -EINVAL; 1076 1077 regmap_write(r, CDA2D_RBMXCNFG(sub->swm->rb.map), 0); 1078 regmap_write(r, CDA2D_RBMXBGNADRS(sub->swm->rb.map), 1079 lower_32_bits(start)); 1080 regmap_write(r, CDA2D_RBMXBGNADRSU(sub->swm->rb.map), 1081 upper_32_bits(start)); 1082 regmap_write(r, CDA2D_RBMXENDADRS(sub->swm->rb.map), 1083 lower_32_bits(end)); 1084 regmap_write(r, CDA2D_RBMXENDADRSU(sub->swm->rb.map), 1085 upper_32_bits(end)); 1086 1087 regmap_write(r, CDA2D_RBADRSLOAD, BIT(sub->swm->rb.map)); 1088 1089 ret = aiodma_rb_set_threshold(sub, size, 2 * period); 1090 if (ret) 1091 return ret; 1092 1093 if (sub->swm->dir == PORT_DIR_OUTPUT) { 1094 aiodma_rb_set_rp(sub, start); 1095 aiodma_rb_set_wp(sub, end - period); 1096 1097 regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map), 1098 CDA2D_RBMXIX_SPACE, 1099 CDA2D_RBMXIX_SPACE); 1100 } else { 1101 aiodma_rb_set_rp(sub, end - period); 1102 aiodma_rb_set_wp(sub, start); 1103 1104 regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map), 1105 CDA2D_RBMXIX_REMAIN, 1106 CDA2D_RBMXIX_REMAIN); 1107 } 1108 1109 sub->threshold = 2 * period; 1110 sub->rd_offs = 0; 1111 sub->wr_offs = 0; 1112 sub->rd_org = 0; 1113 sub->wr_org = 0; 1114 sub->rd_total = 0; 1115 sub->wr_total = 0; 1116 1117 return 0; 1118 } 1119 1120 void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size, 1121 int period) 1122 { 1123 if (sub->swm->dir == PORT_DIR_OUTPUT) { 1124 sub->rd_offs = aiodma_rb_get_rp(sub) - start; 1125 1126 if (sub->use_mmap) { 1127 sub->threshold = 2 * period; 1128 aiodma_rb_set_threshold(sub, size, 2 * period); 1129 1130 sub->wr_offs = sub->rd_offs - period; 1131 if (sub->rd_offs < period) 1132 sub->wr_offs += size; 1133 } 1134 aiodma_rb_set_wp(sub, sub->wr_offs + start); 1135 } else { 1136 sub->wr_offs = aiodma_rb_get_wp(sub) - start; 1137 1138 if (sub->use_mmap) { 1139 sub->threshold = 2 * period; 1140 aiodma_rb_set_threshold(sub, size, 2 * period); 1141 1142 sub->rd_offs = sub->wr_offs - period; 1143 if (sub->wr_offs < period) 1144 sub->rd_offs += size; 1145 } 1146 aiodma_rb_set_rp(sub, sub->rd_offs + start); 1147 } 1148 1149 sub->rd_total += sub->rd_offs - sub->rd_org; 1150 if (sub->rd_offs < sub->rd_org) 1151 sub->rd_total += size; 1152 sub->wr_total += sub->wr_offs - sub->wr_org; 1153 if (sub->wr_offs < sub->wr_org) 1154 sub->wr_total += size; 1155 1156 sub->rd_org = sub->rd_offs; 1157 sub->wr_org = sub->wr_offs; 1158 } 1159 1160 bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub) 1161 { 1162 struct regmap *r = sub->aio->chip->regmap; 1163 u32 ir; 1164 1165 regmap_read(r, CDA2D_RBMXIR(sub->swm->rb.map), &ir); 1166 1167 if (sub->swm->dir == PORT_DIR_OUTPUT) 1168 return !!(ir & CDA2D_RBMXIX_SPACE); 1169 else 1170 return !!(ir & CDA2D_RBMXIX_REMAIN); 1171 } 1172 1173 void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub) 1174 { 1175 struct regmap *r = sub->aio->chip->regmap; 1176 1177 if (sub->swm->dir == PORT_DIR_OUTPUT) 1178 regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map), 1179 CDA2D_RBMXIX_SPACE); 1180 else 1181 regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map), 1182 CDA2D_RBMXIX_REMAIN); 1183 } 1184