aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_jack.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-10-27 19:16:55 -0400
committerTakashi Iwai <tiwai@suse.de>2011-11-16 05:14:03 -0500
commit3a93897ea37cbb8277f8a4232c12c0c18168a7db (patch)
tree1c79df3bb270e86c61bdb13fab0bf66cbd3682ac /sound/pci/hda/hda_jack.c
parent01a61e12b4602c82bde9797d0e153f3e53c95b04 (diff)
ALSA: hda - Manage unsol tags in hda_jack.c
Manage the tags assigned for unsolicited events dynamically together with the jack-detection routines. Basically this is almost same as what we've done in patch_sigmatel.c. Assign the new tag number for each new unsol event, associate with the given NID and the action type, etc. With this change, now all pins looked over in snd_hda_jack_add_kctls() are actually enabled for detection now even if the pins aren't used for jack-retasking by the driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_jack.c')
-rw-r--r--sound/pci/hda/hda_jack.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index cee6a00bd85a..8829d5c83fec 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -51,6 +51,24 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
51EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); 51EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
52 52
53/** 53/**
54 * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
55 */
56struct hda_jack_tbl *
57snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
58{
59 struct hda_jack_tbl *jack = codec->jacktbl.list;
60 int i;
61
62 if (!tag || !jack)
63 return NULL;
64 for (i = 0; i < codec->jacktbl.used; i++, jack++)
65 if (jack->tag == tag)
66 return jack;
67 return NULL;
68}
69EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
70
71/**
54 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID 72 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
55 */ 73 */
56struct hda_jack_tbl * 74struct hda_jack_tbl *
@@ -65,6 +83,7 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
65 return NULL; 83 return NULL;
66 jack->nid = nid; 84 jack->nid = nid;
67 jack->jack_dirty = 1; 85 jack->jack_dirty = 1;
86 jack->tag = codec->jacktbl.used;
68 return jack; 87 return jack;
69} 88}
70 89
@@ -77,7 +96,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
77static void jack_detect_update(struct hda_codec *codec, 96static void jack_detect_update(struct hda_codec *codec,
78 struct hda_jack_tbl *jack) 97 struct hda_jack_tbl *jack)
79{ 98{
80 if (jack->jack_dirty || !jack->jack_cachable) { 99 if (jack->jack_dirty || !jack->jack_detect) {
81 unsigned int val = read_pin_sense(codec, jack->nid); 100 unsigned int val = read_pin_sense(codec, jack->nid);
82 jack->jack_dirty = 0; 101 jack->jack_dirty = 0;
83 if (val != jack->pin_sense) { 102 if (val != jack->pin_sense) {
@@ -141,17 +160,19 @@ EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
141 * snd_hda_jack_detect_enable - enable the jack-detection 160 * snd_hda_jack_detect_enable - enable the jack-detection
142 */ 161 */
143int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 162int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
144 unsigned int tag) 163 unsigned char action)
145{ 164{
146 struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 165 struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
147 if (!jack) 166 if (!jack)
148 return -ENOMEM; 167 return -ENOMEM;
149 if (jack->jack_cachable) 168 if (jack->jack_detect)
150 return 0; /* already registered */ 169 return 0; /* already registered */
151 jack->jack_cachable = 1; 170 jack->jack_detect = 1;
171 if (action)
172 jack->action = action;
152 return snd_hda_codec_write_cache(codec, nid, 0, 173 return snd_hda_codec_write_cache(codec, nid, 0,
153 AC_VERB_SET_UNSOLICITED_ENABLE, 174 AC_VERB_SET_UNSOLICITED_ENABLE,
154 AC_USRSP_EN | tag); 175 AC_USRSP_EN | jack->tag);
155} 176}
156EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); 177EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
157 178
@@ -168,18 +189,6 @@ static void jack_detect_report(struct hda_codec *codec,
168} 189}
169 190
170/** 191/**
171 * snd_hda_jack_report - notify kctl when the jack state was changed
172 */
173void snd_hda_jack_report(struct hda_codec *codec, hda_nid_t nid)
174{
175 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
176
177 if (jack)
178 jack_detect_report(codec, jack);
179}
180EXPORT_SYMBOL_HDA(snd_hda_jack_report);
181
182/**
183 * snd_hda_jack_report_sync - sync the states of all jacks and report if changed 192 * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
184 */ 193 */
185void snd_hda_jack_report_sync(struct hda_codec *codec) 194void snd_hda_jack_report_sync(struct hda_codec *codec)
@@ -231,7 +240,7 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
231 struct hda_jack_tbl *jack; 240 struct hda_jack_tbl *jack;
232 struct snd_kcontrol *kctl; 241 struct snd_kcontrol *kctl;
233 242
234 jack = snd_hda_jack_tbl_get(codec, nid); 243 jack = snd_hda_jack_tbl_new(codec, nid);
235 if (!jack) 244 if (!jack)
236 return 0; 245 return 0;
237 if (jack->kctl) 246 if (jack->kctl)
@@ -251,20 +260,28 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
251static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, 260static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx,
252 const struct auto_pin_cfg *cfg) 261 const struct auto_pin_cfg *cfg)
253{ 262{
263 unsigned int def_conf, conn;
264 int err;
265
254 if (!nid) 266 if (!nid)
255 return 0; 267 return 0;
256 if (!is_jack_detectable(codec, nid)) 268 if (!is_jack_detectable(codec, nid))
257 return 0; 269 return 0;
258 return snd_hda_jack_add_kctl(codec, nid, 270 def_conf = snd_hda_codec_get_pincfg(codec, nid);
271 conn = get_defcfg_connect(def_conf);
272 if (conn != AC_JACK_PORT_COMPLEX)
273 return 0;
274
275 err = snd_hda_jack_add_kctl(codec, nid,
259 snd_hda_get_pin_label(codec, nid, cfg), 276 snd_hda_get_pin_label(codec, nid, cfg),
260 idx); 277 idx);
278 if (err < 0)
279 return err;
280 return snd_hda_jack_detect_enable(codec, nid, 0);
261} 281}
262 282
263/** 283/**
264 * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg 284 * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
265 *
266 * As of now, it assigns only to the pins that enabled the detection.
267 * Usually this is called at the end of build_controls callback.
268 */ 285 */
269int snd_hda_jack_add_kctls(struct hda_codec *codec, 286int snd_hda_jack_add_kctls(struct hda_codec *codec,
270 const struct auto_pin_cfg *cfg) 287 const struct auto_pin_cfg *cfg)