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