~ubuntu-branches/ubuntu/wily/oss4/wily

« back to all changes in this revision

Viewing changes to utils/mixgen.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis, Samuel Thibault, Romain Beauxis, Sebastien NOEL
  • Date: 2011-06-14 10:06:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110614100656-cx4oc7u426zn812z
Tags: 4.2-build2004-1
[ Samuel Thibault ]
* debian/control: Add liboss4-salsa2, liboss4-salsa-dev and
  liboss4-salsa-asound2 packages, equivalent to (and will replace) those from
  the oss-libsalsa package (Closes: #589127).
* debian/patches/liboss4-salsa.patch: New patch to rename libsalsa into
  liboss4-salsa to avoid conflicts in the archive for no good reason.
* debian/rules: Make in libOSSlib and libsalsa.
* debian/liboss4-salsa-dev.install, debian/liboss4-salsa2.install,
  debian/liboss4-salsa-asound2.links, debian/liboss4-salsa-dev.links:
  Install liboss4-salsa libraries like was done in the oss-libsalsa package.
* include-alsa: Add a copy of ALSA 1.0.5 headers: Cf ALSA_1.0.* symbols in
  libsalsa, this is the roughly supported version.
* debian/copyright: Update for new include-alsa files.
* alsa.pc: New file for compatibility with libasound-dev.
* debian/control:
  - Add Vcs-Browser and Vcs-Svn fields.
  - Use linux-any instead of the list of Linux archs (Closes: #604679).
  - Make dkms dependency linux-any only.
* debian/patches/hurd_iot.patch: New patch to fix soundcard.h usage in
  libsalsa on hurd-i386.
* debian/patches/libsalsa_fixes.patch: New patch to fix some printf usages
  and ioctl declaration in libsalsa.
* debian/patches/no_EBADE.patch: New patch to cope with hurd-i386 not having
  EBADE.
* debian/patches/CFLAGS.patch: New patch to make oss4 take debian/rules
  CFLAGS into account.
* debian/patches/snd_asoundlib_version.patch: New patch to add
  snd_asoundlib_version().
* debian/patches/generic_srccconf.patch: New patch to fix source
  configuration on unknown archs.

[ Romain Beauxis ]
* Fixed README.Debian to only mention dkms' modules.
* Switch to dpkg-source 3.0 (quilt) format
* Added DM-Upload-Allowed: yes

[ Sebastien NOEL ]
* New upstream release (Closes: #595298, #619272).
* Fix typo in initscript (Closes: #627149).
* debian/control: adjust linux-headers dependencies (Closes: #628879).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <stdio.h>
 
3
#include <stdlib.h>
 
4
#include <unistd.h>
 
5
#include <fcntl.h>
 
6
#include <sys/ioctl.h>
 
7
#include <errno.h>
 
8
#include <string.h>
 
9
#include <soundcard.h>
 
10
 
 
11
typedef int sound_os_info, mixer_create_controls_t, oss_device_t;
 
12
 
 
13
#include <hdaudio.h>
 
14
 
 
15
#define ioctl_arg int
 
16
#define mixer_ext_init_fn int
 
17
#include <hdaudio_codec.h>
 
18
 
 
19
static int num_widgets = 0;
 
20
 
 
21
static int print_widgets = 0;
 
22
 
 
23
typedef struct
 
24
{
 
25
  int type;
 
26
  int valid;
 
27
  int used;
 
28
 
 
29
  char name[32];
 
30
 
 
31
  unsigned int wcaps;
 
32
  unsigned int pincaps;
 
33
  unsigned int inamp_caps;
 
34
  unsigned int outamp_caps;
 
35
  int nconn;
 
36
  int connections[MAX_CONN];
 
37
  widget_t widget_info;
 
38
} mixgen_widget_t;
 
39
 
 
40
static mixgen_widget_t widgets[256] = { {0} };
 
41
 
 
42
static int errors = 0;
 
43
 
 
44
static unsigned int default_outamp_caps = 0;
 
45
static unsigned int default_inamp_caps = 0;
 
46
static unsigned int subdevice = 0;
 
47
 
 
48
#undef corb_read
 
49
#undef corb_write
 
50
 
 
51
int fd;
 
52
void *mixer = NULL;
 
53
int trace = 0;
 
54
 
 
55
int cad = -1;
 
56
 
 
57
int
 
58
corb_write (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
 
59
            unsigned int verb, unsigned int parm)
 
60
{
 
61
  unsigned int tmp;
 
62
 
 
63
  tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
 
64
  if (trace)
 
65
    printf ("WRITE %08x\n", tmp);
 
66
 
 
67
  if (ioctl (fd, HDA_IOCTL_WRITE, &tmp) == -1)
 
68
    {
 
69
      /* perror("HDA_IOCTL_WRITE"); */
 
70
      return 0;
 
71
    }
 
72
 
 
73
  return 1;
 
74
}
 
75
 
 
76
static int
 
77
corb_read (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
 
78
           unsigned int verb, unsigned int parm, unsigned int *upper,
 
79
           unsigned int *lower)
 
80
{
 
81
  unsigned int tmp;
 
82
 
 
83
  tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | parm;
 
84
 
 
85
  if (ioctl (fd, HDA_IOCTL_READ, &tmp) == -1)
 
86
    {
 
87
      /* perror("HDA_IOCTL_READ"); */
 
88
      if (errno == EINVAL)
 
89
        {
 
90
          fprintf (stderr, "hdaudio_snoopy mode is not available\n");
 
91
          exit (-1);
 
92
        }
 
93
      return 0;
 
94
    }
 
95
 
 
96
  *upper = tmp;
 
97
  *lower = 0;
 
98
  if (trace)
 
99
    printf ("READ %08x\n", tmp);
 
100
 
 
101
  return 1;
 
102
}
 
103
 
 
104
static int
 
105
set_error (char *msg)
 
106
{
 
107
  fprintf (stderr, "%s");
 
108
  errors++;
 
109
 
 
110
  return 0;
 
111
}
 
112
 
 
113
static int
 
114
gen_amps (mixgen_widget_t * widget, int wid)
 
115
{
 
116
  int i;
 
117
  char *name;
 
118
 
 
119
  if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
 
120
    {
 
121
      if (widget->outamp_caps & ~AMPCAP_MUTE)   /* Has gain control */
 
122
        {
 
123
          name = "-";
 
124
          if (widget->type == NT_PIN)
 
125
            name = "invol";
 
126
          printf ("\t\tHDA_OUTAMP(0x%02x, group, \"%s\", 90);\n", wid, name);
 
127
        }
 
128
      else if (widget->outamp_caps & AMPCAP_MUTE)       /* Only mute control */
 
129
        {
 
130
          name = "mute";
 
131
          if (widget->type == NT_PIN)
 
132
            name = "inmute";
 
133
          printf ("\t\tHDA_OUTMUTE(0x%02x, group, \"%s\", UNMUTE);\n", wid,
 
134
                  name);
 
135
        }
 
136
    }
 
137
 
 
138
  if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
 
139
    {
 
140
      int n = widget->nconn;
 
141
      if (widget->type == NT_PIN)
 
142
        n = 1;
 
143
 
 
144
      if (n > 1 && !(widget->inamp_caps & ~AMPCAP_MUTE))
 
145
        {                       /* Create mute group */
 
146
          printf ("\t\t{\n");
 
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++)
 
150
            {
 
151
              char *name;
 
152
 
 
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;
 
156
              printf
 
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]);
 
159
            }
 
160
          printf ("\t\t}\n");
 
161
        }
 
162
      else
 
163
        {
 
164
          for (i = 0; i < n; i++)
 
165
            {
 
166
              char *name;
 
167
 
 
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)
 
172
                name = "out";
 
173
              if (widget->inamp_caps & ~AMPCAP_MUTE)    /* Has gain control */
 
174
                {
 
175
                  printf
 
176
                    ("\t\tHDA_INAMP(0x%02x, %d, group, \"%s\", 90);\t/* From widget 0x%02x */\n",
 
177
                     wid, i, name, widget->connections[i]);
 
178
                }
 
179
              else
 
180
                {
 
181
                  printf
 
182
                    ("\t\tHDA_INMUTE(0x%02x, %d, group, \"%smute\", UNMUTE);\t/* From widget 0x%02x */\n",
 
183
                     wid, i, name, widget->connections[i]);
 
184
                }
 
185
            }
 
186
        }
 
187
    }
 
188
 
 
189
  return 0;
 
190
}
 
191
 
 
192
static int
 
193
follow_widget_chain (int wid, int force)
 
194
{
 
195
  int i;
 
196
  char choice_list[1024] = "", *s = choice_list;
 
197
  mixgen_widget_t *widget;
 
198
 
 
199
  if (!widgets[wid].valid || widgets[wid].used)
 
200
    return 0;
 
201
 
 
202
  widget = &widgets[wid];
 
203
 
 
204
  if (widget->widget_info.refcount > 1 && !force)
 
205
    return 0;
 
206
 
 
207
  widget->used = 1;
 
208
 
 
209
  printf ("\n\t\t/* Widget 0x%02x (%s) */\n", wid, widget->name);
 
210
 
 
211
  for (i = 0; i < widget->nconn; i++)
 
212
    {
 
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;
 
216
      if (i > 0)
 
217
        *s++ = ' ';
 
218
      if (widget->connections[i] < num_widgets)
 
219
        strcpy (s, widgets[widget->connections[i]].name);
 
220
      else
 
221
        strcpy (s, "unknown");
 
222
      printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i], name);
 
223
      s += strlen (s);
 
224
    }
 
