11
typedef int sound_os_info, mixer_create_controls_t, oss_device_t;
16
#define mixer_ext_init_fn int
17
#include <hdaudio_codec.h>
19
static int num_widgets = 0;
21
static int print_widgets = 0;
33
unsigned int inamp_caps;
34
unsigned int outamp_caps;
36
int connections[MAX_CONN];
40
static mixgen_widget_t widgets[256] = { {0} };
42
static int errors = 0;
44
static unsigned int default_outamp_caps = 0;
45
static unsigned int default_inamp_caps = 0;
46
static unsigned int subdevice = 0;
58
corb_write (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
59
unsigned int verb, unsigned int parm)
63
tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
65
printf ("WRITE %08x\n", tmp);
67
if (ioctl (fd, HDA_IOCTL_WRITE, &tmp) == -1)
69
/* perror("HDA_IOCTL_WRITE"); */
77
corb_read (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
78
unsigned int verb, unsigned int parm, unsigned int *upper,
83
tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
85
if (ioctl (fd, HDA_IOCTL_READ, &tmp) == -1)
87
/* perror("HDA_IOCTL_READ"); */
90
fprintf (stderr, "hdaudio_snoopy mode is not available\n");
99
printf ("READ %08x\n", tmp);
105
set_error (char *msg)
107
fprintf (stderr, "%s");
114
gen_amps (mixgen_widget_t * widget, int wid)
119
if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
121
if (widget->outamp_caps & ~AMPCAP_MUTE) /* Has gain control */
124
if (widget->type == NT_PIN)
126
printf ("\t\tHDA_OUTAMP(0x%02x, group, \"%s\", 90);\n", wid, name);
128
else if (widget->outamp_caps & AMPCAP_MUTE) /* Only mute control */
131
if (widget->type == NT_PIN)
133
printf ("\t\tHDA_OUTMUTE(0x%02x, group, \"%s\", UNMUTE);\n", wid,
138
if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
140
int n = widget->nconn;
141
if (widget->type == NT_PIN)
144
if (n > 1 && !(widget->inamp_caps & ~AMPCAP_MUTE))
145
{ /* Create mute group */
147
printf ("\t\t\tint amp_group;\n\n");
148
printf ("\t\t\tHDA_GROUP(amp_group, group, \"mute\");\n");
149
for (i = 0; i < widget->nconn; i++)
153
name = widgets[widget->connections[i]].name;
154
if (widgets[widget->connections[i]].type == NT_PIN)
155
name = widgets[widget->connections[i]].widget_info.color;
157
("\t\t\tHDA_INMUTE(0x%02x, %d, amp_group, \"%s\", UNMUTE);\t/* From widget 0x%02x */\n",
158
wid, i, name, widget->connections[i]);
164
for (i = 0; i < n; i++)
168
name = widgets[widget->connections[i]].name;
169
if (widgets[widget->connections[i]].type == NT_PIN)
170
name = widgets[widget->connections[i]].widget_info.color;
171
if (widget->type == NT_PIN)
173
if (widget->inamp_caps & ~AMPCAP_MUTE) /* Has gain control */
176
("\t\tHDA_INAMP(0x%02x, %d, group, \"%s\", 90);\t/* From widget 0x%02x */\n",
177
wid, i, name, widget->connections[i]);
182
("\t\tHDA_INMUTE(0x%02x, %d, group, \"%smute\", UNMUTE);\t/* From widget 0x%02x */\n",
183
wid, i, name, widget->connections[i]);
193
follow_widget_chain (int wid, int force)
196
char choice_list[1024] = "", *s = choice_list;
197
mixgen_widget_t *widget;
199
if (!widgets[wid].valid || widgets[wid].used)
202
widget = &widgets[wid];
204
if (widget->widget_info.refcount > 1 && !force)
209
printf ("\n\t\t/* Widget 0x%02x (%s) */\n", wid, widget->name);
211
for (i = 0; i < widget->nconn; i++)
213
char *name = widgets[widget->connections[i]].name;
214
if (widgets[widget->connections[i]].type == NT_PIN)
215
name = widgets[widget->connections[i]].widget_info.color;
218
if (widget->connections[i] < num_widgets)
219
strcpy (s, widgets[widget->connections[i]].name);
221
strcpy (s, "unknown");
222
printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i], name);
226
if (widget->type == NT_SELECT && widget->nconn > 1)
228
printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
230
printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
234
gen_amps (widget, wid);
236
* Follow the input connection chain.
238
if (widget->nconn == 1)
239
follow_widget_chain (widget->connections[0], force);
245
handle_pin_widget (int wid, mixgen_widget_t * widget)
247
int outselects = 0, inselects = 0, num_amps = 0;
248
char choice_list[1024] = "", *s = choice_list;
253
if (widget->pincaps & PINCAP_INPUT_CAPABLE)
255
if (!(widget->wcaps & WCAP_DIGITAL)) /* Analog pin */
261
if (widget->pincaps & PINCAP_OUTPUT_CAPABLE)
263
if (!(widget->wcaps & WCAP_DIGITAL)) /* Analog pin */
265
outselects = widget->nconn;
269
if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
271
num_amps += widget->nconn;
274
if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
279
if (inselects + outselects + num_amps == 0)
283
("\n\tif (HDA_PIN_GROUP(0x%02x, group, pin_group, \"%s\", n, \"jack\", 4))\t/* Pin widget 0x%02x */\n",
284
wid, widget->widget_info.color, wid);
287
for (i = 0; i < widget->nconn; i++)
292
if (widget->connections[i] < num_widgets)
293
sprintf (s, "%s-out", widgets[widget->connections[i]].name);
295
strcpy (s, "unknown");
296
printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
297
widgets[widget->connections[i]].name);
301
if (widget->nconn > 0)
303
sprintf (s, "input");
306
printf ("\t\tif (HDA_PINSELECT(0x%02x, ctl, group, \"mode\", -1))\n", wid);
307
printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
309
gen_amps (widget, wid);
311
for (i = 0; i < widget->nconn; i++)
312
follow_widget_chain (widget->connections[i], 0);
320
handle_adc_widget (int wid, mixgen_widget_t * widget)
322
int outselects = 0, inselects = 0, num_amps = 0;
323
char choice_list[4000] = "", *s = choice_list;
328
if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
330
num_amps += widget->nconn;
333
if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
339
("\n\tif (HDA_ADC_GROUP(0x%02x, group, rec_group, \"%s\", n, \"record\", 4))\t/* ADC widget 0x%02x */\n",
340
wid, widget->name, wid);
343
for (i = 0; i < widget->nconn; i++)
347
if (widget->connections[i] < num_widgets)
348
strcpy (s, widgets[widget->connections[i]].name);
350
strcpy (s, "unknown");
351
printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
352
widgets[widget->connections[i]].name);
356
if (widget->nconn > 1)
358
printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
360
printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
364
gen_amps (widget, wid);
366
for (i = 0; i < widget->nconn; i++)
367
follow_widget_chain (widget->connections[i], 0);
375
handle_misc_widget (int wid, mixgen_widget_t * widget)
377
int outselects = 0, inselects = 0, num_amps = 0;
378
char choice_list[4000] = "", *s = choice_list;
383
if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
385
num_amps += widget->nconn;
388
if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
397
("\n\tif (HDA_MISC_GROUP(0x%02x, group, misc_group, \"%s\", n, \"misc\", 8))\t/* Misc widget 0x%02x */\n",
398
wid, widget->name, wid);
401
for (i = 0; i < widget->nconn; i++)
405
if (widget->connections[i] < num_widgets)
406
strcpy (s, widgets[widget->connections[i]].name);
408
strcpy (s, "unknown");
409
printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
410
widgets[widget->connections[i]].name);
414
if (widget->type == NT_SELECT && widget->nconn > 1)
416
printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
418
printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
422
gen_amps (widget, wid);
424
for (i = 0; i < widget->nconn; i++)
425
follow_widget_chain (widget->connections[i], 1);
433
attach_widget (int wid)
436
hda_widget_info_t info;
437
unsigned int wcaps, b;
438
mixgen_widget_t *widget = &widgets[wid];
441
unsigned int nconn, connections[256];
443
memset (&name, 0, sizeof (name));
444
memset (&info, 0, sizeof (info));
448
if (ioctl (fd, HDA_IOCTL_NAME, &name) == -1)
449
strcpy (name.name, "Unknown_widget");
453
if (ioctl (fd, HDA_IOCTL_WIDGET, &info) != -1)
454
memcpy (&widget->widget_info, info.info, sizeof (widget->widget_info));
457
(mixer, cad, wid, 0, GET_PARAMETER, HDA_WIDGET_CAPS, &wcaps, &b))
458
return set_error ("Can't get widget capabilities\n");
460
type = (wcaps >> 20) & 0xf;
463
if (!corb_read (mixer, cad, wid, 0,
464
GET_PARAMETER, HDA_PIN_CAPS, &widget->pincaps, &b))
465
return set_error ("Can't get widget pin capabilities\n");
468
strcpy (widget->name, name.name);
469
widget->wcaps = wcaps;
470
widget->inamp_caps = default_inamp_caps;
471
widget->outamp_caps = default_outamp_caps;
475
* Handle connection list.
478
if (wcaps & WCAP_CONN_LIST)
482
(mixer, cad, wid, 0, GET_PARAMETER, HDA_CONNLIST_LEN, &nconn, &b))
484
if (nconn >= MAX_CONN)
487
"Too many input connections (%d) for widget %d\n", nconn,
499
for (i = 0; i < nconn; i += 4)
501
(mixer, cad, wid, 0, GET_CONNECTION_LIST_ENTRY, i, &clist,
503
for (j = 0; j < 4 && (i + j) < nconn; j++)
505
connections[n++] = (clist >> (j * 8)) & 0xff;
510
for (i = 0; i < nconn; i++)
511
widget->connections[i] = connections[i];
512
widget->nconn = nconn;
514
if ((wcaps & WCAP_AMP_CAP_OVERRIDE) && (wcaps & WCAP_OUTPUT_AMP_PRESENT))
515
if (!corb_read (mixer, cad, wid, 0,
516
GET_PARAMETER, HDA_OUTPUTAMP_CAPS,
517
&widget->outamp_caps, &b))
519
fprintf (stderr, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
520
return set_error ("Can't get outamp capabilities\n");
523
if ((wcaps & WCAP_AMP_CAP_OVERRIDE) && (wcaps & WCAP_INPUT_AMP_PRESENT))
524
if (!corb_read (mixer, cad, wid, 0,
525
GET_PARAMETER, HDA_INPUTAMP_CAPS,
526
&widget->inamp_caps, &b))
528
fprintf (stderr, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
529
return set_error ("Can't get inamp capabilities\n");
539
unsigned int a, b, gtype, gcaps, wcaps, sizes, fmts, pincaps;
540
unsigned int inamp_caps, outamp_caps, clen, pstates, pcaps, gpio_count;
542
int first_node = 0, num_nodes = 0;
547
(mixer, cad, wid, 0, GET_PARAMETER, HDA_GROUP_TYPE, >ype, &b))
548
if ((gtype & 0x1ff) != 0)
552
switch (gtype & 0xff)
559
s = "Audio function group";
562
s = "Vendor defined modem function group";
568
if (corb_read (mixer, cad, wid, 0, GET_SUBSYSTEM_ID, 0, &a, &b))
570
printf ("/* Subsystem ID %08x */\n", a);
574
if (!corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
576
fprintf (stderr, "GET_PARAMETER HDA_NODE_COUNT2 failed\n");
580
if (!corb_read (mixer, cad, wid, 0,
581
GET_PARAMETER, HDA_OUTPUTAMP_CAPS,
582
&default_outamp_caps, &b))
584
fprintf (stderr, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
588
if (!corb_read (mixer, cad, wid, 0,
589
GET_PARAMETER, HDA_INPUTAMP_CAPS, &default_inamp_caps, &b))
591
fprintf (stderr, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
595
printf ("/* Default amplifier caps: in=%08x, out=%08x */\n",
596
default_inamp_caps, default_outamp_caps);
598
first_node = (a >> 16) & 0xff;
599
num_nodes = a & 0xff;
601
for (wid = first_node; wid < first_node + num_nodes; wid++)
604
if (wid >= num_widgets)
605
num_widgets = wid + 1;
614
for (i = 0; i < num_widgets; i++)
616
if (widgets[i].valid)
618
if (widgets[i].name[0] == 0) /* Empty string */
621
printf ("\t\"%s\",\t\t/* 0x%02x */\n", widgets[i].name, i);
624
printf ("\tES,\t\t/* 0x%02x */\n", i);
629
main (int argc, char *argv[])
632
int first_node, num_nodes;
634
char codec_name[32] = "";
637
strcpy (codec_name, argv[1]);
639
if ((fd = open ("/dev/oss/oss_hdaudio0/pcm0", O_RDWR | O_EXCL, 0)) == -1)
641
perror ("/dev/oss/oss_hdaudio0/pcm0");
646
cad = atoi (argv[2]);
648
for (i = 3; i < argc; i++)
656
if (cad == -1) /* Not given on command line so find it. */
657
for (cad = 0; cad < 16; cad++)
658
if (corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_VENDOR, &a, &b))
663
* This file is part of Open Sound System.
665
* Copyright (C) 4Front Technologies 1996-2008.
667
* This this source file is released under GPL v2 license (no other versions).
668
* See the COPYING file included in the main directory of this source
669
* distribution for the license terms and conditions.
673
printf ("/* Codec index is %d */\n", cad);
674
printf ("/* Codec vendor %04x:%04x */\n", a >> 16, a & 0xffff);
676
if (corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_REVISION, &a, &b))
678
printf ("/* HD codec revision %d.%d (%d.%d) (0x%08x) */\n",
679
(a >> 20) & 0xf, (a >> 16) & 0xf, (a >> 8) & 0xff, a & 0xff, a);
682
printf ("hdaudio: Can't get codec revision\n");
685
* Find out the primary group list
688
if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
691
first_node = (a >> 16) & 0xff;
692
num_nodes = a & 0xff;
694
for (i = first_node; i < first_node + num_nodes; i++)
698
* Next produce the output
701
if (*codec_name == 0)
702
sprintf (codec_name, "subdevice%08x", subdevice);
704
printf ("#include \"oss_hdaudio_cfg.h\"\n");
705
printf ("#include \"hdaudio.h\"\n");
706
printf ("#include \"hdaudio_codec.h\"\n");
707
printf ("#include \"hdaudio_dedicated.h\"\n");
712
("hdaudio_%s_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)\n",
715
//printf (" int wid;\n");
716
printf (" int ctl=0;\n");
717
//printf (" codec_t *codec = mixer->codecs[cad];\n");
721
(" DDB(cmn_err(CE_CONT, \"hdaudio_%s_mixer_init got called.\\n\"));\n",
726
* Handle PIN widgets first
728
printf (" /* Handle PIN widgets */\n");
730
printf ("\tint n, group, pin_group;\n");
731
printf ("\n\tn=0;\n");
733
printf ("\n\tHDA_GROUP(pin_group, top_group, \"jack\");\n");
735
for (i = 0; i < num_widgets; i++)
737
mixgen_widget_t *widget = &widgets[i];
742
if (widget->type != NT_PIN)
745
handle_pin_widget (i, widget);
752
printf (" /* Handle ADC widgets */\n");
754
printf ("\tint n, group, rec_group;\n");
755
printf ("\n\tn=0;\n");
757
printf ("\n\tHDA_GROUP(rec_group, top_group, \"record\");\n");
759
for (i = 0; i < num_widgets; i++)
761
mixgen_widget_t *widget = &widgets[i];
763
if (!widget->valid || widget->used)
766
if (widget->type != NT_ADC)
769
handle_adc_widget (i, widget);
774
* Handle the remaining widgets
776
printf (" /* Handle misc widgets */\n");
778
printf ("\tint n, group, misc_group;\n");
779
printf ("\n\tn=0;\n");
781
printf ("\n\tHDA_GROUP(misc_group, top_group, \"misc\");\n");
783
for (i = 0; i < num_widgets; i++)
785
mixgen_widget_t *widget = &widgets[i];
787
if (!widget->valid || widget->used)
790
handle_misc_widget (i, widget);
794
printf (" return 0;\n");