2
* Purpose: USB audio streaming interface support
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
10
* This this source file is released under GPL v2 license (no other versions).
11
* See the COPYING file included in the main directory of this source
12
* distribution for the license terms and conditions.
16
#include "oss_config.h"
19
#define SAMPLING_FREQ_CONTROL 0x01
20
#define PITCH_CONTROL 0x02
22
#define FORMAT_II_UNDEFINED 0x1000
23
#define FORMAT_II_MPEG 0x1001
24
#define FORMAT_II_AC3 0x1002
26
#define TMPBUF_SIZE 4096
30
read_control_value (ossusb_devc * devc, int endpoint, int ctl, int l)
35
memset (buf, 0, sizeof (buf));
37
len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
38
GET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
46
cmn_err (CE_WARN, "Endpoint read error %d\n", len);
50
cmn_err (CE_CONT, "Read len %d (%d): ", len, l);
51
for (i = 0; i < len; i++)
52
cmn_err (CE_CONT, "%02x ", buf[i]);
57
v = buf[0] | (buf[1] << 8) | (buf[2] << 16);
61
cmn_err (CE_CONT, "oss usbaudio: Bad control read (%d)\n", l);
64
cmn_err (CE_CONT, "= %d\n", v);
71
write_control_value (ossusb_devc * devc, udi_endpoint_handle_t * endpoint,
72
int ctl, int l, unsigned int v)
77
memset (buf, 0, sizeof (buf));
83
buf[1] = (v >> 8) & 0xff;
84
buf[2] = (v >> 16) & 0xff;
88
cmn_err (CE_CONT, "oss usbaudio: Bad control size %d\n", l);
92
len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
93
SET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
95
udi_endpoint_get_num (endpoint), // index
101
cmn_err (CE_WARN, "Endpoint control write error %d\n", len);
109
set_fraglimits (adev_t * adev, ossusb_portc * portc)
113
if (portc->bytes_per_sample < 1)
114
portc->bytes_per_sample = 1;
116
l = portc->bytes_per_sample * adev->min_channels * portc->speed / 1000;
117
l = (l / portc->bytes_per_sample) * portc->bytes_per_sample;
125
adev->max_block = TMPBUF_SIZE / 2;
126
portc->fragment_size = l;
130
usbaudio_set_rate (int dev, int arg)
132
adev_p adev = audio_engines[dev];
133
ossusb_portc *portc = adev->portc;
134
ossusb_devc *devc = adev->devc;
136
int i, x, diff, bestdiff;
144
if (arg < adev->min_rate)
145
arg = adev->min_rate;
146
if (arg > adev->max_rate)
147
arg = adev->max_rate;
149
if (!(adev->caps & PCM_CAP_FREERATE))
151
/* Search for the nearest supported rate */
152
bestdiff = 0x7fffffff;
155
for (i = 0; i < adev->nrates; i++)
157
diff = arg - adev->rates[i];
160
diff = -diff; /* ABS */
169
arg = adev->rates[x];
173
set_fraglimits (adev, portc);
180
usbaudio_set_channels (int dev, short arg)
182
adev_p adev = audio_engines[dev];
183
ossusb_devc *devc = adev->devc;
188
return adev->min_channels; /* max_channels should be the same too */
193
usbaudio_set_format (int dev, unsigned int arg)
195
adev_p adev = audio_engines[dev];
196
ossusb_devc *devc = adev->devc;
199
return adev->oformat_mask;
201
return adev->oformat_mask; /* iformat_mask should be the same too */
206
usbaudio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
208
ossusb_devc *devc = audio_engines[dev]->devc;
217
setup_format_I (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
218
unsigned char *d, int l)
220
int min_rate = 0, max_rate = 0;
222
int frame_size, bits, channels;
223
unsigned int fmt = 0;
228
"AS_FORMAT_TYPE: FORMAT_TYPE_I, #ch %d, framesize %d, bits %d, freq_type %02x, freq=",
229
d[4], d[5], d[6], d[7]);
231
cmn_err (CE_CONT, "%d-%d ", ossusb_get_int (&d[8], 3),
232
ossusb_get_int (&d[11], 3));
234
for (i = 0; i < d[7]; i++)
235
cmn_err (CE_CONT, "%d ", ossusb_get_int (&d[8 + i * 3], 3));
236
cmn_err (CE_CONT, " ");
242
cmn_err (CE_CONT, "Undefined ");
245
cmn_err (CE_CONT, "PCM ");
248
cmn_err (CE_CONT, "PCM8 ");
251
cmn_err (CE_CONT, "float ");
254
cmn_err (CE_CONT, "A-Law ");
257
cmn_err (CE_CONT, "u-Law ");
260
cmn_err (CE_CONT, "\n");
266
UDB (cmn_err (CE_CONT, "Channels %d, bits %d (%d bytes)\n", channels, bits,
269
adev->min_channels = adev->max_channels = channels;
270
portc->convert_3byte = 0;
291
if (fmt == AFMT_S16_LE) /* Have to check the frame size too */
304
portc->convert_3byte = 1;
312
portc->bytes_per_sample = frame_size;
313
adev->oformat_mask = adev->iformat_mask = fmt;
314
UDB (cmn_err (CE_CONT, "Format mask %08x\n", fmt));
316
adev->caps &= ~PCM_CAP_FREERATE;
318
if (n < 1) /* Free rate selection between min (0) and max (1) */
321
adev->caps |= PCM_CAP_FREERATE;
324
min_rate = 0x7fffffff;
329
cmn_err (CE_WARN, "The device supports too many sample rates\n");
335
for (i = 0; i < n; i++)
337
int rate = ossusb_get_int (&d[8 + i * 3], 3);
340
/* Skip rates that are not multiples of 1000 Hz */
349
adev->rates[adev->nrates++] = rate;
352
adev->min_rate = min_rate;
353
adev->max_rate = max_rate;
354
UDB (cmn_err (CE_CONT, "Min rate %d, max rate %d\n", min_rate, max_rate));
356
adev->caps &= ~DSP_CH_MASK;
361
adev->caps |= DSP_CH_MONO;
364
adev->caps |= DSP_CH_STEREO;
367
adev->caps |= DSP_CH_MULTI;
375
setup_format_II (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
376
unsigned char *d, int l)
378
int min_rate = 0, max_rate = 0;
383
cmn_err (CE_CONT, "MaxBitRate %d ", d[4]);
384
cmn_err (CE_CONT, "SamplesPerFrame %d ", d[5]);
387
cmn_err (CE_CONT, "Sample Rates %d-%d ", ossusb_get_int (&d[9], 3),
388
ossusb_get_int (&d[12], 3));
392
int min_rate = 0x7fffffff;
399
cmn_err (CE_CONT, "oss usbaudio: Too many sample rates (%d)\n",
405
cmn_err (CE_CONT, "Possible sample rates: ");
406
for (i = 0; i < d[8]; i++)
408
int rate = ossusb_get_int (&d[9 + i * 3], 3);
411
/* Skip rates that are not multiples of 1000 Hz */
420
cmn_err (CE_CONT, "%d ", rate);
421
adev->rates[adev->nrates++] = rate;
423
adev->min_rate = min_rate;
424
adev->max_rate = max_rate;
427
cmn_err (CE_CONT, "\n");
430
adev->caps &= ~PCM_CAP_FREERATE;
433
min_rate = ossusb_get_int (&d[9], 3);
434
max_rate = ossusb_get_int (&d[12], 3);
435
adev->caps |= PCM_CAP_FREERATE;
442
for (i = 0; i < d[8]; i++)
444
int r = ossusb_get_int (&d[9 + i * 3], 3);
453
adev->min_channels = adev->max_channels = 2;
454
adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
455
adev->min_rate = min_rate;
456
adev->max_rate = max_rate;
463
setup_format_specific (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
464
unsigned char *d, int l)
468
fmt = ossusb_get_int (&d[3], 2);
471
cmn_err (CE_CONT, "Format specific: fmt=%04x\n", fmt);
477
cmn_err (CE_CONT, "MPEG format\n");
478
adev->oformat_mask = adev->iformat_mask = AFMT_MPEG;
483
cmn_err (CE_CONT, "AC3 format\n");
484
adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
486
cmn_err (CE_CONT, "BSID=%08x\n", ossusb_get_int (&d[5], 4));
487
cmn_err (CE_CONT, "AC3Features %02x\n", d[9]);
492
cmn_err (CE_CONT, "oss usbaudio: Unsupported FORMAT II tag %04x\n",
501
prepare_altsetting (ossusb_devc * devc, ossusb_portc * portc, int new_setting)
504
unsigned char *desc, *d;
509
adev = audio_engines[portc->audio_dev];
513
if (portc->act_setting == new_setting) /* No need to change */
516
if (new_setting < portc->num_settings)
517
desc = udi_usbdev_get_altsetting (portc->usbdev, new_setting, &desc_len);
521
if (desc == NULL || desc_len < 3)
524
"Audio device %d not available when altsetting=%d\n",
525
audio_engines[portc->audio_dev]->real_dev, new_setting);
528
portc->act_setting = new_setting;
533
(CE_CONT, "Select active setting %d on interface %d (dsp%d)\n",
534
new_setting, portc->if_number, adev->engine_num));
535
portc->act_setting = new_setting;
547
cmn_err (CE_CONT, "Streaming desc: ");
548
for (i = 0; i < l; i++)
549
cmn_err (CE_CONT, "%02x ", d[i]);
550
cmn_err (CE_CONT, "\n");
554
if (d[1] != CS_INTERFACE)
556
UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
561
portc->terminal_link = d[3];
562
portc->pipeline_delay = d[4];
566
cmn_err (CE_CONT, "AS_GENERAL ");
567
cmn_err (CE_CONT, "Terminal link %d/%s ", d[3],
568
devc->units[d[3]].name);
569
cmn_err (CE_CONT, "Delay %d ", d[4]);
570
cmn_err (CE_CONT, "Format tag %02x%02x ", d[5], d[6]);
571
cmn_err (CE_CONT, "\n");
578
cmn_err (CE_CONT, "AS_FORMAT_TYPE: FORMAT_TYPE_%d: ", d[3]);
583
case 1: /* FORMAT_TYPE_I */
584
if ((err = setup_format_I (devc, portc, adev, d, l)) < 0)
588
case 2: /* FORMAT_TYPE_II */
589
if ((err = setup_format_II (devc, portc, adev, d, l)) < 0)
595
"\noss usbaudio: Unsupported format type %d\n",
602
case AS_FORMAT_SPECIFIC:
603
if ((err = setup_format_specific (devc, portc, adev, d, l)) < 0)
609
(CE_CONT, "Unknown descriptor subtype %02x\n", d[2]));
615
desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 0, &l);
618
cmn_err (CE_CONT, "oss usbaudio: Bad endpoint\n");
622
portc->endpoint_desc = desc;
624
desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 1, &l);
628
/* TODO: Handle sync endpoints */
629
cmn_err (CE_CONT, "Sync Endpoint: ");
630
ossusb_dump_desc (desc, l);
637
static void usbaudio_close (int dev, int mode);
641
usbaudio_open (int dev, int mode, int open_flags)
643
ossusb_devc *devc = audio_engines[dev]->devc;
644
ossusb_portc *portc = audio_engines[dev]->portc;
645
oss_native_word flags, phaddr;
652
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
653
if (portc->open_mode != 0)
655
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
658
portc->open_mode = mode;
659
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
661
if ((err = prepare_altsetting (devc, portc, portc->act_setting)) < 0)
663
portc->open_mode = 0;
670
for (i = 0; i < 2; i++)
672
CONTIG_MALLOC (devc->osdev, TMPBUF_SIZE, MEMLIMIT_32BITS, &phaddr, portc->tmpbuf_dma_handle[i]);
676
udi_usbdev_set_interface (portc->usbdev, portc->if_number,
677
portc->act_setting)) < 0)
680
"oss usbaudio: Failed to set interface mode, error %d - ignored\n",
682
// portc->open_mode = 0;
686
portc->curr_datapipe = 0;
688
if ((portc->endpoint_handle =
689
udi_open_endpoint (portc->usbdev, portc->endpoint_desc)) == NULL)
691
usbaudio_close (dev, mode);
692
cmn_err (CE_WARN, "Cannot open audio pipe\n");
696
for (i = 0; i < 2; i++)
698
if ((portc->datapipe[i] =
699
udi_usb_alloc_request (portc->usbdev, portc->endpoint_handle, 1,
700
UDI_USBXFER_ISO_WRITE)) == NULL)
702
usbaudio_close (dev, mode);
703
cmn_err (CE_WARN, "Cannot alloc isoc request\n");
708
set_fraglimits (audio_engines[dev], portc);
712
static void usbaudio_reset (int dev);
716
usbaudio_close (int dev, int mode)
718
ossusb_devc *devc = audio_engines[dev]->devc;
719
ossusb_portc *portc = audio_engines[dev]->portc;
722
usbaudio_reset (dev);
724
for (i = 0; i < 2; i++)
726
if (portc->datapipe[i] != NULL)
728
udi_usb_free_request (portc->datapipe[i]);
729
portc->datapipe[i] = NULL;
732
if (portc->tmp_buf[i] != NULL)
734
CONTIG_FREE (devc->osdev, portc->tmp_buf[i], TMPBUF_SIZE, portc->tmpbuf_dma_handle[i]);
735
portc->tmp_buf[i] = NULL;
739
if (portc->endpoint_handle != NULL)
740
udi_close_endpoint (portc->endpoint_handle);
742
udi_usbdev_set_interface (portc->usbdev, portc->if_number, 0);
743
portc->open_mode = 0;
748
usbaudio_output_block (int dev, oss_native_word buf, int count,
749
int fragsize, int intrflag)
751
ossusb_devc *devc = audio_engines[dev]->devc;
758
usbaudio_start_input (int dev, oss_native_word buf, int count, int fragsize,
761
ossusb_devc *devc = audio_engines[dev]->devc;
766
static int feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc);
767
static void start_input (int dev, ossusb_devc * devc, ossusb_portc * portc);
770
copy_input (ossusb_portc * portc, dmap_t * dmap, unsigned char *buf, int len)
775
offs = (int) (dmap->byte_counter % dmap->bytes_in_use);
782
if (portc->convert_3byte)
788
/* Check for buffer wraparound */
789
if (offs + l > dmap->bytes_in_use)
790
l = dmap->bytes_in_use - offs;
794
if (dmap == NULL || dmap->dmabuf == NULL)
797
dmabuf = (int *) (dmap->dmabuf + offs);
799
for (i = 0; i < n; i++)
803
v = buf[2] | (buf[1] << 8) | (buf[0] << 16);
812
unsigned char *dmabuf;
813
dmabuf = dmap->dmabuf;
815
if (dmap == NULL || dmap->dmabuf == NULL)
818
/* Check for buffer wraparound */
819
if (offs + l > dmap->bytes_in_use)
820
l = dmap->bytes_in_use - offs;
822
memcpy (dmabuf + offs, buf, l);
836
play_callback (udi_usb_request_t * request, void *arg)
838
ossusb_portc *portc = arg;
840
feed_output (portc->audio_dev, portc->devc, portc);
841
oss_audio_outputintr (portc->audio_dev,
842
AINTR_NO_POINTER_UPDATES | AINTR_LOCALQUEUE);
846
rec_callback (udi_usb_request_t * request, void *arg)
848
ossusb_portc *portc = arg;
852
if (portc == NULL || (unsigned long) arg < 4096)
854
cmn_err (CE_WARN, "Bad portc\n");
858
dmap = audio_engines[portc->audio_dev]->dmap_in;
859
len = udi_usb_request_actlen (request);
862
return; /* No data so it looks like we are closing down */
865
copy_input (portc, dmap, udi_usb_request_actdata (request), len)) < 1)
867
cmn_err (CE_WARN, "Saving recorded data failed (%d)\n", len);
871
oss_audio_inc_byte_counter (dmap, len);
872
oss_audio_inputintr (portc->audio_dev, AINTR_NO_POINTER_UPDATES);
874
start_input (portc->audio_dev, portc->devc, portc);
886
static int phase = 0, v;
888
static short sinebuf[48] = {
889
0, 4276, 8480, 12539, 16383, 19947, 23169, 25995,
890
28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272,
891
28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276,
892
0, -4276, -8480, -12539, -16383, -19947, -23169, -25995,
893
-28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272,
894
-28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276
896
v = sinebuf[phase] * 256;
897
phase = (phase + 1) % 48;
905
output_convert (ossusb_devc * devc, ossusb_portc * portc, dmap_p dmap,
906
unsigned char *dmabuf, int pos, int pn, int total_len)
908
unsigned char *tmpbuf = portc->tmp_buf[pn], *b;
909
int i, n, len, out_size = 0;
912
while (total_len > 0)
916
/* Check for buffer wraparound */
917
if (pos + l > dmap->bytes_in_use)
918
l = dmap->bytes_in_use - pos;
924
if (portc->convert_3byte)
928
n = l / sizeof (*buf);
933
for (i = 0; i < n; i++)
939
*tmpbuf++ = (val) & 0xff;
940
*tmpbuf++ = (val >> 8) & 0xff;
941
*tmpbuf++ = (val >> 16) & 0xff;
947
memcpy (tmpbuf, b, l);
956
udi_usb_submit_request (portc->datapipe[pn], play_callback, portc,
957
portc->endpoint_handle, UDI_USBXFER_ISO_WRITE,
958
portc->tmp_buf[pn], out_size)) < 0)
960
//cmn_err(CE_CONT, "oss usbaudio: Write transfer eror %d\n", err);
968
feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc)
971
oss_native_word flags;
972
adev_p adev = audio_engines[dev];
973
dmap_p dmap = adev->dmap_out;
975
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
979
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
983
pn = portc->curr_datapipe;
984
portc->curr_datapipe = (portc->curr_datapipe + 1) % NR_DATAPIPES;
986
pos = (int) (dmap->byte_counter % dmap->bytes_in_use);
987
len = portc->fragment_size;
989
portc->overflow_samples += portc->overflow_size;
990
if (portc->overflow_samples > 1000)
992
len += dmap->frame_size * (portc->overflow_samples / 1000);
993
portc->overflow_samples = portc->overflow_samples % 1000;
996
output_convert (devc, portc, dmap, dmap->dmabuf, pos, pn, len);
997
oss_audio_inc_byte_counter (dmap, len);
998
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
1003
start_input (int dev, ossusb_devc * devc, ossusb_portc * portc)
1006
oss_native_word flags;
1007
adev_p adev = audio_engines[dev];
1008
dmap_p dmap = adev->dmap_in;
1010
if (portc->stopping)
1013
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
1017
udi_usb_submit_request (portc->datapipe[0], rec_callback, portc,
1018
portc->endpoint_handle, UDI_USBXFER_ISO_READ,
1019
dmap->dmabuf + frag * portc->fragment_size,
1020
portc->fragment_size)) < 0)
1022
cmn_err (CE_WARN, "oss usbaudio: Read transfer error %d\n", err);
1023
cmn_err (CE_CONT, "Endpoint %02x\n",
1024
udi_endpoint_get_num (portc->endpoint_handle));
1026
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
1030
usbaudio_trigger (int dev, int state)
1032
ossusb_devc *devc = audio_engines[dev]->devc;
1033
ossusb_portc *portc = audio_engines[dev]->portc;
1038
if (portc->open_mode & PCM_ENABLE_OUTPUT)
1040
if ((portc->prepared_modes & PCM_ENABLE_OUTPUT)
1041
&& (state & PCM_ENABLE_OUTPUT))
1043
portc->prepared_modes &= ~PCM_ENABLE_OUTPUT;
1044
portc->curr_datapipe = 0;
1045
portc->stopping = 0;
1047
feed_output (dev, devc, portc);
1048
feed_output (dev, devc, portc);
1050
else if (!(state & PCM_ENABLE_OUTPUT))
1052
portc->stopping = 1;
1054
udi_usb_cancel_request (portc->datapipe[0]);
1055
udi_usb_cancel_request (portc->datapipe[1]);
1057
portc->curr_datapipe = 0;
1061
if (portc->open_mode & PCM_ENABLE_INPUT)
1063
if ((portc->prepared_modes & PCM_ENABLE_INPUT)
1064
&& (state & PCM_ENABLE_INPUT))
1066
portc->prepared_modes &= ~PCM_ENABLE_INPUT;
1067
portc->stopping = 0;
1068
start_input (dev, devc, portc);
1070
else if (!(state & PCM_ENABLE_INPUT))
1072
portc->stopping = 1;
1074
udi_usb_cancel_request (portc->datapipe[0]);
1075
udi_usb_cancel_request (portc->datapipe[1]);
1077
portc->curr_datapipe = 0;
1083
usbaudio_reset (int dev)
1085
usbaudio_trigger (dev, 0);
1090
usbaudio_prepare_for_input (int dev, int bsize, int bcount)
1092
ossusb_devc *devc = audio_engines[dev]->devc;
1093
ossusb_portc *portc = audio_engines[dev]->portc;
1094
adev_p adev = audio_engines[dev];
1100
if (adev->flags & ADEV_NOINPUT)
1103
portc->stopping = 0;
1105
if (write_control_value
1106
(devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
1109
cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
1114
* Handle fractional samples that don't fit in the 1ms period.
1116
portc->overflow_size = portc->speed % 1000;
1117
portc->overflow_samples = 0;
1119
portc->prepared_modes |= PCM_ENABLE_INPUT;
1125
usbaudio_prepare_for_output (int dev, int bsize, int bcount)
1127
ossusb_devc *devc = audio_engines[dev]->devc;
1128
ossusb_portc *portc = audio_engines[dev]->portc;
1129
adev_p adev = audio_engines[dev];
1134
if (adev->flags & ADEV_NOOUTPUT)
1137
portc->stopping = 0;
1139
if (write_control_value
1140
(devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
1143
cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
1148
* Handle fractional samples that don't fit in the 1ms period.
1150
portc->overflow_size = portc->speed % 1000;
1151
portc->overflow_samples = 0;
1153
portc->prepared_modes |= PCM_ENABLE_OUTPUT;
1158
usbaudio_check_input (int dev)
1160
ossusb_devc *devc = audio_engines[dev]->devc;
1164
"oss usbaudio: Audio device %d removed from the system.\n",
1169
cmn_err (CE_CONT, "oss usbaudio: Audio input timed out on device %d.\n",
1175
usbaudio_check_output (int dev)
1177
ossusb_devc *devc = audio_engines[dev]->devc;
1181
"oss usbaudio: Audio device %d removed from the system.\n",
1186
cmn_err (CE_CONT, "oss usbaudio: Audio output timed out on device %d.\n",
1192
usbaudio_local_qlen (int dev)
1194
ossusb_portc *portc = audio_engines[dev]->portc;
1195
dmap_p dmap = audio_engines[dev]->dmap_out;
1196
int delay = portc->pipeline_delay + 1; /* Pipeline delay in 1 msec ticks */
1198
delay = delay * dmap->data_rate / 1000; /* Bytes/msec */
1203
static audiodrv_t usbaudio_driver = {
1206
usbaudio_output_block,
1207
usbaudio_start_input,
1209
usbaudio_prepare_for_input,
1210
usbaudio_prepare_for_output,
1212
usbaudio_local_qlen,
1218
usbaudio_set_format,
1219
usbaudio_set_channels,
1222
usbaudio_check_input,
1223
usbaudio_check_output,
1224
NULL, /* usbaudio_alloc_buffer */
1225
NULL, /* usbaudio_free_buffer */
1228
NULL /* usbaudio_get_buffer_pointer */
1232
ossusb_init_audiostream (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
1235
int nsettings, actsetting = 0, desc_len;
1236
unsigned char *desc, *d;
1240
void *endpoint_desc;
1244
int opts = ADEV_AUTOMODE;
1246
ossusb_portc *portc;
1248
if (devc->num_audio_engines >= MAX_PORTC)
1250
cmn_err (CE_CONT, "usbaudio: Too many audio streaming interfaces\n");
1256
cmn_err (CE_CONT, "usbaudio: usbdev==NULL\n");
1260
nsettings = udi_usbdev_get_num_altsettings (usbdev);
1261
desc = udi_usbdev_get_endpoint (usbdev, 1, 0, &l);
1264
/* cmn_err(CE_CONT, "Endpoint: ");ossusb_dump_desc(desc, l); */
1265
endpoint_desc = desc;
1268
endpoint_desc = NULL;
1271
for (i = 0; i < devc->num_audio_engines; i++)
1272
if (devc->portc[i].orig_endpoint_desc == endpoint_desc) /* Already registered this */
1274
prepare_altsetting (devc, &devc->portc[i],
1275
devc->portc[i].act_setting);
1279
portc = &devc->portc[devc->num_audio_engines];
1280
portc_num = devc->num_audio_engines;
1281
portc->if_number = inum;
1282
portc->endpoint_desc = portc->orig_endpoint_desc = endpoint_desc;
1283
portc->usbdev = usbdev;
1284
portc->act_setting = -1; /* Set to an impossible value */
1285
devc->num_audio_engines++;
1287
memset (dev_name, 0, sizeof (dev_name));
1288
strncpy (dev_name, devc->dev_name, sizeof (dev_name) - 1);
1289
portc->num_settings = nsettings;
1293
for (i = 0; i < nsettings; i++)
1295
desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
1296
cmn_err (CE_CONT, "\nDumping altsetting %d (l=%d)\n", i, desc_len);
1298
ossusb_dump_desc (desc, desc_len);
1302
desc = udi_usbdev_get_altsetting (usbdev, actsetting, &desc_len);
1304
if (desc == NULL || desc_len < 1)
1305
for (i = 0; i < nsettings && (desc == NULL || desc_len < 1); i++)
1307
UDB (cmn_err (CE_CONT, "Trying to read altsetting %d\n", i));
1308
desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
1313
UDB (cmn_err (CE_CONT, "Altsetting %d, len %d\n", actsetting, desc_len));
1317
cmn_err (CE_WARN, "Can't read interface descriptors\n");
1322
ossusb_dump_desc (desc, desc_len);
1325
while (p < desc_len)
1330
if (d[1] != CS_INTERFACE)
1332
UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
1337
portc->terminal_link = d[3];
1344
if (portc->terminal_link > 0 && portc->terminal_link <= devc->nunits)
1346
char *s = dev_name + strlen (dev_name);
1348
sprintf (s, " %s", devc->units[portc->terminal_link].name);
1351
if (devc->units[portc->terminal_link].typ == TY_OUTPUT) /* USB terminal type */
1353
opts |= ADEV_NOOUTPUT;
1357
opts |= ADEV_NOINPUT;
1361
if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
1366
sizeof (audiodrv_t),
1368
AFMT_S16_NE, devc, -1)) < 0)
1374
adev = audio_engines[portc->audio_dev];
1375
adev->portc = portc;
1376
adev->mixer_dev = devc->mixer_dev;
1377
adev->rate_source = devc->portc[0].audio_dev;
1378
adev->max_block = 256;
1379
adev->min_fragments = 4; /* vmix needs this */
1381
prepare_altsetting (devc, portc, 1);
1383
if (portc->num_settings > 2)
1387
sprintf (name, "%s-altset", devc->units[portc->terminal_link].name);
1388
ossusb_create_altset_control (devc->mixer_dev, portc_num,
1389
portc->num_settings, name);
1393
// TODO: This needs to be checked before vmix is enabled
1394
#ifdef CONFIG_OSS_VMIX
1395
if (devc->units[portc->terminal_link].typ != TY_OUTPUT)
1396
vmix_attach_audiodev(devc->osdev, portc->audio_dev, -1, 0);
1404
ossusb_change_altsetting (int dev, int ctrl, unsigned int cmd, int value)
1406
ossusb_devc *devc = mixer_devs[dev]->devc;
1407
ossusb_portc *portc;
1409
if (ctrl < 0 || ctrl >= devc->num_audio_engines)
1412
portc = &devc->portc[ctrl];
1414
if (cmd == SNDCTL_MIX_READ)
1415
return portc->act_setting;
1417
if (value >= portc->num_settings)
1418
value = portc->num_settings - 1;
1420
if (portc->act_setting != value)
1422
prepare_altsetting (devc, portc, value);