225
 
 
226
  if (widget->type == NT_SELECT && widget->nconn > 1)
 
227
    {
 
228
      printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
 
229
      printf ("\t\t   {\n");
 
230
      printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
 
231
      printf ("\t\t   }\n");
 
232
    }
 
233
 
 
234
  gen_amps (widget, wid);
 
235
/*
 
236
 * Follow the input connection chain.
 
237
 */
 
238
  if (widget->nconn == 1)
 
239
    follow_widget_chain (widget->connections[0], force);
 
240
 
 
241
  return 0;
 
242
}
 
243
 
 
244
static int
 
245
handle_pin_widget (int wid, mixgen_widget_t * widget)
 
246
{
 
247
  int outselects = 0, inselects = 0, num_amps = 0;
 
248
  char choice_list[1024] = "", *s = choice_list;
 
249
  int i;
 
250
 
 
251
  widget->used = 1;
 
252
 
 
253
  if (widget->pincaps & PINCAP_INPUT_CAPABLE)
 
254
    {
 
255
      if (!(widget->wcaps & WCAP_DIGITAL))      /* Analog pin */
 
256
        {
 
257
          inselects = 1;
 
258
        }
 
259
    }
 
260
 
 
261
  if (widget->pincaps & PINCAP_OUTPUT_CAPABLE)
 
262
    {
 
263
      if (!(widget->wcaps & WCAP_DIGITAL))      /* Analog pin */
 
264
        {
 
265
          outselects = widget->nconn;
 
266
        }
 
267
    }
 
268
 
 
269
  if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
 
270
    {
 
271
      num_amps += widget->nconn;
 
272
    }
 
273
 
 
274
  if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
 
275
    {
 
276
      num_amps++;
 
277
    }
 
278
 
 
279
  if (inselects + outselects + num_amps == 0)
 
280
    return 0;
 
281
 
 
282
  printf
 
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);
 
