summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/audio/ac97/ac97.c553
-rw-r--r--usr/src/uts/common/io/audio/ac97/ac97_ad.c47
-rw-r--r--usr/src/uts/common/io/audio/ac97/ac97_alc.c40
-rw-r--r--usr/src/uts/common/io/audio/ac97/ac97_cmi.c82
-rw-r--r--usr/src/uts/common/io/audio/ac97/ac97_impl.h55
-rw-r--r--usr/src/uts/common/sys/audio/ac97.h43
6 files changed, 468 insertions, 352 deletions
diff --git a/usr/src/uts/common/io/audio/ac97/ac97.c b/usr/src/uts/common/io/audio/ac97/ac97.c
index f36df6af43..dc35e279c9 100644
--- a/usr/src/uts/common/io/audio/ac97/ac97.c
+++ b/usr/src/uts/common/io/audio/ac97/ac97.c
@@ -76,7 +76,7 @@
#define INPUT_MONOMIX 6
#define INPUT_PHONE 7
-static const char *ac97_insrcs[] = {
+static const char *ac_insrcs[] = {
AUDIO_PORT_MIC,
AUDIO_PORT_CD,
AUDIO_PORT_VIDEO,
@@ -221,7 +221,7 @@ static const char ac97_val_cvt[101] = {
* ( each channel is "bits" wide )
*/
uint16_t
-ac97_val_scale(int left, int right, int bits)
+ac_val_scale(int left, int right, int bits)
{
ASSERT(left <= 100);
ASSERT(right <= 100);
@@ -257,7 +257,7 @@ ac97_val_scale(int left, int right, int bits)
}
uint16_t
-ac97_mono_scale(int val, int bits)
+ac_mono_scale(int val, int bits)
{
ASSERT(val <= 100);
@@ -269,15 +269,14 @@ ac97_mono_scale(int val, int bits)
return (val * ((1 << bits) - 1) / 100);
}
-
audio_dev_t *
-ac97_get_dev(ac97_t *ac)
+ac_get_dev(ac97_t *ac)
{
return (ac->d);
}
int
-ac97_get_prop(ac97_t *ac, char *prop, int defval)
+ac_get_prop(ac97_t *ac, char *prop, int defval)
{
int rv;
@@ -313,7 +312,7 @@ ac97_get_prop(ac97_t *ac, char *prop, int defval)
* detection.)
*/
static int
-ac97_probe_reg(ac97_t *ac, uint8_t reg)
+ac_probe_reg(ac97_t *ac, uint8_t reg)
{
uint16_t val;
int rv = 0;
@@ -333,7 +332,7 @@ ac97_probe_reg(ac97_t *ac, uint8_t reg)
* Does this device have bass/treble controls?
*/
static int
-ac97_probe_tone(ac97_t *ac)
+ac_probe_tone(ac97_t *ac)
{
/* Bass/Treble contols present */
if (ac->caps & RR_BASS_TREBLE)
@@ -346,7 +345,7 @@ ac97_probe_tone(ac97_t *ac)
* If there is a loudness switch?
*/
static int
-ac97_probe_loud(ac97_t *ac)
+ac_probe_loud(ac97_t *ac)
{
/* loudness contol present */
if (ac->caps & RR_LOUDNESS_SUPPORT)
@@ -359,7 +358,7 @@ ac97_probe_loud(ac97_t *ac)
* Does this device have a mono-mic input volume control?
*/
static int
-ac97_probe_mmic(ac97_t *ac)
+ac_probe_mmic(ac97_t *ac)
{
/* mono mic present */
if (ac->caps & RR_DEDICATED_MIC)
@@ -372,7 +371,7 @@ ac97_probe_mmic(ac97_t *ac)
* Does this device have a simulated stereo switch?
*/
static int
-ac97_probe_stsim(ac97_t *ac)
+ac_probe_stsim(ac97_t *ac)
{
/* simulated stereocontol present */
if (ac->caps & RR_PSEUDO_STEREO)
@@ -385,16 +384,16 @@ ac97_probe_stsim(ac97_t *ac)
* Does this device have a PC beeper input volume control?
*/
static int
-ac97_probe_pcbeep(ac97_t *ac)
+ac_probe_pcbeep(ac97_t *ac)
{
- return (ac97_probe_reg(ac, AC97_PC_BEEP_REGISTER));
+ return (ac_probe_reg(ac, AC97_PC_BEEP_REGISTER));
}
/*
* Does this device have AUX output port volume control?
*/
static int
-ac97_probe_rear(ac97_t *ac)
+ac_probe_rear(ac97_t *ac)
{
if (ac->flags & AC97_FLAG_AUX_4CH)
return (1);
@@ -407,10 +406,10 @@ ac97_probe_rear(ac97_t *ac)
* Does this device have a mic?
*/
static int
-ac97_probe_mic(ac97_t *ac)
+ac_probe_mic(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_MIC)) &&
- (ac97_probe_reg(ac, AC97_MIC_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_MIC_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_MIC);
return (1);
}
@@ -421,7 +420,7 @@ ac97_probe_mic(ac97_t *ac)
* If this device has an AUX output port is it used for headphones?
*/
static int
-ac97_probe_headphone(ac97_t *ac)
+ac_probe_headphone(ac97_t *ac)
{
/* headphone control present */
if ((ac->flags & AC97_FLAG_AUX_HP) &&
@@ -435,7 +434,7 @@ ac97_probe_headphone(ac97_t *ac)
* Does this device have AUX output port volume control?
*/
static int
-ac97_probe_auxout(ac97_t *ac)
+ac_probe_auxout(ac97_t *ac)
{
/* ALT PCM control present */
if ((ac->flags & AC97_FLAG_AUX_LVL) &&
@@ -449,10 +448,10 @@ ac97_probe_auxout(ac97_t *ac)
* Does this device have an AUX input port volume control?
*/
static int
-ac97_probe_auxin(ac97_t *ac)
+ac_probe_auxin(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_AUXIN)) &&
- (ac97_probe_reg(ac, AC97_AUX_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_AUX_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_AUXIN);
return (1);
}
@@ -463,10 +462,10 @@ ac97_probe_auxin(ac97_t *ac)
* Does this device have a phone input port with a volume control?
*/
static int
-ac97_probe_phone(ac97_t *ac)
+ac_probe_phone(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_PHONE)) &&
- (ac97_probe_reg(ac, AC97_PHONE_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_PHONE_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_PHONE);
return (1);
}
@@ -477,12 +476,12 @@ ac97_probe_phone(ac97_t *ac)
* Does this device have a mono output port with volume control?
*/
static int
-ac97_probe_mono(ac97_t *ac)
+ac_probe_mono(ac97_t *ac)
{
if (!(ac->flags & AC97_FLAG_SPEAKER_OK)) {
return (0);
}
- if (ac97_probe_reg(ac, AC97_MONO_MASTER_VOLUME_REGISTER)) {
+ if (ac_probe_reg(ac, AC97_MONO_MASTER_VOLUME_REGISTER)) {
return (1);
}
return (0);
@@ -492,10 +491,10 @@ ac97_probe_mono(ac97_t *ac)
* Does this device have a line input port with volume control?
*/
static int
-ac97_probe_linein(ac97_t *ac)
+ac_probe_linein(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_LINEIN)) &&
- (ac97_probe_reg(ac, AC97_LINE_IN_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_LINE_IN_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_LINEIN);
return (1);
}
@@ -506,10 +505,10 @@ ac97_probe_linein(ac97_t *ac)
* Does this device have a cdrom input port with volume control?
*/
static int
-ac97_probe_cdrom(ac97_t *ac)
+ac_probe_cdrom(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_CDROM)) &&
- (ac97_probe_reg(ac, AC97_CD_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_CD_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_CD);
return (1);
}
@@ -520,10 +519,10 @@ ac97_probe_cdrom(ac97_t *ac)
* Does this device have a video input port with volume control?
*/
static int
-ac97_probe_video(ac97_t *ac)
+ac_probe_video(ac97_t *ac)
{
if ((!(ac->flags & AC97_FLAG_NO_VIDEO)) &&
- (ac97_probe_reg(ac, AC97_VIDEO_VOLUME_REGISTER))) {
+ (ac_probe_reg(ac, AC97_VIDEO_VOLUME_REGISTER))) {
ac->inputs |= (1U << INPUT_VIDEO);
return (1);
}
@@ -534,7 +533,7 @@ ac97_probe_video(ac97_t *ac)
* Does this device have a 3D sound enhancement?
*/
static int
-ac97_probe_3d(ac97_t *ac)
+ac_probe_3d(ac97_t *ac)
{
/* 3D control present */
if (ac->caps & RR_3D_STEREO_ENHANCE_MASK)
@@ -544,7 +543,7 @@ ac97_probe_3d(ac97_t *ac)
}
static int
-ac97_probe_3d_impl(ac97_t *ac, uint16_t mask)
+ac_probe_3d_impl(ac97_t *ac, uint16_t mask)
{
int rv = 0;
uint16_t val;
@@ -564,22 +563,22 @@ ac97_probe_3d_impl(ac97_t *ac, uint16_t mask)
}
static int
-ac97_probe_3d_depth(ac97_t *ac)
+ac_probe_3d_depth(ac97_t *ac)
{
- return (ac97_probe_3d_impl(ac, TDCR_DEPTH_MASK));
+ return (ac_probe_3d_impl(ac, TDCR_DEPTH_MASK));
}
static int
-ac97_probe_3d_center(ac97_t *ac)
+ac_probe_3d_center(ac97_t *ac)
{
- return (ac97_probe_3d_impl(ac, TDCR_CENTER_MASK));
+ return (ac_probe_3d_impl(ac, TDCR_CENTER_MASK));
}
/*
* Does this device have a center output port with volume control?
*/
static int
-ac97_probe_center(ac97_t *ac)
+ac_probe_center(ac97_t *ac)
{
uint16_t val;
@@ -597,7 +596,7 @@ ac97_probe_center(ac97_t *ac)
* a volume control?
*/
static int
-ac97_probe_lfe(ac97_t *ac)
+ac_probe_lfe(ac97_t *ac)
{
uint16_t val;
@@ -615,7 +614,7 @@ ac97_probe_lfe(ac97_t *ac)
* Are we a multichannel codec?
*/
static int
-ac97_probe_front(ac97_t *ac)
+ac_probe_front(ac97_t *ac)
{
uint16_t val;
@@ -629,19 +628,19 @@ ac97_probe_front(ac97_t *ac)
}
static int
-ac97_probe_lineout(ac97_t *ac)
+ac_probe_lineout(ac97_t *ac)
{
/* if not multichannel, then use "lineout" instead of "front" label */
- return (!ac97_probe_front(ac));
+ return (!ac_probe_front(ac));
}
-static const char *ac97_mics[] = {
+static const char *ac_mics[] = {
AUDIO_PORT_MIC1,
AUDIO_PORT_MIC2,
NULL,
};
-static const char *ac97_monos[] = {
+static const char *ac_monos[] = {
AUDIO_PORT_MONOMIX,
AUDIO_PORT_MIC,
NULL
@@ -652,7 +651,7 @@ static const char *ac97_monos[] = {
* to write to a device register.
*/
void
-ac97_wr(ac97_t *ac, uint8_t reg, uint16_t val)
+ac_wr(ac97_t *ac, uint8_t reg, uint16_t val)
{
if ((reg < LAST_SHADOW_REG) && (reg > 0)) {
SHADOW(ac, reg) = val;
@@ -674,7 +673,7 @@ ac97_wr(ac97_t *ac, uint8_t reg, uint16_t val)
* To read a hardware register, use the RD() macro above.
*/
uint16_t
-ac97_rd(ac97_t *ac, uint8_t reg)
+ac_rd(ac97_t *ac, uint8_t reg)
{
if ((reg < LAST_SHADOW_REG) && (reg > 0)) {
return (SHADOW(ac, reg));
@@ -690,9 +689,9 @@ ac97_rd(ac97_t *ac, uint8_t reg)
* to set bits in a device register.
*/
void
-ac97_set(ac97_t *ac, uint8_t reg, uint16_t val)
+ac_set(ac97_t *ac, uint8_t reg, uint16_t val)
{
- ac97_wr(ac, reg, ac->rd(ac->private, reg) | val);
+ ac_wr(ac, reg, ac->rd(ac->private, reg) | val);
}
/*
@@ -700,9 +699,9 @@ ac97_set(ac97_t *ac, uint8_t reg, uint16_t val)
* to clear bits in a device register.
*/
void
-ac97_clr(ac97_t *ac, uint8_t reg, uint16_t val)
+ac_clr(ac97_t *ac, uint8_t reg, uint16_t val)
{
- ac97_wr(ac, reg, ac->rd(ac->private, reg) & ~val);
+ ac_wr(ac, reg, ac->rd(ac->private, reg) & ~val);
}
/*
@@ -719,14 +718,11 @@ ac97_control_find(ac97_t *ac, const char *name)
list_t *l = &ac->ctrls;
/* Validate that ctrlnum is real and usable */
- mutex_enter(&ac->ac_lock);
for (ctrl = list_head(l); ctrl; ctrl = list_next(l, ctrl)) {
if (strcmp(ctrl->actrl_name, name) == 0) {
- mutex_exit(&ac->ac_lock);
return (ctrl);
}
}
- mutex_exit(&ac->ac_lock);
return (NULL);
}
@@ -734,7 +730,7 @@ ac97_control_find(ac97_t *ac, const char *name)
* This will update all the codec registers from the shadow table.
*/
static void
-ac97_restore(ac97_t *ac)
+ac_restore(ac97_t *ac)
{
/*
* If we are restoring previous settings, just reload from the
@@ -760,7 +756,7 @@ ac97_restore(ac97_t *ac)
* start of day.
*/
static void
-ac97_init_values(ac97_t *ac)
+ac_init_values(ac97_t *ac)
{
ac97_ctrl_t *ctrl;
@@ -778,7 +774,7 @@ ac97_init_values(ac97_t *ac)
* for the control AUDIO_CONTROL_INPUTS.
*/
static void
-ac97_insrc_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_insrc_set(ac97_ctrl_t *ctrl, uint64_t value)
{
ac97_t *ac = ctrl->actrl_ac97;
uint16_t set_val;
@@ -786,13 +782,13 @@ ac97_insrc_set(ac97_ctrl_t *ctrl, uint64_t value)
set_val = ddi_ffs(value & 0xffff);
if ((set_val > 0) && (set_val <= 8)) {
set_val--;
- ac97_wr(ac, AC97_RECORD_SELECT_CTRL_REGISTER,
+ ac_wr(ac, AC97_RECORD_SELECT_CTRL_REGISTER,
set_val | (set_val << 8));
}
}
static void
-ac97_gpr_toggle(ac97_ctrl_t *ctrl, int bit, uint64_t onoff)
+ac_gpr_toggle(ac97_ctrl_t *ctrl, int bit, uint64_t onoff)
{
ac97_t *ac = ctrl->actrl_ac97;
uint16_t v;
@@ -803,56 +799,56 @@ ac97_gpr_toggle(ac97_ctrl_t *ctrl, int bit, uint64_t onoff)
} else {
v &= ~bit;
}
- ac97_wr(ac, AC97_GENERAL_PURPOSE_REGISTER, v);
+ ac_wr(ac, AC97_GENERAL_PURPOSE_REGISTER, v);
}
static void
-ac97_3donoff_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_3donoff_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_3D_STEREO_ENHANCE, value);
+ ac_gpr_toggle(ctrl, GPR_3D_STEREO_ENHANCE, value);
}
static void
-ac97_loudness_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_loudness_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_BASS_BOOST, value);
+ ac_gpr_toggle(ctrl, GPR_BASS_BOOST, value);
}
static void
-ac97_loopback_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_loopback_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_LPBK, value);
+ ac_gpr_toggle(ctrl, GPR_LPBK, value);
}
/*
* This will set simulated stereo control to on or off.
*/
static void
-ac97_stsim_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_stsim_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_ST, value);
+ ac_gpr_toggle(ctrl, GPR_ST, value);
}
/*
* This will set mic select control to mic1=0 or mic2=1.
*/
static void
-ac97_selmic_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_selmic_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_MS_MIC2, value & 2);
+ ac_gpr_toggle(ctrl, GPR_MS_MIC2, value & 2);
}
/*
* This will set mono source select control to mix=0 or mic=1.
*/
static void
-ac97_monosrc_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_monosrc_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_gpr_toggle(ctrl, GPR_MONO_MIC_IN, value & 2);
+ ac_gpr_toggle(ctrl, GPR_MONO_MIC_IN, value & 2);
}
static void
-ac97_stereo_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg)
+ac_stereo_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg)
{
ac97_t *ac = ctrl->actrl_ac97;
uint8_t left, right;
@@ -862,11 +858,11 @@ ac97_stereo_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg)
right = value & 0xff;
mute = value ? 0 : ctrl->actrl_muteable;
- ac97_wr(ac, reg, ac97_val_scale(left, right, ctrl->actrl_bits) | mute);
+ ac_wr(ac, reg, ac_val_scale(left, right, ctrl->actrl_bits) | mute);
}
static void
-ac97_mono_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg, int shift)
+ac_mono_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg, int shift)
{
ac97_t *ac = ctrl->actrl_ac97;
uint8_t val;
@@ -884,131 +880,131 @@ ac97_mono_set(ac97_ctrl_t *ctrl, uint64_t value, uint8_t reg, int shift)
/* now set the mute bit, and volume bits */
v |= mute;
- v |= (ac97_mono_scale(val, ctrl->actrl_bits) << shift);
+ v |= (ac_mono_scale(val, ctrl->actrl_bits) << shift);
- ac97_wr(ac, reg, v);
+ ac_wr(ac, reg, v);
}
static void
ac97_master_set(ac97_ctrl_t *ctrl, uint64_t value)
{
value = value | (value << 8);
- ac97_stereo_set(ctrl, value, AC97_PCM_OUT_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_PCM_OUT_VOLUME_REGISTER);
}
static void
ac97_lineout_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_MASTER_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_MASTER_VOLUME_REGISTER);
}
static void
ac97_surround_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_EXTENDED_LRS_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_EXTENDED_LRS_VOLUME_REGISTER);
}
static void
ac97_aux1out_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_HEADPHONE_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_HEADPHONE_VOLUME_REGISTER);
}
static void
ac97_headphone_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_HEADPHONE_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_HEADPHONE_VOLUME_REGISTER);
}
static void
-ac97_cd_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_cd_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_CD_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_CD_VOLUME_REGISTER);
}
static void
-ac97_video_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_video_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_VIDEO_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_VIDEO_VOLUME_REGISTER);
}
static void
-ac97_auxin_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_auxin_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_AUX_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_AUX_VOLUME_REGISTER);
}
static void
-ac97_linein_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_linein_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_LINE_IN_VOLUME_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_LINE_IN_VOLUME_REGISTER);
}
/*
* This will set mono mic gain control.
*/
static void
-ac97_monomic_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_monomic_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_RECORD_GAIN_MIC_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_RECORD_GAIN_MIC_REGISTER, 0);
}
static void
-ac97_phone_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_phone_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_PHONE_VOLUME_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_PHONE_VOLUME_REGISTER, 0);
}
static void
-ac97_mic_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_mic_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_MIC_VOLUME_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_MIC_VOLUME_REGISTER, 0);
}
static void
-ac97_speaker_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_speaker_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_MONO_MASTER_VOLUME_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_MONO_MASTER_VOLUME_REGISTER, 0);
}
static void
-ac97_pcbeep_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_pcbeep_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_PC_BEEP_REGISTER, 1);
+ ac_mono_set(ctrl, value, AC97_PC_BEEP_REGISTER, 1);
}
static void
-ac97_recgain_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_recgain_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_stereo_set(ctrl, value, AC97_RECORD_GAIN_REGISTER);
+ ac_stereo_set(ctrl, value, AC97_RECORD_GAIN_REGISTER);
}
static void
-ac97_center_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_center_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 0);
}
static void
-ac97_lfe_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_lfe_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 8);
+ ac_mono_set(ctrl, value, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 8);
}
static void
-ac97_bass_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_bass_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_MASTER_TONE_CONTROL_REGISTER, 8);
+ ac_mono_set(ctrl, value, AC97_MASTER_TONE_CONTROL_REGISTER, 8);
}
static void
-ac97_treble_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_treble_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_mono_set(ctrl, value, AC97_MASTER_TONE_CONTROL_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_MASTER_TONE_CONTROL_REGISTER, 0);
}
static void
-ac97_3ddepth_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_3ddepth_set(ac97_ctrl_t *ctrl, uint64_t value)
{
/*
* XXX: This is all wrong... 3D depth/center cannot necessarily
@@ -1016,11 +1012,11 @@ ac97_3ddepth_set(ac97_ctrl_t *ctrl, uint64_t value)
* need more information about each of the options available
* to do the right thing.
*/
- ac97_mono_set(ctrl, value, AC97_THREE_D_CONTROL_REGISTER, 0);
+ ac_mono_set(ctrl, value, AC97_THREE_D_CONTROL_REGISTER, 0);
}
static void
-ac97_3dcent_set(ac97_ctrl_t *ctrl, uint64_t value)
+ac_3dcent_set(ac97_ctrl_t *ctrl, uint64_t value)
{
/*
* XXX: This is all wrong... 3D depth/center cannot necessarily
@@ -1028,7 +1024,7 @@ ac97_3dcent_set(ac97_ctrl_t *ctrl, uint64_t value)
* need more information about each of the options available
* to do the right thing.
*/
- ac97_mono_set(ctrl, value, AC97_THREE_D_CONTROL_REGISTER, 8);
+ ac_mono_set(ctrl, value, AC97_THREE_D_CONTROL_REGISTER, 8);
}
static void
@@ -1043,7 +1039,7 @@ ac97_micboost_set(ac97_ctrl_t *ctrl, uint64_t value)
} else {
v &= ~MICVR_20dB_BOOST;
}
- ac97_wr(ac, AC97_MIC_VOLUME_REGISTER, v);
+ ac_wr(ac, AC97_MIC_VOLUME_REGISTER, v);
}
/*
@@ -1058,10 +1054,9 @@ ac97_micboost_set(ac97_ctrl_t *ctrl, uint64_t value)
*
* On success zero is returned.
*/
-static int
-ac97_control_get(void *arg, uint64_t *value)
+int
+ac97_control_get(ac97_ctrl_t *ctrl, uint64_t *value)
{
- ac97_ctrl_t *ctrl = arg;
ac97_t *ac = ctrl->actrl_ac97;
mutex_enter(&ac->ac_lock);
@@ -1071,10 +1066,9 @@ ac97_control_get(void *arg, uint64_t *value)
return (0);
}
-static int
-ac97_control_set(void *arg, uint64_t value)
+int
+ac97_control_set(ac97_ctrl_t *ctrl, uint64_t value)
{
- ac97_ctrl_t *ctrl = arg;
ac97_t *ac = ctrl->actrl_ac97;
uint8_t v1, v2;
@@ -1114,6 +1108,18 @@ ac97_control_set(void *arg, uint64_t value)
return (0);
}
+static int
+ac_get_value(void *arg, uint64_t *value)
+{
+ return (ac97_control_get(arg, value));
+}
+
+static int
+ac_set_value(void *arg, uint64_t value)
+{
+ return (ac97_control_set(arg, value));
+}
+
/*
* This simply sets a flag to block calls to the underlying
* hardware driver to get or set hardware controls. This is usually
@@ -1143,7 +1149,7 @@ ac97_suspend(ac97_t *ac)
* Wait a resonable amount of time for hardware to become ready.
*/
static void
-ac97_analog_reset(ac97_t *ac)
+ac_analog_reset(ac97_t *ac)
{
uint16_t tmp;
int wait = 1000; /* delay for up to 1s */
@@ -1171,7 +1177,7 @@ ac97_analog_reset(ac97_t *ac)
}
}
- audio_dev_warn(ac->d, "AC'97 analog powerup timed out");
+ audio_dev_warn(ac->d, "AC'97 analog power up timed out");
}
/*
@@ -1187,33 +1193,33 @@ ac97_analog_reset(ac97_t *ac)
* last updated versions.
*/
static void
-ac97_hw_reset(ac97_t *ac)
+ac_hw_reset(ac97_t *ac)
{
/*
* Fully Power up the device
*/
if (ac->flags & AC97_FLAG_AMPLIFIER) {
/* power up - external amp powerd up */
- ac97_wr(ac, AC97_POWERDOWN_CTRL_STAT_REGISTER, 0);
+ ac_wr(ac, AC97_POWERDOWN_CTRL_STAT_REGISTER, 0);
} else {
/* power up - external amp powered down */
- ac97_wr(ac, AC97_POWERDOWN_CTRL_STAT_REGISTER, PCSR_EAPD);
+ ac_wr(ac, AC97_POWERDOWN_CTRL_STAT_REGISTER, PCSR_EAPD);
}
- ac97_wr(ac, AC97_GENERAL_PURPOSE_REGISTER, 0);
+ ac_wr(ac, AC97_GENERAL_PURPOSE_REGISTER, 0);
switch (ac->vid) {
case AC97_CODEC_STAC9708:
#if 0
/* non-inverted phase */
- /* ac97_rd(ac, AC97_VENDOR_REGISTER_11) & ~0x8); */
+ /* ac_rd(ac, AC97_VENDOR_REGISTER_11) & ~0x8); */
#endif
WR(AC97_VENDOR_REGISTER_11, 8);
break;
case AC97_CODEC_EM28028:
- ac97_wr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER,
- (ac97_rd(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER) &
+ ac_wr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER,
+ (ac_rd(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER) &
~3800) | 0xE0);
break;
@@ -1228,7 +1234,7 @@ ac97_hw_reset(ac97_t *ac)
#if 0
/* GED: This looks fishy to me, so I'm nuking it for now */
/* headphone/aux volume (?) */
- ac97_wr(ac, AC97_HEADPHONE_VOLUME_REGISTER, 0x0808);
+ ac_wr(ac, AC97_HEADPHONE_VOLUME_REGISTER, 0x0808);
#endif
break;
@@ -1254,7 +1260,7 @@ ac97_hw_reset(ac97_t *ac)
case AC97_CODEC_VT1617A:
case AC97_CODEC_VT1616:
/* Turn off Center, Surround, and LFE DACs */
- ac97_clr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER,
+ ac_clr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER,
EASCR_PRI | EASCR_PRJ | EASCR_PRK);
WR(AC97_VENDOR_REGISTER_01, 0x0230);
break;
@@ -1274,7 +1280,7 @@ ac97_hw_reset(ac97_t *ac)
}
/* Turn off variable sampling rate support */
- ac97_clr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER, EASCR_VRA);
+ ac_clr(ac, AC97_EXTENDED_AUDIO_STAT_CTRL_REGISTER, EASCR_VRA);
}
/*
@@ -1298,9 +1304,9 @@ ac97_reset(ac97_t *ac)
mutex_exit(&ac->ac_lock);
return;
}
- ac97_analog_reset(ac);
- ac97_hw_reset(ac);
- ac97_restore(ac);
+ ac_analog_reset(ac);
+ ac_hw_reset(ac);
+ ac_restore(ac);
mutex_exit(&ac->ac_lock);
}
@@ -1324,9 +1330,9 @@ ac97_resume(ac97_t *ac)
ac->resumer = ddi_get_kt_did();
/* We simply call reset since the operation is the same */
- ac97_analog_reset(ac);
- ac97_hw_reset(ac);
- ac97_restore(ac);
+ ac_analog_reset(ac);
+ ac_hw_reset(ac);
+ ac_restore(ac);
ac->resumer = 0;
ac->suspended = B_FALSE;
@@ -1345,82 +1351,134 @@ ac97_num_channels(ac97_t *ac)
/*
* Register a control -- if it fails, it will generate a message to
* syslog, but the driver muddles on. (Failure to register a control
- * should never occur, and is generally benign if it happens.)
+ * should never occur, but is generally benign if it happens.)
*/
void
-ac97_alloc_control(ac97_t *ac, ac97_ctrl_probe_t *cpt)
+ac97_control_register(ac97_ctrl_t *ctrl)
+{
+ ac97_t *ac = ctrl->actrl_ac97;
+ ASSERT(ac->d != NULL);
+
+ ctrl->actrl_suppress = B_FALSE;
+
+ /* Register control with framework */
+ ctrl->actrl_ctrl = audio_dev_add_control(ac->d, &ctrl->actrl_desc,
+ ac_get_value, ac_set_value, ctrl);
+ if (ctrl->actrl_ctrl == NULL) {
+ audio_dev_warn(ac->d, "AC97 %s alloc failed",
+ ctrl->actrl_name);
+ }
+}
+
+void
+ac97_control_unregister(ac97_ctrl_t *ctrl)
+{
+ ctrl->actrl_suppress = B_TRUE;
+
+ if (ctrl->actrl_ctrl != NULL) {
+ audio_dev_del_control(ctrl->actrl_ctrl);
+ ctrl->actrl_ctrl = NULL;
+ }
+}
+
+const char *
+ac97_control_name(ac97_ctrl_t *ctrl)
+{
+ return (ctrl->actrl_name);
+}
+
+const audio_ctrl_desc_t *
+ac97_control_desc(ac97_ctrl_t *ctrl)
+{
+ return (&ctrl->actrl_desc);
+}
+
+void
+ac97_register_controls(ac97_t *ac)
+{
+ ac97_ctrl_t *ctrl;
+
+ for (ctrl = list_head(&ac->ctrls); ctrl;
+ ctrl = list_next(&ac->ctrls, ctrl)) {
+ if (ctrl->actrl_suppress)
+ continue;
+ ac97_control_register(ctrl);
+ }
+}
+
+void
+ac97_walk_controls(ac97_t *ac, ac97_ctrl_walk_t walker, void *arg)
+{
+ ac97_ctrl_t *ctrl;
+
+ for (ctrl = list_head(&ac->ctrls); ctrl;
+ ctrl = list_next(&ac->ctrls, ctrl)) {
+ if (!(*walker)(ctrl, arg)) {
+ break;
+ }
+ }
+}
+
+void
+ac_add_control(ac97_t *ac, ac97_ctrl_probe_t *cpt)
{
ac97_ctrl_t *ctrl;
- audio_ctrl_desc_t ctrl_des;
+ boolean_t is_new;
ASSERT(ac);
ASSERT(ac->d);
- ctrl = kmem_zalloc(sizeof (ac97_ctrl_t), KM_SLEEP);
-
- bzero(&ctrl_des, sizeof (ctrl_des));
- ctrl_des.acd_name = cpt->cp_name;
- ctrl_des.acd_minvalue = cpt->cp_minval;
- ctrl_des.acd_maxvalue = cpt->cp_maxval;
- ctrl_des.acd_type = cpt->cp_type;
- ctrl_des.acd_flags = cpt->cp_flags;
+ ctrl = ac97_control_find(ac, cpt->cp_name);
+ if (ctrl != NULL) {
+ is_new = B_FALSE;
+ } else {
+ ctrl = kmem_zalloc(sizeof (ac97_ctrl_t), KM_SLEEP);
+ is_new = B_TRUE;
+ }
+ ctrl->actrl_ac97 = ac;
+ ctrl->actrl_minval = cpt->cp_minval;
+ ctrl->actrl_maxval = cpt->cp_maxval;
+ ctrl->actrl_type = cpt->cp_type;
+ ctrl->actrl_name = cpt->cp_name;
+ ctrl->actrl_flags = cpt->cp_flags;
if (cpt->cp_enum) {
for (int e = 0; e < 64; e++) {
if (cpt->cp_enum[e] == NULL)
break;
- ctrl_des.acd_enum[e] = cpt->cp_enum[e];
+ ctrl->actrl_enum[e] = cpt->cp_enum[e];
}
}
- ctrl->actrl_ac97 = ac;
/*
* Warning for extended controls this field gets changed
* by audio_dev_add_control() to be a unique value.
*/
- ctrl->actrl_minval = cpt->cp_minval;
- ctrl->actrl_maxval = cpt->cp_maxval;
ctrl->actrl_initval = cpt->cp_initval;
ctrl->actrl_muteable = cpt->cp_muteable;
ctrl->actrl_write_fn = cpt->cp_write_fn;
ctrl->actrl_bits = cpt->cp_bits;
- ctrl->actrl_type = cpt->cp_type;
- ctrl->actrl_name = cpt->cp_name;
-
- /* Register control with framework */
- ctrl->actrl_ctrl = audio_dev_add_control(ac->d, &ctrl_des,
- ac97_control_get, ac97_control_set, ctrl);
- if (!ctrl->actrl_ctrl) {
- audio_dev_warn(ac->d, "AC97 %s alloc failed", cpt->cp_name);
- kmem_free(ctrl, sizeof (ac97_ctrl_t));
- return;
- }
/*
- * Not that it can not be referenced until in is in the
+ * Not that it can not be referenced until it is in the
* list. So again by adding to the list last we avoid the need
- * for control locks.
+ * for locks.
*/
- mutex_enter(&ac->ac_lock);
- list_insert_tail(&ac->ctrls, ctrl);
- mutex_exit(&ac->ac_lock);
+ if (is_new)
+ list_insert_tail(&ac->ctrls, ctrl);
}
/*
* De-Register and free up a control
- *
- * Note ctrl_lock read write must be held for writing when calling
- * this function
*/
void
-ac97_free_control(ac97_ctrl_t *ctrl)
+ac97_control_remove(ac97_ctrl_t *ctrl)
{
ac97_t *ac = ctrl->actrl_ac97;
- mutex_enter(&ac->ac_lock);
list_remove(&ac->ctrls, ctrl);
- mutex_exit(&ac->ac_lock);
- audio_dev_del_control(ctrl->actrl_ctrl);
+ if (ctrl->actrl_ctrl != NULL)
+ audio_dev_del_control(ctrl->actrl_ctrl);
kmem_free(ctrl, sizeof (ac97_ctrl_t));
}
@@ -1452,99 +1510,99 @@ ac97_ctrl_probe_t ctrl_probe_tbl[] = {
/* LINE out volume */
{AUDIO_CTRL_ID_LINEOUT, INIT_VAL_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MAINVOL, 0x8080, ac97_lineout_set, ac97_probe_lineout, 6},
+ MAINVOL, 0x8080, ac97_lineout_set, ac_probe_lineout, 6},
/* Front volume */
{AUDIO_CTRL_ID_FRONT, INIT_VAL_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MAINVOL, 0x8080, ac97_lineout_set, ac97_probe_front, 6},
+ MAINVOL, 0x8080, ac97_lineout_set, ac_probe_front, 6},
/* 4CH out volume (has one of three possible uses, first use) */
{AUDIO_CTRL_ID_SURROUND, INIT_VAL_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MAINVOL, 0x8080, ac97_surround_set, ac97_probe_rear, 6},
+ MAINVOL, 0x8080, ac97_surround_set, ac_probe_rear, 6},
/* ALT out volume (has one of three possible uses, second use) */
{AUDIO_CTRL_ID_HEADPHONE, INIT_VAL_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MAINVOL, 0x8080, ac97_headphone_set, ac97_probe_headphone, 6},
+ MAINVOL, 0x8080, ac97_headphone_set, ac_probe_headphone, 6},
/* ALT out volume (has one of three possible uses, third use) */
{AUDIO_CTRL_ID_AUX1OUT, INIT_VAL_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MAINVOL, 0x8080, ac97_aux1out_set, ac97_probe_auxout, 6},
+ MAINVOL, 0x8080, ac97_aux1out_set, ac_probe_auxout, 6},
/* center out volume */
{AUDIO_CTRL_ID_CENTER, INIT_VAL_MN, 0, 100, AUDIO_CTRL_TYPE_MONO,
- MAINVOL, EXLFEVR_CENTER_MUTE, ac97_center_set, ac97_probe_center, 6},
+ MAINVOL, EXLFEVR_CENTER_MUTE, ac_center_set, ac_probe_center, 6},
/* LFE out volume (sub-woofer) */
{AUDIO_CTRL_ID_LFE, INIT_VAL_MN, 0, 100, AUDIO_CTRL_TYPE_MONO,
- MAINVOL, EXLFEVR_LFE_MUTE, ac97_lfe_set, ac97_probe_lfe, 6},
+ MAINVOL, EXLFEVR_LFE_MUTE, ac_lfe_set, ac_probe_lfe, 6},
/* MONO out volume */
{AUDIO_CTRL_ID_SPEAKER, INIT_VAL_MN, 0, 100, AUDIO_CTRL_TYPE_MONO,
- MAINVOL, MMVR_MUTE, ac97_speaker_set, ac97_probe_mono, 6},
+ MAINVOL, MMVR_MUTE, ac_speaker_set, ac_probe_mono, 6},
/* Record in GAIN */
{AUDIO_CTRL_ID_RECGAIN, INIT_IGAIN_ST, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- RECVOL, RGR_MUTE, ac97_recgain_set, NULL, -4},
+ RECVOL, RGR_MUTE, ac_recgain_set, NULL, -4},
/* MIC in volume */
{AUDIO_CTRL_ID_MIC, 0, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MONVOL, MICVR_MUTE, ac97_mic_set, ac97_probe_mic, 5},
+ MONVOL, MICVR_MUTE, ac_mic_set, ac_probe_mic, 5},
/* LINE in volume */
{AUDIO_CTRL_ID_LINEIN, 0, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MONVOL, LIVR_MUTE, ac97_linein_set, ac97_probe_linein, 5},
+ MONVOL, LIVR_MUTE, ac_linein_set, ac_probe_linein, 5},
/* CD in volume */
{AUDIO_CTRL_ID_CD, 0, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MONVOL, CDVR_MUTE, ac97_cd_set, ac97_probe_cdrom, 5},
+ MONVOL, CDVR_MUTE, ac_cd_set, ac_probe_cdrom, 5},
/* VIDEO in volume */
{AUDIO_CTRL_ID_VIDEO, 0, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MONVOL, VIDVR_MUTE, ac97_video_set, ac97_probe_video, 5},
+ MONVOL, VIDVR_MUTE, ac_video_set, ac_probe_video, 5},
/* AUX in volume */
{AUDIO_CTRL_ID_AUX1IN, 0, 0, 100, AUDIO_CTRL_TYPE_STEREO,
- MONVOL, AUXVR_MUTE, ac97_auxin_set, ac97_probe_auxin, 5},
+ MONVOL, AUXVR_MUTE, ac_auxin_set, ac_probe_auxin, 5},
/* PHONE in volume */
{AUDIO_CTRL_ID_PHONE, 0, 0, 100, AUDIO_CTRL_TYPE_MONO,
- MONVOL, PVR_MUTE, ac97_phone_set, ac97_probe_phone, 5},
+ MONVOL, PVR_MUTE, ac_phone_set, ac_probe_phone, 5},
/* PC BEEPER in volume (motherboard speaker pins) */
{AUDIO_CTRL_ID_BEEP, INIT_VAL_MN, 0, 100, AUDIO_CTRL_TYPE_MONO,
- AC97_RW, PCBR_MUTE, ac97_pcbeep_set, ac97_probe_pcbeep, 4},
+ AC97_RW, PCBR_MUTE, ac_pcbeep_set, ac_probe_pcbeep, 4},
/* BASS out level (note, zero is hardware bypass) */
{AUDIO_CTRL_ID_BASS, 0, 0, 100, AUDIO_CTRL_TYPE_MONO,
- TONECTL, 0, ac97_bass_set, ac97_probe_tone, 4},
+ TONECTL, 0, ac_bass_set, ac_probe_tone, 4},
/* TREBLE out level (note, zero is hardware bypass) */
{AUDIO_CTRL_ID_TREBLE, 0, 0, 100, AUDIO_CTRL_TYPE_MONO,
- TONECTL, 0, ac97_treble_set, ac97_probe_tone, 4},
+ TONECTL, 0, ac_treble_set, ac_probe_tone, 4},
/* Loudness on/off switch */
{AUDIO_CTRL_ID_LOUDNESS, 0, 0, 1, AUDIO_CTRL_TYPE_BOOLEAN,
- TONECTL, 0, ac97_loudness_set, ac97_probe_loud, 0},
+ TONECTL, 0, ac_loudness_set, ac_probe_loud, 0},
/* 3D depth out level */
{AUDIO_CTRL_ID_3DDEPTH, 0, 0, 100, AUDIO_CTRL_TYPE_MONO,
- T3DCTL, 0, ac97_3ddepth_set, ac97_probe_3d_depth, 4},
+ T3DCTL, 0, ac_3ddepth_set, ac_probe_3d_depth, 4},
/* 3D center out level */
{AUDIO_CTRL_ID_3DCENT, 0, 0, 100, AUDIO_CTRL_TYPE_MONO,
- T3DCTL, 0, ac97_3dcent_set, ac97_probe_3d_center, 4},
+ T3DCTL, 0, ac_3dcent_set, ac_probe_3d_center, 4},
/* 3D enhance on/off switch */
{AUDIO_CTRL_ID_3DENHANCE, 0, 0, 1, AUDIO_CTRL_TYPE_BOOLEAN,
- T3DCTL, 0, ac97_3donoff_set, ac97_probe_3d, 0},
+ T3DCTL, 0, ac_3donoff_set, ac_probe_3d, 0},
/* MIC BOOST switch */
{AUDIO_CTRL_ID_MICBOOST, 0, 0, 1, AUDIO_CTRL_TYPE_BOOLEAN,
- RECCTL, 0, ac97_micboost_set, ac97_probe_mic, 0},
+ RECCTL, 0, ac97_micboost_set, ac_probe_mic, 0},
/* Loopback on/off switch */
{AUDIO_CTRL_ID_LOOPBACK, 0, 0, 1, AUDIO_CTRL_TYPE_BOOLEAN,
- AC97_RW, 0, ac97_loopback_set, NULL, 0},
+ AC97_RW, 0, ac_loopback_set, NULL, 0},
/*
* The following selectors *must* come after the others, as they rely
@@ -1552,25 +1610,25 @@ ac97_ctrl_probe_t ctrl_probe_tbl[] = {
*/
/* record src select (only one port at a time) */
{AUDIO_CTRL_ID_RECSRC, (1U << INPUT_MIC), 0, 0, AUDIO_CTRL_TYPE_ENUM,
- RECCTL, 0, ac97_insrc_set, NULL, 0, ac97_insrcs},
+ RECCTL, 0, ac_insrc_set, NULL, 0, ac_insrcs},
/* Start of non-standard private controls */
/* Simulated stereo on/off switch */
{AUDIO_CTRL_ID_STEREOSIM, 0, 0, 1, AUDIO_CTRL_TYPE_BOOLEAN,
- AC97_RW, 0, ac97_stsim_set, ac97_probe_stsim, 0},
+ AC97_RW, 0, ac_stsim_set, ac_probe_stsim, 0},
/* mono MIC GAIN */
{AUDIO_CTRL_ID_MICGAIN, INIT_IGAIN_MN, 0, 100, AUDIO_CTRL_TYPE_MONO,
- RECCTL, RGMR_MUTE, ac97_monomic_set, ac97_probe_mmic, -4},
+ RECCTL, RGMR_MUTE, ac_monomic_set, ac_probe_mmic, -4},
/* MIC select switch 0=mic1 1=mic2 */
{AUDIO_CTRL_ID_MICSRC, 1, 3, 3, AUDIO_CTRL_TYPE_ENUM,
- RECCTL, 0, ac97_selmic_set, ac97_probe_mic, 0, ac97_mics},
+ RECCTL, 0, ac_selmic_set, ac_probe_mic, 0, ac_mics},
/* MONO out src select 0=mix 1=mic */
{AUDIO_CTRL_ID_SPKSRC, 1, 3, 3, AUDIO_CTRL_TYPE_ENUM,
- AC97_RW, 0, ac97_monosrc_set, ac97_probe_mono, 0, ac97_monos},
+ AC97_RW, 0, ac_monosrc_set, ac_probe_mono, 0, ac_monos},
{NULL}
};
@@ -1581,8 +1639,8 @@ ac97_ctrl_probe_t ctrl_probe_tbl[] = {
*
* Returns zero on success
*/
-static int
-ac97_probeinit_ctrls(ac97_t *ac, int vol_bits, int enh_bits)
+static void
+ac_probeinit_ctrls(ac97_t *ac, int vol_bits, int enh_bits)
{
ac97_ctrl_probe_t *cpt;
ac97_ctrl_probe_t my_cpt;
@@ -1619,15 +1677,13 @@ ac97_probeinit_ctrls(ac97_t *ac, int vol_bits, int enh_bits)
}
if (!my_cpt.cp_probe || my_cpt.cp_probe(ac)) {
- ac97_alloc_control(ac, &my_cpt);
+ ac_add_control(ac, &my_cpt);
}
}
if (ac->codec_init != NULL) {
ac->codec_init(ac);
}
-
- return (0);
}
/*
@@ -1726,6 +1782,23 @@ ac97_alloc(dev_info_t *dip, ac97_rd_t rd, ac97_wr_t wr, void *priv)
return (ac);
}
+/*
+ * Allocate an AC97 instance for use by a hardware driver.
+ *
+ * returns an allocated and initialize ac97 structure.
+ */
+ac97_t *
+ac97_allocate(audio_dev_t *adev, dev_info_t *dip, ac97_rd_t rd, ac97_wr_t wr,
+ void *priv)
+{
+ ac97_t *ac;
+
+ ac = ac97_alloc(dip, rd, wr, priv);
+ if (ac != NULL) {
+ ac->d = adev;
+ }
+ return (ac);
+}
/*
* Free an AC97 instance.
@@ -1737,7 +1810,7 @@ ac97_free(ac97_t *ac)
/* Clear out any controls that are still attached */
while ((ctrl = list_head(&ac->ctrls)) != NULL) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
list_destroy(&ac->ctrls);
@@ -1846,14 +1919,8 @@ static struct codec {
{ 0, NULL }
};
-/*
- * Init the actual hardware related to a previously
- * allocated instance of an AC97 device.
- *
- * Return zero on success.
- */
-int
-ac97_init(ac97_t *ac, struct audio_dev *d)
+void
+ac97_probe_controls(ac97_t *ac)
{
uint32_t vid1, vid2;
uint16_t ear;
@@ -1865,17 +1932,17 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
char nmbuf[128];
char buf[128];
- /* Save audio framework instance structure */
- ac->d = d;
+ /* This is only valid when used with new style ac97_allocate(). */
+ ASSERT(ac->d);
- ac97_analog_reset(ac);
+ ac_analog_reset(ac);
vid1 = RD(AC97_VENDOR_ID1_REGISTER);
vid2 = RD(AC97_VENDOR_ID2_REGISTER);
if (vid1 == 0xffff) {
- audio_dev_warn(d, "AC'97 codec unresponsive");
- return (-1);
+ audio_dev_warn(ac->d, "AC'97 codec unresponsive");
+ return;
}
ac->vid = (vid1 << 16) | vid2;
@@ -1933,7 +2000,7 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
*/
if (ac->caps & RR_HEADPHONE_SUPPORT) {
/* it looks like it is probably headphones */
- if (ac97_probe_reg(ac, AC97_HEADPHONE_VOLUME_REGISTER)) {
+ if (ac_probe_reg(ac, AC97_HEADPHONE_VOLUME_REGISTER)) {
/* it is implemented */
ac->flags |= AC97_FLAG_AUX_HP;
}
@@ -1946,7 +2013,7 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
* If not a headphone, is it 4CH_OUT (surround?)
*/
if ((!(ac->flags & AC97_FLAG_AUX_HP)) && (ear & EAR_SDAC)) {
- if (ac97_probe_reg(ac, AC97_EXTENDED_LRS_VOLUME_REGISTER)) {
+ if (ac_probe_reg(ac, AC97_EXTENDED_LRS_VOLUME_REGISTER)) {
ac->flags |= AC97_FLAG_AUX_4CH;
}
}
@@ -1955,7 +2022,7 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
* If neither, then maybe its an auxiliary line level output?
*/
if (!(ac->flags & (AC97_FLAG_AUX_HP | AC97_FLAG_AUX_4CH))) {
- if (ac97_probe_reg(ac, AC97_HEADPHONE_VOLUME_REGISTER)) {
+ if (ac_probe_reg(ac, AC97_HEADPHONE_VOLUME_REGISTER)) {
ac->flags |= AC97_FLAG_AUX_LVL;
}
}
@@ -1975,11 +2042,10 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
}
ac->flags |= flags;
- (void) snprintf(ac->name, sizeof (ac->name), "%s %s (%d channels)",
- vendor, name, ac->nchan);
+ (void) snprintf(ac->name, sizeof (ac->name), "%s %s", vendor, name);
(void) snprintf(buf, sizeof (buf), "AC'97 codec: %s", ac->name);
- audio_dev_add_info(d, buf);
+ audio_dev_add_info(ac->d, buf);
cmn_err(CE_CONT,
"?%s#%d: AC'97 codec id %s (%x, %d channels, caps %x)\n",
@@ -1989,15 +2055,30 @@ ac97_init(ac97_t *ac, struct audio_dev *d)
/*
* Probe and register all known controls with framework
*/
- if (ac97_probeinit_ctrls(ac, vol_bits, enh_bits)) {
- audio_dev_warn(d, "AC97 controls init failed");
+ ac_probeinit_ctrls(ac, vol_bits, enh_bits);
- /* XXX - need to free all controls registered? */
- return (-1);
- }
+ ac_hw_reset(ac);
+ ac_init_values(ac);
+}
+
+/*
+ * Init the actual hardware related to a previously allocated instance
+ * of an AC97 device. This is a legacy function and should not be
+ * used in new code.
+ *
+ * Return zero on success.
+ */
+int
+ac97_init(ac97_t *ac, struct audio_dev *d)
+{
+ /* Make sure we aren't using this with new style ac97_allocate(). */
+ ASSERT(ac->d == NULL);
+
+ /* Save audio framework instance structure */
+ ac->d = d;
- ac97_hw_reset(ac);
- ac97_init_values(ac);
+ ac97_probe_controls(ac);
+ ac97_register_controls(ac);
return (0);
}
diff --git a/usr/src/uts/common/io/audio/ac97/ac97_ad.c b/usr/src/uts/common/io/audio/ac97/ac97_ad.c
index 1faddcb6fa..40e4ce7bf1 100644
--- a/usr/src/uts/common/io/audio/ac97/ac97_ad.c
+++ b/usr/src/uts/common/io/audio/ac97/ac97_ad.c
@@ -136,35 +136,35 @@ ads_set_micboost(ac97_ctrl_t *actrl, uint64_t value)
ac97_t *ac = actrl->actrl_ac97;
uint16_t v;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
switch (value) {
case 0x1:
/* 0db */
- ac97_clr(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ ac_clr(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
break;
case 0x2:
/* 10dB */
- ac97_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- v = ac97_rd(ac, ADS_MISC_CFG_REGISTER);
+ ac_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ v = ac_rd(ac, ADS_MISC_CFG_REGISTER);
v &= ~AMCR_MBG_MASK;
v |= AMCR_MBG_10dB;
- ac97_wr(ac, ADS_MISC_CFG_REGISTER, v);
+ ac_wr(ac, ADS_MISC_CFG_REGISTER, v);
break;
case 0x4:
/* 20dB */
- ac97_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- v = ac97_rd(ac, ADS_MISC_CFG_REGISTER);
+ ac_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ v = ac_rd(ac, ADS_MISC_CFG_REGISTER);
v &= ~AMCR_MBG_MASK;
v |= AMCR_MBG_20dB;
- ac97_wr(ac, ADS_MISC_CFG_REGISTER, v);
+ ac_wr(ac, ADS_MISC_CFG_REGISTER, v);
break;
case 0x8:
/* 30dB */
- ac97_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- v = ac97_rd(ac, ADS_MISC_CFG_REGISTER);
+ ac_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ v = ac_rd(ac, ADS_MISC_CFG_REGISTER);
v &= ~AMCR_MBG_MASK;
v |= AMCR_MBG_30dB;
- ac97_wr(ac, ADS_MISC_CFG_REGISTER, v);
+ ac_wr(ac, ADS_MISC_CFG_REGISTER, v);
break;
}
}
@@ -174,19 +174,19 @@ ads_set_micsrc(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
switch (value) {
case 0x1: /* mic1 */
- ac97_clr(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
- ac97_clr(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
+ ac_clr(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
+ ac_clr(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
break;
case 0x2: /* mic2 */
- ac97_clr(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
- ac97_set(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
+ ac_clr(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
+ ac_set(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
break;
case 0x4: /* stereo - ms bit clear to allow MIC1 to be mixed */
- ac97_set(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
- ac97_clr(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
+ ac_set(ac, ADS_MISC_CFG_REGISTER, AMCR_2CMIC);
+ ac_clr(ac, AC97_GENERAL_PURPOSE_REGISTER, GPR_MS_MIC2);
break;
}
}
@@ -194,7 +194,6 @@ ads_set_micsrc(ac97_ctrl_t *actrl, uint64_t value)
static void
ads_setup_micsrc(ac97_t *ac)
{
- ac97_ctrl_t *ctrl;
static const char *values[] = {
AUDIO_PORT_MIC1,
AUDIO_PORT_MIC2,
@@ -206,12 +205,7 @@ ads_setup_micsrc(ac97_t *ac)
AC97_FLAGS | AUDIO_CTRL_FLAG_REC, 0, ads_set_micsrc,
NULL, 0, values };
- ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_MICSRC);
- if (ctrl) {
- ac97_free_control(ctrl);
- }
-
- ac97_alloc_control(ac, &cpt);
+ ac_add_control(ac, &cpt);
}
static void
@@ -237,10 +231,9 @@ ads_setup_micboost(ac97_t *ac)
/* 20dB by default */
cpt.cp_initval = 2;
}
- ac97_free_control(ctrl);
}
- ac97_alloc_control(ac, &cpt);
+ ac_add_control(ac, &cpt);
}
void
diff --git a/usr/src/uts/common/io/audio/ac97/ac97_alc.c b/usr/src/uts/common/io/audio/ac97/ac97_alc.c
index 1c621c5094..73ed9828af 100644
--- a/usr/src/uts/common/io/audio/ac97/ac97_alc.c
+++ b/usr/src/uts/common/io/audio/ac97/ac97_alc.c
@@ -78,11 +78,11 @@ alc650_set_linein_func(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
if (value & 2) {
- ac97_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_SURROUND);
+ ac_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_SURROUND);
} else {
- ac97_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_SURROUND);
+ ac_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_SURROUND);
}
}
@@ -91,13 +91,13 @@ alc650_set_mic_func(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
if (value & 2) {
- ac97_set(ac, ALC_MISC_CTRL_REGISTER, AMC_VREFOUT_DIS);
- ac97_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_CENTER_LFE);
+ ac_set(ac, ALC_MISC_CTRL_REGISTER, AMC_VREFOUT_DIS);
+ ac_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_CENTER_LFE);
} else {
- ac97_clr(ac, ALC_MISC_CTRL_REGISTER, AMC_VREFOUT_DIS);
- ac97_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_CENTER_LFE);
+ ac_clr(ac, ALC_MISC_CTRL_REGISTER, AMC_VREFOUT_DIS);
+ ac_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_CENTER_LFE);
}
}
@@ -107,11 +107,11 @@ alc850_set_auxin_func(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
if (value & 2) {
- ac97_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_BACK_SURROUND);
+ ac_set(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_BACK_SURROUND);
} else {
- ac97_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_BACK_SURROUND);
+ ac_clr(ac, ALC_DATA_FLOW_CTRL_REGISTER, ADFC_BACK_SURROUND);
}
}
#endif
@@ -129,14 +129,14 @@ alc650_set_pcm(ac97_ctrl_t *actrl, uint64_t value)
/* If this control is mute-able than set as muted if needed */
mute = vol ? 0 : ASD_SURROUND_MUTE;
- adj_value = ac97_val_scale(vol, vol, 5) | mute;
+ adj_value = ac_val_scale(vol, vol, 5) | mute;
/* select page 0 */
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0);
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0);
/* adjust all three PCM volumes */
- ac97_wr(ac, AC97_PCM_OUT_VOLUME_REGISTER, adj_value);
- ac97_wr(ac, ALC_SURROUND_DAC_REGISTER, adj_value);
- ac97_wr(ac, ALC_CEN_LFE_DAC_REGISTER, adj_value);
+ ac_wr(ac, AC97_PCM_OUT_VOLUME_REGISTER, adj_value);
+ ac_wr(ac, ALC_SURROUND_DAC_REGISTER, adj_value);
+ ac_wr(ac, ALC_CEN_LFE_DAC_REGISTER, adj_value);
}
static const char *alc_linein_funcs[] = {
@@ -179,18 +179,18 @@ alc650_init(ac97_t *ac)
int ival;
bcopy(&alc650_linein_func_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
+ ival = ac_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
if ((ival >= 1) && (ival <= 2)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
bcopy(&alc650_mic_func_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_MIC_FUNC, 0);
+ ival = ac_get_prop(ac, AC97_PROP_MIC_FUNC, 0);
if ((ival >= 1) && (ival <= 2)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
alc_pcm_override(ac);
}
diff --git a/usr/src/uts/common/io/audio/ac97/ac97_cmi.c b/usr/src/uts/common/io/audio/ac97/ac97_cmi.c
index 50351cb08c..7cd0240f1f 100644
--- a/usr/src/uts/common/io/audio/ac97/ac97_cmi.c
+++ b/usr/src/uts/common/io/audio/ac97/ac97_cmi.c
@@ -71,22 +71,22 @@ cmi_set_micboost(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
switch (value) {
case 0x1:
/* 0db */
- ac97_clr(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- ac97_clr(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
+ ac_clr(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ ac_clr(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
break;
case 0x2:
/* 20dB */
- ac97_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- ac97_clr(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
+ ac_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ ac_clr(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
break;
case 0x4:
/* 30dB */
- ac97_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
- ac97_set(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
+ ac_set(ac, AC97_MIC_VOLUME_REGISTER, MICVR_20dB_BOOST);
+ ac_set(ac, CMI_MULTICH_REGISTER, CMR_BSTSEL);
break;
}
}
@@ -96,11 +96,11 @@ cmi_set_linein_func(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
if (value & 2) {
- ac97_set(ac, CMI_MULTICH_REGISTER, CMR_S2LNI);
+ ac_set(ac, CMI_MULTICH_REGISTER, CMR_S2LNI);
} else {
- ac97_clr(ac, CMI_MULTICH_REGISTER, CMR_S2LNI);
+ ac_clr(ac, CMI_MULTICH_REGISTER, CMR_S2LNI);
}
}
@@ -109,11 +109,11 @@ cmi_set_mic_func(ac97_ctrl_t *actrl, uint64_t value)
{
ac97_t *ac = actrl->actrl_ac97;
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
if (value & 2) {
- ac97_set(ac, CMI_MULTICH_REGISTER, CMR_CLCTL);
+ ac_set(ac, CMI_MULTICH_REGISTER, CMR_CLCTL);
} else {
- ac97_clr(ac, CMI_MULTICH_REGISTER, CMR_CLCTL);
+ ac_clr(ac, CMI_MULTICH_REGISTER, CMR_CLCTL);
}
}
@@ -139,10 +139,9 @@ cmi_setup_micboost(ac97_t *ac)
/* 20dB by default */
cpt.cp_initval = 1;
}
- ac97_free_control(ctrl);
}
- ac97_alloc_control(ac, &cpt);
+ ac_add_control(ac, &cpt);
}
static const char *cmi_linein_funcs[] = {
@@ -173,18 +172,18 @@ cmi_setup_jack_funcs(ac97_t *ac)
};
bcopy(&linein_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
+ ival = ac_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
if ((ival >= 1) && (ival <= 2)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
bcopy(&mic_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_MIC_FUNC, 0);
+ ival = ac_get_prop(ac, AC97_PROP_MIC_FUNC, 0);
if ((ival >= 1) && (ival <= 2)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
}
static void
@@ -193,9 +192,9 @@ cmi_set_linein_func_9738(ac97_ctrl_t *actrl, uint64_t value)
ac97_t *ac = actrl->actrl_ac97;
if (value & 2) {
- ac97_set(ac, CMI_TASK_REGISTER, CTR_S2LNI);
+ ac_set(ac, CMI_TASK_REGISTER, CTR_S2LNI);
} else {
- ac97_clr(ac, CMI_TASK_REGISTER, CTR_S2LNI);
+ ac_clr(ac, CMI_TASK_REGISTER, CTR_S2LNI);
}
}
@@ -205,9 +204,9 @@ cmi_set_spread_9738(ac97_ctrl_t *actrl, uint64_t value)
ac97_t *ac = actrl->actrl_ac97;
if (value) {
- ac97_set(ac, CMI_TASK_REGISTER, CTR_F2R);
+ ac_set(ac, CMI_TASK_REGISTER, CTR_F2R);
} else {
- ac97_clr(ac, CMI_TASK_REGISTER, CTR_F2R);
+ ac_clr(ac, CMI_TASK_REGISTER, CTR_F2R);
}
}
@@ -227,18 +226,18 @@ cmi_setup_jack_func_9738(ac97_t *ac)
};
bcopy(&linein_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
+ ival = ac_get_prop(ac, AC97_PROP_LINEIN_FUNC, 0);
if ((ival >= 1) && (ival <= 2)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
bcopy(&spread_cpt, &cp, sizeof (cp));
- ival = ac97_get_prop(ac, AC97_PROP_SPREAD, -1);
+ ival = ac_get_prop(ac, AC97_PROP_SPREAD, -1);
if ((ival >= 0) && (ival <= 1)) {
cp.cp_initval = ival;
}
- ac97_alloc_control(ac, &cp);
+ ac_add_control(ac, &cp);
}
@@ -258,33 +257,40 @@ cmi_setup_volume(ac97_t *ac)
*/
ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_VOLUME);
if (ctrl) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_FRONT);
if (ctrl) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_SURROUND);
if (ctrl) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_CENTER);
if (ctrl) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
ctrl = ac97_control_find(ac, AUDIO_CTRL_ID_LFE);
if (ctrl) {
- ac97_free_control(ctrl);
+ ac97_control_remove(ctrl);
}
/* make sure we have disabled mute and attenuation on physical ctrls */
- ac97_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
- ac97_wr(ac, AC97_PCM_OUT_VOLUME_REGISTER, 0);
- ac97_wr(ac, AC97_MASTER_VOLUME_REGISTER, 0);
- ac97_wr(ac, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 0);
- ac97_wr(ac, AC97_EXTENDED_LRS_VOLUME_REGISTER, 0);
+ ac_wr(ac, AC97_INTERRUPT_PAGING_REGISTER, 0); /* select page 0 */
+ ac_wr(ac, AC97_PCM_OUT_VOLUME_REGISTER, 0);
+ ac_wr(ac, AC97_MASTER_VOLUME_REGISTER, 0);
+ ac_wr(ac, AC97_EXTENDED_C_LFE_VOLUME_REGISTER, 0);
+ ac_wr(ac, AC97_EXTENDED_LRS_VOLUME_REGISTER, 0);
- (void) audio_dev_add_soft_volume(ac97_get_dev(ac));
+ /*
+ * NB: This is probably not the best way to do this, because
+ * it will make overriding this hard for drivers that desire
+ * to. Fortunately, we don't think any drivers that want to
+ * override or fine tune AC'97 controls (i.e. creative cards)
+ * use these C-Media codecs.
+ */
+ (void) audio_dev_add_soft_volume(ac_get_dev(ac));
}
void
diff --git a/usr/src/uts/common/io/audio/ac97/ac97_impl.h b/usr/src/uts/common/io/audio/ac97/ac97_impl.h
index 073707c0d9..c850d307d4 100644
--- a/usr/src/uts/common/io/audio/ac97/ac97_impl.h
+++ b/usr/src/uts/common/io/audio/ac97/ac97_impl.h
@@ -27,25 +27,28 @@
#ifndef _SYS_AC97_IMPL_H
#define _SYS_AC97_IMPL_H
-typedef struct ac97_ctrl ac97_ctrl_t;
typedef void (*ac97_set_t)(ac97_ctrl_t *, uint64_t);
/*
* Per control state
*/
struct ac97_ctrl {
- list_node_t actrl_linkage; /* For private cntrls list */
- struct ac97 *actrl_ac97;
- int actrl_bits; /* Port width */
- uint32_t actrl_type; /* control type */
- const char *actrl_name; /* control's name */
- audio_ctrl_t *actrl_ctrl; /* control framework handle */
- ac97_set_t actrl_write_fn; /* control write function */
- uint64_t actrl_minval; /* MIN value for control */
- uint64_t actrl_maxval; /* MAX value for control */
- uint64_t actrl_value; /* current value in port */
- uint64_t actrl_initval; /* initial value in port */
- uint16_t actrl_muteable; /* if muteable, bits to do it */
+ list_node_t actrl_linkage; /* For private cntrls list */
+ struct ac97 *actrl_ac97;
+ int actrl_bits; /* Port width */
+ audio_ctrl_t *actrl_ctrl; /* control framework handle */
+ ac97_set_t actrl_write_fn; /* control write function */
+ uint64_t actrl_value; /* current value in port */
+ uint64_t actrl_initval; /* initial value in port */
+ uint16_t actrl_muteable; /* if muteable, bits for it */
+ boolean_t actrl_suppress; /* if true, do not register */
+ audio_ctrl_desc_t actrl_desc; /* ctrl desc structure */
+#define actrl_name actrl_desc.acd_name
+#define actrl_minval actrl_desc.acd_minvalue
+#define actrl_maxval actrl_desc.acd_maxvalue
+#define actrl_type actrl_desc.acd_type
+#define actrl_flags actrl_desc.acd_flags
+#define actrl_enum actrl_desc.acd_enum
};
/*
@@ -74,29 +77,21 @@ typedef struct ac97_ctrl_probe {
const char **cp_enum; /* Enumeration value */
} ac97_ctrl_probe_t;
-typedef struct ac97_hooks {
- void (*h_detach)(ac97_t *);
- void (*h_reset)(ac97_t *);
- void (*h_restore)(ac97_t *);
-} ac97_hooks_t;
-
/*
* These are the flags for most of our controls
*/
#define AC97_RW (AUDIO_CTRL_FLAG_READABLE | AUDIO_CTRL_FLAG_WRITEABLE)
#define AC97_FLAGS (AC97_RW | AUDIO_CTRL_FLAG_POLL)
-void ac97_wr(ac97_t *, uint8_t, uint16_t);
-uint16_t ac97_rd(ac97_t *, uint8_t);
-void ac97_clr(ac97_t *, uint8_t, uint16_t);
-void ac97_set(ac97_t *, uint8_t, uint16_t);
-void ac97_alloc_control(ac97_t *, ac97_ctrl_probe_t *);
-void ac97_free_control(ac97_ctrl_t *);
-ac97_ctrl_t *ac97_control_find(ac97_t *, const char *);
-uint16_t ac97_val_scale(int left, int right, int bits);
-uint16_t ac97_mono_scale(int val, int bits);
-audio_dev_t *ac97_get_dev(ac97_t *);
-int ac97_get_prop(ac97_t *, char *, int);
+void ac_wr(ac97_t *, uint8_t, uint16_t);
+uint16_t ac_rd(ac97_t *, uint8_t);
+void ac_clr(ac97_t *, uint8_t, uint16_t);
+void ac_set(ac97_t *, uint8_t, uint16_t);
+void ac_add_control(ac97_t *, ac97_ctrl_probe_t *);
+uint16_t ac_val_scale(int left, int right, int bits);
+uint16_t ac_mono_scale(int val, int bits);
+audio_dev_t *ac_get_dev(ac97_t *);
+int ac_get_prop(ac97_t *, char *, int);
/* Codec specific initializations */
diff --git a/usr/src/uts/common/sys/audio/ac97.h b/usr/src/uts/common/sys/audio/ac97.h
index 3a2b8973d8..95e2d3218d 100644
--- a/usr/src/uts/common/sys/audio/ac97.h
+++ b/usr/src/uts/common/sys/audio/ac97.h
@@ -601,10 +601,51 @@ extern "C" {
typedef struct ac97 ac97_t;
typedef void (*ac97_wr_t)(void *, uint8_t, uint16_t);
typedef uint16_t (*ac97_rd_t)(void *, uint8_t);
+typedef struct ac97_ctrl ac97_ctrl_t;
+typedef boolean_t (*ac97_ctrl_walk_t)(ac97_ctrl_t *, void *);
+/*
+ * Old style initialization. The driver simply calls ac97_alloc()
+ * followed by ac97_init(). These interfaces should not be used in
+ * new drivers.
+ */
ac97_t *ac97_alloc(dev_info_t *, ac97_rd_t, ac97_wr_t, void *);
-void ac97_free(ac97_t *);
int ac97_init(ac97_t *, audio_dev_t *);
+
+/*
+ * New style initialization. The driver will call ac97_allocate(),
+ * then it can call ac97_register_controls() to register controls.
+ * Or, if it doesn't want all controls registered, it can find
+ * controls with ac97_find_control(), and register them individually
+ * with ac97_register_control(). ac97_alloc()
+ *
+ * Note that adjusting the set of controls should only be performed
+ * while the driver is single threaded, during attach or detach
+ * processing. The AC'97 framework does not provide any locks
+ * surrounding its internal list of controls. Note however that
+ * changes to the controls made from within the framework (e.g. by
+ * someone accessing the control via the audio framework) are safe.
+ */
+ac97_t *ac97_allocate(audio_dev_t *, dev_info_t *, ac97_rd_t, ac97_wr_t,
+ void *);
+void ac97_probe_controls(ac97_t *);
+void ac97_register_controls(ac97_t *);
+void ac97_unregister_controls(ac97_t *);
+
+void ac97_walk_controls(ac97_t *, ac97_ctrl_walk_t, void *);
+ac97_ctrl_t *ac97_control_find(ac97_t *, const char *);
+void ac97_control_register(ac97_ctrl_t *);
+void ac97_control_unregister(ac97_ctrl_t *);
+void ac97_control_remove(ac97_ctrl_t *);
+const char *ac97_control_name(ac97_ctrl_t *);
+const audio_ctrl_desc_t *ac97_control_desc(ac97_ctrl_t *);
+int ac97_control_get(ac97_ctrl_t *, uint64_t *);
+int ac97_control_set(ac97_ctrl_t *, uint64_t);
+
+/*
+ * Bits common to both new style and old style initialization.
+ */
+void ac97_free(ac97_t *);
void ac97_suspend(ac97_t *);
void ac97_resume(ac97_t *);
void ac97_reset(ac97_t *);