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 int usb_ac_open(dev_info_t *);
39 void usb_ac_close(dev_info_t *);
40 
41 
42 /* structure for each unit described by descriptors */
43 typedef struct usb_ac_unit_list {
44 	uint_t		acu_type;
45 	void		*acu_descriptor;
46 	size_t		acu_descr_length;
47 } usb_ac_unit_list_t;
48 
49 #define	USB_AC_ID_NONE			0
50 
51 #define	USB_AC_FIND_ONE			0
52 #define	USB_AC_FIND_ALL			1
53 #define	USB_AC_MAX_DEPTH		8
54 
55 /*
56  * plumbing data; info per plumbed module
57  */
58 typedef struct usb_ac_plumbed {
59 	struct usb_ac_state *acp_uacp;	/* usb_ac state pointer */
60 	dev_info_t	*acp_dip;	/* devinfo pointer */
61 	uint_t		acp_ifno;	/* interface number */
62 	int		acp_driver;	/* Plumbed driver, see value below */
63 
64 	ldi_handle_t	acp_lh;		/* ldi handle of plumbed driver */
65 	dev_t		acp_devt;	/* devt of plumbed driver */
66 	ddi_taskq_t	*acp_tqp;	/* taskq for I/O to plumbed driver */
67 	int		acp_flags;
68 #define	ACP_ENABLED	1
69 
70 	void		*acp_data;	/* ptr to streams or hid data */
71 } usb_ac_plumbed_t;
72 
73 
74 /*
75  * request structure to usb_as: info per MCTL request;
76  * only one active at a time.
77  */
78 typedef struct usb_ac_to_as_req {
79 	usb_audio_formats_t acr_curr_format; /* format data from mixer */
80 	int		acr_curr_dir;
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 	/* request structure to usb_as; one active at a time */
94 	usb_ac_to_as_req_t acs_ac_to_as_req;
95 
96 	/* Multiple command management */
97 	int		acs_setup_teardown_count;
98 
99 	usb_audio_formats_t acs_cur_fmt; /* format data from mixer */
100 } usb_ac_streams_info_t;
101 
102 
103 /* power state */
104 typedef struct usb_ac_power {
105 	void		*acpm_state;	/* points back to usb_ac_state */
106 	int		acpm_pm_busy;	/* device busy accounting */
107 	uint8_t		acpm_wakeup_enabled;
108 
109 	/* this is the bit mask of the power states that device has */
110 	uint8_t		acpm_pwr_states;
111 
112 	/* wakeup and power transistion capabilites of an interface */
113 	uint8_t		acpm_capabilities;
114 
115 	/* current power level the device is in */
116 	uint8_t		acpm_current_power;
117 } usb_ac_power_t;
118 
119 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_state))
120 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_wakeup_enabled))
121 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_pwr_states))
122 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_power_t::acpm_capabilities))
123 
124 /* limits */
125 #define	USB_AC_MAX_PLUMBED		3	/* play, record, hid */
126 #define	USB_AC_MAX_AS_PLUMBED		2	/* play, record */
127 
128 /* usb_ac soft state */
129 typedef struct usb_ac_state {
130 	dev_info_t		*usb_ac_dip;
131 	uint_t			usb_ac_instance;
132 	usb_log_handle_t	usb_ac_log_handle;
133 
134 	uint_t			usb_ac_dev_state;
135 	uint_t			usb_ac_ifno;
136 	kmutex_t		usb_ac_mutex;
137 
138 	usb_client_dev_data_t	*usb_ac_dev_data; /* registration data */
139 
140 	/* audio framework */
141 	audiohdl_t		usb_ac_audiohdl;
142 	am_ad_info_t		usb_ac_am_ad_info;
143 	audio_info_t		usb_ac_am_ad_defaults;
144 
145 	/* descriptors */
146 	usb_if_descr_t		usb_ac_if_descr;
147 
148 	/* unit number array, indexed by unit ID */
149 	uint_t			usb_ac_max_unit;
150 	usb_ac_unit_list_t	*usb_ac_units;
151 
152 	/* adjacency matrix for reflecting connections */
153 	uchar_t			**usb_ac_connections;
154 	size_t			usb_ac_connections_len;
155 	uchar_t			*usb_ac_connections_a;
156 	size_t			usb_ac_connections_a_len;
157 	uchar_t			*usb_ac_unit_type;
158 	uchar_t			*usb_ac_traverse_path;
159 	uchar_t			usb_ac_traverse_path_index;
160 
161 	/* port types, eg LINE IN, Micr, Speakers */
162 	uint_t			usb_ac_input_ports;
163 	uint_t			usb_ac_output_ports;
164 
165 	/* pipe handle */
166 	usb_pipe_handle_t	usb_ac_default_ph;
167 
168 	/* serial access */
169 	usb_serialization_t	usb_ac_ser_acc;
170 
171 	/* power management */
172 	usb_ac_power_t		*usb_ac_pm; /* power capabilities */
173 
174 	/* mixer registration data */
175 	uint_t			usb_ac_registered_with_mixer;
176 
177 	/* plumbing management */
178 	uint_t			usb_ac_plumbing_state;
179 	ushort_t		usb_ac_busy_count;
180 	usb_ac_plumbed_t	usb_ac_plumbed[USB_AC_MAX_PLUMBED];
181 
182 	/* Current plumbed module index to usb_ac_plumbed structure */
183 	int			usb_ac_current_plumbed_index;
184 
185 	/* per streams interface info */
186 	usb_ac_streams_info_t	usb_ac_streams[USB_AC_MAX_AS_PLUMBED];
187 
188 	/*
189 	 * preserve streams registration because the mixer does not
190 	 * copy registration data
191 	 */
192 	usb_as_registration_t	usb_ac_streams_reg[USB_AC_MAX_AS_PLUMBED];
193 
194 	ddi_taskq_t		*tqp;
195 
196 	char			dstr[64];
197 } usb_ac_state_t;
198 
199 /* warlock directives, stable data */
200 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_state_t))
201 _NOTE(MUTEX_PROTECTS_DATA(usb_ac_state_t::usb_ac_mutex, usb_ac_power_t))
202 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dip))
203 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ser_acc))
204 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_pm))
205 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_instance))
206 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_default_ph))
207 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_log_handle))
208 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_if_descr))
209 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_audiohdl))
210 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_dev_data))
211 _NOTE(DATA_READABLE_WITHOUT_LOCK(usb_ac_state_t::usb_ac_ifno))
212 
213 /* usb_ac driver only care about two states:  plumbed or unplumbed */
214 #define	USB_AC_STATE_UNPLUMBED		0
215 #define	USB_AC_STATE_PLUMBED		1
216 #define	USB_AC_STATE_PLUMBED_RESTORING	2
217 
218 /* Default pipe states */
219 #define	USB_AC_DEF_CLOSED		0
220 #define	USB_AC_DEF_OPENED		1
221 
222 #define	USB_AC_BUFFER_SIZE		256	/* descriptor buffer size */
223 
224 
225 /*
226  * delay before restoring state
227  */
228 #define	USB_AC_RESTORE_DELAY		drv_usectohz(1000000)
229 
230 /* value for acp_driver */
231 #define	USB_AS_PLUMBED	1
232 #define	USB_AH_PLUMBED	2
233 #define	UNKNOWN_PLUMBED	3
234 
235 /* other useful macros */
236 #define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 
242 #endif	/* _SYS_USB_AC_H */
243