--- uts/common/sys/audio/impl/audiohd_impl.h.3326 Tue Dec 19 22:30:39 2006 +++ uts/common/sys/audio/impl/audiohd_impl.h Thu Jan 11 07:12:21 2007 @@ -55,6 +55,9 @@ #define AUDIOHD_VID_ALC888 0x10ec0888 #define AUDIOHD_VID_STAC9200 0x83847690 #define AUDIOHD_VID_STAC9200D 0x83847691 +#define AUDIOHD_VID_CXD9872RD 0x83847661 +#define AUDIOHD_VID_STAC9872AK 0x83847662 +#define AUDIOHD_VID_CXD9872AKD 0x83847664 #define AUDIOHD_VID_AD1986A 0x11d41986 #define AUDIOHD_VID_AD1988A 0x11d41988 #define AUDIOHD_VID_AD1988B 0x11d4198b --- uts/common/io/audio/sada/drv/audiohd/audiohd.c.3341 Thu Dec 21 00:00:31 2006 +++ uts/common/io/audio/sada/drv/audiohd/audiohd.c Thu Jan 11 06:55:16 2007 @@ -143,9 +143,10 @@ /* - * operation routines for STAC9200 codec + * operation routines for STAC9200 and STAC9872 codecs */ -static int audiohd_stac_init_codec(audiohd_state_t *); +static int audiohd_stac9872_init_codec(audiohd_state_t *); +static int audiohd_stac9200_init_codec(audiohd_state_t *); static int audiohd_stac_set_pcm_fmt(audiohd_state_t *, int, uint_t); static int audiohd_stac_set_gain(audiohd_state_t *, int, int, int); static int audiohd_stac_set_port(audiohd_state_t *, int, int); @@ -156,7 +157,7 @@ /* ops for STAC9200, STAC9200D */ static struct audiohd_codec_ops audiohd_stac9200_ops = { - audiohd_stac_init_codec, /* ac_init_codec */ + audiohd_stac9200_init_codec, /* ac_init_codec */ audiohd_stac_set_pcm_fmt, /* ac_set_pcm_fmt */ audiohd_stac_set_gain, /* ac_set_out_gain */ audiohd_stac_set_port, /* ac_set_port */ @@ -165,6 +166,17 @@ audiohd_stac_max_gain /* ac_get_max_gain */ }; +/* ops for STAC9872 (CXD9872RD, STAC9872AK, CXD9872AKD) */ +static struct audiohd_codec_ops audiohd_stac9872_ops = { + audiohd_stac9872_init_codec, /* ac_init_codec */ + audiohd_stac_set_pcm_fmt, /* ac_set_pcm_fmt */ + audiohd_stac_set_gain, /* ac_set_out_gain */ + audiohd_stac_set_port, /* ac_set_port */ + audiohd_stac_mute_outputs, /* ac_mute_outputs */ + audiohd_stac_set_monitor_gain, /* ac_set_monitor_gain */ + audiohd_stac_max_gain /* ac_get_max_gain */ +}; + /* * operation routines for AD1986A codec */ @@ -1765,6 +1777,13 @@ found = B_TRUE; break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + codec->hc_ops = &audiohd_stac9872_ops; + found = B_TRUE; + break; + case AUDIOHD_VID_STAC9200: case AUDIOHD_VID_STAC9200D: codec->hc_ops = &audiohd_stac9200_ops; @@ -3158,10 +3177,10 @@ /* - * audiohd_stac_init_codec() + * audiohd_stac9200_init_codec() */ static int -audiohd_stac_init_codec(audiohd_state_t *statep) +audiohd_stac9200_init_codec(audiohd_state_t *statep) { uint_t inputs, outputs; uint_t caddr = statep->hda_codec->hc_addr; @@ -3234,9 +3253,104 @@ return (AUDIO_SUCCESS); -} /* audiohd_stac_init_codec() */ +} /* audiohd_stac9200_init_codec() */ +/* + * audiohd_stac9872_init_codec() + */ +static int +audiohd_stac9872_init_codec(audiohd_state_t *statep) +{ + uint_t inputs, outputs; + uint_t caddr = statep->hda_codec->hc_addr; + ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); + + /* power-up AFG node */ + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x1), AUDIOHDC_VERB_SET_POWER_STATE, 0); + + + /* power-up DAC_0 */ + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_POWER_STATE, 0); + + AUDIOHD_NODE_INIT_DAC(statep, caddr, AUDIOHDC_NID(0x2)); + + /* power-up DAC_1 */ + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_POWER_STATE, 0); + + AUDIOHD_NODE_INIT_DAC(statep, caddr, AUDIOHDC_NID(0x5)); + + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, AUDIOHDC_NID(0xA)); /* HP */ + + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, AUDIOHDC_NID(0xF)); /* Speaker */ + + AUDIOHD_NODE_ENABLE_PIN_IN(statep, caddr, AUDIOHDC_NID(0xD)); /* Mic_1 */ + + AUDIOHD_NODE_ENABLE_PIN_IN(statep, caddr, AUDIOHDC_NID(0xE)); /* CD */ + + AUDIOHD_NODE_ENABLE_PIN_IN(statep, caddr, AUDIOHDC_NID(0x14)); /* Mic_2 */ + + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_CONN_SEL, 0x2); + + outputs = AUDIO_HEADPHONE | AUDIO_LINE_OUT; + + statep->hda_info_defaults.play.port = outputs; + statep->hda_info_defaults.play.avail_ports = outputs; + statep->hda_info_defaults.play.mod_ports = outputs; + statep->hda_out_ports = 0; + + /* set master volume to max */ + + /* HP volume */ + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_ROUT_MAX); + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_LOUT_MAX); + /* Speaker volume */ + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_ROUT_MAX); + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_LOUT_MAX); + + /* + * Up to now, we initialized playback paths. we begin + * to initialize record paths. + */ + inputs = AUDIO_MICROPHONE | AUDIO_LINE_IN | AUDIO_CD; + statep->hda_info_defaults.record.port = AUDIO_MICROPHONE; + statep->hda_info_defaults.record.avail_ports = inputs; + statep->hda_info_defaults.record.mod_ports = inputs; + statep->hda_in_ports = 0; + + /* power-up ADC nodes */ + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x8), AUDIOHDC_VERB_SET_POWER_STATE, 0); + + AUDIOHD_NODE_INIT_ADC(statep, caddr, AUDIOHDC_NID(0x8)); + + /* set MUX volume to max */ + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_ROUT_MAX); + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_LOUT_MAX); + + + return (AUDIO_SUCCESS); + +} /* audiohd_stac9872_init_codec() */ + /* * audiohd_stac_set_pcm_fmt() */ @@ -3247,14 +3361,31 @@ uint_t caddr = statep->hda_codec->hc_addr; ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); if (dir == AUDIO_PLAY) { lTmp = audioha_codec_4bit_verb_get(statep, caddr, AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_CONVERTER_FMT, format); } else { - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0x3), AUDIOHDC_VERB_SET_CONVERTER_FMT, format); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x3), AUDIOHDC_VERB_SET_CONVERTER_FMT, format); + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x8), AUDIOHDC_VERB_SET_CONVERTER_FMT, format); + break; + default: + break; + } + } if (lTmp == AUDIOHD_CODEC_FAILURE) @@ -3274,8 +3405,12 @@ uint_t val, lTmp; uint_t caddr = statep->hda_codec->hc_addr; + ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); if (dir == AUDIO_PLAY) { @@ -3290,8 +3425,30 @@ statep->hda_play_rgain = gain; } - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + val); + + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); + + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + val); + break; + default: + break; + } + } else { ASSERT(dir == AUDIO_RECORD); val = AUDIOHDC_AMP_SET_OUTPUT | gain; @@ -3305,8 +3462,21 @@ statep->hda_record_rgain = gain; } - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xA), AUDIOHDC_VERB_SET_AMP_MUTE, val); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xA), AUDIOHDC_VERB_SET_AMP_MUTE, val); + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x9), AUDIOHDC_VERB_SET_AMP_MUTE, val); + break; + default: + break; + } } if (lTmp == AUDIOHD_CODEC_FAILURE) @@ -3328,24 +3498,51 @@ uint_t caddr = statep->hda_codec->hc_addr; ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); if (dir == AUDIO_PLAY) { if (port == AUDIOHD_PORT_UNMUTE) port = statep->hda_out_ports; - if (port & AUDIO_HEADPHONE) { - tmp_port |= AUDIO_HEADPHONE; - AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0D); - } else { - AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0D); - } + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + if (port & AUDIO_HEADPHONE) { + tmp_port |= AUDIO_HEADPHONE; + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0D); + } else { + AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0D); + } - if (port & AUDIO_LINE_OUT) { - tmp_port |= AUDIO_LINE_OUT; - AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0E); - } else { - AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0E); + if (port & AUDIO_LINE_OUT) { + tmp_port |= AUDIO_LINE_OUT; + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0E); + } else { + AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0E); + } + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + if (port & AUDIO_HEADPHONE) { + tmp_port |= AUDIO_HEADPHONE; + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0A); + } else { + AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0A); + } + + if (port & AUDIO_LINE_OUT) { + tmp_port |= AUDIO_LINE_OUT; + AUDIOHD_NODE_ENABLE_PIN_OUT(statep, caddr, 0x0F); + } else { + AUDIOHD_NODE_DISABLE_PIN_OUT(statep, caddr, 0x0F); + } + break; + default: + break; } statep->hda_out_ports = tmp_port; @@ -3358,32 +3555,71 @@ ASSERT(dir == AUDIO_RECORD); nid = 0; - switch (port) { - case AUDIO_NONE: - nid = statep->hda_in_ports; - if (nid != 0) { - AUDIOHD_NODE_DISABLE_PIN_IN(statep, caddr, nid); - statep->hda_in_ports = 0; - } - return (AUDIO_SUCCESS); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + switch (port) { + case AUDIO_NONE: + nid = statep->hda_in_ports; + if (nid != 0) { + AUDIOHD_NODE_DISABLE_PIN_IN(statep, caddr, nid); + statep->hda_in_ports = 0; + } + return (AUDIO_SUCCESS); - case AUDIO_MICROPHONE: - index_port = 0; - nid = 0x10; - break; + case AUDIO_MICROPHONE: + index_port = 0; + nid = 0x10; + break; - case AUDIO_LINE_IN: - index_port = 1; - nid = 0x0F; - break; + case AUDIO_LINE_IN: + index_port = 1; + nid = 0x0F; + break; - case AUDIO_CD: - index_port = 4; - nid = 0x12; + case AUDIO_CD: + index_port = 4; + nid = 0x12; + break; + + default: + return (AUDIO_FAILURE); + } break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + switch (port) { + case AUDIO_NONE: + nid = statep->hda_in_ports; + if (nid != 0) { + AUDIOHD_NODE_DISABLE_PIN_IN(statep, caddr, nid); + statep->hda_in_ports = 0; + } + return (AUDIO_SUCCESS); + + case AUDIO_MICROPHONE: + index_port = 1; + nid = 0x0D; + break; + + case AUDIO_LINE_IN: + index_port = 2; + nid = 0x14; + break; + + case AUDIO_CD: + index_port = 3; + nid = 0x0E; + break; + + default: + return (AUDIO_FAILURE); + } + break; default: - return (AUDIO_FAILURE); + break; } if (nid != statep->hda_in_ports) { @@ -3395,9 +3631,23 @@ /* enable currently selected input */ AUDIOHD_NODE_ENABLE_PIN_IN(statep, caddr, nid); - (void) audioha_codec_verb_get(statep, caddr, - AUDIOHDC_NID(0xC), AUDIOHDC_VERB_SET_CONN_SEL, - index_port); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0xC), AUDIOHDC_VERB_SET_CONN_SEL, + index_port); + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + (void) audioha_codec_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_CONN_SEL, + index_port); + break; + default: + break; + } } return (AUDIO_SUCCESS); @@ -3414,7 +3664,10 @@ uint32_t lTmp; ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); if (statep->hda_outputs_muted == mute) return (AUDIO_SUCCESS); @@ -3421,26 +3674,83 @@ statep->hda_outputs_muted = mute; - if (mute) { - /* mute master volume */ - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, - AUDIOHDC_AMP_SET_MUTE | AUDIOHDC_AMP_SET_LR_OUTPUT); - } else { - /* resume left volume */ - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, - AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | - statep->hda_play_lgain); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + if (mute) { + /* mute master volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_MUTE | AUDIOHDC_AMP_SET_LR_OUTPUT); + } else { + /* resume left volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | + statep->hda_play_lgain); - if (lTmp == AUDIOHD_CODEC_FAILURE) - return (AUDIO_FAILURE); + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); - /* resume right volume */ - lTmp = audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, - AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | - statep->hda_play_rgain); + /* resume right volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | + statep->hda_play_rgain); + } + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + if (mute) { + /* mute master volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_MUTE | AUDIOHDC_AMP_SET_LR_OUTPUT); + + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); + + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_MUTE | AUDIOHDC_AMP_SET_LR_OUTPUT); + } else { + /* resume left volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | + statep->hda_play_lgain); + + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); + + /* resume right volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x2), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | + statep->hda_play_rgain); + + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); + + /* resume left volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | + statep->hda_play_lgain); + + if (lTmp == AUDIOHD_CODEC_FAILURE) + return (AUDIO_FAILURE); + + /* resume right volume */ + lTmp = audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x5), AUDIOHDC_VERB_SET_AMP_MUTE, + AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | + statep->hda_play_rgain); + } + break; + default: + break; } if (lTmp == AUDIOHD_CODEC_FAILURE) @@ -3460,20 +3770,41 @@ uint_t val; ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872RD) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9872AK) || + (statep->hda_codec->hc_vid == AUDIOHD_VID_CXD9872AKD)); + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: /* * STAC9200(D) has no specific hardware/node to control * monitor gain, so we just adjust output volume */ - val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | gain; - (void) audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); + val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | gain; + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); - val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | gain; - (void) audioha_codec_4bit_verb_get(statep, caddr, - AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); + val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | gain; + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0xB), AUDIOHDC_VERB_SET_AMP_MUTE, val); + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_LEFT | gain; + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_AMP_MUTE, val); + val = AUDIOHDC_AMP_SET_OUTPUT | AUDIOHDC_AMP_SET_RIGHT | gain; + (void) audioha_codec_4bit_verb_get(statep, caddr, + AUDIOHDC_NID(0x15), AUDIOHDC_VERB_SET_AMP_MUTE, val); + break; + default: + break; + } + statep->hda_monitor_gain = gain; return (AUDIO_SUCCESS); @@ -3486,13 +3817,22 @@ static void audiohd_stac_max_gain(audiohd_state_t *statep, uint_t *pgain, uint_t *rgain, uint_t *mgain) { - ASSERT((statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200) || - (statep->hda_codec->hc_vid == AUDIOHD_VID_STAC9200D)); - - *pgain = 0x1f; - *rgain = 0x1f; - *mgain = 0x1f; - + switch (statep->hda_codec->hc_vid) { + case AUDIOHD_VID_STAC9200: + case AUDIOHD_VID_STAC9200D: + *pgain = 0x1f; + *rgain = 0x1f; + *mgain = 0x1f; + break; + case AUDIOHD_VID_CXD9872RD: + case AUDIOHD_VID_STAC9872AK: + case AUDIOHD_VID_CXD9872AKD: + *pgain = 0x7f; + *rgain = 0x7f; + *mgain = 0x7f; + default: + break; + } } /* audiohd_stac_max_gain() */