1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2020 Oleksandr Tymoshenko <gonzo@FreeBSD.org> 5 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> 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 * $FreeBSD$ 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/kernel.h> 38 #include <sys/lock.h> 39 #include <sys/module.h> 40 #include <sys/mutex.h> 41 #include <sys/rman.h> 42 #include <sys/resource.h> 43 #include <machine/bus.h> 44 45 #include <dev/ofw/ofw_bus.h> 46 #include <dev/ofw/ofw_bus_subr.h> 47 48 #include <dev/extres/clk/clk.h> 49 #include <dev/extres/syscon/syscon.h> 50 51 #include "syscon_if.h" 52 53 #include "opt_snd.h" 54 #include <dev/sound/pcm/sound.h> 55 #include <dev/sound/fdt/audio_dai.h> 56 #include "audio_dai_if.h" 57 #include "mixer_if.h" 58 59 #define RKCODEC_MIXER_DEVS (1 << SOUND_MIXER_VOLUME) 60 61 #define GRF_SOC_CON2 0x0408 62 #define SOC_CON2_I2S_ACODEC_EN (1 << 14) 63 #define SOC_CON2_I2S_ACODEC_EN_MASK ((1 << 14) << 16) 64 #define GRF_SOC_CON10 0x0428 65 #define SOC_CON10_GPIOMUT (1 << 1) 66 #define SOC_CON10_GPIOMUT_MASK ((1 << 1) << 16) 67 #define SOC_CON10_GPIOMUT_EN (1 << 0) 68 #define SOC_CON10_GPIOMUT_EN_MASK ((1 << 0) << 16) 69 70 #define CODEC_RESET 0x00 71 #define RESET_DIG_CORE_RST (1 << 1) 72 #define RESET_SYS_RST (1 << 0) 73 #define CODEC_DAC_INIT_CTRL1 0x0c 74 #define DAC_INIT_CTRL1_DIRECTION_IN (0 << 5) 75 #define DAC_INIT_CTRL1_DIRECTION_OUT (1 << 5) 76 #define DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE (0 << 4) 77 #define DAC_INIT_CTRL1_DAC_I2S_MODE_MASTER (1 << 4) 78 #define DAC_INIT_CTRL1_MODE_MASK (3 << 4) 79 #define CODEC_DAC_INIT_CTRL2 0x10 80 #define DAC_INIT_CTRL2_DAC_VDL_16BITS (0 << 5) 81 #define DAC_INIT_CTRL2_DAC_VDL_20BITS (1 << 5) 82 #define DAC_INIT_CTRL2_DAC_VDL_24BITS (2 << 5) 83 #define DAC_INIT_CTRL2_DAC_VDL_32BITS (3 << 5) 84 #define DAC_INIT_CTRL2_DAC_VDL_MASK (3 << 5) 85 #define DAC_INIT_CTRL2_DAC_MODE_RJM (0 << 3) 86 #define DAC_INIT_CTRL2_DAC_MODE_LJM (1 << 3) 87 #define DAC_INIT_CTRL2_DAC_MODE_I2S (2 << 3) 88 #define DAC_INIT_CTRL2_DAC_MODE_PCM (3 << 3) 89 #define DAC_INIT_CTRL2_DAC_MODE_MASK (3 << 3) 90 #define CODEC_DAC_INIT_CTRL3 0x14 91 #define DAC_INIT_CTRL3_WL_16BITS (0 << 2) 92 #define DAC_INIT_CTRL3_WL_20BITS (1 << 2) 93 #define DAC_INIT_CTRL3_WL_24BITS (2 << 2) 94 #define DAC_INIT_CTRL3_WL_32BITS (3 << 2) 95 #define DAC_INIT_CTRL3_WL_MASK (3 << 2) 96 #define DAC_INIT_CTRL3_RST_MASK (1 << 1) 97 #define DAC_INIT_CTRL3_RST_DIS (1 << 1) 98 #define DAC_INIT_CTRL3_DAC_BCP_REVERSAL (1 << 0) 99 #define DAC_INIT_CTRL3_DAC_BCP_NORMAL (0 << 0) 100 #define DAC_INIT_CTRL3_DAC_BCP_MASK (1 << 0) 101 #define CODEC_DAC_PRECHARGE_CTRL 0x88 102 #define DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE (1 << 7) 103 #define DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_I (1 << 0) 104 #define DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL (0x7f) 105 #define CODEC_DAC_PWR_CTRL 0x8c 106 #define DAC_PWR_CTRL_DAC_PWR (1 << 6) 107 #define DAC_PWR_CTRL_DACL_PATH_REFV (1 << 5) 108 #define DAC_PWR_CTRL_HPOUTL_ZERO_CROSSING (1 << 4) 109 #define DAC_PWR_CTRL_DACR_PATH_REFV (1 << 1) 110 #define DAC_PWR_CTRL_HPOUTR_ZERO_CROSSING (1 << 0) 111 #define CODEC_DAC_CLK_CTRL 0x90 112 #define DAC_CLK_CTRL_DACL_REFV_ON (1 << 7) 113 #define DAC_CLK_CTRL_DACL_CLK_ON (1 << 6) 114 #define DAC_CLK_CTRL_DACL_ON (1 << 5) 115 #define DAC_CLK_CTRL_DACL_INIT_ON (1 << 4) 116 #define DAC_CLK_CTRL_DACR_REFV_ON (1 << 3) 117 #define DAC_CLK_CTRL_DACR_CLK_ON (1 << 2) 118 #define DAC_CLK_CTRL_DACR_ON (1 << 1) 119 #define DAC_CLK_CTRL_DACR_INIT_ON (1 << 0) 120 #define CODEC_HPMIX_CTRL 0x94 121 #define HPMIX_CTRL_HPMIXL_EN (1 << 6) 122 #define HPMIX_CTRL_HPMIXL_INIT_EN (1 << 5) 123 #define HPMIX_CTRL_HPMIXL_INIT2_EN (1 << 4) 124 #define HPMIX_CTRL_HPMIXR_EN (1 << 2) 125 #define HPMIX_CTRL_HPMIXR_INIT_EN (1 << 1) 126 #define HPMIX_CTRL_HPMIXR_INIT2_EN (1 << 0) 127 #define CODEC_DAC_SELECT 0x98 128 #define DAC_SELECT_DACL_SELECT (1 << 4) 129 #define DAC_SELECT_DACR_SELECT (1 << 0) 130 #define CODEC_HPOUT_CTRL 0x9c 131 #define HPOUT_CTRL_HPOUTL_EN (1 << 7) 132 #define HPOUT_CTRL_HPOUTL_INIT_EN (1 << 6) 133 #define HPOUT_CTRL_HPOUTL_UNMUTE (1 << 5) 134 #define HPOUT_CTRL_HPOUTR_EN (1 << 4) 135 #define HPOUT_CTRL_HPOUTR_INIT_EN (1 << 3) 136 #define HPOUT_CTRL_HPOUTR_UNMUTE (1 << 2) 137 #define CODEC_HPOUTL_GAIN_CTRL 0xa0 138 #define CODEC_HPOUTR_GAIN_CTRL 0xa4 139 #define CODEC_HPOUT_POP_CTRL 0xa8 140 #define HPOUT_POP_CTRL_HPOUTR_POP (1 << 5) 141 #define HPOUT_POP_CTRL_HPOUTR_POP_XCHARGE (1 << 4) 142 #define HPOUT_POP_CTRL_HPOUTL_POP (1 << 1) 143 #define HPOUT_POP_CTRL_HPOUTL_POP_XCHARGE (1 << 0) 144 145 #define DEFAULT_RATE (48000 * 256) 146 147 static struct ofw_compat_data compat_data[] = { 148 { "rockchip,rk3328-codec", 1}, 149 { NULL, 0 } 150 }; 151 152 struct rkcodec_softc { 153 device_t dev; 154 struct resource *res; 155 struct mtx mtx; 156 clk_t mclk; 157 clk_t pclk; 158 struct syscon *grf; 159 u_int regaddr; /* address for the sysctl */ 160 }; 161 162 #define RKCODEC_LOCK(sc) mtx_lock(&(sc)->mtx) 163 #define RKCODEC_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 164 #define RKCODEC_READ(sc, reg) bus_read_4((sc)->res, (reg)) 165 #define RKCODEC_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) 166 167 static int rkcodec_probe(device_t dev); 168 static int rkcodec_attach(device_t dev); 169 static int rkcodec_detach(device_t dev); 170 171 static void 172 rkcodec_set_power(struct rkcodec_softc *sc, bool poweron) 173 { 174 uint32_t val; 175 val = RKCODEC_READ(sc, CODEC_DAC_PRECHARGE_CTRL); 176 if (poweron) 177 val |= DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE; 178 else 179 val &= ~(DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE); 180 RKCODEC_WRITE(sc, CODEC_DAC_PRECHARGE_CTRL, val); 181 182 DELAY(10000); 183 184 val = RKCODEC_READ(sc, CODEC_DAC_PRECHARGE_CTRL); 185 if (poweron) 186 val |= DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL; 187 else 188 val &= ~(DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL); 189 RKCODEC_WRITE(sc, CODEC_DAC_PRECHARGE_CTRL, val); 190 191 } 192 193 static void 194 rkcodec_set_mute(struct rkcodec_softc *sc, bool muted) 195 { 196 uint32_t val; 197 val = SOC_CON10_GPIOMUT_MASK; 198 if (!muted) 199 val |= SOC_CON10_GPIOMUT; 200 SYSCON_WRITE_4(sc->grf, GRF_SOC_CON10, val); 201 } 202 203 static void 204 rkcodec_reset(struct rkcodec_softc *sc) 205 { 206 207 RKCODEC_WRITE(sc, CODEC_RESET, 0); 208 DELAY(10000); 209 RKCODEC_WRITE(sc, CODEC_RESET, RESET_DIG_CORE_RST | RESET_SYS_RST); 210 } 211 212 static int 213 rkcodec_probe(device_t dev) 214 { 215 if (!ofw_bus_status_okay(dev)) 216 return (ENXIO); 217 218 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) 219 return (ENXIO); 220 221 device_set_desc(dev, "Rockchip RK3328 CODEC"); 222 return (BUS_PROBE_DEFAULT); 223 } 224 225 static int 226 rkcodec_attach(device_t dev) 227 { 228 struct rkcodec_softc *sc; 229 int error, rid; 230 phandle_t node; 231 uint32_t val; 232 233 sc = device_get_softc(dev); 234 sc->dev = dev; 235 236 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); 237 238 rid = 0; 239 sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 240 if (!sc->res) { 241 device_printf(dev, "could not allocate resource for device\n"); 242 error = ENXIO; 243 goto fail; 244 } 245 246 node = ofw_bus_get_node(dev); 247 if (syscon_get_by_ofw_property(dev, node, 248 "rockchip,grf", &sc->grf) != 0) { 249 device_printf(dev, "cannot get rockchip,grf handle\n"); 250 return (ENXIO); 251 } 252 253 val = SOC_CON2_I2S_ACODEC_EN | SOC_CON2_I2S_ACODEC_EN_MASK; 254 SYSCON_WRITE_4(sc->grf, GRF_SOC_CON2, val); 255 256 val = 0 | SOC_CON10_GPIOMUT_EN_MASK; 257 SYSCON_WRITE_4(sc->grf, GRF_SOC_CON10, val); 258 259 error = clk_get_by_ofw_name(dev, 0, "pclk", &sc->pclk); 260 if (error != 0) { 261 device_printf(dev, "could not get pclk clock\n"); 262 goto fail; 263 } 264 265 error = clk_get_by_ofw_name(dev, 0, "mclk", &sc->mclk); 266 if (error != 0) { 267 device_printf(dev, "could not get mclk clock\n"); 268 goto fail; 269 } 270 271 error = clk_enable(sc->pclk); 272 if (error != 0) { 273 device_printf(sc->dev, "could not enable pclk clock\n"); 274 goto fail; 275 } 276 277 error = clk_enable(sc->mclk); 278 if (error != 0) { 279 device_printf(sc->dev, "could not enable mclk clock\n"); 280 goto fail; 281 } 282 283 #if 0 284 error = clk_set_freq(sc->mclk, DEFAULT_RATE, 0); 285 if (error != 0) { 286 device_printf(sc->dev, "could not set frequency for mclk clock\n"); 287 goto fail; 288 } 289 #endif 290 291 /* TODO: handle mute-gpios */ 292 293 rkcodec_reset(sc); 294 rkcodec_set_power(sc, true); 295 296 val = RKCODEC_READ(sc, CODEC_DAC_PWR_CTRL); 297 val |= DAC_PWR_CTRL_DAC_PWR; 298 RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); 299 DELAY(1000); 300 301 val |= DAC_PWR_CTRL_DACL_PATH_REFV | 302 DAC_PWR_CTRL_DACR_PATH_REFV; 303 RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); 304 DELAY(1000); 305 306 val |= DAC_PWR_CTRL_HPOUTL_ZERO_CROSSING | 307 DAC_PWR_CTRL_HPOUTR_ZERO_CROSSING; 308 RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); 309 DELAY(1000); 310 311 val = RKCODEC_READ(sc, CODEC_HPOUT_POP_CTRL); 312 val |= HPOUT_POP_CTRL_HPOUTR_POP | HPOUT_POP_CTRL_HPOUTL_POP; 313 val &= ~(HPOUT_POP_CTRL_HPOUTR_POP_XCHARGE | HPOUT_POP_CTRL_HPOUTL_POP_XCHARGE); 314 RKCODEC_WRITE(sc, CODEC_HPOUT_POP_CTRL, val); 315 DELAY(1000); 316 317 val = RKCODEC_READ(sc, CODEC_HPMIX_CTRL); 318 val |= HPMIX_CTRL_HPMIXL_EN | HPMIX_CTRL_HPMIXR_EN; 319 RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); 320 DELAY(1000); 321 322 val |= HPMIX_CTRL_HPMIXL_INIT_EN | HPMIX_CTRL_HPMIXR_INIT_EN; 323 RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); 324 DELAY(1000); 325 326 val = RKCODEC_READ(sc, CODEC_HPOUT_CTRL); 327 val |= HPOUT_CTRL_HPOUTL_EN | HPOUT_CTRL_HPOUTR_EN; 328 RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); 329 DELAY(1000); 330 331 val |= HPOUT_CTRL_HPOUTL_INIT_EN | HPOUT_CTRL_HPOUTR_INIT_EN; 332 RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); 333 DELAY(1000); 334 335 val = RKCODEC_READ(sc, CODEC_DAC_CLK_CTRL); 336 val |= DAC_CLK_CTRL_DACL_REFV_ON | DAC_CLK_CTRL_DACR_REFV_ON; 337 RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); 338 DELAY(1000); 339 340 val |= DAC_CLK_CTRL_DACL_CLK_ON | DAC_CLK_CTRL_DACR_CLK_ON; 341 RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); 342 DELAY(1000); 343 344 val |= DAC_CLK_CTRL_DACL_ON | DAC_CLK_CTRL_DACR_ON; 345 RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); 346 DELAY(1000); 347 348 val |= DAC_CLK_CTRL_DACL_INIT_ON | DAC_CLK_CTRL_DACR_INIT_ON; 349 RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); 350 DELAY(1000); 351 352 val = RKCODEC_READ(sc, CODEC_DAC_SELECT); 353 val |= DAC_SELECT_DACL_SELECT | DAC_SELECT_DACR_SELECT; 354 RKCODEC_WRITE(sc, CODEC_DAC_SELECT, val); 355 DELAY(1000); 356 357 val = RKCODEC_READ(sc, CODEC_HPMIX_CTRL); 358 val |= HPMIX_CTRL_HPMIXL_INIT2_EN | HPMIX_CTRL_HPMIXR_INIT2_EN; 359 RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); 360 DELAY(1000); 361 362 val = RKCODEC_READ(sc, CODEC_HPOUT_CTRL); 363 val |= HPOUT_CTRL_HPOUTL_UNMUTE | HPOUT_CTRL_HPOUTR_UNMUTE; 364 RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); 365 DELAY(1000); 366 367 RKCODEC_WRITE(sc, CODEC_HPOUTL_GAIN_CTRL, 0x18); 368 RKCODEC_WRITE(sc, CODEC_HPOUTR_GAIN_CTRL, 0x18); 369 DELAY(1000); 370 371 rkcodec_set_mute(sc, false); 372 373 node = ofw_bus_get_node(dev); 374 OF_device_register_xref(OF_xref_from_node(node), dev); 375 376 return (0); 377 378 fail: 379 rkcodec_detach(dev); 380 return (error); 381 } 382 383 static int 384 rkcodec_detach(device_t dev) 385 { 386 struct rkcodec_softc *sc; 387 388 sc = device_get_softc(dev); 389 390 if (sc->res) 391 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); 392 mtx_destroy(&sc->mtx); 393 394 return (0); 395 } 396 397 static int 398 rkcodec_mixer_init(struct snd_mixer *m) 399 { 400 401 mix_setdevs(m, RKCODEC_MIXER_DEVS); 402 403 return (0); 404 } 405 406 static int 407 rkcodec_mixer_uninit(struct snd_mixer *m) 408 { 409 410 return (0); 411 } 412 413 static int 414 rkcodec_mixer_reinit(struct snd_mixer *m) 415 { 416 417 return (0); 418 } 419 420 static int 421 rkcodec_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 422 { 423 struct rkcodec_softc *sc; 424 struct mtx *mixer_lock; 425 uint8_t do_unlock; 426 427 sc = device_get_softc(mix_getdevinfo(m)); 428 mixer_lock = mixer_get_lock(m); 429 430 if (mtx_owned(mixer_lock)) { 431 do_unlock = 0; 432 } else { 433 do_unlock = 1; 434 mtx_lock(mixer_lock); 435 } 436 437 right = left; 438 439 RKCODEC_LOCK(sc); 440 switch(dev) { 441 case SOUND_MIXER_VOLUME: 442 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 443 break; 444 445 case SOUND_MIXER_MIC: 446 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 447 break; 448 default: 449 break; 450 } 451 RKCODEC_UNLOCK(sc); 452 453 if (do_unlock) { 454 mtx_unlock(mixer_lock); 455 } 456 457 return (left | (right << 8)); 458 } 459 460 static unsigned 461 rkcodec_mixer_setrecsrc(struct snd_mixer *m, unsigned src) 462 { 463 464 return (0); 465 } 466 467 static kobj_method_t rkcodec_mixer_methods[] = { 468 KOBJMETHOD(mixer_init, rkcodec_mixer_init), 469 KOBJMETHOD(mixer_uninit, rkcodec_mixer_uninit), 470 KOBJMETHOD(mixer_reinit, rkcodec_mixer_reinit), 471 KOBJMETHOD(mixer_set, rkcodec_mixer_set), 472 KOBJMETHOD(mixer_setrecsrc, rkcodec_mixer_setrecsrc), 473 KOBJMETHOD_END 474 }; 475 476 MIXER_DECLARE(rkcodec_mixer); 477 478 static int 479 rkcodec_dai_init(device_t dev, uint32_t format) 480 { 481 struct rkcodec_softc *sc; 482 int fmt, pol, clk; 483 uint32_t ctrl1, ctrl2, ctrl3; 484 485 sc = device_get_softc(dev); 486 487 fmt = AUDIO_DAI_FORMAT_FORMAT(format); 488 pol = AUDIO_DAI_FORMAT_POLARITY(format); 489 clk = AUDIO_DAI_FORMAT_CLOCK(format); 490 491 ctrl1 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL1); 492 ctrl2 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL2); 493 ctrl3 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL3); 494 495 ctrl3 &= ~(DAC_INIT_CTRL3_DAC_BCP_MASK); 496 switch (pol) { 497 case AUDIO_DAI_POLARITY_IB_NF: 498 ctrl3 |= DAC_INIT_CTRL3_DAC_BCP_REVERSAL; 499 break; 500 case AUDIO_DAI_POLARITY_NB_NF: 501 ctrl3 |= DAC_INIT_CTRL3_DAC_BCP_NORMAL; 502 break; 503 default: 504 return (EINVAL); 505 } 506 507 ctrl1 &= ~(DAC_INIT_CTRL1_MODE_MASK); 508 switch (clk) { 509 case AUDIO_DAI_CLOCK_CBM_CFM: 510 ctrl1 |= DAC_INIT_CTRL1_DIRECTION_OUT | 511 DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE; 512 break; 513 case AUDIO_DAI_CLOCK_CBS_CFS: 514 ctrl1 |= DAC_INIT_CTRL1_DIRECTION_IN | 515 DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE; 516 break; 517 default: 518 return (EINVAL); 519 } 520 521 ctrl2 &= ~(DAC_INIT_CTRL2_DAC_VDL_MASK | DAC_INIT_CTRL2_DAC_MODE_MASK); 522 ctrl2 |= DAC_INIT_CTRL2_DAC_VDL_16BITS; 523 ctrl3 &= ~(DAC_INIT_CTRL3_WL_MASK); 524 ctrl3 |= DAC_INIT_CTRL3_WL_32BITS; 525 switch (fmt) { 526 case AUDIO_DAI_FORMAT_I2S: 527 ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_I2S; 528 break; 529 case AUDIO_DAI_FORMAT_LJ: 530 ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_LJM; 531 break; 532 case AUDIO_DAI_FORMAT_RJ: 533 ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_RJM; 534 break; 535 default: 536 return EINVAL; 537 } 538 539 ctrl3 &= ~(DAC_INIT_CTRL3_RST_MASK); 540 ctrl3 |= DAC_INIT_CTRL3_RST_DIS; 541 542 RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL1, ctrl1); 543 RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL2, ctrl2); 544 RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL3, ctrl3); 545 546 return (0); 547 } 548 549 static int 550 rkcodec_dai_trigger(device_t dev, int go, int pcm_dir) 551 { 552 // struct rkcodec_softc *sc = device_get_softc(dev); 553 554 if ((pcm_dir != PCMDIR_PLAY) && (pcm_dir != PCMDIR_REC)) 555 return (EINVAL); 556 557 switch (go) { 558 case PCMTRIG_START: 559 if (pcm_dir == PCMDIR_PLAY) { 560 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 561 } 562 else if (pcm_dir == PCMDIR_REC) { 563 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 564 } 565 break; 566 567 case PCMTRIG_STOP: 568 case PCMTRIG_ABORT: 569 if (pcm_dir == PCMDIR_PLAY) { 570 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 571 } 572 else if (pcm_dir == PCMDIR_REC) { 573 printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); 574 } 575 break; 576 } 577 578 return (0); 579 } 580 581 static int 582 rkcodec_dai_setup_mixer(device_t dev, device_t pcmdev) 583 { 584 585 mixer_init(pcmdev, &rkcodec_mixer_class, dev); 586 587 return (0); 588 } 589 590 static device_method_t rkcodec_methods[] = { 591 /* Device interface */ 592 DEVMETHOD(device_probe, rkcodec_probe), 593 DEVMETHOD(device_attach, rkcodec_attach), 594 DEVMETHOD(device_detach, rkcodec_detach), 595 596 DEVMETHOD(audio_dai_init, rkcodec_dai_init), 597 DEVMETHOD(audio_dai_setup_mixer, rkcodec_dai_setup_mixer), 598 DEVMETHOD(audio_dai_trigger, rkcodec_dai_trigger), 599 600 DEVMETHOD_END 601 }; 602 603 static driver_t rkcodec_driver = { 604 "rk3328codec", 605 rkcodec_methods, 606 sizeof(struct rkcodec_softc), 607 }; 608 609 DRIVER_MODULE(rkcodec, simplebus, rkcodec_driver, 0, 0); 610 SIMPLEBUS_PNP_INFO(compat_data); 611