xref: /linux/sound/pci/ac97/ac97_patch.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*1a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
3c1017a4cSJaroslav Kysela  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
41da177e4SLinus Torvalds  *  Universal interface for Audio Codec '97
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *  For more details look to AC '97 component specification revision 2.2
71da177e4SLinus Torvalds  *  by Intel Corporation (http://developer.intel.com).
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds 
10ac519028STakashi Iwai #define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
11ac519028STakashi Iwai 	((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
12ac519028STakashi Iwai 	 ((invert) << 24))
13ac519028STakashi Iwai #define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
14ac519028STakashi Iwai 	(AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
15ac519028STakashi Iwai #define AC97_SINGLE(xname, reg, shift, mask, invert) \
16ac519028STakashi Iwai { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
17ac519028STakashi Iwai   .info = snd_ac97_info_volsw,		\
18ac519028STakashi Iwai   .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
19ac519028STakashi Iwai   .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
20ac519028STakashi Iwai #define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
21ac519028STakashi Iwai { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
22ac519028STakashi Iwai   .info = snd_ac97_info_volsw,		\
23ac519028STakashi Iwai   .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
24ac519028STakashi Iwai   .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
25ac519028STakashi Iwai #define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
26ac519028STakashi Iwai { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
27ac519028STakashi Iwai   .info = snd_ac97_info_volsw,		\
28ac519028STakashi Iwai   .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
29ac519028STakashi Iwai   .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
30ac519028STakashi Iwai 
31ac519028STakashi Iwai /* enum control */
32ac519028STakashi Iwai struct ac97_enum {
33ac519028STakashi Iwai 	unsigned char reg;
34ac519028STakashi Iwai 	unsigned char shift_l;
35ac519028STakashi Iwai 	unsigned char shift_r;
36ac519028STakashi Iwai 	unsigned short mask;
371bc10bb6STakashi Iwai 	const char * const *texts;
38ac519028STakashi Iwai };
39ac519028STakashi Iwai 
40ac519028STakashi Iwai #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
41ac519028STakashi Iwai { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
42ac519028STakashi Iwai   .mask = xmask, .texts = xtexts }
43ac519028STakashi Iwai #define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
44ac519028STakashi Iwai 	AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
45ac519028STakashi Iwai #define AC97_ENUM(xname, xenum) \
46ac519028STakashi Iwai { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
47ac519028STakashi Iwai   .info = snd_ac97_info_enum_double,		    \
48ac519028STakashi Iwai   .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
49ac519028STakashi Iwai   .private_value = (unsigned long)&xenum }
50ac519028STakashi Iwai 
51ac519028STakashi Iwai /* ac97_codec.c */
52ac519028STakashi Iwai static const struct snd_kcontrol_new snd_ac97_controls_3d[];
53ac519028STakashi Iwai static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
54ac519028STakashi Iwai static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
55ac519028STakashi Iwai 					  struct snd_ac97 * ac97);
56ac519028STakashi Iwai static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
57ac519028STakashi Iwai 			       struct snd_ctl_elem_info *uinfo);
58ac519028STakashi Iwai static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
59ac519028STakashi Iwai 			      struct snd_ctl_elem_value *ucontrol);
60ac519028STakashi Iwai static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
61ac519028STakashi Iwai 			      struct snd_ctl_elem_value *ucontrol);
62ac519028STakashi Iwai static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
63ac519028STakashi Iwai static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
64ac519028STakashi Iwai 			       const char *suffix);
65ac519028STakashi Iwai static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
66ac519028STakashi Iwai 			       const char *dst, const char *suffix);
67ac519028STakashi Iwai static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
68ac519028STakashi Iwai 			     const char *s2, const char *suffix);
69ac519028STakashi Iwai static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
70ac519028STakashi Iwai 				    const char *dst);
7154720a24SKrzysztof Helt #ifdef CONFIG_PM
72ac519028STakashi Iwai static void snd_ac97_restore_status(struct snd_ac97 *ac97);
73ac519028STakashi Iwai static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
7454720a24SKrzysztof Helt #endif
75ac519028STakashi Iwai static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
76ac519028STakashi Iwai 				     struct snd_ctl_elem_info *uinfo);
77ac519028STakashi Iwai static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
78ac519028STakashi Iwai 				    struct snd_ctl_elem_value *ucontrol);
79ac519028STakashi Iwai static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
80ac519028STakashi Iwai 				    struct snd_ctl_elem_value *ucontrol);
81