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