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 *
snd_hda_jack_tbl_get(struct hda_codec * codec,hda_nid_t nid)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, 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 *
snd_hda_jack_detect_enable_callback(struct hda_codec * codec,hda_nid_t nid,hda_jack_callback_fn cb)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, 0, 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
snd_hda_jack_detect_state(struct hda_codec * codec,hda_nid_t nid)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, 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
snd_hda_jack_detect_mst(struct hda_codec * codec,hda_nid_t nid,int dev_id)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
snd_hda_jack_detect(struct hda_codec * codec,hda_nid_t nid)154  snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
155  {
156  	return snd_hda_jack_detect_mst(codec, nid, 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
snd_hda_jack_add_kctl(struct hda_codec * codec,hda_nid_t nid,const char * name,bool phantom_jack,int type,const struct hda_jack_keymap * keymap)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, 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