18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
48c2ecf20Sopenharmony_ci *  Universal interface for Audio Codec '97
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  For more details look to AC '97 component specification revision 2.2
78c2ecf20Sopenharmony_ci *  by Intel Corporation (http://developer.intel.com).
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
118c2ecf20Sopenharmony_ci	((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
128c2ecf20Sopenharmony_ci	 ((invert) << 24))
138c2ecf20Sopenharmony_ci#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
148c2ecf20Sopenharmony_ci	(AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
158c2ecf20Sopenharmony_ci#define AC97_SINGLE(xname, reg, shift, mask, invert) \
168c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
178c2ecf20Sopenharmony_ci  .info = snd_ac97_info_volsw,		\
188c2ecf20Sopenharmony_ci  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
198c2ecf20Sopenharmony_ci  .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
208c2ecf20Sopenharmony_ci#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
218c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
228c2ecf20Sopenharmony_ci  .info = snd_ac97_info_volsw,		\
238c2ecf20Sopenharmony_ci  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
248c2ecf20Sopenharmony_ci  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
258c2ecf20Sopenharmony_ci#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
268c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
278c2ecf20Sopenharmony_ci  .info = snd_ac97_info_volsw,		\
288c2ecf20Sopenharmony_ci  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
298c2ecf20Sopenharmony_ci  .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* enum control */
328c2ecf20Sopenharmony_cistruct ac97_enum {
338c2ecf20Sopenharmony_ci	unsigned char reg;
348c2ecf20Sopenharmony_ci	unsigned char shift_l;
358c2ecf20Sopenharmony_ci	unsigned char shift_r;
368c2ecf20Sopenharmony_ci	unsigned short mask;
378c2ecf20Sopenharmony_ci	const char * const *texts;
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
418c2ecf20Sopenharmony_ci{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
428c2ecf20Sopenharmony_ci  .mask = xmask, .texts = xtexts }
438c2ecf20Sopenharmony_ci#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
448c2ecf20Sopenharmony_ci	AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
458c2ecf20Sopenharmony_ci#define AC97_ENUM(xname, xenum) \
468c2ecf20Sopenharmony_ci{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
478c2ecf20Sopenharmony_ci  .info = snd_ac97_info_enum_double,		    \
488c2ecf20Sopenharmony_ci  .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
498c2ecf20Sopenharmony_ci  .private_value = (unsigned long)&xenum }
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/* ac97_codec.c */
528c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new snd_ac97_controls_3d[];
538c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new snd_ac97_controls_spdif[];
548c2ecf20Sopenharmony_cistatic struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
558c2ecf20Sopenharmony_ci					  struct snd_ac97 * ac97);
568c2ecf20Sopenharmony_cistatic int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
578c2ecf20Sopenharmony_ci			       struct snd_ctl_elem_info *uinfo);
588c2ecf20Sopenharmony_cistatic int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
598c2ecf20Sopenharmony_ci			      struct snd_ctl_elem_value *ucontrol);
608c2ecf20Sopenharmony_cistatic int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
618c2ecf20Sopenharmony_ci			      struct snd_ctl_elem_value *ucontrol);
628c2ecf20Sopenharmony_cistatic int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
638c2ecf20Sopenharmony_cistatic int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
648c2ecf20Sopenharmony_ci			       const char *suffix);
658c2ecf20Sopenharmony_cistatic int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
668c2ecf20Sopenharmony_ci			       const char *dst, const char *suffix);
678c2ecf20Sopenharmony_cistatic int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
688c2ecf20Sopenharmony_ci			     const char *s2, const char *suffix);
698c2ecf20Sopenharmony_cistatic void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
708c2ecf20Sopenharmony_ci				    const char *dst);
718c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
728c2ecf20Sopenharmony_cistatic void snd_ac97_restore_status(struct snd_ac97 *ac97);
738c2ecf20Sopenharmony_cistatic void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
748c2ecf20Sopenharmony_ci#endif
758c2ecf20Sopenharmony_cistatic int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
768c2ecf20Sopenharmony_ci				     struct snd_ctl_elem_info *uinfo);
778c2ecf20Sopenharmony_cistatic int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
788c2ecf20Sopenharmony_ci				    struct snd_ctl_elem_value *ucontrol);
798c2ecf20Sopenharmony_cistatic int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
808c2ecf20Sopenharmony_ci				    struct snd_ctl_elem_value *ucontrol);
81