285
  printf ("\t   {\n");
 
286
 
 
287
  for (i = 0; i < widget->nconn; i++)
 
288
    {
 
289
      if (i > 0)
 
290
        *s++ = ' ';
 
291
 
 
292
      if (widget->connections[i] < num_widgets)
 
293
        sprintf (s, "%s-out", widgets[widget->connections[i]].name);
 
294
      else
 
295
        strcpy (s, "unknown");
 
296
      printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
 
297
              widgets[widget->connections[i]].name);
 
298
      s += strlen (s);
 
299
    }
 
300
 
 
301
  if (widget->nconn > 0)
 
302
    *s++ = ' ';
 
303
  sprintf (s, "input");
 
304
  s += strlen (s);
 
305
 
 
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);
 
308
 
 
309
  gen_amps (widget, wid);
 
310
 
 
311
  for (i = 0; i < widget->nconn; i++)
 
312
    follow_widget_chain (widget->connections[i], 0);
 
313
 
 
314
  printf ("\t   }\n");
 
315
 
 
316
  return 0;
 
317
}
 
318
 
 
319
static int
 
320
handle_adc_widget (int wid, mixgen_widget_t * widget)
 
321
{
 
322
  int outselects = 0, inselects = 0, num_amps = 0;
 
323
  char choice_list[4000] = "", *s = choice_list;
 
324
  int i;
 
325
 
 
326
  widget->used = 1;
 
327
 
 
328
  if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
 
329
    {
 
330
      num_amps += widget->nconn;
 
331
    }
 
332
 
 
333
  if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
 
334
    {
 
335
      num_amps++;
 
336
    }
 
337
 
 
338
  printf
 
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);
 
