OSDN Git Service

ALSA: hda - Give more unique names by snd_hda_get_pin_label()
[uclinux-h8/linux.git] / sound / pci / hda / hda_jack.c
1 /*
2  * Jack-detection handling for HD-audio
3  *
4  * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5  *
6  * This driver is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/export.h>
15 #include <sound/core.h>
16 #include <sound/control.h>
17 #include <sound/jack.h>
18 #include "hda_codec.h"
19 #include "hda_local.h"
20 #include "hda_jack.h"
21
22 /* execute pin sense measurement */
23 static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
24 {
25         u32 pincap;
26
27         if (!codec->no_trigger_sense) {
28                 pincap = snd_hda_query_pin_caps(codec, nid);
29                 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
30                         snd_hda_codec_read(codec, nid, 0,
31                                         AC_VERB_SET_PIN_SENSE, 0);
32         }
33         return snd_hda_codec_read(codec, nid, 0,
34                                   AC_VERB_GET_PIN_SENSE, 0);
35 }
36
37 /**
38  * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
39  */
40 struct hda_jack_tbl *
41 snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
42 {
43         struct hda_jack_tbl *jack = codec->jacktbl.list;
44         int i;
45
46         if (!nid || !jack)
47                 return NULL;
48         for (i = 0; i < codec->jacktbl.used; i++, jack++)
49                 if (jack->nid == nid)
50                         return jack;
51         return NULL;
52 }
53 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
54
55 /**
56  * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
57  */
58 struct hda_jack_tbl *
59 snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
60 {
61         struct hda_jack_tbl *jack = codec->jacktbl.list;
62         int i;
63
64         if (!tag || !jack)
65                 return NULL;
66         for (i = 0; i < codec->jacktbl.used; i++, jack++)
67                 if (jack->tag == tag)
68                         return jack;
69         return NULL;
70 }
71 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
72
73 /**
74  * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
75  */
76 struct hda_jack_tbl *
77 snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
78 {
79         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
80         if (jack)
81                 return jack;
82         snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
83         jack = snd_array_new(&codec->jacktbl);
84         if (!jack)
85                 return NULL;
86         jack->nid = nid;
87         jack->jack_dirty = 1;
88         jack->tag = codec->jacktbl.used;
89         return jack;
90 }
91 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new);
92
93 #ifdef CONFIG_SND_HDA_INPUT_JACK
94 static void snd_hda_input_jack_free(struct hda_codec *codec);
95 #else
96 #define snd_hda_input_jack_free(codec)
97 #endif
98
99 void snd_hda_jack_tbl_clear(struct hda_codec *codec)
100 {
101         snd_hda_input_jack_free(codec);
102         snd_array_free(&codec->jacktbl);
103 }
104
105 /* update the cached value and notification flag if needed */
106 static void jack_detect_update(struct hda_codec *codec,
107                                struct hda_jack_tbl *jack)
108 {
109         if (jack->jack_dirty || !jack->jack_detect) {
110                 jack->pin_sense = read_pin_sense(codec, jack->nid);
111                 jack->jack_dirty = 0;
112         }
113 }
114
115 /**
116  * snd_hda_set_dirty_all - Mark all the cached as dirty
117  *
118  * This function sets the dirty flag to all entries of jack table.
119  * It's called from the resume path in hda_codec.c.
120  */
121 void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
122 {
123         struct hda_jack_tbl *jack = codec->jacktbl.list;
124         int i;
125
126         for (i = 0; i < codec->jacktbl.used; i++, jack++)
127                 if (jack->nid)
128                         jack->jack_dirty = 1;
129 }
130 EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
131
132 /**
133  * snd_hda_pin_sense - execute pin sense measurement
134  * @codec: the CODEC to sense
135  * @nid: the pin NID to sense
136  *
137  * Execute necessary pin sense measurement and return its Presence Detect,
138  * Impedance, ELD Valid etc. status bits.
139  */
140 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
141 {
142         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
143         if (jack) {
144                 jack_detect_update(codec, jack);
145                 return jack->pin_sense;
146         }
147         return read_pin_sense(codec, nid);
148 }
149 EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
150
151 #define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
152
153 /**
154  * snd_hda_jack_detect - query pin Presence Detect status
155  * @codec: the CODEC to sense
156  * @nid: the pin NID to sense
157  *
158  * Query and return the pin's Presence Detect status.
159  */
160 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
161 {
162         u32 sense = snd_hda_pin_sense(codec, nid);
163         return get_jack_plug_state(sense);
164 }
165 EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
166
167 /**
168  * snd_hda_jack_detect_enable - enable the jack-detection
169  */
170 int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
171                                unsigned char action)
172 {
173         struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
174         if (!jack)
175                 return -ENOMEM;
176         if (jack->jack_detect)
177                 return 0; /* already registered */
178         jack->jack_detect = 1;
179         if (action)
180                 jack->action = action;
181         return snd_hda_codec_write_cache(codec, nid, 0,
182                                          AC_VERB_SET_UNSOLICITED_ENABLE,
183                                          AC_USRSP_EN | jack->tag);
184 }
185 EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
186
187 /**
188  * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
189  */
190 void snd_hda_jack_report_sync(struct hda_codec *codec)
191 {
192         struct hda_jack_tbl *jack = codec->jacktbl.list;
193         int i, state;
194
195         for (i = 0; i < codec->jacktbl.used; i++, jack++)
196                 if (jack->nid) {
197                         jack_detect_update(codec, jack);
198                         if (!jack->kctl)
199                                 continue;
200                         state = get_jack_plug_state(jack->pin_sense);
201                         snd_kctl_jack_report(codec->bus->card, jack->kctl, state);
202                 }
203 }
204 EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
205
206 /**
207  * snd_hda_jack_add_kctl - Add a kctl for the given pin
208  *
209  * This assigns a jack-detection kctl to the given pin.  The kcontrol
210  * will have the given name and index.
211  */
212 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
213                           const char *name, int idx)
214 {
215         struct hda_jack_tbl *jack;
216         struct snd_kcontrol *kctl;
217
218         jack = snd_hda_jack_tbl_new(codec, nid);
219         if (!jack)
220                 return 0;
221         if (jack->kctl)
222                 return 0; /* already created */
223         kctl = snd_kctl_jack_new(name, idx, codec);
224         if (!kctl)
225                 return -ENOMEM;
226         if (snd_hda_ctl_add(codec, nid, kctl) < 0)
227                 return -ENOMEM;
228         jack->kctl = kctl;
229         snd_kctl_jack_report(codec->bus->card, kctl,
230                              snd_hda_jack_detect(codec, nid));
231         return 0;
232 }
233 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
234
235 static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
236                          const struct auto_pin_cfg *cfg)
237 {
238         unsigned int def_conf, conn;
239         char name[44];
240         int idx, err;
241
242         if (!nid)
243                 return 0;
244         if (!is_jack_detectable(codec, nid))
245                 return 0;
246         def_conf = snd_hda_codec_get_pincfg(codec, nid);
247         conn = get_defcfg_connect(def_conf);
248         if (conn != AC_JACK_PORT_COMPLEX)
249                 return 0;
250
251         snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
252         err = snd_hda_jack_add_kctl(codec, nid, name, idx);
253         if (err < 0)
254                 return err;
255         return snd_hda_jack_detect_enable(codec, nid, 0);
256 }
257
258 /**
259  * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
260  */
261 int snd_hda_jack_add_kctls(struct hda_codec *codec,
262                            const struct auto_pin_cfg *cfg)
263 {
264         const hda_nid_t *p;
265         int i, err;
266
267         for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
268                 err = add_jack_kctl(codec, *p, cfg);
269                 if (err < 0)
270                         return err;
271         }
272         for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
273                 if (*p == *cfg->line_out_pins) /* might be duplicated */
274                         break;
275                 err = add_jack_kctl(codec, *p, cfg);
276                 if (err < 0)
277                         return err;
278         }
279         for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
280                 if (*p == *cfg->line_out_pins) /* might be duplicated */
281                         break;
282                 err = add_jack_kctl(codec, *p, cfg);
283                 if (err < 0)
284                         return err;
285         }
286         for (i = 0; i < cfg->num_inputs; i++) {
287                 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
288                 if (err < 0)
289                         return err;
290         }
291         for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
292                 err = add_jack_kctl(codec, *p, cfg);
293                 if (err < 0)
294                         return err;
295         }
296         err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
297         if (err < 0)
298                 return err;
299         err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
300         if (err < 0)
301                 return err;
302         return 0;
303 }
304 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
305
306 #ifdef CONFIG_SND_HDA_INPUT_JACK
307 /*
308  * Input-jack notification support
309  */
310 static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
311                                          int type)
312 {
313         switch (type) {
314         case SND_JACK_HEADPHONE:
315                 return "Headphone";
316         case SND_JACK_MICROPHONE:
317                 return "Mic";
318         case SND_JACK_LINEOUT:
319                 return "Line-out";
320         case SND_JACK_LINEIN:
321                 return "Line-in";
322         case SND_JACK_HEADSET:
323                 return "Headset";
324         case SND_JACK_VIDEOOUT:
325                 return "HDMI/DP";
326         default:
327                 return "Misc";
328         }
329 }
330
331 static void hda_free_jack_priv(struct snd_jack *jack)
332 {
333         struct hda_jack_tbl *jacks = jack->private_data;
334         jacks->nid = 0;
335         jacks->jack = NULL;
336 }
337
338 int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
339                            const char *name)
340 {
341         struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
342         int err;
343
344         if (!jack)
345                 return -ENOMEM;
346         if (!name)
347                 name = get_jack_default_name(codec, nid, type);
348         err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
349         if (err < 0)
350                 return err;
351         jack->type = type;
352         jack->jack->private_data = jack;
353         jack->jack->private_free = hda_free_jack_priv;
354         return 0;
355 }
356 EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
357
358 void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
359 {
360         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
361         unsigned int pin_ctl;
362         unsigned int present;
363         int type;
364
365         if (!jack || !jack->jack)
366                 return;
367
368         present = snd_hda_jack_detect(codec, nid);
369         type = jack->type;
370         if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
371                 pin_ctl = snd_hda_codec_read(codec, nid, 0,
372                                              AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
373                 type = (pin_ctl & AC_PINCTL_HP_EN) ?
374                         SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
375         }
376         snd_jack_report(jack->jack, present ? type : 0);
377 }
378 EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
379
380 /* free jack instances manually when clearing/reconfiguring */
381 static void snd_hda_input_jack_free(struct hda_codec *codec)
382 {
383         if (!codec->bus->shutdown && codec->jacktbl.list) {
384                 struct hda_jack_tbl *jack = codec->jacktbl.list;
385                 int i;
386                 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
387                         if (jack->jack)
388                                 snd_device_free(codec->bus->card, jack->jack);
389                 }
390         }
391 }
392 #endif /* CONFIG_SND_HDA_INPUT_JACK */