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
32extern "C" {
33#endif
34
35#include <sys/sunldi.h>
36#include <sys/sysmacros.h>
37#include <sys/usb/usba/usbai_private.h>
38
39
40int usb_ac_open(dev_info_t *);
41void usb_ac_close(dev_info_t *);
42
43
44/* structure for each unit described by descriptors */
45typedef 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 */
60typedef 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 */
80typedef 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 */
86typedef 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 */
103typedef 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
123typedef 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
131typedef 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 */
172typedef struct usb_ac_state  usb_ac_state_t;
173typedef 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
181enum {
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 */
195struct 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
337int 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
351int usb_ac_get_audio(void *, void *, int);
352
353void usb_ac_send_audio(void *, void *, int);
354
355void 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