~ubuntu-branches/ubuntu/oneiric/oss4/oneiric-proposed

« back to all changes in this revision

Viewing changes to kernel/drv/oss_usb/oss_usb.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Rivera
  • Date: 2011-06-16 20:37:48 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110616203748-jbrxik6ql33z54co
Tags: 4.2-build2004-1ubuntu1
* Merge from Debian unstable.
  - Supports our current kernel (LP: #746048)
  Remaining changes:
  - debian/oss4-dkms.dkms.in: s/source/build/ in Kernel headers paths.
* ld-as-needed.patch: Re-order CC arguments to enable building with ld
  --as-needed (LP: #770972)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: Top level USB audio class initialization and mixer functions
 
3
 */
 
4
 
 
5
/*
 
6
 *
 
7
 * This file is part of Open Sound System.
 
8
 *
 
9
 * Copyright (C) 4Front Technologies 1996-2008.
 
10
 *
 
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.
 
14
 *
 
15
 */
 
16
 
 
17
#define KBUILD_MODNAME oss_usb
 
18
#include "oss_config.h"
 
19
#include "ossusb.h"
 
20
 
 
21
 
 
22
static const udi_usb_devinfo known_devices[] = {
 
23
  {0x763, 0x2002, "M Audio USB AudioSport Duo",
 
24
   {
 
25
    {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
 
26
     0x0014},
 
27
    {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
 
28
     0x0014}
 
29
    }
 
30
   },
 
31
  {0x763, 0x2001, "M Audio USB AudioSport Quatro"},
 
32
  {0x763, 0x2805, "M Audio Sonica"},
 
33
  {0x763, 0x2007, "M Audio Sonica Theatre",
 
34
   {
 
35
    {"OFF 24bit_hispeed 16bit_hispeed 16bit_hispeed 24bit_lowspeed 24bit24bit 16bit 16bit OFF OFF", 3},
 
36
    {"OFF 24bit_hispeed 16bit_hispeed 24bit 16bit_lowspeed", 2}
 
37
    }
 
38
   },
 
39
  {0x763, 0x200d, "M Audio OmniStudio USB"},
 
40
  {0x41e, 0x3000, "Creative Sound Blaster Extigy"},
 
41
  {0x41e, 0x3010, "Creative Sound Blaster MP3+"},
 
42
  {0x41e, 0x3020, "Creative Audigy2 NX USB",
 
43
   {
 
44
    {"OFF 16bit22kHz 16bit44kHz "       /* 0-2 */
 
45
     "24bit44kHz 16bit48kHz 24bit48kHz "        /* 3-5 */
 
46
     "16bit96kHz 24bit96kHz 16bit22kHz "        /* 6-8 */
 
47
     "16bit48kHz 24bit48kHz 16bit5.1ch22kHz "   /* 9-11 */
 
48
     "16bit5.1ch48kHz 24bit5.1ch48kHz 16bit7.1ch22kHz " /* 12-14 */
 
49
     "16bit7.1ch48kHz" /* 15 */ , 4},
 
50
 
 
51
    {"OFF 16bit32kHz 24bit32kHz "       /* 0-2 */
 
52
     "16bit44kHz 24bit44kHz 16bit48kHz "        /* 3-5 */
 
53
     "24bit48kHzin 24bit96kHz 24bit96kHz ",     /* 6-8 */
 
54
     5}
 
55
    }
 
56
   },
 
57
  {0x46d, 0x8b2, "Logitec Quickcam Pro 4000 (mic)"},
 
58
  {0x46d, 0xa01, "Logitec USB Headset"},
 
59
  {0x0471, 0x0311, "Philips ToUcam Pro (mic)"},
 
60
  {0x672, 0x1041, "Labtec LCS1040 Speaker System"},
 
61
  {0x6f8, 0xc000, "Hercules Gamesurround MUSE Pocket"},
 
62
  {0x0d8c, 0x000c, "C-Media USB audio"},
 
63
  {0x0d8c, 0x0102, "C-Media 2/4/6/8ch USB audio",
 
64
   {
 
65
    {"OFF 7.1 2.0 3.1 5.1 digital", 2},
 
66
    {"OFF stereo"}
 
67
    }
 
68
   },
 
69
  {0x0d8c, 0x0103, "C-Media USB audio"},
 
70
  {-1, -1, "USB sound device"}
 
71
};
 
72
 
 
73
typedef struct
 
74
{
 
75
  unsigned int devid;
 
76
  special_driver_t driver;
 
77
}
 
78
special_table_t;
 
79
 
 
80
extern int usb_mixerstyle;
 
81
 
 
82
#define MAX_DEVC        10
 
83
static ossusb_devc *devc_list[MAX_DEVC];
 
84
static int ndevs = 0;
 
85
int usb_quiet = 0;
 
86
 
 
87
 
 
88
void
 
89
ossusb_dump_desc (unsigned char *desc, int cfg_len)
 
90
{
 
91
  int i;
 
92
 
 
93
  for (i = 0; i < cfg_len; i++)
 
94
    {
 
95
      if (!(i % 16))
 
96
        cmn_err (CE_CONT, "\n%04x: ", i);
 
97
      cmn_err (CE_CONT, "%02x ", desc[i]);
 
98
    }
 
99
  cmn_err (CE_CONT, "\n");
 
100
}
 
101
 
 
102
unsigned int
 
103
ossusb_get_int (unsigned char *p, int nbytes)
 
104
{
 
105
  unsigned int v = 0;
 
106
  int i;
 
107
 
 
108
  for (i = 0; i < nbytes; i++)
 
109
    {
 
110
      v |= (*p++) << (i * 8);
 
111
    }
 
112
 
 
113
  return v;
 
114
}
 
115
 
 
116
/*
 
117
 * Mixer stuff
 
118
 */
 
119
 
 
120
static int
 
121
decode_vol (usb_control_t * c, unsigned char *buf, int l)
 
122
{
 
123
  int value, range;
 
124
 
 
125
  if (l == 1)
 
126
    value = (signed char) buf[0];
 
127
  else
 
128
    value = (signed short) (buf[0] | (buf[1] << 8));
 
129
 
 
130
  range = c->max - c->min;
 
131
 
 
132
  value -= c->min;
 
133
  value = (value * c->scale + range / 2) / range;
 
134
 
 
135
  if (value < 0)
 
136
    value = 0;
 
137
  if (value > 255)
 
138
    value = 255;
 
139
  return value;
 
140
}
 
141
 
 
142
static void
 
143
encode_vol (usb_control_t * c, unsigned char *buf, int l, int value)
 
144
{
 
145
  int range;
 
146
 
 
147
  range = c->max - c->min;
 
148
 
 
149
  value = (value * range + c->scale / 2) / c->scale;
 
150
 
 
151
  value += c->min;
 
152
 
 
153
  if (l == 1)
 
154
    buf[0] = value;
 
155
  else
 
156
    {
 
157
      buf[0] = value & 0xff;
 
158
      buf[1] = (value >> 8) & 0xff;
 
159
    }
 
160
 
 
161
}
 
162
 
 
163
static int
 
164
read_feature_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
 
165
{
 
166
  int len, value = 0, l;
 
167
  int nch, ch;
 
168
  unsigned char buf[2];
 
169
 
 
170
/*
 
171
 * Volume controls use two message bytes while the others use just one.
 
172
 */
 
173
  l = (c->index == 1) ? 2 : 1;
 
174
 
 
175
  ch = c->min_ch + 1;
 
176
  if (c->global)
 
177
    ch = 0;
 
178
 
 
179
  if (rq != GET_CUR)
 
180
    {
 
181
      buf[0] = buf[1] = 0;
 
182
      len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0,     // endpoint
 
183
                                     rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS,  // rqtype
 
184
                                     ((c->index + 1) << 8) | (ch),      // value
 
185
                                     (c->unit->num << 8),       // index
 
186
                                     buf,       // buffer
 
187
                                     l, // buflen
 
188
                                     OSS_HZ * 2);
 
189
      if (len < 0)
 
190
        return 0;
 
191
 
 
192
      value =
 
193
        (len ==
 
194
         1) ? (signed char) buf[0] : (signed short) (buf[0] | (buf[1] << 8));
 
195
      *v = value;
 
196
      return 1;
 
197
    }
 
198
 
 
199
  nch = c->max_ch - c->min_ch + 1;
 
200
 
 
201
  buf[0] = buf[1] = 0;
 
202
  len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
 
203
                                 GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
204
                                 ((c->index + 1) << 8) | (ch),  // value
 
205
                                 (c->unit->num << 8),   // index
 
206
                                 buf,   // buffer
 
207
                                 l,     // buflen
 
208
                                 OSS_HZ * 2);
 
209
  if (len < 0)
 
210
    {
 
211
      // cmn_err(CE_CONT, "feature (%s/%d) read error %d\n", c->unit->name, c->index, len);
 
212
      *v = 0;
 
213
      return 0;
 
214
    }
 
215
 
 
216
  value = decode_vol (c, buf, len);
 
217
 
 
218
  if (!c->global)
 
219
    if (nch == 2)               /* Read the right channel */
 
220
      {
 
221
        len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0,   // endpoint
 
222
                                       GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS,   // rqtype
 
223
                                       ((c->index + 1) << 8) | (ch + 1),        // value
 
224
                                       (c->unit->num << 8),     // index
 
225
                                       buf,     // buffer
 
226
                                       l,       // buflen
 
227
                                       OSS_HZ * 2);
 
228
        if (len < 0)
 
229
          value |= (value & 0xff) << 8;
 
230
        else
 
231
          value |= (decode_vol (c, buf, len)) << 8;
 
232
      }
 
233
 
 
234
  *v = value;
 
235
  return 1;
 
236
}
 
237
 
 
238
static int
 
239
write_feature_value (ossusb_devc * devc, usb_control_t * c, int value)
 
240
{
 
241
  int len, l;
 
242
  int left, right;
 
243
  int ch, nch;
 
244
  unsigned char buf[2];
 
245
 
 
246
  ch = c->min_ch + 1;
 
247
  if (c->global)
 
248
    ch = 0;
 
249
 
 
250
  left = value & 0xff;
 
251
  right = (value >> 8) & 0xff;
 
252
 
 
253
  if (left > (c->max - c->min))
 
254
    left = c->max - c->min;
 
255
  if (right > (c->max - c->min))
 
256
    right = c->max - c->min;
 
257
 
 
258
  l = (c->index == 1) ? 2 : 1;
 
259
 
 
260
  nch = c->max_ch - c->min_ch + 1;
 
261
  buf[0] = buf[1] = 0;
 
262
  encode_vol (c, buf, l, left);
 
263
 
 
264
  len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
 
265
                                 SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
266
                                 ((c->index + 1) << 8) | ch,    // value
 
267
                                 (c->unit->num << 8),   // index
 
268
                                 buf,   // buffer
 
269
                                 l,     // buflen
 
270
                                 OSS_HZ * 2);
 
271
  if (len < 0)
 
272
    {
 
273
      cmn_err (CE_CONT, "feature write error %d\n", len);
 
274
      return len;
 
275
    }
 
276
 
 
277
  if (nch == 2)                 /* Write the right channel */
 
278
    {
 
279
      buf[0] = buf[1] = 0;
 
280
      encode_vol (c, buf, l, right);
 
281
 
 
282
      len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0,     // endpoint
 
283
                                     SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS,     // rqtype
 
284
                                     ((c->index + 1) << 8) | (ch + 1),  // value
 
285
                                     (c->unit->num << 8),       // index
 
286
                                     buf,       // buffer
 
287
                                     l, // buflen
 
288
                                     OSS_HZ * 2);
 
289
    }
 
290
  else
 
291
    right = left;
 
292
 
 
293
  value = left | (right << 8);
 
294
  return value;
 
295
}
 
296
 
 
297
static int
 
