diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-10-27 19:16:55 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-11-16 05:14:03 -0500 |
commit | 3a93897ea37cbb8277f8a4232c12c0c18168a7db (patch) | |
tree | 1c79df3bb270e86c61bdb13fab0bf66cbd3682ac /sound/pci/hda/hda_jack.c | |
parent | 01a61e12b4602c82bde9797d0e153f3e53c95b04 (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.c | 61 |
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) | |||
51 | EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); | 51 | EXPORT_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 | */ | ||
56 | struct hda_jack_tbl * | ||
57 | snd_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 | } | ||
69 | EXPORT_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 | */ |
56 | struct hda_jack_tbl * | 74 | struct 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) | |||
77 | static void jack_detect_update(struct hda_codec *codec, | 96 | static 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 | */ |
143 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, | 162 | int 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 | } |
156 | EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); | 177 | EXPORT_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 | */ | ||
173 | void 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 | } | ||
180 | EXPORT_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 | */ |
185 | void snd_hda_jack_report_sync(struct hda_codec *codec) | 194 | void 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, | |||
251 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, | 260 | static 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 | */ |
269 | int snd_hda_jack_add_kctls(struct hda_codec *codec, | 286 | int snd_hda_jack_add_kctls(struct hda_codec *codec, |
270 | const struct auto_pin_cfg *cfg) | 287 | const struct auto_pin_cfg *cfg) |