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 * @pll_id: PLL 98 * @freq: frequency in Hz, 0 is ignored 99 * 100 * Sets frequency of audio PLL. This function can be called anytime, 101 * but it takes time till PLL is locked. 102 * 103 * Return: Zero if successful, otherwise a negative value on error. 104 */ 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_ch - set channels of LPCM 269 * @sub: the AIO substream pointer, PCM substream only 270 * 271 * Set suitable slot selecting to input/output port block of AIO. 272 * 273 * This function may return error if non-PCM substream. 274 * 275 * Return: Zero if successful, otherwise a negative value on error. 276 */ 277 static int aio_port_set_ch(struct uniphier_aio_sub *sub) 278 { 279 struct regmap *r = sub->aio->chip->regmap; 280 static const u32 slotsel_2ch[] = { 281 0, 0, 0, 0, 0, 282 }; 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, 289 }; 290 u32 mode; 291 const u32 *slotsel; 292 int i; 293 294 switch (params_channels(&sub->params)) { 295 case 8: 296 case 6: 297 mode = OPORTMXTYSLOTCTR_MODE; 298 slotsel = slotsel_multi; 299 break; 300 case 2: 301 mode = 0; 302 slotsel = slotsel_2ch; 303 break; 304 default: 305 return -EINVAL; 306 } 307 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]); 313 } 314 315 return 0; 316 } 317 318 /** 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. 322 * 323 * Set suitable I2S format settings to input/output port block of AIO. 324 * Parameter is specified by hw_params(). 325 * 326 * This function may return error if non-PCM substream. 327 * 328 * Return: Zero if successful, otherwise a negative value on error. 329 */ 330 static int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate) 331 { 332 struct regmap *r = sub->aio->chip->regmap; 333 struct device *dev = &sub->aio->chip->pdev->dev; 334 u32 v; 335 336 if (sub->swm->dir == PORT_DIR_OUTPUT) { 337 switch (rate) { 338 case 8000: 339 v = OPORTMXCTR1_FSSEL_8; 340 break; 341 case 11025: 342 v = OPORTMXCTR1_FSSEL_11_025; 343 break; 344 case 12000: 345 v = OPORTMXCTR1_FSSEL_12; 346 break; 347 case 16000: 348 v = OPORTMXCTR1_FSSEL_16; 349 break; 350 case 22050: 351 v = OPORTMXCTR1_FSSEL_22_05; 352 break; 353 case 24000: 354 v = OPORTMXCTR1_FSSEL_24; 355 break; 356 case 32000: 357 v = OPORTMXCTR1_FSSEL_32; 358 break; 359 case 44100: 360 v = OPORTMXCTR1_FSSEL_44_1; 361 break; 362 case 48000: 363 v = OPORTMXCTR1_FSSEL_48; 364 break; 365 case 88200: 366 v = OPORTMXCTR1_FSSEL_88_2; 367 break; 368 case 96000: 369 v = OPORTMXCTR1_FSSEL_96; 370 break; 371 case 176400: 372 v = OPORTMXCTR1_FSSEL_176_4; 373 break; 374 case 192000: 375 v = OPORTMXCTR1_FSSEL_192; 376 break; 377 default: 378 dev_err(dev, "Rate not supported(%d)\n", rate); 379 return -EINVAL; 380 } 381 382 regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map), 383 OPORTMXCTR1_FSSEL_MASK, v); 384 } else { 385 switch (rate) { 386 case 8000: 387 v = IPORTMXCTR1_FSSEL_8; 388 break; 389 case 11025: 390 v = IPORTMXCTR1_FSSEL_11_025; 391 break; 392 case 12000: 393 v = IPORTMXCTR1_FSSEL_12; 394 break; 395 case 16000: 396 v = IPORTMXCTR1_FSSEL_16; 397 break; 398 case 22050: 399 v = IPORTMXCTR1_FSSEL_22_05; 400 break; 401 case 24000: 402 v = IPORTMXCTR1_FSSEL_24; 403 break; 404 case 32000: 405 v = IPORTMXCTR1_FSSEL_32; 406 break; 407 case 44100: 408 v = IPORTMXCTR1_FSSEL_44_1; 409 break; 410 case 48000: 411 v = IPORTMXCTR1_FSSEL_48; 412 break; 413 case 88200: 414 v = IPORTMXCTR1_FSSEL_88_2; 415 break; 416 case 96000: 417 v = IPORTMXCTR1_FSSEL_96; 418 break; 419 case 176400: 420 v = IPORTMXCTR1_FSSEL_176_4; 421 break; 422 case 192000: 423 v = IPORTMXCTR1_FSSEL_192; 424 break; 425 default: 426 dev_err(dev, "Rate not supported(%d)\n", rate); 427 return -EINVAL; 428 } 429 430 regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map), 431 IPORTMXCTR1_FSSEL_MASK, v); 432 } 433 434 return 0; 435 } 436 437 /** 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. 441 * 442 * Set suitable I2S format settings to input/output port block of AIO. 443 * Parameter is specified by set_fmt(). 444 * 445 * This function may return error if non-PCM substream. 446 * 447 * Return: Zero if successful, otherwise a negative value on error. 448 */ 449 static int aio_port_set_fmt(struct uniphier_aio_sub *sub) 450 { 451 struct regmap *r = sub->aio->chip->regmap; 452 struct device *dev = &sub->aio->chip->pdev->dev; 453 u32 v; 454 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; 459 break; 460 case SND_SOC_DAIFMT_RIGHT_J: 461 v = OPORTMXCTR1_I2SLRSEL_RIGHT; 462 break; 463 case SND_SOC_DAIFMT_I2S: 464 v = OPORTMXCTR1_I2SLRSEL_I2S; 465 break; 466 default: 467 dev_err(dev, "Format is not supported(%d)\n", 468 sub->aio->fmt); 469 return -EINVAL; 470 } 471 472 v |= OPORTMXCTR1_OUTBITSEL_24; 473 regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map), 474 OPORTMXCTR1_I2SLRSEL_MASK | 475 OPORTMXCTR1_OUTBITSEL_MASK, v); 476 } else { 477 switch (sub->aio->fmt) { 478 case SND_SOC_DAIFMT_LEFT_J: 479 v = IPORTMXCTR1_LRSEL_LEFT; 480 break; 481 case SND_SOC_DAIFMT_RIGHT_J: 482 v = IPORTMXCTR1_LRSEL_RIGHT; 483 break; 484 case SND_SOC_DAIFMT_I2S: 485 v = IPORTMXCTR1_LRSEL_I2S; 486 break; 487 default: 488 dev_err(dev, "Format is not supported(%d)\n", 489 sub->aio->fmt); 490 return -EINVAL; 491 } 492 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); 499 } 500 501 return 0; 502 } 503 504 /** 505 * aio_port_set_clk - set clock and divider of AIO port block 506 * @sub: the AIO substream pointer 507 * 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(). 511 * 512 * Return: Zero if successful, otherwise a negative value on error. 513 */ 514 static int aio_port_set_clk(struct uniphier_aio_sub *sub) 515 { 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, 524 }; 525 static const u32 v_div[] = { 526 OPORTMXCTR2_DACCKSEL_1_2, OPORTMXCTR2_DACCKSEL_1_3, 527 OPORTMXCTR2_DACCKSEL_1_1, OPORTMXCTR2_DACCKSEL_2_3, 528 }; 529 u32 v; 530 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", 535 sub->aio->pll_out); 536 return -EINVAL; 537 } 538 if (sub->aio->plldiv >= ARRAY_SIZE(v_div)) { 539 dev_err(dev, "PLL divider(%d) is invalid\n", 540 sub->aio->plldiv); 541 return -EINVAL; 542 } 543 544 v = v_pll[sub->aio->pll_out] | 545 OPORTMXCTR2_MSSEL_MASTER | 546 v_div[sub->aio->plldiv]; 547 548 switch (chip->plls[sub->aio->pll_out].freq) { 549 case 0: 550 case 36864000: 551 case 33868800: 552 v |= OPORTMXCTR2_EXTLSIFSSEL_36; 553 break; 554 default: 555 v |= OPORTMXCTR2_EXTLSIFSSEL_24; 556 break; 557 } 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", 566 sub->aio->pll_out); 567 return -EINVAL; 568 } 569 v = v_pll[sub->aio->pll_out] | 570 OPORTMXCTR2_MSSEL_MASTER | 571 OPORTMXCTR2_DACCKSEL_1_2; 572 573 switch (chip->plls[sub->aio->pll_out].freq) { 574 case 0: 575 case 36864000: 576 case 33868800: 577 v |= OPORTMXCTR2_EXTLSIFSSEL_36; 578 break; 579 default: 580 v |= OPORTMXCTR2_EXTLSIFSSEL_24; 581 break; 582 } 583 } else { 584 v = OPORTMXCTR2_ACLKSEL_A1 | 585 OPORTMXCTR2_MSSEL_MASTER | 586 OPORTMXCTR2_EXTLSIFSSEL_36 | 587 OPORTMXCTR2_DACCKSEL_1_2; 588 } 589 regmap_write(r, OPORTMXCTR2(sub->swm->oport.map), v); 590 } else { 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); 596 } 597 598 return 0; 599 } 600 601 /** 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 607 * 608 * Set suitable setting to input/output port block of AIO to process the 609 * specified in params. 610 * 611 * Return: Zero if successful, otherwise a negative value on error. 612 */ 613 int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through, 614 const struct snd_pcm_hw_params *params) 615 { 616 struct regmap *r = sub->aio->chip->regmap; 617 unsigned int rate; 618 u32 v; 619 int ret; 620 621 if (!pass_through) { 622 if (sub->swm->type == PORT_TYPE_EVE || 623 sub->swm->type == PORT_TYPE_CONV) { 624 rate = 48000; 625 } else { 626 rate = params_rate(params); 627 } 628 629 ret = aio_port_set_ch(sub); 630 if (ret) 631 return ret; 632 633 ret = aio_port_set_rate(sub, rate); 634 if (ret) 635 return ret; 636 637 ret = aio_port_set_fmt(sub); 638 if (ret) 639 return ret; 640 } 641 642 ret = aio_port_set_clk(sub); 643 if (ret) 644 return ret; 645 646 if (sub->swm->dir == PORT_DIR_OUTPUT) { 647 if (pass_through) 648 v = OPORTMXCTR3_SRCSEL_STREAM | 649 OPORTMXCTR3_VALID_STREAM; 650 else 651 v = OPORTMXCTR3_SRCSEL_PCM | 652 OPORTMXCTR3_VALID_PCM; 653 654 v |= OPORTMXCTR3_IECTHUR_IECOUT | 655 OPORTMXCTR3_PMSEL_PAUSE | 656 OPORTMXCTR3_PMSW_MUTE_OFF; 657 regmap_write(r, OPORTMXCTR3(sub->swm->oport.map), v); 658 } else { 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); 663 } 664 665 return 0; 666 } 667 668 /** 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 672 * 673 * Start or stop the signal input/output port block of AIO. 674 */ 675 void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable) 676 { 677 struct regmap *r = sub->aio->chip->regmap; 678 679 if (sub->swm->dir == PORT_DIR_OUTPUT) { 680 regmap_write(r, OPORTMXPATH(sub->swm->oport.map), 681 sub->swm->oif.map); 682 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); 692 693 if (enable) 694 regmap_write(r, AOUTENCTR0, BIT(sub->swm->oport.map)); 695 else 696 regmap_write(r, AOUTENCTR1, BIT(sub->swm->oport.map)); 697 } else { 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); 703 704 if (enable) 705 regmap_update_bits(r, 706 IPORTMXCTR2(sub->swm->iport.map), 707 IPORTMXCTR2_REQEN_MASK, 708 IPORTMXCTR2_REQEN_ENABLE); 709 else 710 regmap_update_bits(r, 711 IPORTMXCTR2(sub->swm->iport.map), 712 IPORTMXCTR2_REQEN_MASK, 713 IPORTMXCTR2_REQEN_DISABLE); 714 } 715 } 716 717 /** 718 * aio_port_get_volume - get volume of AIO port block 719 * @sub: the AIO substream pointer 720 * 721 * Return: current volume, range is 0x0000 - 0xffff 722 */ 723 int aio_port_get_volume(struct uniphier_aio_sub *sub) 724 { 725 struct regmap *r = sub->aio->chip->regmap; 726 u32 v; 727 728 regmap_read(r, OPORTMXTYVOLGAINSTATUS(sub->swm->oport.map, 0), &v); 729 730 return FIELD_GET(OPORTMXTYVOLGAINSTATUS_CUR_MASK, v); 731 } 732 733 /** 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. 737 * 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 741 */ 742 void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol) 743 { 744 struct regmap *r = sub->aio->chip->regmap; 745 int oport_map = sub->swm->oport.map; 746 int cur, diff, slope = 0, fs; 747 748 if (sub->swm->dir == PORT_DIR_INPUT) 749 return; 750 751 cur = aio_port_get_volume(sub); 752 diff = abs(vol - cur); 753 fs = params_rate(&sub->params); 754 if (fs) 755 slope = diff / AUD_VOL_FADE_TIME * 1000 / fs; 756 slope = max(1, slope); 757 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); 762 763 if (cur < vol) 764 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0), 765 OPORTMXTYVOLPARA2_FADE_MASK, 766 OPORTMXTYVOLPARA2_FADE_FADEIN); 767 else 768 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0), 769 OPORTMXTYVOLPARA2_FADE_MASK, 770 OPORTMXTYVOLPARA2_FADE_FADEOUT); 771 772 regmap_write(r, AOUTFADECTR0, BIT(oport_map)); 773 } 774 775 /** 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. 780 * 781 * Set suitable setting to DMA interface block of AIO to process the 782 * specified in settings. 783 * 784 * Return: Zero if successful, otherwise a negative value on error. 785 */ 786 int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through) 787 { 788 struct regmap *r = sub->aio->chip->regmap; 789 u32 memfmt, v; 790 791 if (sub->swm->dir == PORT_DIR_OUTPUT) { 792 if (pass_through) { 793 v = PBOUTMXCTR0_ENDIAN_0123 | 794 PBOUTMXCTR0_MEMFMT_STREAM; 795 } else { 796 switch (params_channels(&sub->params)) { 797 case 2: 798 memfmt = PBOUTMXCTR0_MEMFMT_2CH; 799 break; 800 case 6: 801 memfmt = PBOUTMXCTR0_MEMFMT_6CH; 802 break; 803 case 8: 804 memfmt = PBOUTMXCTR0_MEMFMT_8CH; 805 break; 806 default: 807 return -EINVAL; 808 } 809 v = PBOUTMXCTR0_ENDIAN_3210 | memfmt; 810 } 811 812 regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v); 813 regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0); 814 } else { 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); 821 } 822 823 return 0; 824 } 825 826 /** 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 830 * 831 * Set special setting to output port block of AIO to output the stream 832 * via S/PDIF. 833 * 834 * Return: Zero if successful, otherwise a negative value on error. 835 */ 836 int aio_oport_set_stream_type(struct uniphier_aio_sub *sub, 837 enum IEC61937_PC pc) 838 { 839 struct regmap *r = sub->aio->chip->regmap; 840 u32 repet = 0, pause = OPORTMXPAUDAT_PAUSEPC_CMN; 841 int ret; 842 843 switch (pc) { 844 case IEC61937_PC_AC3: 845 repet = OPORTMXREPET_STRLENGTH_AC3 | 846 OPORTMXREPET_PMLENGTH_AC3; 847 pause |= OPORTMXPAUDAT_PAUSEPD_AC3; 848 break; 849 case IEC61937_PC_MPA: 850 repet = OPORTMXREPET_STRLENGTH_MPA | 851 OPORTMXREPET_PMLENGTH_MPA; 852 pause |= OPORTMXPAUDAT_PAUSEPD_MPA; 853 break; 854 case IEC61937_PC_MP3: 855 repet = OPORTMXREPET_STRLENGTH_MP3 | 856 OPORTMXREPET_PMLENGTH_MP3; 857 pause |= OPORTMXPAUDAT_PAUSEPD_MP3; 858 break; 859 case IEC61937_PC_DTS1: 860 repet = OPORTMXREPET_STRLENGTH_DTS1 | 861 OPORTMXREPET_PMLENGTH_DTS1; 862 pause |= OPORTMXPAUDAT_PAUSEPD_DTS1; 863 break; 864 case IEC61937_PC_DTS2: 865 repet = OPORTMXREPET_STRLENGTH_DTS2 | 866 OPORTMXREPET_PMLENGTH_DTS2; 867 pause |= OPORTMXPAUDAT_PAUSEPD_DTS2; 868 break; 869 case IEC61937_PC_DTS3: 870 repet = OPORTMXREPET_STRLENGTH_DTS3 | 871 OPORTMXREPET_PMLENGTH_DTS3; 872 pause |= OPORTMXPAUDAT_PAUSEPD_DTS3; 873 break; 874 case IEC61937_PC_AAC: 875 repet = OPORTMXREPET_STRLENGTH_AAC | 876 OPORTMXREPET_PMLENGTH_AAC; 877 pause |= OPORTMXPAUDAT_PAUSEPD_AAC; 878 break; 879 case IEC61937_PC_PAUSE: 880 /* Do nothing */ 881 break; 882 } 883 884 ret = regmap_write(r, OPORTMXREPET(sub->swm->oport.map), repet); 885 if (ret) 886 return ret; 887 888 ret = regmap_write(r, OPORTMXPAUDAT(sub->swm->oport.map), pause); 889 if (ret) 890 return ret; 891 892 return 0; 893 } 894 895 /** 896 * aio_src_reset - reset AIO SRC block 897 * @sub: the AIO substream pointer 898 * 899 * Resets the digital signal input/output port with sampling rate converter 900 * block of AIO. 901 * This function has no effect if substream is not supported rate converter. 902 */ 903 void aio_src_reset(struct uniphier_aio_sub *sub) 904 { 905 struct regmap *r = sub->aio->chip->regmap; 906 907 if (sub->swm->dir != PORT_DIR_OUTPUT) 908 return; 909 910 regmap_write(r, AOUTSRCRSTCTR0, BIT(sub->swm->oport.map)); 911 regmap_write(r, AOUTSRCRSTCTR1, BIT(sub->swm->oport.map)); 912 } 913 914 /** 915 * aio_src_set_param - set parameters of AIO SRC block 916 * @sub: the AIO substream pointer 917 * @params: hardware parameters of ALSA 918 * 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. 922 * 923 * Return: Zero if successful, otherwise a negative value on error. 924 */ 925 int aio_src_set_param(struct uniphier_aio_sub *sub, 926 const struct snd_pcm_hw_params *params) 927 { 928 struct regmap *r = sub->aio->chip->regmap; 929 u32 v; 930 int ret; 931 932 if (sub->swm->dir != PORT_DIR_OUTPUT) 933 return 0; 934 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); 941 if (ret) 942 return ret; 943 944 switch (params_rate(params)) { 945 default: 946 case 48000: 947 v = OPORTMXRATE_I_ACLKSEL_APLLA1 | 948 OPORTMXRATE_I_MCKSEL_36 | 949 OPORTMXRATE_I_FSSEL_48; 950 break; 951 case 44100: 952 v = OPORTMXRATE_I_ACLKSEL_APLLA2 | 953 OPORTMXRATE_I_MCKSEL_33 | 954 OPORTMXRATE_I_FSSEL_44_1; 955 break; 956 case 32000: 957 v = OPORTMXRATE_I_ACLKSEL_APLLA1 | 958 OPORTMXRATE_I_MCKSEL_36 | 959 OPORTMXRATE_I_FSSEL_32; 960 break; 961 } 962 963 964 ret = regmap_write(r, OPORTMXRATE_I(sub->swm->oport.map), 965 v | OPORTMXRATE_I_ACLKSRC_APLL | 966 OPORTMXRATE_I_LRCKSTP_STOP); 967 if (ret) 968 return ret; 969 970 ret = regmap_update_bits(r, OPORTMXRATE_I(sub->swm->oport.map), 971 OPORTMXRATE_I_LRCKSTP_MASK, 972 OPORTMXRATE_I_LRCKSTP_START); 973 if (ret) 974 return ret; 975 976 return 0; 977 } 978 979 int aio_srcif_set_param(struct uniphier_aio_sub *sub) 980 { 981 struct regmap *r = sub->aio->chip->regmap; 982 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); 989 990 return 0; 991 } 992 993 int aio_srcch_set_param(struct uniphier_aio_sub *sub) 994 { 995 struct regmap *r = sub->aio->chip->regmap; 996 997 regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->och.map), 998 CDA2D_CHMXCTRL1_INDSIZE_INFINITE); 999 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); 1004 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)); 1010 1011 return 0; 1012 } 1013 1014 void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable) 1015 { 1016 struct regmap *r = sub->aio->chip->regmap; 1017 u32 v; 1018 1019 if (enable) 1020 v = CDA2D_STRT0_STOP_START; 1021 else 1022 v = CDA2D_STRT0_STOP_STOP; 1023 1024 regmap_write(r, CDA2D_STRT0, 1025 v | BIT(sub->swm->och.map)); 1026 } 1027 1028 int aiodma_ch_set_param(struct uniphier_aio_sub *sub) 1029 { 1030 struct regmap *r = sub->aio->chip->regmap; 1031 u32 v; 1032 1033 regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->ch.map), 1034 CDA2D_CHMXCTRL1_INDSIZE_INFINITE); 1035 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); 1042 else 1043 regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->ch.map), v); 1044 1045 return 0; 1046 } 1047 1048 void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable) 1049 { 1050 struct regmap *r = sub->aio->chip->regmap; 1051 1052 if (enable) { 1053 regmap_write(r, CDA2D_STRT0, 1054 CDA2D_STRT0_STOP_START | BIT(sub->swm->ch.map)); 1055 1056 regmap_update_bits(r, INTRBIM(0), 1057 BIT(sub->swm->rb.map), 1058 BIT(sub->swm->rb.map)); 1059 } else { 1060 regmap_write(r, CDA2D_STRT0, 1061 CDA2D_STRT0_STOP_STOP | BIT(sub->swm->ch.map)); 1062 1063 regmap_update_bits(r, INTRBIM(0), 1064 BIT(sub->swm->rb.map), 1065 0); 1066 } 1067 } 1068 1069 static u64 aiodma_rb_get_rp(struct uniphier_aio_sub *sub) 1070 { 1071 struct regmap *r = sub->aio->chip->regmap; 1072 u32 pos_u, pos_l; 1073 int i; 1074 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); 1080 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); 1084 1085 return ((u64)pos_u << 32) | pos_l; 1086 } 1087 1088 static void aiodma_rb_set_rp(struct uniphier_aio_sub *sub, u64 pos) 1089 { 1090 struct regmap *r = sub->aio->chip->regmap; 1091 u32 tmp; 1092 int i; 1093 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); 1100 } 1101 1102 static u64 aiodma_rb_get_wp(struct uniphier_aio_sub *sub) 1103 { 1104 struct regmap *r = sub->aio->chip->regmap; 1105 u32 pos_u, pos_l; 1106 int i; 1107 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); 1113 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); 1117 1118 return ((u64)pos_u << 32) | pos_l; 1119 } 1120 1121 static void aiodma_rb_set_wp(struct uniphier_aio_sub *sub, u64 pos) 1122 { 1123 struct regmap *r = sub->aio->chip->regmap; 1124 u32 tmp; 1125 int i; 1126 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); 1135 } 1136 1137 int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th) 1138 { 1139 struct regmap *r = sub->aio->chip->regmap; 1140 1141 if (size <= th) 1142 return -EINVAL; 1143 1144 regmap_write(r, CDA2D_RBMXBTH(sub->swm->rb.map), th); 1145 regmap_write(r, CDA2D_RBMXRTH(sub->swm->rb.map), th); 1146 1147 return 0; 1148 } 1149 1150 int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end, 1151 int period) 1152 { 1153 struct regmap *r = sub->aio->chip->regmap; 1154 u64 size = end - start; 1155 int ret; 1156 1157 if (end < start || period < 0) 1158 return -EINVAL; 1159 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)); 1169 1170 regmap_write(r, CDA2D_RBADRSLOAD, BIT(sub->swm->rb.map)); 1171 1172 ret = aiodma_rb_set_threshold(sub, size, 2 * period); 1173 if (ret) 1174 return ret; 1175 1176 if (sub->swm->dir == PORT_DIR_OUTPUT) { 1177 aiodma_rb_set_rp(sub, start); 1178 aiodma_rb_set_wp(sub, end - period); 1179 1180 regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map), 1181 CDA2D_RBMXIX_SPACE, 1182 CDA2D_RBMXIX_SPACE); 1183 } else { 1184 aiodma_rb_set_rp(sub, end - period); 1185 aiodma_rb_set_wp(sub, start); 1186 1187 regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map), 1188 CDA2D_RBMXIX_REMAIN, 1189 CDA2D_RBMXIX_REMAIN); 1190 } 1191 1192 sub->threshold = 2 * period; 1193 sub->rd_offs = 0; 1194 sub->wr_offs = 0; 1195 sub->rd_org = 0; 1196 sub->wr_org = 0; 1197 sub->rd_total = 0; 1198 sub->wr_total = 0; 1199 1200 return 0; 1201 } 1202 1203 void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size, 1204 int period) 1205 { 1206 if (sub->swm->dir == PORT_DIR_OUTPUT) { 1207 sub->rd_offs = aiodma_rb_get_rp(sub) - start; 1208 1209 if (sub->use_mmap) { 1210 sub->threshold = 2 * period; 1211 aiodma_rb_set_threshold(sub, size, 2 * period); 1212 1213 sub->wr_offs = sub->rd_offs - period; 1214 if (sub->rd_offs < period) 1215 sub->wr_offs += size; 1216 } 1217 aiodma_rb_set_wp(sub, sub->wr_offs + start); 1218 } else { 1219 sub->wr_offs = aiodma_rb_get_wp(sub) - start; 1220 1221 if (sub->use_mmap) { 1222 sub->threshold = 2 * period; 1223 aiodma_rb_set_threshold(sub, size, 2 * period); 1224 1225 sub->rd_offs = sub->wr_offs - period; 1226 if (sub->wr_offs < period) 1227 sub->rd_offs += size; 1228 } 1229 aiodma_rb_set_rp(sub, sub->rd_offs + start); 1230 } 1231 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; 1238 1239 sub->rd_org = sub->rd_offs; 1240 sub->wr_org = sub->wr_offs; 1241 } 1242 1243 bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub) 1244 { 1245 struct regmap *r = sub->aio->chip->regmap; 1246 u32 ir; 1247 1248 regmap_read(r, CDA2D_RBMXIR(sub->swm->rb.map), &ir); 1249 1250 if (sub->swm->dir == PORT_DIR_OUTPUT) 1251 return !!(ir & CDA2D_RBMXIX_SPACE); 1252 else 1253 return !!(ir & CDA2D_RBMXIX_REMAIN); 1254 } 1255 1256 void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub) 1257 { 1258 struct regmap *r = sub->aio->chip->regmap; 1259 1260 if (sub->swm->dir == PORT_DIR_OUTPUT) 1261 regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map), 1262 CDA2D_RBMXIX_SPACE); 1263 else 1264 regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map), 1265 CDA2D_RBMXIX_REMAIN); 1266 } 1267