341
  printf ("\t   {\n");
 
342
 
 
343
  for (i = 0; i < widget->nconn; i++)
 
344
    {
 
345
      if (i > 0)
 
346
        *s++ = ' ';
 
347
      if (widget->connections[i] < num_widgets)
 
348
        strcpy (s, widgets[widget->connections[i]].name);
 
349
      else
 
350
        strcpy (s, "unknown");
 
351
      printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
 
352
              widgets[widget->connections[i]].name);
 
353
      s += strlen (s);
 
354
    }
 
355
 
 
356
  if (widget->nconn > 1)
 
357
    {
 
358
      printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
 
359
      printf ("\t\t   {\n");
 
360
      printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
 
361
      printf ("\t\t   }\n");
 
362
    }
 
363
 
 
364
  gen_amps (widget, wid);
 
365
 
 
366
  for (i = 0; i < widget->nconn; i++)
 
367
    follow_widget_chain (widget->connections[i], 0);
 
368
 
 
369
  printf ("\t   }\n");
 
370
 
 
371
  return 0;
 
372
}
 
373
 
 
374
static int
 
375
handle_misc_widget (int wid, mixgen_widget_t * widget)
 
376
{
 
377
  int outselects = 0, inselects = 0, num_amps = 0;
 
378
  char choice_list[4000] = "", *s = choice_list;
 
379
  int i;
 
380
 
 
381
  widget->used = 1;
 
382
 
 
383
  if (widget->wcaps & WCAP_INPUT_AMP_PRESENT)
 
384
    {
 
385
      num_amps += widget->nconn;
 
386
    }
 
387
 
 
388
  if (widget->wcaps & WCAP_OUTPUT_AMP_PRESENT)
 
389
    {
 
390
      num_amps++;
 
391
    }
 
392
 
 
393
  if (num_amps == 0)
 
394
    return 0;
 
395
 
 
396
  printf
 
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);
 
399
  printf ("\t   {\n");
 
400
 
 
401
  for (i = 0; i < widget->nconn; i++)
 
402
    {
 
403
      if (i > 0)
 
404
        *s++ = ' ';
 
405
      if (widget->connections[i] < num_widgets)
 
406
        strcpy (s, widgets[widget->connections[i]].name);
 
407
      else
 
408
        strcpy (s, "unknown");
 
409
      printf ("\t\t/* Src 0x%x=%s */\n", widget->connections[i],
 
410
              widgets[widget->connections[i]].name);
 
411
      s += strlen (s);
 
412
    }
 
413
 
 
414
  if (widget->type == NT_SELECT && widget->nconn > 1)
 
415
    {
 
416
      printf ("\t\tif (HDA_SELECT(0x%02x, \"src\", ctl, group, -1))\n", wid);
 
417
      printf ("\t\t   {\n");
 
418
      printf ("\t\t\tHDA_CHOICES(ctl, \"%s\");\n", choice_list);
 
419
      printf ("\t\t   }\n");
 
420
    }
 
421
 
 
422
  gen_amps (widget, wid);
 
423
 
 
424
  for (i = 0; i < widget->nconn; i++)
 
425
    follow_widget_chain (widget->connections[i], 1);
 
426
 
 
427
  printf ("\t   }\n");
 
428
 
 
429
  return 0;
 
430
}
 
431
 
 
432
static int
 
433
attach_widget (int wid)
 
