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 */
363