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