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