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 | |