434
{
 
435
  hda_name_t name;
 
436
  hda_widget_info_t info;
 
437
  unsigned int wcaps, b;
 
438
  mixgen_widget_t *widget = &widgets[wid];
 
439
  int type;
 
440
  int i;
 
441
  unsigned int nconn, connections[256];
 
442
 
 
443
  memset (&name, 0, sizeof (name));
 
444
  memset (&info, 0, sizeof (info));
 
445
 
 
446
  name.cad = cad;
 
447
  name.wid = wid;
 
448
  if (ioctl (fd, HDA_IOCTL_NAME, &name) == -1)
 
449
    strcpy (name.name, "Unknown_widget");
 
450
 
 
451
  info.cad = cad;
 
452
  info.wid = wid;
 
453
  if (ioctl (fd, HDA_IOCTL_WIDGET, &info) != -1)
 
454
    memcpy (&widget->widget_info, info.info, sizeof (widget->widget_info));
 
455
 
 
456
  if (!corb_read
 
457
      (mixer, cad, wid, 0, GET_PARAMETER, HDA_WIDGET_CAPS, &wcaps, &b))
 
458
    return set_error ("Can't get widget capabilities\n");
 
459
 
 
460
  type = (wcaps >> 20) & 0xf;
 
461
 
 
462
  if (type == NT_PIN)
 
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");
 
466
 
 
467
  widget->valid = 1;
 
468
  strcpy (widget->name, name.name);
 
469
  widget->wcaps = wcaps;
 
470
  widget->inamp_caps = default_inamp_caps;
 
471
  widget->outamp_caps = default_outamp_caps;
 
472
  widget->type = type;
 
473
 
 
474
  /*
 
475
   * Handle connection list.
 
476
   */
 
477
  nconn = 0;
 
478
  if (wcaps & WCAP_CONN_LIST)
 
479
    {
 
480
 
 
481
      if (corb_read
 
482
          (mixer, cad, wid, 0, GET_PARAMETER, HDA_CONNLIST_LEN, &nconn, &b))
 
483
 
 
484
        if (nconn >= MAX_CONN)
 
485
          {
 
486
            fprintf (stderr,
 
487
                     "Too many input connections (%d) for widget %d\n", nconn,
 
488
                     wid);
 
489
            exit (-1);
 
490
          }
 
491
      if (nconn != 0)
 
492
        {
 
493
          unsigned int clist;
 
494
          int j;
 
495
          int n = 0;
 
496
 
 
497
          nconn &= 0x7f;
 
498
 
 
499
          for (i = 0; i < nconn; i += 4)
 
500
            if (corb_read
 
501
                (mixer, cad, wid, 0, GET_CONNECTION_LIST_ENTRY, i, &clist,
 
502
                 &b))
 
503
              for (j = 0; j < 4 && (i + j) < nconn; j++)
 
504
                {
 
505
                  connections[n++] = (clist >> (j * 8)) & 0xff;
 
506
                }
 
507
        }
 
508
    }
 
509
 
 
510
  for (i = 0; i < nconn; i++)
 
511
    widget->connections[i] = connections[i];
 
512
  widget->nconn = nconn;
 
513
 
 
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))
 
518
      {
 
519
        fprintf (stderr, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
 
520
        return set_error ("Can't get outamp capabilities\n");
 
521
      }
 
522
 
 
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))
 
527
      {
 
528
        fprintf (stderr, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
 
529
        return set_error ("Can't get inamp capabilities\n");
 
530
      }
 
531
 
 
532
  return 0;
 
533
}
 
534
 
 
535
static void
 
536
dump_node (int wid)
 
