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