298
read_mixer_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
 
299
{
 
300
  int len, value = 0;
 
301
  unsigned char buf[2];
 
302
 
 
303
  if (rq != GET_CUR)
 
304
    {
 
305
      len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0,     // endpoint
 
306
                                     rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS,  // rqtype
 
307
                                     (c->index << 8) | c->min_ch,       // value
 
308
                                     (c->unit->num << 8) | 1,   // index
 
309
                                     buf,       // buffer
 
310
                                     2, // buflen
 
311
                                     OSS_HZ * 2);
 
312
      if (len < 0)
 
313
        return 0;
 
314
 
 
315
      *v = (signed char) buf[1];
 
316
      return 1;
 
317
    }
 
318
 
 
319
  len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
 
320
                                 rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS,      // rqtype
 
321
                                 (c->index << 8) | c->min_ch,   // value
 
322
                                 (c->unit->num << 8) | 1,       // index
 
323
                                 buf,   // buffer
 
324
                                 2,     // buflen
 
325
                                 OSS_HZ * 2);
 
326
  if (len < 0)
 
327
    {
 
328
      cmn_err (CE_CONT, "mixer read error %d\n", len);
 
329
      return 0;
 
330
    }
 
331
 
 
332
  value = buf[1] - c->min;
 
333
 
 
334
  *v = value;
 
335
  return 1;
 
336
}
 
337
 
 
338
static int
 
339
write_mixer_value (ossusb_devc * devc, usb_control_t * c, int value)
 
340
{
 
341
  int len;
 
342
  unsigned char buf[2];
 
343
 
 
344
  value &= 0xff;
 
345
 
 
346
  buf[0] = 0;
 
347
  buf[1] = value + c->min;
 
348
  len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
 
349
                                 SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
350
                                 (c->index << 8) | c->min_ch,   // value
 
351
                                 (c->unit->num << 8) | 1,       // index
 
352
                                 buf,   // buffer
 
353
                                 2,     // buflen
 
354
                                 OSS_HZ * 2);
 
355
  if (len < 0)
 
356
    {
 
357
      cmn_err (CE_CONT, "mixer write error %d\n", len);
 
358
      return 0;
 
359
    }
 
360
 
 
361
  return value;
 
362
}
 
363
 
 
364
static int
 
365
read_unit (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
 
366
{
 
367
  int err, value;
 
368
  unsigned char buf[2];
 
369
 
 
370
  *v = value = 0;
 
371
 
 
372
  switch (c->unit->typ)
 
373
    {
 
374
    case TY_FEAT:
 
375
      return read_feature_value (devc, c, rq, v);
 
376
      break;
 
377
 
 
378
    case TY_MIXER:
 
379
      return read_mixer_value (devc, c, rq, v);
 
380
      break;
 
381
 
 
382
    case TY_SELECT:
 
383
      err = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0,     // endpoint
 
384
                                     rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS,  // rqtype
 
385
                                     0, // value
 
386
                                     (c->unit->num << 8),       // index
 
387
                                     buf,       // buffer
 
388
                                     1, // buflen
 
389
                                     OSS_HZ * 2);
 
390
      if (err < 0)
 
391
        {
 
392
          cmn_err (CE_CONT, "USB mixer unit read error %d\n", err);
 
393
          return 0;
 
394
        }
 
395
      value = buf[0] - 1;
 
396
      break;
 
397
 
 
398
    }                           /* switch */
 
399
 
 
400
  *v = value;
 
401
  return 1;
 
402
}
 
403
 
 
404
static int
 
405
read_current_value (ossusb_devc * devc, usb_control_t * c)
 
406
{
 
407
  int v;
 
408
 
 
409
  if (!read_unit (devc, c, GET_CUR, &v))
 
410
    return 0;
 
411
 
 
412
  c->value = v;
 
413
 
 
414
  return 1;
 
415
}
 
416
 
 
417
static int
 
418
write_current_value (ossusb_devc * devc, usb_control_t * c, int value)
 
419
{
 
420
  unsigned char buf[2];
 
421
  int err;
 
422
 
 
423
  switch (c->unit->typ)
 
424
    {
 
425
    case TY_SELECT:
 
426
      if (value > c->max)
 
427
        value = c->max;
 
428
      buf[0] = value + 1;
 
429
      err = udi_usb_snd_control_msg (devc->mixer_usbdev, 0,     // endpoint
 
430
                                     SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS,     // rqtype
 
431
                                     0, // value
 
432
                                     (c->unit->num << 8),       // index
 
433
                                     buf,       // buffer
 
434
                                     1, // buflen
 
435
                                     OSS_HZ * 2);
 
436
      if (err < 0)
 
437
        {
 
438
          cmn_err (CE_CONT, "Selector write error %d\n", err);
 
439
          return 0;
 
440
        }
 
441
      break;
 
442
 
 
443
    case TY_FEAT:
 
444
      value = write_feature_value (devc, c, value);
 
445
      break;
 
446
 
 
447
    case TY_MIXER:
 
448
      value = write_mixer_value (devc, c, value);
 
449
      break;
 
450
 
 
451
    default:
 
452
      return OSS_EIO;
 
453
    }
 
454
 
 
455
  return value;
 
456
}
 
457
 
 
458
static int
 
459
new_ctl (ossusb_devc * devc, usb_audio_unit_t * un, int index, int exttype,
 
460
         int chmask)
 
461
{
 
462
  int n, min, max;
 
463
  usb_control_t *c;
 
464
  int i, min_ch = 0, max_ch = 0;
 
465
 
 
466
  if (devc->ncontrols >= MAX_CONTROLS)
 
467
    {
 
468
      cmn_err (CE_CONT, "Too many mixer features.\n");
 
469
      return OSS_EIO;
 
470
    }
 
471
 
 
472
  n = devc->ncontrols++;
 
473
 
 
474
  c = &devc->controls[n];
 
475
 
 
476
  if (chmask)
 
477
    {
 
478
      min_ch = -1;
 
479
 
 
480
      for (i = 0; i < 32; i++)
 
481
        if (chmask & (1 << i))
 
482
          {
 
483
            if (min_ch == -1)
 
484
              min_ch = i;
 
485
            max_ch = i;
 
486
          }
 
487
    }
 
488
 
 
489
  c->unit = un;
 
490
  c->index = index;
 
491
  c->exttype = exttype;
 
492
  c->min_ch = min_ch;
 
493
  c->global = (chmask == 0) ? 1 : 0;
 
494
  c->max_ch = max_ch;
 
495
  c->min = 0;
 
496
  c->max = 255;
 
497
  c->chmask = chmask;
 
498
  c->value = 0;
 
499
 
 
500
  if (index != 1)               /* Not volume control */
 
501
    {
 
502
      c->max = 1;
 
503
    }
 
504
  else
 
505
    {
 
506
      if (read_unit (devc, c, GET_MAX, &max))
 
507
        {
 
508
          c->max = max;
 
509
          if (read_unit (devc, c, GET_MIN, &min))
 
510
            {
 
511
              c->min = min;
 
512
            }
 
513
        }
 
514
    }
 
515
 
 
516
  if (c->max <= c->min)
 
517
    {
 
518
/*
 
519
 * The device reported bad limits. Try to fix the situation.
 
520
 */
 
521
      if (c->min < 0)
 
522
        c->max = 0;
 
523
      else
 
524
        c->min = 0;
 
525
      if (c->max <= c->min)
 
526
        {
 
527
          c->min = 0;
 
528
          c->max = 255;
 
529
        }
 
530
    }
 
531
 
 
532
  c->scale = 255;
 
533
  if (c->max - c->min < 255)
 
534
    c->scale = c->max - c->min;
 
535
 
 
536
 
 
537
  read_current_value (devc, c);
 
538
 
 
539
  if (usb_trace)
 
540
    {
 
541
      cmn_err (CE_CONT, "Ctl %2d: %d/%s %d ", n, c->unit->num, c->unit->name,
 
542
               c->index);
 
543
      cmn_err (CE_CONT, "Min %d, max %d, scale %d\n", c->min, c->max,
 
544
               c->scale);
 
545
      cmn_err (CE_CONT, "ch=%x ", c->chmask);
 
546
      cmn_err (CE_CONT, "Value %04x, (%d - %d, %d)\n", c->value, c->min,
 
547
               c->max, c->scale);
 
548
    }
 
549
 
 
550
  return n;
 
551
}
 
552
 
 
553
static int
 
554
mixer_func (int dev, int ctrl, unsigned int cmd, int value)
 
555
{
 
556
  ossusb_devc *devc = mixer_devs[dev]->devc;
 
557
  usb_control_t *c;
 
558
 
 
559
  if (devc->disabled)
 
560
    return OSS_EPIPE;
 
561
 
 
562
  if (ctrl < 0 || ctrl >= devc->ncontrols)
 
563
    return OSS_EIO;
 
564
 
 
565
  c = &devc->controls[ctrl];
 
566
 
 
567
  if (cmd == SNDCTL_MIX_READ)
 
568
    {
 
569
      return c->value;
 
570
    }
 
571
 
 
572
  if (cmd != SNDCTL_MIX_WRITE)
 
573
    return OSS_EINVAL;
 
574
 
 
575
  value = c->value = write_current_value (devc, c, value);
 
576
 
 
577
  return value;
 
578
}
 
579
 
 
580
static char *
 
581
get_feature_name (int n)
 
582
{
 
583
  switch (n)
 
584
    {
 
585
    case 0:
 
586
      return "mute";
 
587
    case 1:
 
588
      return "vol";
 
589
    case 2:
 
590
      return "bass";
 
591
    case 3:
 
592
      return "mid";
 
593
    case 4:
 
594
      return "treble";
 
595
    case 5:
 
596
      return "eq";
 
597
    case 6:
 
598
      return "agc";
 
599
    case 7:
 
600
      return "delay";
 
601
    case 8:
 
602
      return "boost";
 
603
    case 9:
 
604
      return "loud";
 
605
    case 10:
 
606
      return "igain";
 
607
    case 11:
 
608
      return "igainpad";
 
609
    case 12:
 
610
      return "phaseinv";
 
611
    case 13:
 
612
      return "underflow";
 
613
    case 14:
 
614
      return "overflow";
 
615
    default:
 
616
      return "misc";
 
617
    }
 
618
}
 
619
 
 
620
static int
 
621
get_feature_type (int n)
 
622
{
 
623
  switch (n)
 
624
    {
 
625
    case 0:
 
626
      return MIXT_ONOFF;
 
627
    case 1:
 
628
      return MIXT_SLIDER;
 
629
    case 2:
 
630
      return MIXT_SLIDER;
 
631
    case 3:
 
632
      return MIXT_SLIDER;
 
633
    case 4:
 
634
      return MIXT_SLIDER;
 
635
    case 5:
 
636
      return MIXT_SLIDER;
 
637
    case 6:
 
638
      return MIXT_ONOFF;
 
639
    case 7:
 
640
      return MIXT_SLIDER;
 
641
    case 8:
 
642
      return MIXT_ONOFF;
 
643
    case 9:
 
644
      return MIXT_ONOFF;
 
645
    default:
 
646
      return MIXT_ONOFF;
 
647
    }
 
648
}
 
649
 
 
650
struct chmasks
 
651
{
 
652
  unsigned int mask;
 
653
  char *name;
 
654
  char type;
 
655
  char channels;
 
656
};
 
