xref: /freebsd/sys/dev/sound/macio/onyx.c (revision 6f96ef84b359137a51dc1e717887ca7d31ba7bad)
19c3fbfbdSAndreas Tobler /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
49c3fbfbdSAndreas Tobler  * Copyright 2012 by Andreas Tobler. All rights reserved.
59c3fbfbdSAndreas Tobler  *
69c3fbfbdSAndreas Tobler  * Redistribution and use in source and binary forms, with or without
79c3fbfbdSAndreas Tobler  * modification, are permitted provided that the following conditions
89c3fbfbdSAndreas Tobler  * are met:
99c3fbfbdSAndreas Tobler  * 1. Redistributions of source code must retain the above copyright
109c3fbfbdSAndreas Tobler  *    notice, this list of conditions and the following disclaimer.
119c3fbfbdSAndreas Tobler  * 2. Redistributions in binary form must reproduce the above copyright
129c3fbfbdSAndreas Tobler  *    notice, this list of conditions and the following disclaimer in the
139c3fbfbdSAndreas Tobler  *    documentation and/or other materials provided with the distribution.
149c3fbfbdSAndreas Tobler  *
159c3fbfbdSAndreas Tobler  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
169c3fbfbdSAndreas Tobler  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
179c3fbfbdSAndreas Tobler  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
189c3fbfbdSAndreas Tobler  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
199c3fbfbdSAndreas Tobler  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
209c3fbfbdSAndreas Tobler  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
219c3fbfbdSAndreas Tobler  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
229c3fbfbdSAndreas Tobler  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
239c3fbfbdSAndreas Tobler  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249c3fbfbdSAndreas Tobler  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259c3fbfbdSAndreas Tobler  * SUCH DAMAGE.
269c3fbfbdSAndreas Tobler  */
279c3fbfbdSAndreas Tobler 
289c3fbfbdSAndreas Tobler /*
299c3fbfbdSAndreas Tobler  * Apple PCM3052 aka Onyx audio codec.
309c3fbfbdSAndreas Tobler  *
319c3fbfbdSAndreas Tobler  * Datasheet: http://www.ti.com/product/pcm3052a
329c3fbfbdSAndreas Tobler  */
339c3fbfbdSAndreas Tobler 
349c3fbfbdSAndreas Tobler #include <sys/param.h>
359c3fbfbdSAndreas Tobler #include <sys/systm.h>
369c3fbfbdSAndreas Tobler #include <sys/kernel.h>
379c3fbfbdSAndreas Tobler #include <sys/module.h>
389c3fbfbdSAndreas Tobler #include <sys/bus.h>
399c3fbfbdSAndreas Tobler #include <sys/malloc.h>
409c3fbfbdSAndreas Tobler #include <sys/lock.h>
419c3fbfbdSAndreas Tobler #include <sys/mutex.h>
429c3fbfbdSAndreas Tobler #include <machine/dbdma.h>
439c3fbfbdSAndreas Tobler #include <machine/intr_machdep.h>
449c3fbfbdSAndreas Tobler #include <machine/resource.h>
459c3fbfbdSAndreas Tobler #include <machine/bus.h>
469c3fbfbdSAndreas Tobler #include <machine/pio.h>
479c3fbfbdSAndreas Tobler #include <sys/rman.h>
489c3fbfbdSAndreas Tobler 
499c3fbfbdSAndreas Tobler #include <dev/iicbus/iicbus.h>
509c3fbfbdSAndreas Tobler #include <dev/iicbus/iiconf.h>
519c3fbfbdSAndreas Tobler #include <dev/ofw/ofw_bus.h>
529c3fbfbdSAndreas Tobler 
539c3fbfbdSAndreas Tobler #ifdef HAVE_KERNEL_OPTION_HEADERS
549c3fbfbdSAndreas Tobler #include "opt_snd.h"
559c3fbfbdSAndreas Tobler #endif
569c3fbfbdSAndreas Tobler 
579c3fbfbdSAndreas Tobler #include <dev/sound/pcm/sound.h>
589c3fbfbdSAndreas Tobler 
599c3fbfbdSAndreas Tobler #include "mixer_if.h"
609c3fbfbdSAndreas Tobler 
619c3fbfbdSAndreas Tobler extern kobj_class_t i2s_mixer_class;
629c3fbfbdSAndreas Tobler extern device_t	i2s_mixer;
639c3fbfbdSAndreas Tobler 
649c3fbfbdSAndreas Tobler struct onyx_softc
659c3fbfbdSAndreas Tobler {
669c3fbfbdSAndreas Tobler 	device_t sc_dev;
679c3fbfbdSAndreas Tobler 	uint32_t sc_addr;
689c3fbfbdSAndreas Tobler };
699c3fbfbdSAndreas Tobler 
709c3fbfbdSAndreas Tobler static int	onyx_probe(device_t);
719c3fbfbdSAndreas Tobler static int	onyx_attach(device_t);
729c3fbfbdSAndreas Tobler static int	onyx_init(struct snd_mixer *m);
739c3fbfbdSAndreas Tobler static int	onyx_uninit(struct snd_mixer *m);
749c3fbfbdSAndreas Tobler static int	onyx_reinit(struct snd_mixer *m);
759c3fbfbdSAndreas Tobler static int	onyx_set(struct snd_mixer *m, unsigned dev, unsigned left,
769c3fbfbdSAndreas Tobler 			    unsigned right);
779c3fbfbdSAndreas Tobler static u_int32_t	onyx_setrecsrc(struct snd_mixer *m, u_int32_t src);
789c3fbfbdSAndreas Tobler 
799c3fbfbdSAndreas Tobler static device_method_t onyx_methods[] = {
809c3fbfbdSAndreas Tobler 	/* Device interface. */
819c3fbfbdSAndreas Tobler 	DEVMETHOD(device_probe,		onyx_probe),
829c3fbfbdSAndreas Tobler 	DEVMETHOD(device_attach,	onyx_attach),
839c3fbfbdSAndreas Tobler 	{ 0, 0 }
849c3fbfbdSAndreas Tobler };
859c3fbfbdSAndreas Tobler 
869c3fbfbdSAndreas Tobler static driver_t onyx_driver = {
879c3fbfbdSAndreas Tobler 	"onyx",
889c3fbfbdSAndreas Tobler 	onyx_methods,
899c3fbfbdSAndreas Tobler 	sizeof(struct onyx_softc)
909c3fbfbdSAndreas Tobler };
919c3fbfbdSAndreas Tobler 
923390adfeSJohn Baldwin DRIVER_MODULE(onyx, iicbus, onyx_driver, 0, 0);
939c3fbfbdSAndreas Tobler MODULE_VERSION(onyx, 1);
949c3fbfbdSAndreas Tobler MODULE_DEPEND(onyx, iicbus, 1, 1, 1);
959c3fbfbdSAndreas Tobler 
969c3fbfbdSAndreas Tobler static kobj_method_t onyx_mixer_methods[] = {
979c3fbfbdSAndreas Tobler 	KOBJMETHOD(mixer_init,		onyx_init),
989c3fbfbdSAndreas Tobler 	KOBJMETHOD(mixer_uninit,	onyx_uninit),
999c3fbfbdSAndreas Tobler 	KOBJMETHOD(mixer_reinit,	onyx_reinit),
1009c3fbfbdSAndreas Tobler 	KOBJMETHOD(mixer_set,		onyx_set),
1019c3fbfbdSAndreas Tobler 	KOBJMETHOD(mixer_setrecsrc,	onyx_setrecsrc),
1029c3fbfbdSAndreas Tobler 	KOBJMETHOD_END
1039c3fbfbdSAndreas Tobler };
1049c3fbfbdSAndreas Tobler 
1059c3fbfbdSAndreas Tobler MIXER_DECLARE(onyx_mixer);
1069c3fbfbdSAndreas Tobler 
1079c3fbfbdSAndreas Tobler #define PCM3052_IICADDR	0x8C	/* Hard-coded I2C slave addr */
1089c3fbfbdSAndreas Tobler 
1099c3fbfbdSAndreas Tobler /*
1109c3fbfbdSAndreas Tobler  * PCM3052 registers.
1119c3fbfbdSAndreas Tobler  * Numbering in decimal as used in the data sheet.
1129c3fbfbdSAndreas Tobler  */
1139c3fbfbdSAndreas Tobler #define PCM3052_REG_LEFT_ATTN       65
1149c3fbfbdSAndreas Tobler #define PCM3052_REG_RIGHT_ATTN      66
1159c3fbfbdSAndreas Tobler #define PCM3052_REG_CONTROL         67
1169c3fbfbdSAndreas Tobler #define PCM3052_MRST                (1 << 7)
1179c3fbfbdSAndreas Tobler #define PCM3052_SRST                (1 << 6)
1189c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_CONTROL     68
1199c3fbfbdSAndreas Tobler #define PCM3052_OVR1                (1 << 6)
1209c3fbfbdSAndreas Tobler #define PCM3052_MUTE_L              (1 << 1)
1219c3fbfbdSAndreas Tobler #define PCM3052_MUTE_R              (1 << 0)
1229c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_DEEMPH      69
1239c3fbfbdSAndreas Tobler #define PCM3052_REG_DAC_FILTER      70
1249c3fbfbdSAndreas Tobler #define PCM3052_DAC_FILTER_ALWAYS   (1 << 2)
1259c3fbfbdSAndreas Tobler #define PCM3052_REG_OUT_PHASE       71
1269c3fbfbdSAndreas Tobler #define PCM3052_REG_ADC_CONTROL     72
1279c3fbfbdSAndreas Tobler #define PCM3052_REG_ADC_HPF_BP      75
1289c3fbfbdSAndreas Tobler #define PCM3052_HPF_ALWAYS          (1 << 2)
1299c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_1          77
1309c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_2          78
1319c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_3          79
1329c3fbfbdSAndreas Tobler #define PCM3052_REG_INFO_4          80
1339c3fbfbdSAndreas Tobler 
1349c3fbfbdSAndreas Tobler struct onyx_reg {
1359c3fbfbdSAndreas Tobler 	u_char LEFT_ATTN;
1369c3fbfbdSAndreas Tobler 	u_char RIGHT_ATTN;
1379c3fbfbdSAndreas Tobler 	u_char CONTROL;
1389c3fbfbdSAndreas Tobler 	u_char DAC_CONTROL;
1399c3fbfbdSAndreas Tobler 	u_char DAC_DEEMPH;
1409c3fbfbdSAndreas Tobler 	u_char DAC_FILTER;
1419c3fbfbdSAndreas Tobler 	u_char OUT_PHASE;
1429c3fbfbdSAndreas Tobler 	u_char ADC_CONTROL;
1439c3fbfbdSAndreas Tobler 	u_char ADC_HPF_BP;
1449c3fbfbdSAndreas Tobler 	u_char INFO_1;
1459c3fbfbdSAndreas Tobler 	u_char INFO_2;
1469c3fbfbdSAndreas Tobler 	u_char INFO_3;
1479c3fbfbdSAndreas Tobler 	u_char INFO_4;
1489c3fbfbdSAndreas Tobler };
1499c3fbfbdSAndreas Tobler 
1509c3fbfbdSAndreas Tobler static const struct onyx_reg onyx_initdata = {
1519c3fbfbdSAndreas Tobler 	0x80,				  /* LEFT_ATTN, Mute default */
1529c3fbfbdSAndreas Tobler 	0x80,				  /* RIGHT_ATTN, Mute default */
1539c3fbfbdSAndreas Tobler 	PCM3052_MRST | PCM3052_SRST,      /* CONTROL */
1549c3fbfbdSAndreas Tobler 	0,                                /* DAC_CONTROL */
1559c3fbfbdSAndreas Tobler 	0,				  /* DAC_DEEMPH */
1569c3fbfbdSAndreas Tobler 	PCM3052_DAC_FILTER_ALWAYS,	  /* DAC_FILTER */
1579c3fbfbdSAndreas Tobler 	0,				  /* OUT_PHASE */
1589c3fbfbdSAndreas Tobler 	(-1 /* dB */ + 8) & 0xf,          /* ADC_CONTROL */
1599c3fbfbdSAndreas Tobler 	PCM3052_HPF_ALWAYS,		  /* ADC_HPF_BP */
1609c3fbfbdSAndreas Tobler 	(1 << 2),			  /* INFO_1 */
1619c3fbfbdSAndreas Tobler 	2,				  /* INFO_2,  */
1629c3fbfbdSAndreas Tobler 	0,				  /* INFO_3, CLK 0 (level II),
1639c3fbfbdSAndreas Tobler 					     SF 0 (44.1 kHz) */
1649c3fbfbdSAndreas Tobler 	1				  /* INFO_4, VALIDL/R 0,
1659c3fbfbdSAndreas Tobler 					     WL 24-bit depth */
1669c3fbfbdSAndreas Tobler };
1679c3fbfbdSAndreas Tobler 
1689c3fbfbdSAndreas Tobler static int
onyx_write(struct onyx_softc * sc,uint8_t reg,const uint8_t value)1699c3fbfbdSAndreas Tobler onyx_write(struct onyx_softc *sc, uint8_t reg, const uint8_t value)
1709c3fbfbdSAndreas Tobler {
1719c3fbfbdSAndreas Tobler 	u_int size;
1729c3fbfbdSAndreas Tobler 	uint8_t buf[16];
1739c3fbfbdSAndreas Tobler 
1749c3fbfbdSAndreas Tobler 	struct iic_msg msg[] = {
1759c3fbfbdSAndreas Tobler 		{ sc->sc_addr, IIC_M_WR, 0, buf }
1769c3fbfbdSAndreas Tobler 	};
1779c3fbfbdSAndreas Tobler 
1789c3fbfbdSAndreas Tobler 	size = 1;
1799c3fbfbdSAndreas Tobler 	msg[0].len = size + 1;
1809c3fbfbdSAndreas Tobler 	buf[0] = reg;
1819c3fbfbdSAndreas Tobler 	buf[1] = value;
1829c3fbfbdSAndreas Tobler 
1839c3fbfbdSAndreas Tobler 	iicbus_transfer(sc->sc_dev, msg, 1);
1849c3fbfbdSAndreas Tobler 
1859c3fbfbdSAndreas Tobler 	return (0);
1869c3fbfbdSAndreas Tobler }
1879c3fbfbdSAndreas Tobler 
1889c3fbfbdSAndreas Tobler static int
onyx_probe(device_t dev)1899c3fbfbdSAndreas Tobler onyx_probe(device_t dev)
1909c3fbfbdSAndreas Tobler {
1919c3fbfbdSAndreas Tobler 	const char *name, *compat;
1929c3fbfbdSAndreas Tobler 
1939c3fbfbdSAndreas Tobler 	name = ofw_bus_get_name(dev);
1949c3fbfbdSAndreas Tobler 	if (name == NULL)
1959c3fbfbdSAndreas Tobler 		return (ENXIO);
1969c3fbfbdSAndreas Tobler 
1979c3fbfbdSAndreas Tobler 	if (strcmp(name, "codec") == 0) {
1989c3fbfbdSAndreas Tobler 		if (iicbus_get_addr(dev) != PCM3052_IICADDR)
1999c3fbfbdSAndreas Tobler 			return (ENXIO);
2009c3fbfbdSAndreas Tobler 		compat = ofw_bus_get_compat(dev);
2019c3fbfbdSAndreas Tobler 		if (compat == NULL || strcmp(compat, "pcm3052") != 0)
2029c3fbfbdSAndreas Tobler 			return (ENXIO);
2039c3fbfbdSAndreas Tobler 	} else
2049c3fbfbdSAndreas Tobler 		return (ENXIO);
2059c3fbfbdSAndreas Tobler 
2069c3fbfbdSAndreas Tobler 	device_set_desc(dev, "Texas Instruments PCM3052 Audio Codec");
2079c3fbfbdSAndreas Tobler 	return (0);
2089c3fbfbdSAndreas Tobler }
2099c3fbfbdSAndreas Tobler 
2109c3fbfbdSAndreas Tobler static int
onyx_attach(device_t dev)2119c3fbfbdSAndreas Tobler onyx_attach(device_t dev)
2129c3fbfbdSAndreas Tobler {
2139c3fbfbdSAndreas Tobler 	struct onyx_softc *sc;
2149c3fbfbdSAndreas Tobler 
2159c3fbfbdSAndreas Tobler 	sc = device_get_softc(dev);
2169c3fbfbdSAndreas Tobler 	sc->sc_dev = dev;
2179c3fbfbdSAndreas Tobler 	sc->sc_addr = iicbus_get_addr(dev);
2189c3fbfbdSAndreas Tobler 
2199c3fbfbdSAndreas Tobler 	i2s_mixer_class = &onyx_mixer_class;
2209c3fbfbdSAndreas Tobler 	i2s_mixer = dev;
2219c3fbfbdSAndreas Tobler 
2229c3fbfbdSAndreas Tobler 	return (0);
2239c3fbfbdSAndreas Tobler }
2249c3fbfbdSAndreas Tobler 
2259c3fbfbdSAndreas Tobler static int
onyx_init(struct snd_mixer * m)2269c3fbfbdSAndreas Tobler onyx_init(struct snd_mixer *m)
2279c3fbfbdSAndreas Tobler {
2289c3fbfbdSAndreas Tobler 	struct onyx_softc *sc;
2299c3fbfbdSAndreas Tobler 	u_int  x = 0;
2309c3fbfbdSAndreas Tobler 
2319c3fbfbdSAndreas Tobler 	sc = device_get_softc(mix_getdevinfo(m));
2329c3fbfbdSAndreas Tobler 
2339c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_LEFT_ATTN, onyx_initdata.LEFT_ATTN);
2349c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_RIGHT_ATTN, onyx_initdata.RIGHT_ATTN);
2359c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_CONTROL, onyx_initdata.CONTROL);
2369c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_DAC_CONTROL,
2379c3fbfbdSAndreas Tobler 		      onyx_initdata.DAC_CONTROL);
2389c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_DAC_DEEMPH, onyx_initdata.DAC_DEEMPH);
2399c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_DAC_FILTER, onyx_initdata.DAC_FILTER);
2409c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_OUT_PHASE, onyx_initdata.OUT_PHASE);
2419c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_ADC_CONTROL,
2429c3fbfbdSAndreas Tobler 		      onyx_initdata.ADC_CONTROL);
2439c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_ADC_HPF_BP, onyx_initdata.ADC_HPF_BP);
2449c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_INFO_1, onyx_initdata.INFO_1);
2459c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_INFO_2, onyx_initdata.INFO_2);
2469c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_INFO_3, onyx_initdata.INFO_3);
2479c3fbfbdSAndreas Tobler 	onyx_write(sc, PCM3052_REG_INFO_4, onyx_initdata.INFO_4);
2489c3fbfbdSAndreas Tobler 
2499c3fbfbdSAndreas Tobler 	x |= SOUND_MASK_VOLUME;
2509c3fbfbdSAndreas Tobler 	mix_setdevs(m, x);
2519c3fbfbdSAndreas Tobler 
2529c3fbfbdSAndreas Tobler 	return (0);
2539c3fbfbdSAndreas Tobler }
2549c3fbfbdSAndreas Tobler 
2559c3fbfbdSAndreas Tobler static int
onyx_uninit(struct snd_mixer * m)2569c3fbfbdSAndreas Tobler onyx_uninit(struct snd_mixer *m)
2579c3fbfbdSAndreas Tobler {
2589c3fbfbdSAndreas Tobler 	return (0);
2599c3fbfbdSAndreas Tobler }
2609c3fbfbdSAndreas Tobler 
2619c3fbfbdSAndreas Tobler static int
onyx_reinit(struct snd_mixer * m)2629c3fbfbdSAndreas Tobler onyx_reinit(struct snd_mixer *m)
2639c3fbfbdSAndreas Tobler {
2649c3fbfbdSAndreas Tobler 	return (0);
2659c3fbfbdSAndreas Tobler }
2669c3fbfbdSAndreas Tobler 
2679c3fbfbdSAndreas Tobler static int
onyx_set(struct snd_mixer * m,unsigned dev,unsigned left,unsigned right)2689c3fbfbdSAndreas Tobler onyx_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
2699c3fbfbdSAndreas Tobler {
2709c3fbfbdSAndreas Tobler 	struct onyx_softc *sc;
2719c3fbfbdSAndreas Tobler 	struct mtx *mixer_lock;
2729c3fbfbdSAndreas Tobler 	int locked;
2739c3fbfbdSAndreas Tobler 	uint8_t l, r;
2749c3fbfbdSAndreas Tobler 
2759c3fbfbdSAndreas Tobler 	sc = device_get_softc(mix_getdevinfo(m));
2769c3fbfbdSAndreas Tobler 	mixer_lock = mixer_get_lock(m);
2779c3fbfbdSAndreas Tobler 	locked = mtx_owned(mixer_lock);
2789c3fbfbdSAndreas Tobler 
2799c3fbfbdSAndreas Tobler 	switch (dev) {
2809c3fbfbdSAndreas Tobler 	case SOUND_MIXER_VOLUME:
2819c3fbfbdSAndreas Tobler 
2829c3fbfbdSAndreas Tobler 		/*
2839c3fbfbdSAndreas Tobler 		 * We need to unlock the mixer lock because iicbus_transfer()
2849c3fbfbdSAndreas Tobler 		 * may sleep. The mixer lock itself is unnecessary here
2859c3fbfbdSAndreas Tobler 		 * because it is meant to serialize hardware access, which
2869c3fbfbdSAndreas Tobler 		 * is taken care of by the I2C layer, so this is safe.
2879c3fbfbdSAndreas Tobler 		 */
2889c3fbfbdSAndreas Tobler 		if (left > 100 || right > 100)
2899c3fbfbdSAndreas Tobler 			return (0);
2909c3fbfbdSAndreas Tobler 
2919c3fbfbdSAndreas Tobler 		l = left + 128;
2929c3fbfbdSAndreas Tobler 		r = right + 128;
2939c3fbfbdSAndreas Tobler 
2949c3fbfbdSAndreas Tobler 		if (locked)
2959c3fbfbdSAndreas Tobler 			mtx_unlock(mixer_lock);
2969c3fbfbdSAndreas Tobler 
2979c3fbfbdSAndreas Tobler 		onyx_write(sc, PCM3052_REG_LEFT_ATTN, l);
2989c3fbfbdSAndreas Tobler 		onyx_write(sc, PCM3052_REG_RIGHT_ATTN, r);
2999c3fbfbdSAndreas Tobler 
3009c3fbfbdSAndreas Tobler 		if (locked)
3019c3fbfbdSAndreas Tobler 			mtx_lock(mixer_lock);
3029c3fbfbdSAndreas Tobler 
3039c3fbfbdSAndreas Tobler 		return (left | (right << 8));
3049c3fbfbdSAndreas Tobler 	}
3059c3fbfbdSAndreas Tobler 
3069c3fbfbdSAndreas Tobler 	return (0);
3079c3fbfbdSAndreas Tobler }
3089c3fbfbdSAndreas Tobler 
3099c3fbfbdSAndreas Tobler static u_int32_t
onyx_setrecsrc(struct snd_mixer * m,u_int32_t src)3109c3fbfbdSAndreas Tobler onyx_setrecsrc(struct snd_mixer *m, u_int32_t src)
3119c3fbfbdSAndreas Tobler {
3129c3fbfbdSAndreas Tobler 	return (0);
3139c3fbfbdSAndreas Tobler }
314