1 /* $OpenBSD: rkiis.c,v 1.1 2020/06/11 00:02:08 patrick Exp $ */ 2 /* $NetBSD: rk_i2s.c,v 1.3 2020/02/29 05:51:10 isaki Exp $ */ 3 /*- 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/device.h> 32 #include <sys/malloc.h> 33 34 #include <machine/intr.h> 35 #include <machine/bus.h> 36 #include <machine/fdt.h> 37 38 #include <dev/ofw/openfirm.h> 39 #include <dev/ofw/ofw_clock.h> 40 #include <dev/ofw/ofw_misc.h> 41 #include <dev/ofw/ofw_pinctrl.h> 42 #include <dev/ofw/fdt.h> 43 44 #include <sys/audioio.h> 45 #include <dev/audio_if.h> 46 #include <dev/midi_if.h> 47 48 #define RK_I2S_FIFO_DEPTH 32 49 #define RK_I2S_SAMPLE_RATE 48000 50 51 #define I2S_TXCR 0x00 52 #define TXCR_RCNT_MASK (0x3f << 17) 53 #define TXCR_RCNT_SHIFT 17 54 #define TXCR_TCSR_MASK (0x3 << 15) 55 #define TXCR_TCSR_SHIFT 15 56 #define TXCR_HWT (1 << 14) 57 #define TXCR_SJM (1 << 12) 58 #define TXCR_FBM (1 << 11) 59 #define TXCR_IBM_MASK (0x3 << 9) 60 #define TXCR_IBM_SHIFT 9 61 #define TXCR_PBM_MASK (0x3 << 7) 62 #define TXCR_PBM_SHIFT 7 63 #define TXCR_TFS (1 << 5) 64 #define TXCR_VDW_MASK (0x1f << 0) 65 #define TXCR_VDW_SHIFT 0 66 #define I2S_RXCR 0x04 67 #define RXCR_RCSR_MASK (0x3 << 15) 68 #define RXCR_RCSR_SHIFT 15 69 #define RXCR_HWT (1 << 14) 70 #define RXCR_SJM (1 << 12) 71 #define RXCR_FBM (1 << 11) 72 #define RXCR_IBM_MASK (0x3 << 9) 73 #define RXCR_IBM_SHIFT 9 74 #define RXCR_PBM_MASK (0x3 << 7) 75 #define RXCR_PBM_SHIFT 7 76 #define RXCR_TFS (1 << 5) 77 #define RXCR_VDW_MASK (0x1f << 0) 78 #define RXCR_VDW_SHIFT 0 79 #define I2S_CKR 0x08 80 #define CKR_TRCM_MASK (0x3 << 28) 81 #define CKR_TRCM_SHIFT 28 82 #define CKR_MSS (1 << 27) 83 #define CKR_CKP (1 << 26) 84 #define CKR_RLP (1 << 25) 85 #define CKR_TLP (1 << 24) 86 #define CKR_MDIV_MASK (0xff << 16) 87 #define CKR_MDIV_SHIFT 16 88 #define CKR_RSD_MASK (0xff << 8) 89 #define CKR_RSD_SHIFT 8 90 #define CKR_TSD_MASK (0xff << 0) 91 #define CKR_TSD_SHIFT 0 92 #define I2S_TXFIFOLR 0x0c 93 #define TXFIFOLR_TFL_MASK(n) (0x3f << ((n) * 6)) 94 #define TXFIFOLR_TFL_SHIFT(n) ((n) * 6) 95 #define I2S_DMACR 0x10 96 #define DMACR_RDE (1 << 24) 97 #define DMACR_RDL_MASK (0x1f << 16) 98 #define DMACR_RDL_SHIFT 16 99 #define DMACR_TDE (1 << 8) 100 #define DMACR_TDL_MASK (0x1f << 0) 101 #define DMACR_TDL_SHIFT 0 102 #define I2S_INTCR 0x14 103 #define INTCR_RFT_MASK (0x1f << 20) 104 #define INTCR_RFT_SHIFT 20 105 #define INTCR_RXOIC (1 << 18) 106 #define INTCR_RXOIE (1 << 17) 107 #define INTCR_RXFIE (1 << 16) 108 #define INTCR_TFT_MASK (0x1f << 4) 109 #define INTCR_TFT_SHIFT 4 110 #define INTCR_TXUIC (1 << 2) 111 #define INTCR_TXUIE (1 << 1) 112 #define INTCR_TXEIE (1 << 0) 113 #define I2S_INTSR 0x18 114 #define INTSR_RXOI (1 << 17) 115 #define INTSR_RXFI (1 << 16) 116 #define INTSR_TXUI (1 << 1) 117 #define INTSR_TXEI (1 << 0) 118 #define I2S_XFER 0x1c 119 #define XFER_RXS (1 << 1) 120 #define XFER_TXS (1 << 0) 121 #define I2S_CLR 0x20 122 #define CLR_RXC (1 << 1) 123 #define CLR_TXC (1 << 0) 124 #define I2S_TXDR 0x24 125 #define I2S_RXDR 0x28 126 #define I2S_RXFIFOLR 0x2c 127 #define RXFIFOLR_RFL_MASK(n) (0x3f << ((n) * 6)) 128 #define RXFIFOLR_RFL_SHIFT(n) ((n) * 6) 129 130 #define HREAD4(sc, reg) \ 131 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 132 #define HWRITE4(sc, reg, val) \ 133 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 134 #define HSET4(sc, reg, bits) \ 135 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 136 #define HCLR4(sc, reg, bits) \ 137 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 138 139 int rkiis_match(struct device *, void *, void *); 140 void rkiis_attach(struct device *, struct device *, void *); 141 142 int rkiis_intr(void *); 143 int rkiis_set_format(void *, uint32_t, uint32_t, uint32_t); 144 int rkiis_set_sysclk(void *, uint32_t); 145 146 int rkiis_open(void *, int); 147 void rkiis_close(void *); 148 int rkiis_set_params(void *, int, int, 149 struct audio_params *, struct audio_params *); 150 void *rkiis_allocm(void *, int, size_t, int, int); 151 void rkiis_freem(void *, void *, int); 152 int rkiis_get_props(void *); 153 int rkiis_trigger_output(void *, void *, void *, int, 154 void (*)(void *), void *, struct audio_params *); 155 int rkiis_trigger_input(void *, void *, void *, int, 156 void (*)(void *), void *, struct audio_params *); 157 int rkiis_halt_output(void *); 158 int rkiis_halt_input(void *); 159 160 struct rkiis_config { 161 bus_size_t oe_reg; 162 uint32_t oe_mask; 163 uint32_t oe_shift; 164 uint32_t oe_val; 165 }; 166 167 struct rkiis_config rk3399_i2s_config = { 168 .oe_reg = 0xe220, 169 .oe_mask = 0x7, 170 .oe_shift = 11, 171 .oe_val = 0x7, 172 }; 173 174 struct rkiis_chan { 175 uint32_t *ch_start; 176 uint32_t *ch_end; 177 uint32_t *ch_cur; 178 179 int ch_blksize; 180 int ch_resid; 181 182 void (*ch_intr)(void *); 183 void *ch_intrarg; 184 }; 185 186 struct rkiis_softc { 187 struct device sc_dev; 188 bus_space_tag_t sc_iot; 189 bus_space_handle_t sc_ioh; 190 void *sc_ih; 191 192 int sc_node; 193 struct rkiis_config *sc_conf; 194 195 struct rkiis_chan sc_pchan; 196 struct rkiis_chan sc_rchan; 197 198 uint32_t sc_active; 199 200 struct dai_device sc_dai; 201 }; 202 203 struct audio_hw_if rkiis_hw_if = { 204 .set_params = rkiis_set_params, 205 .get_props = rkiis_get_props, 206 .allocm = rkiis_allocm, 207 .freem = rkiis_freem, 208 .trigger_output = rkiis_trigger_output, 209 .trigger_input = rkiis_trigger_input, 210 .halt_output = rkiis_halt_output, 211 .halt_input = rkiis_halt_input, 212 }; 213 214 struct cfattach rkiis_ca = { 215 sizeof (struct rkiis_softc), rkiis_match, rkiis_attach 216 }; 217 218 struct cfdriver rkiis_cd = { 219 NULL, "rkiis", DV_DULL 220 }; 221 222 int 223 rkiis_match(struct device *parent, void *match, void *aux) 224 { 225 struct fdt_attach_args *faa = aux; 226 227 return OF_is_compatible(faa->fa_node, "rockchip,rk3399-i2s"); 228 } 229 230 void 231 rkiis_attach(struct device *parent, struct device *self, void *aux) 232 { 233 struct rkiis_softc *sc = (struct rkiis_softc *)self; 234 struct fdt_attach_args *faa = aux; 235 struct regmap *rm; 236 uint32_t grf, val; 237 238 if (faa->fa_nreg < 1) { 239 printf(": no registers\n"); 240 return; 241 } 242 243 sc->sc_iot = faa->fa_iot; 244 sc->sc_node = faa->fa_node; 245 sc->sc_conf = &rk3399_i2s_config; 246 247 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 248 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 249 printf(": can't map registers\n"); 250 return; 251 } 252 253 pinctrl_byname(sc->sc_node, "default"); 254 clock_enable_all(sc->sc_node); 255 256 grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0); 257 rm = regmap_byphandle(grf); 258 if (rm && sc->sc_conf->oe_mask) { 259 val = sc->sc_conf->oe_val << sc->sc_conf->oe_shift; 260 val |= (sc->sc_conf->oe_mask << sc->sc_conf->oe_shift) << 16; 261 regmap_write_4(rm, sc->sc_conf->oe_reg, val); 262 } 263 264 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_AUDIO | IPL_MPSAFE, 265 rkiis_intr, sc, sc->sc_dev.dv_xname); 266 if (sc->sc_ih == NULL) { 267 printf(": can't establish interrupt\n"); 268 goto unmap; 269 } 270 271 printf("\n"); 272 273 sc->sc_dai.dd_node = faa->fa_node; 274 sc->sc_dai.dd_cookie = sc; 275 sc->sc_dai.dd_hw_if = &rkiis_hw_if; 276 sc->sc_dai.dd_set_format = rkiis_set_format; 277 sc->sc_dai.dd_set_sysclk = rkiis_set_sysclk; 278 dai_register(&sc->sc_dai); 279 return; 280 281 unmap: 282 bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size); 283 } 284 285 int 286 rkiis_intr(void *cookie) 287 { 288 struct rkiis_softc *sc = cookie; 289 struct rkiis_chan *pch = &sc->sc_pchan; 290 #if notyet 291 struct rkiis_chan *rch = &sc->sc_rchan; 292 #endif 293 uint32_t sr, val; 294 int fifolr; 295 296 mtx_enter(&audio_lock); 297 298 sr = HREAD4(sc, I2S_INTSR); 299 300 if ((sr & INTSR_RXFI) != 0) { 301 #if notyet 302 val = HREAD4(sc, I2S_RXFIFOLR); 303 fifolr = val & RXFIFOLR_RFL_MASK(0); 304 fifolr >>= RXFIFOLR_RFL_SHIFT(0); 305 while (fifolr > 0) { 306 *rch->ch_data = HREAD4(sc, I2S_RXDR); 307 rch->ch_data++; 308 rch->ch_resid -= 4; 309 if (rch->ch_resid == 0) 310 rch->ch_intr(rch->ch_intrarg); 311 --fifolr; 312 } 313 #endif 314 } 315 316 if ((sr & INTSR_TXEI) != 0) { 317 val = HREAD4(sc, I2S_TXFIFOLR); 318 fifolr = val & TXFIFOLR_TFL_MASK(0); 319 fifolr >>= TXFIFOLR_TFL_SHIFT(0); 320 fifolr = min(fifolr, RK_I2S_FIFO_DEPTH); 321 while (fifolr < RK_I2S_FIFO_DEPTH - 1) { 322 HWRITE4(sc, I2S_TXDR, *pch->ch_cur); 323 pch->ch_cur++; 324 if (pch->ch_cur == pch->ch_end) 325 pch->ch_cur = pch->ch_start; 326 pch->ch_resid -= 4; 327 if (pch->ch_resid == 0) { 328 pch->ch_intr(pch->ch_intrarg); 329 pch->ch_resid = pch->ch_blksize; 330 } 331 ++fifolr; 332 } 333 } 334 335 mtx_leave(&audio_lock); 336 337 return 1; 338 } 339 340 int 341 rkiis_set_format(void *cookie, uint32_t fmt, uint32_t pol, 342 uint32_t clk) 343 { 344 struct rkiis_softc *sc = cookie; 345 uint32_t txcr, rxcr, ckr; 346 347 txcr = HREAD4(sc, I2S_TXCR); 348 rxcr = HREAD4(sc, I2S_RXCR); 349 ckr = HREAD4(sc, I2S_CKR); 350 351 txcr &= ~(TXCR_IBM_MASK|TXCR_PBM_MASK|TXCR_TFS); 352 rxcr &= ~(RXCR_IBM_MASK|RXCR_PBM_MASK|RXCR_TFS); 353 switch (fmt) { 354 case DAI_FORMAT_I2S: 355 txcr |= 0 << TXCR_IBM_SHIFT; 356 rxcr |= 0 << RXCR_IBM_SHIFT; 357 break; 358 case DAI_FORMAT_LJ: 359 txcr |= 1 << TXCR_IBM_SHIFT; 360 rxcr |= 1 << RXCR_IBM_SHIFT; 361 break; 362 case DAI_FORMAT_RJ: 363 txcr |= 2 << TXCR_IBM_SHIFT; 364 rxcr |= 2 << RXCR_IBM_SHIFT; 365 break; 366 case DAI_FORMAT_DSPA: 367 txcr |= 0 << TXCR_PBM_SHIFT; 368 txcr |= TXCR_TFS; 369 rxcr |= 0 << RXCR_PBM_SHIFT; 370 txcr |= RXCR_TFS; 371 break; 372 case DAI_FORMAT_DSPB: 373 txcr |= 1 << TXCR_PBM_SHIFT; 374 txcr |= TXCR_TFS; 375 rxcr |= 1 << RXCR_PBM_SHIFT; 376 txcr |= RXCR_TFS; 377 break; 378 default: 379 return EINVAL; 380 } 381 382 HWRITE4(sc, I2S_TXCR, txcr); 383 HWRITE4(sc, I2S_RXCR, rxcr); 384 385 switch (pol) { 386 case DAI_POLARITY_IB|DAI_POLARITY_NF: 387 ckr |= CKR_CKP; 388 break; 389 case DAI_POLARITY_NB|DAI_POLARITY_NF: 390 ckr &= ~CKR_CKP; 391 break; 392 default: 393 return EINVAL; 394 } 395 396 switch (clk) { 397 case DAI_CLOCK_CBM|DAI_CLOCK_CFM: 398 ckr |= CKR_MSS; /* sclk input */ 399 break; 400 case DAI_CLOCK_CBS|DAI_CLOCK_CFS: 401 ckr &= ~CKR_MSS; /* sclk output */ 402 break; 403 default: 404 return EINVAL; 405 } 406 407 HWRITE4(sc, I2S_CKR, ckr); 408 409 return 0; 410 } 411 412 int 413 rkiis_set_sysclk(void *cookie, uint32_t rate) 414 { 415 struct rkiis_softc *sc = cookie; 416 int error; 417 418 error = clock_set_frequency(sc->sc_node, "i2s_clk", rate); 419 if (error != 0) { 420 printf("%s: can't set sysclk to %u Hz\n", 421 sc->sc_dev.dv_xname, rate); 422 return error; 423 } 424 425 return 0; 426 } 427 428 int 429 rkiis_set_params(void *cookie, int setmode, int usemode, 430 struct audio_params *play, struct audio_params *rec) 431 { 432 struct rkiis_softc *sc = cookie; 433 uint32_t mclk_rate, bclk_rate; 434 uint32_t bclk_div, lrck_div; 435 uint32_t ckr, txcr, rxcr; 436 int i; 437 438 ckr = HREAD4(sc, I2S_CKR); 439 if ((ckr & CKR_MSS) == 0) { 440 mclk_rate = clock_get_frequency(sc->sc_node, "i2s_clk"); 441 bclk_rate = 2 * 32 * RK_I2S_SAMPLE_RATE; 442 bclk_div = mclk_rate / bclk_rate; 443 lrck_div = bclk_rate / RK_I2S_SAMPLE_RATE; 444 445 ckr &= ~CKR_MDIV_MASK; 446 ckr |= (bclk_div - 1) << CKR_MDIV_SHIFT; 447 ckr &= ~CKR_TSD_MASK; 448 ckr |= (lrck_div - 1) << CKR_TSD_SHIFT; 449 ckr &= ~CKR_RSD_MASK; 450 ckr |= (lrck_div - 1) << CKR_RSD_SHIFT; 451 } 452 453 ckr &= ~CKR_TRCM_MASK; 454 HWRITE4(sc, I2S_CKR, ckr); 455 456 for (i = 0; i < 2; i++) { 457 struct audio_params *p; 458 int mode; 459 460 switch (i) { 461 case 0: 462 mode = AUMODE_PLAY; 463 p = play; 464 break; 465 case 1: 466 mode = AUMODE_RECORD; 467 p = rec; 468 break; 469 default: 470 return EINVAL; 471 } 472 473 if (!(setmode & mode)) 474 continue; 475 476 if (p->channels & 1) 477 return EINVAL; 478 479 if (setmode & AUMODE_PLAY) { 480 txcr = HREAD4(sc, I2S_TXCR); 481 txcr &= ~TXCR_VDW_MASK; 482 txcr |= (16 - 1) << TXCR_VDW_SHIFT; 483 txcr &= ~TXCR_TCSR_MASK; 484 txcr |= (p->channels / 2 - 1) << TXCR_TCSR_SHIFT; 485 HWRITE4(sc, I2S_TXCR, txcr); 486 } else { 487 rxcr = HREAD4(sc, I2S_RXCR); 488 rxcr &= ~RXCR_VDW_MASK; 489 rxcr |= (16 - 1) << RXCR_VDW_SHIFT; 490 rxcr &= ~RXCR_RCSR_MASK; 491 rxcr |= (p->channels / 2 - 1) << RXCR_RCSR_SHIFT; 492 HWRITE4(sc, I2S_RXCR, rxcr); 493 } 494 495 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 496 p->precision = 16; 497 p->bps = AUDIO_BPS(p->precision); 498 p->msb = 1; 499 p->sample_rate = RK_I2S_SAMPLE_RATE; 500 } 501 502 return 0; 503 } 504 505 int 506 rkiis_get_props(void *cookie) 507 { 508 return 0; 509 } 510 511 void * 512 rkiis_allocm(void *cookie, int direction, size_t size, int type, 513 int flags) 514 { 515 return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); 516 } 517 518 void 519 rkiis_freem(void *cookie, void *addr, int size) 520 { 521 free(addr, M_DEVBUF, size); 522 } 523 524 int 525 rkiis_trigger_output(void *cookie, void *start, void *end, int blksize, 526 void (*intr)(void *), void *intrarg, struct audio_params *params) 527 { 528 struct rkiis_softc *sc = cookie; 529 struct rkiis_chan *ch = &sc->sc_pchan; 530 uint32_t val; 531 532 if (sc->sc_active == 0) { 533 val = HREAD4(sc, I2S_XFER); 534 val |= (XFER_TXS | XFER_RXS); 535 HWRITE4(sc, I2S_XFER, val); 536 } 537 538 sc->sc_active |= XFER_TXS; 539 540 val = HREAD4(sc, I2S_INTCR); 541 val |= INTCR_TXEIE; 542 val &= ~INTCR_TFT_MASK; 543 val |= (RK_I2S_FIFO_DEPTH / 2) << INTCR_TFT_SHIFT; 544 HWRITE4(sc, I2S_INTCR, val); 545 546 ch->ch_intr = intr; 547 ch->ch_intrarg = intrarg; 548 ch->ch_start = ch->ch_cur = start; 549 ch->ch_end = end; 550 ch->ch_blksize = blksize; 551 ch->ch_resid = blksize; 552 553 return 0; 554 } 555 556 int 557 rkiis_trigger_input(void *cookie, void *start, void *end, int blksize, 558 void (*intr)(void *), void *intrarg, struct audio_params *params) 559 { 560 return EIO; 561 } 562 563 int 564 rkiis_halt_output(void *cookie) 565 { 566 struct rkiis_softc *sc = cookie; 567 struct rkiis_chan *ch = &sc->sc_pchan; 568 uint32_t val; 569 570 sc->sc_active &= ~XFER_TXS; 571 if (sc->sc_active == 0) { 572 val = HREAD4(sc, I2S_XFER); 573 val &= ~(XFER_TXS|XFER_RXS); 574 HWRITE4(sc, I2S_XFER, val); 575 } 576 577 val = HREAD4(sc, I2S_INTCR); 578 val &= ~INTCR_TXEIE; 579 HWRITE4(sc, I2S_INTCR, val); 580 581 val = HREAD4(sc, I2S_CLR); 582 val |= CLR_TXC; 583 HWRITE4(sc, I2S_CLR, val); 584 585 while ((HREAD4(sc, I2S_CLR) & CLR_TXC) != 0) 586 delay(1); 587 588 ch->ch_intr = NULL; 589 ch->ch_intrarg = NULL; 590 591 return 0; 592 } 593 594 int 595 rkiis_halt_input(void *cookie) 596 { 597 struct rkiis_softc *sc = cookie; 598 struct rkiis_chan *ch = &sc->sc_rchan; 599 uint32_t val; 600 601 sc->sc_active &= ~XFER_RXS; 602 if (sc->sc_active == 0) { 603 val = HREAD4(sc, I2S_XFER); 604 val &= ~(XFER_TXS|XFER_RXS); 605 HWRITE4(sc, I2S_XFER, val); 606 } 607 608 val = HREAD4(sc, I2S_INTCR); 609 val &= ~INTCR_RXFIE; 610 HWRITE4(sc, I2S_INTCR, val); 611 612 ch->ch_intr = NULL; 613 ch->ch_intrarg = NULL; 614 615 return 0; 616 } 617