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