2
* Purpose: Top level USB audio class initialization and mixer functions
7
* This file is part of Open Sound System.
9
* Copyright (C) 4Front Technologies 1996-2008.
11
* This this source file is released under GPL v2 license (no other versions).
12
* See the COPYING file included in the main directory of this source
13
* distribution for the license terms and conditions.
17
#define KBUILD_MODNAME oss_usb
18
#include "oss_config.h"
22
static const udi_usb_devinfo known_devices[] = {
23
{0x763, 0x2002, "M Audio USB AudioSport Duo",
25
{"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
27
{"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
31
{0x763, 0x2001, "M Audio USB AudioSport Quatro"},
32
{0x763, 0x2805, "M Audio Sonica"},
33
{0x763, 0x2007, "M Audio Sonica Theatre",
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}
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",
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},
51
{"OFF 16bit32kHz 24bit32kHz " /* 0-2 */
52
"16bit44kHz 24bit44kHz 16bit48kHz " /* 3-5 */
53
"24bit48kHzin 24bit96kHz 24bit96kHz ", /* 6-8 */
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",
65
{"OFF 7.1 2.0 3.1 5.1 digital", 2},
69
{0x0d8c, 0x0103, "C-Media USB audio"},
70
{-1, -1, "USB sound device"}
76
special_driver_t driver;
80
extern int usb_mixerstyle;
83
static ossusb_devc *devc_list[MAX_DEVC];
89
ossusb_dump_desc (unsigned char *desc, int cfg_len)
93
for (i = 0; i < cfg_len; i++)
96
cmn_err (CE_CONT, "\n%04x: ", i);
97
cmn_err (CE_CONT, "%02x ", desc[i]);
99
cmn_err (CE_CONT, "\n");
103
ossusb_get_int (unsigned char *p, int nbytes)
108
for (i = 0; i < nbytes; i++)
110
v |= (*p++) << (i * 8);
121
decode_vol (usb_control_t * c, unsigned char *buf, int l)
126
value = (signed char) buf[0];
128
value = (signed short) (buf[0] | (buf[1] << 8));
130
range = c->max - c->min;
133
value = (value * c->scale + range / 2) / range;
143
encode_vol (usb_control_t * c, unsigned char *buf, int l, int value)
147
range = c->max - c->min;
149
value = (value * range + c->scale / 2) / c->scale;
157
buf[0] = value & 0xff;
158
buf[1] = (value >> 8) & 0xff;
164
read_feature_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
166
int len, value = 0, l;
168
unsigned char buf[2];
171
* Volume controls use two message bytes while the others use just one.
173
l = (c->index == 1) ? 2 : 1;
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
194
1) ? (signed char) buf[0] : (signed short) (buf[0] | (buf[1] << 8));
199
nch = c->max_ch - c->min_ch + 1;
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
211
// cmn_err(CE_CONT, "feature (%s/%d) read error %d\n", c->unit->name, c->index, len);
216
value = decode_vol (c, buf, len);
219
if (nch == 2) /* Read the right channel */
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
229
value |= (value & 0xff) << 8;
231
value |= (decode_vol (c, buf, len)) << 8;
239
write_feature_value (ossusb_devc * devc, usb_control_t * c, int value)
244
unsigned char buf[2];
251
right = (value >> 8) & 0xff;
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;
258
l = (c->index == 1) ? 2 : 1;
260
nch = c->max_ch - c->min_ch + 1;
262
encode_vol (c, buf, l, left);
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
273
cmn_err (CE_CONT, "feature write error %d\n", len);
277
if (nch == 2) /* Write the right channel */
280
encode_vol (c, buf, l, right);
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
293
value = left | (right << 8);
298
read_mixer_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
301
unsigned char buf[2];
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
315
*v = (signed char) buf[1];
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
328
cmn_err (CE_CONT, "mixer read error %d\n", len);
332
value = buf[1] - c->min;
339
write_mixer_value (ossusb_devc * devc, usb_control_t * c, int value)
342
unsigned char buf[2];
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
357
cmn_err (CE_CONT, "mixer write error %d\n", len);
365
read_unit (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
368
unsigned char buf[2];
372
switch (c->unit->typ)
375
return read_feature_value (devc, c, rq, v);
379
return read_mixer_value (devc, c, rq, v);
383
err = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
384
rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
386
(c->unit->num << 8), // index
392
cmn_err (CE_CONT, "USB mixer unit read error %d\n", err);
405
read_current_value (ossusb_devc * devc, usb_control_t * c)
409
if (!read_unit (devc, c, GET_CUR, &v))
418
write_current_value (ossusb_devc * devc, usb_control_t * c, int value)
420
unsigned char buf[2];
423
switch (c->unit->typ)
429
err = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
430
SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
432
(c->unit->num << 8), // index
438
cmn_err (CE_CONT, "Selector write error %d\n", err);
444
value = write_feature_value (devc, c, value);
448
value = write_mixer_value (devc, c, value);
459
new_ctl (ossusb_devc * devc, usb_audio_unit_t * un, int index, int exttype,
464
int i, min_ch = 0, max_ch = 0;
466
if (devc->ncontrols >= MAX_CONTROLS)
468
cmn_err (CE_CONT, "Too many mixer features.\n");
472
n = devc->ncontrols++;
474
c = &devc->controls[n];
480
for (i = 0; i < 32; i++)
481
if (chmask & (1 << i))
491
c->exttype = exttype;
493
c->global = (chmask == 0) ? 1 : 0;
500
if (index != 1) /* Not volume control */
506
if (read_unit (devc, c, GET_MAX, &max))
509
if (read_unit (devc, c, GET_MIN, &min))
516
if (c->max <= c->min)
519
* The device reported bad limits. Try to fix the situation.
525
if (c->max <= c->min)
533
if (c->max - c->min < 255)
534
c->scale = c->max - c->min;
537
read_current_value (devc, c);
541
cmn_err (CE_CONT, "Ctl %2d: %d/%s %d ", n, c->unit->num, c->unit->name,
543
cmn_err (CE_CONT, "Min %d, max %d, scale %d\n", c->min, c->max,
545
cmn_err (CE_CONT, "ch=%x ", c->chmask);
546
cmn_err (CE_CONT, "Value %04x, (%d - %d, %d)\n", c->value, c->min,
554
mixer_func (int dev, int ctrl, unsigned int cmd, int value)
556
ossusb_devc *devc = mixer_devs[dev]->devc;
562
if (ctrl < 0 || ctrl >= devc->ncontrols)
565
c = &devc->controls[ctrl];
567
if (cmd == SNDCTL_MIX_READ)
572
if (cmd != SNDCTL_MIX_WRITE)
575
value = c->value = write_current_value (devc, c, value);
581
get_feature_name (int n)
621
get_feature_type (int n)
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},
696
count_source_controls (ossusb_devc * devc, int unit)
699
usb_audio_unit_t *un;
702
if (unit <= 0 || unit >= devc->nunits)
705
un = &devc->units[unit];
717
for (i = 0; i < nn; i++)
719
n += count_source_controls (devc, *d);
728
for (i = 0; i < nn; i++)
730
n += count_source_controls (devc, *d);
736
if (un->source <= 0 && un->source < devc->nunits)
738
n = count_source_controls (devc, un->source);
745
return n + un->control_count;
749
count_target_controls (ossusb_devc * devc, int unit)
752
usb_audio_unit_t *un;
754
if (unit <= 0 || unit >= devc->nunits)
757
un = &devc->units[unit];
762
if (un->typ == TY_SELECT || un->typ == TY_MIXER)
766
else if (un->target <= 0 && un->target < devc->nunits)
768
n = count_target_controls (devc, un->target);
774
return n + un->control_count;
778
follow_source_links (ossusb_devc * devc, usb_audio_unit_t * un)
780
while (un->source > 0 && un->source < devc->nunits)
781
un = &devc->units[un->source];
787
follow_target_links (ossusb_devc * devc, usb_audio_unit_t * un)
789
while (un->target > 0 && un->target < devc->nunits)
790
un = &devc->units[un->target];
796
add_controls_for_mixer (ossusb_devc * devc, usb_audio_unit_t * un, int group)
799
unsigned char *d = un->desc;
807
for (i = 0; i < n; i++)
808
if (*d > 0 && *d < devc->nunits)
810
int ref = follow_source_links (devc, &devc->units[*d]);
814
int ctl = new_ctl (devc, un, i, MIXT_MONOSLIDER, un->chmask);
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)
832
add_controls_for_proc (ossusb_devc * devc, usb_audio_unit_t * un, int group)
835
unsigned char *d = un->desc;
843
for (i = 0; i < n; i++)
844
if (*d > 0 && *d < devc->nunits)
853
add_controls_for_selector (ossusb_devc * devc, usb_audio_unit_t * un,
856
static oss_mixer_enuminfo ent;
859
unsigned char *d = un->desc;
860
int ctl = new_ctl (devc, un, 0, MIXT_ENUM, 0);
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,
872
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
875
memset (&ent, 0, sizeof (ent));
879
for (i = 0; i < n; i++)
880
if (*d > 0 && *d < devc->nunits)
882
int ref = follow_source_links (devc, &devc->units[*d]);
887
strcpy (s, devc->units[ref].name);
892
for (i = 0; i < strlen (s); i++)
900
ent.dev = devc->mixer_dev;
904
mixer_ext_set_enum (&ent);
911
add_multich_volumes (ossusb_devc * devc, usb_audio_unit_t * un, int group,
912
int fea, int mask, unsigned int *feature_mask)
916
for (i = 0; mask != 0 && chmasks[i].mask != 0; i++)
918
int m = chmasks[i].mask;
925
ctl = new_ctl (devc, un, fea, chmasks[i].type, chmasks[i].mask);
926
c = &devc->controls[ctl];
929
(CE_CONT, "Add multich feature control %d/%s\n", un->num,
931
if (mixer_ext_create_control (devc->mixer_dev, group, ctl, mixer_func,
932
chmasks[i].type, chmasks[i].name,
934
MIXF_READABLE | MIXF_WRITEABLE) < 0)
941
cmn_err (CE_CONT, "Warning! Unsupported channels (%02x)\n", mask);
945
translate_feature_mask_usb2 (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
948
unsigned char *d = un->desc;
951
d = d + 5 + n; // Skip the global mask
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
957
for (c = 0; c < un->channels; c++)
960
unsigned char *p = d + c * n;
967
for (i = 0; i < n * 4; i++)
968
if ((mask & (3 << 2*i)) && (un->ctl_avail & (1 << i)))
970
feature_mask[i] |= 1 << c;
976
translate_feature_mask (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
979
unsigned char *d = un->desc;
981
if (devc->usb_version > 1)
983
translate_feature_mask_usb2(devc, un, feature_mask);
990
cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
994
d = d + 6 + n; // Skip the global mask
996
for (c = 0; c < un->channels; c++)
1000
mask |= d[c * n + 1];
1002
for (i = 0; i < n * 8; i++)
1003
if ((mask & (1 << i)) && (un->ctl_avail & (1 << i)))
1005
feature_mask[i] |= 1 << c;
1011
add_controls_for_feature (ossusb_devc * devc, usb_audio_unit_t * un,
1015
unsigned int feature_mask[16], global_mask;
1020
// Handle the global controls first
1022
global_mask = un->desc[6];
1023
if (un->desc[5] > 0)
1024
global_mask |= un->desc[7] << 8;
1026
for (i = 0; i < 11; i++)
1027
if (un->ctl_avail & (1 << i) && (global_mask & (1 << i)))
1029
char *name = get_feature_name (i);
1030
int type = get_feature_type (i);
1035
ctl = new_ctl (devc, un, i, type, 0);
1037
if (type == MIXT_SLIDER)
1038
max = devc->controls[ctl].max - devc->controls[ctl].min;
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)
1052
//un->ctl_avail &= ~(1 << i);
1055
// Handle the channelized controls
1057
if (un->ctl_avail == 0) /* Nothing left */
1060
// Translate the channel/feature availability matrix
1062
memset (feature_mask, 0, sizeof (feature_mask));
1063
translate_feature_mask (devc, un, feature_mask);
1065
for (i = 0; i < 16; i++)
1066
if (feature_mask[i])
1068
char *name = get_feature_name (i);
1069
int type = get_feature_type (i);
1070
int max, instances = 0;
1074
for (j = 0; j < 16; j++)
1075
if (feature_mask[i] & (1 << j))
1078
if (type == MIXT_SLIDER)
1082
type = MIXT_MONOSLIDER;
1087
type = MIXT_STEREOSLIDER;
1092
type = MIXT_MONOSLIDER;
1093
if (i == 1) /* "volume" */
1098
type = MIXT_MONOSLIDER;
1106
if (instances && (instances > 1 || feature_mask[i] > 0x0003))
1111
UDB (cmn_err (CE_CONT, "Add feature group %s\n", tmp));
1113
mixer_ext_create_group (devc->mixer_dev, group, tmp)) < 0)
1116
add_multich_volumes (devc, un, g, i, feature_mask[i],
1122
int ctl = new_ctl (devc, un, i, type, un->chmask);
1124
max = devc->controls[ctl].max - devc->controls[ctl].min;
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)
1137
un->ctl_avail = 0; // All done (hope so)
1141
traverse_source_controls (ossusb_devc * devc, usb_audio_unit_t * un,
1148
if (un->typ == TY_MIXER)
1150
add_controls_for_mixer (devc, un, group);
1154
if (un->typ == TY_PROC)
1156
add_controls_for_proc (devc, un, group);
1158
if (d[6] > 1) /* More than 1 sources */
1162
if (un->typ == TY_SELECT)
1164
add_controls_for_selector (devc, un, group);
1168
if (un->source > 0 && un->source < devc->nunits)
1170
traverse_source_controls (devc, &devc->units[un->source], group);
1173
if (un->typ == TY_FEAT)
1175
add_controls_for_feature (devc, un, group);
1180
traverse_target_controls (ossusb_devc * devc, usb_audio_unit_t * un,
1188
if (un->typ == TY_SELECT)
1190
add_controls_for_selector (devc, un, group);
1193
if (un->typ == TY_PROC || un->typ == TY_EXT)
1194
if (d[6] > 1) // More than 1 input pins
1197
if (un->typ == TY_MIXER)
1200
add_controls_for_mixer (devc, un, group);
1204
if (un->target > 0 && un->target < devc->nunits)
1205
traverse_target_controls (devc, &devc->units[un->target], group);
1207
if (un->typ == TY_FEAT)
1209
add_controls_for_feature (devc, un, group);
1214
ossusb_create_altset_control (int dev, int portc_num, int nalt, char *name)
1217
ossusb_devc *devc = mixer_devs[dev]->devc;
1219
int default_altsetting;
1220
unsigned int altsetting_mask;
1222
if (nalt < 3) /* Only one alternative setting (plus "OFF") available */
1225
udi_usbdev_get_altsetting_labels (devc->mixer_usbdev, portc_num,
1226
&default_altsetting,
1227
&altsetting_mask)) != NULL)
1229
if (altsetting_mask != 0)
1232
* Check if more than one of them are enabled.
1237
for (i = 1; i < nalt; i++)
1238
if (altsetting_mask & (1 << i))
1246
if ((ctl = mixer_ext_create_control (dev, 0,
1247
portc_num, ossusb_change_altsetting,
1250
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1253
if (as != NULL) /* Use custom labels */
1255
mixer_ext_set_strings (dev, ctl, as, 0);
1256
if (altsetting_mask != 0)
1261
ext = mixer_find_ext (dev, ctl);
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));
1269
if (default_altsetting > 0)
1270
ossusb_change_altsetting (dev, portc_num, SNDCTL_MIX_WRITE,
1271
default_altsetting);
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",
1281
usb_mix_init (int dev)
1286
devc = mixer_devs[dev]->devc;
1288
for (i = 0; i < devc->nunits; i++)
1290
usb_audio_unit_t *un = &devc->units[i];
1292
if (un->typ == TY_OUTPUT)
1294
if (count_source_controls (devc, un->source) == 0)
1299
if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
1302
traverse_source_controls (devc, un, group);
1307
for (i = 0; i < devc->nunits; i++)
1309
usb_audio_unit_t *un = &devc->units[i];
1311
if (un->typ == TY_INPUT)
1313
if (count_target_controls (devc, un->target) == 0)
1318
if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
1321
traverse_target_controls (devc, un, group);
1331
check_feature (usb_audio_unit_t * un, unsigned char *mask, int n)
1333
if (mask[n / 8] & (1 << (n % 8)))
1335
un->control_count++;
1337
return get_feature_name (n);
1345
usb_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
1347
ossusb_devc *devc = mixer_devs[dev]->hw_devc;
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;
1367
static mixer_driver_t usb_mixer_driver = {
1372
init_mixer (ossusb_devc * devc)
1374
if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
1379
sizeof (mixer_driver_t),
1384
sprintf (mxname, "USB_%d", ndevs);
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);
1394
static usb_audio_unit_t *
1395
setup_unit (ossusb_devc * devc, int unit, char *name, unsigned char *desc,
1396
int desclen, int typ)
1398
usb_audio_unit_t *un;
1400
if (unit < 0 || unit >= MAX_UNIT)
1402
cmn_err (CE_WARN, "Bad unit number %d\n", unit);
1406
if (typ >= sizeof (devc->unit_counters))
1408
cmn_err (CE_WARN, "Bad unit type %d\n", typ);
1412
devc->unit_counters[typ]++;
1414
if (unit >= devc->nunits)
1415
devc->nunits = unit + 1;
1417
un = &devc->units[unit];
1422
un->desclen = desclen;
1426
strcpy (un->name, name);
1432
get_terminal_id (int type, char *def, int typ, int *mn)
1443
if (typ == TY_INPUT)
1445
*mixnum = SOUND_MIXER_PCM;
1448
if (typ == TY_OUTPUT)
1450
*mixnum = SOUND_MIXER_RECLEV;
1455
*mixnum = SOUND_MIXER_VOLUME;
1458
*mixnum = SOUND_MIXER_VOLUME;
1479
*mixnum = SOUND_MIXER_LINE1;
1482
*mixnum = SOUND_MIXER_LINE2;
1487
*mixnum = SOUND_MIXER_LINE;
1490
*mixnum = SOUND_MIXER_SPEAKER;
1493
*mixnum = SOUND_MIXER_DIGITAL1;
1494
if (typ == TY_INPUT)
1508
*mixnum = SOUND_MIXER_CD;
1519
*mixnum = SOUND_MIXER_VIDEO;
1530
*mixnum = SOUND_MIXER_RADIO;
1533
*mixnum = SOUND_MIXER_RADIO;
1538
*mixnum = SOUND_MIXER_SYNTH;
1542
if (type < 0x201) // Unknown type
1547
*mixnum = SOUND_MIXER_MIC;
1555
setup_legacy_mixer (ossusb_devc * devc)
1559
// Set up the recording selector
1561
for (x = 1; x < devc->nunits; x++)
1563
usb_audio_unit_t *un = &devc->units[x];
1565
unsigned char *d = un->desc;
1567
if (un->typ != TY_SELECT || strcmp (un->name, "rec.src") != 0)
1576
devc->num_recdevs = n = d[4];
1578
for (i = 0; i < n; i++)
1580
int ref = follow_source_links (devc, &devc->units[*d]);
1585
if (ref < 1 || ref >= devc->nunits || devc->units[ref].mixnum == -1)
1588
mask = (1 << devc->units[ref].mixnum);
1589
if (devc->recmask & mask) // Duplicate
1592
(CE_CONT, "Recsrc %d, num=%d, mask %x\n", i, ref, mask));
1594
devc->recdevs[i] = mask;
1596
devc->recmask |= mask;
1597
if (devc->recsrc == 0)
1598
devc->recsrc = mask;
1604
// Set up the legacy mixer controls
1606
for (x = 1; x < devc->nunits; x++)
1608
usb_audio_unit_t *un = &devc->units[x];
1610
unsigned char *d = un->desc;
1612
if (!(un->ctl_avail & 0x02))
1615
if (un->typ == TY_FEAT && d[6] & 0x02) // Volume control
1618
mixnum = un->mixnum;
1622
t = follow_target_links (devc, un);
1623
if (t && devc->units[t].mixnum != -1)
1624
mixnum = devc->units[t].mixnum;
1627
t = follow_source_links (devc, un);
1628
if (t && devc->units[t].mixnum != -1)
1629
mixnum = devc->units[t].mixnum;
1633
if (mixnum == -1 || un->channels > 2)
1635
UDB (cmn_err (CE_CONT, "Unit %d is volume %d\n", x, mixnum));
1636
un->ctl_avail &= ~0x02; // Reserve the volume slider
1638
devc->devmask |= (1 << mixnum);
1639
if (un->channels == 2)
1640
devc->stereodevs |= (1 << mixnum);
1649
get_processor_type (int t)
1671
parse_processing_unit (ossusb_devc * devc, unsigned char *d, int l)
1673
usb_audio_unit_t *un;
1676
name = get_processor_type (d[4]);
1678
if ((un = setup_unit (devc, d[3], name, d, l, TY_PROC)) == NULL)
1683
if (un->subtyp == 1) // Upmix/downmix unit
1685
un->channels = d[8];
1686
un->chmask = ossusb_get_int (&d[9], 2);
1691
get_feature_mask (unsigned char *d, int channels)
1693
int i, n, mask = 0, v;
1696
for (i = 0; i <= channels; i++)
1700
v |= d[6 + i * n + 1] << 8;
1710
mixer_dump (ossusb_devc * devc)
1713
usb_audio_unit_t *un;
1715
for (i = 1; i < devc->nunits; i++)
1717
un = &devc->units[i];
1719
if (un->typ == TY_FEAT)
1721
cmn_err (CE_CONT, "Unit %d\n", un->num);
1723
for (j = 0; j < 8; j++)
1725
for (c = 0; c < 7; c++)
1727
unsigned char buf[2];
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
1741
cmn_err (CE_CONT, " Feature %d/%d, ch %d: ", un->num, j,
1743
cmn_err (CE_CONT, "%02x%02x ", buf[0], buf[1]);
1746
cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
1748
cmn_err (CE_CONT, "(%d) ",
1749
(signed short) (buf[0] | (buf[1] << 8)));
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
1761
cmn_err (CE_CONT, "Min=%02x%02x ", buf[0], buf[1]);
1763
cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
1765
cmn_err (CE_CONT, "(%d) ",
1766
(signed short) (buf[0] | (buf[1] << 8)));
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
1778
cmn_err (CE_CONT, "max=%02x%02x ", buf[0], buf[1]);
1780
cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
1782
cmn_err (CE_CONT, "(%d) ",
1783
(signed short) (buf[0] | (buf[1] << 8)));
1785
cmn_err (CE_CONT, "\n");
1794
static ossusb_devc *
1795
ossusb_init_audioctl (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
1799
unsigned char *desc, *d;
1800
int i, l, n = 0, p, x, mixnum = -1;
1802
usb_audio_unit_t *un;
1804
/* nsettings = udi_usbdev_get_num_altsettings (usbdev); */
1805
devc->mixer_usbdev = usbdev;
1807
if (!init_mixer (devc))
1810
desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
1814
cmn_err (CE_CONT, "Can't read interface descriptors\n");
1819
while (p < desc_len)
1826
char str[256], *s = str;
1827
sprintf (s, "Control desc(%d): ", p);
1829
for (i = 0; i < l; i++)
1831
sprintf (s, "%02x ", d[i]);
1834
cmn_err (CE_CONT, "%s\n", str);
1837
#define CASE(x) case x:cmn_err(CE_CONT, #x "\n"); break;
1839
if (d[1] == CS_INTERFACE)
1845
cmn_err (CE_CONT, " Audio control interface header\n");
1847
cmn_err (CE_CONT, " %d related streaming interfaces: ",
1849
for (i = 0; i < n; i++)
1851
cmn_err (CE_CONT, "%d ", d[8 + i]);
1853
cmn_err (CE_CONT, "\n");
1857
case AC_INPUT_TERMINAL:
1859
get_terminal_id (ossusb_get_int (&d[4], 2), "in", TY_INPUT,
1861
if ((un = setup_unit (devc, d[3], name, d, l, TY_INPUT)) == NULL)
1863
un->mixnum = mixnum;
1864
un->channels = d[7];
1865
un->chmask = ossusb_get_int (&d[8], 2);
1868
case AC_OUTPUT_TERMINAL:
1870
get_terminal_id (ossusb_get_int (&d[4], 2), "out", TY_OUTPUT,
1872
if ((un = setup_unit (devc, d[3], name, d, l, TY_OUTPUT)) == NULL)
1874
un->mixnum = mixnum;
1878
if ((un = setup_unit (devc, d[3], "mix", d, l, TY_MIXER)) == NULL)
1881
// Check if there are any visible controls
1885
n = d[4]; // # of input pins
1887
nn = *d; // # of channels
1888
d += 4; // Seek to bmControls
1890
n = (n * nn + 7) / 8;
1892
for (i = 0; i < n; i++)
1895
un->ctl_avail = mask;
1899
case AC_SELECTOR_UNIT:
1901
setup_unit (devc, d[3], "src", d, l, TY_SELECT)) == NULL)
1906
case AC_FEATURE_UNIT:
1907
if ((un = setup_unit (devc, d[3], "fea", d, l, TY_FEAT)) == NULL)
1909
un->ctl_avail = get_feature_mask (d, 2); /* For now */
1912
case AC_PROCESSING_UNIT:
1913
parse_processing_unit (devc, d, l);
1916
case AC_EXTENSION_UNIT:
1917
if ((un = setup_unit (devc, d[3], "ext", d, l, TY_EXT)) == NULL)
1928
// Make sure the unit names are unique */
1930
for (x = 1; x < devc->nunits; x++)
1932
usb_audio_unit_t *un = &devc->units[x];
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)
1943
strcpy (tmpname, un->name);
1946
for (i = x; i < devc->nunits; i++)
1947
if (strcmp (devc->units[i].name, tmpname) == 0)
1950
sprintf (devc->units[i].name, "%s%d", tmpname, n);
1955
// Make sure the mixer control numbers are unique too
1958
if (un->mixnum != -1)
1959
for (i = x + 1; i < devc->nunits; i++)
1960
if (devc->units[i].mixnum == un->mixnum)
1964
for (i = x + 1; i < devc->nunits; i++)
1965
if (devc->units[i].mixnum == un->mixnum)
1967
usb_audio_unit_t *uu = &devc->units[i];
1971
case SOUND_MIXER_PCM:
1972
uu->mixnum = SOUND_MIXER_ALTPCM;
1974
case SOUND_MIXER_LINE:
1975
uu->mixnum = SOUND_MIXER_LINE1;
1977
case SOUND_MIXER_LINE1:
1978
uu->mixnum = SOUND_MIXER_LINE2;
1980
case SOUND_MIXER_LINE2:
1981
uu->mixnum = SOUND_MIXER_LINE3;
1983
case SOUND_MIXER_DIGITAL1:
1984
uu->mixnum = SOUND_MIXER_DIGITAL2;
1986
case SOUND_MIXER_DIGITAL2:
1987
uu->mixnum = SOUND_MIXER_DIGITAL3;
1996
// Handle output selector names
1999
for (x = 1; x < devc->nunits; x++)
2001
usb_audio_unit_t *un = &devc->units[x];
2004
if (un->typ != TY_OUTPUT)
2007
n = un->desc[7]; // Source ID
2008
if (n < 0 || n >= devc->nunits)
2011
if (devc->units[n].target == 0)
2012
devc->units[n].target = x;
2014
if (devc->units[n].typ == TY_SELECT && usb_mixerstyle == 0)
2015
sprintf (devc->units[n].name, "%s.src", un->name);
2018
// Find out the sources
2019
for (x = 1; x < devc->nunits; x++)
2021
usb_audio_unit_t *un = &devc->units[x];
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;
2046
un->control_count = n;
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;
2054
un->channels = *d++;
2055
un->chmask = ossusb_get_int (d, 2);
2060
if (d[4] > 0 && d[4] <= devc->nunits)
2061
if (devc->units[d[4]].target == 0)
2062
devc->units[d[4]].target = x;
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;
2077
// Trace the channel config
2079
for (x = 1; x < devc->nunits; x++)
2081
usb_audio_unit_t *un = &devc->units[x], *uu;
2084
if (un->typ == TY_INPUT || un->typ == TY_MIXER)
2087
if (un->typ == TY_PROC && un->subtyp == 1) // Upmix/downmix unit
2090
ref = follow_source_links (devc, un);
2091
uu = &devc->units[ref];
2093
un->channels = uu->channels;
2094
un->chmask = uu->chmask;
2097
// Handle feature channels
2098
for (x = 1; x < devc->nunits; x++)
2100
usb_audio_unit_t *un = &devc->units[x];
2102
if (un->num == 0 || un->typ != TY_FEAT)
2108
un->ctl_avail = get_feature_mask (d, un->channels);
2112
for (x = 1; x < devc->nunits; x++)
2114
usb_audio_unit_t *un = &devc->units[x];
2119
//cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
2129
un->control_count = n;
2135
un->control_count = n;
2142
for (i = 0; i < n * 8; i++)
2143
name = check_feature (un, d, i);
2144
for (j = 1; j <= un->channels; j++)
2146
for (i = 0; i < n * 8; i++)
2147
name = check_feature (un, d + j * n, i);
2157
for (x = 1; x < devc->nunits; x++)
2159
usb_audio_unit_t *un = &devc->units[x];
2165
//cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
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);
2175
cmn_err (CE_CONT, "source=%d ", un->source);
2177
cmn_err (CE_CONT, "target=%d ", un->target);
2178
cmn_err (CE_CONT, "ch=%d/%x ", un->channels, un->chmask);
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));
2189
cmn_err (CE_CONT, "chname# %d ", d[10]);
2191
cmn_err (CE_CONT, "terminalname# %d (%s) ", d[11],
2192
udi_usbdev_get_string (usbdev, d[11]));
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]);
2201
cmn_err (CE_CONT, "terminalname# %d ", d[8]);
2207
cmn_err (CE_CONT, "%d input pins (", n);
2208
for (i = 0; i < n; i++)
2210
ref = follow_source_links (devc, &devc->units[*d]);
2211
cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
2214
cmn_err (CE_CONT, ") ");
2220
cmn_err (CE_CONT, "%d inputs (", n);
2221
for (i = 0; i < n; i++)
2223
ref = follow_source_links (devc, &devc->units[*d]);
2224
cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
2227
cmn_err (CE_CONT, ") ");
2231
//ossusb_dump_desc(d, l);
2232
cmn_err (CE_CONT, "Source %d:%s ", d[4], devc->units[d[4]].name);
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++)
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, ") ");
2251
cmn_err (CE_CONT, "subtype %x Sources/%d) (", un->subtyp, n);
2254
cmn_err (CE_CONT, "%d ", *d);
2256
cmn_err (CE_CONT, ") ");
2260
cmn_err (CE_CONT, "Extension unit %02x%02x ", d[5], d[4]);
2265
cmn_err (CE_CONT, "\n");
2269
if (usb_mixerstyle == 0)
2270
setup_legacy_mixer (devc);
2271
touch_mixer (devc->mixer_dev);
2279
static ossusb_devc *
2280
find_devc (char *devpath, int vendor, int product)
2284
for (i = 0; i < ndevs; i++)
2286
if (devc_list[i]->vendor == vendor && devc_list[i]->product == product)
2287
if (strcmp (devc_list[i]->devpath, devpath) == 0)
2289
UDB (cmn_err (CE_CONT, "Another instance of '%s'\n", devpath));
2290
return devc_list[i];
2298
ossusb_device_disconnect (void *d)
2300
ossusb_devc *devc = d;
2305
cmn_err (CE_WARN, "oss_usb_device_disconnect: devc==NULL\n");
2309
if (devc->unload_func)
2311
devc->unload_func (devc);
2317
for (i = 0; i < devc->num_audio_engines; i++)
2321
dev = devc->portc[i].audio_dev;
2323
if (dev < 0 || dev >= num_audio_engines)
2326
audio_engines[dev]->enabled = 0;
2328
if (devc->mixer_dev >= 0)
2329
mixer_devs[devc->mixer_dev]->enabled = 0;
2335
ossusb_device_attach (udi_usb_devc * usbdev, oss_device_t * osdev)
2342
int class, subclass;
2343
int vendor, product, version;
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);
2353
if ((devc = find_devc (devpath, vendor, product)) == NULL)
2357
if (ndevs >= MAX_DEVC)
2359
cmn_err (CE_CONT, "Too many USB audio devices\n");
2363
if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
2365
cmn_err (CE_CONT, "Out of memory\n");
2368
memset (devc, 0, sizeof (*devc));
2369
devc->mixer_dev = -1;
2371
devc->osdev = osdev;
2374
MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
2376
devc->vendor = vendor;
2377
devc->product = product;
2378
devc->usb_version = version;
2379
devc->dev_name = udi_usbdev_get_name (usbdev);
2381
strcpy (devc->devpath, udi_usbdev_get_devpath (usbdev));
2383
devc_list[ndevs++] = devc;
2387
devc->osdev = osdev;
2391
if (devc->dev_name == NULL)
2392
devc->dev_name = "Generic USB device";
2393
oss_register_device (osdev, devc->dev_name);
2399
/* Check if this interface number is already seen */
2401
for (i = 0; !old && i < devc->num_interfaces; i++)
2402
if (devc->inum[i] == inum)
2408
if (devc->num_interfaces >= MAX_IFACE)
2410
cmn_err (CE_CONT, "The device has too many interfaces\n");
2414
devc->usbdev[devc->num_interfaces] = usbdev;
2415
devc->last_usbdev = usbdev;
2416
devc->inum[devc->num_interfaces] = inum;
2417
devc->num_interfaces++;
2421
devc->last_usbdev = usbdev;
2426
case USBCLASS_AUDIO:
2429
case 1: /* Audiocontrol subclass */
2430
devc->main_osdev = osdev;
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);
2438
case 2: /* Audio streaming subclass */
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);
2447
case 3: /* MIDI streaming subclass */
2453
"Unknown USB audio device subclass %x:%d, device=%s\n",
2454
class, subclass, devc->dev_name);
2461
cmn_err (CE_CONT, "HID interface class %x:%d, device=%s\n",
2462
class, subclass, devc->dev_name);
2468
cmn_err (CE_CONT, "Unknown USB device class %x:%d, device=%s\n",
2469
class, subclass, devc->dev_name);
2475
static udi_usb_driver ossusb_driver = {
2476
ossusb_device_attach,
2477
ossusb_device_disconnect
2481
oss_usb_attach (oss_device_t * osdev)
2489
else if (usb_trace > 0)
2490
udi_usb_trace = usb_trace;
2492
return udi_attach_usbdriver (osdev, known_devices, &ossusb_driver);
2496
oss_usb_detach (oss_device_t * osdev)
2498
if (oss_disable_device (osdev) < 0)
2501
udi_unload_usbdriver (osdev);
2502
oss_unregister_device (osdev);