usb_ac.h revision 7492:2387323b838f
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 2008 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/usb/usba/usbai_private.h>
37
38/* driver specific macros */
39#define	USB_AC_HIWATER		(AM_MAX_QUEUED_MSGS_SIZE)
40#define	USB_AC_LOWATER		(32*1024)
41
42
43/* structure for each unit described by descriptors */
44typedef 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 */
59typedef struct usb_ac_plumbed {
60	dev_info_t	*acp_dip;	/* devinfo pointer */
61	uint_t		acp_ifno;	/* interface number */
62	int		acp_linkid;	/* link ID for plumbing */
63	int		acp_driver;	/* Plumbed driver, see value below */
64	queue_t		*acp_lrq;	/* lower read queue */
65	queue_t		*acp_lwq;	/* lower write queue */
66	void		*acp_data;	/* ptr to streams or hid data */
67} usb_ac_plumbed_t;
68
69
70/*
71 * request structure to usb_as: info per MCTL request;
72 * only one active at a time.
73 */
74typedef struct usb_ac_to_as_req {
75	int		acr_wait_flag;	/* an mblk sent wait on this flag */
76	kcondvar_t	acr_cv;		/* an mblk sent; wait on this cv */
77	mblk_t		*acr_reply_mp;	/* response to current request */
78	usb_audio_formats_t acr_curr_format; /* format data from mixer */
79	int		acr_curr_dir;
80} usb_ac_to_as_req_t;
81
82
83/* registration and plumbing info per streaming interface */
84typedef struct usb_ac_streams_info {
85					/* ptr to entry in plumbed list */
86	usb_ac_plumbed_t *acs_plumbed;
87					/* valid registration data rcvd */
88	uint_t		acs_rcvd_reg_data;
89					/* pointer to registration data */
90	usb_as_registration_t *acs_streams_reg;
91
92	/* request structure to usb_as; one active at a time */
93	usb_ac_to_as_req_t acs_ac_to_as_req;
94
95	/* Multiple command management */
96	int		acs_setup_teardown_count;
97
98	usb_audio_formats_t acs_cur_fmt; /* format data from mixer */
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
123/* limits */
124#define	USB_AC_MAX_PLUMBED		3	/* play, record, hid */
125#define	USB_AC_MAX_AS_PLUMBED		2	/* play, record */
126
127/* usb_ac soft state */
128typedef struct usb_ac_state {
129	dev_info_t		*usb_ac_dip;
130	uint_t			usb_ac_instance;
131	usb_log_handle_t	usb_ac_log_handle;
132
133	uint_t			usb_ac_dev_state;
134	uint_t			usb_ac_ifno;
135	kmutex_t		usb_ac_mutex;
136
137	usb_client_dev_data_t	*usb_ac_dev_data; /* registration data */
138
139	/* audio framework */
140	audiohdl_t		usb_ac_audiohdl;
141	am_ad_info_t		usb_ac_am_ad_info;
142	audio_info_t		usb_ac_am_ad_defaults;
143
144	/* descriptors */
145	usb_if_descr_t		usb_ac_if_descr;
146
147	/* unit number array, indexed by unit ID */
148	uint_t			usb_ac_max_unit;
149	usb_ac_unit_list_t	*usb_ac_units;
150
151	/* adjacency matrix for reflecting connections */
152	uchar_t			**usb_ac_connections;
153	size_t			usb_ac_connections_len;
154	uchar_t			*usb_ac_connections_a;
155	size_t			usb_ac_connections_a_len;
156	uchar_t			*usb_ac_unit_type;
157	uchar_t			*usb_ac_traverse_path;
158	uchar_t			usb_ac_traverse_path_index;
159
160	/* port types, eg LINE IN, Micr, Speakers */
161	uint_t			usb_ac_input_ports;
162	uint_t			usb_ac_output_ports;
163
164	/* pipe handle */
165	usb_pipe_handle_t	usb_ac_default_ph;
166
167	/* streams management */
168	queue_t			*usb_ac_rq;		/* read q ptr */
169	queue_t			*usb_ac_wq;		/* write q ptr */
170	dev_t			usb_ac_dev;	/* dev_t of plumbing open */
171
172	/* serial access */
173	usb_serialization_t	usb_ac_ser_acc;
174
175	/* power management */
176	usb_ac_power_t		*usb_ac_pm; /* power capabilities */
177
178	/* mixer registration data */
179	uint_t			usb_ac_mixer_mode_enable;
180	uint_t			usb_ac_registered_with_mixer;
181
182	/* plumbing management */
183	int			usb_ac_mux_minor;
184	uint_t			usb_ac_plumbing_state;
185	ldi_handle_t		usb_ac_mux_lh;
186	ushort_t		usb_ac_busy_count;
187	usb_ac_plumbed_t	usb_ac_plumbed[USB_AC_MAX_PLUMBED];
188
189	/* Current plumbed module index to usb_ac_plumbed structure */
190	int			usb_ac_current_plumbed_index;
191
192	/* per streams interface info */
193	usb_ac_streams_info_t	usb_ac_streams[USB_AC_MAX_AS_PLUMBED];
194
195	/*
196	 * preserve streams registration because the mixer does not
197	 * copy registration data
198	 */
199	usb_as_registration_t	usb_ac_streams_reg[USB_AC_MAX_AS_PLUMBED];
200} usb_ac_state_t;
201
202typedef struct usb_ac_state_space {
203	void			*sp;	/* soft state for the instance */
204				/* ptr to usb_ac_restore_audio_state */
205	int			(*restore_func)
206					(usb_ac_state_t *, int);
207				/* ptr to usb_ac_get_featureID */
208	uint_t			(* get_featureID_func)
209					(usb_ac_state_t *, uchar_t,
210					uint_t, uint_t);
211				/* ptr to the usb_ac entry points */
212	am_ad_entry_t		*ac_entryp;
213				/* ptr to pm_busy/idle calls */
214	void			(*pm_busy_component)
215					(usb_ac_state_t *);
216	void			(*pm_idle_component)
217					(usb_ac_state_t *);
218} usb_ac_state_space_t;
219
220/* warlock directives, stable data */
221_NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_state_t))
222_NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_power_t))
223_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dip))
224_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ser_acc))
225_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_pm))
226_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_instance))
227_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_default_ph))
228_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_log_handle))
229_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_if_descr))
230_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_audiohdl))
231_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dev_data))
232_NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ifno))
233
234/* usb_ac driver only care about two states:  plumbed or unplumbed */
235#define	USB_AC_STATE_UNPLUMBED		0
236#define	USB_AC_STATE_PLUMBED		1
237#define	USB_AC_STATE_PLUMBED_RESTORING	2
238
239/* Default pipe states */
240#define	USB_AC_DEF_CLOSED		0
241#define	USB_AC_DEF_OPENED		1
242
243#define	USB_AC_BUFFER_SIZE		256	/* descriptor buffer size */
244
245
246/*
247 * delay before restoring state
248 */
249#define	USB_AC_RESTORE_DELAY		drv_usectohz(1000000)
250
251/* value for acp_driver */
252#define	USB_AS_PLUMBED	1
253#define	USB_AH_PLUMBED	2
254#define	UNKNOWN_PLUMBED	3
255
256/* other useful macros */
257#define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
258
259#ifdef __cplusplus
260}
261#endif
262
263#endif	/* _SYS_USB_AC_H */
264