657
 
 
658
static const struct chmasks chmasks[] = {
 
659
  {0x00000003, "front", MIXT_STEREOSLIDER, 2},
 
660
  {0x00000001, "L", MIXT_MONOSLIDER, 1},
 
661
  {0x00000002, "R", MIXT_MONOSLIDER, 1},
 
662
  {0x00000030, "surr", MIXT_STEREOSLIDER, 2},
 
663
  {0x00000010, "LS", MIXT_MONOSLIDER, 1},
 
664
  {0x00000020, "RS", MIXT_MONOSLIDER, 1},
 
665
  {0x0000000c, "C/L", MIXT_STEREOSLIDER, 2},
 
666
  {0x00000004, "C", MIXT_MONOSLIDER, 1},
 
667
  {0x00000008, "LFE", MIXT_MONOSLIDER, 1},
 
668
  {0x000000c0, "center", MIXT_STEREOSLIDER, 2},
 
669
  {0x00000040, "LC", MIXT_MONOSLIDER, 1},
 
670
  {0x00000080, "RC", MIXT_MONOSLIDER, 1},
 
671
  {0x00000100, "surr", MIXT_STEREOSLIDER, 2},
 
672
  {0x00000600, "side", MIXT_STEREOSLIDER, 2},
 
673
  {0x00000200, "SL", MIXT_MONOSLIDER, 1},
 
674
  {0x00000400, "SR", MIXT_MONOSLIDER, 1},
 
675
  {0x00000800, "TC", MIXT_MONOSLIDER, 1},
 
676
  {0x00001000, "TFL", MIXT_MONOSLIDER, 1},
 
677
  {0x00002000, "TFC", MIXT_MONOSLIDER, 1},
 
678
  {0x00004000, "TFR", MIXT_MONOSLIDER, 1},
 
679
  {0x00008000, "TBL", MIXT_MONOSLIDER, 1},
 
680
  {0x00010000, "TBC", MIXT_MONOSLIDER, 1},
 
681
  {0x00020000, "TBR", MIXT_MONOSLIDER, 1},
 
682
  {0x00040000, "TFLC", MIXT_MONOSLIDER, 1},
 
683
  {0x00080000, "TFRC", MIXT_MONOSLIDER, 1},
 
684
  {0x00100000, "LLFE", MIXT_MONOSLIDER, 1},
 
685
  {0x00200000, "RLFE", MIXT_MONOSLIDER, 1},
 
686
  {0x00400000, "TSL", MIXT_MONOSLIDER, 1},
 
687
  {0x00800000, "TSR", MIXT_MONOSLIDER, 1},
 
688
  {0x01000000, "BC", MIXT_MONOSLIDER, 1},
 
689
  {0x02000000, "BLC", MIXT_MONOSLIDER, 1},
 
690
  {0x04000000, "BRC", MIXT_MONOSLIDER, 1},
 
691
  {0x80000000, "RD", MIXT_MONOSLIDER, 1},
 
692
  {0, NULL}
 
693
};
 
694
 
 
695
static int
 
696
count_source_controls (ossusb_devc * devc, int unit)
 
697
{
 
698
  int n = 0, nn, i;
 
699
  usb_audio_unit_t *un;
 
700
  unsigned char *d;
 
701
 
 
702
  if (unit <= 0 || unit >= devc->nunits)
 
703
    return 0;
 
704
 
 
705
  un = &devc->units[unit];
 
706
  d = un->desc;
 
707
 
 
708
  if (un == NULL)
 
709
    return 0;
 
710
 
 
711
  switch (un->typ)
 
712
    {
 
713
    case TY_MIXER:
 
714
    case TY_SELECT:
 
715
      nn = d[4];
 
716
      d += 5;
 
717
      for (i = 0; i < nn; i++)
 
718
        {
 
719
          n += count_source_controls (devc, *d);
 
720
          d++;
 
721
        }
 
722
      break;
 
723
 
 
724
    case TY_PROC:
 
725
    case TY_EXT:
 
726
      nn = d[6];
 
727
      d += 7;
 
728
      for (i = 0; i < nn; i++)
 
729
        {
 
730
          n += count_source_controls (devc, *d);
 
731
          d++;
 
732
        }
 
733
      break;
 
734
 
 
735
    default:
 
736
      if (un->source <= 0 && un->source < devc->nunits)
 
737
        {
 
738
          n = count_source_controls (devc, un->source);
 
739
        }
 
740
    }
 
741
 
 
742
  if (!un->ctl_avail)
 
743
    return n;
 
744
 
 
745
  return n + un->control_count;
 
746
}
 
747
 
 
748
static int
 
749
count_target_controls (ossusb_devc * devc, int unit)
 
750
{
 
751
  int n = 0;
 
752
  usb_audio_unit_t *un;
 
753
 
 
754
  if (unit <= 0 || unit >= devc->nunits)
 
755
    return 0;
 
756
 
 
757
  un = &devc->units[unit];
 
758
 
 
759
  if (un == NULL)
 
760
    return 0;
 
761
 
 
762
  if (un->typ == TY_SELECT || un->typ == TY_MIXER)
 
763
    {
 
764
      n = 0;
 
765
    }
 
766
  else if (un->target <= 0 && un->target < devc->nunits)
 
767
    {
 
768
      n = count_target_controls (devc, un->target);
 
769
    }
 
770
 
 
771
  if (!un->ctl_avail)
 
772
    return n;
 
773
 
 
774
  return n + un->control_count;
 
775
}
 
776
 
 
777
static int
 
778
follow_source_links (ossusb_devc * devc, usb_audio_unit_t * un)
 
779
{
 
780
  while (un->source > 0 && un->source < devc->nunits)
 
781
    un = &devc->units[un->source];
 
782
 
 
783
  return un->num;
 
784
}
 
785
 
 
786
static int
 
787
follow_target_links (ossusb_devc * devc, usb_audio_unit_t * un)
 
788
{
 
789
  while (un->target > 0 && un->target < devc->nunits)
 
790
    un = &devc->units[un->target];
 
791
 
 
792
  return un->num;
 
793
}
 
794
 
 
795
static void
 
796
add_controls_for_mixer (ossusb_devc * devc, usb_audio_unit_t * un, int group)
 
797
{
 
798
  int i, n;
 
799
  unsigned char *d = un->desc;
 
800
 
 
801
  if (!un->ctl_avail)
 
802
    return;
 
803
 
 
804
  n = d[4];
 
805
  d += 5;
 
806
 
 
807
  for (i = 0; i < n; i++)
 
808
    if (*d > 0 && *d < devc->nunits)
 
809
      {
 
810
        int ref = follow_source_links (devc, &devc->units[*d]);
 
811
 
 
812
        {
 
813
 
 
814
          int ctl = new_ctl (devc, un, i, MIXT_MONOSLIDER, un->chmask);
 
815
          UDB (cmn_err
 
816
               (CE_CONT, "Add mixer control %d/%s\n", un->num,
 
817
                devc->units[ref].name));
 
818
          if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
 
819
                                        mixer_func, MIXT_MONOSLIDER,
 
820
                                        devc->units[ref].name, 255,
 
821
                                        MIXF_READABLE | MIXF_WRITEABLE) < 0)
 
822
            return;
 
823
        }
 
824
        d++;
 
825
      }
 
826
 
 
827
  un->ctl_avail = 0;
 
828
}
 
829
 
 
830
/*ARGSUSED*/
 
831
static void
 
832
add_controls_for_proc (ossusb_devc * devc, usb_audio_unit_t * un, int group)
 
833
{
 
834
  int i, n;
 
835
  unsigned char *d = un->desc;
 
836
 
 
837
  if (!un->ctl_avail)
 
838
    return;
 
839
 
 
840
  n = d[6];
 
841
  d += 7;
 
842
 
 
843
  for (i = 0; i < n; i++)
 
844
    if (*d > 0 && *d < devc->nunits)
 
845
      {
 
846
        d++;
 
847
      }
 
848
 
 
849
  un->ctl_avail = 0;
 
850
}
 
851
 
 
852
static void
 
853
add_controls_for_selector (ossusb_devc * devc, usb_audio_unit_t * un,
 
854
                           int group)
 
