2
* Temporary utility used to develop the next hdaudio driver
7
* This file is part of Open Sound System.
9
* Copyright (C) 4Front Technologies 1996-2008.
11
* This this source file is released under GPL v2 license (no other versions).
12
* See the COPYING file included in the main directory of this source
13
* distribution for the license terms and conditions.
21
#include <sys/ioctl.h>
24
#include <soundcard.h>
27
#define DRIVER_NICK "hdaudio"
34
#define PMALLOC(osdev, s) malloc(s)
36
typedef int sound_os_info, mixer_create_controls_t;
46
#define mixer_ext_init_fn int
47
#include <hdaudio_codec.h>
48
//#include <hdaudio_codecids.h>
57
int association, sequence;
62
widget_t *widgets[PATH_MAXWID];
66
path_t *paths[MAX_PATHS];
70
corb_write (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
71
unsigned int verb, unsigned int parm)
75
tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
77
if (ioctl (fd, HDA_IOCTL_WRITE, &tmp) == -1)
79
perror ("HDA_IOCTL_WRITE");
87
corb_read (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
88
unsigned int verb, unsigned int parm, unsigned int *upper,
93
tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
95
if (ioctl (fd, HDA_IOCTL_READ, &tmp) == -1)
97
/* perror("HDA_IOCTL_READ"); */
100
fprintf (stderr, "hdaudio_snoopy mode is not available\n");
113
cmn_err (int level, char *s, ...)
115
char tmp[1024], *a[6];
121
for (i = 0; i < strlen (s); i++)
125
for (i = 0; i < n && i < 6; i++)
127
a[i] = va_arg (ap, char *);
130
for (i = n; i < 6; i++)
133
if (level == CE_CONT)
135
sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
141
strcpy (tmp, DRIVER_NICK ": ");
143
sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5],
144
NULL, NULL, NULL, NULL);
152
********************************
155
static const char *widget_id[16] = {
175
attach_pin_widget (hdaudio_mixer_t * mixer, codec_t * codec,
176
widget_t * widget, int cad, int wid, int group_type)
179
int num = codec->jack_number++;
180
unsigned int pincaps, b;
181
int association, sequence;
188
char *name = NULL, *loc = "", *color_name = NULL;
190
if (!corb_read (mixer, cad, wid, 0, GET_CONFIG_DEFAULT, 0, &conf, &b))
193
default_device = (conf >> 20) & 0x0f;
194
default_loc = (conf >> 24) & 0x3f;
195
conn = (conf >> 30) & 0x03;
197
if (!corb_read (mixer, cad, wid, 0,
198
GET_PARAMETER, HDA_PIN_CAPS, &pincaps, &b))
200
cmn_err (CE_WARN, "GET_PARAMETER HDA_PIN_CAPS failed\n");
204
widget->pincaps = pincaps;
209
"CONFIG_DEFAULT information not provided by BIOS for cad=%d, wid=%02x\n",
211
cmn_err (CE_CONT, "Cannot work in this system.\n");
215
color = (conf >> 12) & 0x0f;
217
association = (conf>>4) & 0xf;
218
sequence = conf & 0xf;
220
if (pincaps & (1 << 6))
221
cmn_err (CE_WARN, "Balanced I/O not supported\n");
222
if (!(pincaps & (1 << 5))) /* No input */
223
widget->pin_type = PIN_OUT;
224
if (!(pincaps & (1 << 4)))
225
widget->pin_type = PIN_IN;
227
DDB (cmn_err (CE_CONT, "\tConfig default %08x\n", conf));
229
if ((default_loc & 0x0f) == 0x1) /* Rear panel - default */
231
if ((default_loc & 0x0f) == 0x2) /* Front panel */
233
if ((default_loc & 0xf0) == 0x10) /* Internal func - eg cd/tad/spk */
236
if (conn == 1) /* Pin not connected to anything */
239
widget->skip_output = 1;
242
widget->association = association;
243
widget->sequence = sequence;
245
switch (default_device)
249
widget->pin_type = PIN_OUT;
254
widget->pin_type = PIN_OUT;
258
widget->pin_type = PIN_OUT;
263
widget->pin_type = PIN_IN;
268
widget->pin_type = PIN_OUT;
273
widget->pin_type = PIN_OUT;
285
widget->pin_type = PIN_IN;
292
widget->pin_type = PIN_MIC;
310
case 0xf: /* Unused pin widget */
312
widget->skip_output = 1;
316
/* process only colored jacks and skip fixed function jacks */
320
color_name = "black";
321
widget->rgbcolor = OSS_RGB_BLACK;
325
widget->rgbcolor = OSS_RGB_GRAY;
329
widget->rgbcolor = OSS_RGB_BLUE;
332
color_name = "green";
333
widget->rgbcolor = OSS_RGB_GREEN;
337
widget->rgbcolor = OSS_RGB_RED;
340
color_name = "orange";
341
widget->rgbcolor = OSS_RGB_ORANGE;
344
color_name = "yellow";
345
widget->rgbcolor = OSS_RGB_YELLOW;
348
color_name = "purple";
349
widget->rgbcolor = OSS_RGB_PURPLE;
353
widget->rgbcolor = OSS_RGB_PINK;
356
color_name = "white";
357
widget->rgbcolor = OSS_RGB_WHITE;
364
color_name = "internal";
368
widget->rgbcolor = 0;
370
if (default_device == 0xf) /* Not present */
372
widget->rgbcolor = 0;
373
color_name = "internal";
376
sprintf (widget->color, "%s%s", loc, color_name);
378
if (name == NULL || default_device == 0x00)
380
sprintf (widget->name, "%s%s", loc, name);
382
DDB(cmn_err(CE_CONT, "\tJack name %s, color %s (%06x)\n",
383
widget->name, widget->color, widget->rgbcolor));
384
DDB(cmn_err(CE_CONT, "\tAssociation %x, sequence %x\n", association, sequence));
386
printf("Widget %02x: default_device=%d, name=%s, color=%s\n", wid, default_device, widget->name, widget->color);
391
attach_widget (hdaudio_mixer_t * mixer, int cad, int wid, int group_type)
393
static const char *widget_types[16] = {
409
"Vendor defined audio"
412
static const int bit_sizes[] = {
420
static const unsigned int bit_fmts[] = {
428
static const int srates[] = {
443
unsigned int widget_caps, b, pstate;
444
unsigned int inamp_caps, outamp_caps;
448
codec_t *codec = mixer->codecs[cad];
454
if (wid >= MAX_WIDGETS)
456
cmn_err (CE_WARN, "Too many widgets for codec %d (%d/%d)\n", cad, wid,
463
codec->nwidgets = wid + 1;
464
widget = &codec->widgets[wid];
469
widget->rgbcolor = 0;
471
widget->group_type = group_type;
473
DDB (cmn_err (CE_CONT, " * Widget %02x, type %d\n", wid, group_type));
476
(mixer, cad, wid, 0, GET_PARAMETER, HDA_WIDGET_CAPS, &widget_caps, &b))
478
cmn_err (CE_WARN, "GET_PARAMETER HDA_WIDGET_CAPS failed\n");
482
if (widget_caps & WCAP_AMP_CAP_OVERRIDE) /* Amp param override? */
484
if (!corb_read (mixer, widget->cad, widget->wid, 0,
485
GET_PARAMETER, HDA_OUTPUTAMP_CAPS, &outamp_caps, &b))
487
cmn_err (CE_WARN, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
490
widget->outamp_caps = outamp_caps;
492
if (!corb_read (mixer, widget->cad, widget->wid, 0,
493
GET_PARAMETER, HDA_INPUTAMP_CAPS, &inamp_caps, &b))
495
cmn_err (CE_WARN, "GET_PARAMETER HDA_INPUTAMP_CAPS failed\n");
498
widget->inamp_caps = inamp_caps;
502
widget->outamp_caps = outamp_caps = codec->default_outamp_caps;
503
widget->inamp_caps = inamp_caps = codec->default_inamp_caps;
506
if (!corb_read (mixer, cad, wid, 0, GET_POWER_STATE, 0, &pstate, &b))
509
/* power up each of the widgets if there is a Power Capability (1<<10) */
510
if (widget_caps & WCAP_POWER_CTL)
511
corb_write (mixer, cad, wid, 0, SET_POWER_STATE, 0);
513
widget->widget_caps = widget_caps;
515
wid_type = (widget_caps >> 20) & 0x0f;
517
(CE_CONT, "\tWidget type %d (%s)(%s)\n", wid_type,
518
widget_types[wid_type], widget_id[wid_type]));
519
DDB (cmn_err (CE_CONT, "\tPower State %d\n", pstate));
521
if (widget_caps & WCAP_CONN_LIST)
524
/* Handle connection list */
527
(mixer, cad, wid, 0, GET_PARAMETER, HDA_CONNLIST_LEN, &clen, &b))
529
cmn_err (CE_WARN, "GET_PARAMETER HDA_CONNLIST_LEN failed\n");
535
cmn_err (CE_WARN, "Long form connection list not supported\n");
543
cmn_err (CE_WARN, "Too many connections\n");
547
DDB (cmn_err (CE_CONT, "\tConn list (%d): ", clen));
549
for (i = 0; i < clen; i += 4)
555
(mixer, cad, wid, 0, GET_CONNECTION_LIST_ENTRY, i, &a, &b))
557
cmn_err (CE_WARN, "GET_CONNECTION_LIST_ENTRY failed\n");
561
for (j = 0; j < 4 && (i + j) < clen; j++)
565
if (widget->nconn >= MAX_CONN)
568
"Too many connections for widget %d (%d)\n",
569
widget->wid, widget->nconn);
573
v = (a >> (j * 8)) & 0xff;
574
DDB (cmn_err (CE_CONT, "%d ", v));
582
if (v < 0 || v >= MAX_WIDGETS)
585
"Connection %d for widget %d is out of range (%d) - Skipped\n",
590
if (is_range) /* Range: prev...v */
593
codec->widgets[v].references[codec->widgets[v].
596
if (widget->nconn < 1)
599
"Bad range connection for widget %d\n",
604
for (x = widget->connections[widget->nconn - 1] + 1;
607
if (widget->nconn >= MAX_CONN)
610
"Too many connectionsi(B) for widget %d (%d)\n",
611
widget->wid, widget->nconn);
615
widget->connections[widget->nconn++] = x;
616
codec->widgets[x].references[codec->widgets[x].
622
widget->connections[widget->nconn++] = v;
623
codec->widgets[v].references[codec->widgets[v].
629
DDB (cmn_err (CE_CONT, "\n"));
633
widget->wid_type = wid_type;
634
strcpy (widget->name, widget_id[wid_type]);
637
* Handle widget based on its type.
643
if (!attach_pin_widget (mixer, codec, widget, cad, wid, group_type))
651
/*ARGSUSED*/ static int
652
attach_function_group (hdaudio_mixer_t * mixer, int cad, int wid,
655
unsigned int a, b, gt;
656
int i, first_node, num_nodes;
657
codec_t *codec = mixer->codecs[cad];
661
cmn_err (CE_CONT, "Attach function group, cad=%02x, wid=%02x\n", cad, wid);
663
if (!corb_read (mixer, cad, wid, 0,
664
GET_PARAMETER, HDA_OUTPUTAMP_CAPS,
665
&codec->default_outamp_caps, &b))
667
cmn_err (CE_WARN, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
671
if (!corb_read (mixer, cad, wid, 0,
672
GET_PARAMETER, HDA_INPUTAMP_CAPS,
673
&codec->default_inamp_caps, &b))
675
cmn_err (CE_WARN, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
679
if (!corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
681
cmn_err (CE_WARN, "GET_PARAMETER HDA_NODE_COUNT2 failed\n");
685
first_node = (a >> 16) & 0xff;
686
num_nodes = a & 0xff;
688
corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_GROUP_TYPE, >, &b);
693
" * Function group %d First node %d, num nodes %d, group type %x\n",
694
wid, first_node, num_nodes, gt));
696
* Ignore other than audio function groups. Codecs probably allocate
697
* higher widget number for the modem group than the audio group. So in this
698
* way we can have smaller MAX_WIDGETS which in turn conserves memory.
700
if (gt != group_type)
703
if (corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_PCM_SIZES, &a, &b))
709
for (i = first_node; i < first_node + num_nodes; i++)
710
if (!attach_widget (mixer, cad, i, gt))
718
attach_codec (hdaudio_mixer_t * mixer, int cad, char *hw_info,
719
unsigned int pci_subdevice, int group_type)
721
unsigned int a, b, x;
723
int first_node, num_nodes;
724
int has_audio_group = 0;
727
if (cad >= MAX_CODECS)
729
cmn_err (CE_WARN, "attach_codec: Too many codecs %d\n", cad);
733
mixer->ncodecs = cad + 1;
735
if (mixer->codecs[cad] == NULL)
737
if ((codec = PMALLOC (mixer->osdev, sizeof (*codec))) == NULL)
739
cmn_err (CE_CONT, "Cannot allocate codec descriptor\n");
743
memset (codec, 0, sizeof (*codec));
745
mixer->codecs[cad] = codec;
749
codec = mixer->codecs[cad];
752
corb_write (mixer, cad, 0, 0, SET_POWER_STATE, 0); /* Power up everything */
754
if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_VENDOR, &a, &b))
758
sprintf (hw_info, " Codec %2d: Not present\n", cad);
760
"attach_codec: Codec #%d is not physically present\n",
766
codec->vendor_id = a;
769
* Find out the primary group list
772
if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_NODE_COUNT, &x, &b))
774
cmn_err (CE_WARN, "GET_PARAMETER HDA_NODE_COUNT3 failed\n");
778
codec->first_node = first_node = (x >> 16) & 0xff;
779
num_nodes = x & 0xff;
782
* Check if this one is an audio codec (has an audio function group)
784
for (i = first_node; i < first_node + num_nodes; i++)
789
(mixer, cad, i, 0, GET_PARAMETER, HDA_GROUP_TYPE, >, &b));
790
if ((gt & 0xff) != 1) /* Audio function group */
798
* Find codec specific settings
800
for (ix = 0; codecs[ix].id != 0; ix++)
801
if (codecs[ix].id == a)
805
(CE_CONT, "HD audio Codec ID: %08x (%s)\n", a, codecs[ix].name));
807
if (codecs[ix].id == 0) /* Unknown codec */
810
sprintf (hw_info, " Codec %2d: Unknown (0x%08x", cad, a);
811
cmn_err (CE_NOTE, "Unknown HDA codec 0x%08x\n", a);
813
* Create hexadecimal codec ID
815
if (has_audio_group && mixer->chip_name == NULL)
816
if ((mixer->chip_name = PMALLOC (mixer->osdev, 32)) != NULL)
818
sprintf (mixer->chip_name, "0x%08x", a);
824
sprintf (hw_info, " Codec %2d: %s (0x%08x", cad, codecs[ix].name, a);
827
if (has_audio_group && mixer->chip_name == NULL)
829
mixer->chip_name = codecs[ix].name;
833
if (codecs[ix].remap != NULL)
834
codec->remap = codecs[ix].remap;
836
if (codecs[ix].flags != 0)
837
codec->vendor_flags = codecs[ix].flags;
839
if (codecs[ix].mixer_init != NULL)
840
codec->mixer_init = codecs[ix].mixer_init;
842
codec->multich_map = codecs[ix].multich_map;
843
codec->codec_desc = &codecs[ix];
846
if (corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_REVISION, &a, &b))
848
DDB (cmn_err (CE_CONT, "HDA codec revision %d.%d (%d.%d) (0x%08x)\n",
850
(a >> 16) & 0xf, (a >> 8) & 0xff, a & 0xff, a));
853
DDB (cmn_err (CE_CONT, "Can't get codec revision\n"));
855
DDB (cmn_err (CE_CONT, "**** Codec %d ****\n", cad));
857
(CE_CONT, "First group node %d, num nodes %d\n", first_node,
860
for (i = first_node; i < first_node + num_nodes; i++)
862
corb_read (mixer, cad, i, 0, GET_PARAMETER, HDA_GROUP_TYPE, &a, &b);
863
if ((a & 0xff) == group_type) /* Proper function group type */
867
if (corb_read (mixer, cad, i, 0, GET_SUBSYSTEM_ID, 0, &a, &b))
869
DDB (cmn_err (CE_CONT, "Subsystem ID = 0x%08x\n", a));
873
/* Append subvendor ID to hw_info */
874
hw_info += strlen (hw_info);
875
sprintf (hw_info, "/0x%08x", a);
878
codec->subvendor_id = a;
881
for (subix = 0; subdevices[subix].id != 0; subix++)
882
if (subdevices[subix].id == a)
884
if (subdevices[subix].main_id != 0)
885
if (subdevices[subix].main_id != codec->vendor_id)
888
if (subdevices[subix].pci_subdevice != 0)
889
if (subdevices[subix].pci_subdevice != pci_subdevice)
894
(CE_CONT, "Subdevice known as %s\n",
895
subdevices[subix].name));
898
hw_info += strlen (hw_info);
899
sprintf (hw_info, " %s", subdevices[subix].name);
901
if (subdevices[subix].remap != NULL)
903
codec->remap = subdevices[subix].remap;
906
if (subdevices[subix].multich_map != 0)
907
codec->multich_map = subdevices[subix].multich_map;
908
if (subdevices[subix].flags != 0)
909
codec->vendor_flags = subdevices[subix].flags;
910
if (subdevices[subix].mixer_init != NULL)
912
codec->mixer_init = subdevices[subix].mixer_init;
921
hw_info += strlen (hw_info);
923
strcpy (hw_info, ")\n");
925
for (i = first_node; i < first_node + num_nodes; i++)
927
if (!attach_function_group (mixer, cad, i, group_type))
930
/* power up the AFG! */
931
corb_write (mixer, cad, i, 0, SET_POWER_STATE, 0);
937
polish_widget_list (mixer, cad);
940
copy_endpoints (mixer, codec, 0); /* Copy analog endpoints from codec to mixer */
943
return (has_audio_group) ? 0 : -EIO;
947
follow_path(hdaudio_mixer_t *mixer, codec_t *codec, widget_t *widget, path_t *path, int use_force)
955
path->widgets[path->nwidgets++] = widget;
956
if (widget->wid_type == NT_PIN)
959
path->association=widget->association;
960
path->sequence=widget->sequence;
963
* Stop at a pin widget that is not the first widget of the path.
964
* In this way we don't walk back the input chain from the pin.
967
if (path->nwidgets > 1)
971
if (use_force || path->nwidgets == 1 || widget->nconn == 1 || (widget->nconn>0 && widget->wid_type == NT_SELECT))
973
for (i=0;i<widget->nconn;i++)
974
if (!codec->widgets[widget->connections[i]].used)
975
//if (codec->widgets[widget->connections[i]].refcount < 2)
977
follow_path(mixer, codec, &codec->widgets[widget->connections[i]], path, use_force);
984
dump_path(hdaudio_mixer_t *mixer, path_t *path)
988
if (path->nwidgets == 0)
991
printf("Path (a=%x, s=%x, jc=%d):\n ", path->association, path->sequence, path->jack_count);
993
for (i=0;i<path->nwidgets;i++)
995
widget_t *widget = path->widgets[i];
997
printf("\t%02x(%s/%s/nc=%d/rc=%d", widget->wid, widget_id[widget->wid_type], widget->name, widget->nconn, widget->refcount);
1000
if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
1002
printf("\t\tOutput amp\n");
1005
if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
1007
printf("\t\t%d input amp(s)\n", widget->nconn);
1009
for (j=0;j<widget->nconn;j++)
1011
widget_t *in_widget;
1013
in_widget = &mixer->codecs[widget->cad]->
1014
widgets[widget->connections[j]];
1015
printf("\t\t\t%02x(%s/%s/nc=%d/rc=%d)\n", in_widget->wid, widget_id[in_widget->wid_type], in_widget->name, in_widget->nconn, in_widget->refcount);
1025
store_path(hdaudio_mixer_t *mixer, path_t *path)
1027
if (npaths>=MAX_PATHS)
1029
cmn_err(CE_WARN, "Too many paths\n");
1033
paths[npaths++]=path;
1037
create_path_list(hdaudio_mixer_t *mixer, int cad, int node_type, int use_force)
1044
cmn_err(CE_CONT, "Create path list %d (%s)\n", node_type, widget_id[node_type]);
1045
codec=mixer->codecs[cad];
1047
for (wid=0;wid<codec->nwidgets;wid++)
1048
if (codec->widgets[wid].wid_type == node_type)
1049
if (!codec->widgets[wid].skip)
1050
if (codec->widgets[wid].wid == wid)
1052
path=malloc(sizeof(*path));
1054
follow_path(mixer, codec, &codec->widgets[wid], path, use_force);
1056
if (path->nwidgets>1)
1057
store_path(mixer, path);
1059
if (path->nwidgets>0)
1060
path->widgets[0]->used=0;
1066
create_path_list_for_pin(hdaudio_mixer_t *mixer, int cad, int association, int sequence)
1073
codec=mixer->codecs[cad];
1075
for (wid=0;wid<codec->nwidgets;wid++)
1076
if (codec->widgets[wid].wid_type == NT_PIN && !codec->widgets[wid].skip)
1077
if (codec->widgets[wid].pin_type == PIN_HEADPHONE || codec->widgets[wid].pin_type == PIN_OUT)
1078
if (codec->widgets[wid].wid == wid)
1079
if (codec->widgets[wid].nconn > 0)
1080
if (!codec->widgets[wid].skip)
1081
if (codec->widgets[wid].sequence == sequence)
1082
if (codec->widgets[wid].association == association)
1084
path=malloc(sizeof(*path));
1086
follow_path(mixer, codec, &codec->widgets[wid], path, 0);
1088
if (path->nwidgets>1)
1089
store_path(mixer, path);
1091
if (path->nwidgets>0)
1092
path->widgets[0]->used=0;
1098
hdaudio_mixer_create (char *name, void *devc,
1099
oss_device_t * osdev,
1100
hdmixer_write_t writefunc,
1101
hdmixer_read_t readfunc, unsigned int codecmask,
1102
unsigned int vendor_id, unsigned int subvendor_id)
1104
hdaudio_mixer_t *mixer;
1110
char *hw_info = osdev->hw_info; /* For printing hardware information */
1112
if ((mixer = PMALLOC (osdev, sizeof (*mixer))) == NULL)
1114
cmn_err (CE_WARN, "hdaudio_mixer_create: Out of memory\n");
1118
memset (mixer, 0, sizeof (*mixer));
1121
mixer->osdev = osdev;
1122
mixer->mixer_dev = 0;
1123
strncpy (mixer->name, name, sizeof (mixer->name) - 1);
1124
mixer->name[sizeof (mixer->name) - 1] = 0;
1126
for (i = 0; i < MAX_CODECS; i++)
1127
mixer->codecs[i] = NULL;
1130
mixer->read = readfunc;
1131
mixer->write = writefunc;
1134
mixer->codecmask = codecmask;
1136
sprintf (hw_info, "HD Audio controller %s\n"
1137
"Vendor ID 0x%08x\n"
1138
"Subvendor ID 0x%08x\n", name, vendor_id, subvendor_id);
1139
hw_info += strlen (hw_info);
1142
* Search first all audio function groups for all codecs and then
1143
* handle modem function groups.
1145
for (func = 1; func <= 2; func++)
1146
for (i = 0; i < 16; i++)
1147
if (mixer->codecmask & (1 << i))
1149
if (attach_codec (mixer, i, hw_info, subvendor_id, func) >= 0)
1151
hw_info += strlen (hw_info);
1154
for (i = 0; i < 16; i++)
1155
if (mixer->codecmask & (1 << i))
1157
int association, sequence;
1159
printf("*** Codec %d\n", i);
1160
for (association=1;association<16;association++)
1161
for (sequence=0;sequence<16;sequence++)
1162
create_path_list_for_pin(mixer, i, association, sequence);
1164
create_path_list(mixer, i, NT_ADC, 0);
1165
create_path_list(mixer, i, NT_MIXER, 1);
1166
create_path_list(mixer, i, NT_SELECT, 1);
1169
for (i=0;i<npaths;i++)
1170
dump_path(mixer, paths[i]);
1173
printf("\n\nOther widgets:\n");
1175
for (i = 0; i < 16; i++)
1176
if (mixer->codecmask & (1 << i))
1180
for (wid=0;wid<mixer->codecs[i]->nwidgets;wid++)
1182
widget_t *widget = &mixer->codecs[i]->widgets[wid];
1184
if (widget->wid != wid)
1187
if (widget->used || widget->skip)
1189
printf("Codec %d, Widget %02x %s/%s/%d\n", widget->cad, widget->wid, widget_id[widget->wid_type], widget->name, widget->nconn);
1198
main (int argc, char *argv[])
1200
unsigned int rev, b;
1201
int first_node, num_nodes;
1207
oss_device_t osdev = { 0 };
1209
osdev.hw_info = malloc (256);
1211
if ((fd = open ("/dev/oss/oss_hdaudio0/pcm0", O_RDWR | O_EXCL, 0)) == -1)
1213
perror ("/dev/oss/oss_hdaudio0/pcm0");
1217
for (cad = 0; cad < 15; cad++)
1218
if (corb_read (NULL, cad, 0, 0, GET_PARAMETER, HDA_REVISION, &rev, &b))
1221
printf ("Codec %2d: HD codec revision %d.%d (%d.%d) (0x%08x)\n", cad,
1222
(rev >> 20) & 0xf, (rev >> 16) & 0xf, (rev >> 8) & 0xff,
1225
codecmask |= (1 << cad);
1228
hdaudio_mixer_create ("ACME hdaudio", NULL,
1229
&osdev, NULL, NULL, codecmask, 0x12345678, 0x8754321);
1231
//printf("HW Info: %s\n", osdev.hw_info);