/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _SYS_AUDIOHD_IMPL_H_ #define _SYS_AUDIOHD_IMPL_H_ #ifdef __cplusplus extern "C" { #endif /* * vendor IDs of PCI audio controllers */ #define AUDIOHD_VID_ATI 0x1002 #define AUDIOHD_VID_CIRRUS 0x1013 #define AUDIOHD_VID_NVIDIA 0x10de #define AUDIOHD_VID_REALTEK 0x10ec #define AUDIOHD_VID_CREATIVE 0x1102 #define AUDIOHD_VID_IDT 0x111d #define AUDIOHD_VID_ANALOG 0x11d4 #define AUDIOHD_VID_CONEXANT 0x14f1 #define AUDIOHD_VID_SIGMATEL 0x8384 #define AUDIOHD_VID_INTEL 0x8086 /* * specific audiohd controller device id */ #define AUDIOHD_CONTROLLER_MCP51 0x10de026c /* * codec special initial flags */ #define NO_GPIO 0x00000001 #define NO_MIXER 0x00000002 #define NO_SPDIF 0x00000004 #define EN_PIN_BEEP 0x00000008 #define AUDIOHD_DEV_CONFIG "onboard1" #define AUDIOHD_DEV_VERSION "a" /* * Only for Intel hardware: * PCI Express traffic class select register in PCI configure space */ #define AUDIOHD_INTEL_PCI_TCSEL 0x44 #define AUDIOHD_INTEL_TCS_MASK 0xf8 /* * Only for ATI SB450: * MISC control register 2 */ #define AUDIOHD_ATI_PCI_MISC2 0x42 #define AUDIOHD_ATI_MISC2_MASK 0xf8 #define AUDIOHD_ATI_MISC2_SNOOP 0x02 /* NVIDIA snoop */ #define AUDIOHD_NVIDIA_SNOOP 0x0f #define AUDIOHDC_NID(x) x #define AUDIOHDC_NULL_NODE -1 #define AUDIOHD_NULL_CONN ((uint_t)(-1)) #define AUDIOHD_EXT_AMP_MASK 0x00010000 #define AUDIOHD_EXT_AMP_ENABLE 0x02 /* Power On/Off */ #define AUDIOHD_PW_D0 0 #define AUDIOHD_PW_D2 2 /* Pin speaker On/Off */ #define AUDIOHD_SP_ON 1 #define AUDIOHD_SP_OFF 0 #define AUDIOHD_PORT_MAX 15 #define AUDIOHD_CODEC_MAX 16 #define AUDIOHD_MEMIO_LEN 0x4000 #define AUDIOHD_RETRY_TIMES 60 #define AUDIOHD_TEST_TIMES 500 #define AUDIOHD_OUTSTR_NUM_OFF 12 #define AUDIOHD_INSTR_NUM_OFF 8 #define AUDIOHD_CORB_SIZE_OFF 0x4e #define AUDIOHD_URCAP_MASK 0x80 #define AUDIOHD_DTCCAP_MASK 0x4 #define AUDIOHD_UR_ENABLE_OFF 8 #define AUDIOHD_UR_TAG_MASK 0x3f #define AUDIOHD_CIS_MASK 0x40000000 #define AUDIOHD_RIRB_UR_MASK 0x10 #define AUDIOHD_RIRB_CODEC_MASK 0xf #define AUDIOHD_RIRB_WID_OFF 27 #define AUDIOHD_RIRB_INTRCNT 0x0 #define AUDIOHD_RIRB_WPMASK 0xff #define AUDIOHD_FORM_MASK 0x0080 #define AUDIOHD_LEN_MASK 0x007f #define AUDIOHD_PIN_CAP_MASK 0x00000010 #define AUDIOHD_PIN_CONF_MASK 0xc0000000 #define AUDIOHD_PIN_CON_MASK 3 #define AUDIOHD_PIN_CON_STEP 30 #define AUDIOHD_PIN_IO_MASK 0X0018 #define AUDIOHD_PIN_SEQ_MASK 0x0000000f #define AUDIOHD_PIN_ASO_MASK 0x000000f0 #define AUDIOHD_PIN_ASO_OFF 0x4 #define AUDIOHD_PIN_DEV_MASK 0x00f00000 #define AUDIOHD_PIN_DEV_OFF 20 #define AUDIOHD_PIN_NUMS 6 #define AUDIOHD_PIN_NO_CONN 0x40000000 #define AUDIOHD_PIN_IN_ENABLE 0x20 #define AUDIOHD_PIN_OUT_ENABLE 0x40 #define AUDIOHD_PIN_PRES_MASK 0x80000000 #define AUDIOHD_PIN_CONTP_OFF 0x1e #define AUDIOHD_PIN_CON_JACK 0 #define AUDIOHD_PIN_CON_FIXED 0x2 #define AUDIOHD_PIN_CONTP_MASK 0x3 #define AUDIOHD_PIN_VREF_L1 0x20 #define AUDIOHD_PIN_VREF_L2 0x10 #define AUDIOHD_PIN_VREF_L3 0x04 #define AUDIOHD_PIN_VREF_L4 0x02 #define AUDIOHD_PIN_VREF_OFF 8 #define AUDIOHD_PIN_VREF_MASK 0xff #define AUDIOHD_PIN_CLR_MASK 0xf #define AUDIOHD_PIN_CLR_OFF 12 #define AUDIOHD_VERB_ADDR_OFF 28 #define AUDIOHD_VERB_NID_OFF 20 #define AUDIOHD_VERB_CMD_OFF 8 #define AUDIOHD_VERB_CMD16_OFF 16 #define AUDIOHD_RING_MAX_SIZE 0x00ff #define AUDIOHD_REC_TAG_OFF 4 #define AUDIOHD_PLAY_TAG_OFF 4 #define AUDIOHD_PLAY_CTL_OFF 2 #define AUDIOHD_REC_CTL_OFF 2 #define AUDIOHD_SPDIF_ON 1 #define AUDIOHD_SPDIF_MASK 0x00ff #define AUDIOHD_GAIN_OFF 8 #define AUDIOHD_CODEC_STR_OFF 16 #define AUDIOHD_CODEC_STR_MASK 0x000000ff #define AUDIOHD_CODEC_NUM_MASK 0x000000ff #define AUDIOHD_CODEC_TYPE_MASK 0x000000ff #define AUDIOHD_ROUNDUP(x, algn) (((x) + ((algn) - 1)) & ~((algn) - 1)) #define AUDIOHD_BDLE_BUF_ALIGN 128 #define AUDIOHD_CMDIO_ENT_MASK 0x00ff /* 256 entries for CORB/RIRB */ #define AUDIOHD_CDBIO_CORB_LEN 1024 /* 256 entries for CORB, 1024B */ #define AUDIOHD_CDBIO_RIRB_LEN 2048 /* 256 entries for RIRB, 2048B */ #define AUDIOHD_BDLE_NUMS 4 /* 4 entires for record/play BD list */ #define AUDIOHD_PORT_UNMUTE (0xffffffff) /* * Audio registers of high definition */ #define AUDIOHD_REG_GCAP 0x00 #define AUDIOHDR_GCAP_OUTSTREAMS 0xf000 #define AUDIOHDR_GCAP_INSTREAMS 0x0f00 #define AUDIOHDR_GCAP_BSTREAMS 0x00f8 #define AUDIOHDR_GCAP_NSDO 0x0006 #define AUDIOHDR_GCAP_64OK 0x0001 #define AUDIOHD_REG_VMIN 0x02 #define AUDIOHD_REG_VMAJ 0x03 #define AUDIOHD_REG_OUTPAY 0x04 #define AUDIOHD_REG_INPAY 0x06 #define AUDIOHD_REG_GCTL 0x08 #define AUDIOHD_REG_WAKEEN 0x0C #define AUDIOHD_REG_STATESTS 0x0E #define AUDIOHD_STATESTS_BIT_SDINS 0x7F #define AUDIOHD_REG_GSTS 0x10 #define AUDIOHD_REG_INTCTL 0x20 #define AUDIOHD_INTCTL_BIT_GIE 0x80000000 #define AUDIOHD_INTCTL_BIT_CIE 0x40000000 #define AUDIOHD_INTCTL_BIT_SIE 0x3FFFFFFF #define AUDIOHD_REG_INTSTS 0x24 #define AUDIOHD_INTSTS_BIT_GIS 0x80000000 #define AUDIOHD_INTSTS_BIT_CIS 0x40000000 #define AUDIOHD_INTSTS_BIT_SINTS (0x3fffffff) #define AUDIOHD_REG_WALCLK 0x30 #define AUDIOHD_REG_SYNC 0x38 #define AUDIOHD_REG_CORBLBASE 0x40 #define AUDIOHD_REG_CORBUBASE 0x44 #define AUDIOHD_REG_CORBWP 0x48 #define AUDIOHD_REG_CORBRP 0x4A #define AUDIOHD_REG_CORBCTL 0x4C #define AUDIOHD_REG_CORBST 0x4D #define AUDIOHD_REG_CORBSIZE 0x4E #define AUDIOHD_REG_RIRBLBASE 0x50 #define AUDIOHD_REG_RIRBUBASE 0x54 #define AUDIOHD_REG_RIRBWP 0x58 #define AUDIOHD_REG_RINTCNT 0x5A #define AUDIOHD_REG_RIRBCTL 0x5C #define AUDIOHD_REG_RIRBSTS 0x5D #define AUDIOHD_REG_RIRBSIZE 0x5E #define AUDIOHD_REG_IC 0x60 #define AUDIOHD_REG_IR 0x64 #define AUDIOHD_REG_IRS 0x68 #define AUDIOHD_REG_DPLBASE 0x70 #define AUDIOHD_REG_DPUBASE 0x74 #define AUDIOHD_REG_SD_BASE 0x80 #define AUDIOHD_REG_SD_LEN 0x20 /* * Offset of Stream Descriptor Registers */ #define AUDIOHD_SDREG_OFFSET_CTL 0x00 #define AUDIOHD_SDREG_OFFSET_STS 0x03 #define AUDIOHD_SDREG_OFFSET_LPIB 0x04 #define AUDIOHD_SDREG_OFFSET_CBL 0x08 #define AUDIOHD_SDREG_OFFSET_LVI 0x0c #define AUDIOHD_SDREG_OFFSET_FIFOW 0x0e #define AUDIOHD_SDREG_OFFSET_FIFOSIZE 0x10 #define AUDIOHD_SDREG_OFFSET_FORMAT 0x12 #define AUDIOHD_SDREG_OFFSET_BDLPL 0x18 #define AUDIOHD_SDREG_OFFSET_BDLPU 0x1c /* bits for stream descriptor control reg */ #define AUDIOHDR_SD_CTL_DEIE 0x000010 #define AUDIOHDR_SD_CTL_FEIE 0x000008 #define AUDIOHDR_SD_CTL_IOCE 0x000004 #define AUDIOHDR_SD_CTL_SRUN 0x000002 #define AUDIOHDR_SD_CTL_SRST 0x000001 /* bits for stream descriptor status register */ #define AUDIOHDR_SD_STS_BCIS 0x0004 #define AUDIOHDR_SD_STS_FIFOE 0x0008 #define AUDIOHDR_SD_STS_DESE 0x0010 #define AUDIOHDR_SD_STS_FIFORY 0x0020 #define AUDIOHDR_SD_STS_INTRS \ (AUDIOHDR_SD_STS_BCIS | \ AUDIOHDR_SD_STS_FIFOE | \ AUDIOHDR_SD_STS_DESE) /* bits for GCTL register */ #define AUDIOHDR_GCTL_CRST 0x00000001 #define AUDIOHDR_GCTL_URESPE 0x00000100 /* bits for CORBRP register */ #define AUDIOHDR_CORBRP_RESET 0x8000 #define AUDIOHDR_CORBRP_WPTR 0x00ff /* bits for CORBCTL register */ #define AUDIOHDR_CORBCTL_CMEIE 0x01 #define AUDIOHDR_CORBCTL_DMARUN 0x02 /* bits for CORB SIZE register */ #define AUDIOHDR_CORBSZ_8 0 #define AUDIOHDR_CORBSZ_16 1 #define AUDIOHDR_CORBSZ_256 2 /* bits for RIRBCTL register */ #define AUDIOHDR_RIRBCTL_RINTCTL 0x01 #define AUDIOHDR_RIRBCTL_DMARUN 0x02 #define AUDIOHDR_RIRBCTL_RIRBOIC 0x04 #define AUDIOHDR_RIRBCTL_RSTINT 0xfe /* bits for RIRBWP register */ #define AUDIOHDR_RIRBWP_RESET 0x8000 #define AUDIOHDR_RIRBWP_WPTR 0x00ff /* bits for RIRB SIZE register */ #define AUDIOHDR_RIRBSZ_8 0 #define AUDIOHDR_RIRBSZ_16 1 #define AUDIOHDR_RIRBSZ_256 2 #define AUDIOHD_BDLE_RIRB_SDI 0x0000000f #define AUDIOHD_BDLE_RIRB_UNSOLICIT 0x00000010 /* HD spec: ID of Root node is 0 */ #define AUDIOHDC_NODE_ROOT 0x00 /* HD spec: ID of audio function group is "1" */ #define AUDIOHDC_AUDIO_FUNC_GROUP 1 /* * HD audio verbs can be either 12-bit or 4-bit in length. */ #define AUDIOHDC_12BIT_VERB_MASK 0xfffff000 #define AUDIOHDC_4BIT_VERB_MASK 0xfffffff0 #define AUDIOHDC_SAMPR48000 48000 #define AUDIOHDC_MAX_BEEP_GEN 12000 #define AUDIOHDC_MIX_BEEP_GEN 47 #define AUDIOHDC_MUTE_BEEP_GEN 0x0 /* * 12-bit verbs */ #define AUDIOHDC_VERB_GET_PARAM 0xf00 #define AUDIOHDC_VERB_GET_CONN_SEL 0xf01 #define AUDIOHDC_VERB_SET_CONN_SEL 0x701 #define AUDIOHDC_VERB_GET_CONN_LIST_ENT 0xf02 #define AUDIOHDC_VERB_GET_PROCESS_STATE 0xf03 #define AUDIOHDC_VERB_GET_SDI_SEL 0xf04 #define AUDIOHDC_VERB_GET_POWER_STATE 0xf05 #define AUDIOHDC_VERB_SET_POWER_STATE 0x705 #define AUDIOHDC_VERB_GET_STREAM_CHANN 0xf06 #define AUDIOHDC_VERB_SET_STREAM_CHANN 0x706 #define AUDIOHDC_VERB_GET_PIN_CTRL 0xf07 #define AUDIOHDC_VERB_SET_PIN_CTRL 0x707 #define AUDIOHDC_VERB_GET_UNS_ENABLE 0xf08 #define AUDIOHDC_VERB_SET_UNS_ENABLE 0x708 #define AUDIOHDC_VERB_GET_PIN_SENSE 0xf09 #define AUDIOHDC_VERB_GET_PIN_SENSE 0xf09 #define AUDIOHDC_VERB_EXEC_PIN_SENSE 0x709 #define AUDIOHDC_VERB_GET_BEEP_GEN 0xf0a #define AUDIOHDC_VERB_SET_BEEP_GEN 0x70a #define AUDIOHDC_VERB_GET_EAPD 0xf0c #define AUDIOHDC_VERB_SET_EAPD 0x70c #define AUDIOHDC_VERB_GET_DEFAULT_CONF 0xf1c #define AUDIOHDC_VERB_GET_SPDIF_CTL 0xf0d #define AUDIOHDC_VERB_SET_SPDIF_LCL 0x70d #define AUDIOHDC_VERB_GET_GPIO_MASK 0xf16 #define AUDIOHDC_VERB_SET_GPIO_MASK 0x716 #define AUDIOHDC_VERB_GET_UNSOL_ENABLE_MASK 0xf19 #define AUDIOHDC_VERB_SET_UNSOL_ENABLE_MASK 0x719 #define AUDIOHDC_VERB_GET_GPIO_DIREC 0xf17 #define AUDIOHDC_VERB_SET_GPIO_DIREC 0x717 #define AUDIOHDC_VERB_GET_GPIO_DATA 0xf15 #define AUDIOHDC_VERB_SET_GPIO_DATA 0x715 #define AUDIOHDC_VERB_GET_GPIO_STCK 0xf1a #define AUDIOHDC_VERB_SET_GPIO_STCK 0x71a #define AUDIOHDC_GPIO_ENABLE 0xff #define AUDIOHDC_GPIO_DIRECT 0xf1 #define AUDIOHDC_GPIO_DATA_CTRL 0xff #define AUDIOHDC_GPIO_STCK_CTRL 0xff /* * 4-bit verbs */ #define AUDIOHDC_VERB_GET_CONV_FMT 0xa #define AUDIOHDC_VERB_SET_CONV_FMT 0x2 #define AUDIOHDC_VERB_GET_AMP_MUTE 0xb #define AUDIOHDC_VERB_SET_AMP_MUTE 0x3 #define AUDIOHDC_VERB_SET_BEEP_VOL 0x3A0 /* * parameters of nodes */ #define AUDIOHDC_PAR_VENDOR_ID 0x00 #define AUDIOHDC_PAR_SUBSYS_ID 0x01 #define AUDIOHDC_PAR_REV_ID 0x02 #define AUDIOHDC_PAR_NODE_COUNT 0x04 #define AUDIOHDC_PAR_FUNCTION_TYPE 0x05 #define AUDIOHDC_PAR_AUDIO_FG_CAP 0x08 #define AUDIOHDC_PAR_AUDIO_WID_CAP 0x09 #define AUDIOHDC_PAR_PCM 0x0a #define AUDIOHDC_PAR_STREAM 0x0b #define AUDIOHDC_PAR_PIN_CAP 0x0c #define AUDIOHDC_PAR_INAMP_CAP 0x0d #define AUDIOHDC_PAR_CONNLIST_LEN 0x0e #define AUDIOHDC_PAR_POWER_STATE 0x0f #define AUDIOHDC_PAR_PROC_CAP 0x10 #define AUDIOHDC_PAR_GPIO_CAP 0x11 #define AUDIOHDC_PAR_OUTAMP_CAP 0x12 /* * bits for get/set amplifier gain/mute */ #define AUDIOHDC_AMP_SET_OUTPUT 0x8000 #define AUDIOHDC_AMP_SET_INPUT 0x4000 #define AUDIOHDC_AMP_SET_LEFT 0x2000 #define AUDIOHDC_AMP_SET_RIGHT 0x1000 #define AUDIOHDC_AMP_SET_MUTE 0x0080 #define AUDIOHDC_AMP_SET_LNR 0x3000 #define AUDIOHDC_AMP_SET_LR_INPUT 0x7000 #define AUDIOHDC_AMP_SET_LR_OUTPUT 0xb000 #define AUDIOHDC_AMP_SET_INDEX_OFFSET 8 #define AUDIOHDC_AMP_SET_GAIN_MASK 0x007f #define AUDIOHDC_GAIN_MAX 0x7f #define AUDIOHDC_GAIN_BITS 7 #define AUDIOHDC_GAIN_DEFAULT 0x0f #define AUDIOHDC_AMP_GET_OUTPUT 0x8000 #define AUDIOHDC_AMP_GET_INPUT 0x0000 /* value used to set max volume for left output */ #define AUDIOHDC_AMP_LOUT_MAX \ (AUDIOHDC_AMP_SET_OUTPUT | \ AUDIOHDC_AMP_SET_LEFT | \ AUDIOHDC_GAIN_MAX) /* value used to set max volume for right output */ #define AUDIOHDC_AMP_ROUT_MAX \ (AUDIOHDC_AMP_SET_OUTPUT | \ AUDIOHDC_AMP_SET_RIGHT | \ AUDIOHDC_GAIN_MAX) /* * Bits for pin widget control verb */ #define AUDIOHDC_PIN_CONTROL_HP_ENABLE 0x80 #define AUDIOHDC_PIN_CONTROL_OUT_ENABLE 0x40 #define AUDIOHDC_PIN_CONTROL_IN_ENABLE 0x20 /* * Bits for Amplifier capabilities */ #define AUDIOHDC_AMP_CAP_MUTE_CAP 0x80000000 #define AUDIOHDC_AMP_CAP_STEP_SIZE 0x007f0000 #define AUDIOHDC_AMP_CAP_STEP_NUMS 0x00007f00 #define AUDIOHDC_AMP_CAP_0DB_OFFSET 0x0000007f /* * Bits for Audio Widget Capabilities */ #define AUDIOHD_WIDCAP_STEREO 0x00000001 #define AUDIOHD_WIDCAP_INAMP 0x00000002 #define AUDIOHD_WIDCAP_OUTAMP 0x00000004 #define AUDIOHD_WIDCAP_AMP_OVRIDE 0x00000008 #define AUDIOHD_WIDCAP_FMT_OVRIDE 0x00000010 #define AUDIOHD_WIDCAP_STRIP 0x00000020 #define AUDIOHD_WIDCAP_PROC_WID 0x00000040 #define AUDIOHD_WIDCAP_UNSOL 0x00000080 #define AUDIOHD_WIDCAP_CONNLIST 0x00000100 #define AUDIOHD_WIDCAP_DIGIT 0x00000200 #define AUDIOHD_WIDCAP_PWRCTRL 0x00000400 #define AUDIOHD_WIDCAP_LRSWAP 0x00000800 #define AUDIOHD_WIDCAP_TYPE 0x00f00000 #define AUDIOHD_WIDCAP_TO_WIDTYPE(wcap) \ ((wcap & AUDIOHD_WIDCAP_TYPE) >> 20) #define AUDIOHD_CODEC_FAILURE (uint32_t)(-1) /* Higher sample/bits support */ #define AUDIOHD_BIT_DEPTH16 0x00020000 #define AUDIOHD_BIT_DEPTH24 0x00080000 #define AUDIOHD_SAMP_RATE48 0x00000040 #define AUDIOHD_SAMP_RATE96 0x00000100 #define AUDIOHD_SAMP_RATE192 0x00000400 /* * buffer descriptor list entry of stream descriptor */ typedef struct { uint64_t sbde_addr; uint32_t sbde_len; uint32_t sbde_ioc: 1, reserved: 31; }sd_bdle_t; #define AUDIOHD_PLAY_STARTED 0x00000001 #define AUDIOHD_PLAY_EMPTY 0x00000002 #define AUDIOHD_PLAY_PAUSED 0x00000004 #define AUDIOHD_RECORD_STARTED 0x00000008 enum audiohda_widget_type { WTYPE_AUDIO_OUT = 0, WTYPE_AUDIO_IN, WTYPE_AUDIO_MIX, WTYPE_AUDIO_SEL, WTYPE_PIN, WTYPE_POWER, WTYPE_VOL_KNOB, WTYPE_BEEP, WTYPE_VENDOR = 0xf }; enum audiohda_device_type { DTYPE_LINEOUT = 0, DTYPE_SPEAKER, DTYPE_HP_OUT, DTYPE_CD, DTYPE_SPDIF_OUT, DTYPE_DIGIT_OUT, DTYPE_MODEM_SIDE, DTYPE_MODEM_HNAD_SIDE, DTYPE_LINE_IN, DTYPE_AUX, DTYPE_MIC_IN, DTYPE_TEL, DTYPE_SPDIF_IN, DTYPE_DIGIT_IN, DTYPE_OTHER = 0x0f, }; enum audiohd_pin_color { AUDIOHD_PIN_UNKNOWN = 0, AUDIOHD_PIN_BLACK, AUDIOHD_PIN_GREY, AUDIOHD_PIN_BLUE, AUDIOHD_PIN_GREEN, AUDIOHD_PIN_RED, AUDIOHD_PIN_ORANGE, AUDIOHD_PIN_YELLOW, AUDIOHD_PIN_PURPLE, AUDIOHD_PIN_PINK, AUDIOHD_PIN_WHITE = 0xe, AUDIOHD_PIN_OTHER = 0xf, }; /* values for audiohd_widget.path_flags */ #define AUDIOHD_PATH_DAC (1 << 0) #define AUDIOHD_PATH_ADC (1 << 1) #define AUDIOHD_PATH_MON (1 << 2) #define AUDIOHD_PATH_NOMON (1 << 3) #define AUDIOHD_PATH_BEEP (1 << 4) #define AUDIOHD_PATH_LOOPBACK (1 << 5) typedef struct audiohd_path audiohd_path_t; typedef struct audiohd_widget audiohd_widget_t; typedef struct audiohd_state audiohd_state_t; typedef struct audiohd_codec_info audiohd_codec_info_t; typedef struct audiohd_pin audiohd_pin_t; typedef struct hda_codec hda_codec_t; typedef uint32_t wid_t; /* id of widget */ typedef struct audiohd_entry_prop audiohd_entry_prop_t; typedef enum audiohda_device_type audiohda_device_type_t; typedef enum audiohd_pin_color audiohd_pin_color_t; #define AUDIOHD_MAX_WIDGET 128 #define AUDIOHD_MAX_CONN 16 #define AUDIOHD_MAX_PINS 16 #define AUDIOHD_MAX_DEPTH 8 struct audiohd_entry_prop { uint32_t conn_len; uint32_t mask_range; uint32_t mask_wid; wid_t input_wid; int conns_per_entry; int bits_per_conn; }; struct audiohd_widget { wid_t wid_wid; hda_codec_t *codec; enum audiohda_widget_type type; uint32_t widget_cap; uint32_t pcm_format; uint32_t inamp_cap; uint32_t outamp_cap; uint32_t path_flags; int out_weight; int in_weight; int finish; /* * available (input) connections. 0 means this widget * has fixed connection */ int nconns; /* * wid of possible & selected input & output connections */ wid_t avail_conn[AUDIOHD_MAX_CONN]; wid_t output_path_next; /* output pin -> DAC */ wid_t input_path_next; /* ADC -> input pin */ wid_t monitor_path_next[AUDIOHD_MAX_CONN]; /* output pin -> input pin */ wid_t beep_path_next; /* output pin -> beep widget */ wid_t loopback_path_next; /* ADC -> output pin */ uint16_t used; /* * pointer to struct depending on widget type: * 1. DAC audiohd_path_t * 2. ADC audiohd_path_t * 3. PIN audiohd_pin_t */ void *priv; }; #define AUDIOHD_FLAG_LINEOUT (1 << 0) #define AUDIOHD_FLAG_SPEAKER (1 << 1) #define AUDIOHD_FLAG_HP (1 << 2) #define AUDIOHD_FLAG_MONO (1 << 3) #define AUDIOHD_MAX_MIXER 5 #define AUDIOHD_MAX_PIN 4 #define PORT_DAC 0 #define PORT_ADC 1 #define PORT_MAX 2 typedef enum { PLAY = 0, RECORD = 1, BEEP = 2, LOOPBACK = 3, } path_type_t; struct audiohd_path { wid_t adda_wid; wid_t beep_wid; wid_t pin_wid[AUDIOHD_MAX_PINS]; int sum_selconn[AUDIOHD_MAX_PINS]; int mon_wid[AUDIOHD_MAX_PIN][AUDIOHD_MAX_MIXER]; int pin_nums; int maxmixer[AUDIOHD_MAX_PINS]; path_type_t path_type; wid_t mute_wid; int mute_dir; wid_t gain_wid; int gain_dir; uint32_t gain_bits; uint32_t pin_outputs; uint8_t tag; hda_codec_t *codec; wid_t sum_wid; audiohd_state_t *statep; }; typedef struct audiohd_port { uint8_t nchan; int index; uint16_t regoff; unsigned nframes; size_t bufsize; size_t fragsize; uint64_t count; int curpos; uint_t format; unsigned sync_dir; ddi_dma_handle_t samp_dmah; ddi_acc_handle_t samp_acch; caddr_t samp_kaddr; uint64_t samp_paddr; ddi_dma_handle_t bdl_dmah; ddi_acc_handle_t bdl_acch; size_t bdl_size; caddr_t bdl_kaddr; uint64_t bdl_paddr; audio_engine_t *engine; audiohd_state_t *statep; }audiohd_port_t; enum { CTL_VOLUME = 0, CTL_FRONT, CTL_SPEAKER, CTL_HEADPHONE, CTL_REAR, CTL_CENTER, CTL_SURROUND, CTL_LFE, CTL_IGAIN, CTL_LINEIN, CTL_MIC, CTL_CD, CTL_MONGAIN, CTL_MONSRC, CTL_RECSRC, CTL_BEEP, CTL_LOOP, /* this one must be last */ CTL_MAX }; typedef struct audiohd_ctrl { audiohd_state_t *statep; audio_ctrl_t *ctrl; int num; uint64_t val; } audiohd_ctrl_t; struct audiohd_pin { audiohd_pin_t *next; wid_t wid; wid_t mute_wid; /* node used to mute this pin */ int mute_dir; /* 1: input, 2: output */ wid_t gain_wid; /* node for gain control */ int gain_dir; /* _OUTPUT/_INPUT */ uint32_t gain_bits; uint8_t vrefvalue; /* value of VRef */ uint32_t cap; uint32_t config; uint32_t ctrl; uint32_t assoc; uint32_t seq; wid_t adc_wid; wid_t dac_wid; wid_t beep_wid; int no_phys_conn; enum audiohda_device_type device; /* * mg_dir, mg_gain, mg_wid are used to store the monitor gain control * widget wid. */ int mg_dir[AUDIOHD_MAX_CONN]; int mg_gain[AUDIOHD_MAX_CONN]; int mg_wid[AUDIOHD_MAX_CONN]; int num; int finish; }; typedef struct { ddi_dma_handle_t ad_dmahdl; ddi_acc_handle_t ad_acchdl; caddr_t ad_vaddr; /* virtual addr */ uint64_t ad_paddr; /* physical addr */ size_t ad_req_sz; /* required size of memory */ size_t ad_real_sz; /* real size of memory */ } audiohd_dma_t; struct hda_codec { uint8_t index; /* codec address */ uint32_t vid; /* vendor id and device id */ uint32_t revid; /* revision id */ wid_t wid_afg; /* id of AFG */ wid_t first_wid; /* wid of 1st subnode of AFG */ wid_t last_wid; /* wid of the last subnode of AFG */ int nnodes; /* # of subnodes of AFG */ uint8_t nistream; uint32_t outamp_cap; uint32_t inamp_cap; uint32_t stream_format; uint32_t pcm_format; audiohd_state_t *statep; audiohd_codec_info_t *codec_info; /* use wid as index to the array of widget pointers */ audiohd_widget_t *widget[AUDIOHD_MAX_WIDGET]; audiohd_port_t *port[AUDIOHD_PORT_MAX]; uint8_t portnum; audiohd_pin_t *first_pin; }; #define AUDIOHD_MAX_ASSOC 15 struct audiohd_state { dev_info_t *hda_dip; kstat_t *hda_ksp; kmutex_t hda_mutex; uint32_t hda_flags; caddr_t hda_reg_base; ddi_acc_handle_t hda_pci_handle; ddi_acc_handle_t hda_reg_handle; audiohd_dma_t hda_dma_corb; audiohd_dma_t hda_dma_rirb; uint8_t hda_rirb_rp; /* read pointer for rirb */ uint16_t hda_codec_mask; audio_dev_t *adev; uint32_t devid; int hda_input_streams; /* # of input stream */ int hda_output_streams; /* # of output stream */ int hda_streams_nums; /* # of stream */ uint_t hda_play_regbase; uint_t hda_record_regbase; uint_t hda_play_stag; /* tag of playback stream */ uint_t hda_record_stag; /* tag of record stream */ uint_t hda_play_lgain; /* left gain for playback */ uint_t hda_play_rgain; /* right gain for playback */ /* * Now, for the time being, we add some fields * for parsing codec topology */ hda_codec_t *codec[AUDIOHD_CODEC_MAX]; /* * Suspend/Resume used fields */ boolean_t suspended; audiohd_path_t *path[AUDIOHD_PORT_MAX]; uint8_t pathnum; audiohd_port_t *port[PORT_MAX]; uint8_t pchan; uint8_t rchan; uint64_t inmask; uint_t hda_out_ports; uint_t in_port; /* Higher sample/rate */ uint32_t sample_rate; uint32_t sample_bit_depth; uint8_t sample_packed_bytes; /* * Controls */ audiohd_ctrl_t ctrls[CTL_MAX]; boolean_t monitor_supported; boolean_t loopback_supported; /* for multichannel */ uint8_t chann[AUDIOHD_MAX_ASSOC]; uint8_t assoc; }; struct audiohd_codec_info { uint32_t devid; const char *buf; uint32_t flags; }; /* * Operation for high definition audio control system bus * interface registers */ #define AUDIOHD_REG_GET8(reg) \ ddi_get8(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg))) #define AUDIOHD_REG_GET16(reg) \ ddi_get16(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg))) #define AUDIOHD_REG_GET32(reg) \ ddi_get32(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg))) #define AUDIOHD_REG_GET64(reg) \ ddi_get64(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg))) #define AUDIOHD_REG_SET8(reg, val) \ ddi_put8(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg)), (val)) #define AUDIOHD_REG_SET16(reg, val) \ ddi_put16(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg)), (val)) #define AUDIOHD_REG_SET32(reg, val) \ ddi_put32(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg)), (val)) #define AUDIOHD_REG_SET64(reg, val) \ ddi_put64(statep->hda_reg_handle, \ (void *)((char *)statep->hda_reg_base + (reg)), (val)) /* * enable a pin widget to input */ #define AUDIOHD_ENABLE_PIN_IN(statep, caddr, wid) \ { \ (void) audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_SET_PIN_CTRL, AUDIOHDC_PIN_CONTROL_IN_ENABLE | 4); \ } /* * disable input pin */ #define AUDIOHD_DISABLE_PIN_IN(statep, caddr, wid) \ { \ uint32_t lTmp; \ \ lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_GET_PIN_CTRL, 0); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ return (DDI_FAILURE); \ lTmp = audioha_codec_verb_get(statep, caddr, wid, \ AUDIOHDC_VERB_SET_PIN_CTRL, \ (lTmp & ~AUDIOHDC_PIN_CONTROL_IN_ENABLE)); \ if (lTmp == AUDIOHD_CODEC_FAILURE) \ return (DDI_FAILURE); \ } /* * unmute an output pin */ #define AUDIOHD_NODE_UNMUTE_OUT(statep, caddr, wid) \ { \ if (audioha_codec_4bit_verb_get(statep, \ caddr, wid, AUDIOHDC_VERB_SET_AMP_MUTE, \ AUDIOHDC_AMP_SET_LR_OUTPUT | AUDIOHDC_GAIN_MAX) == \ AUDIOHD_CODEC_FAILURE) \ return (DDI_FAILURE); \ } /* * check volume adjust value of 2 channels control */ #define AUDIOHD_CHECK_2CHANNELS_VOLUME(value) \ { \ if ((value) & ~0xffff) \ return (EINVAL); \ if ((((value) & 0xff00) >> 8) > 100 || \ ((value) & 0xff) > 100) \ return (EINVAL); \ } /* * check volume adjust value of mono channel control */ #define AUDIOHD_CHECK_CHANNEL_VOLUME(value) \ { \ if ((value) & ~0xff) \ return (EINVAL); \ if (((value) & 0xff) > 100) \ return (EINVAL); \ } #ifdef __cplusplus } #endif /* Warlock annotation */ _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_ctrl::statep)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::inmask)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::adev)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::sample_bit_depth)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::sample_rate)) _NOTE(READ_ONLY_DATA(audiohd_state::hda_reg_handle)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_widget::codec)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_widget::wid_wid)) _NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::index)) _NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::statep)) _NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::vid)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::nchan)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::statep)) _NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::sync_dir)) #endif /* _SYS_AUDIOHD_IMPL_H_ */