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 */