Home | History | Annotate | Line # | Download | only in ic
ac97.c revision 1.86
      1 /*      $NetBSD: ac97.c,v 1.86 2007/02/21 22:59:59 thorpej Exp $ */
      2 /*	$OpenBSD: ac97.c,v 1.8 2000/07/19 09:01:35 csapuntz Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 1999, 2000 Constantine Sapuntzakis
      6  *
      7  * Author:        Constantine Sapuntzakis <csapuntz (at) stanford.edu>
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. The name of the author may not be used to endorse or promote
     18  *    products derived from this software without specific prior written
     19  *    permission.
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
     21  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
     24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
     26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     27  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     30  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
     31  * DAMAGE
     32  */
     33 
     34 /* Partially inspired by FreeBSD's sys/dev/pcm/ac97.c. It came with
     35    the following copyright */
     36 
     37 /*
     38  * Copyright (c) 1999 Cameron Grant <gandalf (at) vilnya.demon.co.uk>
     39  * All rights reserved.
     40  *
     41  * Redistribution and use in source and binary forms, with or without
     42  * modification, are permitted provided that the following conditions
     43  * are met:
     44  * 1. Redistributions of source code must retain the above copyright
     45  *    notice, this list of conditions and the following disclaimer.
     46  * 2. Redistributions in binary form must reproduce the above copyright
     47  *    notice, this list of conditions and the following disclaimer in the
     48  *    documentation and/or other materials provided with the distribution.
     49  *
     50  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     60  * SUCH DAMAGE.
     61  *
     62  * $FreeBSD$
     63  */
     64 
     65 #include <sys/cdefs.h>
     66 __KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.86 2007/02/21 22:59:59 thorpej Exp $");
     67 
     68 #include <sys/param.h>
     69 #include <sys/systm.h>
     70 #include <sys/kernel.h>
     71 #include <sys/malloc.h>
     72 #include <sys/device.h>
     73 #include <sys/sysctl.h>
     74 
     75 #include <sys/audioio.h>
     76 #include <dev/audio_if.h>
     77 
     78 #include <dev/ic/ac97reg.h>
     79 #include <dev/ic/ac97var.h>
     80 
     81 struct ac97_softc;
     82 struct ac97_source_info;
     83 static int	ac97_mixer_get_port(struct ac97_codec_if *, mixer_ctrl_t *);
     84 static int	ac97_mixer_set_port(struct ac97_codec_if *, mixer_ctrl_t *);
     85 static void	ac97_detach(struct ac97_codec_if *);
     86 static void	ac97_lock(struct ac97_codec_if *);
     87 static void	ac97_unlock(struct ac97_codec_if *);
     88 static int	ac97_query_devinfo(struct ac97_codec_if *, mixer_devinfo_t *);
     89 static int	ac97_get_portnum_by_name(struct ac97_codec_if *, const char *,
     90 					 const char *, const char *);
     91 static void	ac97_restore_shadow(struct ac97_codec_if *);
     92 static int	ac97_set_rate(struct ac97_codec_if *, int, u_int *);
     93 static void	ac97_set_clock(struct ac97_codec_if *, unsigned int);
     94 static uint16_t ac97_get_extcaps(struct ac97_codec_if *);
     95 static int	ac97_add_port(struct ac97_softc *,
     96 			      const struct ac97_source_info *);
     97 static int	ac97_str_equal(const char *, const char *);
     98 static int	ac97_check_capability(struct ac97_softc *, int);
     99 static void	ac97_setup_source_info(struct ac97_softc *);
    100 static void	ac97_read(struct ac97_softc *, uint8_t, uint16_t *);
    101 static void	ac97_setup_defaults(struct ac97_softc *);
    102 static int	ac97_write(struct ac97_softc *, uint8_t, uint16_t);
    103 
    104 static void	ac97_ad198x_init(struct ac97_softc *);
    105 static void	ac97_alc650_init(struct ac97_softc *);
    106 static void	ac97_vt1616_init(struct ac97_softc *);
    107 
    108 static int	ac97_modem_offhook_set(struct ac97_softc *, int, int);
    109 static int	ac97_sysctl_verify(SYSCTLFN_ARGS);
    110 
    111 #define Ac97Nphone	"phone"
    112 #define Ac97Nline1	"line1"
    113 #define Ac97Nline2	"line2"
    114 #define Ac97Nhandset	"handset"
    115 
    116 static const struct audio_mixer_enum
    117 ac97_on_off = { 2, { { { AudioNoff, 0 } , 0 },
    118 		     { { AudioNon, 0 }  , 1 },
    119         [2 ... 31] = { { "", 0 }, 0 } } };
    120 
    121 static const struct audio_mixer_enum
    122 ac97_mic_select = { 2, { { { AudioNmicrophone "0", 0  }, 0 },
    123 			 { { AudioNmicrophone "1", 0  }, 1 },
    124 	    [2 ... 31] = { { "", 0 }, 0 } } };
    125 
    126 static const struct audio_mixer_enum
    127 ac97_mono_select = { 2, { { { AudioNmixerout, 0  }, 0 },
    128 			  { { AudioNmicrophone, 0  }, 1 },
    129 	     [2 ... 31] = { { "", 0 }, 0 } } };
    130 
    131 static const struct audio_mixer_enum
    132 ac97_source = { 8, { { { AudioNmicrophone, 0  } , 0 },
    133 		     { { AudioNcd, 0 }, 1 },
    134 		     { { AudioNvideo, 0 }, 2 },
    135 		     { { AudioNaux, 0 }, 3 },
    136 		     { { AudioNline, 0 }, 4 },
    137 		     { { AudioNmixerout, 0 }, 5 },
    138 		     { { AudioNmixerout AudioNmono, 0 }, 6 },
    139 		     { { Ac97Nphone, 0 }, 7 },
    140 	[8 ... 31] = { { "", 0 }, 0 } } };
    141 
    142 /*
    143  * Due to different values for each source that uses these structures,
    144  * the ac97_query_devinfo function sets delta in mixer_devinfo_t using
    145  * ac97_source_info.bits.
    146  */
    147 static const struct audio_mixer_value
    148 ac97_volume_stereo = { { AudioNvolume, 0 }, 2, 0 };
    149 
    150 static const struct audio_mixer_value
    151 ac97_volume_mono = { { AudioNvolume, 0 }, 1, 0 };
    152 
    153 #define WRAP(a)  &a, sizeof(a)
    154 
    155 struct ac97_source_info {
    156 	const char *class;
    157 	const char *device;
    158 	const char *qualifier;
    159 
    160 	int  type;
    161 	const void *info;
    162 	int  info_size;
    163 
    164 	uint8_t  reg;
    165 	int32_t	 default_value;
    166 	unsigned bits:3;
    167 	unsigned ofs:4;
    168 	unsigned mute:1;
    169 	unsigned polarity:1;   /* Does 0 == MAX or MIN */
    170 	unsigned checkbits:1;
    171 	enum {
    172 		CHECK_NONE = 0,
    173 		CHECK_SURROUND,
    174 		CHECK_CENTER,
    175 		CHECK_LFE,
    176 		CHECK_HEADPHONES,
    177 		CHECK_TONE,
    178 		CHECK_MIC,
    179 		CHECK_LOUDNESS,
    180 		CHECK_3D,
    181 		CHECK_LINE1,
    182 		CHECK_LINE2,
    183 		CHECK_HANDSET,
    184 		CHECK_SPDIF
    185 	} req_feature;
    186 
    187 	int  prev;
    188 	int  next;
    189 	int  mixer_class;
    190 };
    191 
    192 static const struct ac97_source_info audio_source_info[] = {
    193 	{ AudioCinputs,		NULL,		NULL,
    194 	  AUDIO_MIXER_CLASS,    NULL,		0,
    195 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    196 	{ AudioCoutputs,	NULL,		0,
    197 	  AUDIO_MIXER_CLASS,    NULL,		0,
    198 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    199 	{ AudioCrecord,		NULL,		0,
    200 	  AUDIO_MIXER_CLASS,    NULL,		0,
    201 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    202 	/* Stereo master volume*/
    203 	{ AudioCoutputs,	AudioNmaster,	0,
    204 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    205 	  AC97_REG_MASTER_VOLUME, 0x8000, 5, 0, 1, 0, 1, 0, 0, 0, 0,
    206 	},
    207 	/* Mono volume */
    208 	{ AudioCoutputs,	AudioNmono,	NULL,
    209 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    210 	  AC97_REG_MASTER_VOLUME_MONO, 0x8000, 6, 0, 1, 0, 1, 0, 0, 0, 0,
    211 	},
    212 	{ AudioCoutputs,	AudioNmono,	AudioNsource,
    213 	  AUDIO_MIXER_ENUM, WRAP(ac97_mono_select),
    214 	  AC97_REG_GP, 0x0000, 1, 9, 0, 0, 0, 0, 0, 0, 0,
    215 	},
    216 	/* Headphone volume */
    217 	{ AudioCoutputs,	AudioNheadphone, NULL,
    218 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    219 	  AC97_REG_HEADPHONE_VOLUME, 0x8000, 5, 0, 1, 0, 1, CHECK_HEADPHONES, 0, 0, 0,
    220 	},
    221 	/* Surround volume - logic hard coded for mute */
    222 	{ AudioCoutputs,	AudioNsurround,	NULL,
    223 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    224 	  AC97_REG_SURR_MASTER, 0x8080, 5, 0, 1, 0, 1, CHECK_SURROUND, 0, 0, 0
    225 	},
    226 	/* Center volume*/
    227 	{ AudioCoutputs,	AudioNcenter,	NULL,
    228 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    229 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 0, 0, 0, 1, CHECK_CENTER, 0, 0, 0
    230 	},
    231 	{ AudioCoutputs,	AudioNcenter,	AudioNmute,
    232 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    233 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 7, 0, 0, 0, CHECK_CENTER, 0, 0, 0
    234 	},
    235 	/* LFE volume*/
    236 	{ AudioCoutputs,	AudioNlfe,	NULL,
    237 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    238 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 5, 8, 0, 0, 1, CHECK_LFE, 0, 0, 0
    239 	},
    240 	{ AudioCoutputs,	AudioNlfe,	AudioNmute,
    241 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    242 	  AC97_REG_CENTER_LFE_MASTER, 0x8080, 1, 15, 0, 0, 0, CHECK_LFE, 0, 0, 0
    243 	},
    244 	/* Tone - bass */
    245 	{ AudioCoutputs,	AudioNbass,	NULL,
    246 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    247 	  AC97_REG_MASTER_TONE, 0x0f0f, 4, 8, 0, 0, 0, CHECK_TONE, 0, 0, 0
    248 	},
    249 	/* Tone - treble */
    250 	{ AudioCoutputs,	AudioNtreble,	NULL,
    251 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    252 	  AC97_REG_MASTER_TONE, 0x0f0f, 4, 0, 0, 0, 0, CHECK_TONE, 0, 0, 0
    253 	},
    254 	/* PC Beep Volume */
    255 	{ AudioCinputs,		AudioNspeaker,	NULL,
    256 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    257 	  AC97_REG_PCBEEP_VOLUME, 0x0000, 4, 1, 1, 0, 0, 0, 0, 0, 0,
    258 	},
    259 
    260 	/* Phone */
    261 	{ AudioCinputs,		Ac97Nphone,	NULL,
    262 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    263 	  AC97_REG_PHONE_VOLUME, 0x8008, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    264 	},
    265 	/* Mic Volume */
    266 	{ AudioCinputs,		AudioNmicrophone, NULL,
    267 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    268 	  AC97_REG_MIC_VOLUME, 0x8008, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    269 	},
    270 	{ AudioCinputs,		AudioNmicrophone, AudioNpreamp,
    271 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    272 	  AC97_REG_MIC_VOLUME, 0x8008, 1, 6, 0, 0, 0, 0, 0, 0, 0,
    273 	},
    274 	{ AudioCinputs,		AudioNmicrophone, AudioNsource,
    275 	  AUDIO_MIXER_ENUM, WRAP(ac97_mic_select),
    276 	  AC97_REG_GP, 0x0000, 1, 8, 0, 0, 0, 0, 0, 0, 0,
    277 	},
    278 	/* Line in Volume */
    279 	{ AudioCinputs,		AudioNline,	NULL,
    280 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    281 	  AC97_REG_LINEIN_VOLUME, 0x8808, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    282 	},
    283 	/* CD Volume */
    284 	{ AudioCinputs,		AudioNcd,	NULL,
    285 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    286 	  AC97_REG_CD_VOLUME, 0x8808, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    287 	},
    288 	/* Video Volume */
    289 	{ AudioCinputs,		AudioNvideo,	NULL,
    290 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    291 	  AC97_REG_VIDEO_VOLUME, 0x8808, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    292 	},
    293 	/* AUX volume */
    294 	{ AudioCinputs,		AudioNaux,	NULL,
    295 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    296 	  AC97_REG_AUX_VOLUME, 0x8808, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    297 	},
    298 	/* PCM out volume */
    299 	{ AudioCinputs,		AudioNdac,	NULL,
    300 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    301 	  AC97_REG_PCMOUT_VOLUME, 0x8808, 5, 0, 1, 0, 0, 0, 0, 0, 0,
    302 	},
    303 	/* Record Source - some logic for this is hard coded - see below */
    304 	{ AudioCrecord,		AudioNsource,	NULL,
    305 	  AUDIO_MIXER_ENUM, WRAP(ac97_source),
    306 	  AC97_REG_RECORD_SELECT, 0x0000, 3, 0, 0, 0, 0, 0, 0, 0, 0,
    307 	},
    308 	/* Record Gain */
    309 	{ AudioCrecord,		AudioNvolume,	NULL,
    310 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_stereo),
    311 	  AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1, 1, 0, 0, 0, 0, 0,
    312 	},
    313 	/* Record Gain mic */
    314 	{ AudioCrecord,		AudioNmicrophone, NULL,
    315 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    316 	  AC97_REG_RECORD_GAIN_MIC, 0x8000, 4, 0, 1, 1, 0, CHECK_MIC, 0, 0, 0
    317 	},
    318 	/* */
    319 	{ AudioCoutputs,	AudioNloudness,	NULL,
    320 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    321 	  AC97_REG_GP, 0x0000, 1, 12, 0, 0, 0, CHECK_LOUDNESS, 0, 0, 0
    322 	},
    323 	{ AudioCoutputs,	AudioNspatial,	NULL,
    324 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    325 	  AC97_REG_GP, 0x0000, 1, 13, 0, 1, 0, CHECK_3D, 0, 0, 0
    326 	},
    327 	{ AudioCoutputs,	AudioNspatial,	"center",
    328 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    329 	  AC97_REG_3D_CONTROL, 0x0000, 4, 8, 0, 1, 0, CHECK_3D, 0, 0, 0
    330 	},
    331 	{ AudioCoutputs,	AudioNspatial,	"depth",
    332 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    333 	  AC97_REG_3D_CONTROL, 0x0000, 4, 0, 0, 1, 0, CHECK_3D, 0, 0, 0
    334 	},
    335 
    336 	/* SPDIF */
    337 	{ "spdif", NULL, NULL,
    338 	  AUDIO_MIXER_CLASS, NULL, 0,
    339 	  0, 0, 0, 0, 0, 0, 0, CHECK_SPDIF, 0, 0, 0
    340 	},
    341 	{ "spdif", "enable", NULL,
    342 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    343 	  AC97_REG_EXT_AUDIO_CTRL, -1, 1, 2, 0, 0, 0, CHECK_SPDIF, 0, 0, 0
    344 	},
    345 
    346 	/* Missing features: Simulated Stereo, POP, Loopback mode */
    347 };
    348 
    349 static const struct ac97_source_info modem_source_info[] = {
    350 	/* Classes */
    351 	{ AudioCinputs,		NULL,		NULL,
    352 	  AUDIO_MIXER_CLASS,    NULL,		0,
    353 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    354 	{ AudioCoutputs,	NULL,		NULL,
    355 	  AUDIO_MIXER_CLASS,    NULL,		0,
    356 	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
    357 	{ AudioCinputs,		Ac97Nline1,	NULL,
    358 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    359 	  AC97_REG_LINE1_LEVEL, 0x8080, 4, 0, 0, 1, 0, CHECK_LINE1, 0, 0, 0
    360 	},
    361 	{ AudioCoutputs,	Ac97Nline1,	NULL,
    362 	  AUDIO_MIXER_VALUE, WRAP(ac97_volume_mono),
    363 	  AC97_REG_LINE1_LEVEL, 0x8080, 4, 8, 0, 1, 0, CHECK_LINE1, 0, 0, 0
    364 	},
    365 	{ AudioCinputs,		Ac97Nline1,	AudioNmute,
    366 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    367 	  AC97_REG_LINE1_LEVEL, 0x8080, 1, 7, 0, 0, 0, CHECK_LINE1, 0, 0, 0
    368 	},
    369 	{ AudioCoutputs,	Ac97Nline1,	AudioNmute,
    370 	  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
    371 	  AC97_REG_LINE1_LEVEL, 0x8080, 1, 15, 0, 0, 0, CHECK_LINE1, 0, 0, 0
    372 	},
    373 };
    374 
    375 #define AUDIO_SOURCE_INFO_SIZE \
    376 		(sizeof(audio_source_info)/sizeof(audio_source_info[0]))
    377 #define MODEM_SOURCE_INFO_SIZE \
    378 		(sizeof(modem_source_info)/sizeof(modem_source_info[0]))
    379 #define SOURCE_INFO_SIZE(as) ((as)->type == AC97_CODEC_TYPE_MODEM ? \
    380 		MODEM_SOURCE_INFO_SIZE : AUDIO_SOURCE_INFO_SIZE)
    381 
    382 /*
    383  * Check out http://www.intel.com/support/motherboards/desktop/sb/cs-025406.htm for
    384  * AC'97 Component Specification
    385  */
    386 
    387 struct ac97_softc {
    388 	/* ac97_codec_if must be at the first of ac97_softc. */
    389 	struct ac97_codec_if codec_if;
    390 
    391 	struct ac97_host_if *host_if;
    392 
    393 #define AUDIO_MAX_SOURCES	(2 * AUDIO_SOURCE_INFO_SIZE)
    394 #define MODEM_MAX_SOURCES	(2 * MODEM_SOURCE_INFO_SIZE)
    395 	struct ac97_source_info audio_source_info[AUDIO_MAX_SOURCES];
    396 	struct ac97_source_info modem_source_info[MODEM_MAX_SOURCES];
    397 	struct ac97_source_info *source_info;
    398 	int num_source_info;
    399 
    400 	enum ac97_host_flags host_flags;
    401 	unsigned int ac97_clock; /* usually 48000 */
    402 #define AC97_STANDARD_CLOCK	48000U
    403 	uint16_t power_all;
    404 	uint16_t power_reg;	/* -> AC97_REG_POWER */
    405 	uint16_t caps;		/* -> AC97_REG_RESET */
    406 	uint16_t ext_id;	/* -> AC97_REG_EXT_AUDIO_ID */
    407 	uint16_t ext_mid;	/* -> AC97_REG_EXT_MODEM_ID */
    408 	uint16_t shadow_reg[128];
    409 
    410 	int lock_counter;
    411 	int type;
    412 
    413 	/* sysctl */
    414 	struct sysctllog *log;
    415 	int offhook_line1_mib;
    416 	int offhook_line2_mib;
    417 	int offhook_line1;
    418 	int offhook_line2;
    419 };
    420 
    421 static struct ac97_codec_if_vtbl ac97civ = {
    422 	ac97_mixer_get_port,
    423 	ac97_mixer_set_port,
    424 	ac97_query_devinfo,
    425 	ac97_get_portnum_by_name,
    426 	ac97_restore_shadow,
    427 	ac97_get_extcaps,
    428 	ac97_set_rate,
    429 	ac97_set_clock,
    430 	ac97_detach,
    431 	ac97_lock,
    432 	ac97_unlock,
    433 };
    434 
    435 static const struct ac97_codecid {
    436 	uint32_t id;
    437 	uint32_t mask;
    438 	const char *name;
    439 	void (*init)(struct ac97_softc *);
    440 } ac97codecid[] = {
    441 	/*
    442 	 * Analog Devices SoundMAX
    443 	 * http://www.soundmax.com/products/information/codecs.html
    444 	 * http://www.analog.com/productSelection/pdf/AD1881A_0.pdf
    445 	 * http://www.analog.com/productSelection/pdf/AD1885_0.pdf
    446 	 * http://www.analog.com/UploadedFiles/Data_Sheets/206585810AD1980_0.pdf
    447 	 * http://www.analog.com/productSelection/pdf/AD1981A_0.pdf
    448 	 * http://www.analog.com/productSelection/pdf/AD1981B_0.pdf
    449 	 * http://www.analog.com/UploadedFiles/Data_Sheets/180644528AD1985_0.pdf
    450 	 */
    451 	{ AC97_CODEC_ID('A', 'D', 'S', 3),
    452 	  0xffffffff,			"Analog Devices AD1819B", NULL, },
    453 	{ AC97_CODEC_ID('A', 'D', 'S', 0x40),
    454 	  0xffffffff,			"Analog Devices AD1881", NULL, },
    455 	{ AC97_CODEC_ID('A', 'D', 'S', 0x48),
    456 	  0xffffffff,			"Analog Devices AD1881A", NULL, },
    457 	{ AC97_CODEC_ID('A', 'D', 'S', 0x60),
    458 	  0xffffffff,			"Analog Devices AD1885", NULL, },
    459 	{ AC97_CODEC_ID('A', 'D', 'S', 0x61),
    460 	  0xffffffff,			"Analog Devices AD1886", NULL, },
    461 	{ AC97_CODEC_ID('A', 'D', 'S', 0x63),
    462 	  0xffffffff,			"Analog Devices AD1886A", NULL, },
    463 	{ AC97_CODEC_ID('A', 'D', 'S', 0x68),
    464 	  0xffffffff,			"Analog Devices AD1888", ac97_ad198x_init },
    465 	{ AC97_CODEC_ID('A', 'D', 'S', 0x70),
    466 	  0xffffffff,			"Analog Devices AD1980", ac97_ad198x_init },
    467 	{ AC97_CODEC_ID('A', 'D', 'S', 0x72),
    468 	  0xffffffff,			"Analog Devices AD1981A", NULL, },
    469 	{ AC97_CODEC_ID('A', 'D', 'S', 0x74),
    470 	  0xffffffff,			"Analog Devices AD1981B", NULL, },
    471 	{ AC97_CODEC_ID('A', 'D', 'S', 0x75),
    472 	  0xffffffff,			"Analog Devices AD1985", ac97_ad198x_init },
    473 	{ AC97_CODEC_ID('A', 'D', 'S', 0),
    474 	  AC97_VENDOR_ID_MASK,		"Analog Devices unknown", NULL, },
    475 
    476 	/*
    477 	 * Datasheets:
    478 	 *	http://www.asahi-kasei.co.jp/akm/japanese/product/ak4543/ek4543.pdf
    479 	 *	http://www.asahi-kasei.co.jp/akm/japanese/product/ak4544a/ek4544a.pdf
    480 	 *	http://www.asahi-kasei.co.jp/akm/japanese/product/ak4545/ak4545_f00e.pdf
    481 	 */
    482 	{ AC97_CODEC_ID('A', 'K', 'M', 0),
    483 	  0xffffffff,			"Asahi Kasei AK4540", NULL,	},
    484 	{ AC97_CODEC_ID('A', 'K', 'M', 1),
    485 	  0xffffffff,			"Asahi Kasei AK4542", NULL,	},
    486 	{ AC97_CODEC_ID('A', 'K', 'M', 2),
    487 	  0xffffffff,			"Asahi Kasei AK4541/AK4543", NULL, },
    488 	{ AC97_CODEC_ID('A', 'K', 'M', 5),
    489 	  0xffffffff,			"Asahi Kasei AK4544", NULL, },
    490 	{ AC97_CODEC_ID('A', 'K', 'M', 6),
    491 	  0xffffffff,			"Asahi Kasei AK4544A", NULL, },
    492 	{ AC97_CODEC_ID('A', 'K', 'M', 7),
    493 	  0xffffffff,			"Asahi Kasei AK4545", NULL, },
    494 	{ AC97_CODEC_ID('A', 'K', 'M', 0),
    495 	  AC97_VENDOR_ID_MASK,		"Asahi Kasei unknown", NULL, },
    496 
    497 	/*
    498 	 * Realtek & Avance Logic
    499 	 *	http://www.realtek.com.tw/downloads/downloads1-3.aspx?lineid=5&famid=All&series=All&Spec=True
    500 	 *
    501 	 * ALC650 and ALC658 support VRA, but it supports only 8000, 11025,
    502 	 * 12000, 16000, 22050, 24000, 32000, 44100, and 48000 Hz.
    503 	 */
    504 	{ AC97_CODEC_ID('A', 'L', 'C', 0x00),
    505 	  0xfffffff0,			"Realtek RL5306", NULL,	},
    506 	{ AC97_CODEC_ID('A', 'L', 'C', 0x10),
    507 	  0xfffffff0,			"Realtek RL5382", NULL,	},
    508 	{ AC97_CODEC_ID('A', 'L', 'C', 0x20),
    509 	  0xfffffff0,			"Realtek RL5383/RL5522/ALC100", NULL,	},
    510 	{ AC97_CODEC_ID('A', 'L', 'G', 0x10),
    511 	  0xffffffff,			"Avance Logic ALC200/ALC201", NULL,	},
    512 	{ AC97_CODEC_ID('A', 'L', 'G', 0x20),
    513 	  0xfffffff0,			"Avance Logic ALC650", ac97_alc650_init },
    514 	{ AC97_CODEC_ID('A', 'L', 'G', 0x30),
    515 	  0xffffffff,			"Avance Logic ALC101", NULL,	},
    516 	{ AC97_CODEC_ID('A', 'L', 'G', 0x40),
    517 	  0xffffffff,			"Avance Logic ALC202", NULL,	},
    518 	{ AC97_CODEC_ID('A', 'L', 'G', 0x50),
    519 	  0xffffffff,			"Avance Logic ALC250", NULL,	},
    520 	{ AC97_CODEC_ID('A', 'L', 'G', 0x60),
    521 	  0xfffffff0,			"Avance Logic ALC655", NULL,	},
    522 	{ AC97_CODEC_ID('A', 'L', 'G', 0x80),
    523 	  0xfffffff0,			"Avance Logic ALC658", NULL,	},
    524 	{ AC97_CODEC_ID('A', 'L', 'G', 0x90),
    525 	  0xfffffff0,			"Avance Logic ALC850", NULL,	},
    526 	{ AC97_CODEC_ID('A', 'L', 'C', 0),
    527 	  AC97_VENDOR_ID_MASK,		"Realtek unknown", NULL,	},
    528 	{ AC97_CODEC_ID('A', 'L', 'G', 0),
    529 	  AC97_VENDOR_ID_MASK,		"Avance Logic unknown", NULL,	},
    530 
    531 	/**
    532 	 * C-Media Electronics Inc.
    533 	 * http://www.cmedia.com.tw/doc/CMI9739%206CH%20Audio%20Codec%20SPEC_Ver12.pdf
    534 	 */
    535 	{ AC97_CODEC_ID('C', 'M', 'I', 0x61),
    536 	  0xffffffff,			"C-Media CMI9739", NULL,	},
    537 	{ AC97_CODEC_ID('C', 'M', 'I', 0),
    538 	  AC97_VENDOR_ID_MASK,		"C-Media unknown", NULL,	},
    539 
    540 	/* Cirrus Logic, Crystal series:
    541 	 *  'C' 'R' 'Y' 0x0[0-7]  - CS4297
    542 	 *              0x1[0-7]  - CS4297A
    543 	 *              0x2[0-7]  - CS4298
    544 	 *              0x2[8-f]  - CS4294
    545 	 *              0x3[0-7]  - CS4299
    546 	 *              0x4[8-f]  - CS4201
    547 	 *              0x5[8-f]  - CS4205
    548 	 *              0x6[0-7]  - CS4291
    549 	 *              0x7[0-7]  - CS4202
    550 	 * Datasheets:
    551 	 *	http://www.cirrus.com/pubs/cs4297A-5.pdf?DocumentID=593
    552 	 *	http://www.cirrus.com/pubs/cs4294.pdf?DocumentID=32
    553 	 *	http://www.cirrus.com/pubs/cs4299-5.pdf?DocumentID=594
    554 	 *	http://www.cirrus.com/pubs/cs4201-2.pdf?DocumentID=492
    555 	 *	http://www.cirrus.com/pubs/cs4205-2.pdf?DocumentID=492
    556 	 *	http://www.cirrus.com/pubs/cs4202-1.pdf?DocumentID=852
    557 	 */
    558 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x00),
    559 	  0xfffffff8,			"Crystal CS4297", NULL,	},
    560 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x10),
    561 	  0xfffffff8,			"Crystal CS4297A", NULL,	},
    562 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x20),
    563 	  0xfffffff8,			"Crystal CS4298", NULL,	},
    564 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x28),
    565 	  0xfffffff8,			"Crystal CS4294", NULL,	},
    566 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x30),
    567 	  0xfffffff8,			"Crystal CS4299", NULL,	},
    568 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x48),
    569 	  0xfffffff8,			"Crystal CS4201", NULL,	},
    570 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x58),
    571 	  0xfffffff8,			"Crystal CS4205", NULL,	},
    572 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x60),
    573 	  0xfffffff8,			"Crystal CS4291", NULL,	},
    574 	{ AC97_CODEC_ID('C', 'R', 'Y', 0x70),
    575 	  0xfffffff8,			"Crystal CS4202", NULL,	},
    576 	{ AC97_CODEC_ID('C', 'R', 'Y', 0),
    577 	  AC97_VENDOR_ID_MASK,		"Cirrus Logic unknown", NULL,	},
    578 
    579 	{ 0x45838308, 0xffffffff,	"ESS Technology ES1921", NULL, },
    580 	{ 0x45838300, AC97_VENDOR_ID_MASK, "ESS Technology unknown", NULL, },
    581 
    582 	{ AC97_CODEC_ID('H', 'R', 'S', 0),
    583 	  0xffffffff,			"Intersil HMP9701", NULL,	},
    584 	{ AC97_CODEC_ID('H', 'R', 'S', 0),
    585 	  AC97_VENDOR_ID_MASK,		"Intersil unknown", NULL,	},
    586 
    587 	/*
    588 	 * IC Ensemble (VIA)
    589 	 *	http://www.viatech.com/en/datasheet/DS1616.pdf
    590 	 */
    591 	{ AC97_CODEC_ID('I', 'C', 'E', 0x01),
    592 	  0xffffffff,			"ICEnsemble ICE1230/VT1611", NULL,	},
    593 	{ AC97_CODEC_ID('I', 'C', 'E', 0x11),
    594 	  0xffffffff,			"ICEnsemble ICE1232/VT1611A", NULL,	},
    595 	{ AC97_CODEC_ID('I', 'C', 'E', 0x14),
    596 	  0xffffffff,			"ICEnsemble ICE1232A", NULL,	},
    597 	{ AC97_CODEC_ID('I', 'C', 'E', 0x51),
    598 	  0xffffffff,			"VIA Technologies VT1616", ac97_vt1616_init },
    599 	{ AC97_CODEC_ID('I', 'C', 'E', 0x52),
    600 	  0xffffffff,			"VIA Technologies VT1616i", ac97_vt1616_init },
    601 	{ AC97_CODEC_ID('I', 'C', 'E', 0),
    602 	  AC97_VENDOR_ID_MASK,		"ICEnsemble/VIA unknown", NULL,	},
    603 
    604 	{ AC97_CODEC_ID('N', 'S', 'C', 0),
    605 	  0xffffffff,			"National Semiconductor LM454[03568]", NULL, },
    606 	{ AC97_CODEC_ID('N', 'S', 'C', 49),
    607 	  0xffffffff,			"National Semiconductor LM4549", NULL, },
    608 	{ AC97_CODEC_ID('N', 'S', 'C', 0),
    609 	  AC97_VENDOR_ID_MASK,		"National Semiconductor unknown", NULL, },
    610 
    611 	{ AC97_CODEC_ID('P', 'S', 'C', 4),
    612 	  0xffffffff,			"Philips Semiconductor UCB1400", NULL, },
    613 	{ AC97_CODEC_ID('P', 'S', 'C', 0),
    614 	  AC97_VENDOR_ID_MASK,		"Philips Semiconductor unknown", NULL, },
    615 
    616 	{ AC97_CODEC_ID('S', 'I', 'L', 34),
    617 	  0xffffffff,			"Silicon Laboratory Si3036", NULL, },
    618 	{ AC97_CODEC_ID('S', 'I', 'L', 35),
    619 	  0xffffffff,			"Silicon Laboratory Si3038", NULL, },
    620 	{ AC97_CODEC_ID('S', 'I', 'L', 0),
    621 	  AC97_VENDOR_ID_MASK,		"Silicon Laboratory unknown", NULL, },
    622 
    623 	{ AC97_CODEC_ID('T', 'R', 'A', 2),
    624 	  0xffffffff,			"TriTech TR28022", NULL,	},
    625 	{ AC97_CODEC_ID('T', 'R', 'A', 3),
    626 	  0xffffffff,			"TriTech TR28023", NULL,	},
    627 	{ AC97_CODEC_ID('T', 'R', 'A', 6),
    628 	  0xffffffff,			"TriTech TR28026", NULL,	},
    629 	{ AC97_CODEC_ID('T', 'R', 'A', 8),
    630 	  0xffffffff,			"TriTech TR28028", NULL,	},
    631 	{ AC97_CODEC_ID('T', 'R', 'A', 35),
    632 	  0xffffffff,			"TriTech TR28602", NULL,	},
    633 	{ AC97_CODEC_ID('T', 'R', 'A', 0),
    634 	  AC97_VENDOR_ID_MASK,		"TriTech unknown", NULL,	},
    635 
    636 	{ AC97_CODEC_ID('T', 'X', 'N', 0x20),
    637 	  0xffffffff,			"Texas Instruments TLC320AD9xC", NULL, },
    638 	{ AC97_CODEC_ID('T', 'X', 'N', 0),
    639 	  AC97_VENDOR_ID_MASK,		"Texas Instruments unknown", NULL, },
    640 
    641 	/*
    642 	 * VIA
    643 	 * http://www.viatech.com/en/multimedia/audio.jsp
    644 	 */
    645 	{ AC97_CODEC_ID('V', 'I', 'A', 0x61),
    646 	  0xffffffff,			"VIA Technologies VT1612A", NULL, },
    647 	{ AC97_CODEC_ID('V', 'I', 'A', 0),
    648 	  AC97_VENDOR_ID_MASK,		"VIA Technologies unknown", NULL, },
    649 
    650 	{ AC97_CODEC_ID('W', 'E', 'C', 1),
    651 	  0xffffffff,			"Winbond W83971D", NULL,	},
    652 	{ AC97_CODEC_ID('W', 'E', 'C', 0),
    653 	  AC97_VENDOR_ID_MASK,		"Winbond unknown", NULL,	},
    654 
    655 	/*
    656 	 * http://www.wolfsonmicro.com/product_list.asp?cid=64
    657 	 *	http://www.wolfsonmicro.com/download.asp/did.56/WM9701A.pdf - 00
    658 	 *	http://www.wolfsonmicro.com/download.asp/did.57/WM9703.pdf  - 03
    659 	 *	http://www.wolfsonmicro.com/download.asp/did.58/WM9704M.pdf - 04
    660 	 *	http://www.wolfsonmicro.com/download.asp/did.59/WM9704Q.pdf - 04
    661 	 *	http://www.wolfsonmicro.com/download.asp/did.184/WM9705_Rev34.pdf - 05
    662 	 *	http://www.wolfsonmicro.com/download.asp/did.60/WM9707.pdf  - 03
    663 	 *	http://www.wolfsonmicro.com/download.asp/did.136/WM9708.pdf - 03
    664 	 *	http://www.wolfsonmicro.com/download.asp/did.243/WM9710.pdf - 05
    665 	 */
    666 	{ AC97_CODEC_ID('W', 'M', 'L', 0),
    667 	  0xffffffff,			"Wolfson WM9701A", NULL,	},
    668 	{ AC97_CODEC_ID('W', 'M', 'L', 3),
    669 	  0xffffffff,			"Wolfson WM9703/WM9707/WM9708", NULL,	},
    670 	{ AC97_CODEC_ID('W', 'M', 'L', 4),
    671 	  0xffffffff,			"Wolfson WM9704", NULL,	},
    672 	{ AC97_CODEC_ID('W', 'M', 'L', 5),
    673 	  0xffffffff,			"Wolfson WM9705/WM9710", NULL, },
    674 	{ AC97_CODEC_ID('W', 'M', 'L', 0),
    675 	  AC97_VENDOR_ID_MASK,		"Wolfson unknown", NULL,	},
    676 
    677 	/*
    678 	 * http://www.yamaha.co.jp/english/product/lsi/us/products/pcaudio.html
    679 	 * Datasheets:
    680 	 *	http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF743A20.pdf
    681 	 *	http://www.yamaha.co.jp/english/product/lsi/us/products/pdf/4MF753A20.pdf
    682 	 */
    683 	{ AC97_CODEC_ID('Y', 'M', 'H', 0),
    684 	  0xffffffff,			"Yamaha YMF743-S", NULL,	},
    685 	{ AC97_CODEC_ID('Y', 'M', 'H', 3),
    686 	  0xffffffff,			"Yamaha YMF753-S", NULL,	},
    687 	{ AC97_CODEC_ID('Y', 'M', 'H', 0),
    688 	  AC97_VENDOR_ID_MASK,		"Yamaha unknown", NULL,	},
    689 
    690 	/*
    691 	 * http://www.sigmatel.com/products/technical_docs.htm
    692 	 * and
    693 	 * http://www.sigmatel.com/documents/c-major-brochure-9-0.pdf
    694 	 */
    695 	{ 0x83847600, 0xffffffff,	"SigmaTel STAC9700",	NULL, },
    696 	{ 0x83847604, 0xffffffff,	"SigmaTel STAC9701/3/4/5", NULL, },
    697 	{ 0x83847605, 0xffffffff,	"SigmaTel STAC9704",	NULL, },
    698 	{ 0x83847608, 0xffffffff,	"SigmaTel STAC9708",	NULL, },
    699 	{ 0x83847609, 0xffffffff,	"SigmaTel STAC9721/23",	NULL, },
    700 	{ 0x83847644, 0xffffffff,	"SigmaTel STAC9744/45",	NULL, },
    701 	{ 0x83847650, 0xffffffff,	"SigmaTel STAC9750/51",	NULL, },
    702 	{ 0x83847652, 0xffffffff,	"SigmaTel STAC9752/53",	NULL, },
    703 	{ 0x83847656, 0xffffffff,	"SigmaTel STAC9756/57",	NULL, },
    704 	{ 0x83847658, 0xffffffff,	"SigmaTel STAC9758/59",	NULL, },
    705 	{ 0x83847666, 0xffffffff,	"SigmaTel STAC9766/67",	NULL, },
    706 	{ 0x83847684, 0xffffffff,	"SigmaTel STAC9783/84",	NULL, },
    707 	{ 0x83847600, AC97_VENDOR_ID_MASK, "SigmaTel unknown",	NULL, },
    708 
    709 	/* Conexant AC'97 modems -- good luck finding datasheets! */
    710 	{ AC97_CODEC_ID('C', 'X', 'T', 33),
    711 	  0xffffffff,			"Conexant HSD11246", NULL, },
    712 	{ AC97_CODEC_ID('C', 'X', 'T', 34),
    713 	  0xffffffff,			"Conexant D480 MDC V.92 Modem", NULL, },
    714 	{ AC97_CODEC_ID('C', 'X', 'T', 48),
    715 	  0xffffffff,			"Conexant CXT48", NULL, },
    716 	{ AC97_CODEC_ID('C', 'X', 'T', 0),
    717 	  AC97_VENDOR_ID_MASK,		"Conexant unknown", NULL, },
    718 
    719 	{ 0,
    720 	  0,			NULL,	NULL, 		},
    721 };
    722 
    723 static const char * const ac97enhancement[] = {
    724 	"no 3D stereo",
    725 	"Analog Devices Phat Stereo",
    726 	"Creative",
    727 	"National Semi 3D",
    728 	"Yamaha Ymersion",
    729 	"BBE 3D",
    730 	"Crystal Semi 3D",
    731 	"Qsound QXpander",
    732 	"Spatializer 3D",
    733 	"SRS 3D",
    734 	"Platform Tech 3D",
    735 	"AKM 3D",
    736 	"Aureal",
    737 	"AZTECH 3D",
    738 	"Binaura 3D",
    739 	"ESS Technology",
    740 	"Harman International VMAx",
    741 	"Nvidea 3D",
    742 	"Philips Incredible Sound",
    743 	"Texas Instruments' 3D",
    744 	"VLSI Technology 3D",
    745 	"TriTech 3D",
    746 	"Realtek 3D",
    747 	"Samsung 3D",
    748 	"Wolfson Microelectronics 3D",
    749 	"Delta Integration 3D",
    750 	"SigmaTel 3D",
    751 	"KS Waves 3D",
    752 	"Rockwell 3D",
    753 	"Unknown 3D",
    754 	"Unknown 3D",
    755 	"Unknown 3D",
    756 };
    757 
    758 static const char * const ac97feature[] = {
    759 	"dedicated mic channel",
    760 	"reserved",
    761 	"tone",
    762 	"simulated stereo",
    763 	"headphone",
    764 	"bass boost",
    765 	"18 bit DAC",
    766 	"20 bit DAC",
    767 	"18 bit ADC",
    768 	"20 bit ADC"
    769 };
    770 
    771 
    772 /* #define AC97_DEBUG 10 */
    773 /* #define AC97_IO_DEBUG */
    774 
    775 #ifdef AUDIO_DEBUG
    776 #define DPRINTF(x)	if (ac97debug) printf x
    777 #define DPRINTFN(n,x)	if (ac97debug>(n)) printf x
    778 #ifdef AC97_DEBUG
    779 int	ac97debug = AC97_DEBUG;
    780 #else
    781 int	ac97debug = 0;
    782 #endif
    783 #else
    784 #define DPRINTF(x)
    785 #define DPRINTFN(n,x)
    786 #endif
    787 
    788 #ifdef AC97_IO_DEBUG
    789 static const char *ac97_register_names[0x80 / 2] = {
    790 	"RESET", "MASTER_VOLUME", "HEADPHONE_VOLUME", "MASTER_VOLUME_MONO",
    791 	"MASTER_TONE", "PCBEEP_VOLUME", "PHONE_VOLUME", "MIC_VOLUME",
    792 	"LINEIN_VOLUME", "CD_VOLUME", "VIDEO_VOLUME", "AUX_VOLUME",
    793 	"PCMOUT_VOLUME", "RECORD_SELECT", "RECORD_GATIN", "RECORD_GAIN_MIC",
    794 	"GP", "3D_CONTROL", "AUDIO_INT", "POWER",
    795 	"EXT_AUDIO_ID", "EXT_AUDIO_CTRL", "PCM_FRONT_DAC_RATE", "PCM_SURR_DAC_RATE",
    796 	"PCM_LFE_DAC_RATE", "PCM_LR_ADC_RATE", "PCM_MIC_ADC_RATE", "CENTER_LFE_MASTER",
    797 	"SURR_MASTER", "SPDIF_CTRL", "EXT_MODEM_ID", "EXT_MODEM_CTRL",
    798 	"LINE1_RATE", "LINE2_RATE", "HANDSET_RATE", "LINE1_LEVEL",
    799 	"LINE2_LEVEL", "HANDSET_LEVEL", "GPIO_PIN_CONFIG", "GPIO_PIN_POLARITY",
    800 	"GPIO_PIN_STICKY", "GPIO_PIN_WAKEUP", "GPIO_PIN_STATUS", "MISC_MODEM_CTRL",
    801 	"0x58", "VENDOR-5A", "VENDOR-5C", "VENDOR-5E",
    802 	"0x60", "0x62", "0x64", "0x66",
    803 	"0x68", "0x6a", "0x6c", "0x6e",
    804 	"VENDOR-70", "VENDOR-72", "VENDOR-74", "VENDOR-76",
    805 	"VENDOR-78", "VENDOR-7A", "VENDOR_ID1", "VENDOR_ID2"
    806 };
    807 #endif
    808 
    809 /*
    810  * XXX Some cards have an inverted AC97_POWER_EAMP bit.
    811  * These cards will produce no sound unless AC97_HOST_INVERTED_EAMP is set.
    812  */
    813 
    814 #define POWER_EAMP_ON(as)  ((as->host_flags & AC97_HOST_INVERTED_EAMP) \
    815 			    ? AC97_POWER_EAMP : 0)
    816 #define POWER_EAMP_OFF(as) ((as->host_flags & AC97_HOST_INVERTED_EAMP) \
    817 			    ? 0 : AC97_POWER_EAMP)
    818 
    819 static void
    820 ac97_read(struct ac97_softc *as, uint8_t reg, uint16_t *val)
    821 {
    822 	if (as->host_flags & AC97_HOST_DONT_READ &&
    823 	    (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 &&
    824 	     reg != AC97_REG_RESET)) {
    825 		*val = as->shadow_reg[reg >> 1];
    826 		return;
    827 	}
    828 
    829 	if (as->host_if->read(as->host_if->arg, reg, val)) {
    830 		*val = as->shadow_reg[reg >> 1];
    831 	}
    832 }
    833 
    834 static int
    835 ac97_write(struct ac97_softc *as, uint8_t reg, uint16_t val)
    836 {
    837 #ifndef AC97_IO_DEBUG
    838 	as->shadow_reg[reg >> 1] = val;
    839 	return as->host_if->write(as->host_if->arg, reg, val);
    840 #else
    841 	int ret;
    842 	uint16_t actual;
    843 
    844 	as->shadow_reg[reg >> 1] = val;
    845 	ret = as->host_if->write(as->host_if->arg, reg, val);
    846 	as->host_if->read(as->host_if->arg, reg, &actual);
    847 	if (val != actual && reg < 0x80) {
    848 		printf("ac97_write: reg=%s, written=0x%04x, read=0x%04x\n",
    849 		       ac97_register_names[reg / 2], val, actual);
    850 	}
    851 	return ret;
    852 #endif
    853 }
    854 
    855 static void
    856 ac97_setup_defaults(struct ac97_softc *as)
    857 {
    858 	int idx;
    859 	const struct ac97_source_info *si;
    860 
    861 	memset(as->shadow_reg, 0, sizeof(as->shadow_reg));
    862 
    863 	for (idx = 0; idx < AUDIO_SOURCE_INFO_SIZE; idx++) {
    864 		si = &audio_source_info[idx];
    865 		if (si->default_value >= 0)
    866 			ac97_write(as, si->reg, si->default_value);
    867 	}
    868 	for (idx = 0; idx < MODEM_SOURCE_INFO_SIZE; idx++) {
    869 		si = &modem_source_info[idx];
    870 		if (si->default_value >= 0)
    871 			ac97_write(as, si->reg, si->default_value);
    872 	}
    873 }
    874 
    875 static void
    876 ac97_restore_shadow(struct ac97_codec_if *self)
    877 {
    878 	struct ac97_softc *as;
    879 	const struct ac97_source_info *si;
    880 	int idx;
    881 	uint16_t val;
    882 
    883 	as = (struct ac97_softc *) self;
    884 
    885 	if (as->type == AC97_CODEC_TYPE_AUDIO) {
    886 		/* restore AC97_REG_POWER */
    887 		ac97_write(as, AC97_REG_POWER, as->power_reg);
    888 		/* make sure chip is fully operational */
    889 		for (idx = 50000; idx >= 0; idx--) {
    890 			ac97_read(as, AC97_REG_POWER, &val);
    891 			if ((val & as->power_all) == as->power_all)
    892 				break;
    893 			DELAY(10);
    894 		}
    895 
    896 		/*
    897 		 * actually try changing a value!
    898 		 * The default value of AC97_REG_MASTER_VOLUME is 0x8000.
    899 		 */
    900 		for (idx = 50000; idx >= 0; idx--) {
    901 			ac97_write(as, AC97_REG_MASTER_VOLUME, 0x1010);
    902 			ac97_read(as, AC97_REG_MASTER_VOLUME, &val);
    903 			if (val == 0x1010)
    904 				break;
    905 			DELAY(10);
    906 		}
    907 	}
    908 
    909        for (idx = 0; idx < SOURCE_INFO_SIZE(as); idx++) {
    910 		if (as->type == AC97_CODEC_TYPE_MODEM)
    911 			si = &modem_source_info[idx];
    912 		else
    913 			si = &audio_source_info[idx];
    914 		/* don't "restore" to the reset reg! */
    915 		if (si->reg != AC97_REG_RESET)
    916 			ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
    917 	}
    918 
    919 	if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA
    920 			  | AC97_EXT_AUDIO_SPDIF | AC97_EXT_AUDIO_VRM
    921 			  | AC97_EXT_AUDIO_CDAC | AC97_EXT_AUDIO_SDAC
    922 			  | AC97_EXT_AUDIO_LDAC)) {
    923 		ac97_write(as, AC97_REG_EXT_AUDIO_CTRL,
    924 		    as->shadow_reg[AC97_REG_EXT_AUDIO_CTRL >> 1]);
    925 	}
    926 	if (as->ext_mid & (AC97_EXT_MODEM_LINE1 | AC97_EXT_MODEM_LINE2
    927 			  | AC97_EXT_MODEM_HANDSET | AC97_EXT_MODEM_CID1
    928 			  | AC97_EXT_MODEM_CID2 | AC97_EXT_MODEM_ID0
    929 			  | AC97_EXT_MODEM_ID1)) {
    930 		ac97_write(as, AC97_REG_EXT_MODEM_CTRL,
    931 		    as->shadow_reg[AC97_REG_EXT_MODEM_CTRL >> 1]);
    932 	}
    933 }
    934 
    935 static int
    936 ac97_str_equal(const char *a, const char *b)
    937 {
    938 	return (a == b) || (a && b && (!strcmp(a, b)));
    939 }
    940 
    941 static int
    942 ac97_check_capability(struct ac97_softc *as, int check)
    943 {
    944 	switch (check) {
    945 	case CHECK_NONE:
    946 		return 1;
    947 	case CHECK_SURROUND:
    948 		return as->ext_id & AC97_EXT_AUDIO_SDAC;
    949 	case CHECK_CENTER:
    950 		return as->ext_id & AC97_EXT_AUDIO_CDAC;
    951 	case CHECK_LFE:
    952 		return as->ext_id & AC97_EXT_AUDIO_LDAC;
    953 	case CHECK_SPDIF:
    954 		return as->ext_id & AC97_EXT_AUDIO_SPDIF;
    955 	case CHECK_HEADPHONES:
    956 		return as->caps & AC97_CAPS_HEADPHONES;
    957 	case CHECK_TONE:
    958 		return as->caps & AC97_CAPS_TONECTRL;
    959 	case CHECK_MIC:
    960 		return as->caps & AC97_CAPS_MICIN;
    961 	case CHECK_LOUDNESS:
    962 		return as->caps & AC97_CAPS_LOUDNESS;
    963 	case CHECK_3D:
    964 		return AC97_CAPS_ENHANCEMENT(as->caps) != 0;
    965 	case CHECK_LINE1:
    966 		return as->ext_mid & AC97_EXT_MODEM_LINE1;
    967 	case CHECK_LINE2:
    968 		return as->ext_mid & AC97_EXT_MODEM_LINE2;
    969 	case CHECK_HANDSET:
    970 		return as->ext_mid & AC97_EXT_MODEM_HANDSET;
    971 	default:
    972 		printf("%s: internal error: feature=%d\n", __func__, check);
    973 		return 0;
    974 	}
    975 }
    976 
    977 static void
    978 ac97_setup_source_info(struct ac97_softc *as)
    979 {
    980 	int idx, ouridx;
    981 	struct ac97_source_info *si, *si2;
    982 	uint16_t value1, value2, value3;
    983 
    984 	for (idx = 0, ouridx = 0; idx < SOURCE_INFO_SIZE(as); idx++) {
    985 		si = &as->source_info[ouridx];
    986 		if (as->type == AC97_CODEC_TYPE_MODEM) {
    987 			memcpy(si, &modem_source_info[idx], sizeof(*si));
    988 		} else {
    989 			memcpy(si, &audio_source_info[idx], sizeof(*si));
    990 		}
    991 		if (!ac97_check_capability(as, si->req_feature))
    992 			continue;
    993 		if (si->checkbits) {
    994 			/* read the register value */
    995 			ac97_read(as, si->reg, &value1);
    996 			/* write 0b100000 */
    997 			value2 = value1 & 0xffc0;
    998 			value2 |= 0x20;
    999 			ac97_write(as, si->reg, value2);
   1000 			/* verify */
   1001 			ac97_read(as, si->reg, &value3);
   1002 			if (value2 == value3) {
   1003 				si->bits = 6;
   1004 			} else {
   1005 				si->bits = 5;
   1006 			}
   1007 			DPRINTF(("%s: register=%02x bits=%d\n",
   1008 			    __func__, si->reg, si->bits));
   1009 			ac97_write(as, si->reg, value1);
   1010 		}
   1011 
   1012 		switch (si->type) {
   1013 		case AUDIO_MIXER_CLASS:
   1014 			si->mixer_class = ouridx;
   1015 			ouridx++;
   1016 			break;
   1017 		case AUDIO_MIXER_VALUE:
   1018 			/* Todo - Test to see if it works */
   1019 			ouridx++;
   1020 
   1021 			/* Add an entry for mute, if necessary */
   1022 			if (si->mute) {
   1023 				si = &as->source_info[ouridx];
   1024 				if (as->type == AC97_CODEC_TYPE_MODEM)
   1025 					memcpy(si, &modem_source_info[idx],
   1026 					    sizeof(*si));
   1027 				else
   1028 					memcpy(si, &audio_source_info[idx],
   1029 					    sizeof(*si));
   1030 				si->qualifier = AudioNmute;
   1031 				si->type = AUDIO_MIXER_ENUM;
   1032 				si->info = &ac97_on_off;
   1033 				si->info_size = sizeof(ac97_on_off);
   1034 				si->bits = 1;
   1035 				si->ofs = 15;
   1036 				si->mute = 0;
   1037 				si->polarity = 0;
   1038 				ouridx++;
   1039 			}
   1040 			break;
   1041 		case AUDIO_MIXER_ENUM:
   1042 			/* Todo - Test to see if it works */
   1043 			ouridx++;
   1044 			break;
   1045 		default:
   1046 			aprint_error ("ac97: shouldn't get here\n");
   1047 			break;
   1048 		}
   1049 	}
   1050 
   1051 	as->num_source_info = ouridx;
   1052 
   1053 	for (idx = 0; idx < as->num_source_info; idx++) {
   1054 		int idx2, previdx;
   1055 
   1056 		si = &as->source_info[idx];
   1057 
   1058 		/* Find mixer class */
   1059 		for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
   1060 			si2 = &as->source_info[idx2];
   1061 
   1062 			if (si2->type == AUDIO_MIXER_CLASS &&
   1063 			    ac97_str_equal(si->class,
   1064 					   si2->class)) {
   1065 				si->mixer_class = idx2;
   1066 			}
   1067 		}
   1068 
   1069 
   1070 		/* Setup prev and next pointers */
   1071 		if (si->prev != 0)
   1072 			continue;
   1073 
   1074 		if (si->qualifier)
   1075 			continue;
   1076 
   1077 		si->prev = AUDIO_MIXER_LAST;
   1078 		previdx = idx;
   1079 
   1080 		for (idx2 = 0; idx2 < as->num_source_info; idx2++) {
   1081 			if (idx2 == idx)
   1082 				continue;
   1083 
   1084 			si2 = &as->source_info[idx2];
   1085 
   1086 			if (!si2->prev &&
   1087 			    ac97_str_equal(si->class, si2->class) &&
   1088 			    ac97_str_equal(si->device, si2->device)) {
   1089 				as->source_info[previdx].next = idx2;
   1090 				as->source_info[idx2].prev = previdx;
   1091 
   1092 				previdx = idx2;
   1093 			}
   1094 		}
   1095 
   1096 		as->source_info[previdx].next = AUDIO_MIXER_LAST;
   1097 	}
   1098 }
   1099 
   1100 /* backward compatibility */
   1101 int
   1102 ac97_attach(struct ac97_host_if *host_if, struct device *sc_dev)
   1103 {
   1104 	return ac97_attach_type(host_if, sc_dev, AC97_CODEC_TYPE_AUDIO);
   1105 }
   1106 
   1107 int
   1108 ac97_attach_type(struct ac97_host_if *host_if, struct device *sc_dev, int type)
   1109 {
   1110 	struct ac97_softc *as;
   1111 	int error, i, j;
   1112 	uint32_t id;
   1113 	uint16_t id1, id2;
   1114 	uint16_t extstat, rate;
   1115 	uint16_t val;
   1116 	mixer_ctrl_t ctl;
   1117 	void (*initfunc)(struct ac97_softc *);
   1118 #define FLAGBUFLEN	140
   1119 	char flagbuf[FLAGBUFLEN];
   1120 
   1121 	initfunc = NULL;
   1122 	as = malloc(sizeof(struct ac97_softc), M_DEVBUF, M_WAITOK|M_ZERO);
   1123 
   1124 	if (as == NULL)
   1125 		return ENOMEM;
   1126 
   1127 	as->codec_if.vtbl = &ac97civ;
   1128 	as->host_if = host_if;
   1129 	as->type = type;
   1130 
   1131 	if ((error = host_if->attach(host_if->arg, &as->codec_if))) {
   1132 		free(as, M_DEVBUF);
   1133 		return error;
   1134 	}
   1135 
   1136 	if (host_if->reset != NULL) {
   1137 		if ((error = host_if->reset(host_if->arg))) {
   1138 			free(as, M_DEVBUF);
   1139 			return error;
   1140 		}
   1141 	}
   1142 
   1143 	if (host_if->flags)
   1144 		as->host_flags = host_if->flags(host_if->arg);
   1145 
   1146 	/*
   1147 	 * Assume codec has all four power bits.
   1148 	 * XXXSCW: what to do for modems?
   1149 	 */
   1150 	as->power_all = AC97_POWER_REF | AC97_POWER_ANL | AC97_POWER_DAC |
   1151 	    AC97_POWER_ADC;
   1152 	if (as->type == AC97_CODEC_TYPE_AUDIO) {
   1153 		host_if->write(host_if->arg, AC97_REG_RESET, 0);
   1154 
   1155 		/*
   1156 		 * Power-up everything except the analogue mixer.
   1157 		 * If this codec doesn't support analogue mixer power-down,
   1158 		 * AC97_POWER_MIXER will read back as zero.
   1159 		 */
   1160 		host_if->write(host_if->arg, AC97_REG_POWER, AC97_POWER_MIXER);
   1161 		ac97_read(as, AC97_REG_POWER, &val);
   1162 		if ((val & AC97_POWER_MIXER) == 0) {
   1163 			/* Codec doesn't support analogue mixer power-down */
   1164 			as->power_all &= ~AC97_POWER_ANL;
   1165 		}
   1166 		host_if->write(host_if->arg, AC97_REG_POWER, POWER_EAMP_ON(as));
   1167 
   1168 		for (i = 500000; i >= 0; i--) {
   1169 			ac97_read(as, AC97_REG_POWER, &val);
   1170 			if ((val & as->power_all) == as->power_all)
   1171 			       break;
   1172 			DELAY(1);
   1173 		}
   1174 
   1175 		/* save AC97_REG_POWER so that we can restore it later */
   1176 		ac97_read(as, AC97_REG_POWER, &as->power_reg);
   1177 	} else if (as->type == AC97_CODEC_TYPE_MODEM) {
   1178 		host_if->write(host_if->arg, AC97_REG_EXT_MODEM_ID, 0);
   1179 	}
   1180 
   1181 	ac97_setup_defaults(as);
   1182 	if (as->type == AC97_CODEC_TYPE_AUDIO)
   1183 		ac97_read(as, AC97_REG_RESET, &as->caps);
   1184 	ac97_read(as, AC97_REG_VENDOR_ID1, &id1);
   1185 	ac97_read(as, AC97_REG_VENDOR_ID2, &id2);
   1186 
   1187 	id = (id1 << 16) | id2;
   1188 	aprint_normal("%s: ac97: ", sc_dev->dv_xname);
   1189 
   1190 	for (i = 0; ; i++) {
   1191 		if (ac97codecid[i].id == 0) {
   1192 			char pnp[4];
   1193 
   1194 			AC97_GET_CODEC_ID(id, pnp);
   1195 #define ISASCII(c) ((c) >= ' ' && (c) < 0x7f)
   1196 			if (ISASCII(pnp[0]) && ISASCII(pnp[1]) &&
   1197 			    ISASCII(pnp[2]))
   1198 				aprint_normal("%c%c%c%d",
   1199 				    pnp[0], pnp[1], pnp[2], pnp[3]);
   1200 			else
   1201 				aprint_normal("unknown (0x%08x)", id);
   1202 			break;
   1203 		}
   1204 		if (ac97codecid[i].id == (id & ac97codecid[i].mask)) {
   1205 			aprint_normal("%s", ac97codecid[i].name);
   1206 			if (ac97codecid[i].mask == AC97_VENDOR_ID_MASK) {
   1207 				aprint_normal(" (0x%08x)", id);
   1208 			}
   1209 			initfunc = ac97codecid[i].init;
   1210 			break;
   1211 		}
   1212 	}
   1213 	aprint_normal(" codec; ");
   1214 	for (i = j = 0; i < 10; i++) {
   1215 		if (as->caps & (1 << i)) {
   1216 			aprint_normal("%s%s", j ? ", " : "", ac97feature[i]);
   1217 			j++;
   1218 		}
   1219 	}
   1220 	aprint_normal("%s%s\n", j ? ", " : "",
   1221 	       ac97enhancement[AC97_CAPS_ENHANCEMENT(as->caps)]);
   1222 
   1223 	as->ac97_clock = AC97_STANDARD_CLOCK;
   1224 
   1225 	if (as->type == AC97_CODEC_TYPE_AUDIO) {
   1226 		ac97_read(as, AC97_REG_EXT_AUDIO_ID, &as->ext_id);
   1227 		if (as->ext_id != 0) {
   1228 			/* Print capabilities */
   1229 			bitmask_snprintf(as->ext_id,
   1230 				 "\20\20SECONDARY10\17SECONDARY01"
   1231 				 "\14AC97_23\13AC97_22\12AMAP\11LDAC\10SDAC"
   1232 				 "\7CDAC\4VRM\3SPDIF\2DRA\1VRA",
   1233 				 flagbuf, FLAGBUFLEN);
   1234 			aprint_normal("%s: ac97: ext id %s\n", sc_dev->dv_xname,
   1235 				      flagbuf);
   1236 
   1237 			/* Print unusual settings */
   1238 			if (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) {
   1239 				aprint_normal("%s: ac97: Slot assignment: ",
   1240 					      sc_dev->dv_xname);
   1241 				switch (as->ext_id & AC97_EXT_AUDIO_DSA_MASK) {
   1242 				case AC97_EXT_AUDIO_DSA01:
   1243 					aprint_normal("7&8, 6&9, 10&11.\n");
   1244 					break;
   1245 				case AC97_EXT_AUDIO_DSA10:
   1246 					aprint_normal("6&9, 10&11, 3&4.\n");
   1247 					break;
   1248 				case AC97_EXT_AUDIO_DSA11:
   1249 					aprint_normal("10&11, 3&4, 7&8.\n");
   1250 					break;
   1251 				}
   1252 			}
   1253 			if (as->host_flags & AC97_HOST_INVERTED_EAMP) {
   1254 				aprint_normal("%s: ac97: using inverted "
   1255 					      "AC97_POWER_EAMP bit\n",
   1256 					      sc_dev->dv_xname);
   1257 			}
   1258 
   1259 			/* Enable and disable features */
   1260 			ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &extstat);
   1261 			extstat &= ~AC97_EXT_AUDIO_DRA;
   1262 			if (as->ext_id & AC97_EXT_AUDIO_LDAC)
   1263 				extstat |= AC97_EXT_AUDIO_LDAC;
   1264 			if (as->ext_id & AC97_EXT_AUDIO_SDAC)
   1265 				extstat |= AC97_EXT_AUDIO_SDAC;
   1266 			if (as->ext_id & AC97_EXT_AUDIO_CDAC)
   1267 				extstat |= AC97_EXT_AUDIO_CDAC;
   1268 			if (as->ext_id & AC97_EXT_AUDIO_VRM)
   1269 				extstat |= AC97_EXT_AUDIO_VRM;
   1270 			if (as->ext_id & AC97_EXT_AUDIO_SPDIF) {
   1271 				/* Output the same data as DAC to SPDIF output */
   1272 				extstat &= ~AC97_EXT_AUDIO_SPSA_MASK;
   1273 				extstat |= AC97_EXT_AUDIO_SPSA34;
   1274 				ac97_read(as, AC97_REG_SPDIF_CTRL, &val);
   1275 				val = (val & ~AC97_SPDIF_SPSR_MASK)
   1276 				    | AC97_SPDIF_SPSR_48K;
   1277 				ac97_write(as, AC97_REG_SPDIF_CTRL, val);
   1278 			}
   1279 			if (as->ext_id & AC97_EXT_AUDIO_VRA)
   1280 				extstat |= AC97_EXT_AUDIO_VRA;
   1281 			ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, extstat);
   1282 			if (as->ext_id & AC97_EXT_AUDIO_VRA) {
   1283 				/* VRA should be enabled. */
   1284 				/* so it claims to do variable rate, let's make sure */
   1285 				ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE,
   1286 					   44100);
   1287 				ac97_read(as, AC97_REG_PCM_FRONT_DAC_RATE,
   1288 					  &rate);
   1289 				if (rate != 44100) {
   1290 					/* We can't believe ext_id */
   1291 					as->ext_id = 0;
   1292 					aprint_normal(
   1293 					    "%s: Ignore these capabilities.\n",
   1294 					    sc_dev->dv_xname);
   1295 				}
   1296 				/* restore the default value */
   1297 				ac97_write(as, AC97_REG_PCM_FRONT_DAC_RATE,
   1298 					   AC97_SINGLE_RATE);
   1299 			}
   1300 		}
   1301 	} else if (as->type == AC97_CODEC_TYPE_MODEM) {
   1302 		const struct sysctlnode *node;
   1303 		const struct sysctlnode *node_line1;
   1304 		const struct sysctlnode *node_line2;
   1305 		uint16_t xrate = 8000;
   1306 		uint16_t xval, reg;
   1307 		int err;
   1308 
   1309 		ac97_read(as, AC97_REG_EXT_MODEM_ID, &as->ext_mid);
   1310 		if (as->ext_mid == 0 || as->ext_mid == 0xffff) {
   1311 			aprint_normal("%s: no modem codec found\n",
   1312 				      sc_dev->dv_xname);
   1313 			return ENXIO;
   1314 		}
   1315 		as->type = AC97_CODEC_TYPE_MODEM;
   1316 
   1317 		/* Print capabilities */
   1318 		bitmask_snprintf(as->ext_mid,
   1319 				 "\20\5CID2\4CID1\3HANDSET\2LINE2\1LINE1",
   1320 				 flagbuf, FLAGBUFLEN);
   1321 		aprint_normal("%s: ac97: ext mid %s", sc_dev->dv_xname,
   1322 			      flagbuf);
   1323 		aprint_normal(", %s codec\n",
   1324 			      (as->ext_mid & 0xc000) == 0 ?
   1325 			      "primary" : "secondary");
   1326 
   1327 		/* Setup modem and sysctls */
   1328 		err = sysctl_createv(&as->log, 0, NULL, NULL, 0, CTLTYPE_NODE,
   1329 				     "hw", NULL, NULL, 0, NULL, 0, CTL_HW,
   1330 				     CTL_EOL);
   1331 		if (err != 0)
   1332 			goto setup_modem;
   1333 		err = sysctl_createv(&as->log, 0, NULL, &node, 0,
   1334 				     CTLTYPE_NODE, sc_dev->dv_xname, NULL,
   1335 				     NULL, 0, NULL, 0, CTL_HW, CTL_CREATE,
   1336 				     CTL_EOL);
   1337 		if (err != 0)
   1338 			goto setup_modem;
   1339 setup_modem:
   1340 		/* reset */
   1341 		ac97_write(as, AC97_REG_EXT_MODEM_ID, 1);
   1342 
   1343 		/* program rates */
   1344 		xval = 0xff00 & ~AC97_EXT_MODEM_CTRL_PRA;
   1345 		if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
   1346 			ac97_write(as, AC97_REG_LINE1_RATE, xrate);
   1347 			xval &= ~(AC97_EXT_MODEM_CTRL_PRC |
   1348 			       AC97_EXT_MODEM_CTRL_PRD);
   1349 		}
   1350 		if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
   1351 			ac97_write(as, AC97_REG_LINE2_RATE, xrate);
   1352 			xval &= ~(AC97_EXT_MODEM_CTRL_PRE |
   1353 			       AC97_EXT_MODEM_CTRL_PRF);
   1354 		}
   1355 		if (as->ext_mid & AC97_EXT_MODEM_HANDSET) {
   1356 			ac97_write(as, AC97_REG_HANDSET_RATE, xrate);
   1357 			xval &= ~(AC97_EXT_MODEM_CTRL_PRG |
   1358 			       AC97_EXT_MODEM_CTRL_PRH);
   1359 		}
   1360 
   1361 		/* power-up everything */
   1362 		ac97_write(as, AC97_REG_EXT_MODEM_CTRL, 0);
   1363 		for (i = 5000; i >= 0; i--) {
   1364 			ac97_read(as, AC97_REG_EXT_MODEM_CTRL, &reg);
   1365 			if ((reg & /*XXXval*/0xf) == /*XXXval*/0xf)
   1366 			       break;
   1367 			DELAY(1);
   1368 		}
   1369 		if (i <= 0) {
   1370 			printf("%s: codec not responding, status=0x%x\n",
   1371 			    sc_dev->dv_xname, reg);
   1372 			return ENXIO;
   1373 		}
   1374 
   1375 		/* setup sysctls */
   1376 		if (as->ext_mid & AC97_EXT_MODEM_LINE1) {
   1377 			ac97_read(as, AC97_REG_GPIO_CFG, &reg);
   1378 			reg &= ~AC97_GPIO_LINE1_OH;
   1379 			ac97_write(as, AC97_REG_GPIO_CFG, reg);
   1380 			ac97_read(as, AC97_REG_GPIO_POLARITY, &reg);
   1381 			reg &= ~AC97_GPIO_LINE1_OH;
   1382 			ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
   1383 
   1384 			err = sysctl_createv(&as->log, 0, NULL, &node_line1,
   1385 					     CTLFLAG_READWRITE, CTLTYPE_INT,
   1386 					     "line1",
   1387 					     SYSCTL_DESCR("off-hook line1"),
   1388 					     ac97_sysctl_verify, 0, as, 0,
   1389 					     CTL_HW, node->sysctl_num,
   1390 					     CTL_CREATE, CTL_EOL);
   1391 			if (err != 0)
   1392 				goto sysctl_err;
   1393 			as->offhook_line1_mib = node_line1->sysctl_num;
   1394 		}
   1395 		if (as->ext_mid & AC97_EXT_MODEM_LINE2) {
   1396 			ac97_read(as, AC97_REG_GPIO_CFG, &reg);
   1397 			reg &= ~AC97_GPIO_LINE2_OH;
   1398 			ac97_write(as, AC97_REG_GPIO_CFG, reg);
   1399 			ac97_read(as, AC97_REG_GPIO_POLARITY, &reg);
   1400 			reg &= ~AC97_GPIO_LINE2_OH;
   1401 			ac97_write(as, AC97_REG_GPIO_POLARITY, reg);
   1402 
   1403 			err = sysctl_createv(&as->log, 0, NULL, &node_line2,
   1404 					     CTLFLAG_READWRITE, CTLTYPE_INT,
   1405 					     "line2",
   1406 					     SYSCTL_DESCR("off-hook line2"),
   1407 					     ac97_sysctl_verify, 0, as, 0,
   1408 					     CTL_HW, node->sysctl_num,
   1409 					     CTL_CREATE, CTL_EOL);
   1410 			if (err != 0)
   1411 				goto sysctl_err;
   1412 			as->offhook_line2_mib = node_line2->sysctl_num;
   1413 		}
   1414 sysctl_err:
   1415 
   1416 		ac97_write(as, AC97_REG_GPIO_STICKY, 0xffff);
   1417 		ac97_write(as, AC97_REG_GPIO_WAKEUP, 0x0);
   1418 		ac97_write(as, AC97_REG_MISC_AFE, 0x0);
   1419 	}
   1420 
   1421 	as->source_info = (as->type == AC97_CODEC_TYPE_MODEM ?
   1422 			   as->modem_source_info : as->audio_source_info);
   1423 	ac97_setup_source_info(as);
   1424 
   1425 	memset(&ctl, 0, sizeof(ctl));
   1426 	/* disable mutes */
   1427 	for (i = 0; i < 11; i++) {
   1428 		static struct {
   1429 			const char *class, *device;
   1430 		} d[11] = {
   1431 			{ AudioCoutputs, AudioNmaster},
   1432 			{ AudioCoutputs, AudioNheadphone},
   1433 			{ AudioCoutputs, AudioNsurround},
   1434 			{ AudioCoutputs, AudioNcenter},
   1435 			{ AudioCoutputs, AudioNlfe},
   1436 			{ AudioCinputs, AudioNdac},
   1437 			{ AudioCinputs, AudioNcd},
   1438 			{ AudioCinputs, AudioNline},
   1439 			{ AudioCinputs, AudioNaux},
   1440 			{ AudioCinputs, AudioNvideo},
   1441 			{ AudioCrecord, AudioNvolume},
   1442 		};
   1443 
   1444 		ctl.type = AUDIO_MIXER_ENUM;
   1445 		ctl.un.ord = 0;
   1446 
   1447 		ctl.dev = ac97_get_portnum_by_name(&as->codec_if,
   1448 			d[i].class, d[i].device, AudioNmute);
   1449 		ac97_mixer_set_port(&as->codec_if, &ctl);
   1450 	}
   1451 	ctl.type = AUDIO_MIXER_ENUM;
   1452 	ctl.un.ord = 0;
   1453 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCrecord,
   1454 					   AudioNsource, NULL);
   1455 	ac97_mixer_set_port(&as->codec_if, &ctl);
   1456 
   1457 	/* set a reasonable default volume */
   1458 	ctl.type = AUDIO_MIXER_VALUE;
   1459 	ctl.un.value.num_channels = 2;
   1460 	ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = \
   1461 	ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127;
   1462 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
   1463 					   AudioNmaster, NULL);
   1464 	ac97_mixer_set_port(&as->codec_if, &ctl);
   1465 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
   1466 					   AudioNsurround, NULL);
   1467 	ac97_mixer_set_port(&as->codec_if, &ctl);
   1468 	ctl.un.value.num_channels = 1;
   1469 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
   1470 					   AudioNcenter, NULL);
   1471 	ac97_mixer_set_port(&as->codec_if, &ctl);
   1472 	ctl.dev = ac97_get_portnum_by_name(&as->codec_if, AudioCoutputs,
   1473 					   AudioNlfe, NULL);
   1474 	ac97_mixer_set_port(&as->codec_if, &ctl);
   1475 
   1476 	if (initfunc != NULL)
   1477 		initfunc(as);
   1478 
   1479 	/* restore AC97_REG_POWER */
   1480 	if (as->type == AC97_CODEC_TYPE_AUDIO)
   1481 		ac97_write(as, AC97_REG_POWER, as->power_reg);
   1482 
   1483 	return 0;
   1484 }
   1485 
   1486 static void
   1487 ac97_detach(struct ac97_codec_if *codec_if)
   1488 {
   1489 	struct ac97_softc *as;
   1490 
   1491 	as = (struct ac97_softc *)codec_if;
   1492 	ac97_write(as, AC97_REG_POWER, AC97_POWER_IN | AC97_POWER_OUT
   1493 		   | AC97_POWER_MIXER | AC97_POWER_MIXER_VREF
   1494 		   | AC97_POWER_ACLINK | AC97_POWER_CLK | AC97_POWER_AUX
   1495 		   | POWER_EAMP_OFF(as));
   1496 	free(as, M_DEVBUF);
   1497 }
   1498 
   1499 static void
   1500 ac97_lock(struct ac97_codec_if *codec_if)
   1501 {
   1502 	struct ac97_softc *as;
   1503 
   1504 	as = (struct ac97_softc *)codec_if;
   1505 	as->lock_counter++;
   1506 }
   1507 
   1508 static void
   1509 ac97_unlock(struct ac97_codec_if *codec_if)
   1510 {
   1511 	struct ac97_softc *as;
   1512 
   1513 	as = (struct ac97_softc *)codec_if;
   1514 	as->lock_counter--;
   1515 }
   1516 
   1517 static int
   1518 ac97_query_devinfo(struct ac97_codec_if *codec_if, mixer_devinfo_t *dip)
   1519 {
   1520 	struct ac97_softc *as;
   1521 	struct ac97_source_info *si;
   1522 	const char *name;
   1523 
   1524 	as = (struct ac97_softc *)codec_if;
   1525 	if (dip->index < as->num_source_info) {
   1526 		si = &as->source_info[dip->index];
   1527 		dip->type = si->type;
   1528 		dip->mixer_class = si->mixer_class;
   1529 		dip->prev = si->prev;
   1530 		dip->next = si->next;
   1531 
   1532 		if (si->qualifier)
   1533 			name = si->qualifier;
   1534 		else if (si->device)
   1535 			name = si->device;
   1536 		else if (si->class)
   1537 			name = si->class;
   1538 		else
   1539 			name = 0;
   1540 
   1541 		if (name)
   1542 			strcpy(dip->label.name, name);
   1543 
   1544 		memcpy(&dip->un, si->info, si->info_size);
   1545 
   1546 		/* Set the delta for volume sources */
   1547 		if (dip->type == AUDIO_MIXER_VALUE)
   1548 			dip->un.v.delta = 1 << (8 - si->bits);
   1549 
   1550 		return 0;
   1551 	}
   1552 
   1553 	return ENXIO;
   1554 }
   1555 
   1556 static int
   1557 ac97_mixer_set_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
   1558 {
   1559 	struct ac97_softc *as;
   1560 	struct ac97_source_info *si;
   1561 	uint16_t mask;
   1562 	uint16_t val, newval;
   1563 	int error;
   1564 	bool spdif;
   1565 
   1566 	as = (struct ac97_softc *)codec_if;
   1567 	if (cp->dev < 0 || cp->dev >= as->num_source_info)
   1568 		return EINVAL;
   1569 	si = &as->source_info[cp->dev];
   1570 
   1571 	if (cp->type == AUDIO_MIXER_CLASS || cp->type != si->type)
   1572 		return EINVAL;
   1573 	spdif = si->req_feature == CHECK_SPDIF && si->reg == AC97_REG_EXT_AUDIO_CTRL;
   1574 	if (spdif && as->lock_counter >= 0) {
   1575 		/* When the value of lock_counter is the default 0,
   1576 		 * it is not allowed to change the SPDIF mode. */
   1577 		return EBUSY;
   1578 	}
   1579 
   1580 	ac97_read(as, si->reg, &val);
   1581 
   1582 	DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
   1583 
   1584 	mask = (1 << si->bits) - 1;
   1585 
   1586 	switch (cp->type) {
   1587 	case AUDIO_MIXER_ENUM:
   1588 		if (cp->un.ord > mask || cp->un.ord < 0)
   1589 			return EINVAL;
   1590 
   1591 		newval = (cp->un.ord << si->ofs);
   1592 		if (si->reg == AC97_REG_RECORD_SELECT) {
   1593 			newval |= (newval << (8 + si->ofs));
   1594 			mask |= (mask << 8);
   1595 			mask = mask << si->ofs;
   1596 		} else if (si->reg == AC97_REG_SURR_MASTER) {
   1597 			newval = cp->un.ord ? 0x8080 : 0x0000;
   1598 			mask = 0x8080;
   1599 		} else
   1600 			mask = mask << si->ofs;
   1601 		break;
   1602 	case AUDIO_MIXER_VALUE:
   1603 	{
   1604 		const struct audio_mixer_value *value = si->info;
   1605 		uint16_t  l, r, ol, or;
   1606 		int deltal, deltar;
   1607 
   1608 		if ((cp->un.value.num_channels <= 0) ||
   1609 		    (cp->un.value.num_channels > value->num_channels))
   1610 			return EINVAL;
   1611 
   1612 		if (cp->un.value.num_channels == 1) {
   1613 			l = r = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
   1614 		} else {
   1615 			if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
   1616 				l = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
   1617 				r = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
   1618 			} else {	/* left/right is reversed here */
   1619 				r = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
   1620 				l = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
   1621 			}
   1622 
   1623 		}
   1624 
   1625 		if (!si->polarity) {
   1626 			l = 255 - l;
   1627 			r = 255 - r;
   1628 		}
   1629 
   1630 		ol = (val >> (8+si->ofs)) & mask;
   1631 		or = (val >> si->ofs) & mask;
   1632 
   1633 		deltal = (ol << (8 - si->bits)) - l;
   1634 		deltar = (or << (8 - si->bits)) - r;
   1635 
   1636 		l = l >> (8 - si->bits);
   1637 		r = r >> (8 - si->bits);
   1638 
   1639 		if (deltal && ol == l)
   1640 			l += (deltal > 0) ? (l ? -1 : 0) : (l < mask ? 1 : 0);
   1641 		if (deltar && or == r)
   1642 			r += (deltar > 0) ? (r ? -1 : 0) : (r < mask ? 1 : 0);
   1643 
   1644 		newval = ((r & mask) << si->ofs);
   1645 		if (value->num_channels == 2) {
   1646 			newval = newval | ((l & mask) << (si->ofs+8));
   1647 			mask |= (mask << 8);
   1648 		}
   1649 		mask = mask << si->ofs;
   1650 		break;
   1651 	}
   1652 	default:
   1653 		return EINVAL;
   1654 	}
   1655 
   1656 	error = ac97_write(as, si->reg, (val & ~mask) | newval);
   1657 	if (error)
   1658 		return error;
   1659 
   1660 	if (spdif && as->host_if->spdif_event != NULL) {
   1661 		DPRINTF(("%s: call spdif_event(%d)\n", __func__, cp->un.ord));
   1662 		as->host_if->spdif_event(as->host_if->arg, cp->un.ord);
   1663 	}
   1664 	return 0;
   1665 }
   1666 
   1667 static int
   1668 ac97_get_portnum_by_name(struct ac97_codec_if *codec_if, const char *class,
   1669 			 const char *device, const char *qualifier)
   1670 {
   1671 	struct ac97_softc *as;
   1672 	int idx;
   1673 
   1674 	as = (struct ac97_softc *)codec_if;
   1675 	for (idx = 0; idx < as->num_source_info; idx++) {
   1676 		struct ac97_source_info *si = &as->source_info[idx];
   1677 		if (ac97_str_equal(class, si->class) &&
   1678 		    ac97_str_equal(device, si->device) &&
   1679 		    ac97_str_equal(qualifier, si->qualifier))
   1680 			return idx;
   1681 	}
   1682 
   1683 	return -1;
   1684 }
   1685 
   1686 static int
   1687 ac97_mixer_get_port(struct ac97_codec_if *codec_if, mixer_ctrl_t *cp)
   1688 {
   1689 	struct ac97_softc *as;
   1690 	struct ac97_source_info *si;
   1691 	uint16_t mask;
   1692 	uint16_t val;
   1693 
   1694 	as = (struct ac97_softc *)codec_if;
   1695 	si = &as->source_info[cp->dev];
   1696 	if (cp->dev < 0 || cp->dev >= as->num_source_info)
   1697 		return EINVAL;
   1698 
   1699 	if (cp->type != si->type)
   1700 		return EINVAL;
   1701 
   1702 	ac97_read(as, si->reg, &val);
   1703 
   1704 	DPRINTFN(5, ("read(%x) = %x\n", si->reg, val));
   1705 
   1706 	mask = (1 << si->bits) - 1;
   1707 
   1708 	switch (cp->type) {
   1709 	case AUDIO_MIXER_ENUM:
   1710 		cp->un.ord = (val >> si->ofs) & mask;
   1711 		DPRINTFN(4, ("AUDIO_MIXER_ENUM: %x %d %x %d\n",
   1712 			     val, si->ofs, mask, cp->un.ord));
   1713 		break;
   1714 	case AUDIO_MIXER_VALUE:
   1715 	{
   1716 		const struct audio_mixer_value *value = si->info;
   1717 		uint16_t  l, r;
   1718 
   1719 		if ((cp->un.value.num_channels <= 0) ||
   1720 		    (cp->un.value.num_channels > value->num_channels))
   1721 			return EINVAL;
   1722 
   1723 		if (value->num_channels == 1) {
   1724 			l = r = (val >> si->ofs) & mask;
   1725 		} else {
   1726 			if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
   1727 				l = (val >> (si->ofs + 8)) & mask;
   1728 				r = (val >> si->ofs) & mask;
   1729 			} else {	/* host has reversed channels */
   1730 				r = (val >> (si->ofs + 8)) & mask;
   1731 				l = (val >> si->ofs) & mask;
   1732 			}
   1733 		}
   1734 
   1735 		l = (l << (8 - si->bits));
   1736 		r = (r << (8 - si->bits));
   1737 		if (!si->polarity) {
   1738 			l = 255 - l;
   1739 			r = 255 - r;
   1740 		}
   1741 
   1742 		/* The EAP driver averages l and r for stereo
   1743 		   channels that are requested in MONO mode. Does this
   1744 		   make sense? */
   1745 		if (cp->un.value.num_channels == 1) {
   1746 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = l;
   1747 		} else if (cp->un.value.num_channels == 2) {
   1748 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
   1749 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
   1750 		}
   1751 
   1752 		break;
   1753 	}
   1754 	default:
   1755 		return EINVAL;
   1756 	}
   1757 
   1758 	return 0;
   1759 }
   1760 
   1761 
   1762 static int
   1763 ac97_set_rate(struct ac97_codec_if *codec_if, int target, u_int *rate)
   1764 {
   1765 	struct ac97_softc *as;
   1766 	u_int value;
   1767 	uint16_t ext_stat;
   1768 	uint16_t actual;
   1769 	uint16_t power;
   1770 	uint16_t power_bit;
   1771 
   1772 	as = (struct ac97_softc *)codec_if;
   1773 	if (target == AC97_REG_PCM_MIC_ADC_RATE) {
   1774 		if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) {
   1775 			*rate = AC97_SINGLE_RATE;
   1776 			return 0;
   1777 		}
   1778 	} else {
   1779 		if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
   1780 			*rate = AC97_SINGLE_RATE;
   1781 			return 0;
   1782 		}
   1783 	}
   1784 	value = *rate * AC97_STANDARD_CLOCK / as->ac97_clock;
   1785 	ext_stat = 0;
   1786 	/*
   1787 	 * PCM_FRONT_DAC_RATE/PCM_SURR_DAC_RATE/PCM_LFE_DAC_RATE
   1788 	 *	Check VRA, DRA
   1789 	 * PCM_LR_ADC_RATE
   1790 	 *	Check VRA
   1791 	 * PCM_MIC_ADC_RATE
   1792 	 *	Check VRM
   1793 	 */
   1794 	switch (target) {
   1795 	case AC97_REG_PCM_FRONT_DAC_RATE:
   1796 	case AC97_REG_PCM_SURR_DAC_RATE:
   1797 	case AC97_REG_PCM_LFE_DAC_RATE:
   1798 		power_bit = AC97_POWER_OUT;
   1799 		if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
   1800 			*rate = AC97_SINGLE_RATE;
   1801 			return 0;
   1802 		}
   1803 		if (as->ext_id & AC97_EXT_AUDIO_DRA) {
   1804 			ac97_read(as, AC97_REG_EXT_AUDIO_CTRL, &ext_stat);
   1805 			if (value > 0x1ffff) {
   1806 				return EINVAL;
   1807 			} else if (value > 0xffff) {
   1808 				/* Enable DRA */
   1809 				ext_stat |= AC97_EXT_AUDIO_DRA;
   1810 				ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
   1811 				value /= 2;
   1812 			} else {
   1813 				/* Disable DRA */
   1814 				ext_stat &= ~AC97_EXT_AUDIO_DRA;
   1815 				ac97_write(as, AC97_REG_EXT_AUDIO_CTRL, ext_stat);
   1816 			}
   1817 		} else {
   1818 			if (value > 0xffff)
   1819 				return EINVAL;
   1820 		}
   1821 		break;
   1822 	case AC97_REG_PCM_LR_ADC_RATE:
   1823 		power_bit = AC97_POWER_IN;
   1824 		if (!(as->ext_id & AC97_EXT_AUDIO_VRA)) {
   1825 			*rate = AC97_SINGLE_RATE;
   1826 			return 0;
   1827 		}
   1828 		if (value > 0xffff)
   1829 			return EINVAL;
   1830 		break;
   1831 	case AC97_REG_PCM_MIC_ADC_RATE:
   1832 		power_bit = AC97_POWER_IN;
   1833 		if (!(as->ext_id & AC97_EXT_AUDIO_VRM)) {
   1834 			*rate = AC97_SINGLE_RATE;
   1835 			return 0;
   1836 		}
   1837 		if (value > 0xffff)
   1838 			return EINVAL;
   1839 		break;
   1840 	default:
   1841 		printf("%s: Unknown register: 0x%x\n", __func__, target);
   1842 		return EINVAL;
   1843 	}
   1844 
   1845 	ac97_read(as, AC97_REG_POWER, &power);
   1846 	ac97_write(as, AC97_REG_POWER, power | power_bit);
   1847 
   1848 	ac97_write(as, target, (uint16_t)value);
   1849 	ac97_read(as, target, &actual);
   1850 	actual = (uint32_t)actual * as->ac97_clock / AC97_STANDARD_CLOCK;
   1851 
   1852 	ac97_write(as, AC97_REG_POWER, power);
   1853 	if (ext_stat & AC97_EXT_AUDIO_DRA) {
   1854 		*rate = actual * 2;
   1855 	} else {
   1856 		*rate = actual;
   1857 	}
   1858 	return 0;
   1859 }
   1860 
   1861 static void
   1862 ac97_set_clock(struct ac97_codec_if *codec_if, unsigned int clock)
   1863 {
   1864 	struct ac97_softc *as;
   1865 
   1866 	as = (struct ac97_softc *)codec_if;
   1867 	as->ac97_clock = clock;
   1868 }
   1869 
   1870 static uint16_t
   1871 ac97_get_extcaps(struct ac97_codec_if *codec_if)
   1872 {
   1873 	struct ac97_softc *as;
   1874 
   1875 	as = (struct ac97_softc *)codec_if;
   1876 	return as->ext_id;
   1877 }
   1878 
   1879 static int
   1880 ac97_add_port(struct ac97_softc *as, const struct ac97_source_info *src)
   1881 {
   1882 	struct ac97_source_info *si;
   1883 	int ouridx, idx;
   1884 
   1885 	if ((as->type == AC97_CODEC_TYPE_AUDIO &&
   1886 	     as->num_source_info >= AUDIO_MAX_SOURCES) ||
   1887 	    (as->type == AC97_CODEC_TYPE_MODEM &&
   1888 	     as->num_source_info >= MODEM_MAX_SOURCES)) {
   1889 		printf("%s: internal error: increase MAX_SOURCES in %s\n",
   1890 		       __func__, __FILE__);
   1891 		return -1;
   1892 	}
   1893 	if (!ac97_check_capability(as, src->req_feature))
   1894 		return -1;
   1895 	ouridx = as->num_source_info;
   1896 	si = &as->source_info[ouridx];
   1897 	memcpy(si, src, sizeof(*si));
   1898 
   1899 	switch (si->type) {
   1900 	case AUDIO_MIXER_CLASS:
   1901 	case AUDIO_MIXER_VALUE:
   1902 		printf("%s: adding class/value is not supported yet.\n",
   1903 		       __func__);
   1904 		return -1;
   1905 	case AUDIO_MIXER_ENUM:
   1906 		break;
   1907 	default:
   1908 		printf("%s: unknown type: %d\n", __func__, si->type);
   1909 		return -1;
   1910 	}
   1911 	as->num_source_info++;
   1912 
   1913 	si->mixer_class = ac97_get_portnum_by_name(&as->codec_if, si->class,
   1914 						   NULL, NULL);
   1915 	/* Find the root of the device */
   1916 	idx = ac97_get_portnum_by_name(&as->codec_if, si->class,
   1917 				       si->device, NULL);
   1918 	/* Find the last item */
   1919 	while (as->source_info[idx].next != AUDIO_MIXER_LAST)
   1920 		idx = as->source_info[idx].next;
   1921 	/* Append */
   1922 	as->source_info[idx].next = ouridx;
   1923 	si->prev = idx;
   1924 	si->next = AUDIO_MIXER_LAST;
   1925 
   1926 	return 0;
   1927 }
   1928 
   1929 /**
   1930  * Codec-dependent initialization
   1931  */
   1932 
   1933 #define	AD1980_REG_MISC	0x76
   1934 #define		AD1980_MISC_MBG0	0x0001	/* 0 1888/1980/1981 /1985 */
   1935 #define		AD1980_MISC_MBG1	0x0002	/* 1 1888/1980/1981 /1985 */
   1936 #define		AD1980_MISC_VREFD	0x0004	/* 2 1888/1980/1981 /1985 */
   1937 #define		AD1980_MISC_VREFH	0x0008	/* 3 1888/1980/1981 /1985 */
   1938 #define		AD1980_MISC_SRU		0x0010	/* 4 1888/1980      /1985 */
   1939 #define		AD1980_MISC_LOSEL	0x0020	/* 5 1888/1980/1981 /1985 */
   1940 #define		AD1980_MISC_2CMIC	0x0040	/* 6      1980/1981B/1985 */
   1941 #define		AD1980_MISC_SPRD	0x0080	/* 7 1888/1980      /1985 */
   1942 #define		AD1980_MISC_DMIX0	0x0100	/* 8 1888/1980      /1985 */
   1943 #define		AD1980_MISC_DMIX1	0x0200	/* 9 1888/1980      /1985 */
   1944 #define		AD1980_MISC_HPSEL	0x0400	/*10 1888/1980      /1985 */
   1945 #define		AD1980_MISC_CLDIS	0x0800	/*11 1888/1980      /1985 */
   1946 #define		AD1980_MISC_LODIS	0x1000	/*12 1888/1980/1981 /1985 */
   1947 #define		AD1980_MISC_MSPLT	0x2000	/*13 1888/1980/1981 /1985 */
   1948 #define		AD1980_MISC_AC97NC	0x4000	/*14 1888/1980      /1985 */
   1949 #define		AD1980_MISC_DACZ	0x8000	/*15 1888/1980/1981 /1985 */
   1950 #define	AD1981_REG_MISC	0x76
   1951 #define		AD1981_MISC_MADST	0x0010  /* 4 */
   1952 #define		AD1981A_MISC_MADPD	0x0040  /* 6 */
   1953 #define		AD1981B_MISC_MADPD	0x0080  /* 7 */
   1954 #define		AD1981_MISC_FMXE	0x0200  /* 9 */
   1955 #define		AD1981_MISC_DAM		0x0800  /*11 */
   1956 static void
   1957 ac97_ad198x_init(struct ac97_softc *as)
   1958 {
   1959 	int i;
   1960 	uint16_t misc;
   1961 
   1962 	ac97_read(as, AD1980_REG_MISC, &misc);
   1963 	ac97_write(as, AD1980_REG_MISC,
   1964 		   misc | AD1980_MISC_LOSEL | AD1980_MISC_HPSEL);
   1965 
   1966 	for (i = 0; i < as->num_source_info; i++) {
   1967 		if (as->source_info[i].type != AUDIO_MIXER_VALUE)
   1968 			continue;
   1969 
   1970 		if (as->source_info[i].reg == AC97_REG_MASTER_VOLUME)
   1971 			as->source_info[i].reg = AC97_REG_SURR_MASTER;
   1972 		else if (as->source_info[i].reg == AC97_REG_SURR_MASTER)
   1973 			as->source_info[i].reg = AC97_REG_MASTER_VOLUME;
   1974 	}
   1975 }
   1976 
   1977 #define ALC650_REG_MULTI_CHANNEL_CONTROL	0x6a
   1978 #define		ALC650_MCC_SLOT_MODIFY_MASK		0xc000
   1979 #define		ALC650_MCC_FRONTDAC_FROM_SPDIFIN	0x2000 /* 13 */
   1980 #define		ALC650_MCC_SPDIFOUT_FROM_ADC		0x1000 /* 12 */
   1981 #define		ALC650_MCC_PCM_FROM_SPDIFIN		0x0800 /* 11 */
   1982 #define		ALC650_MCC_MIC_OR_CENTERLFE		0x0400 /* 10 */
   1983 #define		ALC650_MCC_LINEIN_OR_SURROUND		0x0200 /* 9 */
   1984 #define		ALC650_MCC_INDEPENDENT_MASTER_L		0x0080 /* 7 */
   1985 #define		ALC650_MCC_INDEPENDENT_MASTER_R		0x0040 /* 6 */
   1986 #define		ALC650_MCC_ANALOG_TO_CENTERLFE		0x0020 /* 5 */
   1987 #define		ALC650_MCC_ANALOG_TO_SURROUND		0x0010 /* 4 */
   1988 #define		ALC650_MCC_EXCHANGE_CENTERLFE		0x0008 /* 3 */
   1989 #define		ALC650_MCC_CENTERLFE_DOWNMIX		0x0004 /* 2 */
   1990 #define		ALC650_MCC_SURROUND_DOWNMIX		0x0002 /* 1 */
   1991 #define		ALC650_MCC_LINEOUT_TO_SURROUND		0x0001 /* 0 */
   1992 static void
   1993 ac97_alc650_init(struct ac97_softc *as)
   1994 {
   1995 	static const struct ac97_source_info sources[6] = {
   1996 		{ AudioCoutputs, AudioNsurround, "lineinjack",
   1997 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   1998 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   1999 		  0x0000, 1, 9, 0, 0, 0, CHECK_SURROUND, 0, 0, 0, },
   2000 		{ AudioCoutputs, AudioNsurround, "mixtofront",
   2001 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2002 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   2003 		  0x0000, 1, 1, 0, 0, 0, CHECK_SURROUND, 0, 0, 0, },
   2004 		{ AudioCoutputs, AudioNcenter, "micjack",
   2005 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2006 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   2007 		  0x0000, 1, 10, 0, 0, 0, CHECK_CENTER, 0, 0, 0, },
   2008 		{ AudioCoutputs, AudioNlfe, "micjack",
   2009 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2010 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   2011 		  0x0000, 1, 10, 0, 0, 0, CHECK_LFE, 0, 0, 0, },
   2012 		{ AudioCoutputs, AudioNcenter, "mixtofront",
   2013 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2014 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   2015 		  0x0000, 1, 2, 0, 0, 0, CHECK_CENTER, 0, 0, 0, },
   2016 		{ AudioCoutputs, AudioNlfe, "mixtofront",
   2017 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2018 		  ALC650_REG_MULTI_CHANNEL_CONTROL,
   2019 		  0x0000, 1, 2, 0, 0, 0, CHECK_LFE, 0, 0, 0, },
   2020 	};
   2021 
   2022 	ac97_add_port(as, &sources[0]);
   2023 	ac97_add_port(as, &sources[1]);
   2024 	ac97_add_port(as, &sources[2]);
   2025 	ac97_add_port(as, &sources[3]);
   2026 	ac97_add_port(as, &sources[4]);
   2027 	ac97_add_port(as, &sources[5]);
   2028 }
   2029 
   2030 #define VT1616_REG_IO_CONTROL	0x5a
   2031 #define		VT1616_IC_LVL			(1 << 15)
   2032 #define		VT1616_IC_LFECENTER_TO_FRONT	(1 << 12)
   2033 #define		VT1616_IC_SURROUND_TO_FRONT	(1 << 11)
   2034 #define		VT1616_IC_BPDC			(1 << 10)
   2035 #define		VT1616_IC_DC			(1 << 9)
   2036 #define		VT1616_IC_IB_MASK		0x000c
   2037 static void
   2038 ac97_vt1616_init(struct ac97_softc *as)
   2039 {
   2040 	static const struct ac97_source_info sources[3] = {
   2041 		{ AudioCoutputs, AudioNsurround, "mixtofront",
   2042 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2043 		  VT1616_REG_IO_CONTROL,
   2044 		  0x0000, 1, 11, 0, 0, 0, CHECK_SURROUND, 0, 0, 0, },
   2045 		{ AudioCoutputs, AudioNcenter, "mixtofront",
   2046 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2047 		  VT1616_REG_IO_CONTROL,
   2048 		  0x0000, 1, 12, 0, 0, 0, CHECK_CENTER, 0, 0, 0, },
   2049 		{ AudioCoutputs, AudioNlfe, "mixtofront",
   2050 		  AUDIO_MIXER_ENUM, WRAP(ac97_on_off),
   2051 		  VT1616_REG_IO_CONTROL,
   2052 		  0x0000, 1, 12, 0, 0, 0, CHECK_LFE, 0, 0, 0, },
   2053 	};
   2054 
   2055 	ac97_add_port(as, &sources[0]);
   2056 	ac97_add_port(as, &sources[1]);
   2057 	ac97_add_port(as, &sources[2]);
   2058 }
   2059 
   2060 static int
   2061 ac97_modem_offhook_set(struct ac97_softc *as, int line, int newval)
   2062 {
   2063 	uint16_t val;
   2064 
   2065 	val = as->shadow_reg[AC97_REG_GPIO_STATUS >> 1];
   2066 	switch (newval) {
   2067 	case 0:
   2068 		val &= ~line;
   2069 		break;
   2070 	case 1:
   2071 		val |= line;
   2072 		break;
   2073 	}
   2074 	ac97_write(as, AC97_REG_GPIO_STATUS, val);
   2075 
   2076 	return 0;
   2077 }
   2078 
   2079 static int
   2080 ac97_sysctl_verify(SYSCTLFN_ARGS)
   2081 {
   2082 	int error, tmp;
   2083 	struct sysctlnode node;
   2084 	struct ac97_softc *as;
   2085 
   2086 	node = *rnode;
   2087 	as = rnode->sysctl_data;
   2088 	if (node.sysctl_num == as->offhook_line1_mib) {
   2089 		tmp = as->offhook_line1;
   2090 		node.sysctl_data = &tmp;
   2091 		error = sysctl_lookup(SYSCTLFN_CALL(&node));
   2092 		if (error || newp == NULL)
   2093 			return error;
   2094 
   2095 		if (tmp < 0 || tmp > 1)
   2096 			return EINVAL;
   2097 
   2098 		as->offhook_line1 = tmp;
   2099 		ac97_modem_offhook_set(as, AC97_GPIO_LINE1_OH, tmp);
   2100 	} else if (node.sysctl_num == as->offhook_line2_mib) {
   2101 		tmp = as->offhook_line2;
   2102 		node.sysctl_data = &tmp;
   2103 		error = sysctl_lookup(SYSCTLFN_CALL(&node));
   2104 		if (error || newp == NULL)
   2105 			return error;
   2106 
   2107 		if (tmp < 0 || tmp > 1)
   2108 			return EINVAL;
   2109 
   2110 		as->offhook_line2 = tmp;
   2111 		ac97_modem_offhook_set(as, AC97_GPIO_LINE2_OH, tmp);
   2112 	}
   2113 
   2114 	return 0;
   2115 }
   2116