f3f9d1fb95
On devices that can assign interrupt IN, bulk IN and bulk OUT endpoints this change results in the serial interface working out of the box on Linux and Windows. On Linux it is registered as ttyACM device and on Windows it is assigned a COM port number. On devices that cannot assign the interrupt IN this change won't have any effect. Implement minimum required interface control requests. Respond with whatever line coding was set to make terminal programs happy. Change-Id: Id7d3899d8546e45d7cb4ecc3fe464908cb59e810
471 lines
17 KiB
C
471 lines
17 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) by Linux Kernel Developers
|
|
*
|
|
* Based on code from the Linux Kernel
|
|
* available at http://www.kernel.org
|
|
* Original file: <kernel>/include/linux/usb/ch9.h
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/*
|
|
* This file holds USB constants and structures that are needed for
|
|
* USB device APIs. These are used by the USB device model, which is
|
|
* defined in chapter 9 of the USB 2.0 specification and in the
|
|
* Wireless USB 1.0 (spread around). Linux has several APIs in C that
|
|
* need these:
|
|
*
|
|
* - the master/host side Linux-USB kernel driver API;
|
|
* - the "usbfs" user space API; and
|
|
* - the Linux "gadget" slave/device/peripheral side driver API.
|
|
*
|
|
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
|
|
* act either as a USB master/host or as a USB slave/device. That means
|
|
* the master and slave side APIs benefit from working well together.
|
|
*
|
|
* There's also "Wireless USB", using low power short range radios for
|
|
* peripheral interconnection but otherwise building on the USB framework.
|
|
*
|
|
* Note all descriptors are declared '__attribute__((packed))' so that:
|
|
*
|
|
* [a] they never get padded, either internally (USB spec writers
|
|
* probably handled that) or externally;
|
|
*
|
|
* [b] so that accessing bigger-than-a-bytes fields will never
|
|
* generate bus errors on any platform, even when the location of
|
|
* its descriptor inside a bundle isn't "naturally aligned", and
|
|
*
|
|
* [c] for consistency, removing all doubt even when it appears to
|
|
* someone that the two other points are non-issues for that
|
|
* particular descriptor type.
|
|
*/
|
|
|
|
#ifndef _CH9_H_
|
|
#define _CH9_H_
|
|
|
|
#include <inttypes.h>
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* CONTROL REQUEST SUPPORT */
|
|
|
|
/*
|
|
* USB directions
|
|
*
|
|
* This bit flag is used in endpoint descriptors' bEndpointAddress field.
|
|
* It's also one of three fields in control requests bRequestType.
|
|
*/
|
|
#define USB_DIR_OUT 0 /* to device */
|
|
#define USB_DIR_IN 0x80 /* to host */
|
|
|
|
/*
|
|
* USB types, the second of three bRequestType fields
|
|
*/
|
|
#define USB_TYPE_MASK (0x03 << 5)
|
|
#define USB_TYPE_STANDARD (0x00 << 5)
|
|
#define USB_TYPE_CLASS (0x01 << 5)
|
|
#define USB_TYPE_VENDOR (0x02 << 5)
|
|
#define USB_TYPE_RESERVED (0x03 << 5)
|
|
|
|
/*
|
|
* USB recipients, the third of three bRequestType fields
|
|
*/
|
|
#define USB_RECIP_MASK 0x1f
|
|
#define USB_RECIP_DEVICE 0x00
|
|
#define USB_RECIP_INTERFACE 0x01
|
|
#define USB_RECIP_ENDPOINT 0x02
|
|
#define USB_RECIP_OTHER 0x03
|
|
|
|
/*
|
|
* Standard requests, for the bRequest field of a SETUP packet.
|
|
*
|
|
* These are qualified by the bRequestType field, so that for example
|
|
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
|
|
* by a GET_STATUS request.
|
|
*/
|
|
#define USB_REQ_GET_STATUS 0x00
|
|
#define USB_REQ_CLEAR_FEATURE 0x01
|
|
#define USB_REQ_SET_FEATURE 0x03
|
|
#define USB_REQ_SET_ADDRESS 0x05
|
|
#define USB_REQ_GET_DESCRIPTOR 0x06
|
|
#define USB_REQ_SET_DESCRIPTOR 0x07
|
|
#define USB_REQ_GET_CONFIGURATION 0x08
|
|
#define USB_REQ_SET_CONFIGURATION 0x09
|
|
#define USB_REQ_GET_INTERFACE 0x0A
|
|
#define USB_REQ_SET_INTERFACE 0x0B
|
|
#define USB_REQ_SYNCH_FRAME 0x0C
|
|
/*
|
|
* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
|
|
* are read as a bit array returned by USB_REQ_GET_STATUS. (So there
|
|
* are at most sixteen features of each type.) Hubs may also support a
|
|
* new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend.
|
|
*/
|
|
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
|
|
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
|
|
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
|
|
#define USB_DEVICE_BATTERY 2 /* (wireless) */
|
|
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
|
|
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
|
|
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
|
|
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
|
|
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
|
|
|
|
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
|
|
|
|
|
|
/**
|
|
* struct usb_ctrlrequest - SETUP data for a USB device control request
|
|
* @bRequestType: matches the USB bmRequestType field
|
|
* @bRequest: matches the USB bRequest field
|
|
* @wValue: matches the USB wValue field (le16 byte order)
|
|
* @wIndex: matches the USB wIndex field (le16 byte order)
|
|
* @wLength: matches the USB wLength field (le16 byte order)
|
|
*
|
|
* This structure is used to send control requests to a USB device. It matches
|
|
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
|
|
* USB spec for a fuller description of the different fields, and what they are
|
|
* used for.
|
|
*
|
|
* Note that the driver for any interface can issue control requests.
|
|
* For most devices, interfaces don't coordinate with each other, so
|
|
* such requests may be made at any time.
|
|
*/
|
|
struct usb_ctrlrequest {
|
|
uint8_t bRequestType;
|
|
uint8_t bRequest;
|
|
uint16_t wValue;
|
|
uint16_t wIndex;
|
|
uint16_t wLength;
|
|
} __attribute__ ((packed));
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/*
|
|
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
|
|
* (rarely) accepted by SET_DESCRIPTOR.
|
|
*
|
|
* Note that all multi-byte values here are encoded in little endian
|
|
* byte order "on the wire". But when exposed through Linux-USB APIs,
|
|
* they've been converted to cpu byte order.
|
|
*/
|
|
|
|
/*
|
|
* Descriptor types ... USB 2.0 spec table 9.5
|
|
*/
|
|
#define USB_DT_DEVICE 0x01
|
|
#define USB_DT_CONFIG 0x02
|
|
#define USB_DT_STRING 0x03
|
|
#define USB_DT_INTERFACE 0x04
|
|
#define USB_DT_ENDPOINT 0x05
|
|
#define USB_DT_DEVICE_QUALIFIER 0x06
|
|
#define USB_DT_OTHER_SPEED_CONFIG 0x07
|
|
#define USB_DT_INTERFACE_POWER 0x08
|
|
/* these are from a minor usb 2.0 revision (ECN) */
|
|
#define USB_DT_OTG 0x09
|
|
#define USB_DT_DEBUG 0x0a
|
|
#define USB_DT_INTERFACE_ASSOCIATION 0x0b
|
|
/* these are from the Wireless USB spec */
|
|
#define USB_DT_SECURITY 0x0c
|
|
#define USB_DT_KEY 0x0d
|
|
#define USB_DT_ENCRYPTION_TYPE 0x0e
|
|
#define USB_DT_BOS 0x0f
|
|
#define USB_DT_DEVICE_CAPABILITY 0x10
|
|
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
|
|
#define USB_DT_WIRE_ADAPTER 0x21
|
|
#define USB_DT_RPIPE 0x22
|
|
#define USB_DT_CS_RADIO_CONTROL 0x23
|
|
|
|
/* Conventional codes for class-specific descriptors. The convention is
|
|
* defined in the USB "Common Class" Spec (3.11). Individual class specs
|
|
* are authoritative for their usage, not the "common class" writeup.
|
|
*/
|
|
#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE)
|
|
#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG)
|
|
#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING)
|
|
#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE)
|
|
#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT)
|
|
|
|
/* All standard descriptors have these 2 fields at the beginning */
|
|
struct usb_descriptor_header {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_DEVICE: Device descriptor */
|
|
struct usb_device_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint16_t bcdUSB;
|
|
uint8_t bDeviceClass;
|
|
uint8_t bDeviceSubClass;
|
|
uint8_t bDeviceProtocol;
|
|
uint8_t bMaxPacketSize0;
|
|
uint16_t idVendor;
|
|
uint16_t idProduct;
|
|
uint16_t bcdDevice;
|
|
uint8_t iManufacturer;
|
|
uint8_t iProduct;
|
|
uint8_t iSerialNumber;
|
|
uint8_t bNumConfigurations;
|
|
} __attribute__ ((packed));
|
|
|
|
#define USB_DT_DEVICE_SIZE 18
|
|
|
|
|
|
/*
|
|
* Device and/or Interface Class codes
|
|
* as found in bDeviceClass or bInterfaceClass
|
|
* and defined by www.usb.org documents
|
|
*/
|
|
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
|
|
#define USB_CLASS_AUDIO 1
|
|
#define USB_CLASS_COMM 2
|
|
#define USB_CLASS_HID 3
|
|
#define USB_CLASS_PHYSICAL 5
|
|
#define USB_CLASS_STILL_IMAGE 6
|
|
#define USB_CLASS_PRINTER 7
|
|
#define USB_CLASS_MASS_STORAGE 8
|
|
#define USB_CLASS_HUB 9
|
|
#define USB_CLASS_CDC_DATA 0x0a
|
|
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
|
|
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
|
|
#define USB_CLASS_VIDEO 0x0e
|
|
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
|
#define USB_CLASS_MISC 0xef
|
|
#define USB_CLASS_APP_SPEC 0xfe
|
|
#define USB_CLASS_VENDOR_SPEC 0xff
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_CONFIG: Configuration descriptor information.
|
|
*
|
|
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
|
|
* descriptor type is different. Highspeed-capable devices can look
|
|
* different depending on what speed they're currently running. Only
|
|
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
|
|
* descriptors.
|
|
*/
|
|
struct usb_config_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint16_t wTotalLength;
|
|
uint8_t bNumInterfaces;
|
|
uint8_t bConfigurationValue;
|
|
uint8_t iConfiguration;
|
|
uint8_t bmAttributes;
|
|
uint8_t bMaxPower;
|
|
} __attribute__ ((packed));
|
|
|
|
#define USB_DT_CONFIG_SIZE 9
|
|
|
|
/* from config descriptor bmAttributes */
|
|
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
|
|
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
|
|
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
|
|
#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_STRING: String descriptor */
|
|
struct usb_string_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint16_t wString[]; /* UTF-16LE encoded */
|
|
} __attribute__ ((packed));
|
|
|
|
/* note that "string" zero is special, it holds language codes that
|
|
* the device supports, not Unicode characters.
|
|
*/
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_INTERFACE: Interface descriptor */
|
|
struct usb_interface_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint8_t bInterfaceNumber;
|
|
uint8_t bAlternateSetting;
|
|
uint8_t bNumEndpoints;
|
|
uint8_t bInterfaceClass;
|
|
uint8_t bInterfaceSubClass;
|
|
uint8_t bInterfaceProtocol;
|
|
uint8_t iInterface;
|
|
} __attribute__ ((packed));
|
|
|
|
#define USB_DT_INTERFACE_SIZE 9
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_ENDPOINT: Endpoint descriptor */
|
|
struct usb_endpoint_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint8_t bEndpointAddress;
|
|
uint8_t bmAttributes;
|
|
uint16_t wMaxPacketSize;
|
|
uint8_t bInterval;
|
|
} __attribute__ ((packed));
|
|
|
|
#define USB_DT_ENDPOINT_SIZE 7
|
|
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
|
|
|
|
|
|
/*
|
|
* Endpoints
|
|
*/
|
|
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
|
|
#define USB_ENDPOINT_DIR_MASK 0x80
|
|
|
|
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
|
|
#define USB_ENDPOINT_XFER_CONTROL 0
|
|
#define USB_ENDPOINT_XFER_ISOC 1
|
|
#define USB_ENDPOINT_XFER_BULK 2
|
|
#define USB_ENDPOINT_XFER_INT 3
|
|
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
|
|
struct usb_qualifier_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint16_t bcdUSB;
|
|
uint8_t bDeviceClass;
|
|
uint8_t bDeviceSubClass;
|
|
uint8_t bDeviceProtocol;
|
|
uint8_t bMaxPacketSize0;
|
|
uint8_t bNumConfigurations;
|
|
uint8_t bRESERVED;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_OTG (from OTG 1.0a supplement) */
|
|
struct usb_otg_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint8_t bmAttributes; /* support for HNP, SRP, etc */
|
|
} __attribute__ ((packed));
|
|
|
|
/* from usb_otg_descriptor.bmAttributes */
|
|
#define USB_OTG_SRP (1 << 0)
|
|
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
|
|
struct usb_debug_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
/* bulk endpoints with 8 byte maxpacket */
|
|
uint8_t bDebugInEndpoint;
|
|
uint8_t bDebugOutEndpoint;
|
|
} __attribute__((packed));
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
|
|
struct usb_interface_assoc_descriptor {
|
|
uint8_t bLength;
|
|
uint8_t bDescriptorType;
|
|
|
|
uint8_t bFirstInterface;
|
|
uint8_t bInterfaceCount;
|
|
uint8_t bFunctionClass;
|
|
uint8_t bFunctionSubClass;
|
|
uint8_t bFunctionProtocol;
|
|
uint8_t iFunction;
|
|
} __attribute__ ((packed));
|
|
|
|
#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/* USB 2.0 defines three speeds, here's how Linux identifies them */
|
|
|
|
enum usb_device_speed {
|
|
USB_SPEED_UNKNOWN = 0, /* enumerating */
|
|
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
|
|
USB_SPEED_HIGH, /* usb 2.0 */
|
|
USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
|
|
};
|
|
|
|
enum usb_device_state {
|
|
/* NOTATTACHED isn't in the USB spec, and this state acts
|
|
* the same as ATTACHED ... but it's clearer this way.
|
|
*/
|
|
USB_STATE_NOTATTACHED = 0,
|
|
|
|
/* chapter 9 and authentication (wireless) device states */
|
|
USB_STATE_ATTACHED,
|
|
USB_STATE_POWERED, /* wired */
|
|
USB_STATE_UNAUTHENTICATED, /* auth */
|
|
USB_STATE_RECONNECTING, /* auth */
|
|
USB_STATE_DEFAULT, /* limited function */
|
|
USB_STATE_ADDRESS,
|
|
USB_STATE_CONFIGURED, /* most functions */
|
|
|
|
USB_STATE_SUSPENDED
|
|
|
|
/* NOTE: there are actually four different SUSPENDED
|
|
* states, returning to POWERED, DEFAULT, ADDRESS, or
|
|
* CONFIGURED respectively when SOF tokens flow again.
|
|
* At this level there's no difference between L1 and L2
|
|
* suspend states. (L2 being original USB 1.1 suspend.)
|
|
*/
|
|
};
|
|
|
|
/**
|
|
* struct usb_string - wraps a C string and its USB id
|
|
* @id:the (nonzero) ID for this string
|
|
* @s:the string, in UTF-8 encoding
|
|
*
|
|
* If you're using usb_gadget_get_string(), use this to wrap a string
|
|
* together with its ID.
|
|
*/
|
|
struct usb_string {
|
|
uint8_t id;
|
|
const char* s;
|
|
};
|
|
|
|
/**
|
|
* struct usb_gadget_strings - a set of USB strings in a given language
|
|
* @language:identifies the strings' language (0x0409 for en-us)
|
|
* @strings:array of strings with their ids
|
|
*
|
|
* If you're using usb_gadget_get_string(), use this to wrap all the
|
|
* strings for a given language.
|
|
*/
|
|
struct usb_gadget_strings {
|
|
uint16_t language; /* 0x0409 for en-us */
|
|
struct usb_string* strings;
|
|
};
|
|
|
|
#endif /*_CH9_H_*/
|