1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #ifndef _SYS_USB_AC_H
27 #define _SYS_USB_AC_H
28
29
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #include <sys/sunldi.h>
36 #include <sys/usb/usba/usbai_private.h>
37
38
39 int usb_ac_open(dev_info_t *);
40 void usb_ac_close(dev_info_t *);
41
42
43 /* structure for each unit described by descriptors */
44 typedef struct usb_ac_unit_list {
45 uint_t acu_type;
46 void *acu_descriptor;
47 size_t acu_descr_length;
48 } usb_ac_unit_list_t;
49
50 #define USB_AC_ID_NONE 0
51
52 #define USB_AC_FIND_ONE 0
53 #define USB_AC_FIND_ALL 1
54 #define USB_AC_MAX_DEPTH 8
55
56 /*
57 * plumbing data; info per plumbed module
58 */
59 typedef struct usb_ac_plumbed {
60 struct usb_ac_state *acp_uacp; /* usb_ac state pointer */
61 dev_info_t *acp_dip; /* devinfo pointer */
62 uint_t acp_ifno; /* interface number */
63 int acp_driver; /* Plumbed driver, see value below */
64
65 ldi_handle_t acp_lh; /* ldi handle of plumbed driver */
66 dev_t acp_devt; /* devt of plumbed driver */
67 ddi_taskq_t *acp_tqp; /* taskq for I/O to plumbed driver */
68 int acp_flags;
69 #define ACP_ENABLED 1
70
71 void *acp_data; /* ptr to streams or hid data */
72 } usb_ac_plumbed_t;
73
74
75 /*
76 * request structure to usb_as: info per MCTL request;
77 * only one active at a time.
78 */
79 typedef struct usb_ac_to_as_req {
80 usb_audio_formats_t acr_curr_format; /* format data from mixer */
81 } usb_ac_to_as_req_t;
82
83
84 /* registration and plumbing info per streaming interface */
85 typedef struct usb_ac_streams_info {
86 /* ptr to entry in plumbed list */
87 usb_ac_plumbed_t *acs_plumbed;
88 /* valid registration data rcvd */
89 uint_t acs_rcvd_reg_data;
90 /* pointer to registration data */
91 usb_as_registration_t acs_streams_reg;
92
93
94 /* Multiple command management */
95 int acs_setup_teardown_count;
96
97 uint8_t acs_default_gain;
98 } usb_ac_streams_info_t;
99
100
101 /* power state */
102 typedef struct usb_ac_power {
103 void *acpm_state; /* points back to usb_ac_state */
104 int acpm_pm_busy; /* device busy accounting */
105 uint8_t acpm_wakeup_enabled;
106
107 /* this is the bit mask of the power states that device has */
108 uint8_t acpm_pwr_states;
109
110 /* wakeup and power transistion capabilites of an interface */
111 uint8_t acpm_capabilities;
112
113 /* current power level the device is in */
114 uint8_t acpm_current_power;
115 } usb_ac_power_t;
116
117 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_state))
118 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_wakeup_enabled))
119 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_pwr_states))
120 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_capabilities))
121
122 typedef struct usb_audio_format {
123 int sr; /* sample rate */
124 uint_t ch; /* channels */
125 uint_t prec; /* precision */
126 uint_t enc; /* encoding */
127 } usb_audio_format_t;
128
129
130 typedef struct usb_audio_eng {
131 void *statep;
132 usb_ac_streams_info_t *streams;
133 audio_engine_t *af_engp;
134
135 int af_eflags; /* ENGINE_* flags */
136 usb_audio_format_t fmt;
137 uint64_t af_defgain;
138
139 unsigned intrate; /* interrupt rate */
140 unsigned sampsz; /* sample size */
141 unsigned framesz; /* frame size */
142 unsigned fragsz; /* fragment size */
143 unsigned nfrags; /* number of fragments in buffer */
144 unsigned fragfr; /* number of frames per fragment */
145 unsigned frsmshift; /* right shift: frames in sample cnt */
146 unsigned smszshift; /* left shift: sample cnt * sampsz */
147
148
149 caddr_t bufp; /* I/O buf; framework to/from drv */
150 unsigned bufsz; /* buffer size */
151 caddr_t bufpos; /* buffer position */
152 caddr_t bufendp; /* end of buffer */
153
154
155 uint64_t frames;
156 uint64_t io_count; /* i/o requests from the driver */
157 uint64_t bufio_count; /* i/o requests to the framework */
158
159 boolean_t started;
160 boolean_t busy;
161
162 kcondvar_t usb_audio_cv;
163
164 kmutex_t lock;
165 } usb_audio_eng_t;
166
167
168 /* limits */
169 #define USB_AC_MAX_PLUMBED 3 /* play, record, hid */
170 #define USB_AC_MAX_AS_PLUMBED 2 /* play, record */
171 typedef struct usb_ac_state usb_ac_state_t;
172 typedef struct usb_audio_ctrl {
173 audio_ctrl_t *af_ctrlp; /* framework handle */
174 usb_ac_state_t *statep;
175
176 kmutex_t ctrl_mutex;
177 uint64_t cval; /* current control value */
178 } usb_audio_ctrl_t;
179
180 enum {
181 CTL_VOLUME_MONO = 0,
182 CTL_VOLUME_STERO,
183 CTL_REC_MONO,
184 CTL_REC_STERO,
185 CTL_REC_SRC,
186 CTL_MONITOR_GAIN,
187 CTL_MIC_BOOST,
188 CTL_NUM
189 };
190
191 #define USB_AC_ENG_MAX 2
192
193 /* usb_ac soft state */
194 struct usb_ac_state {
195
196 dev_info_t *usb_ac_dip;
197 uint_t usb_ac_instance;
198 usb_log_handle_t usb_ac_log_handle;
199
200 uint_t usb_ac_dev_state;
201 uint_t usb_ac_ifno;
202 kmutex_t usb_ac_mutex;
203
204 usb_client_dev_data_t *usb_ac_dev_data; /* registration data */
205 audio_dev_t *usb_ac_audio_dev;
206
207
208
209
210 usb_audio_eng_t engines[USB_AC_ENG_MAX];
211
212
213
214 int flags;
215 usb_audio_ctrl_t *controls[CTL_NUM];
216
217 /* descriptors */
218 usb_if_descr_t usb_ac_if_descr;
219
220 /* unit number array, indexed by unit ID */
221 uint_t usb_ac_max_unit;
222 usb_ac_unit_list_t *usb_ac_units;
223
224 /* adjacency matrix for reflecting connections */
225 uchar_t **usb_ac_connections;
226 size_t usb_ac_connections_len;
227 uchar_t *usb_ac_connections_a;
228 size_t usb_ac_connections_a_len;
229 uchar_t *usb_ac_unit_type;
230 uchar_t *usb_ac_traverse_path;
231 uchar_t usb_ac_traverse_path_index;
232
233 /* port types, eg LINE IN, Micr, Speakers */
234 uint64_t usb_ac_input_ports;
235 uint64_t usb_ac_output_ports;
236
237 /* pipe handle */
238 usb_pipe_handle_t usb_ac_default_ph;
239
240 /* serial access */
241 usb_serialization_t usb_ac_ser_acc;
242
243 /* power management */
244 usb_ac_power_t *usb_ac_pm; /* power capabilities */
245
246 /* mixer registration data */
247 uint_t usb_ac_registered_with_mixer;
248
249 /* plumbing management */
250 uint_t usb_ac_plumbing_state;
251 ushort_t usb_ac_busy_count;
252 usb_ac_plumbed_t usb_ac_plumbed[USB_AC_MAX_PLUMBED];
253
254 /* Current plumbed module index to usb_ac_plumbed structure */
255 int usb_ac_current_plumbed_index;
256
257 /* per streams interface info */
258 usb_ac_streams_info_t usb_ac_streams[USB_AC_MAX_AS_PLUMBED];
259
260
261 ddi_taskq_t *tqp;
262
263 char dstr[64];
264 };
265
266 /* warlock directives, stable data */
267 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_state_t))
268 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_power_t))
269 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_plumbed_t))
270 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_eng_t::lock, usb_audio_eng_t))
271 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_eng_t::lock, usb_audio_format_t))
272 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_ctrl_t::ctrl_mutex, usb_audio_ctrl_t))
273
274
275 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dip))
276 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ser_acc))
277 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_pm))
278 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_instance))
279 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_default_ph))
280 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_log_handle))
281 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_if_descr))
282 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dev_data))
283 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ifno))
284 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::flags))
285 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_input_ports))
286 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::engines))
287 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_audio_dev))
288 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::controls))
289
290 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::af_eflags))
291 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::streams))
292 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::statep))
293 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::fmt))
294 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::fragfr))
295 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::frsmshift))
296 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::started))
297 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::af_engp))
298 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::io_count))
299 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::intrate))
300
301 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::statep))
302 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::af_ctrlp))
303 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::cval))
304
305 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_plumbed_t::acp_tqp))
306 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_plumbed_t::acp_uacp))
307
308 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_format_t::ch))
309
310 /* usb_ac driver only care about two states: plumbed or unplumbed */
311 #define USB_AC_STATE_UNPLUMBED 0
312 #define USB_AC_STATE_PLUMBED 1
313 #define USB_AC_STATE_PLUMBED_RESTORING 2
314
315 /* Default pipe states */
316 #define USB_AC_DEF_CLOSED 0
317 #define USB_AC_DEF_OPENED 1
318
319 #define USB_AC_BUFFER_SIZE 256 /* descriptor buffer size */
320
321
322 /*
323 * delay before restoring state
324 */
325 #define USB_AC_RESTORE_DELAY drv_usectohz(1000000)
326
327 /* value for acp_driver */
328 #define USB_AS_PLUMBED 1
329 #define USB_AH_PLUMBED 2
330 #define UNKNOWN_PLUMBED 3
331
332 /* other useful macros */
333 #define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
334
335
336
337
338
339
340 #define AF_REGISTERED 0x1
341 #define AD_SETUP 0x10
342
343
344 int usb_audio_attach(usb_ac_state_t *);
345 /*
346 * framework gain range
347 */
348 #define AUDIO_CTRL_STEREO_VAL(l, r) (((l) & 0xff) | (((r) & 0xff) << 8))
349 #define AUDIO_CTRL_STEREO_LEFT(v) ((uint8_t)((v) & 0xff))
350 #define AUDIO_CTRL_STEREO_RIGHT(v) ((uint8_t)(((v) >> 8) & 0xff))
351
352
353 #define AF_MAX_GAIN 100
354 #define AF_MIN_GAIN 0
355
356
357
358 int usb_ac_get_audio(void *, void *, int);
359
360 void usb_ac_send_audio(void *, void *, int);
361
362 void usb_ac_stop_play(usb_ac_state_t *, usb_audio_eng_t *);
363
364
365 #ifdef __cplusplus
366 }
367 #endif
368
369 #endif /* _SYS_USB_AC_H */