diff -u -r src_bak/sys/dev/sound/pci/hda/hda_reg.h src/sys/dev/sound/pci/hda/hda_reg.h --- src_bak/sys/dev/sound/pci/hda/hda_reg.h 2010-01-12 18:19:46.981930017 +0100 +++ src/sys/dev/sound/pci/hda/hda_reg.h 2010-01-12 18:40:39.517316619 +0100 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/sound/pci/hda/hda_reg.h,v 1.3.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $ + * $FreeBSD$ */ #ifndef _HDA_REG_H_ @@ -660,13 +660,49 @@ #define HDA_CMD_VERB_GET_STRIPE_CONTROL 0xf24 #define HDA_CMD_VERB_SET_STRIPE_CONTROL 0x724 -#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid) \ +#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid) \ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_GET_STRIPE_CONTROL, 0x0)) -#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid, payload) \ +#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid, payload) \ (HDA_CMD_12BIT((cad), (nid), \ HDA_CMD_VERB_SET_STRIPE_CONTROL, (payload))) +/* Channel Count Control */ +#define HDA_CMD_VERB_GET_CONV_CHAN_COUNT 0xf2d +#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT 0x72d + +#define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid) \ + (HDA_CMD_12BIT((cad), (nid), \ + HDA_CMD_VERB_GET_CONV_CHAN_COUNT, 0x0)) +#define HDA_CMD_SET_CONV_CHAN_COUNT(cad, nid, payload) \ + (HDA_CMD_12BIT((cad), (nid), \ + HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload))) + +#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE 0xf2e +#define HDA_CMD_VERB_GET_HDMI_ELDD 0xf2f + +#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX 0xf30 +#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX 0x730 + +#define HDA_CMD_VERB_GET_HDMI_DIP_DATA 0xf31 +#define HDA_CMD_VERB_SET_HDMI_DIP_DATA 0x731 + +#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT 0xf32 +#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT 0x732 + +#define HDA_CMD_VERB_GET_HDMI_CP_CTRL 0xf33 +#define HDA_CMD_VERB_SET_HDMI_CP_CTRL 0x733 + +#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT 0xf34 +#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT 0x734 + +#define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid) \ + (HDA_CMD_12BIT((cad), (nid), \ + HDA_CMD_VERB_GET_HDMI_CHAN_SLOT, 0x0)) +#define HDA_CMD_SET_HDMI_CHAN_SLOT(cad, nid, payload) \ + (HDA_CMD_12BIT((cad), (nid), \ + HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload))) + /* Function Reset */ #define HDA_CMD_VERB_FUNCTION_RESET 0x7ff @@ -779,6 +815,10 @@ #define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT 20 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK 0x000f0000 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT 16 +#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK 0x0000e000 +#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT 13 +#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK 0x00001000 +#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT 12 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK 0x00000800 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT 11 #define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK 0x00000400 @@ -810,6 +850,14 @@ #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY(param) \ (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK) >> \ HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT) +#define HDA_PARAM_AUDIO_WIDGET_CAP_CC(param) \ + ((((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK) >> \ + (HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT - 1)) | \ + (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >> \ + HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT)) +#define HDA_PARAM_AUDIO_WIDGET_CAP_CP(param) \ + (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK) >> \ + HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT) #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(param) \ (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK) >> \ HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT) @@ -971,6 +1019,10 @@ /* Pin Capabilities */ #define HDA_PARAM_PIN_CAP 0x0c +#define HDA_PARAM_PIN_CAP_HBR_MASK 0x08000000 +#define HDA_PARAM_PIN_CAP_HBR_SHIFT 27 +#define HDA_PARAM_PIN_CAP_DP_MASK 0x01000000 +#define HDA_PARAM_PIN_CAP_DP_SHIFT 24 #define HDA_PARAM_PIN_CAP_EAPD_CAP_MASK 0x00010000 #define HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT 16 #define HDA_PARAM_PIN_CAP_VREF_CTRL_MASK 0x0000ff00 @@ -985,6 +1037,8 @@ #define HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT 9 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK 0x00000100 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT 8 +#define HDA_PARAM_PIN_CAP_HDMI_MASK 0x00000080 +#define HDA_PARAM_PIN_CAP_HDMI_SHIFT 7 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK 0x00000040 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT 6 #define HDA_PARAM_PIN_CAP_INPUT_CAP_MASK 0x00000020 @@ -1000,6 +1054,12 @@ #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK 0x00000001 #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT 0 +#define HDA_PARAM_PIN_CAP_HBR(param) \ + (((param) & HDA_PARAM_PIN_CAP_HBR_MASK) >> \ + HDA_PARAM_PIN_CAP_HBR_SHIFT) +#define HDA_PARAM_PIN_CAP_DP(param) \ + (((param) & HDA_PARAM_PIN_CAP_DP_MASK) >> \ + HDA_PARAM_PIN_CAP_DP_SHIFT) #define HDA_PARAM_PIN_CAP_EAPD_CAP(param) \ (((param) & HDA_PARAM_PIN_CAP_EAPD_CAP_MASK) >> \ HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT) @@ -1021,6 +1081,9 @@ #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(param) \ (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK) >> \ HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT) +#define HDA_PARAM_PIN_CAP_HDMI(param) \ + (((param) & HDA_PARAM_PIN_CAP_HDMI_MASK) >> \ + HDA_PARAM_PIN_CAP_HDMI_SHIFT) #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(param) \ (((param) & HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK) >> \ HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT) diff -u -r src_bak/sys/dev/sound/pci/hda/hdac.c src/sys/dev/sound/pci/hda/hdac.c --- src_bak/sys/dev/sound/pci/hda/hdac.c 2010-01-12 18:19:46.980930169 +0100 +++ src/sys/dev/sound/pci/hda/hdac.c 2010-01-12 18:40:26.054257767 +0100 @@ -38,7 +38,6 @@ * 2) HDA Codecs support, which may include * - HDA * - Modem - * - HDMI * 3) Widget parser - the real magic of why this driver works on so * many hardwares with minimal vendor specific quirk. The original * parser was written using Ruby and can be found at @@ -87,9 +86,9 @@ #include "mixer_if.h" -#define HDA_DRV_TEST_REV "20090624_0136" +#define HDA_DRV_TEST_REV "20100112_0140" -SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pci/hda/hdac.c,v 1.109.2.2.2.1 2009/10/25 01:10:29 kensmith Exp $"); +SND_DECLARE_FILE("$FreeBSD$"); #define HDA_BOOTVERBOSE(stmt) do { \ if (bootverbose != 0 || snd_verbose > 3) { \ @@ -146,7 +145,8 @@ #define HDA_INTEL_82801G HDA_MODEL_CONSTRUCT(INTEL, 0x27d8) #define HDA_INTEL_82801H HDA_MODEL_CONSTRUCT(INTEL, 0x284b) #define HDA_INTEL_82801I HDA_MODEL_CONSTRUCT(INTEL, 0x293e) -#define HDA_INTEL_82801J HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e) +#define HDA_INTEL_82801JI HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e) +#define HDA_INTEL_82801JD HDA_MODEL_CONSTRUCT(INTEL, 0x3a6e) #define HDA_INTEL_PCH HDA_MODEL_CONSTRUCT(INTEL, 0x3b56) #define HDA_INTEL_SCH HDA_MODEL_CONSTRUCT(INTEL, 0x811b) #define HDA_INTEL_ALL HDA_MODEL_CONSTRUCT(INTEL, 0xffff) @@ -171,6 +171,10 @@ #define HDA_NVIDIA_MCP79_2 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac1) #define HDA_NVIDIA_MCP79_3 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac2) #define HDA_NVIDIA_MCP79_4 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac3) +#define HDA_NVIDIA_MCP89_1 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d94) +#define HDA_NVIDIA_MCP89_2 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d95) +#define HDA_NVIDIA_MCP89_3 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d96) +#define HDA_NVIDIA_MCP89_4 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d97) #define HDA_NVIDIA_ALL HDA_MODEL_CONSTRUCT(NVIDIA, 0xffff) /* ATI */ @@ -311,6 +315,7 @@ * (see HDA_CODEC_STAC9221 below). */ #define APPLE_INTEL_MAC 0x76808384 +#define APPLE_MACBOOKPRO55 0xcb7910de /* LG Electronics */ #define LG_VENDORID 0x1854 @@ -486,7 +491,8 @@ { HDA_INTEL_82801G, "Intel 82801G", 0 }, { HDA_INTEL_82801H, "Intel 82801H", 0 }, { HDA_INTEL_82801I, "Intel 82801I", 0 }, - { HDA_INTEL_82801J, "Intel 82801J", 0 }, + { HDA_INTEL_82801JI, "Intel 82801JI", 0 }, + { HDA_INTEL_82801JD, "Intel 82801JD", 0 }, { HDA_INTEL_PCH, "Intel PCH", 0 }, { HDA_INTEL_SCH, "Intel SCH", 0 }, { HDA_NVIDIA_MCP51, "NVidia MCP51", HDAC_NO_MSI }, @@ -507,6 +513,10 @@ { HDA_NVIDIA_MCP79_2, "NVidia MCP79", 0 }, { HDA_NVIDIA_MCP79_3, "NVidia MCP79", 0 }, { HDA_NVIDIA_MCP79_4, "NVidia MCP79", 0 }, + { HDA_NVIDIA_MCP89_1, "NVidia MCP89", 0 }, + { HDA_NVIDIA_MCP89_2, "NVidia MCP89", 0 }, + { HDA_NVIDIA_MCP89_3, "NVidia MCP89", 0 }, + { HDA_NVIDIA_MCP89_4, "NVidia MCP89", 0 }, { HDA_ATI_SB450, "ATI SB450", 0 }, { HDA_ATI_SB600, "ATI SB600", 0 }, { HDA_ATI_RS600, "ATI RS600", 0 }, @@ -596,6 +606,12 @@ #define HDA_CODEC_CONSTRUCT(vendor, id) \ (((uint32_t)(vendor##_VENDORID) << 16) | ((id) & 0xffff)) +/* Cirrus Logic */ +#define CIRRUSLOGIC_VENDORID 0x1013 +#define HDA_CODEC_CS4206 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4206) +#define HDA_CODEC_CS4207 HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4207) +#define HDA_CODEC_CSXXXX HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0xffff) + /* Realtek */ #define REALTEK_VENDORID 0x10ec #define HDA_CODEC_ALC260 HDA_CODEC_CONSTRUCT(REALTEK, 0x0260) @@ -613,6 +629,7 @@ #define HDA_CODEC_ALC882 HDA_CODEC_CONSTRUCT(REALTEK, 0x0882) #define HDA_CODEC_ALC883 HDA_CODEC_CONSTRUCT(REALTEK, 0x0883) #define HDA_CODEC_ALC885 HDA_CODEC_CONSTRUCT(REALTEK, 0x0885) +#define HDA_CODEC_ALC887 HDA_CODEC_CONSTRUCT(REALTEK, 0x0887) #define HDA_CODEC_ALC888 HDA_CODEC_CONSTRUCT(REALTEK, 0x0888) #define HDA_CODEC_ALC889 HDA_CODEC_CONSTRUCT(REALTEK, 0x0889) #define HDA_CODEC_ALCXXXX HDA_CODEC_CONSTRUCT(REALTEK, 0xffff) @@ -667,7 +684,9 @@ #define HDA_CODEC_IDT92HD700D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7639) #define HDA_CODEC_IDT92HD206X HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7645) #define HDA_CODEC_IDT92HD206D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7646) +#define HDA_CODEC_CXD9872RDK HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7661) #define HDA_CODEC_STAC9872AK HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7662) +#define HDA_CODEC_CXD9872AKD HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7664) #define HDA_CODEC_STAC9221 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7680) #define HDA_CODEC_STAC922XD HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7681) #define HDA_CODEC_STAC9221_A2 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7682) @@ -715,6 +734,7 @@ #define HDA_CODEC_CX20549 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5045) #define HDA_CODEC_CX20551 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047) #define HDA_CODEC_CX20561 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051) +#define HDA_CODEC_CX20582 HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066) #define HDA_CODEC_CXXXXX HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff) /* VIA */ @@ -754,6 +774,16 @@ #define HDA_CODEC_VT1702_5 HDA_CODEC_CONSTRUCT(VIA, 0x5398) #define HDA_CODEC_VT1702_6 HDA_CODEC_CONSTRUCT(VIA, 0x6398) #define HDA_CODEC_VT1702_7 HDA_CODEC_CONSTRUCT(VIA, 0x7398) +#define HDA_CODEC_VT1716S_0 HDA_CODEC_CONSTRUCT(VIA, 0x0433) +#define HDA_CODEC_VT1716S_1 HDA_CODEC_CONSTRUCT(VIA, 0xa721) +#define HDA_CODEC_VT1718S_0 HDA_CODEC_CONSTRUCT(VIA, 0x0428) +#define HDA_CODEC_VT1718S_1 HDA_CODEC_CONSTRUCT(VIA, 0x4428) +#define HDA_CODEC_VT1812 HDA_CODEC_CONSTRUCT(VIA, 0x0448) +#define HDA_CODEC_VT1818S HDA_CODEC_CONSTRUCT(VIA, 0x0440) +#define HDA_CODEC_VT1828S HDA_CODEC_CONSTRUCT(VIA, 0x4441) +#define HDA_CODEC_VT2002P_0 HDA_CODEC_CONSTRUCT(VIA, 0x0438) +#define HDA_CODEC_VT2002P_1 HDA_CODEC_CONSTRUCT(VIA, 0x4438) +#define HDA_CODEC_VT2020 HDA_CODEC_CONSTRUCT(VIA, 0x0441) #define HDA_CODEC_VTXXXX HDA_CODEC_CONSTRUCT(VIA, 0xffff) /* ATI */ @@ -776,6 +806,7 @@ #define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802) #define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803) #define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb) +#define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054) #define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff) /* Codecs */ @@ -783,6 +814,8 @@ uint32_t id; char *name; } hdac_codecs[] = { + { HDA_CODEC_CS4206, "Cirrus Logic CS4206" }, + { HDA_CODEC_CS4207, "Cirrus Logic CS4207" }, { HDA_CODEC_ALC260, "Realtek ALC260" }, { HDA_CODEC_ALC262, "Realtek ALC262" }, { HDA_CODEC_ALC267, "Realtek ALC267" }, @@ -798,6 +831,7 @@ { HDA_CODEC_ALC882, "Realtek ALC882" }, { HDA_CODEC_ALC883, "Realtek ALC883" }, { HDA_CODEC_ALC885, "Realtek ALC885" }, + { HDA_CODEC_ALC887, "Realtek ALC887" }, { HDA_CODEC_ALC888, "Realtek ALC888" }, { HDA_CODEC_ALC889, "Realtek ALC889" }, { HDA_CODEC_AD1882, "Analog Devices AD1882" }, @@ -816,6 +850,8 @@ { HDA_CODEC_AD1988B, "Analog Devices AD1988B" }, { HDA_CODEC_AD1989B, "Analog Devices AD1989B" }, { HDA_CODEC_CMI9880, "CMedia CMI9880" }, + { HDA_CODEC_CXD9872RDK, "Sigmatel CXD9872RD/K" }, + { HDA_CODEC_CXD9872AKD, "Sigmatel CXD9872AKD" }, { HDA_CODEC_STAC9200D, "Sigmatel STAC9200D" }, { HDA_CODEC_STAC9204X, "Sigmatel STAC9204X" }, { HDA_CODEC_STAC9204D, "Sigmatel STAC9204D" }, @@ -870,6 +906,7 @@ { HDA_CODEC_CX20549, "Conexant CX20549 (Venice)" }, { HDA_CODEC_CX20551, "Conexant CX20551 (Waikiki)" }, { HDA_CODEC_CX20561, "Conexant CX20561 (Hermosa)" }, + { HDA_CODEC_CX20582, "Conexant CX20582 (Pebble)" }, { HDA_CODEC_VT1708_8, "VIA VT1708_8" }, { HDA_CODEC_VT1708_9, "VIA VT1708_9" }, { HDA_CODEC_VT1708_A, "VIA VT1708_A" }, @@ -906,6 +943,16 @@ { HDA_CODEC_VT1702_5, "VIA VT1702_5" }, { HDA_CODEC_VT1702_6, "VIA VT1702_6" }, { HDA_CODEC_VT1702_7, "VIA VT1702_7" }, + { HDA_CODEC_VT1716S_0, "VIA VT1716S_0" }, + { HDA_CODEC_VT1716S_1, "VIA VT1716S_1" }, + { HDA_CODEC_VT1718S_0, "VIA VT1718S_0" }, + { HDA_CODEC_VT1718S_1, "VIA VT1718S_1" }, + { HDA_CODEC_VT1812, "VIA VT1812" }, + { HDA_CODEC_VT1818S, "VIA VT1818S" }, + { HDA_CODEC_VT1828S, "VIA VT1828S" }, + { HDA_CODEC_VT2002P_0, "VIA VT2002P_0" }, + { HDA_CODEC_VT2002P_1, "VIA VT2002P_1" }, + { HDA_CODEC_VT2020, "VIA VT2020" }, { HDA_CODEC_ATIRS600_1,"ATI RS600 HDMI" }, { HDA_CODEC_ATIRS600_2,"ATI RS600 HDMI" }, { HDA_CODEC_ATIRS690, "ATI RS690/780 HDMI" }, @@ -919,11 +966,13 @@ { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" }, { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" }, { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" }, + { HDA_CODEC_INTELQ57, "Intel Q57 HDMI" }, { HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" }, { HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" }, /* Unknown codec */ { HDA_CODEC_ALCXXXX, "Realtek (Unknown)" }, { HDA_CODEC_ADXXXX, "Analog Devices (Unknown)" }, + { HDA_CODEC_CSXXXX, "Cirrus Logic (Unknown)" }, { HDA_CODEC_CMIXXXX, "CMedia (Unknown)" }, { HDA_CODEC_STACXXXX, "Sigmatel (Unknown)" }, { HDA_CODEC_SIIXXXX, "Silicon Image (Unknown)" }, @@ -1520,7 +1569,7 @@ sc->num_iss = HDAC_GCAP_ISS(gcap); sc->num_oss = HDAC_GCAP_OSS(gcap); sc->num_bss = HDAC_GCAP_BSS(gcap); - + sc->num_sdo = HDAC_GCAP_NSDO(gcap); sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK); corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE); @@ -1555,11 +1604,12 @@ return (ENXIO); } - HDA_BOOTHVERBOSE( - device_printf(sc->dev, " CORB size: %d\n", sc->corb_size); - device_printf(sc->dev, " RIRB size: %d\n", sc->rirb_size); - device_printf(sc->dev, " Streams: ISS=%d OSS=%d BSS=%d\n", - sc->num_iss, sc->num_oss, sc->num_bss); + HDA_BOOTVERBOSE( + device_printf(sc->dev, "Caps: OSS %d, ISS %d, BSS %d, " + "NSDO %d%s, CORB %d, RIRB %d\n", + sc->num_oss, sc->num_iss, sc->num_bss, 1 << sc->num_sdo, + sc->support_64bit ? ", 64bit" : "", + sc->corb_size, sc->rirb_size); ); return (0); @@ -3405,7 +3455,11 @@ int i, chn, totalchn, c; nid_t cad = ch->devinfo->codec->cad; uint16_t fmt, dfmt; + uint16_t chmap[2][5] = {{ 0x0010, 0x0001, 0x0201, 0x0231, 0x0231 }, /* 5.1 */ + { 0x0010, 0x0001, 0x2001, 0x2031, 0x2431 }};/* 7.1 */ + int map = -1; + totalchn = AFMT_CHANNEL(ch->fmt); HDA_BOOTHVERBOSE( device_printf(ch->pdevinfo->dev, "PCMDIR_%s: Stream setup fmt=%08x speed=%d\n", @@ -3419,7 +3473,6 @@ fmt |= ch->bit32 << 4; else fmt |= 1 << 4; - for (i = 0; i < HDA_RATE_TAB_LEN; i++) { if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) { fmt |= hda_rate_tab[i].base; @@ -3428,10 +3481,13 @@ break; } } + fmt |= (totalchn - 1); - totalchn = AFMT_CHANNEL(ch->fmt); - if (totalchn > 1) - fmt |= 1; + /* Set channel mapping for known speaker setups. */ + if (as->pinset == 0x0007 || as->pinset == 0x0013) /* Standard 5.1 */ + map = 0; + else if (as->pinset == 0x0017) /* Standard 7.1 */ + map = 1; HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDFMT, fmt); @@ -3445,14 +3501,26 @@ if (w == NULL) continue; - if (as->hpredir >= 0 && i == as->pincnt) - chn = 0; + /* If HP redirection is enabled, but failed to use same + DAC, make last DAC to duplicate first one. */ + if (as->hpredir >= 0 && i == as->pincnt) { + c = (ch->sid << 4); + } else { + if (map >= 0) /* Map known speaker setups. */ + chn = (((chmap[map][totalchn / 2] >> i * 4) & + 0xf) - 1) * 2; + if (chn < 0 || chn >= totalchn) { + c = 0; + } else { + c = (ch->sid << 4) | chn; + } + } HDA_BOOTHVERBOSE( device_printf(ch->pdevinfo->dev, "PCMDIR_%s: Stream setup nid=%d: " - "fmt=0x%04x, dfmt=0x%04x\n", + "fmt=0x%04x, dfmt=0x%04x, chan=0x%04x\n", (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", - ch->io[i], fmt, dfmt); + ch->io[i], fmt, dfmt, c); ); hdac_command(sc, HDA_CMD_SET_CONV_FMT(cad, ch->io[i], fmt), cad); @@ -3461,25 +3529,46 @@ HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, ch->io[i], dfmt), cad); } - /* If HP redirection is enabled, but failed to use same - DAC make last DAC one to duplicate first one. */ - if (as->hpredir >= 0 && i == as->pincnt) { - c = (ch->sid << 4); - } else if (chn >= totalchn) { - /* This is until OSS will support multichannel. - Should be: c = 0; to disable unused DAC */ - c = (ch->sid << 4); - }else { - c = (ch->sid << 4) | chn; - } hdac_command(sc, HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], c), cad); - chn += - HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap) ? - 2 : 1; +#if 0 + hdac_command(sc, + HDA_CMD_SET_CONV_CHAN_COUNT(cad, ch->io[i], 1), cad); + hdac_command(sc, + HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x00), cad); + hdac_command(sc, + HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x11), cad); +#endif + chn += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1; } } +/* + * Greatest Common Divisor. + */ +static unsigned +gcd(unsigned a, unsigned b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static unsigned +lcm(unsigned a, unsigned b) +{ + + return ((a * b) / gcd(a, b)); +} + static int hdac_channel_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) @@ -3487,7 +3576,7 @@ struct hdac_chan *ch = data; struct hdac_softc *sc = ch->devinfo->codec->sc; - blksz &= HDA_BLK_ALIGN; + blksz -= blksz % lcm(HDAC_DMA_ALIGNMENT, sndbuf_getalign(ch->b)); if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN)) blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN; @@ -4481,7 +4570,7 @@ for (i = 0; i < max; i++) { as[i].hpredir = -1; as[i].chan = -1; - as[i].digital = 1; + as[i].digital = 0; } /* Scan associations skipping as=0. */ @@ -4536,8 +4625,14 @@ __func__, w->nid, j); as[cnt].enable = 0; } - if (!HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) - as[cnt].digital = 0; + if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) { + if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap)) + as[cnt].digital = 3; + else if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap)) + as[cnt].digital = 2; + else + as[cnt].digital = 1; + } /* Headphones with seq=15 may mean redirection. */ if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT && seq == 15) @@ -4619,6 +4714,8 @@ HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0}, { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0 }, + { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, + HDA_QUIRK_GPIO1 | HDA_QUIRK_GPIO3, 0 }, { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_QUIRK_GPIO0, 0 }, { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, @@ -6370,7 +6467,8 @@ struct hdac_audio_as *as = devinfo->function.audio.as; struct hdac_widget *w; uint32_t cap, fmtcap, pcmcap; - int i, j, ret, max; + int i, j, ret, channels, onlystereo; + uint16_t pinset; ch->caps = hdac_caps; ch->caps.fmtlist = ch->fmtlist; @@ -6380,11 +6478,13 @@ ch->pcmrates[1] = 0; ret = 0; + channels = 0; + onlystereo = 1; + pinset = 0; fmtcap = devinfo->function.audio.supp_stream_formats; pcmcap = devinfo->function.audio.supp_pcm_size_rate; - max = (sizeof(ch->io) / sizeof(ch->io[0])) - 1; - for (i = 0; i < 16 && ret < max; i++) { + for (i = 0; i < 16; i++) { /* Check as is correct */ if (ch->as < 0) break; @@ -6402,15 +6502,11 @@ w = hdac_widget_get(devinfo, as[ch->as].dacs[i]); if (w == NULL || w->enable == 0) continue; - if (!HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap)) - continue; cap = w->param.supp_stream_formats; - /*if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap)) { - }*/ if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap) && !HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap)) continue; - /* Many codec does not declare AC3 support on SPDIF. + /* Many CODECs does not declare AC3 support on SPDIF. I don't beleave that they doesn't support it! */ if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) cap |= HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK; @@ -6422,9 +6518,24 @@ pcmcap &= w->param.supp_pcm_size_rate; } ch->io[ret++] = as[ch->as].dacs[i]; + /* Do not count redirection pin/dac channels. */ + if (i == 15 && as[ch->as].hpredir >= 0) + continue; + channels += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1; + if (HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) != 1) + onlystereo = 0; + pinset |= (1 << i); } ch->io[ret] = -1; + if (as[ch->as].fakeredir) + ret--; + /* Standard speaks only about stereo pins and playback, ... */ + if ((!onlystereo) || as[ch->as].dir != HDA_CTL_OUT) + pinset = 0; + /* ..., but there it gives us info about speakers layout. */ + as[ch->as].pinset = pinset; + ch->supp_stream_formats = fmtcap; ch->supp_pcm_size_rate = pcmcap; @@ -6448,17 +6559,34 @@ ch->bit32 = 3; else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap)) ch->bit32 = 2; - if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO)) - ch->fmtlist[i++] = - SND_FORMAT(AFMT_S16_LE, 1, 0); - ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0); - if (ch->bit32 > 0) { - if (!(devinfo->function.audio.quirks & - HDA_QUIRK_FORCESTEREO)) - ch->fmtlist[i++] = - SND_FORMAT(AFMT_S32_LE, 1, 0); - ch->fmtlist[i++] = - SND_FORMAT(AFMT_S32_LE, 2, 0); + if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO)) { + ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 1, 0); + if (ch->bit32) + ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 1, 0); + } + if (channels >= 2) { + ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0); + if (ch->bit32) + ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 2, 0); + } + if (channels == 4 || /* Any 4-channel */ + pinset == 0x0007 || /* 5.1 */ + pinset == 0x0013 || /* 5.1 */ + pinset == 0x0017) { /* 7.1 */ + ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 0); + if (ch->bit32) + ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 0); + } + if (channels == 6 || /* Any 6-channel */ + pinset == 0x0017) { /* 7.1 */ + ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 1); + if (ch->bit32) + ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 1); + } + if (channels == 8) { /* Any 8-channel */ + ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 8, 1); + if (ch->bit32) + ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 8, 1); } } if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(fmtcap)) { @@ -6537,15 +6665,15 @@ devinfo->function.audio.devs[i].devinfo = devinfo; devinfo->function.audio.devs[i].play = -1; devinfo->function.audio.devs[i].rec = -1; - devinfo->function.audio.devs[i].digital = 2; + devinfo->function.audio.devs[i].digital = 255; } for (i = 0; i < devinfo->function.audio.ascnt; i++) { if (as[i].enable == 0) continue; for (j = 0; j < devinfo->function.audio.num_devs; j++) { - if (devinfo->function.audio.devs[j].digital != 2 && - devinfo->function.audio.devs[j].digital != - as[i].digital) + if (devinfo->function.audio.devs[j].digital != 255 && + (!devinfo->function.audio.devs[j].digital) != + (!as[i].digital)) continue; if (as[i].dir == HDA_CTL_IN) { if (devinfo->function.audio.devs[j].rec >= 0) @@ -6721,6 +6849,8 @@ printf(" IN"); if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap)) printf(" BAL"); + if (HDA_PARAM_PIN_CAP_HDMI(pincap)) + printf(" HDMI"); if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) { printf(" VREF["); if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap)) @@ -6737,6 +6867,10 @@ } if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)) printf(" EAPD"); + if (HDA_PARAM_PIN_CAP_DP(pincap)) + printf(" DP"); + if (HDA_PARAM_PIN_CAP_HBR(pincap)) + printf(" HBR"); printf("\n"); device_printf(sc->dev, " Pin config: 0x%08x\n", w->wclass.pin.config); @@ -6844,8 +6978,11 @@ printf(" PROC"); if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap)) printf(" STRIPE"); - if (HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap)) + j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap); + if (j == 1) printf(" STEREO"); + else if (j > 1) + printf(" %dCH", j + 1); printf("\n"); } if (w->bindas != -1) { @@ -7946,7 +8083,9 @@ snprintf(buf, sizeof(buf), "HDA %s PCM #%d %s", hdac_codec_name(pdevinfo->devinfo->codec), pdevinfo->index, - pdevinfo->digital?"Digital":"Analog"); + (pdevinfo->digital == 3)?"DisplayPort": + ((pdevinfo->digital == 2)?"HDMI": + ((pdevinfo->digital)?"Digital":"Analog"))); device_set_desc_copy(dev, buf); return (0); } diff -u -r src_bak/sys/dev/sound/pci/hda/hdac.h src/sys/dev/sound/pci/hda/hdac.h --- src_bak/sys/dev/sound/pci/hda/hdac.h 2010-01-12 18:19:46.982930423 +0100 +++ src/sys/dev/sound/pci/hda/hdac.h 2010-01-12 18:40:34.584922139 +0100 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/sound/pci/hda/hdac.h,v 1.1.12.1.2.1 2009/10/25 01:10:29 kensmith Exp $ + * $FreeBSD$ */ #ifndef _HDAC_H_ diff -u -r src_bak/sys/dev/sound/pci/hda/hdac_private.h src/sys/dev/sound/pci/hda/hdac_private.h --- src_bak/sys/dev/sound/pci/hda/hdac_private.h 2010-01-12 18:19:46.982930423 +0100 +++ src/sys/dev/sound/pci/hda/hdac_private.h 2010-01-12 18:40:28.411441431 +0100 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/sound/pci/hda/hdac_private.h,v 1.10.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $ + * $FreeBSD$ */ #ifndef _HDAC_PRIVATE_H_ @@ -221,6 +221,7 @@ u_char pincnt; u_char fakeredir; u_char digital; + uint16_t pinset; nid_t hpredir; nid_t pins[16]; nid_t dacs[16]; @@ -281,7 +282,7 @@ struct hdac_devinfo *devinfo; struct hdac_pcm_devinfo *pdevinfo; struct hdac_dma bdl_dma; - uint32_t spd, fmt, fmtlist[8], pcmrates[16]; + uint32_t spd, fmt, fmtlist[16], pcmrates[16]; uint32_t supp_stream_formats, supp_pcm_size_rate; uint32_t ptr, prevptr, blkcnt, blksz; uint32_t *dmapos; @@ -339,6 +340,7 @@ int num_iss; int num_oss; int num_bss; + int num_sdo; int support_64bit; int streamcnt; diff -u -r src_bak/sys/dev/sound/pci/hda/hdac_reg.h src/sys/dev/sound/pci/hda/hdac_reg.h --- src_bak/sys/dev/sound/pci/hda/hdac_reg.h 2010-01-12 18:19:46.981930017 +0100 +++ src/sys/dev/sound/pci/hda/hdac_reg.h 2010-01-12 18:40:44.282677301 +0100 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/sound/pci/hda/hdac_reg.h,v 1.1.12.1.2.1 2009/10/25 01:10:29 kensmith Exp $ + * $FreeBSD$ */ #ifndef _HDAC_REG_H_ @@ -136,6 +136,8 @@ (((gcap) & HDAC_GCAP_ISS_MASK) >> HDAC_GCAP_ISS_SHIFT) #define HDAC_GCAP_OSS(gcap) \ (((gcap) & HDAC_GCAP_OSS_MASK) >> HDAC_GCAP_OSS_SHIFT) +#define HDAC_GCAP_NSDO(gcap) \ + (((gcap) & HDAC_GCAP_NSDO_MASK) >> HDAC_GCAP_NSDO_SHIFT) /* GCTL - Global Control */ #define HDAC_GCTL_CRST 0x00000001 Only in src/sys/dev/sound/pci: hda_bak diff -u -r src_bak/sys/dev/sound/pcm/dsp.c src/sys/dev/sound/pcm/dsp.c --- src_bak/sys/dev/sound/pcm/dsp.c 2010-01-12 18:19:47.065938180 +0100 +++ src/sys/dev/sound/pcm/dsp.c 2010-01-12 18:42:25.057522428 +0100 @@ -1003,7 +1003,7 @@ if (volch != NULL && ((j == SOUND_MIXER_PCM && volch->direction == PCMDIR_PLAY) || (j == SOUND_MIXER_RECLEV && volch->direction == PCMDIR_REC))) { - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + if ((cmd & ~0xff) == MIXER_WRITE(0)) { int left, right, center; left = *(int *)arg & 0x7f; @@ -1011,7 +1011,7 @@ center = (left + right) >> 1; chn_setvolume_multi(volch, SND_VOL_C_PCM, left, right, center); - } else if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + } else if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = CHN_GETVOLUME(volch, SND_VOL_C_PCM, SND_CHN_T_FL); *(int *)arg |= CHN_GETVOLUME(volch, @@ -1023,7 +1023,7 @@ case SOUND_MIXER_DEVMASK: case SOUND_MIXER_CAPS: case SOUND_MIXER_STEREODEVS: - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = 0; if (rdch != NULL) *(int *)arg |= SOUND_MASK_RECLEV; @@ -1034,7 +1034,7 @@ break; case SOUND_MIXER_RECMASK: case SOUND_MIXER_RECSRC: - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) + if ((cmd & ~0xff) == MIXER_READ(0)) *(int *)arg = 0; ret = 0; break; diff -u -r src_bak/sys/dev/sound/pcm/mixer.c src/sys/dev/sound/pcm/mixer.c --- src_bak/sys/dev/sound/pcm/mixer.c 2010-01-12 18:19:47.060937265 +0100 +++ src/sys/dev/sound/pcm/mixer.c 2010-01-12 18:42:25.039523213 +0100 @@ -1130,7 +1130,7 @@ if ((j == SOUND_MIXER_DEVMASK || j == SOUND_MIXER_CAPS || j == SOUND_MIXER_STEREODEVS) && - (cmd & MIXER_READ(0)) == MIXER_READ(0)) { + (cmd & ~0xff) == MIXER_READ(0)) { snd_mtxlock(m->lock); *(int *)arg = mix_getdevs(m); snd_mtxunlock(m->lock); @@ -1148,14 +1148,14 @@ KASSERT(c != NULL, ("%s(): NULL channel", __func__)); CHN_LOCKASSERT(c); - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + if ((cmd & ~0xff) == MIXER_WRITE(0)) { int left, right, center; left = *(int *)arg & 0x7f; right = (*(int *)arg >> 8) & 0x7f; center = (left + right) >> 1; chn_setvolume_multi(c, SND_VOL_C_PCM, left, right, center); - } else if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + } else if ((cmd & ~0xff) == MIXER_READ(0)) { *(int *)arg = CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FL); *(int *)arg |= CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FR) << 8; @@ -1208,7 +1208,7 @@ struct thread *td, int from) { struct snd_mixer *m; - int ret, *arg_i = (int *)arg; + int ret = EINVAL, *arg_i = (int *)arg; int v = -1, j = cmd & 0xff; /* @@ -1242,8 +1242,23 @@ snd_mtxunlock(m->lock); return (EBADF); } - - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + switch (cmd) { + case SNDCTL_DSP_GET_RECSRC_NAMES: + bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo)); + ret = 0; + goto done; + case SNDCTL_DSP_GET_RECSRC: + ret = mixer_get_recroute(m, arg_i); + goto done; + case SNDCTL_DSP_SET_RECSRC: + ret = mixer_set_recroute(m, *arg_i); + goto done; + case OSS_GETVERSION: + *arg_i = SOUND_VERSION; + ret = 0; + goto done; + } + if ((cmd & ~0xff) == MIXER_WRITE(0)) { if (j == SOUND_MIXER_RECSRC) ret = mixer_setrecsrc(m, *arg_i); else @@ -1251,23 +1266,19 @@ snd_mtxunlock(m->lock); return ((ret == 0) ? 0 : ENXIO); } - - if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { + if ((cmd & ~0xff) == MIXER_READ(0)) { switch (j) { - case SOUND_MIXER_DEVMASK: - case SOUND_MIXER_CAPS: - case SOUND_MIXER_STEREODEVS: + case SOUND_MIXER_DEVMASK: + case SOUND_MIXER_CAPS: + case SOUND_MIXER_STEREODEVS: v = mix_getdevs(m); break; - - case SOUND_MIXER_RECMASK: + case SOUND_MIXER_RECMASK: v = mix_getrecdevs(m); break; - - case SOUND_MIXER_RECSRC: + case SOUND_MIXER_RECSRC: v = mixer_getrecsrc(m); break; - default: v = mixer_get(m, j); } @@ -1275,29 +1286,8 @@ snd_mtxunlock(m->lock); return ((v != -1) ? 0 : ENXIO); } - - ret = 0; - - switch (cmd) { - case SNDCTL_DSP_GET_RECSRC_NAMES: - bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo)); - break; - case SNDCTL_DSP_GET_RECSRC: - ret = mixer_get_recroute(m, arg_i); - break; - case SNDCTL_DSP_SET_RECSRC: - ret = mixer_set_recroute(m, *arg_i); - break; - case OSS_GETVERSION: - *arg_i = SOUND_VERSION; - break; - default: - ret = EINVAL; - break; - } - +done: snd_mtxunlock(m->lock); - return (ret); }