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