^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Jack-detection handling for HD-audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef __SOUND_HDA_JACK_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define __SOUND_HDA_JACK_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/jack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct auto_pin_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct hda_jack_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct hda_jack_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct hda_jack_callback {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) hda_jack_callback_fn func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned int private_data; /* arbitrary data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned int unsol_res; /* unsolicited event bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct hda_jack_tbl *jack; /* associated jack entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct hda_jack_callback *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct hda_jack_tbl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned char tag; /* unsol event tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct hda_jack_callback *callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* jack-detection stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned int pin_sense; /* cached pin-sense value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int jack_detect:1; /* capable of jack-detection? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int jack_dirty:1; /* needs to update? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned int phantom_jack:1; /* a fixed, always present port? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned int block_report:1; /* in a transitional state - do not report to userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) hda_nid_t gating_jack; /* valid when gating jack plugged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) hda_nid_t gated_jack; /* gated is dependent on this jack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int button_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct snd_jack *jack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct hda_jack_keymap {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) enum snd_jack_types type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) snd_hda_jack_tbl_get_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @nid: pin NID to refer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static inline struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return snd_hda_jack_tbl_get_mst(codec, nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct hda_jack_tbl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned char tag, int dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void snd_hda_jack_tbl_clear(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct hda_jack_callback *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int dev_id, hda_jack_callback_fn func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * snd_hda_jack_detect_enable - enable the jack-detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @nid: pin NID to enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @func: callback function to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * In the case of error, the return value will be a pointer embedded with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * errno. Check and handle the return value appropriately with standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * macros such as @IS_ERR() and @PTR_ERR().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline struct hda_jack_callback *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) hda_jack_callback_fn cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return snd_hda_jack_detect_enable_callback_mst(codec, nid, 0, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hda_nid_t gating_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* the jack state returned from snd_hda_jack_detect_state() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int snd_hda_jack_detect_state_mst(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * snd_hda_jack_detect_state - query pin Presence Detect status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @codec: the CODEC to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @nid: the pin NID to sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Query and return the pin's Presence Detect status, as either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return snd_hda_jack_detect_state_mst(codec, nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * snd_hda_jack_detect_mst - Detect the jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @nid: pin NID to check jack detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @dev_id: pin device entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) snd_hda_jack_detect_mst(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return snd_hda_jack_detect_state_mst(codec, nid, dev_id) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) HDA_JACK_NOT_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * snd_hda_jack_detect - Detect the jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @nid: pin NID to check jack detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return snd_hda_jack_detect_mst(codec, nid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int snd_hda_jack_add_kctl_mst(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int dev_id, const char *name, bool phantom_jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int type, const struct hda_jack_keymap *keymap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * snd_hda_jack_add_kctl - Add a kctl for the given pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @nid: pin NID to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @name: string name for the jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @phantom_jack: flag to deal as a phantom jack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @type: jack type bits to be reported, 0 for guessing from pincfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @keymap: optional jack / key mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * This assigns a jack-detection kctl to the given pin. The kcontrol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * will have the given name and index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const char *name, bool phantom_jack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int type, const struct hda_jack_keymap *keymap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return snd_hda_jack_add_kctl_mst(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) name, phantom_jack, type, keymap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int snd_hda_jack_add_kctls(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const struct auto_pin_cfg *cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) void snd_hda_jack_report_sync(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void snd_hda_jack_poll_all(struct hda_codec *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #endif /* __SOUND_HDA_JACK_H */