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