537
{
 
538
  int i;
 
539
  unsigned int a, b, gtype, gcaps, wcaps, sizes, fmts, pincaps;
 
540
  unsigned int inamp_caps, outamp_caps, clen, pstates, pcaps, gpio_count;
 
541
  unsigned int vkcaps;
 
542
  int first_node = 0, num_nodes = 0;
 
543
  char *s;
 
544
  int ntype = -1;
 
545
 
 
546
  if (corb_read
 
547
      (mixer, cad, wid, 0, GET_PARAMETER, HDA_GROUP_TYPE, &gtype, &b))
 
548
    if ((gtype & 0x1ff) != 0)
 
549
      {
 
550
        s = "Unknown";
 
551
 
 
552
        switch (gtype & 0xff)
 
553
          {
 
554
          case 0:
 
555
            s = "Reserved";
 
556
            return;
 
557
            break;
 
558
          case 1:
 
559
            s = "Audio function group";
 
560
            break;
 
561
          case 2:
 
562
            s = "Vendor defined modem function group";
 
563
            //return;
 
564
            break;
 
565
          }
 
566
 
 
567
      }
 
568
  if (corb_read (mixer, cad, wid, 0, GET_SUBSYSTEM_ID, 0, &a, &b))
 
569
    {
 
570
      printf ("/* Subsystem ID %08x */\n", a);
 
571
      subdevice = a;
 
572
    }
 
573
 
 
574
  if (!corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
 
575
    {
 
576
      fprintf (stderr, "GET_PARAMETER HDA_NODE_COUNT2 failed\n");
 
577
      return;
 
578
    }
 
579
 
 
580
  if (!corb_read (mixer, cad, wid, 0,
 
581
                  GET_PARAMETER, HDA_OUTPUTAMP_CAPS,
 
582
                  &default_outamp_caps, &b))
 
583
    {
 
584
      fprintf (stderr, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
 
585
      return;
 
586
    }
 
587
 
 
588
  if (!corb_read (mixer, cad, wid, 0,
 
589
                  GET_PARAMETER, HDA_INPUTAMP_CAPS, &default_inamp_caps, &b))
 
590
    {
 
591
      fprintf (stderr, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
 
592
      return;
 
593
    }
 
594
 
 
595
  printf ("/* Default amplifier caps: in=%08x, out=%08x */\n",
 
596
          default_inamp_caps, default_outamp_caps);
 
597
 
 
598
  first_node = (a >> 16) & 0xff;
 
599
  num_nodes = a & 0xff;
 
600
 
 
601
  for (wid = first_node; wid < first_node + num_nodes; wid++)
 
602
    {
 
603
      attach_widget (wid);
 
604
      if (wid >= num_widgets)
 
605
        num_widgets = wid + 1;
 
606
    }
 
607
}
 
608
 
 
609
static void
 
610
dump_widgets (void)
 
611
{
 
612
  int i;
 
613
 
 
614
  for (i = 0; i < num_widgets; i++)
 
615
    {
 
616
      if (widgets[i].valid)
 
617
        {
 
618
          if (widgets[i].name[0] == 0) /* Empty string */
 
619
             printf("\tES,\n");
 
620
          else
 
621
             printf ("\t\"%s\",\t\t/* 0x%02x */\n", widgets[i].name, i);
 
622
        }
 
623
      else
 
624
        printf ("\tES,\t\t/* 0x%02x */\n", i);
 
625
    }
 
626
}
 
627
 
 
628
int
 
629
main (int argc, char *argv[])
 
630
{
 
631
  unsigned int a, b;
 
632
  int first_node, num_nodes;
 
633
  int i;
 
634
  char codec_name[32] = "";
 
635
 
 
636
  if (argc > 1)
 
637
    strcpy (codec_name, argv[1]);
 
638
 
 
639
  if ((fd = open ("/dev/oss/oss_hdaudio0/pcm0", O_RDWR | O_EXCL, 0)) == -1)
 
640
    {
 
641
      perror ("/dev/oss/oss_hdaudio0/pcm0");
 
642
      exit (-1);
 
643
    }
 
644
 
 
645
  if (argc > 2)
 
646
    cad = atoi (argv[2]);
 
647
 
 
648
  for (i = 3; i < argc; i++)
 
649
    switch (argv[i][0])
 
650
      {
 
651
      case 'w':
 
652
        print_widgets = 1;
 
653
        break;
 
654
      }
 
655
 
 
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))
 
659
        break;
 
660
  printf
 
661
/*
 
662
 *
 
663
 * This file is part of Open Sound System.
 
664
 *
 
665
 * Copyright (C) 4Front Technologies 1996-2008.
 
666
 *
 
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.
 
670
 *
 
671
 */
 
672
 
 
673
  printf ("/* Codec index is %d */\n", cad);
 
674
  printf ("/* Codec vendor %04x:%04x */\n", a >> 16, a & 0xffff);
 
675
 
 
676
  if (corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_REVISION, &a, &b))
 
677
    {
 
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);
 
680
    }
 
