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