855
{
 
856
  static oss_mixer_enuminfo ent;
 
857
  char *s;
 
858
  int i, n, err;
 
859
  unsigned char *d = un->desc;
 
860
  int ctl = new_ctl (devc, un, 0, MIXT_ENUM, 0);
 
861
 
 
862
  if (!un->ctl_avail)
 
863
    return;
 
864
 
 
865
  n = d[4];
 
866
  d += 5;
 
867
  UDB (cmn_err (CE_CONT, "Add selector control %d/%s\n", un->num, un->name));
 
868
  if ((err = mixer_ext_create_control (devc->mixer_dev, group,
 
869
                                       ctl, mixer_func,
 
870
                                       MIXT_ENUM,
 
871
                                       un->name, n,
 
872
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
873
    return;
 
874
 
 
875
  memset (&ent, 0, sizeof (ent));
 
876
 
 
877
  s = ent.strings;
 
878
 
 
879
  for (i = 0; i < n; i++)
 
880
    if (*d > 0 && *d < devc->nunits)
 
881
      {
 
882
        int ref = follow_source_links (devc, &devc->units[*d]);
 
883
        d++;
 
884
 
 
885
        if (s > ent.strings)
 
886
          *s++ = '|';
 
887
        strcpy (s, devc->units[ref].name);
 
888
        s += strlen (s);
 
889
      }
 
890
 
 
891
  s = ent.strings;
 
892
  for (i = 0; i < strlen (s); i++)
 
893
    {
 
894
      if (s[i] == ' ')
 
895
        s[i] = '_';
 
896
      if (s[i] == '|')
 
897
        s[i] = ' ';
 
898
    }
 
899
 
 
900
  ent.dev = devc->mixer_dev;
 
901
  ent.ctrl = err;
 
902
  ent.nvalues = 0;
 
903
 
 
904
  mixer_ext_set_enum (&ent);
 
905
 
 
906
  un->ctl_avail = 0;
 
907
}
 
908
 
 
909
/*ARGSUSED*/
 
910
static void
 
911
add_multich_volumes (ossusb_devc * devc, usb_audio_unit_t * un, int group,
 
912
                     int fea, int mask, unsigned int *feature_mask)
 
913
{
 
914
  int i;
 
915
 
 
916
  for (i = 0; mask != 0 && chmasks[i].mask != 0; i++)
 
917
    {
 
918
      int m = chmasks[i].mask;
 
919
      int ctl;
 
920
      usb_control_t *c;
 
921
 
 
922
      if (!(mask & m))
 
923
        continue;
 
924
 
 
925
      ctl = new_ctl (devc, un, fea, chmasks[i].type, chmasks[i].mask);
 
926
      c = &devc->controls[ctl];
 
927
 
 
928
      UDB (cmn_err
 
929
           (CE_CONT, "Add multich feature control %d/%s\n", un->num,
 
930
            chmasks[i].name));
 
931
      if (mixer_ext_create_control (devc->mixer_dev, group, ctl, mixer_func,
 
932
                                    chmasks[i].type, chmasks[i].name,
 
933
                                    c->scale,
 
934
                                    MIXF_READABLE | MIXF_WRITEABLE) < 0)
 
935
        return;
 
936
 
 
937
      mask &= ~m;
 
938
    }
 
939
 
 
940
  if (mask)
 
941
    cmn_err (CE_CONT, "Warning! Unsupported channels (%02x)\n", mask);
 
942
}
 
943
 
 
944
static void
 
945
translate_feature_mask_usb2 (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
 
946
{
 
947
  int i, n, c;
 
948
  unsigned char *d = un->desc;
 
949
 
 
950
  n = 4;
 
951
  d = d + 5 + n;                // Skip the global mask
 
952
 
 
953
/*
 
954
 * USB 2.0 uses 2 bits for each control
 
955
 *      01b means that the control is read only and 11b means it's RW
 
956
 */
 
957
  for (c = 0; c < un->channels; c++)
 
958
    {
 
959
      unsigned int mask;
 
960
      unsigned char *p = d + c * n;
 
961
 
 
962
      mask = p[3] |
 
963
             (p[2] << 8) |
 
964
             (p[1] << 16) |
 
965
             (p[0] << 24);
 
966
 
 
967
      for (i = 0; i < n * 4; i++)
 
968
        if ((mask & (3 << 2*i)) && (un->ctl_avail & (1 << i)))
 
969
          {
 
970
            feature_mask[i] |= 1 << c;
 
971
          }
 
972
    }
 
973
}
 
974
 
 
975
static void
 
976
translate_feature_mask (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
 
977
{
 
978
  int i, n, c;
 
979
  unsigned char *d = un->desc;
 
980
 
 
981
  if (devc->usb_version > 1)
 
982
  {
 
983
        translate_feature_mask_usb2(devc, un, feature_mask);
 
984
        return;
 
985
  }
 
986
 
 
987
  n = d[5];
 
988
  if (n < 1 || n > 2)
 
989
    {
 
990
        cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
 
991
        return;
 
992
    }
 
993
 
 
994
    d = d + 6 + n;              // Skip the global mask
 
995
 
 
996
  for (c = 0; c < un->channels; c++)
 
997
    {
 
998
      int mask = d[c * n];
 
999
      if (n > 1)
 
1000
        mask |= d[c * n + 1];
 
1001
 
 
1002
      for (i = 0; i < n * 8; i++)
 
1003
        if ((mask & (1 << i)) && (un->ctl_avail & (1 << i)))
 
1004
          {
 
1005
            feature_mask[i] |= 1 << c;
 
1006
          }
 
1007
    }
 
1008
}
 
1009
 
 
1010
static void
 
1011
add_controls_for_feature (ossusb_devc * devc, usb_audio_unit_t * un,
 
1012
                          int group)
 
1013
{
 
1014
  int i;
 
1015
  unsigned int feature_mask[16], global_mask;
 
1016
 
 
1017
  if (!un->ctl_avail)
 
1018
    return;
 
1019
 
 
1020
// Handle the global controls first
 
1021
 
 
1022
  global_mask = un->desc[6];
 
1023
  if (un->desc[5] > 0)
 
1024
    global_mask |= un->desc[7] << 8;
 
1025
 
 
1026
  for (i = 0; i < 11; i++)
 
1027
    if (un->ctl_avail & (1 << i) && (global_mask & (1 << i)))
 
1028
      {
 
1029
        char *name = get_feature_name (i);
 
1030
        int type = get_feature_type (i);
 
1031
        int max;
 
1032
        char tmp[16];
 
1033
        int ctl;
 
1034
 
 
1035
        ctl = new_ctl (devc, un, i, type, 0);
 
1036
        strcpy (tmp, name);
 
1037
        if (type == MIXT_SLIDER)
 
1038
          max = devc->controls[ctl].max - devc->controls[ctl].min;
 
1039
        else
 
1040
          max = 1;
 
1041
 
 
1042
        if (max > 255)
 
1043
          max = 255;
 
1044
 
 
1045
        UDB (cmn_err
 
1046
             (CE_CONT, "Add (global) feature control %d:%s, max=%d\n",
 
1047
              un->num, name, max));
 
1048
        if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
 
1049
                                      mixer_func, type, tmp, max,
 
1050
                                      MIXF_READABLE | MIXF_WRITEABLE) < 0)
 
1051
          return;
 
1052
        //un->ctl_avail &= ~(1 << i);
 
1053
      }
 
1054
 
 
1055
// Handle the channelized controls
 
1056
 
 
1057
  if (un->ctl_avail == 0)       /* Nothing left */
 
1058
    return;
 
1059
 
 
1060
  // Translate the channel/feature availability matrix
 
1061
 
 
1062
  memset (feature_mask, 0, sizeof (feature_mask));
 
1063
  translate_feature_mask (devc, un, feature_mask);
 
1064
 
 
1065
  for (i = 0; i < 16; i++)
 
1066
    if (feature_mask[i])
 
1067
      {
 
1068
        char *name = get_feature_name (i);
 
1069
        int type = get_feature_type (i);
 
1070
        int max, instances = 0;
 
1071
 
 
1072
        int nc = 0, j;
 
1073
 
 
1074
        for (j = 0; j < 16; j++)
 
1075
          if (feature_mask[i] & (1 << j))
 
1076
            nc = j + 1;
 
1077
 
 
1078
        if (type == MIXT_SLIDER)
 
1079
          {
 
1080
            if (nc == 1)
 
1081
              {
 
1082
                type = MIXT_MONOSLIDER;
 
1083
                instances = 1;
 
1084
              }
 
1085
            else if (nc == 2)
 
1086
              {
 
1087
                type = MIXT_STEREOSLIDER;
 
1088
                instances = 1;
 
1089
              }
 
1090
            else
 
1091
              {
 
1092
                type = MIXT_MONOSLIDER;
 
1093
                if (i == 1)     /* "volume" */
 
1094
                  instances = nc;
 
1095
                else
 
1096
                  {
 
1097
                    instances = 0;
 
1098
                    type = MIXT_MONOSLIDER;
 
1099
                  }
 
1100
              }
 
1101
            max = 255;
 
1102
          }
 
1103
        else
 
1104
          max = 2;
 
1105
 
 
1106
        if (instances && (instances > 1 || feature_mask[i] > 0x0003))
 
1107
          {
 
1108
            int g;
 
1109
            char tmp[16];
 
1110
            strcpy (tmp, name);
 
1111
            UDB (cmn_err (CE_CONT, "Add feature group %s\n", tmp));
 
1112
            if ((g =
 
1113
                 mixer_ext_create_group (devc->mixer_dev, group, tmp)) < 0)
 
1114
              return;
 
1115
 
 
1116
            add_multich_volumes (devc, un, g, i, feature_mask[i],
 
1117
                                 feature_mask);
 
1118
          }
 
1119
        else
 
1120
          {
 
1121
            char tmp[16];
 
1122
            int ctl = new_ctl (devc, un, i, type, un->chmask);
 
1123
            strcpy (tmp, name);
 
1124
            max = devc->controls[ctl].max - devc->controls[ctl].min;
 
1125
            if (max > 255)
 
1126
              max = 255;
 
1127
 
 
1128
            UDB (cmn_err
 
1129
                 (CE_CONT, "Add feature control %d:%s\n", un->num, name));
 
1130
            if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
 
1131
                                          mixer_func, type, tmp, max,
 
1132
                                          MIXF_READABLE | MIXF_WRITEABLE) < 0)
 
1133
              return;
 
1134
          }
 
1135
      }
 
1136
 
 
1137
  un->ctl_avail = 0;            // All done (hope so)
 
1138
}
 
1139
 
 
1140
static void
 
1141
traverse_source_controls (ossusb_devc * devc, usb_audio_unit_t * un,
 
1142
                          int group)
 
1143
{
 
1144
  unsigned char *d;
 
1145
 
 
1146
  d = un->desc;
 
1147
 
 
1148
  if (un->typ == TY_MIXER)
 
1149
    {
 
1150
      add_controls_for_mixer (devc, un, group);
 
1151
      return;
 
1152
    }
 
1153
 
 
1154
  if (un->typ == TY_PROC)
 
1155
    {
 
1156
      add_controls_for_proc (devc, un, group);
 
1157
 
 
1158
      if (d[6] > 1)             /* More than 1 sources */
 
1159
        return;
 
1160
    }
 
1161
 
 
1162
  if (un->typ == TY_SELECT)
 
1163
    {
 
1164
      add_controls_for_selector (devc, un, group);
 
1165
      return;
 
1166
    }
 
1167
 
 
1168
  if (un->source > 0 && un->source < devc->nunits)
 
1169
    {
 
1170
      traverse_source_controls (devc, &devc->units[un->source], group);
 
1171
    }
 
1172
 
 
1173
  if (un->typ == TY_FEAT)
 
1174
    {
 
1175
      add_controls_for_feature (devc, un, group);
 
1176
    }
 
1177
}
 
1178
 
 
1179
static void
 
1180
traverse_target_controls (ossusb_devc * devc, usb_audio_unit_t * un,
 
1181
                          int group)
 
1182
{
 
1183
  unsigned char *d;
 
1184
 
 
1185
 
 
1186
  d = un->desc;
 
1187
 
 
1188
  if (un->typ == TY_SELECT)
 
1189
    {
 
1190
      add_controls_for_selector (devc, un, group);
 
1191
    }
 
1192
 
 
1193
  if (un->typ == TY_PROC || un->typ == TY_EXT)
 
1194
    if (d[6] > 1)               // More than 1 input pins
 
1195
      return;
 
1196
 
 
1197
  if (un->typ == TY_MIXER)
 
1198
    {
 
1199
#if 1
 
1200
      add_controls_for_mixer (devc, un, group);
 
1201
#endif
 
1202
    }
 
1203
 
 
1204
  if (un->target > 0 && un->target < devc->nunits)
 
1205
    traverse_target_controls (devc, &devc->units[un->target], group);
 
1206
 
 
1207
  if (un->typ == TY_FEAT)
 
1208
    {
 
1209
      add_controls_for_feature (devc, un, group);
 
1210
    }
 
1211
}
 
1212
 
 
1213
void
 
1214
ossusb_create_altset_control (int dev, int portc_num, int nalt, char *name)
 
1215
{
 
1216
  int ctl;
 
1217
  ossusb_devc *devc = mixer_devs[dev]->devc;
 
1218
  char *as = NULL;
 
1219
  int default_altsetting;
 
1220
  unsigned int altsetting_mask;
 
1221
 
 
1222
  if (nalt < 3)                 /* Only one alternative setting (plus "OFF") available */
 
1223
    return;
 
1224
  if ((as =
 
1225
       udi_usbdev_get_altsetting_labels (devc->mixer_usbdev, portc_num,
 
1226
                                         &default_altsetting,
 
1227
                                         &altsetting_mask)) != NULL)
 
1228
    {
 
1229
      if (altsetting_mask != 0)
 
1230
        {
 
1231
          /*
 
1232
           * Check if more than one of them are enabled.
 
1233
           */
 
1234
 
 
1235
          int i, n = 0;
 
1236
 
 
1237
          for (i = 1; i < nalt; i++)
 
1238
            if (altsetting_mask & (1 << i))
 
1239
              n++;
 
1240
 
 
1241
          if (n < 2)            /* No */
 
1242
            return;
 
1243
        }
 
1244
    }
 
1245
 
 
1246
  if ((ctl = mixer_ext_create_control (dev, 0,
 
1247
                                       portc_num, ossusb_change_altsetting,
 
1248
                                       MIXT_ENUM,
 
1249
                                       name, nalt,
 
1250
                                       MIXF_READABLE | MIXF_WRITEABLE)) < 0)
 
1251
    return;
 
1252
 
 
1253
  if (as != NULL)               /* Use custom labels */
 
1254
    {
 
1255
      mixer_ext_set_strings (dev, ctl, as, 0);
 
1256
      if (altsetting_mask != 0)
 
1257
        {
 
1258
          oss_mixext *ext;
 
1259
          int i;
 
1260
 
 
1261
          ext = mixer_find_ext (dev, ctl);
 
1262
 
 
1263
          memset (ext->enum_present, 0, sizeof (ext->enum_present));
 
1264
          for (i = 0; i < nalt; i++)
 
1265
            if (altsetting_mask & (1 << i))
 
1266
              ext->enum_present[i / 8] |= (1 << (i % 8));
 
1267
        }
 
1268
 
 
1269
      if (default_altsetting > 0)
 
1270
        ossusb_change_altsetting (dev, portc_num, SNDCTL_MIX_WRITE,
 
1271
                                  default_altsetting);
 
1272
    }
 
1273
  else
 
1274
    mixer_ext_set_strings (dev, ctl,
 
1275
                           "OFF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19",
 
1276
                           0);
 
1277
 
 
1278
}
 
1279
 
 
1280
static int
 
1281
usb_mix_init (int dev)
 
1282
{
 
1283
  ossusb_devc *devc;
 
1284
  int i, group;
 
1285
 
 
1286
  devc = mixer_devs[dev]->devc;
 
1287
 
 
1288
  for (i = 0; i < devc->nunits; i++)
 
1289
    {
 
1290
      usb_audio_unit_t *un = &devc->units[i];
 
1291
 
 
1292
      if (un->typ == TY_OUTPUT)
 
1293
        {
 
1294
          if (count_source_controls (devc, un->source) == 0)
 
1295
            {
 
1296
              continue;
 
1297
            }
 
1298
 
 
1299
          if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
 
1300
            return group;
 
1301
 
 
1302
          traverse_source_controls (devc, un, group);
 
1303
          continue;
 
1304
        }
 
1305
    }
 
1306
 
 
1307
  for (i = 0; i < devc->nunits; i++)
 
1308
    {
 
1309
      usb_audio_unit_t *un = &devc->units[i];
 
1310
 
 
1311
      if (un->typ == TY_INPUT)
 
1312
        {
 
1313
          if (count_target_controls (devc, un->target) == 0)
 
1314
            {
 
1315
              continue;
 
1316
            }
 
1317
 
 
1318
          if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
 
1319
            return group;
 
1320
 
 
1321
          traverse_target_controls (devc, un, group);
 
1322
          un->ctl_avail = 0;
 
1323
          continue;
 
1324
        }
 
1325
    }
 
1326
 
 
1327
  return 0;
 
1328
}
 
1329
 
 
1330
static char *
 
1331
check_feature (usb_audio_unit_t * un, unsigned char *mask, int n)
 
1332
{
 
1333
  if (mask[n / 8] & (1 << (n % 8)))
 
1334
    {
 
1335
      un->control_count++;
 
1336
 
 
1337
      return get_feature_name (n);
 
1338
    }
 
1339
 
 
1340
  return NULL;
 
1341
}
 
1342
 
 
1343
/*ARGSUSED*/
 
1344
static int
 
1345
usb_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
 
1346
{
 
1347
  ossusb_devc *devc = mixer_devs[dev]->hw_devc;
 
1348
 
 
1349
  if (devc->disabled)
 
1350
    return OSS_EPIPE;
 
1351
 
 
1352
  switch (cmd)
 
1353
    {
 
1354
    case SOUND_MIXER_READ_DEVMASK:
 
1355
      return *arg = devc->devmask | devc->recmask;
 
1356
    case SOUND_MIXER_READ_RECMASK:
 
1357
      return *arg = devc->recmask;
 
1358
    case SOUND_MIXER_READ_RECSRC:
 
1359
      return *arg = devc->recsrc;
 
1360
    case SOUND_MIXER_READ_STEREODEVS:
 
1361
      return *arg = devc->stereodevs;
 
1362
    }
 
1363
 
 
1364
  return *arg = 0;
 
1365
}
 
1366
 
 
1367
static mixer_driver_t usb_mixer_driver = {
 
1368
  usb_mixer_ioctl
 
1369
};
 
1370
 
 
1371
static int
 
1372
init_mixer (ossusb_devc * devc)
 
1373
{
 
1374
  if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
 
1375
                                            devc->osdev,
 
1376
                                            devc->osdev,
 
1377
                                            devc->dev_name,
 
1378
                                            &usb_mixer_driver,
 
1379
                                            sizeof (mixer_driver_t),
 
1380
                                            devc)) >= 0)
 
