xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/ac97.h (revision fe2d4a0fa3ebcc16de39aa66383d300ccb7fd860)
17979b1cfSJérôme Duval /*
27979b1cfSJérôme Duval  * AC97 interface
37979b1cfSJérôme Duval  *
47979b1cfSJérôme Duval  * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
57979b1cfSJérôme Duval  * Copyright (c) 2008, Jérôme Duval
67979b1cfSJérôme Duval  *
77979b1cfSJérôme Duval  * All rights reserved.
87979b1cfSJérôme Duval  * Redistribution and use in source and binary forms, with or without modification,
97979b1cfSJérôme Duval  * are permitted provided that the following conditions are met:
107979b1cfSJérôme Duval  *
117979b1cfSJérôme Duval  * - Redistributions of source code must retain the above copyright notice,
127979b1cfSJérôme Duval  *   this list of conditions and the following disclaimer.
137979b1cfSJérôme Duval  * - Redistributions in binary form must reproduce the above copyright notice,
147979b1cfSJérôme Duval  *   this list of conditions and the following disclaimer in the documentation
157979b1cfSJérôme Duval  *   and/or other materials provided with the distribution.
167979b1cfSJérôme Duval  *
177979b1cfSJérôme Duval  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
187979b1cfSJérôme Duval  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
197979b1cfSJérôme Duval  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
207979b1cfSJérôme Duval  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
217979b1cfSJérôme Duval  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
227979b1cfSJérôme Duval  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
237979b1cfSJérôme Duval  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247979b1cfSJérôme Duval  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
257979b1cfSJérôme Duval  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
267979b1cfSJérôme Duval  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277979b1cfSJérôme Duval  *
287979b1cfSJérôme Duval  */
297979b1cfSJérôme Duval #ifndef _AC97_H_
307979b1cfSJérôme Duval #define _AC97_H_
317979b1cfSJérôme Duval 
327979b1cfSJérôme Duval enum AC97_REGISTER {
337979b1cfSJérôme Duval 	/* Baseline audio register set */
347979b1cfSJérôme Duval 	AC97_RESET				= 0x00,
357979b1cfSJérôme Duval 	AC97_MASTER_VOLUME		= 0x02,
367979b1cfSJérôme Duval 	AC97_AUX_OUT_VOLUME		= 0x04,
377979b1cfSJérôme Duval 	AC97_MONO_VOLUME		= 0x06,
387979b1cfSJérôme Duval 	AC97_MASTER_TONE		= 0x08,
397979b1cfSJérôme Duval 	AC97_PC_BEEP_VOLUME		= 0x0A,
407979b1cfSJérôme Duval 	AC97_PHONE_VOLUME		= 0x0C,
417979b1cfSJérôme Duval 	AC97_MIC_VOLUME			= 0x0E,
427979b1cfSJérôme Duval 	AC97_LINE_IN_VOLUME		= 0x10,
437979b1cfSJérôme Duval 	AC97_CD_VOLUME			= 0x12,
447979b1cfSJérôme Duval 	AC97_VIDEO_VOLUME		= 0x14,
457979b1cfSJérôme Duval 	AC97_AUX_IN_VOLUME		= 0x16,
467979b1cfSJérôme Duval 	AC97_PCM_OUT_VOLUME		= 0x18,
477979b1cfSJérôme Duval 	AC97_RECORD_SELECT		= 0x1A,
487979b1cfSJérôme Duval 	AC97_RECORD_GAIN		= 0x1C,
497979b1cfSJérôme Duval 	AC97_RECORD_GAIN_MIC	= 0x1E,
507979b1cfSJérôme Duval 	AC97_GENERAL_PURPOSE	= 0x20,
517979b1cfSJérôme Duval 	AC97_3D_CONTROL			= 0x22,
527979b1cfSJérôme Duval 	AC97_PAGING				= 0x24,
537979b1cfSJérôme Duval 	AC97_POWERDOWN			= 0x26,
547979b1cfSJérôme Duval 
557979b1cfSJérôme Duval 	/* Extended audio register set */
567979b1cfSJérôme Duval 	AC97_EXTENDED_ID		= 0x28,
577979b1cfSJérôme Duval 	AC97_EXTENDED_STAT_CTRL = 0x2A,
587979b1cfSJérôme Duval 	AC97_PCM_FRONT_DAC_RATE = 0x2C,
597979b1cfSJérôme Duval 	AC97_PCM_SURR_DAC_RATE	= 0x2E,
607979b1cfSJérôme Duval 	AC97_PCM_LFE_DAC_RATE	= 0x30,
617979b1cfSJérôme Duval 	AC97_PCM_L_R_ADC_RATE	= 0x32,
627979b1cfSJérôme Duval 	AC97_MIC_ADC_RATE		= 0x34,
637979b1cfSJérôme Duval 	AC97_CENTER_LFE_VOLUME	= 0x36,
647979b1cfSJérôme Duval 	AC97_SURR_VOLUME		= 0x38,
657979b1cfSJérôme Duval 	AC97_SPDIF_CONTROL		= 0x3A,
667979b1cfSJérôme Duval 
677979b1cfSJérôme Duval 	/* Vendor ID */
687979b1cfSJérôme Duval 	AC97_VENDOR_ID1			= 0x7C,
697979b1cfSJérôme Duval 	AC97_VENDOR_ID2			= 0x7E,
707979b1cfSJérôme Duval 
717979b1cfSJérôme Duval 	/* Analog Devices */
727979b1cfSJérôme Duval 	AC97_AD_JACK_SENSE		= 0x72,
737979b1cfSJérôme Duval 	AC97_AD_SERIAL_CONFIG	= 0x74,
747979b1cfSJérôme Duval 	AC97_AD_MISC_CONTROL	= 0x76,
757979b1cfSJérôme Duval 	AC97_AD_SAMPLE_RATE_0	= 0x78,
767979b1cfSJérôme Duval 	AC97_AD_SAMPLE_RATE_1	= 0x7a,
777979b1cfSJérôme Duval 
787979b1cfSJérôme Duval 	/* Realtek ALC650 */
797979b1cfSJérôme Duval 	AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_LO = 0x60, /* only ALC650 Rev. E and later */
807979b1cfSJérôme Duval 	AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_HI = 0x62, /* only ALC650 Rev. E and later */
817979b1cfSJérôme Duval 	AC97_ALC650_SURR_VOLUME		= 0x64,
827979b1cfSJérôme Duval 	AC97_ALC650_CEN_LFE_VOLUME	= 0x66,
837979b1cfSJérôme Duval 	AC97_ALC650_MULTI_CHAN_CTRL	= 0x6A,
847979b1cfSJérôme Duval 	AC97_ALC650_MISC_CONTROL	= 0x74,
857979b1cfSJérôme Duval 	AC97_ALC650_GPIO_SETUP		= 0x76,
867979b1cfSJérôme Duval 	AC97_ALC650_GPIO_STATUS		= 0x78,
877979b1cfSJérôme Duval 	AC97_ALC650_CLOCK_SOURCE	= 0x7A
887979b1cfSJérôme Duval };
897979b1cfSJérôme Duval 
907979b1cfSJérôme Duval // AC97_EXTENDED_ID bits
917979b1cfSJérôme Duval enum {
927979b1cfSJérôme Duval 	EXID_VRA 	= 0x0001,
937979b1cfSJérôme Duval 	EXID_DRA 	= 0x0002,
947979b1cfSJérôme Duval 	EXID_SPDIF 	= 0x0004,
957979b1cfSJérôme Duval 	EXID_VRM 	= 0x0008,
967979b1cfSJérôme Duval 	EXID_DSA0 	= 0x0010,
977979b1cfSJérôme Duval 	EXID_DSA1 	= 0x0020,
987979b1cfSJérôme Duval 	EXID_CDAC 	= 0x0040,
997979b1cfSJérôme Duval 	EXID_SDAC 	= 0x0080,
1007979b1cfSJérôme Duval 	EXID_LDAC 	= 0x0100,
1017979b1cfSJérôme Duval 	EXID_AMAP 	= 0x0200,
1027979b1cfSJérôme Duval 	EXID_REV0 	= 0x0400,
1037979b1cfSJérôme Duval 	EXID_REV1 	= 0x0800,
1047979b1cfSJérôme Duval 	EXID_bit12 	= 0x1000,
1057979b1cfSJérôme Duval 	EXID_bit13 	= 0x2000,
1067979b1cfSJérôme Duval 	EXID_ID0 	= 0x4000,
1077979b1cfSJérôme Duval 	EXID_ID1 	= 0x8000
1087979b1cfSJérôme Duval };
1097979b1cfSJérôme Duval 
1107979b1cfSJérôme Duval // some codec_ids
1117979b1cfSJérôme Duval enum {
1127979b1cfSJérôme Duval 	CODEC_ID_ALC201A	= 0x414c4710,
1137979b1cfSJérôme Duval 	CODEC_ID_AK4540		= 0x414b4d00,
1147979b1cfSJérôme Duval 	CODEC_ID_AK4542		= 0x414b4d01,
1157979b1cfSJérôme Duval 	CODEC_ID_AK4543		= 0x414b4d02,
1167979b1cfSJérôme Duval 	CODEC_ID_AD1819 	= 0x41445303, // ok, AD1819A, AD1819B
1177979b1cfSJérôme Duval 	CODEC_ID_AD1881		= 0x41445340, // ok, AD1881
1187979b1cfSJérôme Duval 	CODEC_ID_AD1881A	= 0x41445348, // ok, AD1881A
1197979b1cfSJérôme Duval 	CODEC_ID_AD1885		= 0x41445360, // ok, AD1885
1207979b1cfSJérôme Duval 	CODEC_ID_AD1886		= 0x41445361, // ok, AD1886
1217979b1cfSJérôme Duval 	CODEC_ID_AD1886A 	= 0x41445363, // ok, AD1886A
1227979b1cfSJérôme Duval 	CODEC_ID_AD1887		= 0x41445362, // ok, AD1887
1237979b1cfSJérôme Duval 	CODEC_ID_AD1888		= 0x41445368, // ok, AD1888
1247979b1cfSJérôme Duval 	CODEC_ID_AD1980		= 0x41445370, // ok, AD1980
1257979b1cfSJérôme Duval 	CODEC_ID_AD1981B	= 0x41445374, // ok, AD1981B
1267979b1cfSJérôme Duval 	CODEC_ID_AD1985		= 0x41445375, // ok, AD1985
1277979b1cfSJérôme Duval 	CODEC_ID_AD1986		= 0x41445378, // ok, AD1986
1287979b1cfSJérôme Duval 	CODEC_ID_CS4299A	= 0x43525931,
1297979b1cfSJérôme Duval 	CODEC_ID_CS4299C	= 0x43525933,
1307979b1cfSJérôme Duval 	CODEC_ID_CS4299D	= 0x43525934,
1317979b1cfSJérôme Duval 	CODEC_ID_STAC9700	= 0x83847600, // ok, STAC9700
1327979b1cfSJérôme Duval 	CODEC_ID_STAC9704	= 0x83847604, // STAC9701/03, STAC9704/07, STAC9705 (???)
1337979b1cfSJérôme Duval 	CODEC_ID_STAC9705	= 0x83847605, // ???
1347979b1cfSJérôme Duval 	CODEC_ID_STAC9708	= 0x83847608, // ok, STAC9708/11
1357979b1cfSJérôme Duval 	CODEC_ID_STAC9721	= 0x83847609, // ok, STAC9721/23
1367979b1cfSJérôme Duval 	CODEC_ID_STAC9744	= 0x83847644, // ok, STAC9744
137*fe2d4a0fSJérôme Duval 	CODEC_ID_STAC9750	= 0x83847650, // ok, STAC9750/51
1387979b1cfSJérôme Duval 	CODEC_ID_STAC9752	= 0x83847652, // ok, STAC9752/53
1397979b1cfSJérôme Duval 	CODEC_ID_STAC9756	= 0x83847656, // ok, STAC9756/57
140*fe2d4a0fSJérôme Duval 	CODEC_ID_STAC9758	= 0x83847658, // ????, STAC9758/59
1417979b1cfSJérôme Duval 	CODEC_ID_STAC9766	= 0x83847666, // ok, STAC9766/67
1427979b1cfSJérôme Duval };
1437979b1cfSJérôme Duval 
1447979b1cfSJérôme Duval // capabilities
1457979b1cfSJérôme Duval enum ac97_capability {
1467979b1cfSJérôme Duval 	CAP_PCM_MIC				= 0x0000000000000001ULL, /* dedicated mic PCM channel */
1477979b1cfSJérôme Duval 	CAP_BASS_TREBLE_CTRL	= 0x0000000000000002ULL,
1487979b1cfSJérôme Duval 	CAP_SIMULATED_STEREO	= 0x0000000000000004ULL,
1497979b1cfSJérôme Duval 	CAP_HEADPHONE_OUT		= 0x0000000000000008ULL,
1507979b1cfSJérôme Duval 	CAP_LAUDNESS			= 0x0000000000000010ULL,
1517979b1cfSJérôme Duval 	CAP_DAC_18BIT			= 0x0000000000000020ULL,
1527979b1cfSJérôme Duval 	CAP_DAC_20BIT			= 0x0000000000000040ULL,
1537979b1cfSJérôme Duval 	CAP_ADC_18BIT			= 0x0000000000000080ULL,
1547979b1cfSJérôme Duval 	CAP_ADC_20BIT			= 0x0000000000000100ULL,
1557979b1cfSJérôme Duval 	CAP_3D_ENHANCEMENT		= 0x0000000000000200ULL,
1567979b1cfSJérôme Duval 	CAP_VARIABLE_PCM		= 0x0000000000000400ULL, /* variable rate PCM */
1577979b1cfSJérôme Duval 	CAP_DOUBLE_PCM			= 0x0000000000000800ULL, /* double rate PCM */
1587979b1cfSJérôme Duval 	CAP_SPDIF				= 0x0000000000001000ULL,
1597979b1cfSJérôme Duval 	CAP_VARIABLE_MIC		= 0x0000000000002000ULL, /* variable rate mic PCM */
1607979b1cfSJérôme Duval 	CAP_CENTER_DAC			= 0x0000000000004000ULL,
1617979b1cfSJérôme Duval 	CAP_SURR_DAC			= 0x0000000000008000ULL,
1627979b1cfSJérôme Duval 	CAP_LFE_DAC				= 0x0000000000010000ULL,
1637979b1cfSJérôme Duval 	CAP_AMAP				= 0x0000000000020000ULL,
1647979b1cfSJérôme Duval 	CAP_REV21				= 0x0000000000040000ULL,
1657979b1cfSJérôme Duval 	CAP_REV22				= 0x0000000000080000ULL,
1667979b1cfSJérôme Duval 	CAP_REV23				= 0x0000000000100000ULL,
1677979b1cfSJérôme Duval 	CAP_PCM_RATE_CONTINUOUS	= 0x0000000000200000ULL,
1687979b1cfSJérôme Duval 	CAP_PCM_RATE_8000		= 0x0000000000400000ULL,
1697979b1cfSJérôme Duval 	CAP_PCM_RATE_11025		= 0x0000000000800000ULL,
1707979b1cfSJérôme Duval 	CAP_PCM_RATE_12000		= 0x0000000001000000ULL,
1717979b1cfSJérôme Duval 	CAP_PCM_RATE_16000		= 0x0000000002000000ULL,
1727979b1cfSJérôme Duval 	CAP_PCM_RATE_22050		= 0x0000000004000000ULL,
1737979b1cfSJérôme Duval 	CAP_PCM_RATE_24000		= 0x0000000008000000ULL,
1747979b1cfSJérôme Duval 	CAP_PCM_RATE_32000		= 0x0000000010000000ULL,
1757979b1cfSJérôme Duval 	CAP_PCM_RATE_44100		= 0x0000000020000000ULL,
1767979b1cfSJérôme Duval 	CAP_PCM_RATE_48000		= 0x0000000040000000ULL,
1777979b1cfSJérôme Duval 	CAP_PCM_RATE_88200		= 0x0000000080000000ULL,
1787979b1cfSJérôme Duval 	CAP_PCM_RATE_96000		= 0x0000000100000000ULL,
1797979b1cfSJérôme Duval 	CAP_PCM_RATE_MASK		= ( CAP_PCM_RATE_CONTINUOUS | CAP_PCM_RATE_8000 | CAP_PCM_RATE_11025 |
1807979b1cfSJérôme Duval 								CAP_PCM_RATE_12000 | CAP_PCM_RATE_16000 | CAP_PCM_RATE_22050 |
1817979b1cfSJérôme Duval 								CAP_PCM_RATE_24000 | CAP_PCM_RATE_32000 | CAP_PCM_RATE_44100 |
1827979b1cfSJérôme Duval 								CAP_PCM_RATE_48000 | CAP_PCM_RATE_88200 | CAP_PCM_RATE_96000)
1837979b1cfSJérôme Duval };
1847979b1cfSJérôme Duval 
1857979b1cfSJérôme Duval struct ac97_dev;
1867979b1cfSJérôme Duval typedef struct ac97_dev ac97_dev;
1877979b1cfSJérôme Duval 
1887979b1cfSJérôme Duval typedef void	(* codec_init)(ac97_dev * dev);
1897979b1cfSJérôme Duval typedef	uint16	(* codec_reg_read)(void * cookie, uint8 reg);
1907979b1cfSJérôme Duval typedef	void	(* codec_reg_write)(void * cookie, uint8 reg, uint16 value);
1917979b1cfSJérôme Duval typedef bool	(* codec_set_rate)(ac97_dev *dev, uint8 reg, uint32 rate);
1927979b1cfSJérôme Duval typedef bool	(* codec_get_rate)(ac97_dev *dev, uint8 reg, uint32 *rate);
1937979b1cfSJérôme Duval 
1947979b1cfSJérôme Duval struct ac97_dev {
1957979b1cfSJérôme Duval 	uint16				reg_cache[0x7f];
1967979b1cfSJérôme Duval 
1977979b1cfSJérôme Duval 	void *				cookie;
1987979b1cfSJérôme Duval 
1997979b1cfSJérôme Duval 	uint32				codec_id;
2007979b1cfSJérôme Duval 	const char *		codec_info;
2017979b1cfSJérôme Duval 	const char *		codec_3d_stereo_enhancement;
2027979b1cfSJérôme Duval 
2037979b1cfSJérôme Duval 	codec_init			init;
2047979b1cfSJérôme Duval 	codec_reg_read		reg_read;
2057979b1cfSJérôme Duval 	codec_reg_write		reg_write;
2067979b1cfSJérôme Duval 	codec_set_rate		set_rate;
2077979b1cfSJérôme Duval 	codec_get_rate		get_rate;
2087979b1cfSJérôme Duval 
2097979b1cfSJérôme Duval 	uint32				max_vsr;
2107979b1cfSJérôme Duval 	uint32				min_vsr;
2117979b1cfSJérôme Duval 	uint32 				clock;
2127979b1cfSJérôme Duval 	uint64				capabilities;
2137979b1cfSJérôme Duval 	bool				reversed_eamp_polarity;
2147979b1cfSJérôme Duval 	uint32				subsystem;
2157979b1cfSJérôme Duval };
2167979b1cfSJérôme Duval 
2177979b1cfSJérôme Duval #ifdef __cplusplus
2187979b1cfSJérôme Duval extern "C" {
2197979b1cfSJérôme Duval #endif
2207979b1cfSJérôme Duval 
221*fe2d4a0fSJérôme Duval void	ac97_attach(ac97_dev **dev, codec_reg_read reg_read,
222*fe2d4a0fSJérôme Duval 	codec_reg_write reg_write, void *cookie, ushort subvendor_id,
223*fe2d4a0fSJérôme Duval 	ushort subsystem_id);
2247979b1cfSJérôme Duval void	ac97_detach(ac97_dev *dev);
2257979b1cfSJérôme Duval void	ac97_suspend(ac97_dev *dev);
2267979b1cfSJérôme Duval void	ac97_resume(ac97_dev *dev);
2277979b1cfSJérôme Duval 
2287979b1cfSJérôme Duval void	ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value);
2297979b1cfSJérôme Duval uint16	ac97_reg_cached_read(ac97_dev *dev, uint8 reg);
2307979b1cfSJérôme Duval void	ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value);
2317979b1cfSJérôme Duval uint16	ac97_reg_uncached_read(ac97_dev *dev, uint8 reg);
2327979b1cfSJérôme Duval 
2337979b1cfSJérôme Duval bool	ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value);
234*fe2d4a0fSJérôme Duval bool	ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask,
235*fe2d4a0fSJérôme Duval 	uint16 value);
2367979b1cfSJérôme Duval 
2377979b1cfSJérôme Duval bool	ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
2387979b1cfSJérôme Duval bool	ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
2397979b1cfSJérôme Duval 
2407979b1cfSJérôme Duval bool	ac97_has_capability(ac97_dev *dev, uint64 cap);
2417979b1cfSJérôme Duval 
2427979b1cfSJérôme Duval void	ac97_set_clock(ac97_dev *dev, uint32 clock);
2437979b1cfSJérôme Duval 
2447979b1cfSJérôme Duval #ifdef __cplusplus
2457979b1cfSJérôme Duval }
2467979b1cfSJérôme Duval #endif
2477979b1cfSJérôme Duval 
2487979b1cfSJérôme Duval // multi support
2497979b1cfSJérôme Duval 
2507979b1cfSJérôme Duval typedef enum {
2517979b1cfSJérôme Duval 	B_MIX_GAIN = 1 << 0,
2527979b1cfSJérôme Duval 	B_MIX_MUTE = 1 << 1,
2537979b1cfSJérôme Duval 	B_MIX_MONO = 1 << 2,
2547979b1cfSJérôme Duval 	B_MIX_STEREO = 1 << 3,
2557979b1cfSJérôme Duval 	B_MIX_MUX = 1 << 4,
2567979b1cfSJérôme Duval 	B_MIX_MICBOOST = 1 << 5,
2577979b1cfSJérôme Duval 	B_MIX_RECORDMUX = 1 << 6
2587979b1cfSJérôme Duval } ac97_mixer_type;
2597979b1cfSJérôme Duval 
2607979b1cfSJérôme Duval typedef struct _ac97_source_info {
2617979b1cfSJérôme Duval 	const char *name;
2627979b1cfSJérôme Duval 	ac97_mixer_type  type;
2637979b1cfSJérôme Duval 
2647979b1cfSJérôme Duval 	int32	id;
2657979b1cfSJérôme Duval 	uint8	reg;
2667979b1cfSJérôme Duval 	uint16	default_value;
2677979b1cfSJérôme Duval 	uint8 	bits:3;
2687979b1cfSJérôme Duval 	uint8	ofs:4;
2697979b1cfSJérôme Duval 	uint8	mute:1;
2707979b1cfSJérôme Duval 	uint8	polarity:1; // max_gain -> 0
2717979b1cfSJérôme Duval 	float	min_gain;
2727979b1cfSJérôme Duval 	float	max_gain;
2737979b1cfSJérôme Duval 	float	granularity;
2747979b1cfSJérôme Duval } ac97_source_info;
2757979b1cfSJérôme Duval 
2767979b1cfSJérôme Duval extern const ac97_source_info source_info[];
2777979b1cfSJérôme Duval extern const int32 source_info_size;
2787979b1cfSJérôme Duval 
2797979b1cfSJérôme Duval #endif
280