uaudio.c (25ee8cca07e4786f8a5fdce0363c8c862a2b918d) | uaudio.c (3a3f90c6c3cc3124c6f4df8a11b57c8a36a2d13c) |
---|---|
1/* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */ 2/* $FreeBSD$ */ 3 4/*- 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation --- 30 unchanged lines hidden (view full) --- 39 */ 40 41/* 42 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 43 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 44 * http://www.usb.org/developers/devclass_docs/termt10.pdf 45 */ 46 | 1/* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */ 2/* $FreeBSD$ */ 3 4/*- 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation --- 30 unchanged lines hidden (view full) --- 39 */ 40 41/* 42 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 43 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 44 * http://www.usb.org/developers/devclass_docs/termt10.pdf 45 */ 46 |
47#include <sys/cdefs.h> 48#if defined(__NetBSD__) || defined(__OpenBSD__) 49__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $"); 50#endif 51 | |
52/* 53 * Also merged: 54 * $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $ 55 * $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $ 56 * $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $ 57 * $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $ | 47/* 48 * Also merged: 49 * $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $ 50 * $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $ 51 * $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $ 52 * $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $ |
58 * $NetBSD: uaudio.c,v 1.102 2006/04/14 17:00:55 christos Exp $ 59 * $NetBSD: uaudio.c,v 1.103 2006/05/11 19:09:25 mrg Exp $ 60 * $NetBSD: uaudio.c,v 1.105 2006/10/04 16:00:15 christos Exp $ | |
61 */ 62 | 53 */ 54 |
63#include <sys/param.h> 64#include <sys/systm.h> 65#include <sys/kernel.h> 66#include <sys/malloc.h> 67#if defined(__NetBSD__) || defined(__OpenBSD__) 68#include <sys/device.h> 69#include <sys/ioctl.h> 70#endif 71#include <sys/tty.h> 72#include <sys/file.h> 73#include <sys/reboot.h> /* for bootverbose */ 74#include <sys/select.h> 75#include <sys/proc.h> 76#if defined(__NetBSD__) || defined(__OpenBSD__) 77#include <sys/device.h> 78#elif defined(__FreeBSD__) 79#include <sys/module.h> 80#include <sys/bus.h> 81#include <sys/conf.h> 82#endif 83#include <sys/poll.h> 84#if defined(__FreeBSD__) 85#include <sys/sysctl.h> 86#include <sys/sbuf.h> 87#endif | 55#include "usbdevs.h" 56#include <dev/usb/usb.h> 57#include <dev/usb/usb_mfunc.h> 58#include <dev/usb/usb_error.h> |
88 | 59 |
89#if defined(__NetBSD__) || defined(__OpenBSD__) 90#include <sys/audioio.h> 91#include <dev/audio_if.h> 92#include <dev/audiovar.h> 93#include <dev/mulaw.h> 94#include <dev/auconv.h> 95#elif defined(__FreeBSD__) 96#include <dev/sound/pcm/sound.h> /* XXXXX */ 97#include <dev/sound/chip.h> 98#include "feeder_if.h" 99#endif | 60#define USB_DEBUG_VAR uaudio_debug |
100 | 61 |
101#include <dev/usb/usb_port.h> 102#include <dev/usb/usb.h> 103#include <dev/usb/usbdi.h> 104#include <dev/usb/usbdi_util.h> 105#include <dev/usb/usb_quirks.h> | 62#include <dev/usb/usb_core.h> 63#include <dev/usb/usb_lookup.h> 64#include <dev/usb/usb_debug.h> 65#include <dev/usb/usb_util.h> 66#include <dev/usb/usb_busdma.h> 67#include <dev/usb/usb_parse.h> 68#include <dev/usb/usb_request.h> 69#include <dev/usb/usb_mbuf.h> 70#include <dev/usb/usb_dev.h> 71#include <dev/usb/usb_dynamic.h> |
106 | 72 |
107#if defined(__NetBSD__) || defined(__OpenBSD__) 108#include <dev/usb/uaudioreg.h> 109#elif defined(__FreeBSD__) | 73#include <dev/usb/quirk/usb_quirk.h> 74 75#include <sys/reboot.h> /* for bootverbose */ 76 77#include <dev/sound/pcm/sound.h> |
110#include <dev/sound/usb/uaudioreg.h> 111#include <dev/sound/usb/uaudio.h> | 78#include <dev/sound/usb/uaudioreg.h> 79#include <dev/sound/usb/uaudio.h> |
112#endif | 80#include <dev/sound/chip.h> 81#include "feeder_if.h" |
113 | 82 |
114#if defined(__NetBSD__) || defined(__OpenBSD__) 115/* #define UAUDIO_DEBUG */ 116#else 117/* #define USB_DEBUG */ 118#endif 119/* #define UAUDIO_MULTIPLE_ENDPOINTS */ 120#ifdef USB_DEBUG 121#define DPRINTF(x) do { if (uaudiodebug) printf x; } while (0) 122#define DPRINTFN(n,x) do { if (uaudiodebug>(n)) printf x; } while (0) 123int uaudiodebug = 0; 124#if defined(__FreeBSD__) 125SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio"); 126SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW, 127 &uaudiodebug, 0, "uaudio debug level"); 128#endif 129#else 130#define DPRINTF(x) 131#define DPRINTFN(n,x) 132#endif | 83static int uaudio_default_rate = 96000; 84static int uaudio_default_bits = 32; 85static int uaudio_default_channels = 2; |
133 | 86 |
134#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */ 135#if defined(__NetBSD__) || defined(__OpenBSD__) 136#define UAUDIO_NFRAMES 10 /* ms of sound in each request */ 137#elif defined(__FreeBSD__) 138#define UAUDIO_NFRAMES 20 /* ms of sound in each request */ | 87#if USB_DEBUG 88static int uaudio_debug = 0; 89 90SYSCTL_NODE(_hw_usb2, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio"); 91SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, debug, CTLFLAG_RW, 92 &uaudio_debug, 0, "uaudio debug level"); 93SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_rate, CTLFLAG_RW, 94 &uaudio_default_rate, 0, "uaudio default sample rate"); 95SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_bits, CTLFLAG_RW, 96 &uaudio_default_bits, 0, "uaudio default sample bits"); 97SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_channels, CTLFLAG_RW, 98 &uaudio_default_channels, 0, "uaudio default sample channels"); |
139#endif 140 | 99#endif 100 |
101#define UAUDIO_MINFRAMES 16 /* must be factor of 8 due HS-USB */ 102#define UAUDIO_NCHANBUFS 2 /* number of outstanding request */ 103#define UAUDIO_RECURSE_LIMIT 24 /* rounds */ |
|
141 | 104 |
142#define MIX_MAX_CHAN 8 143struct mixerctl { 144 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 145 uint16_t wIndex; 146 uint8_t nchan; 147 uint8_t type; 148#define MIX_ON_OFF 1 149#define MIX_SIGNED_16 2 150#define MIX_UNSIGNED_16 3 151#define MIX_SIGNED_8 4 152#define MIX_SELECTOR 5 153#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 154#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 155 int minval, maxval; 156 u_int delta; 157 u_int mul; 158#if defined(__FreeBSD__) /* XXXXX */ 159 unsigned ctl; 160#define MAX_SELECTOR_INPUT_PIN 256 161 uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN]; 162#endif 163 uint8_t class; 164#if !defined(__FreeBSD__) 165 char ctlname[MAX_AUDIO_DEV_LEN]; 166 char *ctlunit; 167#endif 168}; 169#define MAKE(h,l) (((h) << 8) | (l)) | 105#define MAKE_WORD(h,l) (((h) << 8) | (l)) 106#define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1) |
170 | 107 |
171struct as_info { 172 uint8_t alt; 173 uint8_t encoding; 174 uint8_t attributes; /* Copy of bmAttributes of 175 * usb_audio_streaming_endpoint_descriptor 176 */ 177 usbd_interface_handle ifaceh; 178 const usb_interface_descriptor_t *idesc; 179 const usb_endpoint_descriptor_audio_t *edesc; 180 const usb_endpoint_descriptor_audio_t *edesc1; 181 const struct usb_audio_streaming_type1_descriptor *asf1desc; 182 int sc_busy; /* currently used */ | 108struct uaudio_mixer_node { 109 int32_t minval; 110 int32_t maxval; 111#define MIX_MAX_CHAN 8 112 int32_t wValue[MIX_MAX_CHAN]; /* using nchan */ 113 uint32_t delta; 114 uint32_t mul; 115 uint32_t ctl; 116 117 uint16_t wData[MIX_MAX_CHAN]; /* using nchan */ 118 uint16_t wIndex; 119 120 uint8_t update[(MIX_MAX_CHAN + 7) / 8]; 121 uint8_t nchan; 122 uint8_t type; 123#define MIX_ON_OFF 1 124#define MIX_SIGNED_16 2 125#define MIX_UNSIGNED_16 3 126#define MIX_SIGNED_8 4 127#define MIX_SELECTOR 5 128#define MIX_UNKNOWN 6 129#define MIX_SIZE(n) ((((n) == MIX_SIGNED_16) || \ 130 ((n) == MIX_UNSIGNED_16)) ? 2 : 1) 131#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 132 133#define MAX_SELECTOR_INPUT_PIN 256 134 uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN]; 135 uint8_t class; 136 137 struct uaudio_mixer_node *next; |
183}; 184 | 138}; 139 |
185struct chan { 186#if defined(__NetBSD__) || defined(__OpenBSD__) 187 void (*intr)(void *); /* DMA completion intr handler */ 188 void *arg; /* arg for intr() */ 189#else | 140struct uaudio_chan { 141 struct pcmchan_caps pcm_cap; /* capabilities */ 142 143 struct snd_dbuf *pcm_buf; 144 const struct usb2_config *usb2_cfg; 145 struct mtx *pcm_mtx; /* lock protecting this structure */ 146 struct uaudio_softc *priv_sc; |
190 struct pcm_channel *pcm_ch; | 147 struct pcm_channel *pcm_ch; |
191#endif 192 usbd_pipe_handle pipe; 193 usbd_pipe_handle sync_pipe; | 148 struct usb2_xfer *xfer[UAUDIO_NCHANBUFS]; 149 const struct usb2_audio_streaming_interface_descriptor *p_asid; 150 const struct usb2_audio_streaming_type1_descriptor *p_asf1d; 151 const struct usb2_audio_streaming_endpoint_descriptor *p_sed; 152 const usb2_endpoint_descriptor_audio_t *p_ed1; 153 const usb2_endpoint_descriptor_audio_t *p_ed2; 154 const struct uaudio_format *p_fmt; |
194 | 155 |
195 u_int sample_size; 196 u_int sample_rate; 197 u_int bytes_per_frame; 198 u_int fraction; /* fraction/1000 is the extra samples/frame */ 199 u_int residue; /* accumulates the fractional samples */ | 156 uint8_t *buf; /* pointer to buffer */ 157 uint8_t *start; /* upper layer buffer start */ 158 uint8_t *end; /* upper layer buffer end */ 159 uint8_t *cur; /* current position in upper layer 160 * buffer */ |
200 | 161 |
201 u_char *start; /* upper layer buffer start */ 202 u_char *end; /* upper layer buffer end */ 203 u_char *cur; /* current position in upper layer buffer */ 204 int blksize; /* chunk size to report up */ 205 int transferred; /* transferred bytes not reported up */ | 162 uint32_t intr_size; /* in bytes */ 163 uint32_t block_size; 164 uint32_t sample_rate; 165 uint32_t format; 166 uint32_t pcm_format[2]; |
206 | 167 |
207 int altidx; /* currently used altidx */ | 168 uint16_t bytes_per_frame; |
208 | 169 |
209 int curchanbuf; 210 struct chanbuf { 211 struct chan *chan; 212 usbd_xfer_handle xfer; 213 u_char *buffer; 214 u_int16_t sizes[UAUDIO_NFRAMES]; 215 u_int16_t offsets[UAUDIO_NFRAMES]; 216 u_int16_t size; 217 } chanbufs[UAUDIO_NCHANBUFS]; | 170 uint8_t valid; 171 uint8_t iface_index; 172 uint8_t iface_alt_index; 173}; |
218 | 174 |
219 struct uaudio_softc *sc; /* our softc */ 220#if defined(__FreeBSD__) 221 u_int32_t format; 222 int precision; 223 int channels; 224#endif | 175#define UMIDI_N_TRANSFER 4 /* units */ 176#define UMIDI_CABLES_MAX 16 /* units */ 177#define UMIDI_BULK_SIZE 1024 /* bytes */ 178 179struct umidi_sub_chan { 180 struct usb2_fifo_sc fifo; 181 uint8_t *temp_cmd; 182 uint8_t temp_0[4]; 183 uint8_t temp_1[4]; 184 uint8_t state; 185#define UMIDI_ST_UNKNOWN 0 /* scan for command */ 186#define UMIDI_ST_1PARAM 1 187#define UMIDI_ST_2PARAM_1 2 188#define UMIDI_ST_2PARAM_2 3 189#define UMIDI_ST_SYSEX_0 4 190#define UMIDI_ST_SYSEX_1 5 191#define UMIDI_ST_SYSEX_2 6 192 193 uint8_t read_open:1; 194 uint8_t write_open:1; 195 uint8_t unused:6; |
225}; 226 | 196}; 197 |
198struct umidi_chan { 199 200 struct umidi_sub_chan sub[UMIDI_CABLES_MAX]; 201 struct mtx mtx; 202 203 struct usb2_xfer *xfer[UMIDI_N_TRANSFER]; 204 205 uint8_t iface_index; 206 uint8_t iface_alt_index; 207 208 uint8_t flags; 209#define UMIDI_FLAG_READ_STALL 0x01 210#define UMIDI_FLAG_WRITE_STALL 0x02 211 212 uint8_t read_open_refcount; 213 uint8_t write_open_refcount; 214 215 uint8_t curr_cable; 216 uint8_t max_cable; 217 uint8_t valid; 218}; 219 |
|
227struct uaudio_softc { | 220struct uaudio_softc { |
228 device_t sc_dev; /* base device */ 229 usbd_device_handle sc_udev; /* USB device */ 230 int sc_ac_iface; /* Audio Control interface */ 231 usbd_interface_handle sc_ac_ifaceh; 232 struct chan sc_playchan; /* play channel */ 233 struct chan sc_recchan; /* record channel */ 234 int sc_nullalt; 235 int sc_audio_rev; 236 struct as_info *sc_alts; /* alternate settings */ 237 int sc_nalts; /* # of alternate settings */ 238 int sc_altflags; 239#define HAS_8 0x01 240#define HAS_16 0x02 241#define HAS_8U 0x04 242#define HAS_ALAW 0x08 243#define HAS_MULAW 0x10 244#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 245#define HAS_24 0x40 246#define HAS_32 0x80 247 int sc_mode; /* play/record capability */ 248 struct mixerctl *sc_ctls; /* mixer controls */ 249 int sc_nctls; /* # of mixer controls */ 250 device_t sc_audiodev; 251 char sc_dying; 252#if defined(__FreeBSD__) 253 struct sbuf uaudio_sndstat; 254 int uaudio_sndstat_flag; 255 int async; 256#endif 257 int sc_vendor; 258 int sc_product; 259 int sc_release; | 221 struct sbuf sc_sndstat; 222 struct sndcard_func sc_sndcard_func; 223 struct uaudio_chan sc_rec_chan; 224 struct uaudio_chan sc_play_chan; 225 struct umidi_chan sc_midi_chan; 226 227 struct usb2_device *sc_udev; 228 struct usb2_xfer *sc_mixer_xfer[1]; 229 struct uaudio_mixer_node *sc_mixer_root; 230 struct uaudio_mixer_node *sc_mixer_curr; 231 232 uint32_t sc_mix_info; 233 uint32_t sc_recsrc_info; 234 235 uint16_t sc_audio_rev; 236 uint16_t sc_mixer_count; 237 238 uint8_t sc_sndstat_valid; 239 uint8_t sc_mixer_iface_index; 240 uint8_t sc_mixer_iface_no; 241 uint8_t sc_mixer_chan; 242 uint8_t sc_pcm_registered:1; 243 uint8_t sc_mixer_init:1; 244 uint8_t sc_uq_audio_swap_lr:1; 245 uint8_t sc_uq_au_inp_async:1; 246 uint8_t sc_uq_au_no_xu:1; 247 uint8_t sc_uq_bad_adc:1; |
260}; 261 | 248}; 249 |
262struct terminal_list { 263 int size; 264 uint16_t terminals[1]; | 250struct uaudio_search_result { 251 uint8_t bit_input[(256 + 7) / 8]; 252 uint8_t bit_output[(256 + 7) / 8]; 253 uint8_t bit_visited[(256 + 7) / 8]; 254 uint8_t recurse_level; 255 uint8_t id_max; |
265}; | 256}; |
266#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \ 267 + sizeof(uint16_t) * (N)) | |
268 | 257 |
269struct io_terminal { | 258struct uaudio_terminal_node { |
270 union { | 259 union { |
271 const usb_descriptor_t *desc; 272 const struct usb_audio_input_terminal *it; 273 const struct usb_audio_output_terminal *ot; 274 const struct usb_audio_mixer_unit *mu; 275 const struct usb_audio_selector_unit *su; 276 const struct usb_audio_feature_unit *fu; 277 const struct usb_audio_processing_unit *pu; 278 const struct usb_audio_extension_unit *eu; 279 } d; 280 int inputs_size; 281 struct terminal_list **inputs; /* list of source input terminals */ 282 struct terminal_list *output; /* list of destination output terminals */ 283 int direct; /* directly connected to an output terminal */ | 260 const struct usb2_descriptor *desc; 261 const struct usb2_audio_input_terminal *it; 262 const struct usb2_audio_output_terminal *ot; 263 const struct usb2_audio_mixer_unit_0 *mu; 264 const struct usb2_audio_selector_unit *su; 265 const struct usb2_audio_feature_unit *fu; 266 const struct usb2_audio_processing_unit_0 *pu; 267 const struct usb2_audio_extension_unit_0 *eu; 268 } u; 269 struct uaudio_search_result usr; 270 struct uaudio_terminal_node *root; |
284}; 285 | 271}; 272 |
286#define UAC_OUTPUT 0 287#define UAC_INPUT 1 288#define UAC_EQUAL 2 289#define UAC_RECORD 3 290#define UAC_NCLASSES 4 291#ifdef USB_DEBUG 292#if defined(__FreeBSD__) 293#define AudioCinputs "inputs" 294#define AudioCoutputs "outputs" 295#define AudioCrecord "record" 296#define AudioCequalization "equalization" 297#endif 298static const char *uac_names[] = { 299 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord, | 273struct uaudio_format { 274 uint16_t wFormat; 275 uint8_t bPrecision; 276 uint32_t freebsd_fmt; 277 const char *description; |
300}; | 278}; |
301#endif | |
302 | 279 |
303static usbd_status uaudio_identify_ac 304 (struct uaudio_softc *, const usb_config_descriptor_t *); 305static usbd_status uaudio_identify_as 306 (struct uaudio_softc *, const usb_config_descriptor_t *); 307static usbd_status uaudio_process_as 308 (struct uaudio_softc *, const char *, int *, int, 309 const usb_interface_descriptor_t *); | 280static const struct uaudio_format uaudio_formats[] = { |
310 | 281 |
311static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); | 282 {UA_FMT_PCM8, 8, AFMT_U8, "8-bit U-LE PCM"}, 283 {UA_FMT_PCM8, 16, AFMT_U16_LE, "16-bit U-LE PCM"}, 284 {UA_FMT_PCM8, 24, AFMT_U24_LE, "24-bit U-LE PCM"}, 285 {UA_FMT_PCM8, 32, AFMT_U32_LE, "32-bit U-LE PCM"}, |
312 | 286 |
313static const usb_interface_descriptor_t *uaudio_find_iface 314 (const char *, int, int *, int); | 287 {UA_FMT_PCM, 8, AFMT_S8, "8-bit S-LE PCM"}, 288 {UA_FMT_PCM, 16, AFMT_S16_LE, "16-bit S-LE PCM"}, 289 {UA_FMT_PCM, 24, AFMT_S24_LE, "24-bit S-LE PCM"}, 290 {UA_FMT_PCM, 32, AFMT_S32_LE, "32-bit S-LE PCM"}, |
315 | 291 |
316static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); | 292 {UA_FMT_ALAW, 8, AFMT_A_LAW, "8-bit A-Law"}, 293 {UA_FMT_MULAW, 8, AFMT_MU_LAW, "8-bit mu-Law"}, |
317 | 294 |
318#if defined(__NetBSD__) || defined(__OpenBSD__) 319static char *uaudio_id_name 320 (struct uaudio_softc *, const struct io_terminal *, int); 321#endif | 295 {0, 0, 0, NULL} 296}; |
322 | 297 |
323#ifdef USB_DEBUG 324static void uaudio_dump_cluster(const struct usb_audio_cluster *); 325#endif 326static struct usb_audio_cluster uaudio_get_cluster 327 (int, const struct io_terminal *); 328static void uaudio_add_input 329 (struct uaudio_softc *, const struct io_terminal *, int); 330static void uaudio_add_output 331 (struct uaudio_softc *, const struct io_terminal *, int); 332static void uaudio_add_mixer 333 (struct uaudio_softc *, const struct io_terminal *, int); 334static void uaudio_add_selector 335 (struct uaudio_softc *, const struct io_terminal *, int); 336#ifdef USB_DEBUG 337static const char *uaudio_get_terminal_name(int); 338#endif 339static int uaudio_determine_class 340 (const struct io_terminal *, struct mixerctl *); 341#if defined(__FreeBSD__) 342static int uaudio_feature_name(const struct io_terminal *, 343 struct mixerctl *); 344#else 345static const char *uaudio_feature_name 346 (const struct io_terminal *, struct mixerctl *); 347#endif 348static void uaudio_add_feature 349 (struct uaudio_softc *, const struct io_terminal *, int); 350static void uaudio_add_processing_updown 351 (struct uaudio_softc *, const struct io_terminal *, int); 352static void uaudio_add_processing 353 (struct uaudio_softc *, const struct io_terminal *, int); 354static void uaudio_add_extension 355 (struct uaudio_softc *, const struct io_terminal *, int); 356static struct terminal_list *uaudio_merge_terminal_list 357 (const struct io_terminal *); 358static struct terminal_list *uaudio_io_terminaltype 359 (int, struct io_terminal *, int); 360static usbd_status uaudio_identify 361 (struct uaudio_softc *, const usb_config_descriptor_t *); | 298#define UAC_OUTPUT 0 299#define UAC_INPUT 1 300#define UAC_EQUAL 2 301#define UAC_RECORD 3 302#define UAC_NCLASSES 4 |
362 | 303 |
363static int uaudio_signext(int, int); 364#if defined(__NetBSD__) || defined(__OpenBSD__) 365static int uaudio_value2bsd(struct mixerctl *, int); | 304#if USB_DEBUG 305static const char *uac_names[] = { 306 "outputs", "inputs", "equalization", "record" 307}; 308 |
366#endif | 309#endif |
367static int uaudio_bsd2value(struct mixerctl *, int); 368static int uaudio_get(struct uaudio_softc *, int, int, int, int, int); 369#if defined(__NetBSD__) || defined(__OpenBSD__) 370static int uaudio_ctl_get 371 (struct uaudio_softc *, int, struct mixerctl *, int); 372#endif 373static void uaudio_set 374 (struct uaudio_softc *, int, int, int, int, int, int); 375static void uaudio_ctl_set 376 (struct uaudio_softc *, int, struct mixerctl *, int, int); | |
377 | 310 |
378static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); | 311/* prototypes */ |
379 | 312 |
380static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); 381static void uaudio_chan_close(struct uaudio_softc *, struct chan *); 382static usbd_status uaudio_chan_alloc_buffers 383 (struct uaudio_softc *, struct chan *); 384static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *); | 313static device_probe_t uaudio_probe; 314static device_attach_t uaudio_attach; 315static device_detach_t uaudio_detach; |
385 | 316 |
386#if defined(__NetBSD__) || defined(__OpenBSD__) 387static void uaudio_chan_init 388 (struct chan *, int, const struct audio_params *, int); 389static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); | 317static usb2_callback_t uaudio_chan_play_callback; 318static usb2_callback_t uaudio_chan_record_callback; 319static usb2_callback_t uaudio_mixer_write_cfg_callback; 320static usb2_callback_t umidi_read_clear_stall_callback; 321static usb2_callback_t umidi_bulk_read_callback; 322static usb2_callback_t umidi_write_clear_stall_callback; 323static usb2_callback_t umidi_bulk_write_callback; 324 325static void uaudio_chan_fill_info_sub(struct uaudio_softc *, 326 struct usb2_device *, uint32_t, uint16_t, uint8_t, uint8_t); 327static void uaudio_chan_fill_info(struct uaudio_softc *, 328 struct usb2_device *); 329static void uaudio_mixer_add_ctl_sub(struct uaudio_softc *, 330 struct uaudio_mixer_node *); 331static void uaudio_mixer_add_ctl(struct uaudio_softc *, 332 struct uaudio_mixer_node *); 333static void uaudio_mixer_add_input(struct uaudio_softc *, 334 const struct uaudio_terminal_node *, int); 335static void uaudio_mixer_add_output(struct uaudio_softc *, 336 const struct uaudio_terminal_node *, int); 337static void uaudio_mixer_add_mixer(struct uaudio_softc *, 338 const struct uaudio_terminal_node *, int); 339static void uaudio_mixer_add_selector(struct uaudio_softc *, 340 const struct uaudio_terminal_node *, int); 341static uint32_t uaudio_mixer_feature_get_bmaControls( 342 const struct usb2_audio_feature_unit *, uint8_t); 343static void uaudio_mixer_add_feature(struct uaudio_softc *, 344 const struct uaudio_terminal_node *, int); 345static void uaudio_mixer_add_processing_updown(struct uaudio_softc *, 346 const struct uaudio_terminal_node *, int); 347static void uaudio_mixer_add_processing(struct uaudio_softc *, 348 const struct uaudio_terminal_node *, int); 349static void uaudio_mixer_add_extension(struct uaudio_softc *, 350 const struct uaudio_terminal_node *, int); 351static struct usb2_audio_cluster uaudio_mixer_get_cluster(uint8_t, 352 const struct uaudio_terminal_node *); 353static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *, 354 struct uaudio_mixer_node *); 355static uint16_t uaudio_mixer_feature_name(const struct uaudio_terminal_node *, 356 struct uaudio_mixer_node *); 357static const struct uaudio_terminal_node *uaudio_mixer_get_input( 358 const struct uaudio_terminal_node *, uint8_t); 359static const struct uaudio_terminal_node *uaudio_mixer_get_output( 360 const struct uaudio_terminal_node *, uint8_t); 361static void uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *, 362 const uint8_t *, uint8_t, struct uaudio_search_result *); 363static void uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *, 364 uint8_t, uint8_t, struct uaudio_search_result *); 365static void uaudio_mixer_fill_info(struct uaudio_softc *, 366 struct usb2_device *, void *); 367static uint16_t uaudio_mixer_get(struct usb2_device *, uint8_t, 368 struct uaudio_mixer_node *); 369static void uaudio_mixer_ctl_set(struct uaudio_softc *, 370 struct uaudio_mixer_node *, uint8_t, int32_t val); 371static usb2_error_t uaudio_set_speed(struct usb2_device *, uint8_t, uint32_t); 372static int uaudio_mixer_signext(uint8_t, int); 373static int uaudio_mixer_bsd2value(struct uaudio_mixer_node *, int32_t val); 374static const void *uaudio_mixer_verify_desc(const void *, uint32_t); 375static void uaudio_mixer_init(struct uaudio_softc *); 376static uint8_t umidi_convert_to_usb(struct umidi_sub_chan *, uint8_t, uint8_t); 377static struct umidi_sub_chan *umidi_sub_by_fifo(struct usb2_fifo *); 378static void umidi_start_read(struct usb2_fifo *); 379static void umidi_stop_read(struct usb2_fifo *); 380static void umidi_start_write(struct usb2_fifo *); 381static void umidi_stop_write(struct usb2_fifo *); 382static int umidi_open(struct usb2_fifo *, int, struct thread *); 383static int umidi_ioctl(struct usb2_fifo *, u_long cmd, void *, int, struct thread *); 384static void umidi_close(struct usb2_fifo *, int, struct thread *); 385static void umidi_init(device_t dev); 386static int32_t umidi_probe(device_t dev); 387static int32_t umidi_detach(device_t dev); 388 389#if USB_DEBUG 390static void uaudio_chan_dump_ep_desc( 391 const usb2_endpoint_descriptor_audio_t *); 392static void uaudio_mixer_dump_cluster(uint8_t, 393 const struct uaudio_terminal_node *); 394static const char *uaudio_mixer_get_terminal_name(uint16_t); |
390#endif 391 | 395#endif 396 |
392static void uaudio_chan_ptransfer(struct chan *); 393static void uaudio_chan_pintr 394 (usbd_xfer_handle, usbd_private_handle, usbd_status); | 397static const struct usb2_config 398 uaudio_cfg_record[UAUDIO_NCHANBUFS] = { 399 [0] = { 400 .type = UE_ISOCHRONOUS, 401 .endpoint = UE_ADDR_ANY, 402 .direction = UE_DIR_IN, 403 .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ 404 .mh.frames = UAUDIO_MINFRAMES, 405 .mh.flags = {.short_xfer_ok = 1,}, 406 .mh.callback = &uaudio_chan_record_callback, 407 }, |
395 | 408 |
396static void uaudio_chan_rtransfer(struct chan *); 397static void uaudio_chan_rintr 398 (usbd_xfer_handle, usbd_private_handle, usbd_status); | 409 [1] = { 410 .type = UE_ISOCHRONOUS, 411 .endpoint = UE_ADDR_ANY, 412 .direction = UE_DIR_IN, 413 .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ 414 .mh.frames = UAUDIO_MINFRAMES, 415 .mh.flags = {.short_xfer_ok = 1,}, 416 .mh.callback = &uaudio_chan_record_callback, 417 }, 418}; |
399 | 419 |
400#if defined(__NetBSD__) || defined(__OpenBSD__) 401static int uaudio_open(void *, int); 402static void uaudio_close(void *); 403static int uaudio_drain(void *); 404static int uaudio_query_encoding(void *, struct audio_encoding *); 405static void uaudio_get_minmax_rates 406 (int, const struct as_info *, const struct audio_params *, 407 int, u_long *, u_long *); 408static int uaudio_match_alt_sub 409 (int, const struct as_info *, const struct audio_params *, int, u_long); 410static int uaudio_match_alt_chan 411 (int, const struct as_info *, struct audio_params *, int); 412static int uaudio_match_alt 413 (int, const struct as_info *, struct audio_params *, int); 414static int uaudio_set_params 415 (void *, int, int, struct audio_params *, struct audio_params *); 416static int uaudio_round_blocksize(void *, int); 417static int uaudio_trigger_output 418 (void *, void *, void *, int, void (*)(void *), void *, 419 struct audio_params *); 420static int uaudio_trigger_input 421 (void *, void *, void *, int, void (*)(void *), void *, 422 struct audio_params *); 423static int uaudio_halt_in_dma(void *); 424static int uaudio_halt_out_dma(void *); 425static int uaudio_getdev(void *, struct audio_device *); 426static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 427static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 428static int uaudio_query_devinfo(void *, mixer_devinfo_t *); 429static int uaudio_get_props(void *); | 420static const struct usb2_config 421 uaudio_cfg_play[UAUDIO_NCHANBUFS] = { 422 [0] = { 423 .type = UE_ISOCHRONOUS, 424 .endpoint = UE_ADDR_ANY, 425 .direction = UE_DIR_OUT, 426 .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ 427 .mh.frames = UAUDIO_MINFRAMES, 428 .mh.flags = {.short_xfer_ok = 1,}, 429 .mh.callback = &uaudio_chan_play_callback, 430 }, |
430 | 431 |
431static const struct audio_hw_if uaudio_hw_if = { 432 uaudio_open, 433 uaudio_close, 434 uaudio_drain, 435 uaudio_query_encoding, 436 uaudio_set_params, 437 uaudio_round_blocksize, 438 NULL, 439 NULL, 440 NULL, 441 NULL, 442 NULL, 443 uaudio_halt_out_dma, 444 uaudio_halt_in_dma, 445 NULL, 446 uaudio_getdev, 447 NULL, 448 uaudio_mixer_set_port, 449 uaudio_mixer_get_port, 450 uaudio_query_devinfo, 451 NULL, 452 NULL, 453 NULL, 454 NULL, 455 uaudio_get_props, 456 uaudio_trigger_output, 457 uaudio_trigger_input, 458 NULL, | 432 [1] = { 433 .type = UE_ISOCHRONOUS, 434 .endpoint = UE_ADDR_ANY, 435 .direction = UE_DIR_OUT, 436 .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ 437 .mh.frames = UAUDIO_MINFRAMES, 438 .mh.flags = {.short_xfer_ok = 1,}, 439 .mh.callback = &uaudio_chan_play_callback, 440 }, |
459}; 460 | 441}; 442 |
461static struct audio_device uaudio_device = { 462 "USB audio", 463 "", 464 "uaudio" | 443static const struct usb2_config 444 uaudio_mixer_config[1] = { 445 [0] = { 446 .type = UE_CONTROL, 447 .endpoint = 0x00, /* Control pipe */ 448 .direction = UE_DIR_ANY, 449 .mh.bufsize = (sizeof(struct usb2_device_request) + 4), 450 .mh.callback = &uaudio_mixer_write_cfg_callback, 451 .mh.timeout = 1000, /* 1 second */ 452 }, |
465}; 466 | 453}; 454 |
467#elif defined(__FreeBSD__) 468static int audio_attach_mi(device_t); 469static int uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode); 470static int uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose); | 455static const 456uint8_t umidi_cmd_to_len[16] = { 457 [0x0] = 0, /* reserved */ 458 [0x1] = 0, /* reserved */ 459 [0x2] = 2, /* bytes */ 460 [0x3] = 3, /* bytes */ 461 [0x4] = 3, /* bytes */ 462 [0x5] = 1, /* bytes */ 463 [0x6] = 2, /* bytes */ 464 [0x7] = 3, /* bytes */ 465 [0x8] = 3, /* bytes */ 466 [0x9] = 3, /* bytes */ 467 [0xA] = 3, /* bytes */ 468 [0xB] = 3, /* bytes */ 469 [0xC] = 2, /* bytes */ 470 [0xD] = 2, /* bytes */ 471 [0xE] = 3, /* bytes */ 472 [0xF] = 1, /* bytes */ 473}; |
471 | 474 |
472/* for NetBSD compatibirity */ 473#define AUMODE_PLAY 0x01 474#define AUMODE_RECORD 0x02 | 475static const struct usb2_config 476 umidi_config[UMIDI_N_TRANSFER] = { 477 [0] = { 478 .type = UE_BULK, 479 .endpoint = UE_ADDR_ANY, 480 .direction = UE_DIR_OUT, 481 .mh.bufsize = UMIDI_BULK_SIZE, 482 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 483 .mh.callback = &umidi_bulk_write_callback, 484 }, |
475 | 485 |
476#define AUDIO_PROP_FULLDUPLEX 0x01 | 486 [1] = { 487 .type = UE_BULK, 488 .endpoint = UE_ADDR_ANY, 489 .direction = UE_DIR_IN, 490 .mh.bufsize = UMIDI_BULK_SIZE, 491 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 492 .mh.callback = &umidi_bulk_read_callback, 493 }, |
477 | 494 |
478#define AUDIO_ENCODING_ULAW 1 479#define AUDIO_ENCODING_ALAW 2 480#define AUDIO_ENCODING_SLINEAR_LE 6 481#define AUDIO_ENCODING_SLINEAR_BE 7 482#define AUDIO_ENCODING_ULINEAR_LE 8 483#define AUDIO_ENCODING_ULINEAR_BE 9 | 495 [2] = { 496 .type = UE_CONTROL, 497 .endpoint = 0x00, /* Control pipe */ 498 .direction = UE_DIR_ANY, 499 .mh.bufsize = sizeof(struct usb2_device_request), 500 .mh.flags = {}, 501 .mh.callback = &umidi_write_clear_stall_callback, 502 .mh.timeout = 1000, /* 1 second */ 503 .mh.interval = 50, /* 50ms */ 504 }, |
484 | 505 |
485#endif /* FreeBSD */ | 506 [3] = { 507 .type = UE_CONTROL, 508 .endpoint = 0x00, /* Control pipe */ 509 .direction = UE_DIR_ANY, 510 .mh.bufsize = sizeof(struct usb2_device_request), 511 .mh.flags = {}, 512 .mh.callback = &umidi_read_clear_stall_callback, 513 .mh.timeout = 1000, /* 1 second */ 514 .mh.interval = 50, /* 50ms */ 515 }, 516}; |
486 | 517 |
518static devclass_t uaudio_devclass; |
|
487 | 519 |
488#if defined(__NetBSD__) || defined(__OpenBSD__) | 520static device_method_t uaudio_methods[] = { 521 DEVMETHOD(device_probe, uaudio_probe), 522 DEVMETHOD(device_attach, uaudio_attach), 523 DEVMETHOD(device_detach, uaudio_detach), 524 DEVMETHOD(device_suspend, bus_generic_suspend), 525 DEVMETHOD(device_resume, bus_generic_resume), 526 DEVMETHOD(device_shutdown, bus_generic_shutdown), 527 DEVMETHOD(bus_print_child, bus_generic_print_child), 528 {0, 0} 529}; |
489 | 530 |
490USB_DECLARE_DRIVER(uaudio); | 531static driver_t uaudio_driver = { 532 .name = "uaudio", 533 .methods = uaudio_methods, 534 .size = sizeof(struct uaudio_softc), 535}; |
491 | 536 |
492#elif defined(__FreeBSD__) | 537static int 538uaudio_probe(device_t dev) 539{ 540 struct usb2_attach_arg *uaa = device_get_ivars(dev); |
493 | 541 |
494USB_DECLARE_DRIVER_INIT(uaudio, 495 DEVMETHOD(device_suspend, bus_generic_suspend), 496 DEVMETHOD(device_resume, bus_generic_resume), 497 DEVMETHOD(device_shutdown, bus_generic_shutdown), 498 DEVMETHOD(bus_print_child, bus_generic_print_child) 499 ); 500#endif | 542 if (uaa->usb2_mode != USB_MODE_HOST) 543 return (ENXIO); |
501 | 544 |
545 if (uaa->use_generic == 0) 546 return (ENXIO); |
|
502 | 547 |
503USB_MATCH(uaudio) | 548 /* trigger on the control interface */ 549 550 if ((uaa->info.bInterfaceClass == UICLASS_AUDIO) && 551 (uaa->info.bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL)) { 552 if (usb2_test_quirk(uaa, UQ_BAD_AUDIO)) 553 return (ENXIO); 554 else 555 return (0); 556 } 557 return (ENXIO); 558} 559 560static int 561uaudio_attach(device_t dev) |
504{ | 562{ |
505 USB_MATCH_START(uaudio, uaa); 506 usb_interface_descriptor_t *id; | 563 struct usb2_attach_arg *uaa = device_get_ivars(dev); 564 struct uaudio_softc *sc = device_get_softc(dev); 565 struct usb2_interface_descriptor *id; 566 device_t child; |
507 | 567 |
508 if (uaa->iface == NULL) 509 return UMATCH_NONE; | 568 sc->sc_play_chan.priv_sc = sc; 569 sc->sc_rec_chan.priv_sc = sc; 570 sc->sc_udev = uaa->device; |
510 | 571 |
511 id = usbd_get_interface_descriptor(uaa->iface); 512 /* Trigger on the control interface. */ 513 if (id == NULL || 514 id->bInterfaceClass != UICLASS_AUDIO || 515 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL || 516 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO)) 517 return UMATCH_NONE; | 572 if (usb2_test_quirk(uaa, UQ_AUDIO_SWAP_LR)) 573 sc->sc_uq_audio_swap_lr = 1; |
518 | 574 |
519 return UMATCH_IFACECLASS_IFACESUBCLASS; 520} | 575 if (usb2_test_quirk(uaa, UQ_AU_INP_ASYNC)) 576 sc->sc_uq_au_inp_async = 1; |
521 | 577 |
522USB_ATTACH(uaudio) 523{ 524 USB_ATTACH_START(uaudio, sc, uaa); 525 usb_interface_descriptor_t *id; 526 usb_config_descriptor_t *cdesc; 527#if !defined(__FreeBSD__) 528 char devinfo[1024]; 529#endif 530 usbd_status err; 531 int i, j, found; | 578 if (usb2_test_quirk(uaa, UQ_AU_NO_XU)) 579 sc->sc_uq_au_no_xu = 1; |
532 | 580 |
533#if defined(__FreeBSD__) 534 sc->sc_dev = self; 535#else 536 usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo)); 537 printf(": %s\n", devinfo); 538#endif | 581 if (usb2_test_quirk(uaa, UQ_BAD_ADC)) 582 sc->sc_uq_bad_adc = 1; |
539 | 583 |
540 sc->sc_udev = uaa->device; 541 sc->sc_vendor = uaa->vendor; 542 sc->sc_product = uaa->product; 543 sc->sc_release = uaa->release; 544#if defined(__FreeBSD__) 545 if (resource_int_value(device_get_name(sc->sc_dev), 546 device_get_unit(sc->sc_dev), "async", &i) == 0 && i != 0) 547 sc->async = 1; 548 else 549 sc->async = 0; 550#endif | 584 umidi_init(dev); |
551 | 585 |
552 cdesc = usbd_get_config_descriptor(sc->sc_udev); 553 if (cdesc == NULL) { 554 printf("%s: failed to get configuration descriptor\n", 555 device_get_nameunit(sc->sc_dev)); 556 return ENXIO; 557 } | 586 device_set_usb2_desc(dev); |
558 | 587 |
559 err = uaudio_identify(sc, cdesc); 560 if (err) { 561 printf("%s: audio descriptors make no sense, error=%d\n", 562 device_get_nameunit(sc->sc_dev), err); 563 return ENXIO; | 588 id = usb2_get_interface_descriptor(uaa->iface); 589 590 uaudio_chan_fill_info(sc, uaa->device); 591 592 uaudio_mixer_fill_info(sc, uaa->device, id); 593 594 sc->sc_mixer_iface_index = uaa->info.bIfaceIndex; 595 sc->sc_mixer_iface_no = uaa->info.bIfaceNum; 596 597 DPRINTF("audio rev %d.%02x\n", 598 sc->sc_audio_rev >> 8, 599 sc->sc_audio_rev & 0xff); 600 601 DPRINTF("%d mixer controls\n", 602 sc->sc_mixer_count); 603 604 if (sc->sc_play_chan.valid) { 605 device_printf(dev, "Play: %d Hz, %d ch, %s format\n", 606 sc->sc_play_chan.sample_rate, 607 sc->sc_play_chan.p_asf1d->bNrChannels, 608 sc->sc_play_chan.p_fmt->description); 609 } else { 610 device_printf(dev, "No playback!\n"); |
564 } 565 | 611 } 612 |
566 sc->sc_ac_ifaceh = uaa->iface; 567 /* Pick up the AS interface. */ 568 for (i = 0; i < uaa->nifaces; i++) { 569 if (uaa->ifaces[i] == NULL) 570 continue; 571 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 572 if (id == NULL) 573 continue; 574 found = 0; 575 for (j = 0; j < sc->sc_nalts; j++) { 576 if (id->bInterfaceNumber == 577 sc->sc_alts[j].idesc->bInterfaceNumber) { 578 sc->sc_alts[j].ifaceh = uaa->ifaces[i]; 579 found = 1; 580 } 581 } 582 if (found) 583 uaa->ifaces[i] = NULL; | 613 if (sc->sc_rec_chan.valid) { 614 device_printf(dev, "Record: %d Hz, %d ch, %s format\n", 615 sc->sc_rec_chan.sample_rate, 616 sc->sc_rec_chan.p_asf1d->bNrChannels, 617 sc->sc_rec_chan.p_fmt->description); 618 } else { 619 device_printf(dev, "No recording!\n"); |
584 } 585 | 620 } 621 |
586 for (j = 0; j < sc->sc_nalts; j++) { 587 if (sc->sc_alts[j].ifaceh == NULL) { 588 printf("%s: alt %d missing AS interface(s)\n", 589 device_get_nameunit(sc->sc_dev), j); 590 return ENXIO; | 622 if (sc->sc_midi_chan.valid) { 623 624 if (umidi_probe(dev)) { 625 goto detach; |
591 } | 626 } |
627 device_printf(dev, "MIDI sequencer\n"); 628 } else { 629 device_printf(dev, "No midi sequencer\n"); |
|
592 } 593 | 630 } 631 |
594 printf("%s: audio rev %d.%02x\n", device_get_nameunit(sc->sc_dev), 595 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); | 632 DPRINTF("doing child attach\n"); |
596 | 633 |
597 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 598 sc->sc_playchan.altidx = -1; 599 sc->sc_recchan.altidx = -1; | 634 /* attach the children */ |
600 | 635 |
601 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) 602 sc->sc_altflags |= UA_NOFRAC; | 636 sc->sc_sndcard_func.func = SCF_PCM; |
603 | 637 |
604#ifndef USB_DEBUG 605 if (bootverbose) 606#endif 607 printf("%s: %d mixer controls\n", device_get_nameunit(sc->sc_dev), 608 sc->sc_nctls); | 638 child = device_add_child(dev, "pcm", -1); |
609 | 639 |
610#if !defined(__FreeBSD__) 611 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 612 USBDEV(sc->sc_dev)); 613#endif | 640 if (child == NULL) { 641 DPRINTF("out of memory\n"); 642 goto detach; 643 } 644 device_set_ivars(child, &sc->sc_sndcard_func); |
614 | 645 |
615 DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); 616#if defined(__OpenBSD__) 617 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 618#elif defined(__NetBSD__) 619 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 620#elif defined(__FreeBSD__) 621 sc->sc_dying = 0; 622 if (audio_attach_mi(sc->sc_dev)) { 623 printf("audio_attach_mi failed\n"); 624 return ENXIO; | 646 if (bus_generic_attach(dev)) { 647 DPRINTF("child attach failed\n"); 648 goto detach; |
625 } | 649 } |
626#endif | 650 return (0); /* success */ |
627 | 651 |
628#if defined(__FreeBSD__) 629 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->sc_dev), 630 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), 631 OID_AUTO, "async", CTLFLAG_RW, &sc->async, 0, 632 "Asynchronous USB request"); 633#endif 634 return 0; | 652detach: 653 uaudio_detach(dev); 654 return (ENXIO); |
635} 636 | 655} 656 |
637#if defined(__NetBSD__) || defined(__OpenBSD__) | 657static void 658uaudio_pcm_setflags(device_t dev, uint32_t flags) 659{ 660 pcm_setflags(dev, pcm_getflags(dev) | flags); 661} 662 |
638int | 663int |
639uaudio_activate(device_t self, enum devact act) | 664uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class) |
640{ | 665{ |
641 struct uaudio_softc *sc; 642 int rv; | 666 struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); 667 char status[SND_STATUSLEN]; |
643 | 668 |
644 sc = (struct uaudio_softc *)self; 645 rv = 0; 646 switch (act) { 647 case DVACT_ACTIVATE: 648 return EOPNOTSUPP; | 669 uaudio_mixer_init(sc); |
649 | 670 |
650 case DVACT_DEACTIVATE: 651 if (sc->sc_audiodev != NULL) 652 rv = config_deactivate(sc->sc_audiodev); 653 sc->sc_dying = 1; 654 break; | 671 if (sc->sc_uq_audio_swap_lr) { 672 DPRINTF("hardware has swapped left and right\n"); 673 uaudio_pcm_setflags(dev, SD_F_PSWAPLR); |
655 } | 674 } |
656 return rv; | 675 if (!(sc->sc_mix_info & SOUND_MASK_PCM)) { 676 677 DPRINTF("emulating master volume\n"); 678 679 /* 680 * Emulate missing pcm mixer controller 681 * through FEEDER_VOLUME 682 */ 683 uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL); 684 } 685 if (mixer_init(dev, mixer_class, sc)) { 686 goto detach; 687 } 688 sc->sc_mixer_init = 1; 689 690 snprintf(status, sizeof(status), "at ? %s", PCM_KLDSTRING(snd_uaudio)); 691 692 if (pcm_register(dev, sc, 693 sc->sc_play_chan.valid ? 1 : 0, 694 sc->sc_rec_chan.valid ? 1 : 0)) { 695 goto detach; 696 } 697 sc->sc_pcm_registered = 1; 698 699 if (sc->sc_play_chan.valid) { 700 pcm_addchan(dev, PCMDIR_PLAY, chan_class, sc); 701 } 702 if (sc->sc_rec_chan.valid) { 703 pcm_addchan(dev, PCMDIR_REC, chan_class, sc); 704 } 705 pcm_setstatus(dev, status); 706 707 return (0); /* success */ 708 709detach: 710 uaudio_detach_sub(dev); 711 return (ENXIO); |
657} | 712} |
658#endif | |
659 | 713 |
660#if defined(__NetBSD__) || defined(__OpenBSD__) | |
661int | 714int |
662uaudio_detach(device_t self, int flags) | 715uaudio_detach_sub(device_t dev) |
663{ | 716{ |
664 struct uaudio_softc *sc; 665 int rv; | 717 struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); 718 int error = 0; |
666 | 719 |
667 sc = (struct uaudio_softc *)self; 668 rv = 0; 669 /* Wait for outstanding requests to complete. */ 670 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); | 720repeat: 721 if (sc->sc_pcm_registered) { 722 error = pcm_unregister(dev); 723 } else { 724 if (sc->sc_mixer_init) { 725 error = mixer_uninit(dev); 726 } 727 } |
671 | 728 |
672 if (sc->sc_audiodev != NULL) 673 rv = config_detach(sc->sc_audiodev, flags); | 729 if (error) { 730 device_printf(dev, "Waiting for sound application to exit!\n"); 731 usb2_pause_mtx(NULL, 2 * hz); 732 goto repeat; /* try again */ 733 } 734 return (0); /* success */ 735} |
674 | 736 |
675 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 676 USBDEV(sc->sc_dev)); | 737static int 738uaudio_detach(device_t dev) 739{ 740 struct uaudio_softc *sc = device_get_softc(dev); |
677 | 741 |
678 return rv; | 742 if (bus_generic_detach(dev)) { 743 DPRINTF("detach failed!\n"); 744 } 745 sbuf_delete(&sc->sc_sndstat); 746 sc->sc_sndstat_valid = 0; 747 748 umidi_detach(dev); 749 750 return (0); |
679} | 751} |
680#elif defined(__FreeBSD__) | |
681 | 752 |
682USB_DETACH(uaudio) | 753/*========================================================================* 754 * AS - Audio Stream - routines 755 *========================================================================*/ 756 757#if USB_DEBUG 758static void 759uaudio_chan_dump_ep_desc(const usb2_endpoint_descriptor_audio_t *ed) |
683{ | 760{ |
684 struct sndcard_func *func; 685 device_t *devlist = NULL; 686 int err, i, devcount; | 761 if (ed) { 762 DPRINTF("endpoint=%p bLength=%d bDescriptorType=%d \n" 763 "bEndpointAddress=%d bmAttributes=0x%x \n" 764 "wMaxPacketSize=%d bInterval=%d \n" 765 "bRefresh=%d bSynchAddress=%d\n", 766 ed, ed->bLength, ed->bDescriptorType, 767 ed->bEndpointAddress, ed->bmAttributes, 768 UGETW(ed->wMaxPacketSize), ed->bInterval, 769 ed->bRefresh, ed->bSynchAddress); 770 } 771} |
687 | 772 |
688 USB_DETACH_START(uaudio, sc); | 773#endif |
689 | 774 |
690 sbuf_delete(&(sc->uaudio_sndstat)); 691 sc->uaudio_sndstat_flag = 0; | 775static void 776uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb2_device *udev, 777 uint32_t rate, uint16_t fps, uint8_t channels, 778 uint8_t bit_resolution) 779{ 780 struct usb2_descriptor *desc = NULL; 781 const struct usb2_audio_streaming_interface_descriptor *asid = NULL; 782 const struct usb2_audio_streaming_type1_descriptor *asf1d = NULL; 783 const struct usb2_audio_streaming_endpoint_descriptor *sed = NULL; 784 const usb2_endpoint_descriptor_audio_t *ed1 = NULL; 785 const usb2_endpoint_descriptor_audio_t *ed2 = NULL; 786 struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev); 787 struct usb2_interface_descriptor *id; 788 const struct uaudio_format *p_fmt; 789 struct uaudio_chan *chan; 790 uint16_t curidx = 0xFFFF; 791 uint16_t lastidx = 0xFFFF; 792 uint16_t alt_index = 0; 793 uint16_t wFormat; 794 uint8_t ep_dir; 795 uint8_t ep_type; 796 uint8_t ep_sync; 797 uint8_t bChannels; 798 uint8_t bBitResolution; 799 uint8_t x; 800 uint8_t audio_if = 0; 801 uint8_t sample_size; |
692 | 802 |
693 sc->sc_dying = 1; | 803 while ((desc = usb2_desc_foreach(cd, desc))) { |
694 | 804 |
695#if 0 /* XXX */ 696 /* Wait for outstanding requests to complete. */ 697 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); | 805 if ((desc->bDescriptorType == UDESC_INTERFACE) && 806 (desc->bLength >= sizeof(*id))) { 807 808 id = (void *)desc; 809 810 if (id->bInterfaceNumber != lastidx) { 811 lastidx = id->bInterfaceNumber; 812 curidx++; 813 alt_index = 0; 814 815 } else { 816 alt_index++; 817 } 818 819 if ((id->bInterfaceClass == UICLASS_AUDIO) && 820 (id->bInterfaceSubClass == UISUBCLASS_AUDIOSTREAM)) { 821 audio_if = 1; 822 } else { 823 audio_if = 0; 824 } 825 826 if ((id->bInterfaceClass == UICLASS_AUDIO) && 827 (id->bInterfaceSubClass == UISUBCLASS_MIDISTREAM)) { 828 829 /* 830 * XXX could allow multiple MIDI interfaces 831 * XXX 832 */ 833 834 if ((sc->sc_midi_chan.valid == 0) && 835 usb2_get_iface(udev, curidx)) { 836 sc->sc_midi_chan.iface_index = curidx; 837 sc->sc_midi_chan.iface_alt_index = alt_index; 838 sc->sc_midi_chan.valid = 1; 839 } 840 } 841 asid = NULL; 842 asf1d = NULL; 843 ed1 = NULL; 844 ed2 = NULL; 845 sed = NULL; 846 } 847 if ((desc->bDescriptorType == UDESC_CS_INTERFACE) && 848 (desc->bDescriptorSubtype == AS_GENERAL) && 849 (desc->bLength >= sizeof(*asid))) { 850 if (asid == NULL) { 851 asid = (void *)desc; 852 } 853 } 854 if ((desc->bDescriptorType == UDESC_CS_INTERFACE) && 855 (desc->bDescriptorSubtype == FORMAT_TYPE) && 856 (desc->bLength >= sizeof(*asf1d))) { 857 if (asf1d == NULL) { 858 asf1d = (void *)desc; 859 if (asf1d->bFormatType != FORMAT_TYPE_I) { 860 DPRINTFN(11, "ignored bFormatType = %d\n", 861 asf1d->bFormatType); 862 asf1d = NULL; 863 continue; 864 } 865 if (asf1d->bLength < (sizeof(*asf1d) + 866 (asf1d->bSamFreqType == 0) ? 6 : 867 (asf1d->bSamFreqType * 3))) { 868 DPRINTFN(11, "'asf1d' descriptor is too short\n"); 869 asf1d = NULL; 870 continue; 871 } 872 } 873 } 874 if ((desc->bDescriptorType == UDESC_ENDPOINT) && 875 (desc->bLength >= sizeof(*ed1))) { 876 if (ed1 == NULL) { 877 ed1 = (void *)desc; 878 if (UE_GET_XFERTYPE(ed1->bmAttributes) != UE_ISOCHRONOUS) { 879 ed1 = NULL; 880 } 881 } else { 882 if (ed2 == NULL) { 883 ed2 = (void *)desc; 884 if (UE_GET_XFERTYPE(ed2->bmAttributes) != UE_ISOCHRONOUS) { 885 ed2 = NULL; 886 continue; 887 } 888 if (ed2->bSynchAddress != 0) { 889 DPRINTFN(11, "invalid endpoint: bSynchAddress != 0\n"); 890 ed2 = NULL; 891 continue; 892 } 893 if (ed2->bEndpointAddress != ed1->bSynchAddress) { 894 DPRINTFN(11, "invalid endpoint addresses: " 895 "ep[0]->bSynchAddress=0x%x " 896 "ep[1]->bEndpointAddress=0x%x\n", 897 ed1->bSynchAddress, 898 ed2->bEndpointAddress); 899 ed2 = NULL; 900 continue; 901 } 902 } 903 } 904 } 905 if ((desc->bDescriptorType == UDESC_CS_ENDPOINT) && 906 (desc->bDescriptorSubtype == AS_GENERAL) && 907 (desc->bLength >= sizeof(*sed))) { 908 if (sed == NULL) { 909 sed = (void *)desc; 910 } 911 } 912 if (audio_if && asid && asf1d && ed1 && sed) { 913 914 ep_dir = UE_GET_DIR(ed1->bEndpointAddress); 915 ep_type = UE_GET_ISO_TYPE(ed1->bmAttributes); 916 ep_sync = 0; 917 918 if ((sc->sc_uq_au_inp_async) && 919 (ep_dir == UE_DIR_IN) && (ep_type == UE_ISO_ADAPT)) { 920 ep_type = UE_ISO_ASYNC; 921 } 922 if ((ep_dir == UE_DIR_IN) && (ep_type == UE_ISO_ADAPT)) { 923 ep_sync = 1; 924 } 925 if ((ep_dir != UE_DIR_IN) && (ep_type == UE_ISO_ASYNC)) { 926 ep_sync = 1; 927 } 928 /* Ignore sync endpoint information until further. */ 929#if 0 930 if (ep_sync && (!ed2)) { 931 continue; 932 } 933 /* 934 * we can't handle endpoints that need a sync pipe 935 * yet 936 */ 937 938 if (ep_sync) { 939 DPRINTF("skipped sync interface\n"); 940 audio_if = 0; 941 continue; 942 } |
698#endif 699 | 943#endif 944 |
700 err = bus_generic_detach(sc->sc_dev); | 945 wFormat = UGETW(asid->wFormatTag); 946 bChannels = asf1d->bNrChannels; 947 bBitResolution = asf1d->bBitResolution; |
701 | 948 |
702 if (err == 0 && 703 device_get_children(sc->sc_dev, &devlist, &devcount) == 0) { 704 for (i = 0; devlist != NULL && i < devcount; i++) { 705 func = device_get_ivars(devlist[i]); 706 if (func != NULL && func->func == SCF_PCM && 707 func->varinfo == NULL) { 708 device_set_ivars(devlist[i], NULL); 709 free(func, M_DEVBUF); 710 device_delete_child(sc->sc_dev, devlist[i]); | 949 if (asf1d->bSamFreqType == 0) { 950 DPRINTFN(16, "Sample rate: %d-%dHz\n", 951 UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 952 953 if ((rate >= UA_SAMP_LO(asf1d)) && 954 (rate <= UA_SAMP_HI(asf1d))) { 955 goto found_rate; 956 } 957 } else { 958 959 for (x = 0; x < asf1d->bSamFreqType; x++) { 960 DPRINTFN(16, "Sample rate = %dHz\n", 961 UA_GETSAMP(asf1d, x)); 962 963 if (rate == UA_GETSAMP(asf1d, x)) { 964 goto found_rate; 965 } 966 } |
711 } | 967 } |
968 969 audio_if = 0; 970 continue; 971 972 found_rate: 973 974 for (p_fmt = uaudio_formats; 975 p_fmt->wFormat; 976 p_fmt++) { 977 if ((p_fmt->wFormat == wFormat) && 978 (p_fmt->bPrecision == bBitResolution)) { 979 goto found_format; 980 } 981 } 982 983 audio_if = 0; 984 continue; 985 986 found_format: 987 988 if ((bChannels == channels) && 989 (bBitResolution == bit_resolution)) { 990 991 chan = (ep_dir == UE_DIR_IN) ? 992 &sc->sc_rec_chan : 993 &sc->sc_play_chan; 994 995 if ((chan->valid == 0) && usb2_get_iface(udev, curidx)) { 996 997 chan->valid = 1; 998#if USB_DEBUG 999 uaudio_chan_dump_ep_desc(ed1); 1000 uaudio_chan_dump_ep_desc(ed2); 1001 1002 if (sed->bmAttributes & UA_SED_FREQ_CONTROL) { 1003 DPRINTFN(2, "FREQ_CONTROL\n"); 1004 } 1005 if (sed->bmAttributes & UA_SED_PITCH_CONTROL) { 1006 DPRINTFN(2, "PITCH_CONTROL\n"); 1007 } 1008#endif 1009 DPRINTF("Sample rate = %dHz, channels = %d, " 1010 "bits = %d, format = %s\n", rate, channels, 1011 bit_resolution, p_fmt->description); 1012 1013 chan->sample_rate = rate; 1014 chan->p_asid = asid; 1015 chan->p_asf1d = asf1d; 1016 chan->p_ed1 = ed1; 1017 chan->p_ed2 = ed2; 1018 chan->p_fmt = p_fmt; 1019 chan->p_sed = sed; 1020 chan->iface_index = curidx; 1021 chan->iface_alt_index = alt_index; 1022 1023 if (ep_dir == UE_DIR_IN) 1024 chan->usb2_cfg = 1025 uaudio_cfg_record; 1026 else 1027 chan->usb2_cfg = 1028 uaudio_cfg_play; 1029 1030 sample_size = ((chan->p_asf1d->bNrChannels * 1031 chan->p_asf1d->bBitResolution) / 8); 1032 1033 /* 1034 * NOTE: "chan->bytes_per_frame" 1035 * should not be zero! 1036 */ 1037 chan->bytes_per_frame = ((rate / fps) * sample_size); 1038 1039 if (sc->sc_sndstat_valid) { 1040 sbuf_printf(&sc->sc_sndstat, "\n\t" 1041 "mode %d.%d:(%s) %dch, %d/%dbit, %s, %dHz", 1042 curidx, alt_index, 1043 (ep_dir == UE_DIR_IN) ? "input" : "output", 1044 asf1d->bNrChannels, asf1d->bBitResolution, 1045 asf1d->bSubFrameSize * 8, 1046 p_fmt->description, rate); 1047 } 1048 } 1049 } 1050 audio_if = 0; 1051 continue; |
|
712 } | 1052 } |
713 free(devlist, M_TEMP); | |
714 } | 1053 } |
715 716 return err; | |
717} | 1054} |
718#endif | |
719 | 1055 |
720#if defined(__NetBSD__) || defined(__OpenBSD__) 721static int 722uaudio_query_encoding(void *addr, struct audio_encoding *fp) | 1056static void 1057uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb2_device *udev) |
723{ | 1058{ |
724 struct uaudio_softc *sc; 725 int flags; 726 int idx; | 1059 uint32_t rate = uaudio_default_rate; 1060 uint32_t z; 1061 uint16_t fps = usb2_get_isoc_fps(udev); 1062 uint8_t bits = uaudio_default_bits; 1063 uint8_t y; 1064 uint8_t channels = uaudio_default_channels; 1065 uint8_t x; |
727 | 1066 |
728 sc = addr; 729 flags = sc->sc_altflags; 730 if (sc->sc_dying) 731 return EIO; | 1067 bits -= (bits % 8); 1068 if ((bits == 0) || (bits > 32)) { 1069 /* set a valid value */ 1070 bits = 32; 1071 } 1072 rate -= (rate % fps); 1073 if ((rate == 0) || (rate > 192000)) { 1074 /* set a valid value */ 1075 rate = 192000 - (192000 % fps); 1076 } 1077 if ((channels == 0) || (channels > 2)) { 1078 /* set a valid value */ 1079 channels = 2; 1080 } 1081 if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) { 1082 sc->sc_sndstat_valid = 1; 1083 } 1084 /* try to search for a valid config */ |
732 | 1085 |
733 if (sc->sc_nalts == 0 || flags == 0) 734 return ENXIO; | 1086 for (x = channels; x; x--) { 1087 for (y = bits; y; y -= 8) { 1088 for (z = rate; z; z -= fps) { 1089 uaudio_chan_fill_info_sub(sc, udev, z, fps, x, y); |
735 | 1090 |
736 idx = fp->index; 737 switch (idx) { 738 case 0: 739 strlcpy(fp->name, AudioEulinear, sizeof(fp->name)); 740 fp->encoding = AUDIO_ENCODING_ULINEAR; 741 fp->precision = 8; 742 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 743 return (0); 744 case 1: 745 strlcpy(fp->name, AudioEmulaw, sizeof(fp->name)); 746 fp->encoding = AUDIO_ENCODING_ULAW; 747 fp->precision = 8; 748 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 749 return (0); 750 case 2: 751 strlcpy(fp->name, AudioEalaw, sizeof(fp->name)); 752 fp->encoding = AUDIO_ENCODING_ALAW; 753 fp->precision = 8; 754 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 755 return (0); 756 case 3: 757 strlcpy(fp->name, AudioEslinear, sizeof(fp->name)); 758 fp->encoding = AUDIO_ENCODING_SLINEAR; 759 fp->precision = 8; 760 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 761 return (0); 762 case 4: 763 strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name)); 764 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 765 fp->precision = 16; 766 fp->flags = 0; 767 return (0); 768 case 5: 769 strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name)); 770 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 771 fp->precision = 16; 772 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 773 return (0); 774 case 6: 775 strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name)); 776 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 777 fp->precision = 16; 778 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 779 return (0); 780 case 7: 781 strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name)); 782 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 783 fp->precision = 16; 784 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 785 return (0); 786 default: 787 return (EINVAL); | 1091 if (sc->sc_rec_chan.valid && 1092 sc->sc_play_chan.valid) { 1093 goto done; 1094 } 1095 } 1096 } |
788 } | 1097 } |
1098 1099done: 1100 if (sc->sc_sndstat_valid) { 1101 sbuf_finish(&sc->sc_sndstat); 1102 } |
|
789} | 1103} |
790#endif | |
791 | 1104 |
792static const usb_interface_descriptor_t * 793uaudio_find_iface(const char *buf, int size, int *offsp, int subtype) | 1105static void 1106uaudio_chan_play_callback(struct usb2_xfer *xfer) |
794{ | 1107{ |
795 const usb_interface_descriptor_t *d; | 1108 struct uaudio_chan *ch = xfer->priv_sc; 1109 uint32_t *p_len = xfer->frlengths; 1110 uint32_t total; 1111 uint32_t blockcount; 1112 uint32_t n; 1113 uint32_t offset; |
796 | 1114 |
797 while (*offsp < size) { 798 d = (const void *)(buf + *offsp); 799 *offsp += d->bLength; 800 if (d->bDescriptorType == UDESC_INTERFACE && 801 d->bInterfaceClass == UICLASS_AUDIO && 802 d->bInterfaceSubClass == subtype) 803 return d; | 1115 /* allow dynamic sizing of play buffer */ 1116 total = ch->intr_size; 1117 1118 /* allow dynamic sizing of play buffer */ 1119 blockcount = total / ch->bytes_per_frame; 1120 1121 /* align units */ 1122 blockcount -= (blockcount % UAUDIO_MINFRAMES); 1123 1124 /* range check - min */ 1125 if (blockcount == 0) { 1126 blockcount = UAUDIO_MINFRAMES; |
804 } | 1127 } |
805 return NULL; | 1128 /* range check - max */ 1129 if (blockcount > xfer->max_frame_count) { 1130 blockcount = xfer->max_frame_count; 1131 } 1132 /* compute the total length */ 1133 total = blockcount * ch->bytes_per_frame; 1134 1135 switch (USB_GET_STATE(xfer)) { 1136 case USB_ST_TRANSFERRED: 1137tr_transferred: 1138 if (xfer->actlen < xfer->sumlen) { 1139 DPRINTF("short transfer, " 1140 "%d of %d bytes\n", xfer->actlen, total); 1141 } 1142 chn_intr(ch->pcm_ch); 1143 1144 case USB_ST_SETUP: 1145 if (ch->bytes_per_frame > xfer->max_frame_size) { 1146 DPRINTF("bytes per transfer, %d, " 1147 "exceeds maximum, %d!\n", 1148 ch->bytes_per_frame, 1149 xfer->max_frame_size); 1150 break; 1151 } 1152 /* setup frame length */ 1153 xfer->nframes = blockcount; 1154 for (n = 0; n != blockcount; n++) { 1155 p_len[n] = ch->bytes_per_frame; 1156 } 1157 1158 if (ch->end == ch->start) { 1159 DPRINTF("no buffer!\n"); 1160 break; 1161 } 1162 DPRINTFN(6, "transfer %d bytes\n", total); 1163 1164 offset = 0; 1165 1166 while (total > 0) { 1167 1168 n = (ch->end - ch->cur); 1169 if (n > total) { 1170 n = total; 1171 } 1172 usb2_copy_in(xfer->frbuffers, offset, ch->cur, n); 1173 1174 total -= n; 1175 ch->cur += n; 1176 offset += n; 1177 1178 if (ch->cur >= ch->end) { 1179 ch->cur = ch->start; 1180 } 1181 } 1182 1183 usb2_start_hardware(xfer); 1184 break; 1185 1186 default: /* Error */ 1187 if (xfer->error == USB_ERR_CANCELLED) { 1188 break; 1189 } 1190 goto tr_transferred; 1191 } |
806} 807 808static void | 1192} 1193 1194static void |
809uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) | 1195uaudio_chan_record_callback(struct usb2_xfer *xfer) |
810{ | 1196{ |
811 int res; 812 size_t len; 813 struct mixerctl *nmc; | 1197 struct uaudio_chan *ch = xfer->priv_sc; 1198 uint32_t *p_len = xfer->frlengths; 1199 uint32_t n; 1200 uint32_t m; 1201 uint32_t total; 1202 uint32_t blockcount; 1203 uint32_t offset0; 1204 uint32_t offset1; |
814 | 1205 |
815#if defined(__FreeBSD__) 816 if (mc->class < UAC_NCLASSES) { 817 DPRINTF(("%s: adding %s.%d\n", 818 __func__, uac_names[mc->class], mc->ctl)); 819 } else { 820 DPRINTF(("%s: adding %d\n", __func__, mc->ctl)); | 1206 /* allow dynamic sizing of play buffer */ 1207 total = ch->intr_size; 1208 1209 /* allow dynamic sizing of play buffer */ 1210 blockcount = total / ch->bytes_per_frame; 1211 1212 /* align units */ 1213 blockcount -= (blockcount % UAUDIO_MINFRAMES); 1214 1215 /* range check - min */ 1216 if (blockcount == 0) { 1217 blockcount = UAUDIO_MINFRAMES; |
821 } | 1218 } |
822#else 823 if (mc->class < UAC_NCLASSES) { 824 DPRINTF(("%s: adding %s.%s\n", 825 __func__, uac_names[mc->class], mc->ctlname)); 826 } else { 827 DPRINTF(("%s: adding %s\n", __func__, mc->ctlname)); | 1219 /* range check - max */ 1220 if (blockcount > xfer->max_frame_count) { 1221 blockcount = xfer->max_frame_count; |
828 } | 1222 } |
829#endif 830 len = sizeof(*mc) * (sc->sc_nctls + 1); 831 nmc = malloc(len, M_USBDEV, M_NOWAIT); 832 if (nmc == NULL) { 833 printf("uaudio_mixer_add_ctl: no memory\n"); | 1223 /* compute the total length */ 1224 total = blockcount * ch->bytes_per_frame; 1225 1226 switch (USB_GET_STATE(xfer)) { 1227 case USB_ST_TRANSFERRED: 1228tr_transferred: 1229 if (xfer->actlen < total) { 1230 DPRINTF("short transfer, " 1231 "%d of %d bytes\n", xfer->actlen, total); 1232 } else { 1233 DPRINTFN(6, "transferred %d bytes\n", xfer->actlen); 1234 } 1235 1236 offset0 = 0; 1237 1238 for (n = 0; n != xfer->nframes; n++) { 1239 1240 offset1 = offset0; 1241 1242 while (p_len[n] > 0) { 1243 1244 m = (ch->end - ch->cur); 1245 1246 if (m > p_len[n]) { 1247 m = p_len[n]; 1248 } 1249 usb2_copy_out(xfer->frbuffers, offset1, ch->cur, m); 1250 1251 p_len[n] -= m; 1252 offset1 += m; 1253 ch->cur += m; 1254 1255 if (ch->cur >= ch->end) { 1256 ch->cur = ch->start; 1257 } 1258 } 1259 1260 offset0 += ch->bytes_per_frame; 1261 } 1262 1263 chn_intr(ch->pcm_ch); 1264 1265 case USB_ST_SETUP: 1266 if (ch->bytes_per_frame > xfer->max_frame_size) { 1267 DPRINTF("bytes per transfer, %d, " 1268 "exceeds maximum, %d!\n", 1269 ch->bytes_per_frame, 1270 xfer->max_frame_size); 1271 return; 1272 } 1273 xfer->nframes = blockcount; 1274 for (n = 0; n != xfer->nframes; n++) { 1275 p_len[n] = ch->bytes_per_frame; 1276 } 1277 1278 if (ch->end == ch->start) { 1279 DPRINTF("no buffer!\n"); 1280 return; 1281 } 1282 usb2_start_hardware(xfer); |
834 return; | 1283 return; |
1284 1285 default: /* Error */ 1286 if (xfer->error == USB_ERR_CANCELLED) { 1287 return; 1288 } 1289 goto tr_transferred; |
|
835 } | 1290 } |
836 /* Copy old data, if there was any */ 837 if (sc->sc_nctls != 0) { 838 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls)); 839 free(sc->sc_ctls, M_USBDEV); | 1291} 1292 1293void * 1294uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, 1295 struct pcm_channel *c, int dir) 1296{ 1297 struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ? 1298 &sc->sc_play_chan : &sc->sc_rec_chan); 1299 uint32_t buf_size; 1300 uint8_t endpoint; 1301 uint8_t iface_index; 1302 uint8_t alt_index; 1303 usb2_error_t err; 1304 1305 /* compute required buffer size */ 1306 buf_size = (ch->bytes_per_frame * UAUDIO_MINFRAMES); 1307 1308 /* setup interrupt interval */ 1309 ch->intr_size = buf_size; 1310 1311 /* double buffering */ 1312 buf_size *= 2; 1313 1314 ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO); 1315 if (ch->buf == NULL) { 1316 goto error; |
840 } | 1317 } |
841 sc->sc_ctls = nmc; | 1318 if (sndbuf_setup(b, ch->buf, buf_size) != 0) { 1319 goto error; 1320 } 1321 ch->start = ch->buf; 1322 ch->end = ch->buf + buf_size; 1323 ch->cur = ch->buf; 1324 ch->pcm_ch = c; 1325 ch->pcm_mtx = c->lock; 1326 ch->pcm_buf = b; |
842 | 1327 |
843 mc->delta = 0; 844 if (mc->type == MIX_ON_OFF) { 845 mc->minval = 0; 846 mc->maxval = 1; 847 } else if (mc->type == MIX_SELECTOR) { 848 ; 849 } else { 850 /* Determine min and max values. */ 851 mc->minval = uaudio_signext(mc->type, 852 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 853 mc->wValue[0], mc->wIndex, 854 MIX_SIZE(mc->type))); 855 mc->maxval = 1 + uaudio_signext(mc->type, 856 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 857 mc->wValue[0], mc->wIndex, 858 MIX_SIZE(mc->type))); 859 mc->mul = mc->maxval - mc->minval; 860 if (mc->mul == 0) 861 mc->mul = 1; 862 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 863 mc->wValue[0], mc->wIndex, 864 MIX_SIZE(mc->type)); 865 if (res > 0) 866 mc->delta = (res * 255 + mc->mul/2) / mc->mul; | 1328 if (ch->pcm_mtx == NULL) { 1329 DPRINTF("ERROR: PCM channels does not have a mutex!\n"); 1330 goto error; |
867 } | 1331 } |
1332 /* setup play/record format */ |
|
868 | 1333 |
869 sc->sc_ctls[sc->sc_nctls++] = *mc; | 1334 ch->pcm_cap.fmtlist = ch->pcm_format; |
870 | 1335 |
871#ifdef USB_DEBUG 872 if (uaudiodebug > 2) { 873 int i; 874 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0])); 875 for (i = 1; i < mc->nchan; i++) 876 DPRINTF((",%04x", mc->wValue[i])); 877#if defined(__FreeBSD__) 878 DPRINTF((" wIndex=%04x type=%d ctl='%d' " 879 "min=%d max=%d\n", 880 mc->wIndex, mc->type, mc->ctl, 881 mc->minval, mc->maxval)); 882#else 883 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' " 884 "min=%d max=%d\n", 885 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 886 mc->minval, mc->maxval)); 887#endif | 1336 ch->pcm_format[0] = 0; 1337 ch->pcm_format[1] = 0; 1338 1339 ch->pcm_cap.minspeed = ch->sample_rate; 1340 ch->pcm_cap.maxspeed = ch->sample_rate; 1341 1342 ch->pcm_cap.fmtlist[0] = ch->p_fmt->freebsd_fmt; 1343 1344 if (ch->p_asf1d->bNrChannels == 2) { 1345 ch->pcm_cap.fmtlist[0] |= AFMT_STEREO; |
888 } | 1346 } |
889#endif | 1347 ch->pcm_cap.fmtlist[1] = 0; 1348 1349 1350 /* set alternate interface corresponding to the mode */ 1351 1352 endpoint = ch->p_ed1->bEndpointAddress; 1353 iface_index = ch->iface_index; 1354 alt_index = ch->iface_alt_index; 1355 1356 DPRINTF("endpoint=0x%02x, speed=%d, iface=%d alt=%d\n", 1357 endpoint, ch->sample_rate, iface_index, alt_index); 1358 1359 err = usb2_set_alt_interface_index(sc->sc_udev, iface_index, alt_index); 1360 if (err) { 1361 DPRINTF("setting of alternate index failed: %s!\n", 1362 usb2_errstr(err)); 1363 goto error; 1364 } 1365 usb2_set_parent_iface(sc->sc_udev, iface_index, sc->sc_mixer_iface_index); 1366 1367 /* 1368 * If just one sampling rate is supported, 1369 * no need to call "uaudio_set_speed()". 1370 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request. 1371 */ 1372 if (ch->p_asf1d->bSamFreqType != 1) { 1373 if (uaudio_set_speed(sc->sc_udev, endpoint, ch->sample_rate)) { 1374 /* 1375 * If the endpoint is adaptive setting the speed may 1376 * fail. 1377 */ 1378 DPRINTF("setting of sample rate failed! (continuing anyway)\n"); 1379 } 1380 } 1381 if (usb2_transfer_setup(sc->sc_udev, &iface_index, ch->xfer, 1382 ch->usb2_cfg, UAUDIO_NCHANBUFS, ch, ch->pcm_mtx)) { 1383 DPRINTF("could not allocate USB transfers!\n"); 1384 goto error; 1385 } 1386 return (ch); 1387 1388error: 1389 uaudio_chan_free(ch); 1390 return (NULL); |
890} 891 | 1391} 1392 |
892#if defined(__NetBSD__) || defined(__OpenBSD__) 893static char * 894uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1393int 1394uaudio_chan_free(struct uaudio_chan *ch) |
895{ | 1395{ |
896 static char buf[32]; | 1396 if (ch->buf != NULL) { 1397 free(ch->buf, M_DEVBUF); 1398 ch->buf = NULL; 1399 } 1400 usb2_transfer_unsetup(ch->xfer, UAUDIO_NCHANBUFS); |
897 | 1401 |
898 snprintf(buf, sizeof(buf), "i%d", id); 899 return buf; | 1402 ch->valid = 0; 1403 1404 return (0); |
900} | 1405} |
901#endif | |
902 | 1406 |
903#ifdef USB_DEBUG 904static void 905uaudio_dump_cluster(const struct usb_audio_cluster *cl) | 1407int 1408uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize) |
906{ | 1409{ |
907 static const char *channel_names[16] = { 908 "LEFT", "RIGHT", "CENTER", "LFE", 909 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER", 910 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP", 911 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", 912 }; 913 int cc, i, first; | 1410 uaudio_chan_set_param_fragments(ch, blocksize, 0 - 1); |
914 | 1411 |
915 cc = UGETW(cl->wChannelConfig); 916 printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x", 917 cl->bNrChannels, cc); 918 first = TRUE; 919 for (i = 0; cc != 0; i++) { 920 if (cc & 1) { 921 printf("%c%s", first ? '<' : ',', channel_names[i]); 922 first = FALSE; | 1412 return (ch->block_size); 1413} 1414 1415int 1416uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize, 1417 uint32_t blockcount) 1418{ 1419 /* we only support one size */ 1420 blocksize = ch->intr_size; 1421 blockcount = 2; 1422 1423 if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) || 1424 (sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) { 1425 DPRINTFN(1, "resizing to %u x " 1426 "%u bytes\n", blockcount, blocksize); 1427 if (sndbuf_resize(ch->pcm_buf, blockcount, blocksize)) { 1428 DPRINTFN(0, "failed to resize sound buffer, count=%u, " 1429 "size=%u\n", blockcount, blocksize); |
923 } | 1430 } |
924 cc = cc >> 1; | |
925 } | 1431 } |
926 printf("> iChannelNames=%u", cl->iChannelNames); | 1432 ch->block_size = sndbuf_getblksz(ch->pcm_buf); 1433 1434 return (1); |
927} | 1435} |
1436 1437int 1438uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed) 1439{ 1440 if (speed != ch->sample_rate) { 1441 DPRINTF("rate conversion required\n"); 1442 } 1443 return (ch->sample_rate); 1444} 1445 1446int 1447uaudio_chan_getptr(struct uaudio_chan *ch) 1448{ 1449 return (ch->cur - ch->start); 1450} 1451 1452struct pcmchan_caps * 1453uaudio_chan_getcaps(struct uaudio_chan *ch) 1454{ 1455 return (&ch->pcm_cap); 1456} 1457 1458int 1459uaudio_chan_set_param_format(struct uaudio_chan *ch, uint32_t format) 1460{ 1461 ch->format = format; 1462 return (0); 1463} 1464 1465int 1466uaudio_chan_start(struct uaudio_chan *ch) 1467{ 1468 ch->cur = ch->start; 1469 1470#if (UAUDIO_NCHANBUFS != 2) 1471#error "please update code" |
|
928#endif | 1472#endif |
1473 if (ch->xfer[0]) { 1474 usb2_transfer_start(ch->xfer[0]); 1475 } 1476 if (ch->xfer[1]) { 1477 usb2_transfer_start(ch->xfer[1]); 1478 } 1479 return (0); 1480} |
|
929 | 1481 |
930static struct usb_audio_cluster 931uaudio_get_cluster(int id, const struct io_terminal *iot) | 1482int 1483uaudio_chan_stop(struct uaudio_chan *ch) |
932{ | 1484{ |
933 struct usb_audio_cluster r; 934 const usb_descriptor_t *dp; 935 int i; | 1485#if (UAUDIO_NCHANBUFS != 2) 1486#error "please update code" 1487#endif 1488 usb2_transfer_stop(ch->xfer[0]); 1489 usb2_transfer_stop(ch->xfer[1]); 1490 return (0); 1491} |
936 | 1492 |
937 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 938 dp = iot[id].d.desc; 939 if (dp == 0) 940 goto bad; 941 switch (dp->bDescriptorSubtype) { 942 case UDESCSUB_AC_INPUT: 943 r.bNrChannels = iot[id].d.it->bNrChannels; 944 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig)); 945 r.iChannelNames = iot[id].d.it->iChannelNames; 946 return r; 947 case UDESCSUB_AC_OUTPUT: 948 id = iot[id].d.ot->bSourceId; 949 break; 950 case UDESCSUB_AC_MIXER: 951 r = *(const struct usb_audio_cluster *) 952 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; 953 return r; 954 case UDESCSUB_AC_SELECTOR: 955 /* XXX This is not really right */ 956 id = iot[id].d.su->baSourceId[0]; 957 break; 958 case UDESCSUB_AC_FEATURE: 959 id = iot[id].d.fu->bSourceId; 960 break; 961 case UDESCSUB_AC_PROCESSING: 962 r = *(const struct usb_audio_cluster *) 963 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; 964 return r; 965 case UDESCSUB_AC_EXTENSION: 966 r = *(const struct usb_audio_cluster *) 967 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; 968 return r; 969 default: 970 goto bad; | 1493/*========================================================================* 1494 * AC - Audio Controller - routines 1495 *========================================================================*/ 1496 1497static void 1498uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) 1499{ 1500 struct uaudio_mixer_node *p_mc_new = 1501 malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); 1502 1503 if (p_mc_new) { 1504 bcopy(mc, p_mc_new, sizeof(*p_mc_new)); 1505 p_mc_new->next = sc->sc_mixer_root; 1506 sc->sc_mixer_root = p_mc_new; 1507 sc->sc_mixer_count++; 1508 } else { 1509 DPRINTF("out of memory\n"); 1510 } 1511} 1512 1513static void 1514uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) 1515{ 1516 int32_t res; 1517 1518 if (mc->class < UAC_NCLASSES) { 1519 DPRINTF("adding %s.%d\n", 1520 uac_names[mc->class], mc->ctl); 1521 } else { 1522 DPRINTF("adding %d\n", mc->ctl); 1523 } 1524 1525 mc->delta = 0; 1526 if (mc->type == MIX_ON_OFF) { 1527 mc->minval = 0; 1528 mc->maxval = 1; 1529 } else if (mc->type == MIX_SELECTOR) { 1530 1531 } else { 1532 1533 /* determine min and max values */ 1534 1535 mc->minval = uaudio_mixer_get(sc->sc_udev, GET_MIN, mc); 1536 1537 mc->minval = uaudio_mixer_signext(mc->type, mc->minval); 1538 1539 mc->maxval = uaudio_mixer_get(sc->sc_udev, GET_MAX, mc); 1540 1541 mc->maxval = 1 + uaudio_mixer_signext(mc->type, mc->maxval); 1542 1543 mc->mul = mc->maxval - mc->minval; 1544 if (mc->mul == 0) { 1545 mc->mul = 1; |
971 } | 1546 } |
1547 res = uaudio_mixer_get(sc->sc_udev, GET_RES, mc); 1548 if (res > 0) { 1549 mc->delta = ((res * 255) + (mc->mul / 2)) / mc->mul; 1550 } |
|
972 } | 1551 } |
973 bad: 974 printf("uaudio_get_cluster: bad data\n"); 975 memset(&r, 0, sizeof r); 976 return r; | |
977 | 1552 |
1553 if (mc->maxval < mc->minval) { 1554 mc->maxval = mc->minval; 1555 } 1556 uaudio_mixer_add_ctl_sub(sc, mc); 1557 1558#if USB_DEBUG 1559 if (uaudio_debug > 2) { 1560 uint8_t i; 1561 1562 for (i = 0; i < mc->nchan; i++) { 1563 DPRINTF("[mix] wValue=%04x\n", mc->wValue[0]); 1564 } 1565 DPRINTF("[mix] wIndex=%04x type=%d ctl='%d' " 1566 "min=%d max=%d\n", 1567 mc->wIndex, mc->type, mc->ctl, 1568 mc->minval, mc->maxval); 1569 } 1570#endif |
|
978} 979 980static void | 1571} 1572 1573static void |
981uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1574uaudio_mixer_add_input(struct uaudio_softc *sc, 1575 const struct uaudio_terminal_node *iot, int id) |
982{ | 1576{ |
983#ifdef USB_DEBUG 984 const struct usb_audio_input_terminal *d = iot[id].d.it; | 1577#if USB_DEBUG 1578 const struct usb2_audio_input_terminal *d = iot[id].u.it; |
985 | 1579 |
986 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x " 987 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 988 "iChannelNames=%d iTerminal=%d\n", 989 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 990 d->bNrChannels, UGETW(d->wChannelConfig), 991 d->iChannelNames, d->iTerminal)); | 1580 DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x " 1581 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 1582 "iChannelNames=%d\n", 1583 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 1584 d->bNrChannels, UGETW(d->wChannelConfig), 1585 d->iChannelNames); |
992#endif 993} 994 995static void | 1586#endif 1587} 1588 1589static void |
996uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1590uaudio_mixer_add_output(struct uaudio_softc *sc, 1591 const struct uaudio_terminal_node *iot, int id) |
997{ | 1592{ |
998#ifdef USB_DEBUG 999 const struct usb_audio_output_terminal *d; | 1593#if USB_DEBUG 1594 const struct usb2_audio_output_terminal *d = iot[id].u.ot; |
1000 | 1595 |
1001 d = iot[id].d.ot; 1002 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x " 1003 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 1004 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 1005 d->bSourceId, d->iTerminal)); | 1596 DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x " 1597 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 1598 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 1599 d->bSourceId, d->iTerminal); |
1006#endif 1007} 1008 1009static void | 1600#endif 1601} 1602 1603static void |
1010uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1604uaudio_mixer_add_mixer(struct uaudio_softc *sc, 1605 const struct uaudio_terminal_node *iot, int id) |
1011{ | 1606{ |
1012 const struct usb_audio_mixer_unit *d = iot[id].d.mu; 1013 const struct usb_audio_mixer_unit_1 *d1; 1014 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 1015 const uByte *bm; 1016 struct mixerctl mix; | 1607 struct uaudio_mixer_node mix; |
1017 | 1608 |
1018 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n", 1019 d->bUnitId, d->bNrInPins)); | 1609 const struct usb2_audio_mixer_unit_0 *d0 = iot[id].u.mu; 1610 const struct usb2_audio_mixer_unit_1 *d1; |
1020 | 1611 |
1021 /* Compute the number of input channels */ | 1612 uint32_t bno; /* bit number */ 1613 uint32_t p; /* bit number accumulator */ 1614 uint32_t mo; /* matching outputs */ 1615 uint32_t mc; /* matching channels */ 1616 uint32_t ichs; /* input channels */ 1617 uint32_t ochs; /* output channels */ 1618 uint32_t c; 1619 uint32_t chs; /* channels */ 1620 uint32_t i; 1621 uint32_t o; 1622 1623 DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n", 1624 d0->bUnitId, d0->bNrInPins); 1625 1626 /* compute the number of input channels */ 1627 |
1022 ichs = 0; | 1628 ichs = 0; |
1023 for (i = 0; i < d->bNrInPins; i++) 1024 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; | 1629 for (i = 0; i < d0->bNrInPins; i++) { 1630 ichs += (uaudio_mixer_get_cluster(d0->baSourceId[i], iot) 1631 .bNrChannels); 1632 } |
1025 | 1633 |
1634 d1 = (const void *)(d0->baSourceId + d0->bNrInPins); 1635 |
|
1026 /* and the number of output channels */ | 1636 /* and the number of output channels */ |
1027 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; | 1637 |
1028 ochs = d1->bNrChannels; | 1638 ochs = d1->bNrChannels; |
1029 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs)); | |
1030 | 1639 |
1031 bm = d1->bmControls; 1032 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1033 uaudio_determine_class(&iot[id], &mix); | 1640 DPRINTFN(3, "ichs=%d ochs=%d\n", ichs, ochs); 1641 1642 bzero(&mix, sizeof(mix)); 1643 1644 mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); 1645 uaudio_mixer_determine_class(&iot[id], &mix); |
1034 mix.type = MIX_SIGNED_16; | 1646 mix.type = MIX_SIGNED_16; |
1035#if !defined(__FreeBSD__) /* XXXXX */ 1036 mix.ctlunit = AudioNvolume; 1037#endif | |
1038 | 1647 |
1039#define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 1040 for (p = i = 0; i < d->bNrInPins; i++) { 1041 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; | 1648 if (uaudio_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL) { 1649 return; 1650 } 1651 for (p = i = 0; i < d0->bNrInPins; i++) { 1652 chs = uaudio_mixer_get_cluster(d0->baSourceId[i], iot).bNrChannels; |
1042 mc = 0; 1043 for (c = 0; c < chs; c++) { 1044 mo = 0; 1045 for (o = 0; o < ochs; o++) { | 1653 mc = 0; 1654 for (c = 0; c < chs; c++) { 1655 mo = 0; 1656 for (o = 0; o < ochs; o++) { |
1046 bno = (p + c) * ochs + o; 1047 if (BIT(bno)) | 1657 bno = ((p + c) * ochs) + o; 1658 if (BIT_TEST(d1->bmControls, bno)) { |
1048 mo++; | 1659 mo++; |
1660 } |
|
1049 } | 1661 } |
1050 if (mo == 1) | 1662 if (mo == 1) { |
1051 mc++; | 1663 mc++; |
1664 } |
|
1052 } | 1665 } |
1053 if (mc == chs && chs <= MIX_MAX_CHAN) { 1054 k = 0; 1055 for (c = 0; c < chs; c++) | 1666 if ((mc == chs) && (chs <= MIX_MAX_CHAN)) { 1667 1668 /* repeat bit-scan */ 1669 1670 mc = 0; 1671 for (c = 0; c < chs; c++) { |
1056 for (o = 0; o < ochs; o++) { | 1672 for (o = 0; o < ochs; o++) { |
1057 bno = (p + c) * ochs + o; 1058 if (BIT(bno)) 1059 mix.wValue[k++] = 1060 MAKE(p+c+1, o+1); | 1673 bno = ((p + c) * ochs) + o; 1674 if (BIT_TEST(d1->bmControls, bno)) { 1675 mix.wValue[mc++] = MAKE_WORD(p + c + 1, o + 1); 1676 } |
1061 } | 1677 } |
1062#if !defined(__FreeBSD__) 1063 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", 1064 d->bUnitId, uaudio_id_name(sc, iot, 1065 d->baSourceId[i])); 1066#endif | 1678 } |
1067 mix.nchan = chs; 1068 uaudio_mixer_add_ctl(sc, &mix); 1069 } else { 1070 /* XXX */ 1071 } | 1679 mix.nchan = chs; 1680 uaudio_mixer_add_ctl(sc, &mix); 1681 } else { 1682 /* XXX */ 1683 } |
1072#undef BIT | |
1073 p += chs; 1074 } | 1684 p += chs; 1685 } |
1075 | |
1076} 1077 1078static void | 1686} 1687 1688static void |
1079uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1689uaudio_mixer_add_selector(struct uaudio_softc *sc, 1690 const struct uaudio_terminal_node *iot, int id) |
1080{ | 1691{ |
1081 const struct usb_audio_selector_unit *d; 1082 struct mixerctl mix; 1083#if !defined(__FreeBSD__) 1084 int i, wp; 1085#else 1086 int i; 1087 struct mixerctl dummy; 1088#endif | 1692 const struct usb2_audio_selector_unit *d = iot[id].u.su; 1693 struct uaudio_mixer_node mix; 1694 uint16_t i; |
1089 | 1695 |
1090 d = iot[id].d.su; 1091 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n", 1092 d->bUnitId, d->bNrInPins)); 1093 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1094 mix.wValue[0] = MAKE(0, 0); 1095 uaudio_determine_class(&iot[id], &mix); | 1696 DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n", 1697 d->bUnitId, d->bNrInPins); 1698 1699 if (d->bNrInPins == 0) { 1700 return; 1701 } 1702 bzero(&mix, sizeof(mix)); 1703 1704 mix.wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); 1705 mix.wValue[0] = MAKE_WORD(0, 0); 1706 uaudio_mixer_determine_class(&iot[id], &mix); |
1096 mix.nchan = 1; 1097 mix.type = MIX_SELECTOR; | 1707 mix.nchan = 1; 1708 mix.type = MIX_SELECTOR; |
1098#if defined(__FreeBSD__) 1099 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ | 1709 1710 mix.ctl = SOUND_MIXER_NRDEVICES; |
1100 mix.minval = 1; 1101 mix.maxval = d->bNrInPins; | 1711 mix.minval = 1; 1712 mix.maxval = d->bNrInPins; |
1102 mix.mul = mix.maxval - mix.minval; | 1713 1714 if (mix.maxval > MAX_SELECTOR_INPUT_PIN) { 1715 mix.maxval = MAX_SELECTOR_INPUT_PIN; 1716 } 1717 mix.mul = (mix.maxval - mix.minval); |
1103 for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) { 1104 mix.slctrtype[i] = SOUND_MIXER_NRDEVICES; 1105 } | 1718 for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) { 1719 mix.slctrtype[i] = SOUND_MIXER_NRDEVICES; 1720 } |
1106 for (i = mix.minval; i <= mix.maxval; i++) { 1107 mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy); | 1721 1722 for (i = 0; i < mix.maxval; i++) { 1723 mix.slctrtype[i] = uaudio_mixer_feature_name 1724 (&iot[d->baSourceId[i]], &mix); |
1108 } | 1725 } |
1109#else 1110 mix.ctlunit = ""; 1111 mix.minval = 1; 1112 mix.maxval = d->bNrInPins; 1113 mix.mul = mix.maxval - mix.minval; 1114 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); 1115 for (i = 1; i <= d->bNrInPins; i++) { 1116 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, 1117 "i%d", d->baSourceId[i - 1]); 1118 if (wp > MAX_AUDIO_DEV_LEN - 1) 1119 break; 1120 } 1121#endif | 1726 1727 mix.class = 0; /* not used */ 1728 |
1122 uaudio_mixer_add_ctl(sc, &mix); 1123} 1124 | 1729 uaudio_mixer_add_ctl(sc, &mix); 1730} 1731 |
1125#ifdef USB_DEBUG 1126static const char * 1127uaudio_get_terminal_name(int terminal_type) | 1732static uint32_t 1733uaudio_mixer_feature_get_bmaControls(const struct usb2_audio_feature_unit *d, 1734 uint8_t index) |
1128{ | 1735{ |
1129 static char buf[100]; | 1736 uint32_t temp = 0; 1737 uint32_t offset = (index * d->bControlSize); |
1130 | 1738 |
1131 switch (terminal_type) { 1132 /* USB terminal types */ 1133 case UAT_UNDEFINED: return "UAT_UNDEFINED"; 1134 case UAT_STREAM: return "UAT_STREAM"; 1135 case UAT_VENDOR: return "UAT_VENDOR"; 1136 /* input terminal types */ 1137 case UATI_UNDEFINED: return "UATI_UNDEFINED"; 1138 case UATI_MICROPHONE: return "UATI_MICROPHONE"; 1139 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE"; 1140 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE"; 1141 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE"; 1142 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY"; 1143 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR"; 1144 /* output terminal types */ 1145 case UATO_UNDEFINED: return "UATO_UNDEFINED"; 1146 case UATO_SPEAKER: return "UATO_SPEAKER"; 1147 case UATO_HEADPHONES: return "UATO_HEADPHONES"; 1148 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO"; 1149 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER"; 1150 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER"; 1151 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER"; 1152 case UATO_SUBWOOFER: return "UATO_SUBWOOFER"; 1153 /* bidir terminal types */ 1154 case UATB_UNDEFINED: return "UATB_UNDEFINED"; 1155 case UATB_HANDSET: return "UATB_HANDSET"; 1156 case UATB_HEADSET: return "UATB_HEADSET"; 1157 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE"; 1158 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP"; 1159 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC"; 1160 /* telephony terminal types */ 1161 case UATT_UNDEFINED: return "UATT_UNDEFINED"; 1162 case UATT_PHONELINE: return "UATT_PHONELINE"; 1163 case UATT_TELEPHONE: return "UATT_TELEPHONE"; 1164 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE"; 1165 /* external terminal types */ 1166 case UATE_UNDEFINED: return "UATE_UNDEFINED"; 1167 case UATE_ANALOGCONN: return "UATE_ANALOGCONN"; 1168 case UATE_LINECONN: return "UATE_LINECONN"; 1169 case UATE_LEGACYCONN: return "UATE_LEGACYCONN"; 1170 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC"; 1171 case UATE_SPDIF: return "UATE_SPDIF"; 1172 case UATE_1394DA: return "UATE_1394DA"; 1173 case UATE_1394DV: return "UATE_1394DV"; 1174 /* embedded function terminal types */ 1175 case UATF_UNDEFINED: return "UATF_UNDEFINED"; 1176 case UATF_CALIBNOISE: return "UATF_CALIBNOISE"; 1177 case UATF_EQUNOISE: return "UATF_EQUNOISE"; 1178 case UATF_CDPLAYER: return "UATF_CDPLAYER"; 1179 case UATF_DAT: return "UATF_DAT"; 1180 case UATF_DCC: return "UATF_DCC"; 1181 case UATF_MINIDISK: return "UATF_MINIDISK"; 1182 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE"; 1183 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH"; 1184 case UATF_VCRAUDIO: return "UATF_VCRAUDIO"; 1185 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO"; 1186 case UATF_DVDAUDIO: return "UATF_DVDAUDIO"; 1187 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO"; 1188 case UATF_SATELLITE: return "UATF_SATELLITE"; 1189 case UATF_CABLETUNER: return "UATF_CABLETUNER"; 1190 case UATF_DSS: return "UATF_DSS"; 1191 case UATF_RADIORECV: return "UATF_RADIORECV"; 1192 case UATF_RADIOXMIT: return "UATF_RADIOXMIT"; 1193 case UATF_MULTITRACK: return "UATF_MULTITRACK"; 1194 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER"; 1195 default: 1196 snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type); 1197 return buf; | 1739 if (d->bControlSize > 0) { 1740 temp |= d->bmaControls[offset]; 1741 if (d->bControlSize > 1) { 1742 temp |= d->bmaControls[offset + 1] << 8; 1743 if (d->bControlSize > 2) { 1744 temp |= d->bmaControls[offset + 2] << 16; 1745 if (d->bControlSize > 3) { 1746 temp |= d->bmaControls[offset + 3] << 24; 1747 } 1748 } 1749 } |
1198 } | 1750 } |
1751 return (temp); |
|
1199} | 1752} |
1200#endif | |
1201 | 1753 |
1202static int 1203uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix) | 1754static void 1755uaudio_mixer_add_feature(struct uaudio_softc *sc, 1756 const struct uaudio_terminal_node *iot, int id) |
1204{ | 1757{ |
1205 int terminal_type; | 1758 const struct usb2_audio_feature_unit *d = iot[id].u.fu; 1759 struct uaudio_mixer_node mix; 1760 uint32_t fumask; 1761 uint32_t mmask; 1762 uint32_t cmask; 1763 uint16_t mixernumber; 1764 uint8_t nchan; 1765 uint8_t chan; 1766 uint8_t ctl; 1767 uint8_t i; |
1206 | 1768 |
1207 if (iot == NULL || iot->output == NULL) { 1208 mix->class = UAC_OUTPUT; 1209 return 0; | 1769 if (d->bControlSize == 0) { 1770 return; |
1210 } | 1771 } |
1211 terminal_type = 0; 1212 if (iot->output->size == 1) 1213 terminal_type = iot->output->terminals[0]; 1214 /* 1215 * If the only output terminal is USB, 1216 * the class is UAC_RECORD. 1217 */ 1218 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { 1219 mix->class = UAC_RECORD; 1220 if (iot->inputs_size == 1 1221 && iot->inputs[0] != NULL 1222 && iot->inputs[0]->size == 1) 1223 return iot->inputs[0]->terminals[0]; 1224 else 1225 return 0; 1226 } 1227 /* 1228 * If the ultimate destination of the unit is just one output 1229 * terminal and the unit is connected to the output terminal 1230 * directly, the class is UAC_OUTPUT. 1231 */ 1232 if (terminal_type != 0 && iot->direct) { 1233 mix->class = UAC_OUTPUT; 1234 return terminal_type; 1235 } 1236 /* 1237 * If the unit is connected to just one input terminal, 1238 * the class is UAC_INPUT. 1239 */ 1240 if (iot->inputs_size == 1 && iot->inputs[0] != NULL 1241 && iot->inputs[0]->size == 1) { 1242 mix->class = UAC_INPUT; 1243 return iot->inputs[0]->terminals[0]; 1244 } 1245 /* 1246 * Otherwise, the class is UAC_OUTPUT. 1247 */ 1248 mix->class = UAC_OUTPUT; 1249 return terminal_type; 1250} | 1772 bzero(&mix, sizeof(mix)); |
1251 | 1773 |
1252#if defined(__FreeBSD__) 1253static int 1254uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1255{ 1256 int terminal_type; | 1774 nchan = (d->bLength - 7) / d->bControlSize; 1775 mmask = uaudio_mixer_feature_get_bmaControls(d, 0); 1776 cmask = 0; |
1257 | 1777 |
1258 terminal_type = uaudio_determine_class(iot, mix); 1259 if (mix->class == UAC_RECORD && terminal_type == 0) 1260 return SOUND_MIXER_IMIX; 1261 DPRINTF(("%s: terminal_type=%s\n", __func__, 1262 uaudio_get_terminal_name(terminal_type))); 1263 switch (terminal_type) { 1264 case UAT_STREAM: 1265 return SOUND_MIXER_PCM; 1266 1267 case UATI_MICROPHONE: 1268 case UATI_DESKMICROPHONE: 1269 case UATI_PERSONALMICROPHONE: 1270 case UATI_OMNIMICROPHONE: 1271 case UATI_MICROPHONEARRAY: 1272 case UATI_PROCMICROPHONEARR: 1273 return SOUND_MIXER_MIC; 1274 1275 case UATO_SPEAKER: 1276 case UATO_DESKTOPSPEAKER: 1277 case UATO_ROOMSPEAKER: 1278 case UATO_COMMSPEAKER: 1279 return SOUND_MIXER_SPEAKER; 1280 1281 case UATE_ANALOGCONN: 1282 case UATE_LINECONN: 1283 case UATE_LEGACYCONN: 1284 return SOUND_MIXER_LINE; 1285 1286 case UATE_DIGITALAUIFC: 1287 case UATE_SPDIF: 1288 case UATE_1394DA: 1289 case UATE_1394DV: 1290 return SOUND_MIXER_ALTPCM; 1291 1292 case UATF_CDPLAYER: 1293 return SOUND_MIXER_CD; 1294 1295 case UATF_SYNTHESIZER: 1296 return SOUND_MIXER_SYNTH; 1297 1298 case UATF_VIDEODISCAUDIO: 1299 case UATF_DVDAUDIO: 1300 case UATF_TVTUNERAUDIO: 1301 return SOUND_MIXER_VIDEO; 1302 1303/* telephony terminal types */ 1304 case UATT_UNDEFINED: 1305 case UATT_PHONELINE: 1306 case UATT_TELEPHONE: 1307 case UATT_DOWNLINEPHONE: 1308 return SOUND_MIXER_PHONEIN; 1309/* return SOUND_MIXER_PHONEOUT;*/ 1310 1311 case UATF_RADIORECV: 1312 case UATF_RADIOXMIT: 1313 return SOUND_MIXER_RADIO; 1314 1315 case UAT_UNDEFINED: 1316 case UAT_VENDOR: 1317 case UATI_UNDEFINED: 1318/* output terminal types */ 1319 case UATO_UNDEFINED: 1320 case UATO_DISPLAYAUDIO: 1321 case UATO_SUBWOOFER: 1322 case UATO_HEADPHONES: 1323/* bidir terminal types */ 1324 case UATB_UNDEFINED: 1325 case UATB_HANDSET: 1326 case UATB_HEADSET: 1327 case UATB_SPEAKERPHONE: 1328 case UATB_SPEAKERPHONEESUP: 1329 case UATB_SPEAKERPHONEECANC: 1330/* external terminal types */ 1331 case UATE_UNDEFINED: 1332/* embedded function terminal types */ 1333 case UATF_UNDEFINED: 1334 case UATF_CALIBNOISE: 1335 case UATF_EQUNOISE: 1336 case UATF_DAT: 1337 case UATF_DCC: 1338 case UATF_MINIDISK: 1339 case UATF_ANALOGTAPE: 1340 case UATF_PHONOGRAPH: 1341 case UATF_VCRAUDIO: 1342 case UATF_SATELLITE: 1343 case UATF_CABLETUNER: 1344 case UATF_DSS: 1345 case UATF_MULTITRACK: 1346 case 0xffff: 1347 default: 1348 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type)); 1349 return SOUND_MIXER_VOLUME; | 1778 if (nchan == 0) { 1779 return; |
1350 } | 1780 } |
1351 return SOUND_MIXER_VOLUME; 1352} 1353#else 1354static const char * 1355uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1356{ 1357 int terminal_type; | 1781 /* figure out what we can control */ |
1358 | 1782 |
1359 terminal_type = uaudio_determine_class(iot, mix); 1360 if (mix->class == UAC_RECORD && terminal_type == 0) 1361 return AudioNmixerout; 1362 DPRINTF(("%s: terminal_type=%s\n", __func__, 1363 uaudio_get_terminal_name(terminal_type))); 1364 switch (terminal_type) { 1365 case UAT_STREAM: 1366 return AudioNdac; | 1783 for (chan = 1; chan < nchan; chan++) { 1784 DPRINTFN(10, "chan=%d mask=%x\n", 1785 chan, uaudio_mixer_feature_get_bmaControls(d, chan)); |
1367 | 1786 |
1368 case UATI_MICROPHONE: 1369 case UATI_DESKMICROPHONE: 1370 case UATI_PERSONALMICROPHONE: 1371 case UATI_OMNIMICROPHONE: 1372 case UATI_MICROPHONEARRAY: 1373 case UATI_PROCMICROPHONEARR: 1374 return AudioNmicrophone; 1375 1376 case UATO_SPEAKER: 1377 case UATO_DESKTOPSPEAKER: 1378 case UATO_ROOMSPEAKER: 1379 case UATO_COMMSPEAKER: 1380 return AudioNspeaker; 1381 1382 case UATO_HEADPHONES: 1383 return AudioNheadphone; 1384 1385 case UATO_SUBWOOFER: 1386 return AudioNlfe; 1387 1388 /* telephony terminal types */ 1389 case UATT_UNDEFINED: 1390 case UATT_PHONELINE: 1391 case UATT_TELEPHONE: 1392 case UATT_DOWNLINEPHONE: 1393 return "phone"; 1394 1395 case UATE_ANALOGCONN: 1396 case UATE_LINECONN: 1397 case UATE_LEGACYCONN: 1398 return AudioNline; 1399 1400 case UATE_DIGITALAUIFC: 1401 case UATE_SPDIF: 1402 case UATE_1394DA: 1403 case UATE_1394DV: 1404 return AudioNaux; 1405 1406 case UATF_CDPLAYER: 1407 return AudioNcd; 1408 1409 case UATF_SYNTHESIZER: 1410 return AudioNfmsynth; 1411 1412 case UATF_VIDEODISCAUDIO: 1413 case UATF_DVDAUDIO: 1414 case UATF_TVTUNERAUDIO: 1415 return AudioNvideo; 1416 1417 case UAT_UNDEFINED: 1418 case UAT_VENDOR: 1419 case UATI_UNDEFINED: 1420/* output terminal types */ 1421 case UATO_UNDEFINED: 1422 case UATO_DISPLAYAUDIO: 1423/* bidir terminal types */ 1424 case UATB_UNDEFINED: 1425 case UATB_HANDSET: 1426 case UATB_HEADSET: 1427 case UATB_SPEAKERPHONE: 1428 case UATB_SPEAKERPHONEESUP: 1429 case UATB_SPEAKERPHONEECANC: 1430/* external terminal types */ 1431 case UATE_UNDEFINED: 1432/* embedded function terminal types */ 1433 case UATF_UNDEFINED: 1434 case UATF_CALIBNOISE: 1435 case UATF_EQUNOISE: 1436 case UATF_DAT: 1437 case UATF_DCC: 1438 case UATF_MINIDISK: 1439 case UATF_ANALOGTAPE: 1440 case UATF_PHONOGRAPH: 1441 case UATF_VCRAUDIO: 1442 case UATF_SATELLITE: 1443 case UATF_CABLETUNER: 1444 case UATF_DSS: 1445 case UATF_RADIORECV: 1446 case UATF_RADIOXMIT: 1447 case UATF_MULTITRACK: 1448 case 0xffff: 1449 default: 1450 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type)); 1451 return AudioNmaster; | 1787 cmask |= uaudio_mixer_feature_get_bmaControls(d, chan); |
1452 } | 1788 } |
1453 return AudioNmaster; 1454} 1455#endif | |
1456 | 1789 |
1457static void 1458uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1459{ 1460 const struct usb_audio_feature_unit *d; 1461 const uByte *ctls; 1462 int ctlsize; 1463 int nchan; 1464 u_int fumask, mmask, cmask; 1465 struct mixerctl mix; 1466 int chan, ctl, i, unit; 1467#if defined(__FreeBSD__) 1468 int mixernumber; 1469#else 1470 const char *mixername; 1471#endif 1472 1473#define GET(i) (ctls[(i)*ctlsize] | \ 1474 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0)) 1475 d = iot[id].d.fu; 1476 ctls = d->bmaControls; 1477 ctlsize = d->bControlSize; 1478 nchan = (d->bLength - 7) / ctlsize; 1479 mmask = GET(0); 1480 /* Figure out what we can control */ 1481 for (cmask = 0, chan = 1; chan < nchan; chan++) { 1482 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n", 1483 chan, GET(chan))); 1484 cmask |= GET(chan); | 1790 if (nchan > MIX_MAX_CHAN) { 1791 nchan = MIX_MAX_CHAN; |
1485 } | 1792 } |
1793 mix.wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); |
|
1486 | 1794 |
1487#if !defined(__FreeBSD__) 1488 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, " 1489 "%d channels, mmask=0x%04x, cmask=0x%04x\n", 1490 d->bUnitId, nchan, mmask, cmask)); 1491#endif | 1795 for (ctl = 1; ctl <= LOUDNESS_CONTROL; ctl++) { |
1492 | 1796 |
1493 if (nchan > MIX_MAX_CHAN) 1494 nchan = MIX_MAX_CHAN; 1495 unit = d->bUnitId; 1496 mix.wIndex = MAKE(unit, sc->sc_ac_iface); 1497 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) { | |
1498 fumask = FU_MASK(ctl); | 1797 fumask = FU_MASK(ctl); |
1499 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n", 1500 ctl, fumask)); | 1798 1799 DPRINTFN(5, "ctl=%d fumask=0x%04x\n", 1800 ctl, fumask); 1801 |
1501 if (mmask & fumask) { 1502 mix.nchan = 1; | 1802 if (mmask & fumask) { 1803 mix.nchan = 1; |
1503 mix.wValue[0] = MAKE(ctl, 0); | 1804 mix.wValue[0] = MAKE_WORD(ctl, 0); |
1504 } else if (cmask & fumask) { 1505 mix.nchan = nchan - 1; 1506 for (i = 1; i < nchan; i++) { | 1805 } else if (cmask & fumask) { 1806 mix.nchan = nchan - 1; 1807 for (i = 1; i < nchan; i++) { |
1507 if (GET(i) & fumask) 1508 mix.wValue[i-1] = MAKE(ctl, i); | 1808 if (uaudio_mixer_feature_get_bmaControls(d, i) & fumask) 1809 mix.wValue[i - 1] = MAKE_WORD(ctl, i); |
1509 else | 1810 else |
1510 mix.wValue[i-1] = -1; | 1811 mix.wValue[i - 1] = -1; |
1511 } 1512 } else { 1513 continue; 1514 } | 1812 } 1813 } else { 1814 continue; 1815 } |
1515#undef GET | |
1516 | 1816 |
1517#if defined(__FreeBSD__) 1518 mixernumber = uaudio_feature_name(&iot[id], &mix); 1519#else 1520 mixername = uaudio_feature_name(&iot[id], &mix); 1521#endif | 1817 mixernumber = uaudio_mixer_feature_name(&iot[id], &mix); 1818 |
1522 switch (ctl) { 1523 case MUTE_CONTROL: 1524 mix.type = MIX_ON_OFF; | 1819 switch (ctl) { 1820 case MUTE_CONTROL: 1821 mix.type = MIX_ON_OFF; |
1525#if defined(__FreeBSD__) | |
1526 mix.ctl = SOUND_MIXER_NRDEVICES; | 1822 mix.ctl = SOUND_MIXER_NRDEVICES; |
1527#else 1528 mix.ctlunit = ""; 1529 snprintf(mix.ctlname, sizeof(mix.ctlname), 1530 "%s.%s", mixername, AudioNmute); 1531#endif | |
1532 break; | 1823 break; |
1824 |
|
1533 case VOLUME_CONTROL: 1534 mix.type = MIX_SIGNED_16; | 1825 case VOLUME_CONTROL: 1826 mix.type = MIX_SIGNED_16; |
1535#if defined(__FreeBSD__) | |
1536 mix.ctl = mixernumber; | 1827 mix.ctl = mixernumber; |
1537#else 1538 mix.ctlunit = AudioNvolume; 1539 strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname)); 1540#endif | |
1541 break; | 1828 break; |
1829 |
|
1542 case BASS_CONTROL: 1543 mix.type = MIX_SIGNED_8; | 1830 case BASS_CONTROL: 1831 mix.type = MIX_SIGNED_8; |
1544#if defined(__FreeBSD__) | |
1545 mix.ctl = SOUND_MIXER_BASS; | 1832 mix.ctl = SOUND_MIXER_BASS; |
1546#else 1547 mix.ctlunit = AudioNbass; 1548 snprintf(mix.ctlname, sizeof(mix.ctlname), 1549 "%s.%s", mixername, AudioNbass); 1550#endif | |
1551 break; | 1833 break; |
1834 |
|
1552 case MID_CONTROL: 1553 mix.type = MIX_SIGNED_8; | 1835 case MID_CONTROL: 1836 mix.type = MIX_SIGNED_8; |
1554#if defined(__FreeBSD__) | |
1555 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ | 1837 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ |
1556#else 1557 mix.ctlunit = AudioNmid; 1558 snprintf(mix.ctlname, sizeof(mix.ctlname), 1559 "%s.%s", mixername, AudioNmid); 1560#endif | |
1561 break; | 1838 break; |
1839 |
|
1562 case TREBLE_CONTROL: 1563 mix.type = MIX_SIGNED_8; | 1840 case TREBLE_CONTROL: 1841 mix.type = MIX_SIGNED_8; |
1564#if defined(__FreeBSD__) | |
1565 mix.ctl = SOUND_MIXER_TREBLE; | 1842 mix.ctl = SOUND_MIXER_TREBLE; |
1566#else 1567 mix.ctlunit = AudioNtreble; 1568 snprintf(mix.ctlname, sizeof(mix.ctlname), 1569 "%s.%s", mixername, AudioNtreble); 1570#endif | |
1571 break; | 1843 break; |
1844 |
|
1572 case GRAPHIC_EQUALIZER_CONTROL: | 1845 case GRAPHIC_EQUALIZER_CONTROL: |
1573 continue; /* XXX don't add anything */ | 1846 continue; /* XXX don't add anything */ |
1574 break; | 1847 break; |
1848 |
|
1575 case AGC_CONTROL: 1576 mix.type = MIX_ON_OFF; | 1849 case AGC_CONTROL: 1850 mix.type = MIX_ON_OFF; |
1577#if defined(__FreeBSD__) | |
1578 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ | 1851 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ |
1579#else 1580 mix.ctlunit = ""; 1581 snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s", 1582 mixername, AudioNagc); 1583#endif | |
1584 break; | 1852 break; |
1853 |
|
1585 case DELAY_CONTROL: 1586 mix.type = MIX_UNSIGNED_16; | 1854 case DELAY_CONTROL: 1855 mix.type = MIX_UNSIGNED_16; |
1587#if defined(__FreeBSD__) | |
1588 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ | 1856 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ |
1589#else 1590 mix.ctlunit = "4 ms"; 1591 snprintf(mix.ctlname, sizeof(mix.ctlname), 1592 "%s.%s", mixername, AudioNdelay); 1593#endif | |
1594 break; | 1857 break; |
1858 |
|
1595 case BASS_BOOST_CONTROL: 1596 mix.type = MIX_ON_OFF; | 1859 case BASS_BOOST_CONTROL: 1860 mix.type = MIX_ON_OFF; |
1597#if defined(__FreeBSD__) | |
1598 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ | 1861 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ |
1599#else 1600 mix.ctlunit = ""; 1601 snprintf(mix.ctlname, sizeof(mix.ctlname), 1602 "%s.%s", mixername, AudioNbassboost); 1603#endif | |
1604 break; | 1862 break; |
1863 |
|
1605 case LOUDNESS_CONTROL: 1606 mix.type = MIX_ON_OFF; | 1864 case LOUDNESS_CONTROL: 1865 mix.type = MIX_ON_OFF; |
1607#if defined(__FreeBSD__) | |
1608 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */ | 1866 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */ |
1609#else 1610 mix.ctlunit = ""; 1611 snprintf(mix.ctlname, sizeof(mix.ctlname), 1612 "%s.%s", mixername, AudioNloudness); 1613#endif | |
1614 break; | 1867 break; |
1868 1869 default: 1870 mix.type = MIX_UNKNOWN; 1871 break; |
|
1615 } | 1872 } |
1616 uaudio_mixer_add_ctl(sc, &mix); | 1873 1874 if (mix.type != MIX_UNKNOWN) { 1875 uaudio_mixer_add_ctl(sc, &mix); 1876 } |
1617 } 1618} 1619 1620static void | 1877 } 1878} 1879 1880static void |
1621uaudio_add_processing_updown(struct uaudio_softc *sc, 1622 const struct io_terminal *iot, int id) | 1881uaudio_mixer_add_processing_updown(struct uaudio_softc *sc, 1882 const struct uaudio_terminal_node *iot, int id) |
1623{ | 1883{ |
1624 const struct usb_audio_processing_unit *d; 1625 const struct usb_audio_processing_unit_1 *d1; 1626 const struct usb_audio_processing_unit_updown *ud; 1627 struct mixerctl mix; 1628 int i; | 1884 const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu; 1885 const struct usb2_audio_processing_unit_1 *d1 = 1886 (const void *)(d0->baSourceId + d0->bNrInPins); 1887 const struct usb2_audio_processing_unit_updown *ud = 1888 (const void *)(d1->bmControls + d1->bControlSize); 1889 struct uaudio_mixer_node mix; 1890 uint8_t i; |
1629 | 1891 |
1630 d = iot[id].d.pu; 1631 d1 = (const struct usb_audio_processing_unit_1 *) 1632 &d->baSourceId[d->bNrInPins]; 1633 ud = (const struct usb_audio_processing_unit_updown *) 1634 &d1->bmControls[d1->bControlSize]; 1635 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n", 1636 d->bUnitId, ud->bNrModes)); | 1892 if (uaudio_mixer_verify_desc(d0, sizeof(*ud)) == NULL) { 1893 return; 1894 } 1895 if (uaudio_mixer_verify_desc(d0, sizeof(*ud) + (2 * ud->bNrModes)) 1896 == NULL) { 1897 return; 1898 } 1899 DPRINTFN(3, "bUnitId=%d bNrModes=%d\n", 1900 d0->bUnitId, ud->bNrModes); |
1637 1638 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { | 1901 1902 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { |
1639 DPRINTF(("uaudio_add_processing_updown: no mode select\n")); | 1903 DPRINTF("no mode select\n"); |
1640 return; 1641 } | 1904 return; 1905 } |
1906 bzero(&mix, sizeof(mix)); |
|
1642 | 1907 |
1643 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); | 1908 mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); |
1644 mix.nchan = 1; | 1909 mix.nchan = 1; |
1645 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); 1646 uaudio_determine_class(&iot[id], &mix); 1647 mix.type = MIX_ON_OFF; /* XXX */ 1648#if !defined(__FreeBSD__) 1649 mix.ctlunit = ""; 1650 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId); 1651#endif | 1910 mix.wValue[0] = MAKE_WORD(UD_MODE_SELECT_CONTROL, 0); 1911 uaudio_mixer_determine_class(&iot[id], &mix); 1912 mix.type = MIX_ON_OFF; /* XXX */ |
1652 1653 for (i = 0; i < ud->bNrModes; i++) { | 1913 1914 for (i = 0; i < ud->bNrModes; i++) { |
1654 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n", 1655 i, UGETW(ud->waModes[i]))); | 1915 DPRINTFN(3, "i=%d bm=0x%x\n", i, UGETW(ud->waModes[i])); |
1656 /* XXX */ 1657 } | 1916 /* XXX */ 1917 } |
1918 |
|
1658 uaudio_mixer_add_ctl(sc, &mix); 1659} 1660 1661static void | 1919 uaudio_mixer_add_ctl(sc, &mix); 1920} 1921 1922static void |
1662uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1923uaudio_mixer_add_processing(struct uaudio_softc *sc, 1924 const struct uaudio_terminal_node *iot, int id) |
1663{ | 1925{ |
1664 const struct usb_audio_processing_unit *d; 1665 const struct usb_audio_processing_unit_1 *d1; 1666 int ptype; 1667 struct mixerctl mix; | 1926 const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu; 1927 const struct usb2_audio_processing_unit_1 *d1 = 1928 (const void *)(d0->baSourceId + d0->bNrInPins); 1929 struct uaudio_mixer_node mix; 1930 uint16_t ptype; |
1668 | 1931 |
1669 d = iot[id].d.pu; 1670 d1 = (const struct usb_audio_processing_unit_1 *) 1671 &d->baSourceId[d->bNrInPins]; 1672 ptype = UGETW(d->wProcessType); 1673 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d " 1674 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins)); | 1932 bzero(&mix, sizeof(mix)); |
1675 | 1933 |
1934 ptype = UGETW(d0->wProcessType); 1935 1936 DPRINTFN(3, "wProcessType=%d bUnitId=%d " 1937 "bNrInPins=%d\n", ptype, d0->bUnitId, d0->bNrInPins); 1938 1939 if (d1->bControlSize == 0) { 1940 return; 1941 } |
|
1676 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { | 1942 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { |
1677 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); | 1943 mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); |
1678 mix.nchan = 1; | 1944 mix.nchan = 1; |
1679 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0); 1680 uaudio_determine_class(&iot[id], &mix); | 1945 mix.wValue[0] = MAKE_WORD(XX_ENABLE_CONTROL, 0); 1946 uaudio_mixer_determine_class(&iot[id], &mix); |
1681 mix.type = MIX_ON_OFF; | 1947 mix.type = MIX_ON_OFF; |
1682#if !defined(__FreeBSD__) 1683 mix.ctlunit = ""; 1684 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable", 1685 d->bUnitId, ptype); 1686#endif | |
1687 uaudio_mixer_add_ctl(sc, &mix); 1688 } | 1948 uaudio_mixer_add_ctl(sc, &mix); 1949 } |
1689 1690 switch(ptype) { | 1950 switch (ptype) { |
1691 case UPDOWNMIX_PROCESS: | 1951 case UPDOWNMIX_PROCESS: |
1692 uaudio_add_processing_updown(sc, iot, id); | 1952 uaudio_mixer_add_processing_updown(sc, iot, id); |
1693 break; | 1953 break; |
1954 |
|
1694 case DOLBY_PROLOGIC_PROCESS: 1695 case P3D_STEREO_EXTENDER_PROCESS: 1696 case REVERBATION_PROCESS: 1697 case CHORUS_PROCESS: 1698 case DYN_RANGE_COMP_PROCESS: 1699 default: | 1955 case DOLBY_PROLOGIC_PROCESS: 1956 case P3D_STEREO_EXTENDER_PROCESS: 1957 case REVERBATION_PROCESS: 1958 case CHORUS_PROCESS: 1959 case DYN_RANGE_COMP_PROCESS: 1960 default: |
1700#ifdef USB_DEBUG 1701 printf("uaudio_add_processing: unit %d, type=%d not impl.\n", 1702 d->bUnitId, ptype); 1703#endif | 1961 DPRINTF("unit %d, type=%d is not implemented\n", 1962 d0->bUnitId, ptype); |
1704 break; 1705 } 1706} 1707 1708static void | 1963 break; 1964 } 1965} 1966 1967static void |
1709uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id) | 1968uaudio_mixer_add_extension(struct uaudio_softc *sc, 1969 const struct uaudio_terminal_node *iot, int id) |
1710{ | 1970{ |
1711 const struct usb_audio_extension_unit *d; 1712 const struct usb_audio_extension_unit_1 *d1; 1713 struct mixerctl mix; | 1971 const struct usb2_audio_extension_unit_0 *d0 = iot[id].u.eu; 1972 const struct usb2_audio_extension_unit_1 *d1 = 1973 (const void *)(d0->baSourceId + d0->bNrInPins); 1974 struct uaudio_mixer_node mix; |
1714 | 1975 |
1715 d = iot[id].d.eu; 1716 d1 = (const struct usb_audio_extension_unit_1 *) 1717 &d->baSourceId[d->bNrInPins]; 1718 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n", 1719 d->bUnitId, d->bNrInPins)); | 1976 DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n", 1977 d0->bUnitId, d0->bNrInPins); |
1720 | 1978 |
1721 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU) | 1979 if (sc->sc_uq_au_no_xu) { |
1722 return; | 1980 return; |
1723 | 1981 } 1982 if (d1->bControlSize == 0) { 1983 return; 1984 } |
1724 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { | 1985 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { |
1725 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); | 1986 1987 bzero(&mix, sizeof(mix)); 1988 1989 mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); |
1726 mix.nchan = 1; | 1990 mix.nchan = 1; |
1727 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0); 1728 uaudio_determine_class(&iot[id], &mix); | 1991 mix.wValue[0] = MAKE_WORD(UA_EXT_ENABLE, 0); 1992 uaudio_mixer_determine_class(&iot[id], &mix); |
1729 mix.type = MIX_ON_OFF; | 1993 mix.type = MIX_ON_OFF; |
1730#if !defined(__FreeBSD__) 1731 mix.ctlunit = ""; 1732 snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable", 1733 d->bUnitId); 1734#endif | 1994 |
1735 uaudio_mixer_add_ctl(sc, &mix); 1736 } 1737} 1738 | 1995 uaudio_mixer_add_ctl(sc, &mix); 1996 } 1997} 1998 |
1739static struct terminal_list* 1740uaudio_merge_terminal_list(const struct io_terminal *iot) | 1999static const void * 2000uaudio_mixer_verify_desc(const void *arg, uint32_t len) |
1741{ | 2001{ |
1742 struct terminal_list *tml; 1743 uint16_t *ptm; 1744 int i, len; | 2002 const struct usb2_audio_mixer_unit_1 *d1; 2003 const struct usb2_audio_extension_unit_1 *e1; 2004 const struct usb2_audio_processing_unit_1 *u1; |
1745 | 2005 |
1746 len = 0; 1747 if (iot->inputs == NULL) 1748 return NULL; 1749 for (i = 0; i < iot->inputs_size; i++) { 1750 if (iot->inputs[i] != NULL) 1751 len += iot->inputs[i]->size; 1752 } 1753 tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT); 1754 if (tml == NULL) { 1755 printf("uaudio_merge_terminal_list: no memory\n"); 1756 return NULL; 1757 } 1758 tml->size = 0; 1759 ptm = tml->terminals; 1760 for (i = 0; i < iot->inputs_size; i++) { 1761 if (iot->inputs[i] == NULL) 1762 continue; 1763 if (iot->inputs[i]->size > len) 1764 break; 1765 memcpy(ptm, iot->inputs[i]->terminals, 1766 iot->inputs[i]->size * sizeof(uint16_t)); 1767 tml->size += iot->inputs[i]->size; 1768 ptm += iot->inputs[i]->size; 1769 len -= iot->inputs[i]->size; 1770 } 1771 return tml; 1772} | 2006 union { 2007 const struct usb2_descriptor *desc; 2008 const struct usb2_audio_input_terminal *it; 2009 const struct usb2_audio_output_terminal *ot; 2010 const struct usb2_audio_mixer_unit_0 *mu; 2011 const struct usb2_audio_selector_unit *su; 2012 const struct usb2_audio_feature_unit *fu; 2013 const struct usb2_audio_processing_unit_0 *pu; 2014 const struct usb2_audio_extension_unit_0 *eu; 2015 } u; |
1773 | 2016 |
1774static struct terminal_list * 1775uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) 1776{ 1777 struct terminal_list *tml; 1778 struct io_terminal *it; 1779 int src_id, i; | 2017 u.desc = arg; |
1780 | 2018 |
1781 it = &iot[id]; 1782 if (it->output != NULL) { 1783 /* already has outtype? */ 1784 for (i = 0; i < it->output->size; i++) 1785 if (it->output->terminals[i] == outtype) 1786 return uaudio_merge_terminal_list(it); 1787 tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1), 1788 M_TEMP, M_NOWAIT); 1789 if (tml == NULL) { 1790 printf("uaudio_io_terminaltype: no memory\n"); 1791 return uaudio_merge_terminal_list(it); 1792 } 1793 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size)); 1794 tml->terminals[it->output->size] = outtype; 1795 tml->size++; 1796 free(it->output, M_TEMP); 1797 it->output = tml; 1798 if (it->inputs != NULL) { 1799 for (i = 0; i < it->inputs_size; i++) 1800 if (it->inputs[i] != NULL) 1801 free(it->inputs[i], M_TEMP); 1802 free(it->inputs, M_TEMP); 1803 } 1804 it->inputs_size = 0; 1805 it->inputs = NULL; 1806 } else { /* end `iot[id] != NULL' */ 1807 it->inputs_size = 0; 1808 it->inputs = NULL; 1809 it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1810 if (it->output == NULL) { 1811 printf("uaudio_io_terminaltype: no memory\n"); 1812 return NULL; 1813 } 1814 it->output->terminals[0] = outtype; 1815 it->output->size = 1; 1816 it->direct = FALSE; | 2019 if (u.desc == NULL) { 2020 goto error; |
1817 } | 2021 } |
1818 1819 switch (it->d.desc->bDescriptorSubtype) { | 2022 if (u.desc->bDescriptorType != UDESC_CS_INTERFACE) { 2023 goto error; 2024 } 2025 switch (u.desc->bDescriptorSubtype) { |
1820 case UDESCSUB_AC_INPUT: | 2026 case UDESCSUB_AC_INPUT: |
1821 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1822 if (it->inputs == NULL) { 1823 printf("uaudio_io_terminaltype: no memory\n"); 1824 return NULL; 1825 } 1826 tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1827 if (tml == NULL) { 1828 printf("uaudio_io_terminaltype: no memory\n"); 1829 free(it->inputs, M_TEMP); 1830 it->inputs = NULL; 1831 return NULL; 1832 } 1833 it->inputs[0] = tml; 1834 tml->terminals[0] = UGETW(it->d.it->wTerminalType); 1835 tml->size = 1; 1836 it->inputs_size = 1; 1837 return uaudio_merge_terminal_list(it); 1838 case UDESCSUB_AC_FEATURE: 1839 src_id = it->d.fu->bSourceId; 1840 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1841 if (it->inputs == NULL) { 1842 printf("uaudio_io_terminaltype: no memory\n"); 1843 return uaudio_io_terminaltype(outtype, iot, src_id); 1844 } 1845 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1846 it->inputs_size = 1; 1847 return uaudio_merge_terminal_list(it); | 2027 len += sizeof(*u.it); 2028 break; 2029 |
1848 case UDESCSUB_AC_OUTPUT: | 2030 case UDESCSUB_AC_OUTPUT: |
1849 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1850 if (it->inputs == NULL) { 1851 printf("uaudio_io_terminaltype: no memory\n"); 1852 return NULL; 1853 } 1854 src_id = it->d.ot->bSourceId; 1855 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1856 it->inputs_size = 1; 1857 iot[src_id].direct = TRUE; 1858 return NULL; | 2031 len += sizeof(*u.ot); 2032 break; 2033 |
1859 case UDESCSUB_AC_MIXER: | 2034 case UDESCSUB_AC_MIXER: |
1860 it->inputs_size = 0; 1861 it->inputs = malloc(sizeof(struct terminal_list *) 1862 * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT); 1863 if (it->inputs == NULL) { 1864 printf("uaudio_io_terminaltype: no memory\n"); 1865 return NULL; | 2035 len += sizeof(*u.mu); 2036 2037 if (u.desc->bLength < len) { 2038 goto error; |
1866 } | 2039 } |
1867 for (i = 0; i < it->d.mu->bNrInPins; i++) { 1868 src_id = it->d.mu->baSourceId[i]; 1869 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1870 src_id); 1871 it->inputs_size++; | 2040 len += u.mu->bNrInPins; 2041 2042 if (u.desc->bLength < len) { 2043 goto error; |
1872 } | 2044 } |
1873 return uaudio_merge_terminal_list(it); 1874 case UDESCSUB_AC_SELECTOR: 1875 it->inputs_size = 0; 1876 it->inputs = malloc(sizeof(struct terminal_list *) 1877 * it->d.su->bNrInPins, M_TEMP, M_NOWAIT); 1878 if (it->inputs == NULL) { 1879 printf("uaudio_io_terminaltype: no memory\n"); 1880 return NULL; 1881 } 1882 for (i = 0; i < it->d.su->bNrInPins; i++) { 1883 src_id = it->d.su->baSourceId[i]; 1884 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1885 src_id); 1886 it->inputs_size++; 1887 } 1888 return uaudio_merge_terminal_list(it); 1889 case UDESCSUB_AC_PROCESSING: 1890 it->inputs_size = 0; 1891 it->inputs = malloc(sizeof(struct terminal_list *) 1892 * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT); 1893 if (it->inputs == NULL) { 1894 printf("uaudio_io_terminaltype: no memory\n"); 1895 return NULL; 1896 } 1897 for (i = 0; i < it->d.pu->bNrInPins; i++) { 1898 src_id = it->d.pu->baSourceId[i]; 1899 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1900 src_id); 1901 it->inputs_size++; 1902 } 1903 return uaudio_merge_terminal_list(it); 1904 case UDESCSUB_AC_EXTENSION: 1905 it->inputs_size = 0; 1906 it->inputs = malloc(sizeof(struct terminal_list *) 1907 * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT); 1908 if (it->inputs == NULL) { 1909 printf("uaudio_io_terminaltype: no memory\n"); 1910 return NULL; 1911 } 1912 for (i = 0; i < it->d.eu->bNrInPins; i++) { 1913 src_id = it->d.eu->baSourceId[i]; 1914 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1915 src_id); 1916 it->inputs_size++; 1917 } 1918 return uaudio_merge_terminal_list(it); 1919 case UDESCSUB_AC_HEADER: 1920 default: 1921 return NULL; 1922 } 1923} | 2045 d1 = (const void *)(u.mu->baSourceId + u.mu->bNrInPins); |
1924 | 2046 |
1925static usbd_status 1926uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 1927{ 1928 usbd_status err; | 2047 len += sizeof(*d1); 2048 break; |
1929 | 2049 |
1930 err = uaudio_identify_ac(sc, cdesc); 1931 if (err) 1932 return err; 1933 return uaudio_identify_as(sc, cdesc); 1934} | 2050 case UDESCSUB_AC_SELECTOR: 2051 len += sizeof(*u.su); |
1935 | 2052 |
1936static void 1937uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai) 1938{ 1939 size_t len; 1940 struct as_info *nai; | 2053 if (u.desc->bLength < len) { 2054 goto error; 2055 } 2056 len += u.su->bNrInPins; 2057 break; |
1941 | 2058 |
1942 len = sizeof(*ai) * (sc->sc_nalts + 1); 1943 nai = malloc(len, M_USBDEV, M_NOWAIT); 1944 if (nai == NULL) { 1945 printf("uaudio_add_alt: no memory\n"); 1946 return; 1947 } 1948 /* Copy old data, if there was any */ 1949 if (sc->sc_nalts != 0) { 1950 memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts)); 1951 free(sc->sc_alts, M_USBDEV); 1952 } 1953 sc->sc_alts = nai; 1954 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n", 1955 ai->alt, ai->encoding)); 1956 sc->sc_alts[sc->sc_nalts++] = *ai; 1957} | 2059 case UDESCSUB_AC_FEATURE: 2060 len += (sizeof(*u.fu) + 1); 2061 break; |
1958 | 2062 |
1959static usbd_status 1960uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp, 1961 int size, const usb_interface_descriptor_t *id) 1962#define offs (*offsp) 1963{ 1964 const struct usb_audio_streaming_interface_descriptor *asid; 1965 const struct usb_audio_streaming_type1_descriptor *asf1d; 1966 const usb_endpoint_descriptor_audio_t *ed; 1967 const usb_endpoint_descriptor_audio_t *epdesc1; 1968 const struct usb_audio_streaming_endpoint_descriptor *sed; 1969 int format, chan, prec, enc; 1970 int dir, type, sync; 1971 struct as_info ai; 1972 const char *format_str; | 2063 case UDESCSUB_AC_PROCESSING: 2064 len += sizeof(*u.pu); |
1973 | 2065 |
1974 asid = (const void *)(buf + offs); | 2066 if (u.desc->bLength < len) { 2067 goto error; 2068 } 2069 len += u.pu->bNrInPins; |
1975 | 2070 |
1976 if (asid->bDescriptorType != UDESC_CS_INTERFACE || 1977 asid->bDescriptorSubtype != AS_GENERAL) 1978 return USBD_INVAL; 1979 DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n", 1980 asid->bTerminalLink, UGETW(asid->wFormatTag))); 1981 offs += asid->bLength; 1982 if (offs > size) 1983 return USBD_INVAL; | 2071 if (u.desc->bLength < len) { 2072 goto error; 2073 } 2074 u1 = (const void *)(u.pu->baSourceId + u.pu->bNrInPins); |
1984 | 2075 |
1985 asf1d = (const void *)(buf + offs); 1986 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE || 1987 asf1d->bDescriptorSubtype != FORMAT_TYPE) 1988 return USBD_INVAL; 1989 offs += asf1d->bLength; 1990 if (offs > size) 1991 return USBD_INVAL; | 2076 len += sizeof(*u1); |
1992 | 2077 |
1993 if (asf1d->bFormatType != FORMAT_TYPE_I) { 1994 printf("%s: ignored setting with type %d format\n", 1995 device_get_nameunit(sc->sc_dev), UGETW(asid->wFormatTag)); 1996 return USBD_NORMAL_COMPLETION; 1997 } | 2078 if (u.desc->bLength < len) { 2079 goto error; 2080 } 2081 len += u1->bControlSize; |
1998 | 2082 |
1999 ed = (const void *)(buf + offs); 2000 if (ed->bDescriptorType != UDESC_ENDPOINT) 2001 return USBD_INVAL; 2002 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d " 2003 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d " 2004 "bInterval=%d bRefresh=%d bSynchAddress=%d\n", 2005 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress, 2006 ed->bmAttributes, UGETW(ed->wMaxPacketSize), 2007 ed->bInterval, ed->bRefresh, ed->bSynchAddress)); 2008 offs += ed->bLength; 2009 if (offs > size) 2010 return USBD_INVAL; 2011 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) 2012 return USBD_INVAL; | 2083 break; |
2013 | 2084 |
2014 dir = UE_GET_DIR(ed->bEndpointAddress); 2015 type = UE_GET_ISO_TYPE(ed->bmAttributes); 2016 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) && 2017 dir == UE_DIR_IN && type == UE_ISO_ADAPT) 2018 type = UE_ISO_ASYNC; | 2085 case UDESCSUB_AC_EXTENSION: 2086 len += sizeof(*u.eu); |
2019 | 2087 |
2020 /* We can't handle endpoints that need a sync pipe yet. */ 2021 sync = FALSE; 2022 if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) { 2023 sync = TRUE; 2024#ifndef UAUDIO_MULTIPLE_ENDPOINTS 2025 printf("%s: ignored input endpoint of type adaptive\n", 2026 device_get_nameunit(sc->sc_dev)); 2027 return USBD_NORMAL_COMPLETION; 2028#endif 2029 } 2030 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) { 2031 sync = TRUE; 2032#ifndef UAUDIO_MULTIPLE_ENDPOINTS 2033 printf("%s: ignored output endpoint of type async\n", 2034 device_get_nameunit(sc->sc_dev)); 2035 return USBD_NORMAL_COMPLETION; 2036#endif 2037 } | 2088 if (u.desc->bLength < len) { 2089 goto error; 2090 } 2091 len += u.eu->bNrInPins; |
2038 | 2092 |
2039 sed = (const void *)(buf + offs); 2040 if (sed->bDescriptorType != UDESC_CS_ENDPOINT || 2041 sed->bDescriptorSubtype != AS_GENERAL) 2042 return USBD_INVAL; 2043 DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength)); 2044 offs += sed->bLength; 2045 if (offs > size) 2046 return USBD_INVAL; 2047 2048#ifdef UAUDIO_MULTIPLE_ENDPOINTS 2049 if (sync && id->bNumEndpoints <= 1) { 2050 printf("%s: a sync-pipe endpoint but no other endpoint\n", 2051 device_get_nameunit(sc->sc_dev)); 2052 return USBD_INVAL; 2053 } 2054#endif 2055 if (!sync && id->bNumEndpoints > 1) { 2056 printf("%s: non sync-pipe endpoint but multiple endpoints\n", 2057 device_get_nameunit(sc->sc_dev)); 2058 return USBD_INVAL; 2059 } 2060 epdesc1 = NULL; 2061 if (id->bNumEndpoints > 1) { 2062 epdesc1 = (const void*)(buf + offs); 2063 if (epdesc1->bDescriptorType != UDESC_ENDPOINT) 2064 return USBD_INVAL; 2065 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d " 2066 "bDescriptorType=%d bEndpointAddress=%d " 2067 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d " 2068 "bRefresh=%d bSynchAddress=%d\n", 2069 epdesc1->bLength, epdesc1->bDescriptorType, 2070 epdesc1->bEndpointAddress, epdesc1->bmAttributes, 2071 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval, 2072 epdesc1->bRefresh, epdesc1->bSynchAddress)); 2073 offs += epdesc1->bLength; 2074 if (offs > size) 2075 return USBD_INVAL; 2076 if (epdesc1->bSynchAddress != 0) { 2077 printf("%s: invalid endpoint: bSynchAddress=0\n", 2078 device_get_nameunit(sc->sc_dev)); 2079 return USBD_INVAL; | 2093 if (u.desc->bLength < len) { 2094 goto error; |
2080 } | 2095 } |
2081 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) { 2082 printf("%s: invalid endpoint: bmAttributes=0x%x\n", 2083 device_get_nameunit(sc->sc_dev), epdesc1->bmAttributes); 2084 return USBD_INVAL; 2085 } 2086 if (epdesc1->bEndpointAddress != ed->bSynchAddress) { 2087 printf("%s: invalid endpoint addresses: " 2088 "ep[0]->bSynchAddress=0x%x " 2089 "ep[1]->bEndpointAddress=0x%x\n", 2090 device_get_nameunit(sc->sc_dev), ed->bSynchAddress, 2091 epdesc1->bEndpointAddress); 2092 return USBD_INVAL; 2093 } 2094 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */ 2095 } | 2096 e1 = (const void *)(u.eu->baSourceId + u.eu->bNrInPins); |
2096 | 2097 |
2097 format = UGETW(asid->wFormatTag); 2098 chan = asf1d->bNrChannels; 2099 prec = asf1d->bBitResolution; 2100 if (prec != 8 && prec != 16 && prec != 24 && prec != 32) { 2101 printf("%s: ignored setting with precision %d\n", 2102 device_get_nameunit(sc->sc_dev), prec); 2103 return USBD_NORMAL_COMPLETION; 2104 } 2105 switch (format) { 2106 case UA_FMT_PCM: 2107 if (prec == 8) { 2108 sc->sc_altflags |= HAS_8; 2109 } else if (prec == 16) { 2110 sc->sc_altflags |= HAS_16; 2111 } else if (prec == 24) { 2112 sc->sc_altflags |= HAS_24; 2113 } else if (prec == 32) { 2114 sc->sc_altflags |= HAS_32; | 2098 len += sizeof(*e1); 2099 2100 if (u.desc->bLength < len) { 2101 goto error; |
2115 } | 2102 } |
2116 enc = AUDIO_ENCODING_SLINEAR_LE; 2117 format_str = "pcm"; | 2103 len += e1->bControlSize; |
2118 break; | 2104 break; |
2119 case UA_FMT_PCM8: 2120 enc = AUDIO_ENCODING_ULINEAR_LE; 2121 sc->sc_altflags |= HAS_8U; 2122 format_str = "pcm8"; 2123 break; 2124 case UA_FMT_ALAW: 2125 enc = AUDIO_ENCODING_ALAW; 2126 sc->sc_altflags |= HAS_ALAW; 2127 format_str = "alaw"; 2128 break; 2129 case UA_FMT_MULAW: 2130 enc = AUDIO_ENCODING_ULAW; 2131 sc->sc_altflags |= HAS_MULAW; 2132 format_str = "mulaw"; 2133 break; 2134 case UA_FMT_IEEE_FLOAT: | 2105 |
2135 default: | 2106 default: |
2136 printf("%s: ignored setting with format %d\n", 2137 device_get_nameunit(sc->sc_dev), format); 2138 return USBD_NORMAL_COMPLETION; | 2107 goto error; |
2139 } | 2108 } |
2140#ifdef USB_DEBUG 2141 printf("%s: %s: %dch, %d/%dbit, %s,", device_get_nameunit(sc->sc_dev), 2142 dir == UE_DIR_IN ? "recording" : "playback", 2143 chan, prec, asf1d->bSubFrameSize * 8, format_str); 2144 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 2145 printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 2146 } else { 2147 int r; 2148 printf(" %d", UA_GETSAMP(asf1d, 0)); 2149 for (r = 1; r < asf1d->bSamFreqType; r++) 2150 printf(",%d", UA_GETSAMP(asf1d, r)); 2151 printf("Hz\n"); 2152 } 2153#endif 2154#if defined(__FreeBSD__) 2155 if (sc->uaudio_sndstat_flag != 0) { 2156 sbuf_printf(&(sc->uaudio_sndstat), "\n\t"); 2157 sbuf_printf(&(sc->uaudio_sndstat), 2158 "mode %d:(%s) %dch, %d/%dbit, %s,", 2159 id->bAlternateSetting, 2160 dir == UE_DIR_IN ? "input" : "output", 2161 chan, prec, asf1d->bSubFrameSize * 8, format_str); 2162 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 2163 sbuf_printf(&(sc->uaudio_sndstat), " %d-%dHz", 2164 UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 2165 } else { 2166 int r; 2167 sbuf_printf(&(sc->uaudio_sndstat), 2168 " %d", UA_GETSAMP(asf1d, 0)); 2169 for (r = 1; r < asf1d->bSamFreqType; r++) 2170 sbuf_printf(&(sc->uaudio_sndstat), 2171 ",%d", UA_GETSAMP(asf1d, r)); 2172 sbuf_printf(&(sc->uaudio_sndstat), "Hz"); 2173 } 2174 } 2175#endif 2176 ai.alt = id->bAlternateSetting; 2177 ai.encoding = enc; 2178 ai.attributes = sed->bmAttributes; 2179 ai.idesc = id; 2180 ai.edesc = ed; 2181 ai.edesc1 = epdesc1; 2182 ai.asf1desc = asf1d; 2183 ai.sc_busy = 0; 2184 ai.ifaceh = NULL; 2185 uaudio_add_alt(sc, &ai); 2186#ifdef USB_DEBUG 2187 if (ai.attributes & UA_SED_FREQ_CONTROL) 2188 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n")); 2189 if (ai.attributes & UA_SED_PITCH_CONTROL) 2190 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n")); 2191#endif 2192 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD; | |
2193 | 2109 |
2194 return USBD_NORMAL_COMPLETION; 2195} 2196#undef offs 2197 2198static usbd_status 2199uaudio_identify_as(struct uaudio_softc *sc, 2200 const usb_config_descriptor_t *cdesc) 2201{ 2202 const usb_interface_descriptor_t *id; 2203 const char *buf; 2204 int size, offs; 2205 2206 size = UGETW(cdesc->wTotalLength); 2207 buf = (const char *)cdesc; 2208 2209 /* Locate the AudioStreaming interface descriptor. */ 2210 offs = 0; 2211 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM); 2212 if (id == NULL) 2213 return USBD_INVAL; 2214 2215#if defined(__FreeBSD__) 2216 sc->uaudio_sndstat_flag = 0; 2217 if (sbuf_new(&(sc->uaudio_sndstat), NULL, 4096, SBUF_AUTOEXTEND) != NULL) 2218 sc->uaudio_sndstat_flag = 1; 2219#endif 2220 /* Loop through all the alternate settings. */ 2221 while (offs <= size) { 2222 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n", 2223 id->bInterfaceNumber, offs)); 2224 switch (id->bNumEndpoints) { 2225 case 0: 2226 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n", 2227 id->bAlternateSetting)); 2228 sc->sc_nullalt = id->bAlternateSetting; 2229 break; 2230 case 1: 2231#ifdef UAUDIO_MULTIPLE_ENDPOINTS 2232 case 2: 2233#endif 2234 uaudio_process_as(sc, buf, &offs, size, id); 2235 break; 2236 default: 2237 printf("%s: ignored audio interface with %d " 2238 "endpoints\n", 2239 device_get_nameunit(sc->sc_dev), id->bNumEndpoints); 2240 break; 2241 } 2242 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM); 2243 if (id == NULL) 2244 break; | 2110 if (u.desc->bLength < len) { 2111 goto error; |
2245 } | 2112 } |
2246#if defined(__FreeBSD__) 2247 sbuf_finish(&(sc->uaudio_sndstat)); 2248#endif 2249 if (offs > size) 2250 return USBD_INVAL; 2251 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts)); | 2113 return (u.desc); |
2252 | 2114 |
2253 if (sc->sc_mode == 0) { 2254 printf("%s: no usable endpoint found\n", 2255 device_get_nameunit(sc->sc_dev)); 2256 return USBD_INVAL; | 2115error: 2116 if (u.desc) { 2117 DPRINTF("invalid descriptor, type=%d, " 2118 "sub_type=%d, len=%d of %d bytes\n", 2119 u.desc->bDescriptorType, 2120 u.desc->bDescriptorSubtype, 2121 u.desc->bLength, len); |
2257 } | 2122 } |
2258 2259 return USBD_NORMAL_COMPLETION; | 2123 return (NULL); |
2260} 2261 | 2124} 2125 |
2262static usbd_status 2263uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) | 2126#if USB_DEBUG 2127static void 2128uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot) |
2264{ | 2129{ |
2265 struct io_terminal* iot; 2266 const usb_interface_descriptor_t *id; 2267 const struct usb_audio_control_descriptor *acdp; 2268 const usb_descriptor_t *dp; 2269 const struct usb_audio_output_terminal *pot; 2270 struct terminal_list *tml; 2271 const char *buf, *ibuf, *ibufend; 2272 int size, offs, aclen, ndps, i, j; | 2130 static const char *channel_names[16] = { 2131 "LEFT", "RIGHT", "CENTER", "LFE", 2132 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER", 2133 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP", 2134 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", 2135 }; 2136 uint16_t cc; 2137 uint8_t i; 2138 const struct usb2_audio_cluster cl = uaudio_mixer_get_cluster(id, iot); |
2273 | 2139 |
2274 size = UGETW(cdesc->wTotalLength); 2275 buf = (const char *)cdesc; | 2140 cc = UGETW(cl.wChannelConfig); |
2276 | 2141 |
2277 /* Locate the AudioControl interface descriptor. */ 2278 offs = 0; 2279 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL); 2280 if (id == NULL) 2281 return USBD_INVAL; 2282 if (offs + sizeof *acdp > size) 2283 return USBD_INVAL; 2284 sc->sc_ac_iface = id->bInterfaceNumber; 2285 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface)); | 2142 DPRINTF("cluster: bNrChannels=%u iChannelNames=%u wChannelConfig=" 2143 "0x%04x:\n", cl.iChannelNames, cl.bNrChannels, cc); |
2286 | 2144 |
2287 /* A class-specific AC interface header should follow. */ 2288 ibuf = buf + offs; 2289 acdp = (const struct usb_audio_control_descriptor *)ibuf; 2290 if (acdp->bDescriptorType != UDESC_CS_INTERFACE || 2291 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) 2292 return USBD_INVAL; 2293 aclen = UGETW(acdp->wTotalLength); 2294 if (offs + aclen > size) 2295 return USBD_INVAL; 2296 2297 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) && 2298 UGETW(acdp->bcdADC) != UAUDIO_VERSION) 2299 return USBD_INVAL; 2300 2301 sc->sc_audio_rev = UGETW(acdp->bcdADC); 2302 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n", 2303 sc->sc_audio_rev, aclen)); 2304 2305 sc->sc_nullalt = -1; 2306 2307 /* Scan through all the AC specific descriptors */ 2308 ibufend = ibuf + aclen; 2309 dp = (const usb_descriptor_t *)ibuf; 2310 ndps = 0; 2311 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO); 2312 if (iot == NULL) { 2313 printf("%s: no memory\n", __func__); 2314 return USBD_NOMEM; 2315 } 2316 for (;;) { 2317 ibuf += dp->bLength; 2318 if (ibuf >= ibufend) 2319 break; 2320 dp = (const usb_descriptor_t *)ibuf; 2321 if (ibuf + dp->bLength > ibufend) { 2322 free(iot, M_TEMP); 2323 return USBD_INVAL; | 2145 for (i = 0; cc; i++) { 2146 if (cc & 1) { 2147 DPRINTF(" - %s\n", channel_names[i]); |
2324 } | 2148 } |
2325 if (dp->bDescriptorType != UDESC_CS_INTERFACE) { 2326 printf("uaudio_identify_ac: skip desc type=0x%02x\n", 2327 dp->bDescriptorType); 2328 continue; 2329 } 2330 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId; 2331 iot[i].d.desc = dp; 2332 if (i > ndps) 2333 ndps = i; | 2149 cc >>= 1; |
2334 } | 2150 } |
2335 ndps++; | 2151} |
2336 | 2152 |
2337 /* construct io_terminal */ 2338 for (i = 0; i < ndps; i++) { 2339 dp = iot[i].d.desc; 2340 if (dp == NULL) 2341 continue; 2342 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT) 2343 continue; 2344 pot = iot[i].d.ot; 2345 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i); 2346 if (tml != NULL) 2347 free(tml, M_TEMP); 2348 } | 2153#endif |
2349 | 2154 |
2350#ifdef USB_DEBUG 2351 for (i = 0; i < 256; i++) { 2352 struct usb_audio_cluster cluster; | 2155static struct usb2_audio_cluster 2156uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot) 2157{ 2158 struct usb2_audio_cluster r; 2159 const struct usb2_descriptor *dp; 2160 uint8_t i; |
2353 | 2161 |
2354 if (iot[i].d.desc == NULL) 2355 continue; 2356 printf("id %d:\t", i); 2357 switch (iot[i].d.desc->bDescriptorSubtype) { 2358 case UDESCSUB_AC_INPUT: 2359 printf("AC_INPUT type=%s\n", uaudio_get_terminal_name 2360 (UGETW(iot[i].d.it->wTerminalType))); 2361 printf("\t"); 2362 cluster = uaudio_get_cluster(i, iot); 2363 uaudio_dump_cluster(&cluster); 2364 printf("\n"); 2365 break; 2366 case UDESCSUB_AC_OUTPUT: 2367 printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name 2368 (UGETW(iot[i].d.ot->wTerminalType))); 2369 printf("src=%d\n", iot[i].d.ot->bSourceId); 2370 break; 2371 case UDESCSUB_AC_MIXER: 2372 printf("AC_MIXER src="); 2373 for (j = 0; j < iot[i].d.mu->bNrInPins; j++) 2374 printf("%d ", iot[i].d.mu->baSourceId[j]); 2375 printf("\n\t"); 2376 cluster = uaudio_get_cluster(i, iot); 2377 uaudio_dump_cluster(&cluster); 2378 printf("\n"); 2379 break; 2380 case UDESCSUB_AC_SELECTOR: 2381 printf("AC_SELECTOR src="); 2382 for (j = 0; j < iot[i].d.su->bNrInPins; j++) 2383 printf("%d ", iot[i].d.su->baSourceId[j]); 2384 printf("\n"); 2385 break; 2386 case UDESCSUB_AC_FEATURE: 2387 printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId); 2388 break; 2389 case UDESCSUB_AC_PROCESSING: 2390 printf("AC_PROCESSING src="); 2391 for (j = 0; j < iot[i].d.pu->bNrInPins; j++) 2392 printf("%d ", iot[i].d.pu->baSourceId[j]); 2393 printf("\n\t"); 2394 cluster = uaudio_get_cluster(i, iot); 2395 uaudio_dump_cluster(&cluster); 2396 printf("\n"); 2397 break; 2398 case UDESCSUB_AC_EXTENSION: 2399 printf("AC_EXTENSION src="); 2400 for (j = 0; j < iot[i].d.eu->bNrInPins; j++) 2401 printf("%d ", iot[i].d.eu->baSourceId[j]); 2402 printf("\n\t"); 2403 cluster = uaudio_get_cluster(i, iot); 2404 uaudio_dump_cluster(&cluster); 2405 printf("\n"); 2406 break; 2407 default: 2408 printf("unknown audio control (subtype=%d)\n", 2409 iot[i].d.desc->bDescriptorSubtype); | 2162 for (i = 0; i < UAUDIO_RECURSE_LIMIT; i++) { /* avoid infinite loops */ 2163 dp = iot[id].u.desc; 2164 if (dp == NULL) { 2165 goto error; |
2410 } | 2166 } |
2411 for (j = 0; j < iot[i].inputs_size; j++) { 2412 int k; 2413 printf("\tinput%d: ", j); 2414 tml = iot[i].inputs[j]; 2415 if (tml == NULL) { 2416 printf("NULL\n"); 2417 continue; 2418 } 2419 for (k = 0; k < tml->size; k++) 2420 printf("%s ", uaudio_get_terminal_name 2421 (tml->terminals[k])); 2422 printf("\n"); 2423 } 2424 printf("\toutput: "); 2425 tml = iot[i].output; 2426 for (j = 0; j < tml->size; j++) 2427 printf("%s ", uaudio_get_terminal_name(tml->terminals[j])); 2428 printf("\n"); 2429 } 2430#endif 2431 2432 for (i = 0; i < ndps; i++) { 2433 dp = iot[i].d.desc; 2434 if (dp == NULL) 2435 continue; 2436 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n", 2437 i, dp->bDescriptorSubtype)); | |
2438 switch (dp->bDescriptorSubtype) { | 2167 switch (dp->bDescriptorSubtype) { |
2439 case UDESCSUB_AC_HEADER: 2440 printf("uaudio_identify_ac: unexpected AC header\n"); 2441 break; | |
2442 case UDESCSUB_AC_INPUT: | 2168 case UDESCSUB_AC_INPUT: |
2443 uaudio_add_input(sc, iot, i); 2444 break; | 2169 r.bNrChannels = iot[id].u.it->bNrChannels; 2170 r.wChannelConfig[0] = iot[id].u.it->wChannelConfig[0]; 2171 r.wChannelConfig[1] = iot[id].u.it->wChannelConfig[1]; 2172 r.iChannelNames = iot[id].u.it->iChannelNames; 2173 goto done; 2174 |
2445 case UDESCSUB_AC_OUTPUT: | 2175 case UDESCSUB_AC_OUTPUT: |
2446 uaudio_add_output(sc, iot, i); | 2176 id = iot[id].u.ot->bSourceId; |
2447 break; | 2177 break; |
2178 |
|
2448 case UDESCSUB_AC_MIXER: | 2179 case UDESCSUB_AC_MIXER: |
2449 uaudio_add_mixer(sc, iot, i); 2450 break; | 2180 r = *(const struct usb2_audio_cluster *) 2181 &iot[id].u.mu->baSourceId[iot[id].u.mu-> 2182 bNrInPins]; 2183 goto done; 2184 |
2451 case UDESCSUB_AC_SELECTOR: | 2185 case UDESCSUB_AC_SELECTOR: |
2452 uaudio_add_selector(sc, iot, i); | 2186 if (iot[id].u.su->bNrInPins > 0) { 2187 /* XXX This is not really right */ 2188 id = iot[id].u.su->baSourceId[0]; 2189 } |
2453 break; | 2190 break; |
2191 |
|
2454 case UDESCSUB_AC_FEATURE: | 2192 case UDESCSUB_AC_FEATURE: |
2455 uaudio_add_feature(sc, iot, i); | 2193 id = iot[id].u.fu->bSourceId; |
2456 break; | 2194 break; |
2195 |
|
2457 case UDESCSUB_AC_PROCESSING: | 2196 case UDESCSUB_AC_PROCESSING: |
2458 uaudio_add_processing(sc, iot, i); 2459 break; | 2197 r = *((const struct usb2_audio_cluster *) 2198 &iot[id].u.pu->baSourceId[iot[id].u.pu-> 2199 bNrInPins]); 2200 goto done; 2201 |
2460 case UDESCSUB_AC_EXTENSION: | 2202 case UDESCSUB_AC_EXTENSION: |
2461 uaudio_add_extension(sc, iot, i); 2462 break; | 2203 r = *((const struct usb2_audio_cluster *) 2204 &iot[id].u.eu->baSourceId[iot[id].u.eu-> 2205 bNrInPins]); 2206 goto done; 2207 |
2463 default: | 2208 default: |
2464 printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n", 2465 dp->bDescriptorSubtype); 2466 break; | 2209 goto error; |
2467 } 2468 } | 2210 } 2211 } |
2212error: 2213 DPRINTF("bad data\n"); 2214 bzero(&r, sizeof(r)); 2215done: 2216 return (r); 2217} |
|
2469 | 2218 |
2470 /* delete io_terminal */ 2471 for (i = 0; i < 256; i++) { 2472 if (iot[i].d.desc == NULL) 2473 continue; 2474 if (iot[i].inputs != NULL) { 2475 for (j = 0; j < iot[i].inputs_size; j++) { 2476 if (iot[i].inputs[j] != NULL) 2477 free(iot[i].inputs[j], M_TEMP); 2478 } 2479 free(iot[i].inputs, M_TEMP); 2480 } 2481 if (iot[i].output != NULL) 2482 free(iot[i].output, M_TEMP); 2483 iot[i].d.desc = NULL; 2484 } 2485 free(iot, M_TEMP); | 2219#if USB_DEBUG |
2486 | 2220 |
2487 return USBD_NORMAL_COMPLETION; 2488} | 2221struct uaudio_tt_to_string { 2222 uint16_t terminal_type; 2223 const char *desc; 2224}; |
2489 | 2225 |
2490#if defined(__NetBSD__) || defined(__OpenBSD__) 2491static int 2492uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi) 2493{ 2494 struct uaudio_softc *sc; 2495 struct mixerctl *mc; 2496 int n, nctls, i; | 2226static const struct uaudio_tt_to_string uaudio_tt_to_string[] = { |
2497 | 2227 |
2498 sc = addr; 2499 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index)); 2500 if (sc->sc_dying) 2501 return EIO; | 2228 /* USB terminal types */ 2229 {UAT_UNDEFINED, "UAT_UNDEFINED"}, 2230 {UAT_STREAM, "UAT_STREAM"}, 2231 {UAT_VENDOR, "UAT_VENDOR"}, |
2502 | 2232 |
2503 n = mi->index; 2504 nctls = sc->sc_nctls; | 2233 /* input terminal types */ 2234 {UATI_UNDEFINED, "UATI_UNDEFINED"}, 2235 {UATI_MICROPHONE, "UATI_MICROPHONE"}, 2236 {UATI_DESKMICROPHONE, "UATI_DESKMICROPHONE"}, 2237 {UATI_PERSONALMICROPHONE, "UATI_PERSONALMICROPHONE"}, 2238 {UATI_OMNIMICROPHONE, "UATI_OMNIMICROPHONE"}, 2239 {UATI_MICROPHONEARRAY, "UATI_MICROPHONEARRAY"}, 2240 {UATI_PROCMICROPHONEARR, "UATI_PROCMICROPHONEARR"}, |
2505 | 2241 |
2506 switch (n) { 2507 case UAC_OUTPUT: 2508 mi->type = AUDIO_MIXER_CLASS; 2509 mi->mixer_class = UAC_OUTPUT; 2510 mi->next = mi->prev = AUDIO_MIXER_LAST; 2511 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name)); 2512 return 0; 2513 case UAC_INPUT: 2514 mi->type = AUDIO_MIXER_CLASS; 2515 mi->mixer_class = UAC_INPUT; 2516 mi->next = mi->prev = AUDIO_MIXER_LAST; 2517 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name)); 2518 return 0; 2519 case UAC_EQUAL: 2520 mi->type = AUDIO_MIXER_CLASS; 2521 mi->mixer_class = UAC_EQUAL; 2522 mi->next = mi->prev = AUDIO_MIXER_LAST; 2523 strlcpy(mi->label.name, AudioCequalization, 2524 sizeof(mi->label.name)); 2525 return 0; 2526 case UAC_RECORD: 2527 mi->type = AUDIO_MIXER_CLASS; 2528 mi->mixer_class = UAC_RECORD; 2529 mi->next = mi->prev = AUDIO_MIXER_LAST; 2530 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name)); 2531 return 0; 2532 default: 2533 break; 2534 } | 2242 /* output terminal types */ 2243 {UATO_UNDEFINED, "UATO_UNDEFINED"}, 2244 {UATO_SPEAKER, "UATO_SPEAKER"}, 2245 {UATO_HEADPHONES, "UATO_HEADPHONES"}, 2246 {UATO_DISPLAYAUDIO, "UATO_DISPLAYAUDIO"}, 2247 {UATO_DESKTOPSPEAKER, "UATO_DESKTOPSPEAKER"}, 2248 {UATO_ROOMSPEAKER, "UATO_ROOMSPEAKER"}, 2249 {UATO_COMMSPEAKER, "UATO_COMMSPEAKER"}, 2250 {UATO_SUBWOOFER, "UATO_SUBWOOFER"}, |
2535 | 2251 |
2536 n -= UAC_NCLASSES; 2537 if (n < 0 || n >= nctls) 2538 return ENXIO; | 2252 /* bidir terminal types */ 2253 {UATB_UNDEFINED, "UATB_UNDEFINED"}, 2254 {UATB_HANDSET, "UATB_HANDSET"}, 2255 {UATB_HEADSET, "UATB_HEADSET"}, 2256 {UATB_SPEAKERPHONE, "UATB_SPEAKERPHONE"}, 2257 {UATB_SPEAKERPHONEESUP, "UATB_SPEAKERPHONEESUP"}, 2258 {UATB_SPEAKERPHONEECANC, "UATB_SPEAKERPHONEECANC"}, |
2539 | 2259 |
2540 mc = &sc->sc_ctls[n]; 2541 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name)); 2542 mi->mixer_class = mc->class; 2543 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */ 2544 switch (mc->type) { 2545 case MIX_ON_OFF: 2546 mi->type = AUDIO_MIXER_ENUM; 2547 mi->un.e.num_mem = 2; 2548 strlcpy(mi->un.e.member[0].label.name, AudioNoff, 2549 sizeof(mi->un.e.member[0].label.name)); 2550 mi->un.e.member[0].ord = 0; 2551 strlcpy(mi->un.e.member[1].label.name, AudioNon, 2552 sizeof(mi->un.e.member[1].label.name)); 2553 mi->un.e.member[1].ord = 1; 2554 break; 2555 case MIX_SELECTOR: 2556 mi->type = AUDIO_MIXER_ENUM; 2557 mi->un.e.num_mem = mc->maxval - mc->minval + 1; 2558 for (i = 0; i <= mc->maxval - mc->minval; i++) { 2559 snprintf(mi->un.e.member[i].label.name, 2560 sizeof(mi->un.e.member[i].label.name), 2561 "%d", i + mc->minval); 2562 mi->un.e.member[i].ord = i + mc->minval; | 2260 /* telephony terminal types */ 2261 {UATT_UNDEFINED, "UATT_UNDEFINED"}, 2262 {UATT_PHONELINE, "UATT_PHONELINE"}, 2263 {UATT_TELEPHONE, "UATT_TELEPHONE"}, 2264 {UATT_DOWNLINEPHONE, "UATT_DOWNLINEPHONE"}, 2265 2266 /* external terminal types */ 2267 {UATE_UNDEFINED, "UATE_UNDEFINED"}, 2268 {UATE_ANALOGCONN, "UATE_ANALOGCONN"}, 2269 {UATE_LINECONN, "UATE_LINECONN"}, 2270 {UATE_LEGACYCONN, "UATE_LEGACYCONN"}, 2271 {UATE_DIGITALAUIFC, "UATE_DIGITALAUIFC"}, 2272 {UATE_SPDIF, "UATE_SPDIF"}, 2273 {UATE_1394DA, "UATE_1394DA"}, 2274 {UATE_1394DV, "UATE_1394DV"}, 2275 2276 /* embedded function terminal types */ 2277 {UATF_UNDEFINED, "UATF_UNDEFINED"}, 2278 {UATF_CALIBNOISE, "UATF_CALIBNOISE"}, 2279 {UATF_EQUNOISE, "UATF_EQUNOISE"}, 2280 {UATF_CDPLAYER, "UATF_CDPLAYER"}, 2281 {UATF_DAT, "UATF_DAT"}, 2282 {UATF_DCC, "UATF_DCC"}, 2283 {UATF_MINIDISK, "UATF_MINIDISK"}, 2284 {UATF_ANALOGTAPE, "UATF_ANALOGTAPE"}, 2285 {UATF_PHONOGRAPH, "UATF_PHONOGRAPH"}, 2286 {UATF_VCRAUDIO, "UATF_VCRAUDIO"}, 2287 {UATF_VIDEODISCAUDIO, "UATF_VIDEODISCAUDIO"}, 2288 {UATF_DVDAUDIO, "UATF_DVDAUDIO"}, 2289 {UATF_TVTUNERAUDIO, "UATF_TVTUNERAUDIO"}, 2290 {UATF_SATELLITE, "UATF_SATELLITE"}, 2291 {UATF_CABLETUNER, "UATF_CABLETUNER"}, 2292 {UATF_DSS, "UATF_DSS"}, 2293 {UATF_RADIORECV, "UATF_RADIORECV"}, 2294 {UATF_RADIOXMIT, "UATF_RADIOXMIT"}, 2295 {UATF_MULTITRACK, "UATF_MULTITRACK"}, 2296 {UATF_SYNTHESIZER, "UATF_SYNTHESIZER"}, 2297 2298 /* unknown */ 2299 {0x0000, "UNKNOWN"}, 2300}; 2301 2302static const char * 2303uaudio_mixer_get_terminal_name(uint16_t terminal_type) 2304{ 2305 const struct uaudio_tt_to_string *uat = uaudio_tt_to_string; 2306 2307 while (uat->terminal_type) { 2308 if (uat->terminal_type == terminal_type) { 2309 break; |
2563 } | 2310 } |
2564 break; 2565 default: 2566 mi->type = AUDIO_MIXER_VALUE; 2567 strlcpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN); 2568 mi->un.v.num_channels = mc->nchan; 2569 mi->un.v.delta = mc->delta; 2570 break; | 2311 uat++; |
2571 } | 2312 } |
2572 return 0; | 2313 if (uat->terminal_type == 0) { 2314 DPRINTF("unknown terminal type (0x%04x)", terminal_type); 2315 } 2316 return (uat->desc); |
2573} 2574 | 2317} 2318 |
2575static int 2576uaudio_open(void *addr, int flags) | 2319#endif 2320 2321static uint16_t 2322uaudio_mixer_determine_class(const struct uaudio_terminal_node *iot, 2323 struct uaudio_mixer_node *mix) |
2577{ | 2324{ |
2578 struct uaudio_softc *sc; | 2325 uint16_t terminal_type = 0x0000; 2326 const struct uaudio_terminal_node *input[2]; 2327 const struct uaudio_terminal_node *output[2]; |
2579 | 2328 |
2580 sc = addr; 2581 DPRINTF(("uaudio_open: sc=%p\n", sc)); 2582 if (sc->sc_dying) 2583 return EIO; | 2329 input[0] = uaudio_mixer_get_input(iot, 0); 2330 input[1] = uaudio_mixer_get_input(iot, 1); |
2584 | 2331 |
2585 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY)) 2586 return EACCES; 2587 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD)) 2588 return EACCES; | 2332 output[0] = uaudio_mixer_get_output(iot, 0); 2333 output[1] = uaudio_mixer_get_output(iot, 1); |
2589 | 2334 |
2590 return 0; 2591} | 2335 /* 2336 * check if there is only 2337 * one output terminal: 2338 */ 2339 if (output[0] && (!output[1])) { 2340 terminal_type = UGETW(output[0]->u.ot->wTerminalType); 2341 } 2342 /* 2343 * If the only output terminal is USB, 2344 * the class is UAC_RECORD. 2345 */ 2346 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { |
2592 | 2347 |
2593/* 2594 * Close function is called at splaudio(). 2595 */ 2596static void 2597uaudio_close(void *addr) 2598{ | 2348 mix->class = UAC_RECORD; 2349 if (input[0] && (!input[1])) { 2350 terminal_type = UGETW(input[0]->u.it->wTerminalType); 2351 } else { 2352 terminal_type = 0; 2353 } 2354 goto done; 2355 } 2356 /* 2357 * if the unit is connected to just 2358 * one input terminal, the 2359 * class is UAC_INPUT: 2360 */ 2361 if (input[0] && (!input[1])) { 2362 mix->class = UAC_INPUT; 2363 terminal_type = UGETW(input[0]->u.it->wTerminalType); 2364 goto done; 2365 } 2366 /* 2367 * Otherwise, the class is UAC_OUTPUT. 2368 */ 2369 mix->class = UAC_OUTPUT; 2370done: 2371 return (terminal_type); |
2599} 2600 | 2372} 2373 |
2601static int 2602uaudio_drain(void *addr) 2603{ 2604 struct uaudio_softc *sc; | 2374struct uaudio_tt_to_feature { 2375 uint16_t terminal_type; 2376 uint16_t feature; 2377}; |
2605 | 2378 |
2606 sc = addr; 2607 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); | 2379static const struct uaudio_tt_to_feature uaudio_tt_to_feature[] = { |
2608 | 2380 |
2609 return 0; 2610} | 2381 {UAT_STREAM, SOUND_MIXER_PCM}, |
2611 | 2382 |
2612static int 2613uaudio_halt_out_dma(void *addr) 2614{ 2615 struct uaudio_softc *sc; | 2383 {UATI_MICROPHONE, SOUND_MIXER_MIC}, 2384 {UATI_DESKMICROPHONE, SOUND_MIXER_MIC}, 2385 {UATI_PERSONALMICROPHONE, SOUND_MIXER_MIC}, 2386 {UATI_OMNIMICROPHONE, SOUND_MIXER_MIC}, 2387 {UATI_MICROPHONEARRAY, SOUND_MIXER_MIC}, 2388 {UATI_PROCMICROPHONEARR, SOUND_MIXER_MIC}, |
2616 | 2389 |
2617 sc = addr; 2618 if (sc->sc_dying) 2619 return EIO; | 2390 {UATO_SPEAKER, SOUND_MIXER_SPEAKER}, 2391 {UATO_DESKTOPSPEAKER, SOUND_MIXER_SPEAKER}, 2392 {UATO_ROOMSPEAKER, SOUND_MIXER_SPEAKER}, 2393 {UATO_COMMSPEAKER, SOUND_MIXER_SPEAKER}, |
2620 | 2394 |
2621 DPRINTF(("uaudio_halt_out_dma: enter\n")); 2622 if (sc->sc_playchan.pipe != NULL) { 2623 uaudio_chan_close(sc, &sc->sc_playchan); 2624 sc->sc_playchan.pipe = NULL; 2625 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 2626 sc->sc_playchan.intr = NULL; 2627 } 2628 return 0; 2629} | 2395 {UATE_ANALOGCONN, SOUND_MIXER_LINE}, 2396 {UATE_LINECONN, SOUND_MIXER_LINE}, 2397 {UATE_LEGACYCONN, SOUND_MIXER_LINE}, |
2630 | 2398 |
2631static int 2632uaudio_halt_in_dma(void *addr) 2633{ 2634 struct uaudio_softc *sc; | 2399 {UATE_DIGITALAUIFC, SOUND_MIXER_ALTPCM}, 2400 {UATE_SPDIF, SOUND_MIXER_ALTPCM}, 2401 {UATE_1394DA, SOUND_MIXER_ALTPCM}, 2402 {UATE_1394DV, SOUND_MIXER_ALTPCM}, |
2635 | 2403 |
2636 DPRINTF(("uaudio_halt_in_dma: enter\n")); 2637 sc = addr; 2638 if (sc->sc_recchan.pipe != NULL) { 2639 uaudio_chan_close(sc, &sc->sc_recchan); 2640 sc->sc_recchan.pipe = NULL; 2641 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 2642 sc->sc_recchan.intr = NULL; 2643 } 2644 return 0; 2645} | 2404 {UATF_CDPLAYER, SOUND_MIXER_CD}, |
2646 | 2405 |
2647static int 2648uaudio_getdev(void *addr, struct audio_device *retp) 2649{ 2650 struct uaudio_softc *sc; | 2406 {UATF_SYNTHESIZER, SOUND_MIXER_SYNTH}, |
2651 | 2407 |
2652 DPRINTF(("uaudio_mixer_getdev:\n")); 2653 sc = addr; 2654 if (sc->sc_dying) 2655 return EIO; | 2408 {UATF_VIDEODISCAUDIO, SOUND_MIXER_VIDEO}, 2409 {UATF_DVDAUDIO, SOUND_MIXER_VIDEO}, 2410 {UATF_TVTUNERAUDIO, SOUND_MIXER_VIDEO}, |
2656 | 2411 |
2657 *retp = uaudio_device; 2658 return 0; 2659} | 2412 /* telephony terminal types */ 2413 {UATT_UNDEFINED, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ 2414 {UATT_PHONELINE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ 2415 {UATT_TELEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ 2416 {UATT_DOWNLINEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ |
2660 | 2417 |
2661/* 2662 * Make sure the block size is large enough to hold all outstanding transfers. 2663 */ 2664static int 2665uaudio_round_blocksize(void *addr, int blk) 2666{ 2667 struct uaudio_softc *sc; 2668 int b; | 2418 {UATF_RADIORECV, SOUND_MIXER_RADIO}, 2419 {UATF_RADIOXMIT, SOUND_MIXER_RADIO}, |
2669 | 2420 |
2670 sc = addr; 2671 DPRINTF(("uaudio_round_blocksize: blk=%d mode=%s\n", blk, 2672 mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD")); | 2421 {UAT_UNDEFINED, SOUND_MIXER_VOLUME}, 2422 {UAT_VENDOR, SOUND_MIXER_VOLUME}, 2423 {UATI_UNDEFINED, SOUND_MIXER_VOLUME}, |
2673 | 2424 |
2674 /* chan.bytes_per_frame can be 0. */ 2675 if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) { 2676 b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; | 2425 /* output terminal types */ 2426 {UATO_UNDEFINED, SOUND_MIXER_VOLUME}, 2427 {UATO_DISPLAYAUDIO, SOUND_MIXER_VOLUME}, 2428 {UATO_SUBWOOFER, SOUND_MIXER_VOLUME}, 2429 {UATO_HEADPHONES, SOUND_MIXER_VOLUME}, |
2677 | 2430 |
2678 /* 2679 * This does not make accurate value in the case 2680 * of b % USB_FRAMES_PER_SECOND != 0 2681 */ 2682 b /= USB_FRAMES_PER_SECOND; | 2431 /* bidir terminal types */ 2432 {UATB_UNDEFINED, SOUND_MIXER_VOLUME}, 2433 {UATB_HANDSET, SOUND_MIXER_VOLUME}, 2434 {UATB_HEADSET, SOUND_MIXER_VOLUME}, 2435 {UATB_SPEAKERPHONE, SOUND_MIXER_VOLUME}, 2436 {UATB_SPEAKERPHONEESUP, SOUND_MIXER_VOLUME}, 2437 {UATB_SPEAKERPHONEECANC, SOUND_MIXER_VOLUME}, |
2683 | 2438 |
2684 b *= param->precision / 8 * param->channels; 2685 } else { 2686 /* 2687 * use wMaxPacketSize in bytes_per_frame. 2688 * See uaudio_set_params() and uaudio_chan_init() 2689 */ 2690 b = sc->sc_recchan.bytes_per_frame 2691 * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 2692 } | 2439 /* external terminal types */ 2440 {UATE_UNDEFINED, SOUND_MIXER_VOLUME}, |
2693 | 2441 |
2694 if (b <= 0) 2695 b = 1; 2696 blk = blk <= b ? b : blk / b * b; | 2442 /* embedded function terminal types */ 2443 {UATF_UNDEFINED, SOUND_MIXER_VOLUME}, 2444 {UATF_CALIBNOISE, SOUND_MIXER_VOLUME}, 2445 {UATF_EQUNOISE, SOUND_MIXER_VOLUME}, 2446 {UATF_DAT, SOUND_MIXER_VOLUME}, 2447 {UATF_DCC, SOUND_MIXER_VOLUME}, 2448 {UATF_MINIDISK, SOUND_MIXER_VOLUME}, 2449 {UATF_ANALOGTAPE, SOUND_MIXER_VOLUME}, 2450 {UATF_PHONOGRAPH, SOUND_MIXER_VOLUME}, 2451 {UATF_VCRAUDIO, SOUND_MIXER_VOLUME}, 2452 {UATF_SATELLITE, SOUND_MIXER_VOLUME}, 2453 {UATF_CABLETUNER, SOUND_MIXER_VOLUME}, 2454 {UATF_DSS, SOUND_MIXER_VOLUME}, 2455 {UATF_MULTITRACK, SOUND_MIXER_VOLUME}, 2456 {0xffff, SOUND_MIXER_VOLUME}, |
2697 | 2457 |
2698#ifdef DIAGNOSTIC 2699 if (blk <= 0) { 2700 printf("uaudio_round_blocksize: blk=%d\n", blk); 2701 blk = 512; | 2458 /* default */ 2459 {0x0000, SOUND_MIXER_VOLUME}, 2460}; 2461 2462static uint16_t 2463uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, 2464 struct uaudio_mixer_node *mix) 2465{ 2466 const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature; 2467 uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); 2468 2469 if ((mix->class == UAC_RECORD) && (terminal_type == 0)) { 2470 return (SOUND_MIXER_IMIX); |
2702 } | 2471 } |
2703#endif | 2472 while (uat->terminal_type) { 2473 if (uat->terminal_type == terminal_type) { 2474 break; 2475 } 2476 uat++; 2477 } |
2704 | 2478 |
2705 DPRINTF(("uaudio_round_blocksize: resultant blk=%d\n", blk)); 2706 return blk; | 2479 DPRINTF("terminal_type=%s (0x%04x) -> %d\n", 2480 uaudio_mixer_get_terminal_name(terminal_type), 2481 terminal_type, uat->feature); 2482 2483 return (uat->feature); |
2707} 2708 | 2484} 2485 |
2709static int 2710uaudio_get_props(void *addr) | 2486const static struct uaudio_terminal_node * 2487uaudio_mixer_get_input(const struct uaudio_terminal_node *iot, uint8_t index) |
2711{ | 2488{ |
2712 return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT; | 2489 struct uaudio_terminal_node *root = iot->root; 2490 uint8_t n; |
2713 | 2491 |
2492 n = iot->usr.id_max; 2493 do { 2494 if (iot->usr.bit_input[n / 8] & (1 << (n % 8))) { 2495 if (!index--) { 2496 return (root + n); 2497 } 2498 } 2499 } while (n--); 2500 2501 return (NULL); |
|
2714} | 2502} |
2715#endif /* NetBSD or OpenBSD */ | |
2716 | 2503 |
2717static int 2718uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, 2719 int wIndex, int len) | 2504const static struct uaudio_terminal_node * 2505uaudio_mixer_get_output(const struct uaudio_terminal_node *iot, uint8_t index) |
2720{ | 2506{ |
2721 usb_device_request_t req; 2722 uint8_t data[4]; 2723 usbd_status err; 2724 int val; | 2507 struct uaudio_terminal_node *root = iot->root; 2508 uint8_t n; |
2725 | 2509 |
2726#if defined(__FreeBSD__) 2727 if (sc->sc_dying) 2728 return EIO; 2729#endif | 2510 n = iot->usr.id_max; 2511 do { 2512 if (iot->usr.bit_output[n / 8] & (1 << (n % 8))) { 2513 if (!index--) { 2514 return (root + n); 2515 } 2516 } 2517 } while (n--); |
2730 | 2518 |
2731 if (wValue == -1) 2732 return 0; 2733 2734 req.bmRequestType = type; 2735 req.bRequest = which; 2736 USETW(req.wValue, wValue); 2737 USETW(req.wIndex, wIndex); 2738 USETW(req.wLength, len); 2739 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x " 2740 "wIndex=0x%04x len=%d\n", 2741 type, which, wValue, wIndex, len)); 2742#if defined(__FreeBSD__) 2743 if (sc->async != 0) 2744 err = usbd_do_request_async(sc->sc_udev, &req, data); 2745 else 2746#endif 2747 err = usbd_do_request(sc->sc_udev, &req, data); 2748 if (err) { 2749 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err))); 2750 return -1; 2751 } 2752 switch (len) { 2753 case 1: 2754 val = data[0]; 2755 break; 2756 case 2: 2757 val = data[0] | (data[1] << 8); 2758 break; 2759 default: 2760 DPRINTF(("uaudio_get: bad length=%d\n", len)); 2761 return -1; 2762 } 2763 DPRINTFN(2,("uaudio_get: val=%d\n", val)); 2764 return val; | 2519 return (NULL); |
2765} 2766 2767static void | 2520} 2521 2522static void |
2768uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, 2769 int wIndex, int len, int val) | 2523uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *root, 2524 const uint8_t *p_id, uint8_t n_id, 2525 struct uaudio_search_result *info) |
2770{ | 2526{ |
2771 usb_device_request_t req; 2772 uint8_t data[4]; 2773 usbd_status err; | 2527 struct uaudio_terminal_node *iot; 2528 uint8_t n; 2529 uint8_t i; |
2774 | 2530 |
2775#if defined(__FreeBSD__) 2776 if (sc->sc_dying) | 2531 if (info->recurse_level >= UAUDIO_RECURSE_LIMIT) { |
2777 return; | 2532 return; |
2778#endif | 2533 } 2534 info->recurse_level++; |
2779 | 2535 |
2780 if (wValue == -1) 2781 return; | 2536 for (n = 0; n < n_id; n++) { |
2782 | 2537 |
2783 req.bmRequestType = type; 2784 req.bRequest = which; 2785 USETW(req.wValue, wValue); 2786 USETW(req.wIndex, wIndex); 2787 USETW(req.wLength, len); 2788 switch (len) { 2789 case 1: 2790 data[0] = val; 2791 break; 2792 case 2: 2793 data[0] = val; 2794 data[1] = val >> 8; 2795 break; 2796 default: 2797 return; 2798 } 2799 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x " 2800 "wIndex=0x%04x len=%d, val=%d\n", 2801 type, which, wValue, wIndex, len, val & 0xffff)); 2802#if defined(__FreeBSD__) 2803 if (sc->async != 0) 2804 err = usbd_do_request_async(sc->sc_udev, &req, data); 2805 else 2806#endif 2807 err = usbd_do_request(sc->sc_udev, &req, data); 2808#ifdef USB_DEBUG 2809 if (err) 2810 DPRINTF(("uaudio_set: err=%d\n", err)); 2811#endif 2812} | 2538 i = p_id[n]; |
2813 | 2539 |
2814static int 2815uaudio_signext(int type, int val) 2816{ 2817 if (!MIX_UNSIGNED(type)) { 2818 if (MIX_SIZE(type) == 2) 2819 val = (int16_t)val; 2820 else 2821 val = (int8_t)val; 2822 } 2823 return val; 2824} | 2540 if (info->bit_visited[i / 8] & (1 << (i % 8))) { 2541 /* don't go into a circle */ 2542 DPRINTF("avoided going into a circle at id=%d!\n", i); 2543 continue; 2544 } else { 2545 info->bit_visited[i / 8] |= (1 << (i % 8)); 2546 } |
2825 | 2547 |
2826#if defined(__NetBSD__) || defined(__OpenBSD__) 2827static int 2828uaudio_value2bsd(struct mixerctl *mc, int val) 2829{ 2830 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ", 2831 mc->type, val, mc->minval, mc->maxval)); 2832 if (mc->type == MIX_ON_OFF) { 2833 val = (val != 0); 2834 } else if (mc->type == MIX_SELECTOR) { 2835 if (val < mc->minval || val > mc->maxval) 2836 val = mc->minval; 2837 } else 2838 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255 2839 + mc->mul/2) / mc->mul; 2840 DPRINTFN(5, ("val'=%d\n", val)); 2841 return val; 2842} 2843#endif | 2548 iot = (root + i); |
2844 | 2549 |
2845int 2846uaudio_bsd2value(struct mixerctl *mc, int val) 2847{ 2848 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ", 2849 mc->type, val, mc->minval, mc->maxval)); 2850 if (mc->type == MIX_ON_OFF) { 2851 val = (val != 0); 2852 } else if (mc->type == MIX_SELECTOR) { 2853 if (val < mc->minval || val > mc->maxval) 2854 val = mc->minval; 2855 } else 2856 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval; 2857 DPRINTFN(5, ("val'=%d\n", val)); 2858 return val; 2859} | 2550 if (iot->u.desc == NULL) { 2551 continue; 2552 } 2553 switch (iot->u.desc->bDescriptorSubtype) { 2554 case UDESCSUB_AC_INPUT: 2555 info->bit_input[i / 8] |= (1 << (i % 8)); 2556 break; |
2860 | 2557 |
2861#if defined(__NetBSD__) || defined(__OpenBSD__) 2862static int 2863uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2864 int chan) 2865{ 2866 int val; | 2558 case UDESCSUB_AC_FEATURE: 2559 uaudio_mixer_find_inputs_sub 2560 (root, &iot->u.fu->bSourceId, 1, info); 2561 break; |
2867 | 2562 |
2868 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan)); 2869 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan], 2870 mc->wIndex, MIX_SIZE(mc->type)); 2871 return uaudio_value2bsd(mc, val); | 2563 case UDESCSUB_AC_OUTPUT: 2564 uaudio_mixer_find_inputs_sub 2565 (root, &iot->u.ot->bSourceId, 1, info); 2566 break; 2567 2568 case UDESCSUB_AC_MIXER: 2569 uaudio_mixer_find_inputs_sub 2570 (root, iot->u.mu->baSourceId, 2571 iot->u.mu->bNrInPins, info); 2572 break; 2573 2574 case UDESCSUB_AC_SELECTOR: 2575 uaudio_mixer_find_inputs_sub 2576 (root, iot->u.su->baSourceId, 2577 iot->u.su->bNrInPins, info); 2578 break; 2579 2580 case UDESCSUB_AC_PROCESSING: 2581 uaudio_mixer_find_inputs_sub 2582 (root, iot->u.pu->baSourceId, 2583 iot->u.pu->bNrInPins, info); 2584 break; 2585 2586 case UDESCSUB_AC_EXTENSION: 2587 uaudio_mixer_find_inputs_sub 2588 (root, iot->u.eu->baSourceId, 2589 iot->u.eu->bNrInPins, info); 2590 break; 2591 2592 case UDESCSUB_AC_HEADER: 2593 default: 2594 break; 2595 } 2596 } 2597 info->recurse_level--; |
2872} | 2598} |
2873#endif | |
2874 2875static void | 2599 2600static void |
2876uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2877 int chan, int val) | 2601uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *root, uint8_t id, 2602 uint8_t n_id, struct uaudio_search_result *info) |
2878{ | 2603{ |
2879 val = uaudio_bsd2value(mc, val); 2880 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan], 2881 mc->wIndex, MIX_SIZE(mc->type), val); | 2604 struct uaudio_terminal_node *iot = (root + id); 2605 uint8_t j; 2606 2607 j = n_id; 2608 do { 2609 if ((j != id) && ((root + j)->u.desc) && 2610 ((root + j)->u.desc->bDescriptorSubtype == UDESCSUB_AC_OUTPUT)) { 2611 2612 /* 2613 * "j" (output) <--- virtual wire <--- "id" (input) 2614 * 2615 * if "j" has "id" on the input, then "id" have "j" on 2616 * the output, because they are connected: 2617 */ 2618 if ((root + j)->usr.bit_input[id / 8] & (1 << (id % 8))) { 2619 iot->usr.bit_output[j / 8] |= (1 << (j % 8)); 2620 } 2621 } 2622 } while (j--); |
2882} 2883 | 2623} 2624 |
2884#if defined(__NetBSD__) || defined(__OpenBSD__) 2885static int 2886uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp) | 2625static void 2626uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb2_device *udev, 2627 void *desc) |
2887{ | 2628{ |
2888 struct uaudio_softc *sc; 2889 struct mixerctl *mc; 2890 int i, n, vals[MIX_MAX_CHAN], val; | 2629 const struct usb2_audio_control_descriptor *acdp; 2630 struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev); 2631 const struct usb2_descriptor *dp; 2632 const struct usb2_audio_unit *au; 2633 struct uaudio_terminal_node *iot = NULL; 2634 uint16_t wTotalLen; 2635 uint8_t ID_max = 0; /* inclusive */ 2636 uint8_t i; |
2891 | 2637 |
2892 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev)); 2893 sc = addr; 2894 if (sc->sc_dying) 2895 return EIO; | 2638 desc = usb2_desc_foreach(cd, desc); |
2896 | 2639 |
2897 n = cp->dev - UAC_NCLASSES; 2898 if (n < 0 || n >= sc->sc_nctls) 2899 return ENXIO; 2900 mc = &sc->sc_ctls[n]; | 2640 if (desc == NULL) { 2641 DPRINTF("no Audio Control header\n"); 2642 goto done; 2643 } 2644 acdp = desc; |
2901 | 2645 |
2902 if (mc->type == MIX_ON_OFF) { 2903 if (cp->type != AUDIO_MIXER_ENUM) 2904 return EINVAL; 2905 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2906 } else if (mc->type == MIX_SELECTOR) { 2907 if (cp->type != AUDIO_MIXER_ENUM) 2908 return EINVAL; 2909 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2910 } else { 2911 if (cp->type != AUDIO_MIXER_VALUE) 2912 return (EINVAL); 2913 if (cp->un.value.num_channels != 1 && 2914 cp->un.value.num_channels != mc->nchan) 2915 return EINVAL; 2916 for (i = 0; i < mc->nchan; i++) 2917 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i); 2918 if (cp->un.value.num_channels == 1 && mc->nchan != 1) { 2919 for (val = 0, i = 0; i < mc->nchan; i++) 2920 val += vals[i]; 2921 vals[0] = val / mc->nchan; 2922 } 2923 for (i = 0; i < cp->un.value.num_channels; i++) 2924 cp->un.value.level[i] = vals[i]; | 2646 if ((acdp->bLength < sizeof(*acdp)) || 2647 (acdp->bDescriptorType != UDESC_CS_INTERFACE) || 2648 (acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)) { 2649 DPRINTF("invalid Audio Control header\n"); 2650 goto done; |
2925 } | 2651 } |
2652 /* "wTotalLen" is allowed to be corrupt */ 2653 wTotalLen = UGETW(acdp->wTotalLength) - acdp->bLength; |
|
2926 | 2654 |
2927 return 0; 2928} | 2655 /* get USB audio revision */ 2656 sc->sc_audio_rev = UGETW(acdp->bcdADC); |
2929 | 2657 |
2930static int 2931uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2932{ 2933 struct uaudio_softc *sc; 2934 struct mixerctl *mc; 2935 int i, n, vals[MIX_MAX_CHAN]; | 2658 DPRINTFN(3, "found AC header, vers=%03x, len=%d\n", 2659 sc->sc_audio_rev, wTotalLen); |
2936 | 2660 |
2937 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev)); 2938 sc = addr; 2939 if (sc->sc_dying) 2940 return EIO; | 2661 if (sc->sc_audio_rev != UAUDIO_VERSION) { |
2941 | 2662 |
2942 n = cp->dev - UAC_NCLASSES; 2943 if (n < 0 || n >= sc->sc_nctls) 2944 return ENXIO; 2945 mc = &sc->sc_ctls[n]; | 2663 if (sc->sc_uq_bad_adc) { |
2946 | 2664 |
2947 if (mc->type == MIX_ON_OFF) { 2948 if (cp->type != AUDIO_MIXER_ENUM) 2949 return EINVAL; 2950 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2951 } else if (mc->type == MIX_SELECTOR) { 2952 if (cp->type != AUDIO_MIXER_ENUM) 2953 return EINVAL; 2954 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2955 } else { 2956 if (cp->type != AUDIO_MIXER_VALUE) 2957 return EINVAL; 2958 if (cp->un.value.num_channels == 1) 2959 for (i = 0; i < mc->nchan; i++) 2960 vals[i] = cp->un.value.level[0]; 2961 else if (cp->un.value.num_channels == mc->nchan) 2962 for (i = 0; i < mc->nchan; i++) 2963 vals[i] = cp->un.value.level[i]; 2964 else 2965 return EINVAL; 2966 for (i = 0; i < mc->nchan; i++) 2967 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]); | 2665 } else { 2666 DPRINTF("invalid audio version\n"); 2667 goto done; 2668 } |
2968 } | 2669 } |
2969 return 0; 2970} | 2670 iot = malloc(sizeof(struct uaudio_terminal_node) * 256, M_TEMP, 2671 M_WAITOK | M_ZERO); |
2971 | 2672 |
2972static int 2973uaudio_trigger_input(void *addr, void *start, void *end, int blksize, 2974 void (*intr)(void *), void *arg, 2975 struct audio_params *param) 2976{ 2977 struct uaudio_softc *sc; 2978 struct chan *ch; 2979 usbd_status err; 2980 int i, s; | 2673 if (iot == NULL) { 2674 DPRINTF("no memory!\n"); 2675 goto done; 2676 } 2677 while ((desc = usb2_desc_foreach(cd, desc))) { |
2981 | 2678 |
2982 sc = addr; 2983 if (sc->sc_dying) 2984 return EIO; | 2679 dp = desc; |
2985 | 2680 |
2986 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p " 2987 "blksize=%d\n", sc, start, end, blksize)); 2988 ch = &sc->sc_recchan; 2989 uaudio_chan_set_param(ch, start, end, blksize); 2990 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d " 2991 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2992 ch->fraction)); | 2681 if (dp->bLength > wTotalLen) { 2682 break; 2683 } else { 2684 wTotalLen -= dp->bLength; 2685 } |
2993 | 2686 |
2994 err = uaudio_chan_alloc_buffers(sc, ch); 2995 if (err) 2996 return EIO; | 2687 au = uaudio_mixer_verify_desc(dp, 0); |
2997 | 2688 |
2998 err = uaudio_chan_open(sc, ch); 2999 if (err) { 3000 uaudio_chan_free_buffers(sc, ch); 3001 return EIO; | 2689 if (au) { 2690 iot[au->bUnitId].u.desc = (const void *)au; 2691 if (au->bUnitId > ID_max) { 2692 ID_max = au->bUnitId; 2693 } 2694 } |
3002 } 3003 | 2695 } 2696 |
3004 ch->intr = intr; 3005 ch->arg = arg; | 2697 DPRINTF("Maximum ID=%d\n", ID_max); |
3006 | 2698 |
3007 s = splusb(); 3008 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ 3009 uaudio_chan_rtransfer(ch); 3010 splx(s); | 2699 /* 2700 * determine sourcing inputs for 2701 * all nodes in the tree: 2702 */ 2703 i = ID_max; 2704 do { 2705 uaudio_mixer_find_inputs_sub(iot, &i, 1, &((iot + i)->usr)); 2706 } while (i--); |
3011 | 2707 |
3012 return 0; 3013} | 2708 /* 2709 * determine outputs for 2710 * all nodes in the tree: 2711 */ 2712 i = ID_max; 2713 do { 2714 uaudio_mixer_find_outputs_sub(iot, i, ID_max, &((iot + i)->usr)); 2715 } while (i--); |
3014 | 2716 |
3015static int 3016uaudio_trigger_output(void *addr, void *start, void *end, int blksize, 3017 void (*intr)(void *), void *arg, 3018 struct audio_params *param) 3019{ 3020 struct uaudio_softc *sc; 3021 struct chan *ch; 3022 usbd_status err; 3023 int i, s; | 2717 /* set "id_max" and "root" */ |
3024 | 2718 |
3025 sc = addr; 3026 if (sc->sc_dying) 3027 return EIO; | 2719 i = ID_max; 2720 do { 2721 (iot + i)->usr.id_max = ID_max; 2722 (iot + i)->root = iot; 2723 } while (i--); |
3028 | 2724 |
3029 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p " 3030 "blksize=%d\n", sc, start, end, blksize)); 3031 ch = &sc->sc_playchan; 3032 uaudio_chan_set_param(ch, start, end, blksize); 3033 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d " 3034 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 3035 ch->fraction)); | 2725#if USB_DEBUG 2726 i = ID_max; 2727 do { 2728 uint8_t j; |
3036 | 2729 |
3037 err = uaudio_chan_alloc_buffers(sc, ch); 3038 if (err) 3039 return EIO; | 2730 if (iot[i].u.desc == NULL) { 2731 continue; 2732 } 2733 DPRINTF("id %d:\n", i); |
3040 | 2734 |
3041 err = uaudio_chan_open(sc, ch); 3042 if (err) { 3043 uaudio_chan_free_buffers(sc, ch); 3044 return EIO; 3045 } | 2735 switch (iot[i].u.desc->bDescriptorSubtype) { 2736 case UDESCSUB_AC_INPUT: 2737 DPRINTF(" - AC_INPUT type=%s\n", 2738 uaudio_mixer_get_terminal_name 2739 (UGETW(iot[i].u.it->wTerminalType))); 2740 uaudio_mixer_dump_cluster(i, iot); 2741 break; |
3046 | 2742 |
3047 ch->intr = intr; 3048 ch->arg = arg; | 2743 case UDESCSUB_AC_OUTPUT: 2744 DPRINTF(" - AC_OUTPUT type=%s " 2745 "src=%d\n", uaudio_mixer_get_terminal_name 2746 (UGETW(iot[i].u.ot->wTerminalType)), 2747 iot[i].u.ot->bSourceId); 2748 break; |
3049 | 2749 |
3050 s = splusb(); 3051 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 3052 uaudio_chan_ptransfer(ch); 3053 splx(s); | 2750 case UDESCSUB_AC_MIXER: 2751 DPRINTF(" - AC_MIXER src:\n"); 2752 for (j = 0; j < iot[i].u.mu->bNrInPins; j++) { 2753 DPRINTF(" - %d\n", iot[i].u.mu->baSourceId[j]); 2754 } 2755 uaudio_mixer_dump_cluster(i, iot); 2756 break; |
3054 | 2757 |
3055 return 0; 3056} 3057#endif /* NetBSD or OpenBSD */ | 2758 case UDESCSUB_AC_SELECTOR: 2759 DPRINTF(" - AC_SELECTOR src:\n"); 2760 for (j = 0; j < iot[i].u.su->bNrInPins; j++) { 2761 DPRINTF(" - %d\n", iot[i].u.su->baSourceId[j]); 2762 } 2763 break; |
3058 | 2764 |
3059/* Set up a pipe for a channel. */ 3060static usbd_status 3061uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) 3062{ 3063 struct as_info *as; 3064 int endpt; 3065#if defined(__FreeBSD__) 3066 int locked; 3067#endif 3068 usbd_status err; | 2765 case UDESCSUB_AC_FEATURE: 2766 DPRINTF(" - AC_FEATURE src=%d\n", iot[i].u.fu->bSourceId); 2767 break; |
3069 | 2768 |
3070#if defined(__FreeBSD__) 3071 if (sc->sc_dying) 3072 return EIO; 3073#endif | 2769 case UDESCSUB_AC_PROCESSING: 2770 DPRINTF(" - AC_PROCESSING src:\n"); 2771 for (j = 0; j < iot[i].u.pu->bNrInPins; j++) { 2772 DPRINTF(" - %d\n", iot[i].u.pu->baSourceId[j]); 2773 } 2774 uaudio_mixer_dump_cluster(i, iot); 2775 break; |
3074 | 2776 |
3075 as = &sc->sc_alts[ch->altidx]; 3076 endpt = as->edesc->bEndpointAddress; 3077 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n", 3078 endpt, ch->sample_rate, as->alt)); | 2777 case UDESCSUB_AC_EXTENSION: 2778 DPRINTF(" - AC_EXTENSION src:\n"); 2779 for (j = 0; j < iot[i].u.eu->bNrInPins; j++) { 2780 DPRINTF("%d ", iot[i].u.eu->baSourceId[j]); 2781 } 2782 uaudio_mixer_dump_cluster(i, iot); 2783 break; |
3079 | 2784 |
3080#if defined(__FreeBSD__) 3081 locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0; 3082 if (locked) 3083 CHN_UNLOCK(ch->pcm_ch); 3084#endif 3085 /* Set alternate interface corresponding to the mode. */ 3086 err = usbd_set_interface(as->ifaceh, as->alt); 3087#if defined(__FreeBSD__) 3088 if (locked) 3089 CHN_LOCK(ch->pcm_ch); 3090#endif 3091 if (err) 3092 return err; 3093 3094 /* 3095 * If just one sampling rate is supported, 3096 * no need to call uaudio_set_speed(). 3097 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request. 3098 */ 3099 if (as->asf1desc->bSamFreqType != 1) { 3100 err = uaudio_set_speed(sc, endpt, ch->sample_rate); 3101 if (err) { 3102 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n", 3103 usbd_errstr(err))); | 2785 default: 2786 DPRINTF("unknown audio control (subtype=%d)\n", 2787 iot[i].u.desc->bDescriptorSubtype); |
3104 } | 2788 } |
3105 } | |
3106 | 2789 |
3107 ch->pipe = 0; 3108 ch->sync_pipe = 0; 3109 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt)); 3110 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe); 3111 if (err) 3112 return err; 3113 if (as->edesc1 != NULL) { 3114 endpt = as->edesc1->bEndpointAddress; 3115 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt)); 3116 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe); 3117 } 3118 return err; 3119} | 2790 DPRINTF("Inputs to this ID are:\n"); |
3120 | 2791 |
3121static void 3122uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) 3123{ 3124 struct as_info *as; 3125#if defined(__FreeBSD__) 3126 int locked; | 2792 j = ID_max; 2793 do { 2794 if (iot[i].usr.bit_input[j / 8] & (1 << (j % 8))) { 2795 DPRINTF(" -- ID=%d\n", j); 2796 } 2797 } while (j--); |
3127 | 2798 |
3128 if (sc->sc_dying) 3129 return ; 3130#endif | 2799 DPRINTF("Outputs from this ID are:\n"); |
3131 | 2800 |
3132 as = &sc->sc_alts[ch->altidx]; 3133 as->sc_busy = 0; 3134#if defined(__FreeBSD__) 3135 locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0; 3136 if (locked) 3137 CHN_UNLOCK(ch->pcm_ch); | 2801 j = ID_max; 2802 do { 2803 if (iot[i].usr.bit_output[j / 8] & (1 << (j % 8))) { 2804 DPRINTF(" -- ID=%d\n", j); 2805 } 2806 } while (j--); 2807 2808 } while (i--); |
3138#endif | 2809#endif |
3139 if (sc->sc_nullalt >= 0) { 3140 DPRINTF(("uaudio_chan_close: set null alt=%d\n", 3141 sc->sc_nullalt)); 3142 /* 3143 * The interface will be initialized later again, so an 3144 * error does not hurt. 3145 */ 3146 (void)usbd_set_interface(as->ifaceh, sc->sc_nullalt); 3147 } 3148 if (ch->pipe) { 3149 usbd_abort_pipe(ch->pipe); 3150 usbd_close_pipe(ch->pipe); 3151 } 3152 if (ch->sync_pipe) { 3153 usbd_abort_pipe(ch->sync_pipe); 3154 usbd_close_pipe(ch->sync_pipe); 3155 } 3156#if defined(__FreeBSD__) 3157 if (locked) 3158 CHN_LOCK(ch->pcm_ch); 3159#endif 3160} | |
3161 | 2810 |
3162static usbd_status 3163uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) 3164{ 3165 usbd_xfer_handle xfer; 3166 void *buf; 3167 int i, size; | 2811 /* 2812 * scan the config to create a linked 2813 * list of "mixer" nodes: 2814 */ |
3168 | 2815 |
3169 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES; 3170 for (i = 0; i < UAUDIO_NCHANBUFS; i++) { 3171 xfer = usbd_alloc_xfer(sc->sc_udev); 3172 if (xfer == 0) 3173 goto bad; 3174 ch->chanbufs[i].xfer = xfer; 3175 buf = usbd_alloc_buffer(xfer, size); 3176 if (buf == 0) { 3177 i++; 3178 goto bad; | 2816 i = ID_max; 2817 do { 2818 dp = iot[i].u.desc; 2819 2820 if (dp == NULL) { 2821 continue; |
3179 } | 2822 } |
3180 ch->chanbufs[i].buffer = buf; 3181 ch->chanbufs[i].chan = ch; 3182 } | 2823 DPRINTFN(11, "id=%d subtype=%d\n", 2824 i, dp->bDescriptorSubtype); |
3183 | 2825 |
3184 return USBD_NORMAL_COMPLETION; | 2826 switch (dp->bDescriptorSubtype) { 2827 case UDESCSUB_AC_HEADER: 2828 DPRINTF("unexpected AC header\n"); 2829 break; |
3185 | 2830 |
3186bad: 3187 while (--i >= 0) 3188 /* implicit buffer free */ 3189 usbd_free_xfer(ch->chanbufs[i].xfer); 3190 return USBD_NOMEM; 3191} | 2831 case UDESCSUB_AC_INPUT: 2832 uaudio_mixer_add_input(sc, iot, i); 2833 break; |
3192 | 2834 |
3193static void 3194uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) 3195{ 3196 int i; | 2835 case UDESCSUB_AC_OUTPUT: 2836 uaudio_mixer_add_output(sc, iot, i); 2837 break; |
3197 | 2838 |
3198 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 3199 usbd_free_xfer(ch->chanbufs[i].xfer); 3200} | 2839 case UDESCSUB_AC_MIXER: 2840 uaudio_mixer_add_mixer(sc, iot, i); 2841 break; |
3201 | 2842 |
3202/* Called at splusb() */ 3203static void 3204uaudio_chan_ptransfer(struct chan *ch) 3205{ 3206 struct chanbuf *cb; 3207 int i, n, size, residue, total; | 2843 case UDESCSUB_AC_SELECTOR: 2844 uaudio_mixer_add_selector(sc, iot, i); 2845 break; |
3208 | 2846 |
3209 if (ch->sc->sc_dying) 3210 return; | 2847 case UDESCSUB_AC_FEATURE: 2848 uaudio_mixer_add_feature(sc, iot, i); 2849 break; |
3211 | 2850 |
3212 /* Pick the next channel buffer. */ 3213 cb = &ch->chanbufs[ch->curchanbuf]; 3214 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 3215 ch->curchanbuf = 0; | 2851 case UDESCSUB_AC_PROCESSING: 2852 uaudio_mixer_add_processing(sc, iot, i); 2853 break; |
3216 | 2854 |
3217 /* Compute the size of each frame in the next transfer. */ 3218 residue = ch->residue; 3219 total = 0; 3220 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3221 size = ch->bytes_per_frame; 3222 residue += ch->fraction; 3223 if (residue >= USB_FRAMES_PER_SECOND) { 3224 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 3225 size += ch->sample_size; 3226 residue -= USB_FRAMES_PER_SECOND; 3227 } 3228 cb->sizes[i] = size; 3229 total += size; 3230 } 3231 ch->residue = residue; 3232 cb->size = total; | 2855 case UDESCSUB_AC_EXTENSION: 2856 uaudio_mixer_add_extension(sc, iot, i); 2857 break; |
3233 | 2858 |
3234 /* 3235 * Transfer data from upper layer buffer to channel buffer, taking 3236 * care of wrapping the upper layer buffer. 3237 */ 3238 n = min(total, ch->end - ch->cur); 3239 memcpy(cb->buffer, ch->cur, n); 3240 ch->cur += n; 3241 if (ch->cur >= ch->end) 3242 ch->cur = ch->start; 3243 if (total > n) { 3244 total -= n; 3245 memcpy(cb->buffer + n, ch->cur, total); 3246 ch->cur += total; 3247 } 3248 3249#ifdef USB_DEBUG 3250 if (uaudiodebug > 8) { 3251 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n", 3252 cb->buffer, ch->residue)); 3253 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3254 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); | 2859 default: 2860 DPRINTF("bad AC desc subtype=0x%02x\n", 2861 dp->bDescriptorSubtype); 2862 break; |
3255 } | 2863 } |
3256 } 3257#endif | |
3258 | 2864 |
3259 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer)); 3260 /* Fill the request */ 3261 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 3262 UAUDIO_NFRAMES, USBD_NO_COPY, 3263 uaudio_chan_pintr); | 2865 } while (i--); |
3264 | 2866 |
3265 (void)usbd_transfer(cb->xfer); | 2867done: 2868 if (iot) { 2869 free(iot, M_TEMP); 2870 } |
3266} 3267 | 2871} 2872 |
3268static void 3269uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, 3270 usbd_status status) | 2873static uint16_t 2874uaudio_mixer_get(struct usb2_device *udev, uint8_t what, 2875 struct uaudio_mixer_node *mc) |
3271{ | 2876{ |
3272 struct chanbuf *cb; 3273 struct chan *ch; 3274 u_int32_t count; 3275 int s; | 2877 struct usb2_device_request req; 2878 uint16_t val; 2879 uint16_t len = MIX_SIZE(mc->type); 2880 uint8_t data[4]; 2881 usb2_error_t err; |
3276 | 2882 |
3277 cb = priv; 3278 ch = cb->chan; 3279 /* Return if we are aborting. */ 3280 if (status == USBD_CANCELLED) 3281 return; 3282 3283 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3284 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n", 3285 count, ch->transferred)); 3286#ifdef DIAGNOSTIC 3287 if (count != cb->size) { 3288 printf("uaudio_chan_pintr: count(%d) != size(%d)\n", 3289 count, cb->size); | 2883 if (mc->wValue[0] == -1) { 2884 return (0); |
3290 } | 2885 } |
3291#endif | 2886 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2887 req.bRequest = what; 2888 USETW(req.wValue, mc->wValue[0]); 2889 USETW(req.wIndex, mc->wIndex); 2890 USETW(req.wLength, len); |
3292 | 2891 |
3293 ch->transferred += cb->size; 3294#if defined(__FreeBSD__) 3295 /* s = spltty(); */ 3296 s = splhigh(); 3297 chn_intr(ch->pcm_ch); 3298 splx(s); 3299#else 3300 s = splaudio(); 3301 /* Call back to upper layer */ 3302 while (ch->transferred >= ch->blksize) { 3303 ch->transferred -= ch->blksize; 3304 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n", 3305 ch->intr, ch->arg)); 3306 ch->intr(ch->arg); | 2892 err = usb2_do_request(udev, &Giant, &req, data); 2893 if (err) { 2894 DPRINTF("err=%s\n", usb2_errstr(err)); 2895 return (0); |
3307 } | 2896 } |
3308 splx(s); 3309#endif | 2897 if (len < 1) { 2898 data[0] = 0; 2899 } 2900 if (len < 2) { 2901 data[1] = 0; 2902 } 2903 val = (data[0] | (data[1] << 8)); |
3310 | 2904 |
3311 /* start next transfer */ 3312 uaudio_chan_ptransfer(ch); | 2905 DPRINTFN(3, "val=%d\n", val); 2906 2907 return (val); |
3313} 3314 | 2908} 2909 |
3315/* Called at splusb() */ | |
3316static void | 2910static void |
3317uaudio_chan_rtransfer(struct chan *ch) | 2911uaudio_mixer_write_cfg_callback(struct usb2_xfer *xfer) |
3318{ | 2912{ |
3319 struct chanbuf *cb; 3320 int i, size, residue, total; | 2913 struct usb2_device_request req; 2914 struct uaudio_softc *sc = xfer->priv_sc; 2915 struct uaudio_mixer_node *mc = sc->sc_mixer_curr; 2916 uint16_t len; 2917 uint8_t repeat = 1; 2918 uint8_t update; 2919 uint8_t chan; 2920 uint8_t buf[2]; |
3321 | 2921 |
3322 if (ch->sc->sc_dying) 3323 return; | 2922 DPRINTF("\n"); |
3324 | 2923 |
3325 /* Pick the next channel buffer. */ 3326 cb = &ch->chanbufs[ch->curchanbuf]; 3327 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 3328 ch->curchanbuf = 0; | 2924 switch (USB_GET_STATE(xfer)) { 2925 case USB_ST_TRANSFERRED: 2926tr_transferred: 2927 case USB_ST_SETUP: 2928tr_setup: |
3329 | 2929 |
3330 /* Compute the size of each frame in the next transfer. */ 3331 residue = ch->residue; 3332 total = 0; 3333 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3334 size = ch->bytes_per_frame; 3335 cb->sizes[i] = size; 3336 cb->offsets[i] = total; 3337 total += size; 3338 } 3339 ch->residue = residue; 3340 cb->size = total; 3341 3342#ifdef USB_DEBUG 3343 if (uaudiodebug > 8) { 3344 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n", 3345 cb->buffer, ch->residue)); 3346 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3347 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); | 2930 if (mc == NULL) { 2931 mc = sc->sc_mixer_root; 2932 sc->sc_mixer_curr = mc; 2933 sc->sc_mixer_chan = 0; 2934 repeat = 0; |
3348 } | 2935 } |
3349 } 3350#endif | 2936 while (mc) { 2937 while (sc->sc_mixer_chan < mc->nchan) { |
3351 | 2938 |
3352 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); 3353 /* Fill the request */ 3354 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 3355 UAUDIO_NFRAMES, USBD_NO_COPY, 3356 uaudio_chan_rintr); | 2939 len = MIX_SIZE(mc->type); |
3357 | 2940 |
3358 (void)usbd_transfer(cb->xfer); 3359} | 2941 chan = sc->sc_mixer_chan; |
3360 | 2942 |
3361static void 3362uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, 3363 usbd_status status) 3364{ 3365 struct chanbuf *cb = priv; 3366 struct chan *ch = cb->chan; 3367 u_int32_t count; 3368 int s, i, n, frsize; | 2943 sc->sc_mixer_chan++; |
3369 | 2944 |
3370 /* Return if we are aborting. */ 3371 if (status == USBD_CANCELLED) 3372 return; | 2945 update = ((mc->update[chan / 8] & (1 << (chan % 8))) && 2946 (mc->wValue[chan] != -1)); |
3373 | 2947 |
3374 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3375 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n", 3376 count, ch->transferred)); | 2948 mc->update[chan / 8] &= ~(1 << (chan % 8)); |
3377 | 2949 |
3378 /* count < cb->size is normal for asynchronous source */ 3379#ifdef DIAGNOSTIC 3380 if (count > cb->size) { 3381 printf("uaudio_chan_rintr: count(%d) > size(%d)\n", 3382 count, cb->size); 3383 } 3384#endif | 2950 if (update) { |
3385 | 2951 |
3386 /* 3387 * Transfer data from channel buffer to upper layer buffer, taking 3388 * care of wrapping the upper layer buffer. 3389 */ 3390 for(i = 0; i < UAUDIO_NFRAMES; i++) { 3391 frsize = cb->sizes[i]; 3392 n = min(frsize, ch->end - ch->cur); 3393 memcpy(ch->cur, cb->buffer + cb->offsets[i], n); 3394 ch->cur += n; 3395 if (ch->cur >= ch->end) 3396 ch->cur = ch->start; 3397 if (frsize > n) { 3398 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n, 3399 frsize - n); 3400 ch->cur += frsize - n; 3401 } 3402 } | 2952 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 2953 req.bRequest = SET_CUR; 2954 USETW(req.wValue, mc->wValue[chan]); 2955 USETW(req.wIndex, mc->wIndex); 2956 USETW(req.wLength, len); |
3403 | 2957 |
3404 /* Call back to upper layer */ 3405 ch->transferred += count; 3406#if defined(__FreeBSD__) 3407 s = spltty(); 3408 chn_intr(ch->pcm_ch); 3409 splx(s); 3410#else 3411 s = splaudio(); 3412 while (ch->transferred >= ch->blksize) { 3413 ch->transferred -= ch->blksize; 3414 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n", 3415 ch->intr, ch->arg)); 3416 ch->intr(ch->arg); 3417 } 3418 splx(s); 3419#endif | 2958 if (len > 0) { 2959 buf[0] = (mc->wData[chan] & 0xFF); 2960 } 2961 if (len > 1) { 2962 buf[1] = (mc->wData[chan] >> 8) & 0xFF; 2963 } 2964 usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); 2965 usb2_copy_in(xfer->frbuffers + 1, 0, buf, len); |
3420 | 2966 |
3421 /* start next transfer */ 3422 uaudio_chan_rtransfer(ch); 3423} | 2967 xfer->frlengths[0] = sizeof(req); 2968 xfer->frlengths[1] = len; 2969 xfer->nframes = xfer->frlengths[1] ? 2 : 1; 2970 usb2_start_hardware(xfer); 2971 return; 2972 } 2973 } |
3424 | 2974 |
3425#if defined(__NetBSD__) || defined(__OpenBSD__) 3426static void 3427uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param, 3428 int maxpktsize) 3429{ 3430 int samples_per_frame, sample_size; | 2975 mc = mc->next; 2976 sc->sc_mixer_curr = mc; 2977 sc->sc_mixer_chan = 0; 2978 } |
3431 | 2979 |
3432 ch->altidx = altidx; 3433 sample_size = param->precision * param->factor * param->hw_channels / 8; 3434 samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND; 3435 ch->sample_size = sample_size; 3436 ch->sample_rate = param->hw_sample_rate; 3437 if (maxpktsize == 0) { 3438 ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND; 3439 ch->bytes_per_frame = samples_per_frame * sample_size; 3440 } else { 3441 ch->fraction = 0; 3442 ch->bytes_per_frame = maxpktsize; | 2980 if (repeat) { 2981 goto tr_setup; 2982 } 2983 break; 2984 2985 default: /* Error */ 2986 DPRINTF("error=%s\n", usb2_errstr(xfer->error)); 2987 if (xfer->error == USB_ERR_CANCELLED) { 2988 /* do nothing - we are detaching */ 2989 break; 2990 } 2991 goto tr_transferred; |
3443 } | 2992 } |
3444 ch->residue = 0; | |
3445} 3446 | 2993} 2994 |
3447static void 3448uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize) | 2995static usb2_error_t 2996uaudio_set_speed(struct usb2_device *udev, uint8_t endpt, uint32_t speed) |
3449{ | 2997{ |
3450 ch->start = start; 3451 ch->end = end; 3452 ch->cur = start; 3453 ch->blksize = blksize; 3454 ch->transferred = 0; 3455 ch->curchanbuf = 0; 3456} | 2998 struct usb2_device_request req; 2999 uint8_t data[3]; |
3457 | 3000 |
3458static void 3459uaudio_get_minmax_rates(int nalts, const struct as_info *alts, 3460 const struct audio_params *p, int mode, 3461 u_long *min, u_long *max) 3462{ 3463 const struct usb_audio_streaming_type1_descriptor *a1d; 3464 int i, j; | 3001 DPRINTFN(6, "endpt=%d speed=%u\n", endpt, speed); |
3465 | 3002 |
3466 *min = ULONG_MAX; 3467 *max = 0; 3468 for (i = 0; i < nalts; i++) { 3469 a1d = alts[i].asf1desc; 3470 if (alts[i].sc_busy) 3471 continue; 3472 if (p->hw_channels != a1d->bNrChannels) 3473 continue; 3474 if (p->hw_precision != a1d->bBitResolution) 3475 continue; 3476 if (p->hw_encoding != alts[i].encoding) 3477 continue; 3478 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress)) 3479 continue; 3480 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3481 DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n", 3482 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3483 if (UA_SAMP_LO(a1d) < *min) 3484 *min = UA_SAMP_LO(a1d); 3485 if (UA_SAMP_HI(a1d) > *max) 3486 *max = UA_SAMP_HI(a1d); 3487 } else { 3488 for (j = 0; j < a1d->bSamFreqType; j++) { 3489 DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n", 3490 j, UA_GETSAMP(a1d, j))); 3491 if (UA_GETSAMP(a1d, j) < *min) 3492 *min = UA_GETSAMP(a1d, j); 3493 if (UA_GETSAMP(a1d, j) > *max) 3494 *max = UA_GETSAMP(a1d, j); 3495 } 3496 } 3497 } | 3003 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 3004 req.bRequest = SET_CUR; 3005 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 3006 USETW(req.wIndex, endpt); 3007 USETW(req.wLength, 3); 3008 data[0] = speed; 3009 data[1] = speed >> 8; 3010 data[2] = speed >> 16; 3011 3012 return (usb2_do_request(udev, &Giant, &req, data)); |
3498} 3499 3500static int | 3013} 3014 3015static int |
3501uaudio_match_alt_sub(int nalts, const struct as_info *alts, 3502 const struct audio_params *p, int mode, u_long rate) | 3016uaudio_mixer_signext(uint8_t type, int val) |
3503{ | 3017{ |
3504 const struct usb_audio_streaming_type1_descriptor *a1d; 3505 int i, j; 3506 3507 DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n", 3508 rate, p->hw_channels)); 3509 for (i = 0; i < nalts; i++) { 3510 a1d = alts[i].asf1desc; 3511 if (alts[i].sc_busy) 3512 continue; 3513 if (p->hw_channels != a1d->bNrChannels) 3514 continue; 3515 if (p->hw_precision != a1d->bBitResolution) 3516 continue; 3517 if (p->hw_encoding != alts[i].encoding) 3518 continue; 3519 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress)) 3520 continue; 3521 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3522 DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n", 3523 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3524 if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d)) 3525 return i; | 3018 if (!MIX_UNSIGNED(type)) { 3019 if (MIX_SIZE(type) == 2) { 3020 val = (int16_t)val; |
3526 } else { | 3021 } else { |
3527 for (j = 0; j < a1d->bSamFreqType; j++) { 3528 DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n", 3529 j, UA_GETSAMP(a1d, j))); 3530 /* XXX allow for some slack */ 3531 if (UA_GETSAMP(a1d, j) == rate) 3532 return i; 3533 } | 3022 val = (int8_t)val; |
3534 } 3535 } | 3023 } 3024 } |
3536 return -1; | 3025 return (val); |
3537} 3538 3539static int | 3026} 3027 3028static int |
3540uaudio_match_alt_chan(int nalts, const struct as_info *alts, 3541 struct audio_params *p, int mode) | 3029uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val) |
3542{ | 3030{ |
3543 int i, n; 3544 u_long min, max; 3545 u_long rate; 3546 3547 /* Exact match */ 3548 DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n", 3549 p->sample_rate, p->hw_channels, p->hw_precision)); 3550 i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate); 3551 if (i >= 0) 3552 return i; 3553 3554 uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max); 3555 DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max)); 3556 if (max <= 0) 3557 return -1; 3558 /* Search for biggers */ 3559 n = 2; 3560 while ((rate = p->sample_rate * n++) <= max) { 3561 i = uaudio_match_alt_sub(nalts, alts, p, mode, rate); 3562 if (i >= 0) { 3563 p->hw_sample_rate = rate; 3564 return i; | 3031 if (mc->type == MIX_ON_OFF) { 3032 val = (val != 0); 3033 } else if (mc->type == MIX_SELECTOR) { 3034 if ((val < mc->minval) || 3035 (val > mc->maxval)) { 3036 val = mc->minval; |
3565 } | 3037 } |
3566 } 3567 if (p->sample_rate >= min) { 3568 i = uaudio_match_alt_sub(nalts, alts, p, mode, max); 3569 if (i >= 0) { 3570 p->hw_sample_rate = max; 3571 return i; 3572 } | |
3573 } else { | 3038 } else { |
3574 i = uaudio_match_alt_sub(nalts, alts, p, mode, min); 3575 if (i >= 0) { 3576 p->hw_sample_rate = min; 3577 return i; 3578 } | 3039 val = (((val + (mc->delta / 2)) * mc->mul) / 255) + mc->minval; |
3579 } | 3040 } |
3580 return -1; | 3041 3042 DPRINTFN(6, "type=0x%03x val=%d min=%d max=%d val=%d\n", 3043 mc->type, val, mc->minval, mc->maxval, val); 3044 return (val); |
3581} 3582 | 3045} 3046 |
3583static int 3584uaudio_match_alt(int nalts, const struct as_info *alts, 3585 struct audio_params *p, int mode) | 3047static void 3048uaudio_mixer_ctl_set(struct uaudio_softc *sc, struct uaudio_mixer_node *mc, 3049 uint8_t chan, int32_t val) |
3586{ | 3050{ |
3587 int i, n; | 3051 val = uaudio_mixer_bsd2value(mc, val); |
3588 | 3052 |
3589 mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN; 3590 i = uaudio_match_alt_chan(nalts, alts, p, mode); 3591 if (i >= 0) 3592 return i; | 3053 mc->update[chan / 8] |= (1 << (chan % 8)); 3054 mc->wData[chan] = val; |
3593 | 3055 |
3594 for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) { 3595 p->hw_channels = n; 3596 i = uaudio_match_alt_chan(nalts, alts, p, mode); 3597 if (i >= 0) 3598 return i; 3599 } | 3056 /* start the transfer, if not already started */ |
3600 | 3057 |
3601 if (p->channels != 2) 3602 return -1; 3603 p->hw_channels = 1; 3604 return uaudio_match_alt_chan(nalts, alts, p, mode); | 3058 usb2_transfer_start(sc->sc_mixer_xfer[0]); |
3605} 3606 | 3059} 3060 |
3607static int 3608uaudio_set_params(void *addr, int setmode, int usemode, 3609 struct audio_params *play, struct audio_params *rec) | 3061static void 3062uaudio_mixer_init(struct uaudio_softc *sc) |
3610{ | 3063{ |
3611 struct uaudio_softc *sc; 3612 int flags; 3613 int factor; 3614 int enc, i; 3615 int paltidx, raltidx; 3616 void (*swcode)(void *, u_char *buf, int cnt); 3617 struct audio_params *p; 3618 int mode; | 3064 struct uaudio_mixer_node *mc; 3065 int32_t i; |
3619 | 3066 |
3620 sc = addr; 3621 flags = sc->sc_altflags; 3622 paltidx = -1; 3623 raltidx = -1; 3624 if (sc->sc_dying) 3625 return EIO; | 3067 for (mc = sc->sc_mixer_root; mc; 3068 mc = mc->next) { |
3626 | 3069 |
3627 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) || 3628 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL)) 3629 return EBUSY; | 3070 if (mc->ctl != SOUND_MIXER_NRDEVICES) { 3071 /* 3072 * Set device mask bits. See 3073 * /usr/include/machine/soundcard.h 3074 */ 3075 sc->sc_mix_info |= (1 << mc->ctl); 3076 } 3077 if ((mc->ctl == SOUND_MIXER_NRDEVICES) && 3078 (mc->type == MIX_SELECTOR)) { |
3630 | 3079 |
3631 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3632 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0; 3633 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3634 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0; 3635 3636 /* Some uaudio devices are unidirectional. Don't try to find a 3637 matching mode for the unsupported direction. */ 3638 setmode &= sc->sc_mode; 3639 3640 for (mode = AUMODE_RECORD; mode != -1; 3641 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 3642 if ((setmode & mode) == 0) 3643 continue; 3644 3645 p = (mode == AUMODE_PLAY) ? play : rec; 3646 3647 factor = 1; 3648 swcode = 0; 3649 enc = p->encoding; 3650 switch (enc) { 3651 case AUDIO_ENCODING_SLINEAR_BE: 3652 /* FALLTHROUGH */ 3653 case AUDIO_ENCODING_SLINEAR_LE: 3654 if (enc == AUDIO_ENCODING_SLINEAR_BE 3655 && p->precision == 16 && (flags & HAS_16)) { 3656 swcode = swap_bytes; 3657 enc = AUDIO_ENCODING_SLINEAR_LE; 3658 } else if (p->precision == 8) { 3659 if (flags & HAS_8) { 3660 /* No conversion */ 3661 } else if (flags & HAS_8U) { 3662 swcode = change_sign8; 3663 enc = AUDIO_ENCODING_ULINEAR_LE; 3664 } else if (flags & HAS_16) { 3665 factor = 2; 3666 p->hw_precision = 16; 3667 if (mode == AUMODE_PLAY) 3668 swcode = linear8_to_linear16_le; 3669 else 3670 swcode = linear16_to_linear8_le; | 3080 for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) { 3081 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) { 3082 continue; |
3671 } | 3083 } |
3084 sc->sc_recsrc_info |= 1 << mc->slctrtype[i - 1]; |
|
3672 } | 3085 } |
3673 break; 3674 case AUDIO_ENCODING_ULINEAR_BE: 3675 /* FALLTHROUGH */ 3676 case AUDIO_ENCODING_ULINEAR_LE: 3677 if (p->precision == 16) { 3678 if (enc == AUDIO_ENCODING_ULINEAR_LE) 3679 swcode = change_sign16_le; 3680 else if (mode == AUMODE_PLAY) 3681 swcode = swap_bytes_change_sign16_le; 3682 else 3683 swcode = change_sign16_swap_bytes_le; 3684 enc = AUDIO_ENCODING_SLINEAR_LE; 3685 } else if (p->precision == 8) { 3686 if (flags & HAS_8U) { 3687 /* No conversion */ 3688 } else if (flags & HAS_8) { 3689 swcode = change_sign8; 3690 enc = AUDIO_ENCODING_SLINEAR_LE; 3691 } else if (flags & HAS_16) { 3692 factor = 2; 3693 p->hw_precision = 16; 3694 enc = AUDIO_ENCODING_SLINEAR_LE; 3695 if (mode == AUMODE_PLAY) 3696 swcode = ulinear8_to_slinear16_le; 3697 else 3698 swcode = slinear16_to_ulinear8_le; 3699 } 3700 } 3701 break; 3702 case AUDIO_ENCODING_ULAW: 3703 if (flags & HAS_MULAW) 3704 break; 3705 if (flags & HAS_16) { 3706 if (mode == AUMODE_PLAY) 3707 swcode = mulaw_to_slinear16_le; 3708 else 3709 swcode = slinear16_to_mulaw_le; 3710 factor = 2; 3711 enc = AUDIO_ENCODING_SLINEAR_LE; 3712 p->hw_precision = 16; 3713 } else if (flags & HAS_8U) { 3714 if (mode == AUMODE_PLAY) 3715 swcode = mulaw_to_ulinear8; 3716 else 3717 swcode = ulinear8_to_mulaw; 3718 enc = AUDIO_ENCODING_ULINEAR_LE; 3719 } else if (flags & HAS_8) { 3720 if (mode == AUMODE_PLAY) 3721 swcode = mulaw_to_slinear8; 3722 else 3723 swcode = slinear8_to_mulaw; 3724 enc = AUDIO_ENCODING_SLINEAR_LE; 3725 } else 3726 return (EINVAL); 3727 break; 3728 case AUDIO_ENCODING_ALAW: 3729 if (flags & HAS_ALAW) 3730 break; 3731 if (mode == AUMODE_PLAY && (flags & HAS_16)) { 3732 swcode = alaw_to_slinear16_le; 3733 factor = 2; 3734 enc = AUDIO_ENCODING_SLINEAR_LE; 3735 p->hw_precision = 16; 3736 } else if (flags & HAS_8U) { 3737 if (mode == AUMODE_PLAY) 3738 swcode = alaw_to_ulinear8; 3739 else 3740 swcode = ulinear8_to_alaw; 3741 enc = AUDIO_ENCODING_ULINEAR_LE; 3742 } else if (flags & HAS_8) { 3743 if (mode == AUMODE_PLAY) 3744 swcode = alaw_to_slinear8; 3745 else 3746 swcode = slinear8_to_alaw; 3747 enc = AUDIO_ENCODING_SLINEAR_LE; 3748 } else 3749 return (EINVAL); 3750 break; 3751 default: 3752 return (EINVAL); | |
3753 } | 3086 } |
3754 /* XXX do some other conversions... */ | 3087 } 3088} |
3755 | 3089 |
3756 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n", 3757 p->channels, p->hw_precision, enc, p->sample_rate)); | 3090int 3091uaudio_mixer_init_sub(struct uaudio_softc *sc, struct snd_mixer *m) 3092{ 3093 DPRINTF("\n"); |
3758 | 3094 |
3759 p->hw_encoding = enc; 3760 i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode); 3761 if (i < 0) 3762 return (EINVAL); 3763 3764 p->sw_code = swcode; 3765 p->factor = factor; 3766 3767 if (mode == AUMODE_PLAY) 3768 paltidx = i; 3769 else 3770 raltidx = i; | 3095 if (usb2_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index, 3096 sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc, 3097 mixer_get_lock(m))) { 3098 DPRINTFN(0, "could not allocate USB " 3099 "transfer for audio mixer!\n"); 3100 return (ENOMEM); |
3771 } | 3101 } |
3772 3773 if ((setmode & AUMODE_PLAY)) { 3774 /* XXX abort transfer if currently happening? */ 3775 uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0); | 3102 if (!(sc->sc_mix_info & SOUND_MASK_VOLUME)) { 3103 mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM); 3104 mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE); |
3776 } | 3105 } |
3777 if ((setmode & AUMODE_RECORD)) { 3778 /* XXX abort transfer if currently happening? */ 3779 uaudio_chan_init(&sc->sc_recchan, raltidx, rec, 3780 UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize)); 3781 } | 3106 mix_setdevs(m, sc->sc_mix_info); 3107 mix_setrecdevs(m, sc->sc_recsrc_info); 3108 return (0); 3109} |
3782 | 3110 |
3783 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3784 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1; 3785 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3786 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1; | 3111int 3112uaudio_mixer_uninit_sub(struct uaudio_softc *sc) 3113{ 3114 DPRINTF("\n"); |
3787 | 3115 |
3788 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n", 3789 sc->sc_playchan.altidx, sc->sc_recchan.altidx, 3790 (sc->sc_playchan.altidx >= 0) 3791 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting 3792 : -1, 3793 (sc->sc_recchan.altidx >= 0) 3794 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting 3795 : -1)); | 3116 usb2_transfer_unsetup(sc->sc_mixer_xfer, 1); |
3796 | 3117 |
3797 return 0; | 3118 return (0); |
3798} | 3119} |
3799#endif /* NetBSD or OpenBSD */ | |
3800 | 3120 |
3801static usbd_status 3802uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed) | 3121void 3122uaudio_mixer_set(struct uaudio_softc *sc, unsigned type, 3123 unsigned left, unsigned right) |
3803{ | 3124{ |
3804 usb_device_request_t req; 3805 uint8_t data[3]; | 3125 struct uaudio_mixer_node *mc; |
3806 | 3126 |
3807 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed)); 3808 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 3809 req.bRequest = SET_CUR; 3810 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 3811 USETW(req.wIndex, endpt); 3812 USETW(req.wLength, 3); 3813 data[0] = speed; 3814 data[1] = speed >> 8; 3815 data[2] = speed >> 16; | 3127 for (mc = sc->sc_mixer_root; mc; 3128 mc = mc->next) { |
3816 | 3129 |
3817#if defined(__FreeBSD__) 3818 if (sc->async != 0) 3819 return usbd_do_request_async(sc->sc_udev, &req, data); 3820#endif 3821 return usbd_do_request(sc->sc_udev, &req, data); | 3130 if (mc->ctl == type) { 3131 if (mc->nchan == 2) { 3132 /* set Right */ 3133 uaudio_mixer_ctl_set(sc, mc, 1, (int)(right * 255) / 100); 3134 } 3135 /* set Left or Mono */ 3136 uaudio_mixer_ctl_set(sc, mc, 0, (int)(left * 255) / 100); 3137 } 3138 } |
3822} 3823 | 3139} 3140 |
3824 3825#if defined(__FreeBSD__) 3826/************************************************************/ 3827int 3828uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode) | 3141uint32_t 3142uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src) |
3829{ | 3143{ |
3830 int i, j, enc; 3831 int samples_per_frame, sample_size; | 3144 struct uaudio_mixer_node *mc; 3145 uint32_t mask; 3146 uint32_t temp; 3147 int32_t i; |
3832 | 3148 |
3833 if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL)) 3834 return (-1); | 3149 for (mc = sc->sc_mixer_root; mc; 3150 mc = mc->next) { |
3835 | 3151 |
3836 switch(ch->format & 0x000FFFFF) { 3837 case AFMT_U8: 3838 enc = AUDIO_ENCODING_ULINEAR_LE; 3839 ch->precision = 8; 3840 break; 3841 case AFMT_S8: 3842 enc = AUDIO_ENCODING_SLINEAR_LE; 3843 ch->precision = 8; 3844 break; 3845 case AFMT_A_LAW: /* ? */ 3846 enc = AUDIO_ENCODING_ALAW; 3847 ch->precision = 8; 3848 break; 3849 case AFMT_MU_LAW: /* ? */ 3850 enc = AUDIO_ENCODING_ULAW; 3851 ch->precision = 8; 3852 break; 3853 case AFMT_S16_LE: 3854 enc = AUDIO_ENCODING_SLINEAR_LE; 3855 ch->precision = 16; 3856 break; 3857 case AFMT_S16_BE: 3858 enc = AUDIO_ENCODING_SLINEAR_BE; 3859 ch->precision = 16; 3860 break; 3861 case AFMT_U16_LE: 3862 enc = AUDIO_ENCODING_ULINEAR_LE; 3863 ch->precision = 16; 3864 break; 3865 case AFMT_U16_BE: 3866 enc = AUDIO_ENCODING_ULINEAR_BE; 3867 ch->precision = 16; 3868 break; 3869 case AFMT_S24_LE: 3870 enc = AUDIO_ENCODING_SLINEAR_LE; 3871 ch->precision = 24; 3872 break; 3873 case AFMT_S24_BE: 3874 enc = AUDIO_ENCODING_SLINEAR_BE; 3875 ch->precision = 24; 3876 break; 3877 case AFMT_U24_LE: 3878 enc = AUDIO_ENCODING_ULINEAR_LE; 3879 ch->precision = 24; 3880 break; 3881 case AFMT_U24_BE: 3882 enc = AUDIO_ENCODING_ULINEAR_BE; 3883 ch->precision = 24; 3884 break; 3885 case AFMT_S32_LE: 3886 enc = AUDIO_ENCODING_SLINEAR_LE; 3887 ch->precision = 32; 3888 break; 3889 case AFMT_S32_BE: 3890 enc = AUDIO_ENCODING_SLINEAR_BE; 3891 ch->precision = 32; 3892 break; 3893 case AFMT_U32_LE: 3894 enc = AUDIO_ENCODING_ULINEAR_LE; 3895 ch->precision = 32; 3896 break; 3897 case AFMT_U32_BE: 3898 enc = AUDIO_ENCODING_ULINEAR_BE; 3899 ch->precision = 32; 3900 break; 3901 default: 3902 enc = 0; 3903 ch->precision = 16; 3904 printf("Unknown format %x\n", ch->format); 3905 } | 3152 if ((mc->ctl == SOUND_MIXER_NRDEVICES) && 3153 (mc->type == MIX_SELECTOR)) { |
3906 | 3154 |
3907 if (ch->format & AFMT_STEREO) { 3908 ch->channels = 2; 3909 } else { 3910 ch->channels = 1; 3911 } | 3155 /* compute selector mask */ |
3912 | 3156 |
3913/* for (mode = ...... */ 3914 for (i = 0; i < sc->sc_nalts; i++) { 3915 const struct usb_audio_streaming_type1_descriptor *a1d = 3916 sc->sc_alts[i].asf1desc; 3917 if (ch->channels == a1d->bNrChannels && 3918 ch->precision == a1d->bBitResolution && 3919#if 0 3920 enc == sc->sc_alts[i].encoding) { 3921#else 3922 enc == sc->sc_alts[i].encoding && 3923 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) == 3924 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) { 3925#endif 3926 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3927 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n", 3928 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3929 if (UA_SAMP_LO(a1d) <= ch->sample_rate && 3930 ch->sample_rate <= UA_SAMP_HI(a1d)) { 3931 if (mode == AUMODE_PLAY) 3932 sc->sc_playchan.altidx = i; 3933 else 3934 sc->sc_recchan.altidx = i; 3935 goto found; 3936 } 3937 } else { 3938 for (j = 0; j < a1d->bSamFreqType; j++) { 3939 DPRINTFN(2,("uaudio_set_params: disc #" 3940 "%d: %d\n", j, UA_GETSAMP(a1d, j))); 3941 /* XXX allow for some slack */ 3942 if (UA_GETSAMP(a1d, j) == 3943 ch->sample_rate) { 3944 if (mode == AUMODE_PLAY) 3945 sc->sc_playchan.altidx = i; 3946 else 3947 sc->sc_recchan.altidx = i; 3948 goto found; 3949 } 3950 } 3951 } | 3157 mask = 0; 3158 for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) { 3159 mask |= (1 << mc->slctrtype[i - 1]); |
3952 } | 3160 } |
3953 } 3954 /* return (EINVAL); */ 3955 if (mode == AUMODE_PLAY) 3956 printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate); 3957 else 3958 printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate); 3959 return (-1); | |
3960 | 3161 |
3961 found: 3962#if 0 /* XXX */ 3963 p->sw_code = swcode; 3964 p->factor = factor; 3965 if (usemode == mode) 3966 sc->sc_curaltidx = i; 3967#endif 3968/* } */ | 3162 temp = mask & src; 3163 if (temp == 0) { 3164 continue; 3165 } 3166 /* find the first set bit */ 3167 temp = (-temp) & temp; |
3969 | 3168 |
3970 sample_size = ch->precision * ch->channels / 8; 3971 samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND; 3972 ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND; 3973 ch->sample_size = sample_size; 3974 ch->bytes_per_frame = samples_per_frame * sample_size; 3975 ch->residue = 0; | 3169 /* update "src" */ 3170 src &= ~mask; 3171 src |= temp; |
3976 | 3172 |
3977 ch->cur = ch->start; 3978 ch->transferred = 0; 3979 ch->curchanbuf = 0; 3980 return (0); | 3173 for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) { 3174 if (temp != (1 << mc->slctrtype[i - 1])) { 3175 continue; 3176 } 3177 uaudio_mixer_ctl_set(sc, mc, 0, i); 3178 break; 3179 } 3180 } 3181 } 3182 return (src); |
3981} 3982 | 3183} 3184 |
3983struct uaudio_conversion { 3984 uint8_t uaudio_fmt; 3985 uint8_t uaudio_prec; 3986 uint32_t freebsd_fmt; 3987}; | 3185/*========================================================================* 3186 * MIDI support routines 3187 *========================================================================*/ |
3988 | 3188 |
3989const struct uaudio_conversion const accepted_conversion[] = { 3990 {AUDIO_ENCODING_ULINEAR_LE, 8, AFMT_U8}, 3991 {AUDIO_ENCODING_ULINEAR_LE, 16, AFMT_U16_LE}, 3992 {AUDIO_ENCODING_ULINEAR_LE, 24, AFMT_U24_LE}, 3993 {AUDIO_ENCODING_ULINEAR_LE, 32, AFMT_U32_LE}, 3994 {AUDIO_ENCODING_ULINEAR_BE, 16, AFMT_U16_BE}, 3995 {AUDIO_ENCODING_ULINEAR_BE, 24, AFMT_U24_BE}, 3996 {AUDIO_ENCODING_ULINEAR_BE, 32, AFMT_U32_BE}, 3997 {AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8}, 3998 {AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE}, 3999 {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE}, 4000 {AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE}, 4001 {AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE}, 4002 {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE}, 4003 {AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE}, 4004 {AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW}, 4005 {AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW}, 4006 {0,0,0} 4007}; | 3189static void 3190umidi_read_clear_stall_callback(struct usb2_xfer *xfer) 3191{ 3192 struct umidi_chan *chan = xfer->priv_sc; 3193 struct usb2_xfer *xfer_other = chan->xfer[1]; |
4008 | 3194 |
4009unsigned 4010uaudio_query_formats(device_t dev, int reqdir, unsigned maxfmt, struct pcmchan_caps *cap) | 3195 if (usb2_clear_stall_callback(xfer, xfer_other)) { 3196 DPRINTF("stall cleared\n"); 3197 chan->flags &= ~UMIDI_FLAG_READ_STALL; 3198 usb2_transfer_start(xfer_other); 3199 } 3200} 3201 3202static void 3203umidi_bulk_read_callback(struct usb2_xfer *xfer) |
4011{ | 3204{ |
4012 struct uaudio_softc *sc; 4013 const struct usb_audio_streaming_type1_descriptor *asf1d; 4014 const struct uaudio_conversion *iterator; 4015 unsigned fmtcount, foundcount; 4016 u_int32_t fmt; 4017 uint8_t format, numchan, subframesize, prec, dir, iscontinuous; 4018 int freq, freq_min, freq_max; 4019 char *numchannel_descr; 4020 char freq_descr[64]; 4021 int i,r; | 3205 struct umidi_chan *chan = xfer->priv_sc; 3206 struct umidi_sub_chan *sub; 3207 uint8_t buf[1]; 3208 uint8_t cmd_len; 3209 uint8_t cn; 3210 uint16_t pos; |
4022 | 3211 |
4023 sc = device_get_softc(dev); 4024 if (sc == NULL) 4025 return 0; | 3212 switch (USB_GET_STATE(xfer)) { 3213 case USB_ST_TRANSFERRED: |
4026 | 3214 |
4027 cap->minspeed = cap->maxspeed = 0; 4028 foundcount = fmtcount = 0; | 3215 DPRINTF("actlen=%d bytes\n", xfer->actlen); |
4029 | 3216 |
4030 for (i = 0; i < sc->sc_nalts; i++) { 4031 dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress); | 3217 if (xfer->actlen == 0) { 3218 /* should not happen */ 3219 goto tr_error; 3220 } 3221 pos = 0; |
4032 | 3222 |
4033 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY)) 4034 continue; | 3223 while (xfer->actlen >= 4) { |
4035 | 3224 |
4036 asf1d = sc->sc_alts[i].asf1desc; 4037 format = sc->sc_alts[i].encoding; | 3225 usb2_copy_out(xfer->frbuffers, pos, buf, 1); |
4038 | 3226 |
4039 numchan = asf1d->bNrChannels; 4040 subframesize = asf1d->bSubFrameSize; 4041 prec = asf1d->bBitResolution; /* precision */ 4042 iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS; | 3227 cmd_len = umidi_cmd_to_len[buf[0] & 0xF]; /* command length */ 3228 cn = buf[0] >> 4; /* cable number */ 3229 sub = &chan->sub[cn]; |
4043 | 3230 |
4044 if (iscontinuous) 4045 snprintf(freq_descr, sizeof(freq_descr), "continous min %d max %d", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 4046 else 4047 snprintf(freq_descr, sizeof(freq_descr), "fixed frequency (%d listed formats)", asf1d->bSamFreqType); | 3231 if (cmd_len && (cn < chan->max_cable) && sub->read_open) { 3232 usb2_fifo_put_data(sub->fifo.fp[USB_FIFO_RX], xfer->frbuffers, 3233 pos + 1, cmd_len, 1); 3234 } else { 3235 /* ignore the command */ 3236 } |
4048 | 3237 |
4049 if (numchan == 1) 4050 numchannel_descr = " (mono)"; 4051 else if (numchan == 2) 4052 numchannel_descr = " (stereo)"; 4053 else 4054 numchannel_descr = ""; | 3238 xfer->actlen -= 4; 3239 pos += 4; 3240 } |
4055 | 3241 |
4056 if (bootverbose) { 4057 device_printf(dev, "uaudio_query_formats: found a native %s channel%s %s %dbit %dbytes/subframe X %d channels = %d bytes per sample\n", 4058 (dir==UE_DIR_OUT)?"playback":"record", 4059 numchannel_descr, freq_descr, 4060 prec, subframesize, numchan, subframesize*numchan); | 3242 case USB_ST_SETUP: 3243 DPRINTF("start\n"); 3244 3245 if (chan->flags & UMIDI_FLAG_READ_STALL) { 3246 usb2_transfer_start(chan->xfer[3]); 3247 return; |
4061 } | 3248 } |
4062 /* 4063 * Now start rejecting the ones that don't map to FreeBSD 4064 */ | 3249 xfer->frlengths[0] = xfer->max_data_length; 3250 usb2_start_hardware(xfer); 3251 return; |
4065 | 3252 |
4066 if (numchan != 1 && numchan != 2) 4067 continue; | 3253 default: 3254tr_error: |
4068 | 3255 |
4069 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++) 4070 if (iterator->uaudio_fmt == format && iterator->uaudio_prec == prec) 4071 break; | 3256 DPRINTF("error=%s\n", usb2_errstr(xfer->error)); |
4072 | 3257 |
4073 if (iterator->uaudio_fmt == 0) 4074 continue; | 3258 if (xfer->error != USB_ERR_CANCELLED) { 3259 /* try to clear stall first */ 3260 chan->flags |= UMIDI_FLAG_READ_STALL; 3261 usb2_transfer_start(chan->xfer[3]); 3262 } 3263 return; |
4075 | 3264 |
4076 fmt = iterator->freebsd_fmt; | 3265 } 3266} |
4077 | 3267 |
4078 if (numchan == 2) 4079 fmt |= AFMT_STEREO; | 3268static void 3269umidi_write_clear_stall_callback(struct usb2_xfer *xfer) 3270{ 3271 struct umidi_chan *chan = xfer->priv_sc; 3272 struct usb2_xfer *xfer_other = chan->xfer[0]; |
4080 | 3273 |
4081 foundcount++; | 3274 if (usb2_clear_stall_callback(xfer, xfer_other)) { 3275 DPRINTF("stall cleared\n"); 3276 chan->flags &= ~UMIDI_FLAG_WRITE_STALL; 3277 usb2_transfer_start(xfer_other); 3278 } 3279} |
4082 | 3280 |
4083 if (fmtcount >= maxfmt) 4084 continue; | 3281/* 3282 * The following statemachine, that converts MIDI commands to 3283 * USB MIDI packets, derives from Linux's usbmidi.c, which 3284 * was written by "Clemens Ladisch": 3285 * 3286 * Returns: 3287 * 0: No command 3288 * Else: Command is complete 3289 */ 3290static uint8_t 3291umidi_convert_to_usb(struct umidi_sub_chan *sub, uint8_t cn, uint8_t b) 3292{ 3293 uint8_t p0 = (cn << 4); |
4085 | 3294 |
4086 cap->fmtlist[fmtcount++] = fmt; | 3295 if (b >= 0xf8) { 3296 sub->temp_0[0] = p0 | 0x0f; 3297 sub->temp_0[1] = b; 3298 sub->temp_0[2] = 0; 3299 sub->temp_0[3] = 0; 3300 sub->temp_cmd = sub->temp_0; 3301 return (1); |
4087 | 3302 |
4088 if (iscontinuous) { 4089 freq_min = UA_SAMP_LO(asf1d); 4090 freq_max = UA_SAMP_HI(asf1d); | 3303 } else if (b >= 0xf0) { 3304 switch (b) { 3305 case 0xf0: /* system exclusive begin */ 3306 sub->temp_1[1] = b; 3307 sub->state = UMIDI_ST_SYSEX_1; 3308 break; 3309 case 0xf1: /* MIDI time code */ 3310 case 0xf3: /* song select */ 3311 sub->temp_1[1] = b; 3312 sub->state = UMIDI_ST_1PARAM; 3313 break; 3314 case 0xf2: /* song position pointer */ 3315 sub->temp_1[1] = b; 3316 sub->state = UMIDI_ST_2PARAM_1; 3317 break; 3318 case 0xf4: /* unknown */ 3319 case 0xf5: /* unknown */ 3320 sub->state = UMIDI_ST_UNKNOWN; 3321 break; 3322 case 0xf6: /* tune request */ 3323 sub->temp_1[0] = p0 | 0x05; 3324 sub->temp_1[1] = 0xf6; 3325 sub->temp_1[2] = 0; 3326 sub->temp_1[3] = 0; 3327 sub->temp_cmd = sub->temp_1; 3328 sub->state = UMIDI_ST_UNKNOWN; 3329 return (1); |
4091 | 3330 |
4092 if (cap->minspeed == 0 || freq_min < cap->minspeed) 4093 cap->minspeed = freq_min; 4094 if (cap->maxspeed == 0) 4095 cap->maxspeed = cap->minspeed; 4096 if (freq_max > cap->maxspeed) 4097 cap->maxspeed = freq_max; | 3331 case 0xf7: /* system exclusive end */ 3332 switch (sub->state) { 3333 case UMIDI_ST_SYSEX_0: 3334 sub->temp_1[0] = p0 | 0x05; 3335 sub->temp_1[1] = 0xf7; 3336 sub->temp_1[2] = 0; 3337 sub->temp_1[3] = 0; 3338 sub->temp_cmd = sub->temp_1; 3339 sub->state = UMIDI_ST_UNKNOWN; 3340 return (1); 3341 case UMIDI_ST_SYSEX_1: 3342 sub->temp_1[0] = p0 | 0x06; 3343 sub->temp_1[2] = 0xf7; 3344 sub->temp_1[3] = 0; 3345 sub->temp_cmd = sub->temp_1; 3346 sub->state = UMIDI_ST_UNKNOWN; 3347 return (1); 3348 case UMIDI_ST_SYSEX_2: 3349 sub->temp_1[0] = p0 | 0x07; 3350 sub->temp_1[3] = 0xf7; 3351 sub->temp_cmd = sub->temp_1; 3352 sub->state = UMIDI_ST_UNKNOWN; 3353 return (1); 3354 } 3355 sub->state = UMIDI_ST_UNKNOWN; 3356 break; 3357 } 3358 } else if (b >= 0x80) { 3359 sub->temp_1[1] = b; 3360 if ((b >= 0xc0) && (b <= 0xdf)) { 3361 sub->state = UMIDI_ST_1PARAM; |
4098 } else { | 3362 } else { |
4099 for (r = 0; r < asf1d->bSamFreqType; r++) { 4100 freq = UA_GETSAMP(asf1d, r); 4101 if (cap->minspeed == 0 || freq < cap->minspeed) 4102 cap->minspeed = freq; 4103 if (cap->maxspeed == 0) 4104 cap->maxspeed = cap->minspeed; 4105 if (freq > cap->maxspeed) 4106 cap->maxspeed = freq; | 3363 sub->state = UMIDI_ST_2PARAM_1; 3364 } 3365 } else { /* b < 0x80 */ 3366 switch (sub->state) { 3367 case UMIDI_ST_1PARAM: 3368 if (sub->temp_1[1] < 0xf0) { 3369 p0 |= sub->temp_1[1] >> 4; 3370 } else { 3371 p0 |= 0x02; 3372 sub->state = UMIDI_ST_UNKNOWN; |
4107 } | 3373 } |
3374 sub->temp_1[0] = p0; 3375 sub->temp_1[2] = b; 3376 sub->temp_1[3] = 0; 3377 sub->temp_cmd = sub->temp_1; 3378 return (1); 3379 case UMIDI_ST_2PARAM_1: 3380 sub->temp_1[2] = b; 3381 sub->state = UMIDI_ST_2PARAM_2; 3382 break; 3383 case UMIDI_ST_2PARAM_2: 3384 if (sub->temp_1[1] < 0xf0) { 3385 p0 |= sub->temp_1[1] >> 4; 3386 sub->state = UMIDI_ST_2PARAM_1; 3387 } else { 3388 p0 |= 0x03; 3389 sub->state = UMIDI_ST_UNKNOWN; 3390 } 3391 sub->temp_1[0] = p0; 3392 sub->temp_1[3] = b; 3393 sub->temp_cmd = sub->temp_1; 3394 return (1); 3395 case UMIDI_ST_SYSEX_0: 3396 sub->temp_1[1] = b; 3397 sub->state = UMIDI_ST_SYSEX_1; 3398 break; 3399 case UMIDI_ST_SYSEX_1: 3400 sub->temp_1[2] = b; 3401 sub->state = UMIDI_ST_SYSEX_2; 3402 break; 3403 case UMIDI_ST_SYSEX_2: 3404 sub->temp_1[0] = p0 | 0x04; 3405 sub->temp_1[3] = b; 3406 sub->temp_cmd = sub->temp_1; 3407 sub->state = UMIDI_ST_SYSEX_0; 3408 return (1); |
|
4108 } 4109 } | 3409 } 3410 } |
4110 cap->fmtlist[fmtcount] = 0; 4111 return foundcount; | 3411 return (0); |
4112} 4113 | 3412} 3413 |
4114void 4115uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end, 4116 struct pcm_channel *pc, int dir) | 3414static void 3415umidi_bulk_write_callback(struct usb2_xfer *xfer) |
4117{ | 3416{ |
4118 struct uaudio_softc *sc; 4119 struct chan *ch; | 3417 struct umidi_chan *chan = xfer->priv_sc; 3418 struct umidi_sub_chan *sub; 3419 uint32_t actlen; 3420 uint16_t total_length; 3421 uint8_t buf; 3422 uint8_t start_cable; 3423 uint8_t tr_any; |
4120 | 3424 |
4121 sc = device_get_softc(dev); 4122#ifndef NO_RECORDING 4123 if (dir == PCMDIR_PLAY) 4124 ch = &sc->sc_playchan; 4125 else 4126 ch = &sc->sc_recchan; 4127#else 4128 ch = &sc->sc_playchan; 4129#endif | 3425 switch (USB_GET_STATE(xfer)) { 3426 case USB_ST_TRANSFERRED: 3427 DPRINTF("actlen=%d bytes\n", xfer->actlen); |
4130 | 3428 |
4131 ch->start = start; 4132 ch->end = end; | 3429 case USB_ST_SETUP: |
4133 | 3430 |
4134 ch->pcm_ch = pc; | 3431 DPRINTF("start\n"); |
4135 | 3432 |
4136 return; 4137} | 3433 if (chan->flags & UMIDI_FLAG_WRITE_STALL) { 3434 usb2_transfer_start(chan->xfer[2]); 3435 return; 3436 } 3437 total_length = 0; /* reset */ |
4138 | 3438 |
4139void 4140uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir) 4141{ 4142 struct uaudio_softc *sc; 4143 struct chan *ch; | 3439 start_cable = chan->curr_cable; |
4144 | 3440 |
4145 sc = device_get_softc(dev); 4146#ifndef NO_RECORDING 4147 if (dir == PCMDIR_PLAY) 4148 ch = &sc->sc_playchan; 4149 else 4150 ch = &sc->sc_recchan; 4151#else 4152 ch = &sc->sc_playchan; 4153#endif | 3441 tr_any = 0; |
4154 | 3442 |
4155 ch->blksize = blocksize; | 3443 while (1) { |
4156 | 3444 |
4157 return; 4158} | 3445 /* round robin de-queueing */ |
4159 | 3446 |
4160int 4161uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir) 4162{ 4163 const struct uaudio_conversion *iterator; 4164 struct uaudio_softc *sc; 4165 struct chan *ch; 4166 int i, r, score, hiscore, bestspeed; | 3447 sub = &chan->sub[chan->curr_cable]; |
4167 | 3448 |
4168 sc = device_get_softc(dev); 4169#ifndef NO_RECORDING 4170 if (reqdir == PCMDIR_PLAY) 4171 ch = &sc->sc_playchan; 4172 else 4173 ch = &sc->sc_recchan; 4174#else 4175 ch = &sc->sc_playchan; 4176#endif 4177 /* 4178 * We are successful if we find an endpoint that matches our selected format and it 4179 * supports the requested speed. 4180 */ 4181 hiscore = 0; 4182 bestspeed = 1; 4183 for (i = 0; i < sc->sc_nalts; i++) { 4184 int dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress); 4185 int format = sc->sc_alts[i].encoding; 4186 const struct usb_audio_streaming_type1_descriptor *asf1d = sc->sc_alts[i].asf1desc; 4187 int iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS; | 3449 if (sub->write_open) { 3450 usb2_fifo_get_data(sub->fifo.fp[USB_FIFO_TX], 3451 xfer->frbuffers, total_length, 3452 1, &actlen, 0); 3453 } else { 3454 actlen = 0; 3455 } |
4188 | 3456 |
4189 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY)) 4190 continue; | 3457 if (actlen) { 3458 usb2_copy_out(xfer->frbuffers, total_length, &buf, 1); |
4191 | 3459 |
4192 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++) 4193 if (iterator->uaudio_fmt != format || iterator->freebsd_fmt != (ch->format&0xfffffff)) 4194 continue; 4195 if (iscontinuous) { 4196 if (speed >= UA_SAMP_LO(asf1d) && speed <= UA_SAMP_HI(asf1d)) { 4197 ch->sample_rate = speed; 4198 return speed; 4199 } else if (speed < UA_SAMP_LO(asf1d)) { 4200 score = 0xfff * speed / UA_SAMP_LO(asf1d); 4201 if (score > hiscore) { 4202 bestspeed = UA_SAMP_LO(asf1d); 4203 hiscore = score; | 3460 tr_any = 1; 3461 3462 DPRINTF("byte=0x%02x\n", buf); 3463 3464 if (umidi_convert_to_usb(sub, chan->curr_cable, buf)) { 3465 3466 DPRINTF("sub= %02x %02x %02x %02x\n", 3467 sub->temp_cmd[0], sub->temp_cmd[1], 3468 sub->temp_cmd[2], sub->temp_cmd[3]); 3469 3470 usb2_copy_in(xfer->frbuffers, total_length, 3471 sub->temp_cmd, 4); 3472 3473 total_length += 4; 3474 3475 if (total_length >= UMIDI_BULK_SIZE) { 3476 break; |
4204 } | 3477 } |
4205 } else if (speed > UA_SAMP_HI(asf1d)) { 4206 score = 0xfff * UA_SAMP_HI(asf1d) / speed; 4207 if (score > hiscore) { 4208 bestspeed = UA_SAMP_HI(asf1d); 4209 hiscore = score; 4210 } | 3478 } else { 3479 continue; |
4211 } | 3480 } |
4212 continue; | |
4213 } | 3481 } |
4214 for (r = 0; r < asf1d->bSamFreqType; r++) { 4215 if (speed == UA_GETSAMP(asf1d, r)) { 4216 ch->sample_rate = speed; 4217 return speed; | 3482 chan->curr_cable++; 3483 if (chan->curr_cable >= chan->max_cable) { 3484 chan->curr_cable = 0; 3485 } 3486 if (chan->curr_cable == start_cable) { 3487 if (tr_any == 0) { 3488 break; |
4218 } | 3489 } |
4219 if (speed > UA_GETSAMP(asf1d, r)) 4220 score = 0xfff * UA_GETSAMP(asf1d, r) / speed; 4221 else 4222 score = 0xfff * speed / UA_GETSAMP(asf1d, r); 4223 if (score > hiscore) { 4224 bestspeed = UA_GETSAMP(asf1d, r); 4225 hiscore = score; 4226 } | 3490 tr_any = 0; |
4227 } | 3491 } |
4228 } 4229 if (bestspeed != 1) { 4230 ch->sample_rate = bestspeed; 4231 return bestspeed; 4232 } | 3492 } |
4233 | 3493 |
4234 return 0; 4235} | 3494 if (total_length) { 3495 xfer->frlengths[0] = total_length; 3496 usb2_start_hardware(xfer); 3497 } 3498 return; |
4236 | 3499 |
4237int 4238uaudio_chan_getptr(device_t dev, int dir) 4239{ 4240 struct uaudio_softc *sc; 4241 struct chan *ch; 4242 int ptr; | 3500 default: /* Error */ |
4243 | 3501 |
4244 sc = device_get_softc(dev); 4245#ifndef NO_RECORDING 4246 if (dir == PCMDIR_PLAY) 4247 ch = &sc->sc_playchan; 4248 else 4249 ch = &sc->sc_recchan; 4250#else 4251 ch = &sc->sc_playchan; 4252#endif | 3502 DPRINTF("error=%s\n", usb2_errstr(xfer->error)); |
4253 | 3503 |
4254 ptr = ch->cur - ch->start; | 3504 if (xfer->error != USB_ERR_CANCELLED) { 3505 /* try to clear stall first */ 3506 chan->flags |= UMIDI_FLAG_WRITE_STALL; 3507 usb2_transfer_start(chan->xfer[2]); 3508 } 3509 return; |
4255 | 3510 |
4256 return ptr; | 3511 } |
4257} 4258 | 3512} 3513 |
4259void 4260uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir) | 3514static struct umidi_sub_chan * 3515umidi_sub_by_fifo(struct usb2_fifo *fifo) |
4261{ | 3516{ |
4262 struct uaudio_softc *sc; 4263 struct chan *ch; | 3517 struct umidi_chan *chan = fifo->priv_sc0; 3518 struct umidi_sub_chan *sub; 3519 uint32_t n; |
4264 | 3520 |
4265 sc = device_get_softc(dev); 4266#ifndef NO_RECORDING 4267 if (dir == PCMDIR_PLAY) 4268 ch = &sc->sc_playchan; 4269 else 4270 ch = &sc->sc_recchan; 4271#else 4272 ch = &sc->sc_playchan; 4273#endif | 3521 for (n = 0; n < UMIDI_CABLES_MAX; n++) { 3522 sub = &chan->sub[n]; 3523 if ((sub->fifo.fp[USB_FIFO_RX] == fifo) || 3524 (sub->fifo.fp[USB_FIFO_TX] == fifo)) { 3525 return (sub); 3526 } 3527 } |
4274 | 3528 |
4275 ch->format = format; | 3529 panic("%s:%d cannot find usb2_fifo!\n", 3530 __FILE__, __LINE__); |
4276 | 3531 |
4277 return; | 3532 return (NULL); |
4278} 4279 | 3533} 3534 |
4280int 4281uaudio_halt_out_dma(device_t dev) | 3535static void 3536umidi_start_read(struct usb2_fifo *fifo) |
4282{ | 3537{ |
4283 struct uaudio_softc *sc; | 3538 struct umidi_chan *chan = fifo->priv_sc0; |
4284 | 3539 |
4285 sc = device_get_softc(dev); 4286 4287 DPRINTF(("uaudio_halt_out_dma: enter\n")); 4288 if (sc->sc_playchan.pipe != NULL) { 4289 uaudio_chan_close(sc, &sc->sc_playchan); 4290 sc->sc_playchan.pipe = 0; 4291 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 4292 } 4293 return (0); | 3540 usb2_transfer_start(chan->xfer[1]); |
4294} 4295 | 3541} 3542 |
4296int 4297uaudio_halt_in_dma(device_t dev) | 3543static void 3544umidi_stop_read(struct usb2_fifo *fifo) |
4298{ | 3545{ |
4299 struct uaudio_softc *sc; | 3546 struct umidi_chan *chan = fifo->priv_sc0; 3547 struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo); |
4300 | 3548 |
4301 sc = device_get_softc(dev); | 3549 DPRINTF("\n"); |
4302 | 3550 |
4303 if (sc->sc_dying) 4304 return (EIO); | 3551 sub->read_open = 0; |
4305 | 3552 |
4306 DPRINTF(("uaudio_halt_in_dma: enter\n")); 4307 if (sc->sc_recchan.pipe != NULL) { 4308 uaudio_chan_close(sc, &sc->sc_recchan); 4309 sc->sc_recchan.pipe = NULL; 4310 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 4311/* sc->sc_recchan.intr = NULL; */ | 3553 if (--(chan->read_open_refcount) == 0) { 3554 /* 3555 * XXX don't stop the read transfer here, hence that causes 3556 * problems with some MIDI adapters 3557 */ 3558 DPRINTF("(stopping read transfer)\n"); |
4312 } | 3559 } |
4313 return (0); | |
4314} 4315 | 3560} 3561 |
4316int 4317uaudio_trigger_input(device_t dev) | 3562static void 3563umidi_start_write(struct usb2_fifo *fifo) |
4318{ | 3564{ |
4319 struct uaudio_softc *sc; 4320 struct chan *ch; 4321 usbd_status err; 4322 int i, s; | 3565 struct umidi_chan *chan = fifo->priv_sc0; |
4323 | 3566 |
4324 sc = device_get_softc(dev); 4325 ch = &sc->sc_recchan; 4326 4327 if (sc->sc_dying) 4328 return (EIO); 4329 4330/* uaudio_chan_set_param(ch, start, end, blksize) */ 4331 if (uaudio_init_params(sc, ch, AUMODE_RECORD)) 4332 return (EIO); 4333 4334 err = uaudio_chan_alloc_buffers(sc, ch); 4335 if (err) 4336 return (EIO); 4337 4338 err = uaudio_chan_open(sc, ch); 4339 if (err) { 4340 uaudio_chan_free_buffers(sc, ch); 4341 return (EIO); 4342 } 4343 4344/* ch->intr = intr; 4345 ch->arg = arg; */ 4346 4347 s = splusb(); 4348 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ 4349 uaudio_chan_rtransfer(ch); 4350 splx(s); 4351 4352 return (0); | 3567 usb2_transfer_start(chan->xfer[0]); |
4353} 4354 | 3568} 3569 |
4355int 4356uaudio_trigger_output(device_t dev) | 3570static void 3571umidi_stop_write(struct usb2_fifo *fifo) |
4357{ | 3572{ |
4358 struct uaudio_softc *sc; 4359 struct chan *ch; 4360 usbd_status err; 4361 int i, s; | 3573 struct umidi_chan *chan = fifo->priv_sc0; 3574 struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo); |
4362 | 3575 |
4363 sc = device_get_softc(dev); 4364 ch = &sc->sc_playchan; | 3576 DPRINTF("\n"); |
4365 | 3577 |
4366 if (sc->sc_dying) 4367 return (EIO); | 3578 sub->write_open = 0; |
4368 | 3579 |
4369 if (uaudio_init_params(sc, ch, AUMODE_PLAY)) 4370 return (EIO); 4371 4372 err = uaudio_chan_alloc_buffers(sc, ch); 4373 if (err) 4374 return (EIO); 4375 4376 err = uaudio_chan_open(sc, ch); 4377 if (err) { 4378 uaudio_chan_free_buffers(sc, ch); 4379 return (EIO); | 3580 if (--(chan->write_open_refcount) == 0) { 3581 DPRINTF("(stopping write transfer)\n"); 3582 usb2_transfer_stop(chan->xfer[2]); 3583 usb2_transfer_stop(chan->xfer[0]); |
4380 } | 3584 } |
4381 4382 s = splusb(); 4383 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 4384 uaudio_chan_ptransfer(ch); 4385 splx(s); 4386 4387 return (0); | |
4388} 4389 | 3585} 3586 |
4390u_int32_t 4391uaudio_query_mix_info(device_t dev) | 3587static int 3588umidi_open(struct usb2_fifo *fifo, int fflags, struct thread *td) |
4392{ | 3589{ |
4393 int i; 4394 u_int32_t mask = 0; 4395 struct uaudio_softc *sc; 4396 struct mixerctl *mc; | 3590 struct umidi_chan *chan = fifo->priv_sc0; 3591 struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo); |
4397 | 3592 |
4398 sc = device_get_softc(dev); 4399 for (i=0; i < sc->sc_nctls; i++) { 4400 mc = &sc->sc_ctls[i]; 4401 if (mc->ctl != SOUND_MIXER_NRDEVICES) { 4402 /* Set device mask bits. 4403 See /usr/include/machine/soundcard.h */ 4404 mask |= (1 << mc->ctl); | 3593 if (fflags & FREAD) { 3594 if (usb2_fifo_alloc_buffer(fifo, 4, (1024 / 4))) { 3595 return (ENOMEM); |
4405 } | 3596 } |
3597 mtx_lock(fifo->priv_mtx); 3598 chan->read_open_refcount++; 3599 sub->read_open = 1; 3600 mtx_unlock(fifo->priv_mtx); |
|
4406 } | 3601 } |
4407 return mask; 4408} 4409 4410u_int32_t 4411uaudio_query_recsrc_info(device_t dev) 4412{ 4413 int i, rec_selector_id; 4414 u_int32_t mask = 0; 4415 struct uaudio_softc *sc; 4416 struct mixerctl *mc; 4417 4418 sc = device_get_softc(dev); 4419 rec_selector_id = -1; 4420 for (i=0; i < sc->sc_nctls; i++) { 4421 mc = &sc->sc_ctls[i]; 4422 if (mc->ctl == SOUND_MIXER_NRDEVICES && 4423 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) { 4424 if (rec_selector_id == -1) { 4425 rec_selector_id = i; 4426 } else { 4427 printf("There are many selectors. Can't recognize which selector is a record source selector.\n"); 4428 return mask; 4429 } | 3602 if (fflags & FWRITE) { 3603 if (usb2_fifo_alloc_buffer(fifo, 32, (1024 / 32))) { 3604 return (ENOMEM); |
4430 } | 3605 } |
4431 } 4432 if (rec_selector_id == -1) 4433 return mask; 4434 mc = &sc->sc_ctls[rec_selector_id]; 4435 for (i = mc->minval; i <= mc->maxval; i++) { 4436 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) 4437 continue; 4438 mask |= 1 << mc->slctrtype[i - 1]; 4439 } 4440 return mask; 4441} | 3606 /* clear stall first */ 3607 mtx_lock(fifo->priv_mtx); 3608 chan->flags |= UMIDI_FLAG_WRITE_STALL; 3609 chan->write_open_refcount++; 3610 sub->write_open = 1; |
4442 | 3611 |
4443void 4444uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right) 4445{ 4446 int i; 4447 struct uaudio_softc *sc; 4448 struct mixerctl *mc; 4449 4450 sc = device_get_softc(dev); 4451 for (i=0; i < sc->sc_nctls; i++) { 4452 mc = &sc->sc_ctls[i]; 4453 if (mc->ctl == type) { 4454 if (mc->nchan == 2) { 4455 /* set Right */ 4456 uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*255)/100); 4457 } 4458 /* set Left or Mono */ 4459 uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*255)/100); 4460 } | 3612 /* reset */ 3613 sub->state = UMIDI_ST_UNKNOWN; 3614 mtx_unlock(fifo->priv_mtx); |
4461 } | 3615 } |
4462 return; | 3616 return (0); /* success */ |
4463} 4464 | 3617} 3618 |
4465u_int32_t 4466uaudio_mixer_setrecsrc(device_t dev, u_int32_t src) | 3619static void 3620umidi_close(struct usb2_fifo *fifo, int fflags, struct thread *td) |
4467{ | 3621{ |
4468 int i, rec_selector_id; 4469 struct uaudio_softc *sc; 4470 struct mixerctl *mc; 4471 4472 sc = device_get_softc(dev); 4473 rec_selector_id = -1; 4474 for (i=0; i < sc->sc_nctls; i++) { 4475 mc = &sc->sc_ctls[i]; 4476 if (mc->ctl == SOUND_MIXER_NRDEVICES && 4477 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) { 4478 if (rec_selector_id == -1) { 4479 rec_selector_id = i; 4480 } else { 4481 return src; /* Can't recognize which selector is record source selector */ 4482 } 4483 } | 3622 if (fflags & FREAD) { 3623 usb2_fifo_free_buffer(fifo); |
4484 } | 3624 } |
4485 if (rec_selector_id == -1) 4486 return src; 4487 mc = &sc->sc_ctls[rec_selector_id]; 4488 for (i = mc->minval; i <= mc->maxval; i++) { 4489 if (src != (1 << mc->slctrtype[i - 1])) 4490 continue; 4491 uaudio_ctl_set(sc, SET_CUR, mc, 0, i); 4492 return (1 << mc->slctrtype[i - 1]); | 3625 if (fflags & FWRITE) { 3626 usb2_fifo_free_buffer(fifo); |
4493 } | 3627 } |
4494 uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval); 4495 return (1 << mc->slctrtype[mc->minval - 1]); | |
4496} 4497 | 3628} 3629 |
3630 |
|
4498static int | 3631static int |
4499uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) | 3632umidi_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data, 3633 int fflags, struct thread *td) |
4500{ | 3634{ |
4501 struct snddev_info *d; 4502 struct pcm_channel *c; 4503 struct pcm_feeder *f; 4504 device_t pa_dev = device_get_parent(dev); 4505 struct uaudio_softc *sc = device_get_softc(pa_dev); | 3635 return (ENODEV); 3636} |
4506 | 3637 |
4507 if (verbose < 1) 4508 return 0; | 3638static void 3639umidi_init(device_t dev) 3640{ 3641 struct uaudio_softc *sc = device_get_softc(dev); 3642 struct umidi_chan *chan = &sc->sc_midi_chan; |
4509 | 3643 |
4510 d = device_get_softc(dev); 4511 if (!d) 4512 return ENXIO; | 3644 mtx_init(&chan->mtx, "umidi lock", NULL, MTX_DEF | MTX_RECURSE); 3645} |
4513 | 3646 |
4514 PCM_BUSYASSERT(d); | 3647static struct usb2_fifo_methods umidi_fifo_methods = { 3648 .f_start_read = &umidi_start_read, 3649 .f_start_write = &umidi_start_write, 3650 .f_stop_read = &umidi_stop_read, 3651 .f_stop_write = &umidi_stop_write, 3652 .f_open = &umidi_open, 3653 .f_close = &umidi_close, 3654 .f_ioctl = &umidi_ioctl, 3655 .basename[0] = "umidi", 3656}; |
4515 | 3657 |
4516 if (CHN_EMPTY(d, channels.pcm)) { 4517 sbuf_printf(s, " (mixer only)"); 4518 return 0; | 3658static int32_t 3659umidi_probe(device_t dev) 3660{ 3661 struct uaudio_softc *sc = device_get_softc(dev); 3662 struct usb2_attach_arg *uaa = device_get_ivars(dev); 3663 struct umidi_chan *chan = &sc->sc_midi_chan; 3664 struct umidi_sub_chan *sub; 3665 int unit = device_get_unit(dev); 3666 int error; 3667 uint32_t n; 3668 3669 if (usb2_set_alt_interface_index(sc->sc_udev, chan->iface_index, 3670 chan->iface_alt_index)) { 3671 DPRINTF("setting of alternate index failed!\n"); 3672 goto detach; |
4519 } | 3673 } |
3674 usb2_set_parent_iface(sc->sc_udev, chan->iface_index, sc->sc_mixer_iface_index); |
|
4520 | 3675 |
4521 sbuf_printf(s, " (%dp:%dv/%dr:%dv channels%s%s)", 4522 d->playcount, d->pvchancount, 4523 d->reccount, d->rvchancount, 4524 (d->flags & SD_F_SIMPLEX)? "" : " duplex", 4525#ifdef USING_DEVFS 4526 (device_get_unit(dev) == snd_unit)? " default" : "" 4527#else 4528 "" 4529#endif 4530 ); 4531 4532 if (sc->uaudio_sndstat_flag != 0) { 4533 sbuf_cat(s, sbuf_data(&(sc->uaudio_sndstat))); | 3676 error = usb2_transfer_setup(uaa->device, &chan->iface_index, 3677 chan->xfer, umidi_config, UMIDI_N_TRANSFER, 3678 chan, &chan->mtx); 3679 if (error) { 3680 DPRINTF("error=%s\n", usb2_errstr(error)); 3681 goto detach; |
4534 } | 3682 } |
3683 if ((chan->max_cable > UMIDI_CABLES_MAX) || 3684 (chan->max_cable == 0)) { 3685 chan->max_cable = UMIDI_CABLES_MAX; 3686 } 3687 /* set interface permissions */ 3688 usb2_set_iface_perm(sc->sc_udev, chan->iface_index, 3689 UID_ROOT, GID_OPERATOR, 0644); |
|
4535 | 3690 |
4536 if (verbose <= 1) 4537 return 0; | 3691 for (n = 0; n < chan->max_cable; n++) { |
4538 | 3692 |
4539 CHN_FOREACH(c, d, channels.pcm) { | 3693 sub = &chan->sub[n]; |
4540 | 3694 |
4541 KASSERT(c->bufhard != NULL && c->bufsoft != NULL, 4542 ("hosed pcm channel setup")); 4543 4544 sbuf_printf(s, "\n\t"); 4545 4546 /* it would be better to indent child channels */ 4547 sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name); 4548 sbuf_printf(s, "spd %d", c->speed); 4549 if (c->speed != sndbuf_getspd(c->bufhard)) 4550 sbuf_printf(s, "/%d", sndbuf_getspd(c->bufhard)); 4551 sbuf_printf(s, ", fmt 0x%08x", c->format); 4552 if (c->format != sndbuf_getfmt(c->bufhard)) 4553 sbuf_printf(s, "/0x%08x", sndbuf_getfmt(c->bufhard)); 4554 sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags); 4555 if (c->pid != -1) 4556 sbuf_printf(s, ", pid %d", c->pid); 4557 sbuf_printf(s, "\n\t"); 4558 4559 sbuf_printf(s, "interrupts %d, ", c->interrupts); 4560 if (c->direction == PCMDIR_REC) 4561 sbuf_printf(s, "overruns %d, feed %u, hfree %d, sfree %d [b:%d/%d/%d|bs:%d/%d/%d]", 4562 c->xruns, c->feedcount, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft), 4563 sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard), 4564 sndbuf_getblkcnt(c->bufhard), 4565 sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft), 4566 sndbuf_getblkcnt(c->bufsoft)); 4567 else 4568 sbuf_printf(s, "underruns %d, feed %u, ready %d [b:%d/%d/%d|bs:%d/%d/%d]", 4569 c->xruns, c->feedcount, sndbuf_getready(c->bufsoft), 4570 sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard), 4571 sndbuf_getblkcnt(c->bufhard), 4572 sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft), 4573 sndbuf_getblkcnt(c->bufsoft)); 4574 sbuf_printf(s, "\n\t"); 4575 4576 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "hardware" : "userland"); 4577 sbuf_printf(s, " -> "); 4578 f = c->feeder; 4579 while (f->source != NULL) 4580 f = f->source; 4581 while (f != NULL) { 4582 sbuf_printf(s, "%s", f->class->name); 4583 if (f->desc->type == FEEDER_FMT) 4584 sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out); 4585 if (f->desc->type == FEEDER_RATE) 4586 sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST)); 4587 if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER || 4588 f->desc->type == FEEDER_VOLUME) 4589 sbuf_printf(s, "(0x%08x)", f->desc->out); 4590 sbuf_printf(s, " -> "); 4591 f = f->parent; | 3695 error = usb2_fifo_attach(sc->sc_udev, chan, &chan->mtx, 3696 &umidi_fifo_methods, &sub->fifo, unit, n, 3697 chan->iface_index); 3698 if (error) { 3699 goto detach; |
4592 } | 3700 } |
4593 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "userland" : "hardware"); | |
4594 } 4595 | 3701 } 3702 |
4596 return 0; 4597} | 3703 mtx_lock(&chan->mtx); |
4598 | 3704 |
4599void 4600uaudio_sndstat_register(device_t dev) 4601{ 4602 struct snddev_info *d = device_get_softc(dev); 4603 sndstat_register(dev, d->status, uaudio_sndstat_prepare_pcm); 4604} | 3705 /* clear stall first */ 3706 chan->flags |= UMIDI_FLAG_READ_STALL; |
4605 | 3707 |
4606int 4607uaudio_get_vendor(device_t dev) 4608{ 4609 struct uaudio_softc *sc = device_get_softc(dev); | 3708 /* 3709 * NOTE: at least one device will not work properly unless 3710 * the BULK pipe is open all the time. 3711 */ 3712 usb2_transfer_start(chan->xfer[1]); |
4610 | 3713 |
4611 if (sc == NULL) 4612 return 0; | 3714 mtx_unlock(&chan->mtx); |
4613 | 3715 |
4614 return sc->sc_vendor; 4615} | 3716 return (0); /* success */ |
4616 | 3717 |
4617int 4618uaudio_get_product(device_t dev) 4619{ 4620 struct uaudio_softc *sc = device_get_softc(dev); 4621 4622 if (sc == NULL) 4623 return 0; 4624 4625 return sc->sc_product; | 3718detach: 3719 return (ENXIO); /* failure */ |
4626} 4627 | 3720} 3721 |
4628int 4629uaudio_get_release(device_t dev) | 3722static int32_t 3723umidi_detach(device_t dev) |
4630{ 4631 struct uaudio_softc *sc = device_get_softc(dev); | 3724{ 3725 struct uaudio_softc *sc = device_get_softc(dev); |
3726 struct umidi_chan *chan = &sc->sc_midi_chan; 3727 uint32_t n; |
|
4632 | 3728 |
4633 if (sc == NULL) 4634 return 0; | 3729 for (n = 0; n < UMIDI_CABLES_MAX; n++) { 3730 usb2_fifo_detach(&chan->sub[n].fifo); 3731 } |
4635 | 3732 |
4636 return sc->sc_release; 4637} | 3733 mtx_lock(&chan->mtx); |
4638 | 3734 |
4639static int 4640audio_attach_mi(device_t dev) 4641{ 4642 device_t child; 4643 struct sndcard_func *func; | 3735 usb2_transfer_stop(chan->xfer[3]); 3736 usb2_transfer_stop(chan->xfer[1]); |
4644 | 3737 |
4645 /* Attach the children. */ 4646 /* PCM Audio */ 4647 func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); 4648 if (func == NULL) 4649 return (ENOMEM); 4650 func->func = SCF_PCM; 4651 child = device_add_child(dev, "pcm", -1); 4652 device_set_ivars(child, func); | 3738 mtx_unlock(&chan->mtx); |
4653 | 3739 |
4654 bus_generic_attach(dev); | 3740 usb2_transfer_unsetup(chan->xfer, UMIDI_N_TRANSFER); |
4655 | 3741 |
4656 return 0; /* XXXXX */ | 3742 mtx_destroy(&chan->mtx); 3743 3744 return (0); |
4657} 4658 | 3745} 3746 |
4659DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0); | 3747DRIVER_MODULE(uaudio, ushub, uaudio_driver, uaudio_devclass, NULL, 0); 3748MODULE_DEPEND(uaudio, usb, 1, 1, 1); 3749MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); |
4660MODULE_VERSION(uaudio, 1); | 3750MODULE_VERSION(uaudio, 1); |
4661 4662#endif | |