1381
    {
 
1382
      char mxname[20];
 
1383
 
 
1384
      sprintf (mxname, "USB_%d", ndevs);
 
1385
 
 
1386
      devc->levels = load_mixer_volumes (mxname, NULL, 1);
 
1387
      mixer_devs[devc->mixer_dev]->hw_devc = devc;
 
1388
      mixer_ext_set_init_fn (devc->mixer_dev, usb_mix_init, MAX_CONTROLS);
 
1389
    }
 
1390
 
 
1391
  return 1;
 
1392
}
 
1393
 
 
1394
static usb_audio_unit_t *
 
1395
setup_unit (ossusb_devc * devc, int unit, char *name, unsigned char *desc,
 
1396
            int desclen, int typ)
 
1397
{
 
1398
  usb_audio_unit_t *un;
 
1399
 
 
1400
  if (unit < 0 || unit >= MAX_UNIT)
 
1401
    {
 
1402
      cmn_err (CE_WARN, "Bad unit number %d\n", unit);
 
1403
      return NULL;
 
1404
    }
 
1405
 
 
1406
  if (typ >= sizeof (devc->unit_counters))
 
1407
    {
 
1408
      cmn_err (CE_WARN, "Bad unit type %d\n", typ);
 
1409
      return NULL;
 
1410
    }
 
1411
 
 
1412
  devc->unit_counters[typ]++;
 
1413
 
 
1414
  if (unit >= devc->nunits)
 
1415
    devc->nunits = unit + 1;
 
1416
 
 
1417
  un = &devc->units[unit];
 
1418
 
 
1419
  un->num = unit;
 
1420
  un->typ = typ;
 
1421
  un->desc = desc;
 
1422
  un->desclen = desclen;
 
1423
  un->mixnum = -1;
 
1424
  un->channels = 2;
 
1425
  un->chmask = 0x03;
 
1426
  strcpy (un->name, name);
 
1427
 
 
1428
  return un;
 
1429
}
 
1430
 
 
1431
static char *
 
1432
get_terminal_id (int type, char *def, int typ, int *mn)
 
1433
{
 
1434
  int dummy, *mixnum;
 
1435
 
 
1436
  if (mn != NULL)
 
1437
    mixnum = mn;
 
1438
  else
 
1439
    mixnum = &dummy;
 
1440
  switch (type)
 
1441
    {
 
1442
    case 0x0101:
 
1443
      if (typ == TY_INPUT)
 
1444
        {
 
1445
          *mixnum = SOUND_MIXER_PCM;
 
1446
          return "play";
 
1447
        }
 
1448
      if (typ == TY_OUTPUT)
 
1449
        {
 
1450
          *mixnum = SOUND_MIXER_RECLEV;
 
1451
          return "rec";
 
1452
        }
 
1453
      break;
 
1454
    case 0x0301:
 
1455
      *mixnum = SOUND_MIXER_VOLUME;
 
1456
      return "output";
 
1457
    case 0x0302:
 
1458
      *mixnum = SOUND_MIXER_VOLUME;
 
1459
      return "headph";
 
1460
    case 0x0307:
 
1461
      return "LFE";
 
1462
 
 
1463
    case 0x0401:
 
1464
      return "handset";
 
1465
    case 0x0402:
 
1466
      return "headset";
 
1467
 
 
1468
    case 0x0403:
 
1469
    case 0x0404:
 
1470
    case 0x0405:
 
1471
    case 0x0500:
 
1472
    case 0x0501:
 
1473
    case 0x0502:
 
1474
    case 0x0504:
 
1475
      return "phone";
 
1476
      break;
 
1477
 
 
1478
    case 0x0600:
 
1479
      *mixnum = SOUND_MIXER_LINE1;
 
1480
      return "aux";
 
1481
    case 0x0601:
 
1482
      *mixnum = SOUND_MIXER_LINE2;
 
1483
      return "aux";
 
1484
    case 0x0602:
 
1485
      return "digital";
 
1486
    case 0x0603:
 
1487
      *mixnum = SOUND_MIXER_LINE;
 
1488
      return "line";
 
1489
    case 0x0604:
 
1490
      *mixnum = SOUND_MIXER_SPEAKER;
 
1491
      return "pc_in";
 
1492
    case 0x0605:
 
1493
      *mixnum = SOUND_MIXER_DIGITAL1;
 
1494
      if (typ == TY_INPUT)
 
1495
        return "spdin";
 
1496
      else
 
1497
        return "spdout";
 
1498
    case 0x0606:
 
1499
      return "da_stream";
 
1500
    case 0x0607:
 
1501
      return "DV_audio";
 
1502
 
 
1503
    case 0x0701:
 
1504
      return "noise";
 
1505
    case 0x0702:
 
1506
      return "eq_noise";
 
1507
    case 0x0703:
 
1508
      *mixnum = SOUND_MIXER_CD;
 
1509
      return "cd";
 
1510
    case 0x0704:
 
1511
      return "dat";
 
1512
    case 0x0706:
 
1513
      return "md";
 
1514
    case 0x0707:
 
1515
      return "tape";
 
1516
    case 0x0708:
 
1517
      return "phono";
 
1518
    case 0x0709:
 
1519
      *mixnum = SOUND_MIXER_VIDEO;
 
1520
      return "vcr";
 
1521
    case 0x070b:
 
1522
      return "dvd";
 
1523
    case 0x070c:
 
1524
      return "tv";
 
1525
    case 0x070d:
 
1526
      return "sat";
 
1527
    case 0x070e:
 
1528
      return "cable";
 
1529
    case 0x0710:
 
1530
      *mixnum = SOUND_MIXER_RADIO;
 
1531
      return "radio";
 
1532
    case 0x0711:
 
1533
      *mixnum = SOUND_MIXER_RADIO;
 
1534
      return "xmitter";
 
1535
    case 0x0712:
 
1536
      return "mtrack";
 
1537
    case 0x0713:
 
1538
      *mixnum = SOUND_MIXER_SYNTH;
 
1539
      return "synth";
 
1540
    }
 
1541
 
 
1542
  if (type < 0x201)             // Unknown type
 
1543
    return def;
 
1544
 
 
1545
  if (type < 0x300)
 
1546
    {
 
1547
      *mixnum = SOUND_MIXER_MIC;
 
1548
      return "mic";
 
1549
    }
 
1550
 
 
1551
  return def;
 
1552
}
 
1553
 
 
1554
static void
 
1555
setup_legacy_mixer (ossusb_devc * devc)
 
1556
{
 
1557
  int x;
 
1558
 
 
1559
// Set up the recording selector
 
1560
 
 
1561
  for (x = 1; x < devc->nunits; x++)
 
1562
    {
 
1563
      usb_audio_unit_t *un = &devc->units[x];
 
1564
      int i, n;
 
1565
      unsigned char *d = un->desc;
 
1566
 
 
1567
      if (un->typ != TY_SELECT || strcmp (un->name, "rec.src") != 0)
 
1568
        continue;
 
1569
 
 
1570
      if (!un->ctl_avail)
 
1571
        continue;
 
1572
 
 
1573
      devc->rec_unit = x;
 
1574
      un->ctl_avail = 0;
 
1575
 
 
1576
      devc->num_recdevs = n = d[4];
 
1577
      d += 5;
 
1578
      for (i = 0; i < n; i++)
 
1579
        {
 
1580
          int ref = follow_source_links (devc, &devc->units[*d]);
 
1581
          int mask;
 
1582
 
 
1583
          d++;
 
1584
 
 
1585
          if (ref < 1 || ref >= devc->nunits || devc->units[ref].mixnum == -1)
 
1586
            continue;
 
1587
 
 
1588
          mask = (1 << devc->units[ref].mixnum);
 
1589
          if (devc->recmask & mask)     // Duplicate
 
1590
            continue;
 
1591
          UDB (cmn_err
 
1592
               (CE_CONT, "Recsrc %d, num=%d, mask %x\n", i, ref, mask));
 
1593
 
 
1594
          devc->recdevs[i] = mask;
 
1595
 
 
1596
          devc->recmask |= mask;
 
1597
          if (devc->recsrc == 0)
 
1598
            devc->recsrc = mask;
 
1599
        }
 
1600
 
 
1601
      break;
 
1602
    }
 
1603
 
 
1604
// Set up the legacy mixer controls
 
1605
 
 
1606
  for (x = 1; x < devc->nunits; x++)
 
1607
    {
 
1608
      usb_audio_unit_t *un = &devc->units[x];
 
1609
      int mixnum;
 
1610
      unsigned char *d = un->desc;
 
1611
 
 
1612
      if (!(un->ctl_avail & 0x02))
 
1613
        continue;
 
1614
 
 
1615
      if (un->typ == TY_FEAT && d[6] & 0x02)    // Volume control
 
1616
        {
 
1617
          int t;
 
1618
          mixnum = un->mixnum;
 
1619
 
 
1620
          if (mixnum == -1)
 
1621
            {
 
1622
              t = follow_target_links (devc, un);
 
1623
              if (t && devc->units[t].mixnum != -1)
 
1624
                mixnum = devc->units[t].mixnum;
 
1625
              else
 
1626
                {
 
1627
                  t = follow_source_links (devc, un);
 
1628
                  if (t && devc->units[t].mixnum != -1)
 
1629
                    mixnum = devc->units[t].mixnum;
 
1630
                }
 
1631
            }
 
1632
 
 
1633
          if (mixnum == -1 || un->channels > 2)
 
1634
            continue;
 
1635
          UDB (cmn_err (CE_CONT, "Unit %d is volume %d\n", x, mixnum));
 
1636
          un->ctl_avail &= ~0x02;       // Reserve the volume slider
 
1637
 
 
1638
          devc->devmask |= (1 << mixnum);
 
1639
          if (un->channels == 2)
 
1640
            devc->stereodevs |= (1 << mixnum);
 
1641
 
 
1642
          continue;
 
1643
        }
 
1644
    }
 
1645
 
 
1646
}
 
