blob: 39edfcfd3abdf0b0613829977bb09e8ebf28ff92 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic widget tree parser
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This driver is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This driver is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/pci.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29#include "hda_local.h"
30
31/* widget node for parsing */
32struct hda_gnode {
33 hda_nid_t nid; /* NID of this widget */
34 unsigned short nconns; /* number of input connections */
Takashi Iwaid2569502005-11-21 16:33:51 +010035 hda_nid_t *conn_list;
36 hda_nid_t slist[2]; /* temporay list */
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 unsigned int wid_caps; /* widget capabilities */
38 unsigned char type; /* widget type */
39 unsigned char pin_ctl; /* pin controls */
40 unsigned char checked; /* the flag indicates that the node is already parsed */
41 unsigned int pin_caps; /* pin widget capabilities */
42 unsigned int def_cfg; /* default configuration */
43 unsigned int amp_out_caps; /* AMP out capabilities */
44 unsigned int amp_in_caps; /* AMP in capabilities */
45 struct list_head list;
46};
47
Takashi Iwaic3132922005-04-20 13:43:00 +020048/* patch-specific record */
Linus Torvalds1da177e2005-04-16 15:20:36 -070049struct hda_gspec {
50 struct hda_gnode *dac_node; /* DAC node */
51 struct hda_gnode *out_pin_node; /* Output pin (Line-Out) node */
52 struct hda_gnode *pcm_vol_node; /* Node for PCM volume */
53 unsigned int pcm_vol_index; /* connection of PCM volume */
54
55 struct hda_gnode *adc_node; /* ADC node */
56 struct hda_gnode *cap_vol_node; /* Node for capture volume */
57 unsigned int cur_cap_src; /* current capture source */
58 struct hda_input_mux input_mux;
59 char cap_labels[HDA_MAX_NUM_INPUTS][16];
60
61 unsigned int def_amp_in_caps;
62 unsigned int def_amp_out_caps;
63
64 struct hda_pcm pcm_rec; /* PCM information */
65
66 struct list_head nid_list; /* list of widgets */
67};
68
69/*
70 * retrieve the default device type from the default config value
71 */
Takashi Iwaie9edcee2005-06-13 14:16:38 +020072#define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
73#define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
75/*
76 * destructor
77 */
78static void snd_hda_generic_free(struct hda_codec *codec)
79{
80 struct hda_gspec *spec = codec->spec;
81 struct list_head *p, *n;
82
83 if (! spec)
84 return;
85 /* free all widgets */
86 list_for_each_safe(p, n, &spec->nid_list) {
87 struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
Takashi Iwaid2569502005-11-21 16:33:51 +010088 if (node->conn_list != node->slist)
89 kfree(node->conn_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 kfree(node);
91 }
92 kfree(spec);
93}
94
95
96/*
97 * add a new widget node and read its attributes
98 */
99static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid_t nid)
100{
101 struct hda_gnode *node;
102 int nconns;
Takashi Iwaid2569502005-11-21 16:33:51 +0100103 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Takashi Iwaie560d8d2005-09-09 14:21:46 +0200105 node = kzalloc(sizeof(*node), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 if (node == NULL)
107 return -ENOMEM;
108 node->nid = nid;
Takashi Iwaid2569502005-11-21 16:33:51 +0100109 nconns = snd_hda_get_connections(codec, nid, conn_list,
110 HDA_MAX_CONNECTIONS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 if (nconns < 0) {
112 kfree(node);
113 return nconns;
114 }
Takashi Iwaid2569502005-11-21 16:33:51 +0100115 if (nconns <= ARRAY_SIZE(node->slist))
116 node->conn_list = node->slist;
117 else {
118 node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns,
119 GFP_KERNEL);
120 if (! node->conn_list) {
121 snd_printk(KERN_ERR "hda-generic: cannot malloc\n");
122 kfree(node);
123 return -ENOMEM;
124 }
125 }
126 memcpy(node->conn_list, conn_list, nconns);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 node->nconns = nconns;
Takashi Iwaid2569502005-11-21 16:33:51 +0100128 node->wid_caps = get_wcaps(codec, nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
130
131 if (node->type == AC_WID_PIN) {
132 node->pin_caps = snd_hda_param_read(codec, node->nid, AC_PAR_PIN_CAP);
133 node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
134 node->def_cfg = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
135 }
136
137 if (node->wid_caps & AC_WCAP_OUT_AMP) {
138 if (node->wid_caps & AC_WCAP_AMP_OVRD)
139 node->amp_out_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_OUT_CAP);
140 if (! node->amp_out_caps)
141 node->amp_out_caps = spec->def_amp_out_caps;
142 }
143 if (node->wid_caps & AC_WCAP_IN_AMP) {
144 if (node->wid_caps & AC_WCAP_AMP_OVRD)
145 node->amp_in_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_IN_CAP);
146 if (! node->amp_in_caps)
147 node->amp_in_caps = spec->def_amp_in_caps;
148 }
149 list_add_tail(&node->list, &spec->nid_list);
150 return 0;
151}
152
153/*
154 * build the AFG subtree
155 */
156static int build_afg_tree(struct hda_codec *codec)
157{
158 struct hda_gspec *spec = codec->spec;
159 int i, nodes, err;
160 hda_nid_t nid;
161
162 snd_assert(spec, return -EINVAL);
163
164 spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP);
165 spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP);
166
167 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
168 if (! nid || nodes < 0) {
169 printk(KERN_ERR "Invalid AFG subtree\n");
170 return -EINVAL;
171 }
172
173 /* parse all nodes belonging to the AFG */
174 for (i = 0; i < nodes; i++, nid++) {
175 if ((err = add_new_node(codec, spec, nid)) < 0)
176 return err;
177 }
178
179 return 0;
180}
181
182
183/*
184 * look for the node record for the given NID
185 */
186/* FIXME: should avoid the braindead linear search */
187static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid)
188{
189 struct list_head *p;
190 struct hda_gnode *node;
191
192 list_for_each(p, &spec->nid_list) {
193 node = list_entry(p, struct hda_gnode, list);
194 if (node->nid == nid)
195 return node;
196 }
197 return NULL;
198}
199
200/*
201 * unmute (and set max vol) the output amplifier
202 */
203static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
204{
205 unsigned int val, ofs;
206 snd_printdd("UNMUTE OUT: NID=0x%x\n", node->nid);
207 val = (node->amp_out_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
208 ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
209 if (val >= ofs)
210 val -= ofs;
211 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
212 val |= AC_AMP_SET_OUTPUT;
213 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
214}
215
216/*
217 * unmute (and set max vol) the input amplifier
218 */
219static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigned int index)
220{
221 unsigned int val, ofs;
222 snd_printdd("UNMUTE IN: NID=0x%x IDX=0x%x\n", node->nid, index);
223 val = (node->amp_in_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
224 ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
225 if (val >= ofs)
226 val -= ofs;
227 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
228 val |= AC_AMP_SET_INPUT;
229 // awk added - fixed to allow unmuting of indexed amps
230 val |= index << AC_AMP_SET_INDEX_SHIFT;
231 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
232}
233
234/*
235 * select the input connection of the given node.
236 */
237static int select_input_connection(struct hda_codec *codec, struct hda_gnode *node,
238 unsigned int index)
239{
240 snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
241 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index);
242}
243
244/*
245 * clear checked flag of each node in the node list
246 */
247static void clear_check_flags(struct hda_gspec *spec)
248{
249 struct list_head *p;
250 struct hda_gnode *node;
251
252 list_for_each(p, &spec->nid_list) {
253 node = list_entry(p, struct hda_gnode, list);
254 node->checked = 0;
255 }
256}
257
258/*
259 * parse the output path recursively until reach to an audio output widget
260 *
261 * returns 0 if not found, 1 if found, or a negative error code.
262 */
263static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec,
264 struct hda_gnode *node)
265{
266 int i, err;
267 struct hda_gnode *child;
268
269 if (node->checked)
270 return 0;
271
272 node->checked = 1;
273 if (node->type == AC_WID_AUD_OUT) {
274 if (node->wid_caps & AC_WCAP_DIGITAL) {
275 snd_printdd("Skip Digital OUT node %x\n", node->nid);
276 return 0;
277 }
278 snd_printdd("AUD_OUT found %x\n", node->nid);
279 if (spec->dac_node) {
280 /* already DAC node is assigned, just unmute & connect */
281 return node == spec->dac_node;
282 }
283 spec->dac_node = node;
284 if (node->wid_caps & AC_WCAP_OUT_AMP) {
285 spec->pcm_vol_node = node;
286 spec->pcm_vol_index = 0;
287 }
288 return 1; /* found */
289 }
290
291 for (i = 0; i < node->nconns; i++) {
292 child = hda_get_node(spec, node->conn_list[i]);
293 if (! child)
294 continue;
295 err = parse_output_path(codec, spec, child);
296 if (err < 0)
297 return err;
298 else if (err > 0) {
299 /* found one,
300 * select the path, unmute both input and output
301 */
302 if (node->nconns > 1)
303 select_input_connection(codec, node, i);
304 unmute_input(codec, node, i);
305 unmute_output(codec, node);
306 if (! spec->pcm_vol_node) {
307 if (node->wid_caps & AC_WCAP_IN_AMP) {
308 spec->pcm_vol_node = node;
309 spec->pcm_vol_index = i;
310 } else if (node->wid_caps & AC_WCAP_OUT_AMP) {
311 spec->pcm_vol_node = node;
312 spec->pcm_vol_index = 0;
313 }
314 }
315 return 1;
316 }
317 }
318 return 0;
319}
320
321/*
322 * Look for the output PIN widget with the given jack type
323 * and parse the output path to that PIN.
324 *
325 * Returns the PIN node when the path to DAC is established.
326 */
327static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
328 struct hda_gspec *spec,
329 int jack_type)
330{
331 struct list_head *p;
332 struct hda_gnode *node;
333 int err;
334
335 list_for_each(p, &spec->nid_list) {
336 node = list_entry(p, struct hda_gnode, list);
337 if (node->type != AC_WID_PIN)
338 continue;
339 /* output capable? */
340 if (! (node->pin_caps & AC_PINCAP_OUT))
341 continue;
342 if (jack_type >= 0) {
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200343 if (jack_type != defcfg_type(node))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 continue;
345 if (node->wid_caps & AC_WCAP_DIGITAL)
346 continue; /* skip SPDIF */
347 } else {
348 /* output as default? */
349 if (! (node->pin_ctl & AC_PINCTL_OUT_EN))
350 continue;
351 }
352 clear_check_flags(spec);
353 err = parse_output_path(codec, spec, node);
354 if (err < 0)
355 return NULL;
356 else if (err > 0) {
357 /* unmute the PIN output */
358 unmute_output(codec, node);
359 /* set PIN-Out enable */
360 snd_hda_codec_write(codec, node->nid, 0,
361 AC_VERB_SET_PIN_WIDGET_CONTROL,
362 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
363 return node;
364 }
365 }
366 return NULL;
367}
368
369
370/*
371 * parse outputs
372 */
373static int parse_output(struct hda_codec *codec)
374{
375 struct hda_gspec *spec = codec->spec;
376 struct hda_gnode *node;
377
378 /*
379 * Look for the output PIN widget
380 */
381 /* first, look for the line-out pin */
382 node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT);
383 if (node) /* found, remember the PIN node */
384 spec->out_pin_node = node;
385 /* look for the HP-out pin */
386 node = parse_output_jack(codec, spec, AC_JACK_HP_OUT);
387 if (node) {
388 if (! spec->out_pin_node)
389 spec->out_pin_node = node;
390 }
391
392 if (! spec->out_pin_node) {
393 /* no line-out or HP pins found,
394 * then choose for the first output pin
395 */
396 spec->out_pin_node = parse_output_jack(codec, spec, -1);
397 if (! spec->out_pin_node)
398 snd_printd("hda_generic: no proper output path found\n");
399 }
400
401 return 0;
402}
403
404/*
405 * input MUX
406 */
407
408/* control callbacks */
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100409static int capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410{
411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412 struct hda_gspec *spec = codec->spec;
413 return snd_hda_input_mux_info(&spec->input_mux, uinfo);
414}
415
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100416static int capture_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417{
418 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
419 struct hda_gspec *spec = codec->spec;
420
421 ucontrol->value.enumerated.item[0] = spec->cur_cap_src;
422 return 0;
423}
424
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100425static int capture_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426{
427 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
428 struct hda_gspec *spec = codec->spec;
429 return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
430 spec->adc_node->nid, &spec->cur_cap_src);
431}
432
433/*
434 * return the string name of the given input PIN widget
435 */
436static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
437{
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200438 unsigned int location = defcfg_location(node);
439 switch (defcfg_type(node)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 case AC_JACK_LINE_IN:
441 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
442 return "Front Line";
443 return "Line";
444 case AC_JACK_CD:
445 if (pinctl)
Matt1a12de1e2005-04-13 14:37:50 +0200446 *pinctl |= AC_PINCTL_VREF_GRD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 return "CD";
448 case AC_JACK_AUX:
449 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
450 return "Front Aux";
451 return "Aux";
452 case AC_JACK_MIC_IN:
453 if ((location & 0x0f) == AC_JACK_LOC_FRONT)
454 return "Front Mic";
455 return "Mic";
456 case AC_JACK_SPDIF_IN:
457 return "SPDIF";
458 case AC_JACK_DIG_OTHER_IN:
459 return "Digital";
460 }
461 return NULL;
462}
463
464/*
465 * parse the nodes recursively until reach to the input PIN
466 *
467 * returns 0 if not found, 1 if found, or a negative error code.
468 */
469static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
470 struct hda_gnode *node)
471{
472 int i, err;
473 unsigned int pinctl;
474 char *label;
475 const char *type;
476
477 if (node->checked)
478 return 0;
479
480 node->checked = 1;
481 if (node->type != AC_WID_PIN) {
482 for (i = 0; i < node->nconns; i++) {
483 struct hda_gnode *child;
484 child = hda_get_node(spec, node->conn_list[i]);
485 if (! child)
486 continue;
487 err = parse_adc_sub_nodes(codec, spec, child);
488 if (err < 0)
489 return err;
490 if (err > 0) {
491 /* found one,
492 * select the path, unmute both input and output
493 */
494 if (node->nconns > 1)
495 select_input_connection(codec, node, i);
496 unmute_input(codec, node, i);
497 unmute_output(codec, node);
498 return err;
499 }
500 }
501 return 0;
502 }
503
504 /* input capable? */
505 if (! (node->pin_caps & AC_PINCAP_IN))
506 return 0;
507
508 if (node->wid_caps & AC_WCAP_DIGITAL)
509 return 0; /* skip SPDIF */
510
511 if (spec->input_mux.num_items >= HDA_MAX_NUM_INPUTS) {
512 snd_printk(KERN_ERR "hda_generic: Too many items for capture\n");
513 return -EINVAL;
514 }
515
516 pinctl = AC_PINCTL_IN_EN;
517 /* create a proper capture source label */
518 type = get_input_type(node, &pinctl);
519 if (! type) {
520 /* input as default? */
521 if (! (node->pin_ctl & AC_PINCTL_IN_EN))
522 return 0;
523 type = "Input";
524 }
525 label = spec->cap_labels[spec->input_mux.num_items];
526 strcpy(label, type);
527 spec->input_mux.items[spec->input_mux.num_items].label = label;
528
529 /* unmute the PIN external input */
530 unmute_input(codec, node, 0); /* index = 0? */
531 /* set PIN-In enable */
532 snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
533
534 return 1; /* found */
535}
536
537/*
538 * parse input
539 */
540static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
541{
542 struct hda_gspec *spec = codec->spec;
543 struct hda_gnode *node;
544 int i, err;
545
546 snd_printdd("AUD_IN = %x\n", adc_node->nid);
547 clear_check_flags(spec);
548
549 // awk added - fixed no recording due to muted widget
550 unmute_input(codec, adc_node, 0);
551
552 /*
553 * check each connection of the ADC
554 * if it reaches to a proper input PIN, add the path as the
555 * input path.
556 */
557 for (i = 0; i < adc_node->nconns; i++) {
558 node = hda_get_node(spec, adc_node->conn_list[i]);
559 if (! node)
560 continue;
561 err = parse_adc_sub_nodes(codec, spec, node);
562 if (err < 0)
563 return err;
564 else if (err > 0) {
565 struct hda_input_mux_item *csrc = &spec->input_mux.items[spec->input_mux.num_items];
566 char *buf = spec->cap_labels[spec->input_mux.num_items];
567 int ocap;
568 for (ocap = 0; ocap < spec->input_mux.num_items; ocap++) {
569 if (! strcmp(buf, spec->cap_labels[ocap])) {
570 /* same label already exists,
571 * put the index number to be unique
572 */
573 sprintf(buf, "%s %d", spec->cap_labels[ocap],
574 spec->input_mux.num_items);
575 }
576 }
577 csrc->index = i;
578 spec->input_mux.num_items++;
579 }
580 }
581
582 if (! spec->input_mux.num_items)
583 return 0; /* no input path found... */
584
585 snd_printdd("[Capture Source] NID=0x%x, #SRC=%d\n", adc_node->nid, spec->input_mux.num_items);
586 for (i = 0; i < spec->input_mux.num_items; i++)
587 snd_printdd(" [%s] IDX=0x%x\n", spec->input_mux.items[i].label,
588 spec->input_mux.items[i].index);
589
590 spec->adc_node = adc_node;
591 return 1;
592}
593
594/*
595 * parse input
596 */
597static int parse_input(struct hda_codec *codec)
598{
599 struct hda_gspec *spec = codec->spec;
600 struct list_head *p;
601 struct hda_gnode *node;
602 int err;
603
604 /*
605 * At first we look for an audio input widget.
606 * If it reaches to certain input PINs, we take it as the
607 * input path.
608 */
609 list_for_each(p, &spec->nid_list) {
610 node = list_entry(p, struct hda_gnode, list);
611 if (node->wid_caps & AC_WCAP_DIGITAL)
612 continue; /* skip SPDIF */
613 if (node->type == AC_WID_AUD_IN) {
614 err = parse_input_path(codec, node);
615 if (err < 0)
616 return err;
617 else if (err > 0)
618 return 0;
619 }
620 }
621 snd_printd("hda_generic: no proper input path found\n");
622 return 0;
623}
624
625/*
626 * create mixer controls if possible
627 */
628#define DIR_OUT 0x1
629#define DIR_IN 0x2
630
631static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
632 unsigned int index, const char *type, const char *dir_sfx)
633{
634 char name[32];
635 int err;
636 int created = 0;
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100637 struct snd_kcontrol_new knew;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639 if (type)
640 sprintf(name, "%s %s Switch", type, dir_sfx);
641 else
642 sprintf(name, "%s Switch", dir_sfx);
643 if ((node->wid_caps & AC_WCAP_IN_AMP) &&
644 (node->amp_in_caps & AC_AMPCAP_MUTE)) {
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100645 knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
647 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
648 return err;
649 created = 1;
650 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
651 (node->amp_out_caps & AC_AMPCAP_MUTE)) {
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100652 knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
654 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
655 return err;
656 created = 1;
657 }
658
659 if (type)
660 sprintf(name, "%s %s Volume", type, dir_sfx);
661 else
662 sprintf(name, "%s Volume", dir_sfx);
663 if ((node->wid_caps & AC_WCAP_IN_AMP) &&
664 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100665 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
667 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
668 return err;
669 created = 1;
670 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
671 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100672 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
674 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
675 return err;
676 created = 1;
677 }
678
679 return created;
680}
681
682/*
683 * check whether the controls with the given name and direction suffix already exist
684 */
685static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir)
686{
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100687 struct snd_ctl_elem_id id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 memset(&id, 0, sizeof(id));
689 sprintf(id.name, "%s %s Volume", type, dir);
690 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
691 if (snd_ctl_find_id(codec->bus->card, &id))
692 return 1;
693 sprintf(id.name, "%s %s Switch", type, dir);
694 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
695 if (snd_ctl_find_id(codec->bus->card, &id))
696 return 1;
697 return 0;
698}
699
700/*
701 * build output mixer controls
702 */
703static int build_output_controls(struct hda_codec *codec)
704{
705 struct hda_gspec *spec = codec->spec;
706 int err;
707
708 err = create_mixer(codec, spec->pcm_vol_node, spec->pcm_vol_index,
709 "PCM", "Playback");
710 if (err < 0)
711 return err;
712 return 0;
713}
714
715/* create capture volume/switch */
716static int build_input_controls(struct hda_codec *codec)
717{
718 struct hda_gspec *spec = codec->spec;
719 struct hda_gnode *adc_node = spec->adc_node;
720 int err;
721
722 if (! adc_node)
723 return 0; /* not found */
724
725 /* create capture volume and switch controls if the ADC has an amp */
726 err = create_mixer(codec, adc_node, 0, NULL, "Capture");
727
728 /* create input MUX if multiple sources are available */
729 if (spec->input_mux.num_items > 1) {
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100730 static struct snd_kcontrol_new cap_sel = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
732 .name = "Capture Source",
733 .info = capture_source_info,
734 .get = capture_source_get,
735 .put = capture_source_put,
736 };
737 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&cap_sel, codec))) < 0)
738 return err;
739 spec->cur_cap_src = 0;
740 select_input_connection(codec, adc_node, spec->input_mux.items[0].index);
741 }
742 return 0;
743}
744
745
746/*
747 * parse the nodes recursively until reach to the output PIN.
748 *
749 * returns 0 - if not found,
750 * 1 - if found, but no mixer is created
751 * 2 - if found and mixer was already created, (just skip)
752 * a negative error code
753 */
754static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec,
755 struct hda_gnode *node, struct hda_gnode *dest_node,
756 const char *type)
757{
758 int i, err;
759
760 if (node->checked)
761 return 0;
762
763 node->checked = 1;
764 if (node == dest_node) {
765 /* loopback connection found */
766 return 1;
767 }
768
769 for (i = 0; i < node->nconns; i++) {
770 struct hda_gnode *child = hda_get_node(spec, node->conn_list[i]);
771 if (! child)
772 continue;
773 err = parse_loopback_path(codec, spec, child, dest_node, type);
774 if (err < 0)
775 return err;
776 else if (err >= 1) {
777 if (err == 1) {
778 err = create_mixer(codec, node, i, type, "Playback");
779 if (err < 0)
780 return err;
781 if (err > 0)
782 return 2; /* ok, created */
783 /* not created, maybe in the lower path */
784 err = 1;
785 }
786 /* connect and unmute */
787 if (node->nconns > 1)
788 select_input_connection(codec, node, i);
789 unmute_input(codec, node, i);
790 unmute_output(codec, node);
791 return err;
792 }
793 }
794 return 0;
795}
796
797/*
798 * parse the tree and build the loopback controls
799 */
800static int build_loopback_controls(struct hda_codec *codec)
801{
802 struct hda_gspec *spec = codec->spec;
803 struct list_head *p;
804 struct hda_gnode *node;
805 int err;
806 const char *type;
807
808 if (! spec->out_pin_node)
809 return 0;
810
811 list_for_each(p, &spec->nid_list) {
812 node = list_entry(p, struct hda_gnode, list);
813 if (node->type != AC_WID_PIN)
814 continue;
815 /* input capable? */
816 if (! (node->pin_caps & AC_PINCAP_IN))
817 return 0;
818 type = get_input_type(node, NULL);
819 if (type) {
820 if (check_existing_control(codec, type, "Playback"))
821 continue;
822 clear_check_flags(spec);
823 err = parse_loopback_path(codec, spec, spec->out_pin_node,
824 node, type);
825 if (err < 0)
826 return err;
827 if (! err)
828 continue;
829 }
830 }
831 return 0;
832}
833
834/*
835 * build mixer controls
836 */
837static int build_generic_controls(struct hda_codec *codec)
838{
839 int err;
840
841 if ((err = build_input_controls(codec)) < 0 ||
842 (err = build_output_controls(codec)) < 0 ||
843 (err = build_loopback_controls(codec)) < 0)
844 return err;
845
846 return 0;
847}
848
849/*
850 * PCM
851 */
852static struct hda_pcm_stream generic_pcm_playback = {
853 .substreams = 1,
854 .channels_min = 2,
855 .channels_max = 2,
856};
857
858static int build_generic_pcms(struct hda_codec *codec)
859{
860 struct hda_gspec *spec = codec->spec;
861 struct hda_pcm *info = &spec->pcm_rec;
862
863 if (! spec->dac_node && ! spec->adc_node) {
864 snd_printd("hda_generic: no PCM found\n");
865 return 0;
866 }
867
868 codec->num_pcms = 1;
869 codec->pcm_info = info;
870
871 info->name = "HDA Generic";
872 if (spec->dac_node) {
873 info->stream[0] = generic_pcm_playback;
874 info->stream[0].nid = spec->dac_node->nid;
875 }
876 if (spec->adc_node) {
877 info->stream[1] = generic_pcm_playback;
878 info->stream[1].nid = spec->adc_node->nid;
879 }
880
881 return 0;
882}
883
884
885/*
886 */
887static struct hda_codec_ops generic_patch_ops = {
888 .build_controls = build_generic_controls,
889 .build_pcms = build_generic_pcms,
890 .free = snd_hda_generic_free,
891};
892
893/*
894 * the generic parser
895 */
896int snd_hda_parse_generic_codec(struct hda_codec *codec)
897{
898 struct hda_gspec *spec;
899 int err;
900
Sasha Khapyorsky84802f02005-09-13 11:25:54 +0200901 if(!codec->afg)
902 return 0;
Sasha Khapyorsky673b6832005-08-11 11:00:16 +0200903
Takashi Iwaie560d8d2005-09-09 14:21:46 +0200904 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 if (spec == NULL) {
906 printk(KERN_ERR "hda_generic: can't allocate spec\n");
907 return -ENOMEM;
908 }
909 codec->spec = spec;
910 INIT_LIST_HEAD(&spec->nid_list);
911
912 if ((err = build_afg_tree(codec)) < 0)
913 goto error;
914
915 if ((err = parse_input(codec)) < 0 ||
916 (err = parse_output(codec)) < 0)
917 goto error;
918
919 codec->patch_ops = generic_patch_ops;
920
921 return 0;
922
923 error:
924 snd_hda_generic_free(codec);
925 return err;
926}