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