1647
 
 
1648
static char *
 
1649
get_processor_type (int t)
 
1650
{
 
1651
  switch (t)
 
1652
    {
 
1653
    case 0x01:
 
1654
      return "upmix";
 
1655
    case 0x02:
 
1656
      return "prologic";
 
1657
    case 0x03:
 
1658
      return "3D";
 
1659
    case 0x04:
 
1660
      return "reverb";
 
1661
    case 0x05:
 
1662
      return "chorus";
 
1663
    case 0x06:
 
1664
      return "compress";
 
1665
    default:
 
1666
      return "proc";
 
1667
    }
 
1668
}
 
1669
 
 
1670
static void
 
1671
parse_processing_unit (ossusb_devc * devc, unsigned char *d, int l)
 
1672
{
 
1673
  usb_audio_unit_t *un;
 
1674
  char *name;
 
1675
 
 
1676
  name = get_processor_type (d[4]);
 
1677
 
 
1678
  if ((un = setup_unit (devc, d[3], name, d, l, TY_PROC)) == NULL)
 
1679
    return;
 
1680
  un->subtyp = d[4];
 
1681
  un->ctl_avail = 1;
 
1682
 
 
1683
  if (un->subtyp == 1)          // Upmix/downmix unit
 
1684
    {
 
1685
      un->channels = d[8];
 
1686
      un->chmask = ossusb_get_int (&d[9], 2);
 
1687
    }
 
1688
}
 
1689
 
 
1690
static int
 
1691
get_feature_mask (unsigned char *d, int channels)
 
1692
{
 
1693
  int i, n, mask = 0, v;
 
1694
  n = d[5];
 
1695
 
 
1696
  for (i = 0; i <= channels; i++)
 
1697
    {
 
1698
      v = d[6 + i * n];
 
1699
      if (n > 1)
 
1700
        v |= d[6 + i * n + 1] << 8;
 
1701
 
 
1702
      mask |= v;
 
1703
    }
 
1704
 
 
1705
  return mask;
 
1706
}
 
1707
 
 
1708
#if 1
 
1709
static void
 
1710
mixer_dump (ossusb_devc * devc)
 
1711
{
 
1712
  int i, j, c;
 
1713
  usb_audio_unit_t *un;
 
1714
 
 
1715
  for (i = 1; i < devc->nunits; i++)
 
1716
    {
 
1717
      un = &devc->units[i];
 
1718
 
 
1719
      if (un->typ == TY_FEAT)
 
1720
        {
 
1721
          cmn_err (CE_CONT, "Unit %d\n", un->num);
 
1722
 
 
1723
          for (j = 0; j < 8; j++)
 
1724
            {
 
1725
              for (c = 0; c < 7; c++)
 
1726
                {
 
1727
                  unsigned char buf[2];
 
1728
                  int len;
 
1729
 
 
1730
                  buf[0] = buf[1] = 0;
 
1731
                  len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
 
1732
                                                 GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
1733
                                                 ((j) << 8) | (c),      // value
 
1734
                                                 (un->num << 8),        // index
 
1735
                                                 buf,   // buffer
 
1736
                                                 2,     // buflen
 
1737
                                                 OSS_HZ * 2);
 
1738
 
 
1739
                  if (len < 0)
 
1740
                    continue;
 
1741
                  cmn_err (CE_CONT, "  Feature %d/%d, ch %d: ", un->num, j,
 
1742
                           c);
 
1743
                  cmn_err (CE_CONT, "%02x%02x ", buf[0], buf[1]);
 
1744
 
 
1745
                  if (len == 1)
 
1746
                    cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
 
1747
                  else
 
1748
                    cmn_err (CE_CONT, "(%d) ",
 
1749
                             (signed short) (buf[0] | (buf[1] << 8)));
 
1750
 
 
1751
                  buf[0] = buf[1] = 0;
 
1752
                  len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
 
1753
                                                 GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
1754
                                                 ((j) << 8) | (c),      // value
 
1755
                                                 (un->num << 8),        // index
 
1756
                                                 buf,   // buffer
 
1757
                                                 2,     // buflen
 
1758
                                                 OSS_HZ * 2);
 
1759
 
 
1760
                  if (len >= 0)
 
1761
                    cmn_err (CE_CONT, "Min=%02x%02x ", buf[0], buf[1]);
 
1762
                  if (len == 1)
 
1763
                    cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
 
1764
                  else if (len == 2)
 
1765
                    cmn_err (CE_CONT, "(%d) ",
 
1766
                             (signed short) (buf[0] | (buf[1] << 8)));
 
1767
 
 
1768
                  buf[0] = buf[1] = 0;
 
1769
                  len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
 
1770
                                                 GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
 
1771
                                                 ((j) << 8) | (c),      // value
 
1772
                                                 (un->num << 8),        // index
 
1773
                                                 buf,   // buffer
 
1774
                                                 2,     // buflen
 
1775
                                                 OSS_HZ * 2);
 
1776
 
 
1777
                  if (len >= 0)
 
1778
                    cmn_err (CE_CONT, "max=%02x%02x ", buf[0], buf[1]);
 
1779
                  if (len == 1)
 
1780
                    cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
 
1781
                  else if (len == 2)
 
1782
                    cmn_err (CE_CONT, "(%d) ",
 
1783
                             (signed short) (buf[0] | (buf[1] << 8)));
 
1784
 
 
1785
                  cmn_err (CE_CONT, "\n");
 
1786
                }
 
1787
            }
 
1788
        }
 
1789
    }
 
1790
}
 
1791
#endif
 
1792
 
 
1793
/*ARGSUSED*/
 
1794
static ossusb_devc *
 
1795
ossusb_init_audioctl (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
 
1796
                      int reinit)
 
