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 2009 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 
161 	kmutex_t	lock;
162 } usb_audio_eng_t;
163 
164 
165 /* limits */
166 #define	USB_AC_MAX_PLUMBED		3	/* play, record, hid */
167 #define	USB_AC_MAX_AS_PLUMBED		2	/* play, record */
168 typedef struct usb_ac_state  usb_ac_state_t;
169 typedef struct usb_audio_ctrl {
170 	audio_ctrl_t		*af_ctrlp;	/* framework handle */
171 	usb_ac_state_t		*statep;
172 
173 	kmutex_t	ctrl_mutex;
174 	uint64_t		cval;		/* current control value */
175 } usb_audio_ctrl_t;
176 
177 enum {
178 	CTL_VOLUME_MONO = 0,
179 	CTL_VOLUME_STERO,
180 	CTL_REC_MONO,
181 	CTL_REC_STERO,
182 	CTL_REC_SRC,
183 	CTL_MONITOR_GAIN,
184 	CTL_MIC_BOOST,
185 	CTL_NUM
186 };
187 
188 #define	USB_AC_ENG_MAX   2
189 
190 /* usb_ac soft state */
191 struct usb_ac_state {
192 
193 	dev_info_t		*usb_ac_dip;
194 	uint_t			usb_ac_instance;
195 	usb_log_handle_t	usb_ac_log_handle;
196 
197 	uint_t			usb_ac_dev_state;
198 	uint_t			usb_ac_ifno;
199 	kmutex_t		usb_ac_mutex;
200 
201 	usb_client_dev_data_t	*usb_ac_dev_data; /* registration data */
202 	audio_dev_t		*usb_ac_audio_dev;
203 
204 
205 
206 
207 	usb_audio_eng_t  engines[USB_AC_ENG_MAX];
208 
209 
210 
211 	int		flags;
212 	usb_audio_ctrl_t	*controls[CTL_NUM];
213 
214 	/* descriptors */
215 	usb_if_descr_t		usb_ac_if_descr;
216 
217 	/* unit number array, indexed by unit ID */
218 	uint_t			usb_ac_max_unit;
219 	usb_ac_unit_list_t	*usb_ac_units;
220 
221 	/* adjacency matrix for reflecting connections */
222 	uchar_t			**usb_ac_connections;
223 	size_t			usb_ac_connections_len;
224 	uchar_t			*usb_ac_connections_a;
225 	size_t			usb_ac_connections_a_len;
226 	uchar_t			*usb_ac_unit_type;
227 	uchar_t			*usb_ac_traverse_path;
228 	uchar_t			usb_ac_traverse_path_index;
229 
230 	/* port types, eg LINE IN, Micr, Speakers */
231 	uint64_t			usb_ac_input_ports;
232 	uint64_t			usb_ac_output_ports;
233 
234 	/* pipe handle */
235 	usb_pipe_handle_t	usb_ac_default_ph;
236 
237 	/* serial access */
238 	usb_serialization_t	usb_ac_ser_acc;
239 
240 	/* power management */
241 	usb_ac_power_t		*usb_ac_pm; /* power capabilities */
242 
243 	/* mixer registration data */
244 	uint_t			usb_ac_registered_with_mixer;
245 
246 	/* plumbing management */
247 	uint_t			usb_ac_plumbing_state;
248 	ushort_t		usb_ac_busy_count;
249 	usb_ac_plumbed_t	usb_ac_plumbed[USB_AC_MAX_PLUMBED];
250 
251 	/* Current plumbed module index to usb_ac_plumbed structure */
252 	int			usb_ac_current_plumbed_index;
253 
254 	/* per streams interface info */
255 	usb_ac_streams_info_t	usb_ac_streams[USB_AC_MAX_AS_PLUMBED];
256 
257 
258 	ddi_taskq_t		*tqp;
259 
260 	char			dstr[64];
261 };
262 
263 /* warlock directives, stable data */
264 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_state_t))
265 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_power_t))
266 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_plumbed_t))
267 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_eng_t::lock, usb_audio_eng_t))
268 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_eng_t::lock, usb_audio_format_t))
269 _NOTE(MUTEX_PROTECTS_DATA(usb_audio_ctrl_t::ctrl_mutex, usb_audio_ctrl_t))
270 
271 
272 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dip))
273 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ser_acc))
274 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_pm))
275 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_instance))
276 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_default_ph))
277 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_log_handle))
278 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_if_descr))
279 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dev_data))
280 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ifno))
281 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::flags))
282 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_input_ports))
283 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::engines))
284 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_audio_dev))
285 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::controls))
286 
287 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::af_eflags))
288 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::streams))
289 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::statep))
290 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::fmt))
291 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::fragfr))
292 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::frsmshift))
293 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::started))
294 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::af_engp))
295 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::io_count))
296 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_eng_t::intrate))
297 
298 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::statep))
299 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::af_ctrlp))
300 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_ctrl_t::cval))
301 
302 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_plumbed_t::acp_tqp))
303 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_plumbed_t::acp_uacp))
304 
305 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_audio_format_t::ch))
306 
307 /* usb_ac driver only care about two states:  plumbed or unplumbed */
308 #define	USB_AC_STATE_UNPLUMBED		0
309 #define	USB_AC_STATE_PLUMBED		1
310 #define	USB_AC_STATE_PLUMBED_RESTORING	2
311 
312 /* Default pipe states */
313 #define	USB_AC_DEF_CLOSED		0
314 #define	USB_AC_DEF_OPENED		1
315 
316 #define	USB_AC_BUFFER_SIZE		256	/* descriptor buffer size */
317 
318 
319 /*
320  * delay before restoring state
321  */
322 #define	USB_AC_RESTORE_DELAY		drv_usectohz(1000000)
323 
324 /* value for acp_driver */
325 #define	USB_AS_PLUMBED	1
326 #define	USB_AH_PLUMBED	2
327 #define	UNKNOWN_PLUMBED	3
328 
329 /* other useful macros */
330 #define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
331 
332 
333 
334 
335 
336 
337 #define	AF_REGISTERED	0x1
338 #define	AD_SETUP	0x10
339 
340 
341 int usb_audio_attach(usb_ac_state_t *);
342 /*
343  * framework gain range
344  */
345 #define	AUDIO_CTRL_STEREO_VAL(l, r)	(((l) & 0xff) | (((r) & 0xff) << 8))
346 #define	AUDIO_CTRL_STEREO_LEFT(v)	((uint8_t)((v) & 0xff))
347 #define	AUDIO_CTRL_STEREO_RIGHT(v)	((uint8_t)(((v) >> 8) & 0xff))
348 
349 
350 #define	AF_MAX_GAIN	100
351 #define	AF_MIN_GAIN	0
352 
353 
354 
355 int usb_ac_get_audio(void *, void *, int);
356 
357 void usb_ac_send_audio(void *, void *, int);
358 
359 void usb_ac_stop_play(usb_ac_state_t *, usb_audio_eng_t *);
360 
361 
362 #ifdef __cplusplus
363 }
364 #endif
365 
366 #endif	/* _SYS_USB_AC_H */
367