681
  else
 
682
    printf ("hdaudio: Can't get codec revision\n");
 
683
 
 
684
/*
 
685
 * Find out the primary group list
 
686
 */
 
687
 
 
688
  if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
 
689
    exit(1);
 
690
 
 
691
  first_node = (a >> 16) & 0xff;
 
692
  num_nodes = a & 0xff;
 
693
 
 
694
  for (i = first_node; i < first_node + num_nodes; i++)
 
695
    dump_node (i);
 
696
 
 
697
/*
 
698
 * Next produce the output
 
699
 */
 
700
 
 
701
  if (*codec_name == 0)
 
702
    sprintf (codec_name, "subdevice%08x", subdevice);
 
703
 
 
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");
 
708
  printf ("\n");
 
709
 
 
710
  printf ("int\n");
 
711
  printf
 
712
    ("hdaudio_%s_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)\n",
 
713
     codec_name);
 
714
  printf ("{\n");
 
715
  //printf ("  int wid;\n");
 
716
  printf ("  int ctl=0;\n");
 
717
  //printf ("  codec_t *codec = mixer->codecs[cad];\n");
 
718
 
 
719
  printf ("\n");
 
720
  printf
 
721
    ("  DDB(cmn_err(CE_CONT, \"hdaudio_%s_mixer_init got called.\\n\"));\n",
 
722
     codec_name);
 
723
  printf ("\n");
 
724
 
 
725
/*
 
726
 * Handle PIN widgets first
 
727
 */
 
728
  printf ("  /* Handle PIN widgets */\n");
 
729
  printf ("  {\n");
 
730
  printf ("\tint n, group, pin_group;\n");
 
731
  printf ("\n\tn=0;\n");
 
732
 
 
733
  printf ("\n\tHDA_GROUP(pin_group, top_group, \"jack\");\n");
 
734
 
 
735
  for (i = 0; i < num_widgets; i++)
 
736
    {
 
737
      mixgen_widget_t *widget = &widgets[i];
 
738
 
 
739
      if (!widget->valid)
 
740
        continue;
 
741
 
 
742
      if (widget->type != NT_PIN)
 
743
        continue;
 
744
 
 
745
      handle_pin_widget (i, widget);
 
746
    }
 
747
  printf ("  }\n");
 
748
 
 
749
/*
 
750
 * Handle ADC widgets
 
751
 */
 
752
  printf ("  /* Handle ADC widgets */\n");
 
753
  printf ("  {\n");
 
754
  printf ("\tint n, group, rec_group;\n");
 
755
  printf ("\n\tn=0;\n");
 
756
 
 
757
  printf ("\n\tHDA_GROUP(rec_group, top_group, \"record\");\n");
 
758
 
 
759
  for (i = 0; i < num_widgets; i++)
 
760
    {
 
761
      mixgen_widget_t *widget = &widgets[i];
 
762
 
 
763
      if (!widget->valid || widget->used)
 
764
        continue;
 
765
 
 
766
      if (widget->type != NT_ADC)
 
767
        continue;
 
768
 
 
769
      handle_adc_widget (i, widget);
 
770
    }
 
771
  printf ("  }\n");
 
772
 
 
773
/*
 
774
 * Handle the remaining widgets
 
775
 */
 
776
  printf ("  /* Handle misc widgets */\n");
 
777
  printf ("  {\n");
 
778
  printf ("\tint n, group, misc_group;\n");
 
779
  printf ("\n\tn=0;\n");
 
780
 
 
781
  printf ("\n\tHDA_GROUP(misc_group, top_group, \"misc\");\n");
 
782
 
 
783
  for (i = 0; i < num_widgets; i++)
 
784
    {
 
785
      mixgen_widget_t *widget = &widgets[i];
 
786
 
 
787
      if (!widget->valid || widget->used)
 
788
        continue;
 
789
 
 
790
      handle_misc_widget (i, widget);
 
791
    }
 
792
  printf ("  }\n");
 
793
 
 
794
  printf ("  return 0;\n");
 
795
  printf ("}\n");
 
796
 
 
797
  if (print_widgets)
 
798
    dump_widgets ();
 
799
  exit (errors);
 
800
}