1797
{
 
1798
  int desc_len;
 
1799
  unsigned char *desc, *d;
 
1800
  int i, l, n = 0, p, x, mixnum = -1;
 
1801
  char *name;
 
1802
  usb_audio_unit_t *un;
 
1803
 
 
1804
  /* nsettings = udi_usbdev_get_num_altsettings (usbdev); */
 
1805
  devc->mixer_usbdev = usbdev;
 
1806
 
 
1807
  if (!init_mixer (devc))
 
1808
    return NULL;
 
1809
 
 
1810
  desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
 
1811
 
 
1812
  if (desc == NULL)
 
1813
    {
 
1814
      cmn_err (CE_CONT, "Can't read interface descriptors\n");
 
1815
      return NULL;
 
1816
    }
 
1817
 
 
1818
  p = 0;
 
1819
  while (p < desc_len)
 
1820
    {
 
1821
      d = desc + p;
 
1822
 
 
1823
      l = *d;
 
1824
      if (usb_trace > 1)
 
1825
        {
 
1826
          char str[256], *s = str;
 
1827
          sprintf (s, "Control desc(%d): ", p);
 
1828
          s += strlen (s);
 
1829
          for (i = 0; i < l; i++)
 
1830
            {
 
1831
              sprintf (s, "%02x ", d[i]);
 
1832
              s += strlen (s);
 
1833
            }
 
1834
          cmn_err (CE_CONT, "%s\n", str);
 
1835
        }
 
1836
 
 
1837
#define CASE(x) case x:cmn_err(CE_CONT, #x "\n"); break;
 
1838
 
 
1839
      if (d[1] == CS_INTERFACE)
 
1840
        switch (d[2])
 
1841
          {
 
1842
          case AC_HEADER:
 
1843
            if (usb_trace)
 
1844
              {
 
1845
                cmn_err (CE_CONT, "     Audio control interface header\n");
 
1846
                n = d[7];
 
1847
                cmn_err (CE_CONT, "     %d related streaming interfaces: ",
 
1848
                         n);
 
1849
                for (i = 0; i < n; i++)
 
1850
                  {
 
1851
                    cmn_err (CE_CONT, "%d ", d[8 + i]);
 
1852
                  }
 
1853
                cmn_err (CE_CONT, "\n");
 
1854
              }
 
1855
            break;
 
1856
 
 
1857
          case AC_INPUT_TERMINAL:
 
1858
            name =
 
1859
              get_terminal_id (ossusb_get_int (&d[4], 2), "in", TY_INPUT,
 
1860
                               &mixnum);
 
1861
            if ((un = setup_unit (devc, d[3], name, d, l, TY_INPUT)) == NULL)
 
1862
              return NULL;
 
1863
            un->mixnum = mixnum;
 
1864
            un->channels = d[7];
 
1865
            un->chmask = ossusb_get_int (&d[8], 2);
 
1866
            break;
 
1867
 
 
1868
          case AC_OUTPUT_TERMINAL:
 
1869
            name =
 
1870
              get_terminal_id (ossusb_get_int (&d[4], 2), "out", TY_OUTPUT,
 
1871
                               &mixnum);
 
1872
            if ((un = setup_unit (devc, d[3], name, d, l, TY_OUTPUT)) == NULL)
 
1873
              return NULL;
 
1874
            un->mixnum = mixnum;
 
1875
            break;
 
1876
 
 
1877
          case AC_MIXER_UNIT:
 
1878
            if ((un = setup_unit (devc, d[3], "mix", d, l, TY_MIXER)) == NULL)
 
1879
              return NULL;
 
1880
            {
 
1881
              // Check if there are any visible controls
 
1882
 
 
1883
              int mask = 0, nn;
 
1884
 
 
1885
              n = d[4];         // # of input pins
 
1886
              d += 5 + n;
 
1887
              nn = *d;          // # of channels
 
1888
              d += 4;           // Seek to bmControls
 
1889
 
 
1890
              n = (n * nn + 7) / 8;
 
1891
 
 
1892
              for (i = 0; i < n; i++)
 
1893
                mask |= d[i];
 
1894
 
 
1895
              un->ctl_avail = mask;
 
1896
            }
 
1897
            break;
 
1898
 
 
1899
          case AC_SELECTOR_UNIT:
 
1900
            if ((un =
 
1901
                 setup_unit (devc, d[3], "src", d, l, TY_SELECT)) == NULL)
 
1902
              return NULL;
 
1903
            un->ctl_avail = 1;
 
1904
            break;
 
1905
 
 
1906
          case AC_FEATURE_UNIT:
 
1907
            if ((un = setup_unit (devc, d[3], "fea", d, l, TY_FEAT)) == NULL)
 
1908
              return NULL;
 
1909
            un->ctl_avail = get_feature_mask (d, 2);    /* For now */
 
1910
            break;
 
1911
 
 
1912
          case AC_PROCESSING_UNIT:
 
1913
            parse_processing_unit (devc, d, l);
 
1914
            break;
 
1915
 
 
1916
          case AC_EXTENSION_UNIT:
 
1917
            if ((un = setup_unit (devc, d[3], "ext", d, l, TY_EXT)) == NULL)
 
1918
              return NULL;
 
1919
            un->ctl_avail = 1;
 
1920
 
 
1921
            break;
 
1922
 
 
1923
          }
 
1924
 
 
1925
      p += l;
 
1926
    }
 
1927
 
 
1928
// Make sure the unit names are unique */
 
1929
 
 
1930
  for (x = 1; x < devc->nunits; x++)
 
1931
    {
 
1932
      usb_audio_unit_t *un = &devc->units[x];
 
1933
      int n = 0;
 
1934
 
 
1935
      if (un->typ != TY_SELECT)
 
1936
        for (i = x + 1; i < devc->nunits; i++)
 
1937
          if (strcmp (devc->units[i].name, un->name) == 0)
 
1938
            n++;
 
1939
 
 
1940
      if (n > 0)
 
1941
        {
 
1942
          char tmpname[16];
 
1943
          strcpy (tmpname, un->name);
 
1944
          n = 1;
 
1945
 
 
1946
          for (i = x; i < devc->nunits; i++)
 
1947
            if (strcmp (devc->units[i].name, tmpname) == 0)
 
1948
              {
 
1949
                if (n > 1)
 
1950
                  sprintf (devc->units[i].name, "%s%d", tmpname, n);
 
1951
                n++;
 
1952
              }
 
1953
        }
 
1954
 
 
1955
// Make sure the mixer control numbers are unique too
 
1956
 
 
1957
      n = 0;
 
1958
      if (un->mixnum != -1)
 
1959
        for (i = x + 1; i < devc->nunits; i++)
 
1960
          if (devc->units[i].mixnum == un->mixnum)
 
1961
            n++;
 
1962
 
 
1963
      if (n > 0)
 
1964
        for (i = x + 1; i < devc->nunits; i++)
 
1965
          if (devc->units[i].mixnum == un->mixnum)
 
1966
            {
 
1967
              usb_audio_unit_t *uu = &devc->units[i];
 
1968
 
 
1969
              switch (uu->mixnum)
 
1970
                {
 
1971
                case SOUND_MIXER_PCM:
 
1972
                  uu->mixnum = SOUND_MIXER_ALTPCM;
 
1973
                  break;
 
1974
                case SOUND_MIXER_LINE:
 
1975
                  uu->mixnum = SOUND_MIXER_LINE1;
 
1976
                  break;
 
1977
                case SOUND_MIXER_LINE1:
 
1978
                  uu->mixnum = SOUND_MIXER_LINE2;
 
1979
                  break;
 
1980
                case SOUND_MIXER_LINE2:
 
1981
                  uu->mixnum = SOUND_MIXER_LINE3;
 
1982
                  break;
 
1983
                case SOUND_MIXER_DIGITAL1:
 
1984
                  uu->mixnum = SOUND_MIXER_DIGITAL2;
 
1985
                  break;
 
1986
                case SOUND_MIXER_DIGITAL2:
 
1987
                  uu->mixnum = SOUND_MIXER_DIGITAL3;
 
1988
                  break;
 
1989
                default:
 
1990
                  uu->mixnum = -1;
 
1991
                }
 
1992
            }
 
1993
 
 
1994
    }
 
1995
 
 
1996
// Handle output selector names
 
1997
 
 
1998
 
 
1999
  for (x = 1; x < devc->nunits; x++)
 
2000
    {
 
2001
      usb_audio_unit_t *un = &devc->units[x];
 
2002
      int n;
 
2003
 
 
2004
      if (un->typ != TY_OUTPUT)
 
2005
        continue;
 
2006
 
 
2007
      n = un->desc[7];          // Source ID
 
2008
      if (n < 0 || n >= devc->nunits)
 
2009
        continue;
 
2010
 
 
2011
      if (devc->units[n].target == 0)
 
2012
        devc->units[n].target = x;
 
2013
 
 
2014
      if (devc->units[n].typ == TY_SELECT && usb_mixerstyle == 0)
 
2015
        sprintf (devc->units[n].name, "%s.src", un->name);
 
2016
    }
 
2017
 
 
2018
// Find out the sources
 
2019
  for (x = 1; x < devc->nunits; x++)
 
2020
    {
 
2021
      usb_audio_unit_t *un = &devc->units[x];
 
2022
 
 
2023
      d = un->desc;
 
2024
      l = un->desclen;
 
2025
 
 
2026
      switch (un->typ)
 
2027
        {
 
2028
        case TY_INPUT:
 
2029
          break;
 
2030
 
 
2031
        case TY_OUTPUT:
 
2032
          un->source = d[7];
 
2033
          break;
 
2034
 
 
2035
        case TY_SELECT:
 
2036
          un->source = d[5];
 
2037
          n = d[4];
 
2038
          for (i = 0; i < n; i++)
 
2039
            if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
 
2040
              if (devc->units[d[i + 5]].target == 0)
 
2041
                devc->units[d[i + 5]].target = x;
 
2042
          break;
 
2043
 
 
2044
        case TY_MIXER:
 
2045
          n = d[4];
 
2046
          un->control_count = n;
 
2047
          un->source = d[5];
 
2048
          for (i = 0; i < n; i++)
 
2049
            if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
 
2050
              if (devc->units[d[i + 5]].target == 0)
 
2051
                devc->units[d[i + 5]].target = x;
 
2052
 
 
2053
          d += n + 5;
 
2054
          un->channels = *d++;
 
2055
          un->chmask = ossusb_get_int (d, 2);
 
2056
          break;
 
2057
 
 
2058
        case TY_FEAT:
 
2059
          un->source = d[4];
 
2060
          if (d[4] > 0 && d[4] <= devc->nunits)
 
2061
            if (devc->units[d[4]].target == 0)
 
2062
              devc->units[d[4]].target = x;
 
2063
          break;
 
2064
 
 
2065
          //case TY_EXT: 
 
2066
        case TY_PROC:
 
2067
          n = d[6];
 
2068
          un->source = d[7];
 
2069
          for (i = 0; i < n; i++)
 
2070
            if (d[i + 7] > 0 && d[i + 7] <= devc->nunits)
 
2071
              if (devc->units[d[i + 7]].target == 0)
 
2072
                devc->units[d[i + 7]].target = x;
 
2073
          break;
 
2074
        }
 
2075
    }
 
2076
 
 
2077
// Trace the channel config
 
2078
 
 
2079
  for (x = 1; x < devc->nunits; x++)
 
2080
    {
 
2081
      usb_audio_unit_t *un = &devc->units[x], *uu;
 
2082
      int ref;
 
2083
 
 
2084
      if (un->typ == TY_INPUT || un->typ == TY_MIXER)
 
2085
        continue;
 
2086
 
 
2087
      if (un->typ == TY_PROC && un->subtyp == 1)        // Upmix/downmix unit
 
2088
        continue;
 
2089
 
 
2090
      ref = follow_source_links (devc, un);
 
2091
      uu = &devc->units[ref];
 
2092
 
 
2093
      un->channels = uu->channels;
 
2094
      un->chmask = uu->chmask;
 
2095
    }
 
2096
 
 
2097
// Handle feature channels
 
2098
  for (x = 1; x < devc->nunits; x++)
 
2099
    {
 
2100
      usb_audio_unit_t *un = &devc->units[x];
 
2101
 
 
2102
      if (un->num == 0 || un->typ != TY_FEAT)
 
2103
        continue;
 
2104
 
 
2105
      d = un->desc;
 
2106
      l = un->desclen;
 
2107
 
 
2108
      un->ctl_avail = get_feature_mask (d, un->channels);
 
2109
    }
 
2110
 
 
2111
// Final checks
 
2112
  for (x = 1; x < devc->nunits; x++)
 
2113
    {
 
2114
      usb_audio_unit_t *un = &devc->units[x];
 
2115
      int j;
 
2116
 
 
2117
      if (un->num == 0)
 
2118
        {
 
2119
          //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
 
2120
          continue;
 
2121
        }
 
2122
      d = un->desc;
 
2123
      l = un->desclen;
 
2124
 
 
2125
      switch (un->typ)
 
2126
        {
 
2127
        case TY_SELECT:
 
2128
          n = d[4];
 
2129
          un->control_count = n;
 
2130
          d += 5;
 
2131
          break;
 
2132
 
 
2133
        case TY_MIXER:
 
2134
          n = d[4];
 
2135
          un->control_count = n;
 
2136
          d += 5;
 
2137
          break;
 
2138
 
 
2139
        case TY_FEAT:
 
2140
          n = d[5];
 
2141
          d += 6;
 
2142
          for (i = 0; i < n * 8; i++)
 
2143
            name = check_feature (un, d, i);
 
2144
          for (j = 1; j <= un->channels; j++)
 
2145
            {
 
2146
              for (i = 0; i < n * 8; i++)
 
2147
                name = check_feature (un, d + j * n, i);
 
2148
            }
 
2149
          break;
 
2150
 
 
2151
        }
 
2152
    }
 
2153
 
 
2154
#if 0
 
2155
// Debugging
 
2156
  if (usb_trace)
 
2157
    for (x = 1; x < devc->nunits; x++)
 
2158
      {
 
2159
        usb_audio_unit_t *un = &devc->units[x];
 
2160
        int j;
 
2161
        int ref = 0;
 
2162
 
 
2163
        if (un->num == 0)
 
2164
          {
 
2165
            //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
 
2166
            continue;
 
2167
          }
 
2168
        d = un->desc;
 
2169
        l = un->desclen;
 
2170
        // ossusb_dump_desc (d, l);
 
2171
        cmn_err (CE_CONT, "%2d: %s  ", un->num, un->name);
 
2172
        if (un->mixnum != -1)
 
2173
          cmn_err (CE_CONT, "mix=%d ", un->mixnum);
 
2174
        if (un->source)
 
2175
          cmn_err (CE_CONT, "source=%d ", un->source);
 
2176
        if (un->target)
 
2177
          cmn_err (CE_CONT, "target=%d ", un->target);
 
2178
        cmn_err (CE_CONT, "ch=%d/%x ", un->channels, un->chmask);
 
2179
 
 
2180
        switch (un->typ)
 
2181
          {
 
2182
          case TY_INPUT:
 
2183
            cmn_err (CE_CONT, "Input terminal type: %04x ",
 
2184
                     ossusb_get_int (&d[4], 2));
 
2185
            cmn_err (CE_CONT, "Associated output 0x%02x ", d[6]);
 
2186
            cmn_err (CE_CONT, "#chn %d ", d[7]);
 
2187
            cmn_err (CE_CONT, "chconf %04x ", ossusb_get_int (&d[8], 2));
 
2188
            if (d[10])
 
2189
              cmn_err (CE_CONT, "chname# %d ", d[10]);
 
2190
            if (d[11])
 
2191
              cmn_err (CE_CONT, "terminalname# %d (%s) ", d[11],
 
2192
                       udi_usbdev_get_string (usbdev, d[11]));
 
2193
            break;
 
2194
 
 
2195
          case TY_OUTPUT:
 
2196
            cmn_err (CE_CONT, "Output terminal type: %04x ",
 
2197
                     ossusb_get_int (&d[4], 2));
 
2198
            cmn_err (CE_CONT, "Associated input 0x%02x ", d[6]);
 
2199
            cmn_err (CE_CONT, "sourceid %d ", d[7]);
 
2200
            if (d[8])
 
2201
              cmn_err (CE_CONT, "terminalname# %d ", d[8]);
 
2202
            break;
 
2203
 
 
2204
          case TY_SELECT:
 
2205
            n = d[4];
 
2206
            d += 5;
 
2207
            cmn_err (CE_CONT, "%d input pins (", n);
 
2208
            for (i = 0; i < n; i++)
 
2209
              {
 
2210
                ref = follow_source_links (devc, &devc->units[*d]);
 
2211
                cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
 
2212
                d++;
 
2213
              }
 
2214
            cmn_err (CE_CONT, ") ");
 
2215
            break;
 
2216
 
 
2217
          case TY_MIXER:
 
2218
            n = d[4];
 
2219
            d += 5;
 
2220
            cmn_err (CE_CONT, "%d inputs (", n);
 
2221
            for (i = 0; i < n; i++)
 
2222
              {
 
2223
                ref = follow_source_links (devc, &devc->units[*d]);
 
2224
                cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
 
2225
                d++;
 
2226
              }
 
2227
            cmn_err (CE_CONT, ") ");
 
2228
            break;
 
2229
 
 
2230
          case TY_FEAT:
 
2231
            //ossusb_dump_desc(d, l);
 
2232
            cmn_err (CE_CONT, "Source %d:%s ", d[4], devc->units[d[4]].name);
 
2233
            n = d[5];
 
2234
            d += 6;
 
2235
            cmn_err (CE_CONT, "main (", n);
 
2236
            for (i = 0; i < n * 8; i++)
 
2237
              if ((name = check_feature (un, d, i)) != NULL)
 
2238
                cmn_err (CE_CONT, "%s ", name);
 
2239
            cmn_err (CE_CONT, ") ");
 
2240
            for (j = 1; j <= un->channels; j++)
 
2241
              {
 
2242
                cmn_err (CE_CONT, "ch %d (", j);
 
2243
                for (i = 0; i < n * 8; i++)
 
2244
                  if ((name = check_feature (un, d + j * n, i)) != NULL)
 
2245
                    cmn_err (CE_CONT, "%s ", name);
 
2246
                cmn_err (CE_CONT, ") ");
 
2247
              }
 
2248
            break;
 
2249
 
 
2250
          case TY_PROC:
 
2251
            cmn_err (CE_CONT, "subtype %x Sources/%d) (", un->subtyp, n);
 
2252
            n = d[6];
 
2253
            d += 7;
 
2254
            cmn_err (CE_CONT, "%d ", *d);
 
2255
            d++;
 
2256
            cmn_err (CE_CONT, ") ");
 
2257
            break;
 
2258
 
 
2259
          case TY_EXT:
 
2260
            cmn_err (CE_CONT, "Extension unit %02x%02x ", d[5], d[4]);
 
2261
            break;
 
2262
 
 
2263
          }
 
2264
 
 
2265
        cmn_err (CE_CONT, "\n");
 
2266
      }
 
2267
#endif
 
2268
 
 
2269
  if (usb_mixerstyle == 0)
 
2270
    setup_legacy_mixer (devc);
 
2271
  touch_mixer (devc->mixer_dev);
 
2272
 
 
2273
  if (usb_trace)
 
2274
    mixer_dump (devc);
 
2275
 
 
2276
  return devc;
 
2277
}
 
