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