1*9c3fbfbdSAndreas Tobler /*- 2*9c3fbfbdSAndreas Tobler * Copyright 2012 by Andreas Tobler. All rights reserved. 3*9c3fbfbdSAndreas Tobler * 4*9c3fbfbdSAndreas Tobler * Redistribution and use in source and binary forms, with or without 5*9c3fbfbdSAndreas Tobler * modification, are permitted provided that the following conditions 6*9c3fbfbdSAndreas Tobler * are met: 7*9c3fbfbdSAndreas Tobler * 1. Redistributions of source code must retain the above copyright 8*9c3fbfbdSAndreas Tobler * notice, this list of conditions and the following disclaimer. 9*9c3fbfbdSAndreas Tobler * 2. Redistributions in binary form must reproduce the above copyright 10*9c3fbfbdSAndreas Tobler * notice, this list of conditions and the following disclaimer in the 11*9c3fbfbdSAndreas Tobler * documentation and/or other materials provided with the distribution. 12*9c3fbfbdSAndreas Tobler * 13*9c3fbfbdSAndreas Tobler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14*9c3fbfbdSAndreas Tobler * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15*9c3fbfbdSAndreas Tobler * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16*9c3fbfbdSAndreas Tobler * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17*9c3fbfbdSAndreas Tobler * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 18*9c3fbfbdSAndreas Tobler * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19*9c3fbfbdSAndreas Tobler * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 20*9c3fbfbdSAndreas Tobler * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21*9c3fbfbdSAndreas Tobler * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*9c3fbfbdSAndreas Tobler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*9c3fbfbdSAndreas Tobler * SUCH DAMAGE. 24*9c3fbfbdSAndreas Tobler * 25*9c3fbfbdSAndreas Tobler * $FreeBSD$ 26*9c3fbfbdSAndreas Tobler */ 27*9c3fbfbdSAndreas Tobler 28*9c3fbfbdSAndreas Tobler /* 29*9c3fbfbdSAndreas Tobler * Apple PCM3052 aka Onyx audio codec. 30*9c3fbfbdSAndreas Tobler * 31*9c3fbfbdSAndreas Tobler * Datasheet: http://www.ti.com/product/pcm3052a 32*9c3fbfbdSAndreas Tobler */ 33*9c3fbfbdSAndreas Tobler 34*9c3fbfbdSAndreas Tobler #include <sys/param.h> 35*9c3fbfbdSAndreas Tobler #include <sys/systm.h> 36*9c3fbfbdSAndreas Tobler #include <sys/kernel.h> 37*9c3fbfbdSAndreas Tobler #include <sys/module.h> 38*9c3fbfbdSAndreas Tobler #include <sys/bus.h> 39*9c3fbfbdSAndreas Tobler #include <sys/malloc.h> 40*9c3fbfbdSAndreas Tobler #include <sys/lock.h> 41*9c3fbfbdSAndreas Tobler #include <sys/mutex.h> 42*9c3fbfbdSAndreas Tobler #include <machine/dbdma.h> 43*9c3fbfbdSAndreas Tobler #include <machine/intr_machdep.h> 44*9c3fbfbdSAndreas Tobler #include <machine/resource.h> 45*9c3fbfbdSAndreas Tobler #include <machine/bus.h> 46*9c3fbfbdSAndreas Tobler #include <machine/pio.h> 47*9c3fbfbdSAndreas Tobler #include <sys/rman.h> 48*9c3fbfbdSAndreas Tobler 49*9c3fbfbdSAndreas Tobler #include <dev/iicbus/iicbus.h> 50*9c3fbfbdSAndreas Tobler #include <dev/iicbus/iiconf.h> 51*9c3fbfbdSAndreas Tobler #include <dev/ofw/ofw_bus.h> 52*9c3fbfbdSAndreas Tobler 53*9c3fbfbdSAndreas Tobler #ifdef HAVE_KERNEL_OPTION_HEADERS 54*9c3fbfbdSAndreas Tobler #include "opt_snd.h" 55*9c3fbfbdSAndreas Tobler #endif 56*9c3fbfbdSAndreas Tobler 57*9c3fbfbdSAndreas Tobler #include <dev/sound/pcm/sound.h> 58*9c3fbfbdSAndreas Tobler 59*9c3fbfbdSAndreas Tobler #include "mixer_if.h" 60*9c3fbfbdSAndreas Tobler 61*9c3fbfbdSAndreas Tobler extern kobj_class_t i2s_mixer_class; 62*9c3fbfbdSAndreas Tobler extern device_t i2s_mixer; 63*9c3fbfbdSAndreas Tobler 64*9c3fbfbdSAndreas Tobler struct onyx_softc 65*9c3fbfbdSAndreas Tobler { 66*9c3fbfbdSAndreas Tobler device_t sc_dev; 67*9c3fbfbdSAndreas Tobler uint32_t sc_addr; 68*9c3fbfbdSAndreas Tobler }; 69*9c3fbfbdSAndreas Tobler 70*9c3fbfbdSAndreas Tobler static int onyx_probe(device_t); 71*9c3fbfbdSAndreas Tobler static int onyx_attach(device_t); 72*9c3fbfbdSAndreas Tobler static int onyx_init(struct snd_mixer *m); 73*9c3fbfbdSAndreas Tobler static int onyx_uninit(struct snd_mixer *m); 74*9c3fbfbdSAndreas Tobler static int onyx_reinit(struct snd_mixer *m); 75*9c3fbfbdSAndreas Tobler static int onyx_set(struct snd_mixer *m, unsigned dev, unsigned left, 76*9c3fbfbdSAndreas Tobler unsigned right); 77*9c3fbfbdSAndreas Tobler static u_int32_t onyx_setrecsrc(struct snd_mixer *m, u_int32_t src); 78*9c3fbfbdSAndreas Tobler 79*9c3fbfbdSAndreas Tobler static device_method_t onyx_methods[] = { 80*9c3fbfbdSAndreas Tobler /* Device interface. */ 81*9c3fbfbdSAndreas Tobler DEVMETHOD(device_probe, onyx_probe), 82*9c3fbfbdSAndreas Tobler DEVMETHOD(device_attach, onyx_attach), 83*9c3fbfbdSAndreas Tobler { 0, 0 } 84*9c3fbfbdSAndreas Tobler }; 85*9c3fbfbdSAndreas Tobler 86*9c3fbfbdSAndreas Tobler static driver_t onyx_driver = { 87*9c3fbfbdSAndreas Tobler "onyx", 88*9c3fbfbdSAndreas Tobler onyx_methods, 89*9c3fbfbdSAndreas Tobler sizeof(struct onyx_softc) 90*9c3fbfbdSAndreas Tobler }; 91*9c3fbfbdSAndreas Tobler static devclass_t onyx_devclass; 92*9c3fbfbdSAndreas Tobler 93*9c3fbfbdSAndreas Tobler DRIVER_MODULE(onyx, iicbus, onyx_driver, onyx_devclass, 0, 0); 94*9c3fbfbdSAndreas Tobler MODULE_VERSION(onyx, 1); 95*9c3fbfbdSAndreas Tobler MODULE_DEPEND(onyx, iicbus, 1, 1, 1); 96*9c3fbfbdSAndreas Tobler 97*9c3fbfbdSAndreas Tobler static kobj_method_t onyx_mixer_methods[] = { 98*9c3fbfbdSAndreas Tobler KOBJMETHOD(mixer_init, onyx_init), 99*9c3fbfbdSAndreas Tobler KOBJMETHOD(mixer_uninit, onyx_uninit), 100*9c3fbfbdSAndreas Tobler KOBJMETHOD(mixer_reinit, onyx_reinit), 101*9c3fbfbdSAndreas Tobler KOBJMETHOD(mixer_set, onyx_set), 102*9c3fbfbdSAndreas Tobler KOBJMETHOD(mixer_setrecsrc, onyx_setrecsrc), 103*9c3fbfbdSAndreas Tobler KOBJMETHOD_END 104*9c3fbfbdSAndreas Tobler }; 105*9c3fbfbdSAndreas Tobler 106*9c3fbfbdSAndreas Tobler MIXER_DECLARE(onyx_mixer); 107*9c3fbfbdSAndreas Tobler 108*9c3fbfbdSAndreas Tobler #define PCM3052_IICADDR 0x8C /* Hard-coded I2C slave addr */ 109*9c3fbfbdSAndreas Tobler 110*9c3fbfbdSAndreas Tobler /* 111*9c3fbfbdSAndreas Tobler * PCM3052 registers. 112*9c3fbfbdSAndreas Tobler * Numbering in decimal as used in the data sheet. 113*9c3fbfbdSAndreas Tobler */ 114*9c3fbfbdSAndreas Tobler #define PCM3052_REG_LEFT_ATTN 65 115*9c3fbfbdSAndreas Tobler #define PCM3052_REG_RIGHT_ATTN 66 116*9c3fbfbdSAndreas Tobler #define PCM3052_REG_CONTROL 67 117*9c3fbfbdSAndreas Tobler #define PCM3052_MRST (1 << 7) 118*9c3fbfbdSAndreas Tobler #define PCM3052_SRST (1 << 6) 119*9c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_CONTROL 68 120*9c3fbfbdSAndreas Tobler #define PCM3052_OVR1 (1 << 6) 121*9c3fbfbdSAndreas Tobler #define PCM3052_MUTE_L (1 << 1) 122*9c3fbfbdSAndreas Tobler #define PCM3052_MUTE_R (1 << 0) 123*9c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_DEEMPH 69 124*9c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_FILTER 70 125*9c3fbfbdSAndreas Tobler #define PCM3052_DAC_FILTER_ALWAYS (1 << 2) 126*9c3fbfbdSAndreas Tobler #define PCM3052_REG_OUT_PHASE 71 127*9c3fbfbdSAndreas Tobler #define PCM3052_REG_ADC_CONTROL 72 128*9c3fbfbdSAndreas Tobler #define PCM3052_REG_ADC_HPF_BP 75 129*9c3fbfbdSAndreas Tobler #define PCM3052_HPF_ALWAYS (1 << 2) 130*9c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_1 77 131*9c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_2 78 132*9c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_3 79 133*9c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_4 80 134*9c3fbfbdSAndreas Tobler 135*9c3fbfbdSAndreas Tobler struct onyx_reg { 136*9c3fbfbdSAndreas Tobler u_char LEFT_ATTN; 137*9c3fbfbdSAndreas Tobler u_char RIGHT_ATTN; 138*9c3fbfbdSAndreas Tobler u_char CONTROL; 139*9c3fbfbdSAndreas Tobler u_char DAC_CONTROL; 140*9c3fbfbdSAndreas Tobler u_char DAC_DEEMPH; 141*9c3fbfbdSAndreas Tobler u_char DAC_FILTER; 142*9c3fbfbdSAndreas Tobler u_char OUT_PHASE; 143*9c3fbfbdSAndreas Tobler u_char ADC_CONTROL; 144*9c3fbfbdSAndreas Tobler u_char ADC_HPF_BP; 145*9c3fbfbdSAndreas Tobler u_char INFO_1; 146*9c3fbfbdSAndreas Tobler u_char INFO_2; 147*9c3fbfbdSAndreas Tobler u_char INFO_3; 148*9c3fbfbdSAndreas Tobler u_char INFO_4; 149*9c3fbfbdSAndreas Tobler }; 150*9c3fbfbdSAndreas Tobler 151*9c3fbfbdSAndreas Tobler static const struct onyx_reg onyx_initdata = { 152*9c3fbfbdSAndreas Tobler 0x80, /* LEFT_ATTN, Mute default */ 153*9c3fbfbdSAndreas Tobler 0x80, /* RIGHT_ATTN, Mute default */ 154*9c3fbfbdSAndreas Tobler PCM3052_MRST | PCM3052_SRST, /* CONTROL */ 155*9c3fbfbdSAndreas Tobler 0, /* DAC_CONTROL */ 156*9c3fbfbdSAndreas Tobler 0, /* DAC_DEEMPH */ 157*9c3fbfbdSAndreas Tobler PCM3052_DAC_FILTER_ALWAYS, /* DAC_FILTER */ 158*9c3fbfbdSAndreas Tobler 0, /* OUT_PHASE */ 159*9c3fbfbdSAndreas Tobler (-1 /* dB */ + 8) & 0xf, /* ADC_CONTROL */ 160*9c3fbfbdSAndreas Tobler PCM3052_HPF_ALWAYS, /* ADC_HPF_BP */ 161*9c3fbfbdSAndreas Tobler (1 << 2), /* INFO_1 */ 162*9c3fbfbdSAndreas Tobler 2, /* INFO_2, */ 163*9c3fbfbdSAndreas Tobler 0, /* INFO_3, CLK 0 (level II), 164*9c3fbfbdSAndreas Tobler SF 0 (44.1 kHz) */ 165*9c3fbfbdSAndreas Tobler 1 /* INFO_4, VALIDL/R 0, 166*9c3fbfbdSAndreas Tobler WL 24-bit depth */ 167*9c3fbfbdSAndreas Tobler }; 168*9c3fbfbdSAndreas Tobler 169*9c3fbfbdSAndreas Tobler static int 170*9c3fbfbdSAndreas Tobler onyx_write(struct onyx_softc *sc, uint8_t reg, const uint8_t value) 171*9c3fbfbdSAndreas Tobler { 172*9c3fbfbdSAndreas Tobler u_int size; 173*9c3fbfbdSAndreas Tobler uint8_t buf[16]; 174*9c3fbfbdSAndreas Tobler 175*9c3fbfbdSAndreas Tobler struct iic_msg msg[] = { 176*9c3fbfbdSAndreas Tobler { sc->sc_addr, IIC_M_WR, 0, buf } 177*9c3fbfbdSAndreas Tobler }; 178*9c3fbfbdSAndreas Tobler 179*9c3fbfbdSAndreas Tobler size = 1; 180*9c3fbfbdSAndreas Tobler msg[0].len = size + 1; 181*9c3fbfbdSAndreas Tobler buf[0] = reg; 182*9c3fbfbdSAndreas Tobler buf[1] = value; 183*9c3fbfbdSAndreas Tobler 184*9c3fbfbdSAndreas Tobler iicbus_transfer(sc->sc_dev, msg, 1); 185*9c3fbfbdSAndreas Tobler 186*9c3fbfbdSAndreas Tobler return (0); 187*9c3fbfbdSAndreas Tobler } 188*9c3fbfbdSAndreas Tobler 189*9c3fbfbdSAndreas Tobler static int 190*9c3fbfbdSAndreas Tobler onyx_probe(device_t dev) 191*9c3fbfbdSAndreas Tobler { 192*9c3fbfbdSAndreas Tobler const char *name, *compat; 193*9c3fbfbdSAndreas Tobler 194*9c3fbfbdSAndreas Tobler name = ofw_bus_get_name(dev); 195*9c3fbfbdSAndreas Tobler if (name == NULL) 196*9c3fbfbdSAndreas Tobler return (ENXIO); 197*9c3fbfbdSAndreas Tobler 198*9c3fbfbdSAndreas Tobler if (strcmp(name, "codec") == 0) { 199*9c3fbfbdSAndreas Tobler if (iicbus_get_addr(dev) != PCM3052_IICADDR) 200*9c3fbfbdSAndreas Tobler return (ENXIO); 201*9c3fbfbdSAndreas Tobler } else if (strcmp(name, "codec") == 0) { 202*9c3fbfbdSAndreas Tobler compat = ofw_bus_get_compat(dev); 203*9c3fbfbdSAndreas Tobler if (compat == NULL || strcmp(compat, "pcm3052") != 0) 204*9c3fbfbdSAndreas Tobler return (ENXIO); 205*9c3fbfbdSAndreas Tobler } else 206*9c3fbfbdSAndreas Tobler return (ENXIO); 207*9c3fbfbdSAndreas Tobler 208*9c3fbfbdSAndreas Tobler device_set_desc(dev, "Texas Instruments PCM3052 Audio Codec"); 209*9c3fbfbdSAndreas Tobler return (0); 210*9c3fbfbdSAndreas Tobler } 211*9c3fbfbdSAndreas Tobler 212*9c3fbfbdSAndreas Tobler static int 213*9c3fbfbdSAndreas Tobler onyx_attach(device_t dev) 214*9c3fbfbdSAndreas Tobler { 215*9c3fbfbdSAndreas Tobler struct onyx_softc *sc; 216*9c3fbfbdSAndreas Tobler 217*9c3fbfbdSAndreas Tobler sc = device_get_softc(dev); 218*9c3fbfbdSAndreas Tobler sc->sc_dev = dev; 219*9c3fbfbdSAndreas Tobler sc->sc_addr = iicbus_get_addr(dev); 220*9c3fbfbdSAndreas Tobler 221*9c3fbfbdSAndreas Tobler i2s_mixer_class = &onyx_mixer_class; 222*9c3fbfbdSAndreas Tobler i2s_mixer = dev; 223*9c3fbfbdSAndreas Tobler 224*9c3fbfbdSAndreas Tobler return (0); 225*9c3fbfbdSAndreas Tobler } 226*9c3fbfbdSAndreas Tobler 227*9c3fbfbdSAndreas Tobler static int 228*9c3fbfbdSAndreas Tobler onyx_init(struct snd_mixer *m) 229*9c3fbfbdSAndreas Tobler { 230*9c3fbfbdSAndreas Tobler struct onyx_softc *sc; 231*9c3fbfbdSAndreas Tobler u_int x = 0; 232*9c3fbfbdSAndreas Tobler 233*9c3fbfbdSAndreas Tobler sc = device_get_softc(mix_getdevinfo(m)); 234*9c3fbfbdSAndreas Tobler 235*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_LEFT_ATTN, onyx_initdata.LEFT_ATTN); 236*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_RIGHT_ATTN, onyx_initdata.RIGHT_ATTN); 237*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_CONTROL, onyx_initdata.CONTROL); 238*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_DAC_CONTROL, 239*9c3fbfbdSAndreas Tobler onyx_initdata.DAC_CONTROL); 240*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_DAC_DEEMPH, onyx_initdata.DAC_DEEMPH); 241*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_DAC_FILTER, onyx_initdata.DAC_FILTER); 242*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_OUT_PHASE, onyx_initdata.OUT_PHASE); 243*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_ADC_CONTROL, 244*9c3fbfbdSAndreas Tobler onyx_initdata.ADC_CONTROL); 245*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_ADC_HPF_BP, onyx_initdata.ADC_HPF_BP); 246*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_INFO_1, onyx_initdata.INFO_1); 247*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_INFO_2, onyx_initdata.INFO_2); 248*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_INFO_3, onyx_initdata.INFO_3); 249*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_INFO_4, onyx_initdata.INFO_4); 250*9c3fbfbdSAndreas Tobler 251*9c3fbfbdSAndreas Tobler x |= SOUND_MASK_VOLUME; 252*9c3fbfbdSAndreas Tobler mix_setdevs(m, x); 253*9c3fbfbdSAndreas Tobler 254*9c3fbfbdSAndreas Tobler return (0); 255*9c3fbfbdSAndreas Tobler } 256*9c3fbfbdSAndreas Tobler 257*9c3fbfbdSAndreas Tobler static int 258*9c3fbfbdSAndreas Tobler onyx_uninit(struct snd_mixer *m) 259*9c3fbfbdSAndreas Tobler { 260*9c3fbfbdSAndreas Tobler return (0); 261*9c3fbfbdSAndreas Tobler } 262*9c3fbfbdSAndreas Tobler 263*9c3fbfbdSAndreas Tobler static int 264*9c3fbfbdSAndreas Tobler onyx_reinit(struct snd_mixer *m) 265*9c3fbfbdSAndreas Tobler { 266*9c3fbfbdSAndreas Tobler return (0); 267*9c3fbfbdSAndreas Tobler } 268*9c3fbfbdSAndreas Tobler 269*9c3fbfbdSAndreas Tobler static int 270*9c3fbfbdSAndreas Tobler onyx_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 271*9c3fbfbdSAndreas Tobler { 272*9c3fbfbdSAndreas Tobler struct onyx_softc *sc; 273*9c3fbfbdSAndreas Tobler struct mtx *mixer_lock; 274*9c3fbfbdSAndreas Tobler int locked; 275*9c3fbfbdSAndreas Tobler uint8_t l, r; 276*9c3fbfbdSAndreas Tobler 277*9c3fbfbdSAndreas Tobler sc = device_get_softc(mix_getdevinfo(m)); 278*9c3fbfbdSAndreas Tobler mixer_lock = mixer_get_lock(m); 279*9c3fbfbdSAndreas Tobler locked = mtx_owned(mixer_lock); 280*9c3fbfbdSAndreas Tobler 281*9c3fbfbdSAndreas Tobler switch (dev) { 282*9c3fbfbdSAndreas Tobler case SOUND_MIXER_VOLUME: 283*9c3fbfbdSAndreas Tobler 284*9c3fbfbdSAndreas Tobler /* 285*9c3fbfbdSAndreas Tobler * We need to unlock the mixer lock because iicbus_transfer() 286*9c3fbfbdSAndreas Tobler * may sleep. The mixer lock itself is unnecessary here 287*9c3fbfbdSAndreas Tobler * because it is meant to serialize hardware access, which 288*9c3fbfbdSAndreas Tobler * is taken care of by the I2C layer, so this is safe. 289*9c3fbfbdSAndreas Tobler */ 290*9c3fbfbdSAndreas Tobler if (left > 100 || right > 100) 291*9c3fbfbdSAndreas Tobler return (0); 292*9c3fbfbdSAndreas Tobler 293*9c3fbfbdSAndreas Tobler l = left + 128; 294*9c3fbfbdSAndreas Tobler r = right + 128; 295*9c3fbfbdSAndreas Tobler 296*9c3fbfbdSAndreas Tobler if (locked) 297*9c3fbfbdSAndreas Tobler mtx_unlock(mixer_lock); 298*9c3fbfbdSAndreas Tobler 299*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_LEFT_ATTN, l); 300*9c3fbfbdSAndreas Tobler onyx_write(sc, PCM3052_REG_RIGHT_ATTN, r); 301*9c3fbfbdSAndreas Tobler 302*9c3fbfbdSAndreas Tobler if (locked) 303*9c3fbfbdSAndreas Tobler mtx_lock(mixer_lock); 304*9c3fbfbdSAndreas Tobler 305*9c3fbfbdSAndreas Tobler return (left | (right << 8)); 306*9c3fbfbdSAndreas Tobler } 307*9c3fbfbdSAndreas Tobler 308*9c3fbfbdSAndreas Tobler return (0); 309*9c3fbfbdSAndreas Tobler } 310*9c3fbfbdSAndreas Tobler 311*9c3fbfbdSAndreas Tobler static u_int32_t 312*9c3fbfbdSAndreas Tobler onyx_setrecsrc(struct snd_mixer *m, u_int32_t src) 313*9c3fbfbdSAndreas Tobler { 314*9c3fbfbdSAndreas Tobler return (0); 315*9c3fbfbdSAndreas Tobler } 316