// SPDX-License-Identifier: GPL-2.0-or-later // // Realtek HD-audio codec support code // #ifndef __HDA_REALTEK_H #define __HDA_REALTEK_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_beep.h" #include "hda_jack.h" #include "../generic.h" #include "../side-codecs/hda_component.h" /* extra amp-initialization sequence types */ enum { ALC_INIT_UNDEFINED, ALC_INIT_NONE, ALC_INIT_DEFAULT, }; enum { ALC_HEADSET_MODE_UNKNOWN, ALC_HEADSET_MODE_UNPLUGGED, ALC_HEADSET_MODE_HEADSET, ALC_HEADSET_MODE_MIC, ALC_HEADSET_MODE_HEADPHONE, }; enum { ALC_HEADSET_TYPE_UNKNOWN, ALC_HEADSET_TYPE_CTIA, ALC_HEADSET_TYPE_OMTP, }; enum { ALC_KEY_MICMUTE_INDEX, }; struct alc_customize_define { unsigned int sku_cfg; unsigned char port_connectivity; unsigned char check_sum; unsigned char customization; unsigned char external_amp; unsigned int enable_pcbeep:1; unsigned int platform_type:1; unsigned int swap:1; unsigned int override:1; unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ }; struct alc_coef_led { unsigned int idx; unsigned int mask; unsigned int on; unsigned int off; }; struct alc_spec { struct hda_gen_spec gen; /* must be at head */ /* codec parameterization */ struct alc_customize_define cdefine; unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ /* GPIO bits */ unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; bool gpio_write_delay; /* add a delay before writing gpio_data */ /* mute LED for HP laptops, see vref_mute_led_set() */ int mute_led_polarity; int micmute_led_polarity; hda_nid_t mute_led_nid; hda_nid_t cap_mute_led_nid; unsigned int gpio_mute_led_mask; unsigned int gpio_mic_led_mask; struct alc_coef_led mute_led_coef; struct alc_coef_led mic_led_coef; struct mutex coef_mutex; hda_nid_t headset_mic_pin; hda_nid_t headphone_mic_pin; int current_headset_mode; int current_headset_type; /* hooks */ void (*init_hook)(struct hda_codec *codec); void (*power_hook)(struct hda_codec *codec); void (*shutup)(struct hda_codec *codec); int init_amp; int codec_variant; /* flag for other variants */ unsigned int has_alc5505_dsp:1; unsigned int no_depop_delay:1; unsigned int done_hp_init:1; unsigned int no_shutup_pins:1; unsigned int ultra_low_power:1; unsigned int has_hs_key:1; unsigned int no_internal_mic_pin:1; unsigned int en_3kpull_low:1; int num_speaker_amps; /* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; unsigned int coef0; struct input_dev *kb_dev; u8 alc_mute_keycode_map[1]; /* component binding */ struct hda_component_parent comps; }; int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, unsigned int coef_idx); void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, unsigned int coef_idx, unsigned int coef_val); void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, unsigned int coef_idx, unsigned int mask, unsigned int bits_set); #define alc_read_coef_idx(codec, coef_idx) \ alc_read_coefex_idx(codec, 0x20, coef_idx) #define alc_write_coef_idx(codec, coef_idx, coef_val) \ alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) #define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \ alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set) unsigned int alc_get_coef0(struct hda_codec *codec); /* coef writes/updates batch */ struct coef_fw { unsigned char nid; unsigned char idx; unsigned short mask; unsigned short val; }; #define UPDATE_COEFEX(_nid, _idx, _mask, _val) \ { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) } #define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val) #define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val) #define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val) void alc_process_coef_fw(struct hda_codec *codec, const struct coef_fw *fw); /* * GPIO helpers */ void alc_setup_gpio(struct hda_codec *codec, unsigned int mask); void alc_write_gpio_data(struct hda_codec *codec); void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask, bool on); void alc_write_gpio(struct hda_codec *codec); /* common GPIO fixups */ void alc_fixup_gpio(struct hda_codec *codec, int action, unsigned int mask); void alc_fixup_gpio1(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_gpio2(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_gpio3(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_gpio4(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_micmute_led(struct hda_codec *codec, const struct hda_fixup *fix, int action); /* * Common init code, callbacks and helpers */ void alc_fix_pll(struct hda_codec *codec); void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, unsigned int coef_idx, unsigned int coef_bit); void alc_fill_eapd_coef(struct hda_codec *codec); void alc_auto_setup_eapd(struct hda_codec *codec, bool on); int alc_find_ext_mic_pin(struct hda_codec *codec); void alc_headset_mic_no_shutup(struct hda_codec *codec); void alc_shutup_pins(struct hda_codec *codec); void alc_eapd_shutup(struct hda_codec *codec); void alc_auto_init_amp(struct hda_codec *codec, int type); hda_nid_t alc_get_hp_pin(struct alc_spec *spec); int alc_auto_parse_customize_define(struct hda_codec *codec); int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports); void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports); int alc_build_controls(struct hda_codec *codec); void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_callback *jack); static inline void alc_pre_init(struct hda_codec *codec) { alc_fill_eapd_coef(codec); } #define is_s3_resume(codec) \ ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME) #define is_s4_resume(codec) \ ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE) #define is_s4_suspend(codec) \ ((codec)->core.dev.power.power_state.event == PM_EVENT_FREEZE) int alc_init(struct hda_codec *codec); void alc_shutup(struct hda_codec *codec); void alc_power_eapd(struct hda_codec *codec); int alc_suspend(struct hda_codec *codec); int alc_resume(struct hda_codec *codec); int alc_parse_auto_config(struct hda_codec *codec, const hda_nid_t *ignore_nids, const hda_nid_t *ssid_nids); int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid); #define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name) #ifdef CONFIG_SND_HDA_INPUT_BEEP int alc_set_beep_amp(struct alc_spec *spec, hda_nid_t nid, int idx, int dir); int alc_has_cdefine_beep(struct hda_codec *codec); #define set_beep_amp alc_set_beep_amp #define has_cdefine_beep alc_has_cdefine_beep #else #define set_beep_amp(spec, nid, idx, dir) 0 #define has_cdefine_beep(codec) 0 #endif static inline void rename_ctl(struct hda_codec *codec, const char *oldname, const char *newname) { struct snd_kcontrol *kctl; kctl = snd_hda_find_mixer_ctl(codec, oldname); if (kctl) snd_ctl_rename(codec->card, kctl, newname); } /* Common fixups */ void alc_fixup_sku_ignore(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_no_depop_delay(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_inv_dmic(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_dual_codecs(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_bass_chmap(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_headset_mode(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_headset_mic(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_callback *jack); void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, int polarity, bool enabled); void alc_fixup_hp_gpio_led(struct hda_codec *codec, int action, unsigned int mute_mask, unsigned int micmute_mask); void alc_fixup_no_jack_detect(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_disable_aamix(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, const struct hda_fixup *fix, int action); /* device-specific, but used by multiple codec drivers */ void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec, const struct hda_fixup *fix, int action); void alc_fixup_dell_xps13(struct hda_codec *codec, const struct hda_fixup *fix, int action); #endif /* __HDA_REALTEK_H */