2278
 
 
2279
static ossusb_devc *
 
2280
find_devc (char *devpath, int vendor, int product)
 
2281
{
 
2282
  int i;
 
2283
 
 
2284
  for (i = 0; i < ndevs; i++)
 
2285
    {
 
2286
      if (devc_list[i]->vendor == vendor && devc_list[i]->product == product)
 
2287
        if (strcmp (devc_list[i]->devpath, devpath) == 0)
 
2288
          {
 
2289
            UDB (cmn_err (CE_CONT, "Another instance of '%s'\n", devpath));
 
2290
            return devc_list[i];
 
2291
          }
 
2292
    }
 
2293
 
 
2294
  return NULL;
 
2295
}
 
2296
 
 
2297
static void
 
2298
ossusb_device_disconnect (void *d)
 
2299
{
 
2300
  ossusb_devc *devc = d;
 
2301
  int i;
 
2302
 
 
2303
  if (devc == NULL)
 
2304
    {
 
2305
      cmn_err (CE_WARN, "oss_usb_device_disconnect: devc==NULL\n");
 
2306
      return;
 
2307
    }
 
2308
 
 
2309
  if (devc->unload_func)
 
2310
    {
 
2311
      devc->unload_func (devc);
 
2312
      return;
 
2313
    }
 
2314
 
 
2315
  devc->disabled = 1;
 
2316
 
 
2317
  for (i = 0; i < devc->num_audio_engines; i++)
 
2318
    {
 
2319
      int dev;
 
2320
 
 
2321
      dev = devc->portc[i].audio_dev;
 
2322
 
 
2323
      if (dev < 0 || dev >= num_audio_engines)
 
2324
        continue;
 
2325
 
 
2326
      audio_engines[dev]->enabled = 0;
 
2327
 
 
2328
      if (devc->mixer_dev >= 0)
 
2329
        mixer_devs[devc->mixer_dev]->enabled = 0;
 
2330
    }
 
2331
 
 
2332
}
 
2333
 
 
2334
static void *
 
2335
ossusb_device_attach (udi_usb_devc * usbdev, oss_device_t * osdev)
 
2336
{
 
2337
  ossusb_devc *devc;
 
2338
  char *devpath;
 
2339
  int inum;
 
2340
  int old = 1;
 
2341
  int i;
 
2342
  int class, subclass;
 
2343
  int vendor, product, version;
 
2344
 
 
2345
  devpath = udi_usbdev_get_devpath (usbdev);
 
2346
  inum = udi_usbdev_get_inum (usbdev);
 
2347
  class = udi_usbdev_get_class (usbdev);
 
2348
  subclass = udi_usbdev_get_subclass (usbdev);
 
2349
  vendor = udi_usbdev_get_vendor (usbdev);
 
2350
  product = udi_usbdev_get_product (usbdev);
 
2351
  version = udi_usbdev_get_usb_version (usbdev);
 
2352
 
 
2353
  if ((devc = find_devc (devpath, vendor, product)) == NULL)
 
2354
    {
 
2355
      old = 0;
 
2356
 
 
2357
      if (ndevs >= MAX_DEVC)
 
2358
        {
 
2359
          cmn_err (CE_CONT, "Too many USB audio devices\n");
 
2360
          return NULL;
 
2361
        }
 
2362
 
 
2363
      if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
 
2364
        {
 
2365
          cmn_err (CE_CONT, "Out of memory\n");
 
2366
          return NULL;
 
2367
        }
 
2368
      memset (devc, 0, sizeof (*devc));
 
2369
      devc->mixer_dev = -1;
 
2370
 
 
2371
      devc->osdev = osdev;
 
2372
      osdev->devc = devc;
 
2373
 
 
2374
      MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
 
2375
 
 
2376
      devc->vendor = vendor;
 
2377
      devc->product = product;
 
2378
      devc->usb_version = version;
 
2379
      devc->dev_name = udi_usbdev_get_name (usbdev);
 
2380
 
 
2381
      strcpy (devc->devpath, udi_usbdev_get_devpath (usbdev));
 
2382
 
 
2383
      devc_list[ndevs++] = devc;
 
2384
    }
 
2385
  else
 
2386
    {
 
2387
      devc->osdev = osdev;
 
2388
      osdev->devc = devc;
 
2389
    }
 
2390
 
 
2391
  if (devc->dev_name == NULL)
 
2392
    devc->dev_name = "Generic USB device";
 
2393
  oss_register_device (osdev, devc->dev_name);
 
2394
 
 
2395
  devc->disabled = 0;
 
2396
 
 
2397
  if (old)
 
2398
    {
 
2399
      /* Check if this interface number is already seen */
 
2400
      old = 0;
 
2401
      for (i = 0; !old && i < devc->num_interfaces; i++)
 
2402
        if (devc->inum[i] == inum)
 
2403
          old = 1;
 
2404
    }
 
2405
 
 
2406
  if (!old)
 
2407
    {
 
2408
      if (devc->num_interfaces >= MAX_IFACE)
 
2409
        {
 
2410
          cmn_err (CE_CONT, "The device has too many interfaces\n");
 
2411
          return NULL;
 
2412
        }
 
2413
 
 
2414
      devc->usbdev[devc->num_interfaces] = usbdev;
 
2415
      devc->last_usbdev = usbdev;
 
2416
      devc->inum[devc->num_interfaces] = inum;
 
2417
      devc->num_interfaces++;
 
2418
    }
 
2419
  else
 
2420
    {
 
2421
      devc->last_usbdev = usbdev;
 
2422
    }
 
2423
 
 
2424
  switch (class)
 
2425
    {
 
2426
    case USBCLASS_AUDIO:
 
2427
      switch (subclass)
 
2428
        {
 
2429
        case 1:         /* Audiocontrol subclass */
 
2430
          devc->main_osdev = osdev;
 
2431
          if (!usb_quiet)
 
2432
            cmn_err (CE_CONT, "%s audioctl device %s/%d - %s\n",
 
2433
                     old ? "Reinsert of an" : "New",
 
2434
                     devc->devpath, inum, devc->dev_name);
 
2435
          return ossusb_init_audioctl (devc, usbdev, inum, old);
 
2436
          break;
 
2437
 
 
2438
        case 2:         /* Audio streaming subclass */
 
2439
          if (!usb_quiet)
 
2440
            cmn_err (CE_CONT, "%s audio streaming device %s/%d - %s\n",
 
2441
                     old ? "Reinsert of an" : "New",
 
2442
                     devc->devpath, inum, devc->dev_name);
 
2443
          devc->osdev->first_mixer = devc->main_osdev->first_mixer;
 
2444
          return ossusb_init_audiostream (devc, usbdev, inum, old);
 
2445
          break;
 
2446
 
 
2447
        case 3:         /* MIDI streaming subclass */
 
2448
          return NULL;
 
2449
          break;
 
2450
 
 
2451
        default:
 
2452
          cmn_err (CE_CONT,
 
2453
                   "Unknown USB audio device subclass %x:%d, device=%s\n",
 
2454
                   class, subclass, devc->dev_name);
 
2455
          return NULL;
 
2456
        }
 
2457
      break;
 
2458
 
 
2459
#if 0
 
2460
    case USBCLASS_HID:
 
2461
      cmn_err (CE_CONT, "HID interface class %x:%d, device=%s\n",
 
2462
               class, subclass, devc->dev_name);
 
2463
      return NULL;
 
2464
      break;
 
2465
#endif
 
2466
 
 
2467
    default:
 
2468
      cmn_err (CE_CONT, "Unknown USB device class %x:%d, device=%s\n",
 
2469
               class, subclass, devc->dev_name);
 
2470
    }
 
2471
 
 
2472
  return devc;
 
2473
}
 
2474
 
 
2475
static udi_usb_driver ossusb_driver = {
 
2476
  ossusb_device_attach,
 
2477
  ossusb_device_disconnect
 
2478
};
 
2479
 
 
2480
int
 
2481
oss_usb_attach (oss_device_t * osdev)
 
2482
{
 
2483
  if (usb_trace < 0)
 
2484
    {
 
2485
      udi_usb_trace = 0;
 
2486
      usb_trace = 0;
 
2487
      usb_quiet = 1;
 
2488
    }
 
2489
  else if (usb_trace > 0)
 
2490
    udi_usb_trace = usb_trace;
 
2491
 
 
2492
  return udi_attach_usbdriver (osdev, known_devices, &ossusb_driver);
 
2493
}
 
2494
 
 
2495
int
 
2496
oss_usb_detach (oss_device_t * osdev)
 
2497
{
 
2498
  if (oss_disable_device (osdev) < 0)
 
2499
    return 0;
 
2500
 
 
2501
  udi_unload_usbdriver (osdev);
 
2502
  oss_unregister_device (osdev);
 
2503
 
 
2504
  return 1;
 
2505
}