Update to Hekate bdk 5.5.0, prelim Mariko support

This commit is contained in:
shchmue 2020-12-04 11:20:01 -07:00
parent 04378b322d
commit 5d101cad50
89 changed files with 12779 additions and 2210 deletions

View file

@ -0,0 +1,238 @@
/*
* USB driver for Tegra X1
*
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _USB_DESCRIPTORS_TYPES_H_
#define _USB_DESCRIPTORS_TYPES_H_
#include <utils/types.h>
typedef enum {
USB_DESCRIPTOR_DEVICE = 1,
USB_DESCRIPTOR_CONFIGURATION = 2,
USB_DESCRIPTOR_STRING = 3,
USB_DESCRIPTOR_INTERFACE = 4,
USB_DESCRIPTOR_ENDPOINT = 5,
USB_DESCRIPTOR_DEVICE_QUALIFIER = 6,
USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7,
USB_DESCRIPTOR_INTERFACE_POWER = 8,
USB_DESCRIPTOR_INTERFACE_OTG = 9,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT = 15,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP = 16,
USB_DESCRIPTOR_HID = 33,
USB_DESCRIPTOR_HID_REPORT = 34
} usb_desc_type_t;
typedef enum {
USB_DESCRIPTOR_MS_COMPAT_ID = 4,
USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES = 5
} usb_vendor_desc_type_t;
typedef enum {
USB_ATTR_REMOTE_WAKE_UP = 0x20,
USB_ATTR_SELF_POWERED = 0x40,
USB_ATTR_BUS_POWERED_RSVD = 0x80
} usb_cfg_attr_type_t;
typedef enum
{
USB_EP_TYPE_CTRL = 0,
USB_EP_TYPE_ISO = 1,
USB_EP_TYPE_BULK = 2,
USB_EP_TYPE_INTR = 3
} usb_cfg_ep_type_t;
/* Device descriptor structure */
typedef struct _usb_dev_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u16 idVendor; // Vendor ID assigned by USB forum.
u16 idProduct; // Product ID assigned by Organization.
u16 bcdDevice; // Device Release number in BCD.
u8 iManufacturer; // Index of String descriptor describing Manufacturer.
u8 iProduct; // Index of String descriptor describing Product.
u8 iSerialNumber; // Index of String descriptor describing Serial number.
u8 bNumConfigs; // Number of possible configuration.
} __attribute__((packed)) usb_dev_descr_t;
/* Device Qualifier descriptor structure */
typedef struct _usb_dev_qual_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_QUALIFIER)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u8 bNumOtherConfigs; // Number of possible other-speed configurations.
u8 bReserved; // Reserved for future use, must be zero
} __attribute__((packed)) usb_dev_qual_descr_t;
/* Configuration descriptor structure */
typedef struct _usb_cfg_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
u16 wTotalLength; // Total length of all descriptors for this configuration.
u8 bNumInterfaces; // Number of interfaces in this configuration.
u8 bConfigurationValue; // Value of this configuration (1 based).
u8 iConfiguration; // Index of String Descriptor describing the configuration.
u8 bmAttributes; // Configuration characteristics.
u8 bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) usb_cfg_descr_t;
/* Interface descriptor structure */
typedef struct _usb_inter_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
u8 bInterfaceNumber; // Number of this interface (0 based).
u8 bAlternateSetting; // Value of this alternate interface setting.
u8 bNumEndpoints; // Number of endpoints in this interface.
u8 bInterfaceClass; // Class code (assigned by the USB-IF).
u8 bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
u8 bInterfaceProtocol; // Protocol code (assigned by the USB-IF).
u8 iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) usb_inter_descr_t;
/* HID descriptor structure */
typedef struct _usb_hid_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_HID).
u16 bcdHID; // HID class specification release
u8 bCountryCode; // Country code.
u8 bNumDescriptors; // Number of descriptors.
u8 bClassDescriptorType; // Type of class descriptor (USB_DESCRIPTOR_HID_REPORT).
u16 bDescriptorLength; // Report descriptor length.
} __attribute__((packed)) usb_hid_descr_t;
/* Endpoint descriptor structure */
typedef struct _usb_ep_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
u8 bEndpointAddress; // Endpoint address. bit7 indicates direction (0=OUT, 1=IN).
u8 bmAttributes; // Endpoint transfer type.
u16 wMaxPacketSize; // Maximum packet size.
u8 bInterval; // Polling interval in frames. For Interrupt and Isochronous data transfer only.
} __attribute__((packed)) usb_ep_descr_t;
typedef struct _usb_cfg_simple_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_simple_descr_t;
typedef struct _usb_cfg_hid_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_hid_descr_t hid;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_hid_descr_t;
typedef struct _usb_dev_bot_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT)
u16 wTotalLength; // Size of this descriptor in bytes.
u8 bNumDeviceCaps; // Number of device capabilities in this descriptor.
/* Device Capability USB 2.0 Extension Descriptor */
/* Needed for a USB2.10 device. */
u8 bLengthCap0; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap0; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap0; // USB2: 2.
u32 bmAttributesCap0; // bit1: Link Power Management (LPM).
u8 bLengthCap1; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap1; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap1; // USB3: 3.
u8 bmAttributesCap1; // bit1: Latency Tolerance Messaging (LTM).
u16 wSpeedsSupported; // Supported bus speeds. 1: Low Speed, 2: Full Speed, 4: High Speed, 8: Super Speed.
u8 bFunctionalitySupport; // Lowest speed at which all the functionality is available. 1: Full speed and above.
u8 bU1DevExitLat; // USB3.0 U1 exit latency.
u16 wU2DevExitLat; // USB3.0 U2 exit latency.
} __attribute__((packed)) usb_dev_bot_t;
/* Microsoft OS String descriptor structure */
typedef struct _usb_ms_os_descr_t
{
u8 bLength; // 0x12
u8 bDescriptorType; // 3
u16 wSignature[7]; // "MSFT100" UTF16 LE
u8 bVendorCode; //
u8 bPadding;
} __attribute__((packed)) usb_ms_os_descr_t;
/* Microsoft Compatible ID Feature descriptor structure */
typedef struct _usb_ms_cid_descr_t
{
u32 dLength;
u16 wVersion;
u16 wCompatibilityId;
u8 bSections;
u8 bReserved0[7];
u8 bInterfaceNumber;
u8 bReserved1;
u8 bCompatibleId[8];
u8 bSubCompatibleId[8];
u8 bReserved2[6];
} __attribute__((packed)) usb_ms_cid_descr_t;
/* Microsoft Extended Properties Feature descriptor structure */
typedef struct _usb_ms_ext_prop_descr_t
{
u32 dLength;
u16 wVersion;
u16 wExtendedProperty;
u16 wSections;
u32 dPropertySize;
u32 dPropertyType;
u16 wPropertyNameLength;
u16 wPropertyName[22]; // UTF16 LE
u32 dPropertyDataLength;
u16 wPropertyData[2]; // UTF16 LE
} __attribute__((packed)) usb_ms_ext_prop_descr_t;
typedef struct _usb_desc_t
{
usb_dev_descr_t *dev;
usb_dev_qual_descr_t *dev_qual;
usb_cfg_simple_descr_t *cfg;
usb_cfg_simple_descr_t *cfg_other;
usb_dev_bot_t *dev_bot;
u8 *vendor;
u8 *product;
u8 *serial;
u8 *lang_id;
usb_ms_os_descr_t *ms_os;
usb_ms_cid_descr_t *ms_cid;
usb_ms_ext_prop_descr_t *mx_ext;
} usb_desc_t;
#endif

View file

@ -1,7 +1,7 @@
/*
* USB driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -16,224 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_
#include <usb/usb_descriptor_types.h>
#include <utils/types.h>
typedef enum {
USB_DESCRIPTOR_DEVICE = 1,
USB_DESCRIPTOR_CONFIGURATION = 2,
USB_DESCRIPTOR_STRING = 3,
USB_DESCRIPTOR_INTERFACE = 4,
USB_DESCRIPTOR_ENDPOINT = 5,
USB_DESCRIPTOR_DEVICE_QUALIFIER = 6,
USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7,
USB_DESCRIPTOR_INTERFACE_POWER = 8,
USB_DESCRIPTOR_INTERFACE_OTG = 9,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT = 15,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP = 16,
USB_DESCRIPTOR_HID = 33,
USB_DESCRIPTOR_HID_REPORT = 34
} usb_desc_type_t;
typedef enum {
USB_DESCRIPTOR_MS_COMPAT_ID = 4,
USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES = 5
} usb_vendor_desc_type_t;
typedef enum {
USB_ATTR_REMOTE_WAKE_UP = 0x20,
USB_ATTR_SELF_POWERED = 0x40,
USB_ATTR_BUS_POWERED_RSVD = 0x80
} usb_cfg_attr_type_t;
typedef enum
{
USB_EP_TYPE_CTRL = 0,
USB_EP_TYPE_ISO = 1,
USB_EP_TYPE_BULK = 2,
USB_EP_TYPE_INTR = 3
} usb_cfg_ep_type_t;
/* Device descriptor structure */
typedef struct _usb_dev_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u16 idVendor; // Vendor ID assigned by USB forum.
u16 idProduct; // Product ID assigned by Organization.
u16 bcdDevice; // Device Release number in BCD.
u8 iManufacturer; // Index of String descriptor describing Manufacturer.
u8 iProduct; // Index of String descriptor describing Product.
u8 iSerialNumber; // Index of String descriptor describing Serial number.
u8 bNumConfigs; // Number of possible configuration.
} __attribute__((packed)) usb_dev_descr_t;
/* Device Qualigier descriptor structure */
typedef struct _usb_dev_qual_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_QUALIFIER)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u8 bNumOtherConfigs; // Number of possible other-speed configurations.
u8 bReserved; // Reserved for future use, must be zero
} __attribute__((packed)) usb_dev_qual_descr_t;
/* Configuration descriptor structure */
typedef struct _usb_cfg_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
u16 wTotalLength; // Total length of all descriptors for this configuration.
u8 bNumInterfaces; // Number of interfaces in this configuration.
u8 bConfigurationValue; // Value of this configuration (1 based).
u8 iConfiguration; // Index of String Descriptor describing the configuration.
u8 bmAttributes; // Configuration characteristics.
u8 bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) usb_cfg_descr_t;
/* Interface descriptor structure */
typedef struct _usb_inter_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
u8 bInterfaceNumber; // Number of this interface (0 based).
u8 bAlternateSetting; // Value of this alternate interface setting.
u8 bNumEndpoints; // Number of endpoints in this interface.
u8 bInterfaceClass; // Class code (assigned by the USB-IF).
u8 bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
u8 bInterfaceProtocol; // Protocol code (assigned by the USB-IF).
u8 iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) usb_inter_descr_t;
/* HID descriptor structure */
typedef struct _usb_hid_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_HID).
u16 bcdHID; // HID class specification release
u8 bCountryCode; // Country code.
u8 bNumDescriptors; // Number of descriptors.
u8 bClassDescriptorType; // Type of class descriptor (USB_DESCRIPTOR_HID_REPORT).
u16 bDescriptorLength; // Report descriptor length.
} __attribute__((packed)) usb_hid_descr_t;
/* Endpoint descriptor structure */
typedef struct _usb_ep_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
u8 bEndpointAddress; // Endpoint address. bit7 indicates direction (0=OUT, 1=IN).
u8 bmAttributes; // Endpoint transfer type.
u16 wMaxPacketSize; // Maximum packet size.
u8 bInterval; // Polling interval in frames. For Interrupt and Isochronous data transfer only.
} __attribute__((packed)) usb_ep_descr_t;
typedef struct _usb_cfg_simple_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_simple_descr_t;
typedef struct _usb_cfg_hid_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_hid_descr_t hid;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_hid_descr_t;
typedef struct _usb_dev_bot_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT)
u16 wTotalLength; // Size of this descriptor in bytes.
u8 bNumDeviceCaps; // Number of device capabilities in this descriptor.
/* Device Capability USB 2.0 Extension Descriptor */
/* Needed for a USB2.10 device. */
u8 bLengthCap0; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap0; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap0; // USB2: 2.
u32 bmAttributesCap0; // bit1: Link Power Management (LPM).
u8 bLengthCap1; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap1; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap1; // USB3: 3.
u8 bmAttributesCap1; // bit1: Latency Tolerance Messaging (LTM).
u16 wSpeedsSupported; // Supported bus speeds. 1: Low Speed, 2: Full Speed, 4: High Speed, 8: Super Speed.
u8 bFunctionalitySupport; // Lowest speed at which all the functionality is available. 1: Full speed and above.
u8 bU1DevExitLat; // USB3.0 U1 exit latency.
u16 wU2DevExitLat; // USB3.0 U2 exit latency.
} __attribute__((packed)) usb_dev_bot_t;
/* Microsoft OS String descriptor structure */
typedef struct _usb_ms_os_descr_t
{
u8 bLength; // 0x12
u8 bDescriptorType; // 3
u16 wSignature[7]; // "MSFT100" UTF16 LE
u8 bVendorCode; //
u8 bPadding;
} __attribute__((packed)) usb_ms_os_descr_t;
/* Microsoft Compatible ID Feature descriptor structure */
typedef struct _usb_ms_cid_descr_t
{
u32 dLength;
u16 wVersion;
u16 wCompatibilityId;
u8 bSections;
u8 bReserved0[7];
u8 bInterfaceNumber;
u8 bReserved1;
u8 bCompatibleId[8];
u8 bSubCompatibleId[8];
u8 bReserved2[6];
} __attribute__((packed)) usb_ms_cid_descr_t;
/* Microsoft Extended Properties Feature descriptor structure */
typedef struct _usb_ms_ext_prop_descr_t
{
u32 dLength;
u16 wVersion;
u16 wExtendedProperty;
u16 wSections;
u32 dPropertySize;
u32 dPropertyType;
u16 wPropertyNameLength;
u16 wPropertyName[22]; // UTF16 LE
u32 dPropertyDataLength;
u16 wPropertyData[2]; // UTF16 LE
} __attribute__((packed)) usb_ms_ext_prop_descr_t;
typedef struct _usb_desc_t
{
usb_dev_descr_t *dev;
usb_dev_qual_descr_t *dev_qual;
usb_cfg_simple_descr_t *cfg;
usb_cfg_simple_descr_t *cfg_other;
usb_dev_bot_t *dev_bot;
u8 *vendor;
u8 *product;
usb_ms_os_descr_t *ms_os;
usb_ms_cid_descr_t *ms_cid;
usb_ms_ext_prop_descr_t *mx_ext;
} usb_desc_t;
usb_dev_descr_t usb_device_descriptor_ums =
static usb_dev_descr_t usb_device_descriptor_ums =
{
.bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -251,7 +37,7 @@ usb_dev_descr_t usb_device_descriptor_ums =
.bNumConfigs = 1
};
usb_dev_qual_descr_t usb_device_qualifier_descriptor =
static usb_dev_qual_descr_t usb_device_qualifier_descriptor =
{
.bLength = 10,
.bDescriptorType = USB_DESCRIPTOR_DEVICE_QUALIFIER,
@ -264,7 +50,7 @@ usb_dev_qual_descr_t usb_device_qualifier_descriptor =
.bReserved = 0x00
};
usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
static usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
{
/* Configuration descriptor structure */
.config.bLength = 9,
@ -304,7 +90,7 @@ usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
.endpoint[1].bInterval = 0x00
};
usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
static usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
{
/* Other Speed Configuration descriptor structure */
.config.bLength = 9,
@ -344,7 +130,7 @@ usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
.endpoint[1].bInterval = 0
};
usb_dev_bot_t usb_device_binary_object_descriptor =
static usb_dev_bot_t usb_device_binary_object_descriptor =
{
.bLength = 5,
.bDescriptorType = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT,
@ -369,20 +155,33 @@ usb_dev_bot_t usb_device_binary_object_descriptor =
.wU2DevExitLat = 0
};
u8 usb_vendor_string_descriptor_ums[32] =
static u8 usb_lang_id_string_descriptor[4] =
{
4, 3,
0x09, 0x04
};
static u8 usb_serial_string_descriptor[26] =
{
26, 0x03,
'C', 0x00, '7', 0x00, 'C', 0x00, '0', 0x00,
'9', 0x00, '2', 0x00, '4', 0x00, '2', 0x00, 'F', 0x00, '7', 0x00, '0', 0x00, '3', 0x00
};
static u8 usb_vendor_string_descriptor_ums[32] =
{
26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0,
'D', 0, 'i', 0, 's', 0, 'k', 0
};
u8 usb_product_string_descriptor_ums[22] =
static u8 usb_product_string_descriptor_ums[22] =
{
8, 0x03,
'U', 0, 'M', 0, 'S', 0
};
usb_ms_os_descr_t usb_ms_os_descriptor =
static usb_ms_os_descr_t usb_ms_os_descriptor =
{
.bLength = 0x28,
.bDescriptorType = 0x03,
@ -396,7 +195,7 @@ usb_ms_os_descr_t usb_ms_os_descriptor =
.bVendorCode = 0x99,
};
usb_ms_cid_descr_t usb_ms_cid_descriptor =
static usb_ms_cid_descr_t usb_ms_cid_descriptor =
{
.dLength = 0x28,
.wVersion = 0x100,
@ -413,7 +212,7 @@ usb_ms_cid_descr_t usb_ms_cid_descriptor =
.bCompatibleId[5] = 'B',
};
usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
{
.dLength = 0x48,
.wVersion = 0x100,
@ -452,7 +251,7 @@ usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
.wPropertyData[1] = 0x10,
};
usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
{
.dLength = 7,
.wVersion = 0x100,
@ -460,7 +259,7 @@ usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
.wSections = 0,
};
usb_dev_descr_t usb_device_descriptor_hid_jc =
static usb_dev_descr_t usb_device_descriptor_hid_jc =
{
.bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -478,7 +277,7 @@ usb_dev_descr_t usb_device_descriptor_hid_jc =
.bNumConfigs = 1
};
usb_dev_descr_t usb_device_descriptor_hid_touch =
static usb_dev_descr_t usb_device_descriptor_hid_touch =
{
.bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -496,75 +295,6 @@ usb_dev_descr_t usb_device_descriptor_hid_touch =
.bNumConfigs = 1
};
usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
{
/* Configuration descriptor structure */
.config.bLength = 9,
.config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION,
.config.wTotalLength = sizeof(usb_cfg_hid_descr_t),
.config.bNumInterfaces = 0x01,
.config.bConfigurationValue = 0x01,
.config.iConfiguration = 0x00,
.config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD,
.config.bMaxPower = 32 / 2,
/* Interface descriptor structure */
.interface.bLength = 9,
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
.interface.bInterfaceNumber = 0,
.interface.bAlternateSetting = 0,
.interface.bNumEndpoints = 2,
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
.interface.iInterface = 0x00,
.hid.bLength = 9,
.hid.bDescriptorType = USB_DESCRIPTOR_HID,
.hid.bcdHID = 0x110,
.hid.bCountryCode = 0,
.hid.bNumDescriptors = 1,
.hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT,
.hid.bDescriptorLength = 0x43,
/* Endpoint descriptor structure EP1 IN */
.endpoint[0].bLength = 7,
.endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 4ms on FS, 8ms on HS.
/* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7,
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 4ms on FS, 8ms on HS.
};
u8 usb_vendor_string_descriptor_hid[22] =
{
16, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'U', 0, 'S', 0, 'B', 0
};
u8 usb_product_string_descriptor_hid_jc[24] =
{
24, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'J', 0, 'o', 0, 'y', 0, '-', 0, 'C', 0, 'o', 0, 'n', 0
};
u8 usb_product_string_descriptor_hid_touch[26] =
{
26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'T', 0, 'o', 0, 'u', 0, 'c', 0, 'h', 0, 'p', 0, 'a', 0, 'd', 0
};
u8 hid_report_descriptor_jc[] =
{
0x05, 0x01, // USAGE_PAGE (Generic Desktop),
@ -602,6 +332,8 @@ u8 hid_report_descriptor_jc[] =
0xc0 // END_COLLECTION(),
};
u32 hid_report_descriptor_jc_size = sizeof(hid_report_descriptor_jc);
u8 hid_report_descriptor_touch[] =
{
0x05, 0x0d, // USAGE_PAGE (Digitizers)
@ -658,8 +390,78 @@ u8 hid_report_descriptor_touch[] =
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
};
u32 hid_report_descriptor_touch_size = sizeof(hid_report_descriptor_touch);
usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
{
/* Configuration descriptor structure */
.config.bLength = 9,
.config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION,
.config.wTotalLength = sizeof(usb_cfg_hid_descr_t),
.config.bNumInterfaces = 0x01,
.config.bConfigurationValue = 0x01,
.config.iConfiguration = 0x00,
.config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD,
.config.bMaxPower = 32 / 2,
/* Interface descriptor structure */
.interface.bLength = 9,
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
.interface.bInterfaceNumber = 0,
.interface.bAlternateSetting = 0,
.interface.bNumEndpoints = 2,
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
.interface.iInterface = 0x00,
.hid.bLength = 9,
.hid.bDescriptorType = USB_DESCRIPTOR_HID,
.hid.bcdHID = 0x110,
.hid.bCountryCode = 0,
.hid.bNumDescriptors = 1,
.hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT,
.hid.bDescriptorLength = sizeof(hid_report_descriptor_jc),
/* Endpoint descriptor structure EP1 IN */
.endpoint[0].bLength = 7,
.endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 8ms on HS.
/* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7,
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 8ms on HS.
};
static u8 usb_vendor_string_descriptor_hid[22] =
{
16, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'U', 0, 'S', 0, 'B', 0
};
static u8 usb_product_string_descriptor_hid_jc[24] =
{
24, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'J', 0, 'o', 0, 'y', 0, '-', 0, 'C', 0, 'o', 0, 'n', 0
};
static u8 usb_product_string_descriptor_hid_touch[26] =
{
26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'T', 0, 'o', 0, 'u', 0, 'c', 0, 'h', 0, 'p', 0, 'a', 0, 'd', 0
};
static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
{
/* Configuration descriptor structure */
.config.bLength = 9,
@ -696,7 +498,7 @@ usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 4ms on FS, 8ms on HS.
.endpoint[0].bInterval = 3, // 4ms on HS.
/* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7,
@ -704,7 +506,7 @@ usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 4ms on FS, 8ms on HS.
.endpoint[1].bInterval = 3 // 4ms on HS.
};
usb_desc_t usb_gadget_ums_descriptors =
@ -716,6 +518,8 @@ usb_desc_t usb_gadget_ums_descriptors =
.dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_ums,
.product = usb_product_string_descriptor_ums,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_ums
@ -730,6 +534,8 @@ usb_desc_t usb_gadget_hid_jc_descriptors =
.dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_hid,
.product = usb_product_string_descriptor_hid_jc,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_hid
@ -744,9 +550,9 @@ usb_desc_t usb_gadget_hid_touch_descriptors =
.dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_hid,
.product = usb_product_string_descriptor_hid_touch,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_hid
};
#endif

View file

@ -22,6 +22,8 @@
#include <gfx_utils.h>
#include <input/joycon.h>
#include <input/touch.h>
#include <soc/hw_init.h>
#include <soc/t210.h>
#include <utils/util.h>
#include <memory_map.h>
@ -67,6 +69,7 @@ typedef struct _jc_cal_t
} jc_cal_t;
static jc_cal_t jc_cal_ctx;
static usb_ops_t usb_ops;
static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
{
@ -306,16 +309,16 @@ static bool _fts_touch_read(touchpad_report_t *rpt)
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
{
u8 status = usb_device_write_ep1_in((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, true);
if (status == 26)
u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED);
if (status == USB_ERROR_XFER_ERROR)
{
usbs->set_text(usbs->label, "#C7EA46 Status:# Error EP IN");
usbd_flush_endpoint(3);
usbs->set_text(usbs->label, "#FFDD00 Error:# EP IN transfer!");
if (usb_ops.usbd_flush_endpoint)
usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN);
}
// Linux mitigation: If timed out, clear status.
if (status == 3)
if (status == USB_ERROR_TIMEOUT)
return 0;
return status;
@ -350,6 +353,12 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
u32 gadget_type;
u32 polling_time;
// Get USB Controller ops.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
usb_device_get_ops(&usb_ops);
else
xusb_device_get_ops(&usb_ops);
if (usbs->type == USB_HID_GAMEPAD)
{
polling_time = 8000;
@ -363,21 +372,21 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB");
if (usb_device_init())
if (usb_ops.usb_device_init())
{
usbd_end(false, true);
usb_ops.usbd_end(false, true);
return 1;
}
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection");
// Initialize Control Endpoint.
if (usb_device_ep0_initialize(gadget_type))
if (usb_ops.usb_device_enumerate(gadget_type))
goto error;
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for HID report request");
if (usb_device_get_hid_report())
if (usb_ops.usb_device_class_send_hid_report())
goto error;
usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation");
@ -400,11 +409,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
}
// Check for suspended USB in case the cable was pulled.
if (usb_device_get_suspended())
if (usb_ops.usb_device_get_suspended())
break; // Disconnected.
// Handle control endpoint.
usbd_handle_ep0_pending_control_transfer();
usb_ops.usbd_handle_ep0_ctrl_setup();
// Wait max gadget timing.
timer = get_tmr_us() - timer;
@ -422,11 +431,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
goto exit;
error:
usbs->set_text(usbs->label, "#C7EA46 Status:# Timed out or canceled");
usbs->set_text(usbs->label, "#FFDD00 Error:# Timed out or canceled");
res = 1;
exit:
usbd_end(true, false);
usb_ops.usbd_end(true, false);
return res;
}

View file

@ -23,6 +23,8 @@
#include <usb/usbd.h>
#include <gfx_utils.h>
#include <soc/hw_init.h>
#include <soc/t210.h>
#include <storage/nx_sd.h>
#include <storage/sdmmc.h>
#include <storage/sdmmc_driver.h>
@ -198,7 +200,6 @@ typedef struct _usbd_gadget_ums_t {
u32 lun_idx; // lun index
logical_unit_t lun;
u32 bulk_out_maxpacket; // 512
enum ums_state state; // For exception handling.
enum data_direction data_dir;
@ -215,12 +216,15 @@ typedef struct _usbd_gadget_ums_t {
int can_stall;
u32 timeouts;
bool xusb;
void (*system_maintenance)(bool);
void *label;
void (*set_text)(void *, const char *);
} usbd_gadget_ums_t;
static usb_ops_t usb_ops;
static inline void put_array_le_to_be16(u16 val, void *p)
{
u8 *_p = p;
@ -271,7 +275,7 @@ static void raise_exception(usbd_gadget_ums_t *ums, enum ums_state new_state)
static void ums_handle_ep0_ctrl(usbd_gadget_ums_t *ums)
{
if (usbd_handle_ep0_pending_control_transfer())
if (usb_ops.usbd_handle_ep0_ctrl_setup())
raise_exception(ums, UMS_STATE_PROTOCOL_RESET);
}
@ -284,46 +288,56 @@ static int ums_wedge_bulk_in_endpoint(usbd_gadget_ums_t *ums)
static int ums_set_stall(u32 ep)
{
usbd_set_ep_stall(ep, 1);
usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_STALL);
return 0;
}
static int ums_clear_stall(u32 ep)
{
usbd_set_ep_stall(ep, 0);
usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_CLEAR);
return 0;
}
static void ums_flush_endpoint(u32 ep)
{
if (usb_ops.usbd_flush_endpoint)
usb_ops.usbd_flush_endpoint(ep);
}
static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, bool sync)
{
if (ep == bulk_ctxt->bulk_in)
{
bulk_ctxt->bulk_in_status = usb_device_write_ep1_in(
bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_write(
bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length,
&bulk_ctxt->bulk_in_length_actual, sync);
if (bulk_ctxt->bulk_in_status == 26)
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error EP IN");
usbd_flush_endpoint(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!");
ums_flush_endpoint(bulk_ctxt->bulk_in);
}
else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP IN Buffer not aligned!");
if (sync)
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
}
else
{
bulk_ctxt->bulk_out_status = usb_device_read_ep1_out(
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read(
bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length,
&bulk_ctxt->bulk_out_length_actual, sync);
if (bulk_ctxt->bulk_out_status == 26)
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT");
usbd_flush_endpoint(bulk_ctxt->bulk_out);
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
ums_flush_endpoint(bulk_ctxt->bulk_out);
}
else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT Buffer not aligned!");
if (sync)
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -332,14 +346,14 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{
bulk_ctxt->bulk_out_status = usb_device_read_ep1_out_big_reads(
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read_big(
bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length,
&bulk_ctxt->bulk_out_length_actual);
if (bulk_ctxt->bulk_out_status == 26)
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT");
usbd_flush_endpoint(bulk_ctxt->bulk_out);
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
ums_flush_endpoint(bulk_ctxt->bulk_out);
}
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -349,24 +363,26 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
{
if (ep == bulk_ctxt->bulk_in)
{
bulk_ctxt->bulk_in_status = usb_device_ep1_in_writing_finish(&bulk_ctxt->bulk_in_length_actual);
bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_writing_finish(
&bulk_ctxt->bulk_in_length_actual);
if (bulk_ctxt->bulk_in_status == 26)
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error EP IN");
usbd_flush_endpoint(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!");
ums_flush_endpoint(bulk_ctxt->bulk_in);
}
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
}
else
{
bulk_ctxt->bulk_out_status = usb_device_ep1_out_reading_finish(&bulk_ctxt->bulk_out_length_actual);
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish(
&bulk_ctxt->bulk_out_length_actual, 1000000);
if (bulk_ctxt->bulk_out_status == 26)
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT");
usbd_flush_endpoint(bulk_ctxt->bulk_out);
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
ums_flush_endpoint(bulk_ctxt->bulk_out);
}
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -485,7 +501,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// If an error occurred, report it and its position.
if (!amount)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error SDMMC Read");
ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Read!");
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1;
@ -497,7 +513,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
break;
// Start the USB transfer.
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, false);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_START);
first_read = false;
// Increment our buffer to read new data.
@ -568,7 +584,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
if (usb_lba_offset >= ums->lun.num_sectors) //////////Check if it works with concurrency
{
ums->set_text(ums->label, "#C7EA46 Status:# Write Error - Past last sector");
ums->set_text(ums->label, "#FFDD00 Error:# Write - Past last sector!");
amount_left_to_req = 0;
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
ums->lun.sense_data_info = usb_lba_offset;
@ -596,7 +612,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
ums->lun.sense_data = SS_COMMUNICATION_FAILURE;
ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1;
sprintf(txt_buf, "#C7EA46 Status:# Write Error - Comm failure %d", bulk_ctxt->bulk_out_status);
sprintf(txt_buf, "#FFDD00 Error:# Write - Comm failure %d!", bulk_ctxt->bulk_out_status);
ums->set_text(ums->label, txt_buf);
break;
}
@ -634,7 +650,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
/* If an error occurred, report it and its position */
if (!amount)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error SDMMC Write");
ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Write!");
ums->lun.sense_data = SS_WRITE_ERROR;
ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1;
@ -645,7 +661,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
// Did the host decide to stop early?
if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length)
{
ums->set_text(ums->label, "#C7EA46 Status:# Empty Write");
ums->set_text(ums->label, "#FFDD00 Error:# Empty Write!");
ums->short_packet_received = 1;
break;
}
@ -699,7 +715,7 @@ DPRINTF("File read %X @ %X\n", amount, lba_offset);
if (!amount)
{
ums->set_text(ums->label, "#C7EA46 Status:# Error file verify");
ums->set_text(ums->label, "#FFDD00 Error:# File verify!");
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1;
@ -943,7 +959,7 @@ static int _scsi_mode_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
buf += 4;
}
else // SC_MODE_SENSE_10.
{
{
buf[3] = (ums->lun.ro ? 0x80 : 0x00); // WP, DPOFUA.
buf += 8;
}
@ -1158,7 +1174,7 @@ DPRINTF("SCSI command: %X; Dc=%d, D%c=%X; Hc=%d, H%c=%X\n",
ums->cmnd[1] &= 0x1F; // Mask away the LUN.
for (u32 i = 1; i < cmnd_size; ++i)
{
if (ums->cmnd[i] && !(mask & (1 << i)))
if (ums->cmnd[i] && !(mask & BIT(i)))
{
ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB;
@ -1382,7 +1398,7 @@ static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
u32 nsend = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE);
memset(bulk_ctxt->bulk_in_buf + current_len_to_keep, 0, nsend - current_len_to_keep);
bulk_ctxt->bulk_in_length = nsend;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
ums->usb_amount_left -= nsend;
current_len_to_keep = 0;
}
@ -1400,7 +1416,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
u32 amount = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE);
bulk_ctxt->bulk_out_length = amount;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED);
ums->usb_amount_left -= amount;
return 0;
@ -1412,7 +1428,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// A short packet or an error ends everything.
if (bulk_ctxt->bulk_out_length_actual != bulk_ctxt->bulk_out_length ||
bulk_ctxt->bulk_out_status != 0)
bulk_ctxt->bulk_out_status != USB_RES_OK)
{
raise_exception(ums, UMS_STATE_ABORT_BULK_OUT);
return -4; // Interrupted system call
@ -1436,7 +1452,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{
ums_set_stall(bulk_ctxt->bulk_out);
rc = ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# Direction unknown. Stalled both EP");
ums->set_text(ums->label, "#FFDD00 Error:# Direction unknown. Stalled both EP!");
} // Else do nothing.
break;
@ -1447,7 +1463,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// If there's no residue, simply send the last buffer.
if (!ums->residue)
{
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
/* For Bulk-only, if we're allowed to stall then send the
* short packet and halt the bulk-in endpoint. If we can't
@ -1455,9 +1471,9 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
}
else if (ums->can_stall)
{
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
rc = ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# Residue. Stalled EP IN");
ums->set_text(ums->label, "#FFDD00 Error:# Residue. Stalled EP IN!");
}
else
rc = pad_with_zeros(ums, bulk_ctxt);
@ -1523,26 +1539,28 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
DPRINTF("USB: EP timeout\n");
// In case we disconnected, exit UMS.
// Raise timeout if removable and didn't got a unit ready command inside 4s.
if (bulk_ctxt->bulk_out_status == 28 ||
(bulk_ctxt->bulk_out_status == 3 && ums->lun.removable && !ums->lun.prevent_medium_removal))
if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_EP_DISABLED ||
(bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT && ums->lun.removable && !ums->lun.prevent_medium_removal))
{
if (bulk_ctxt->bulk_out_status == 3)
if (bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT)
{
if (usb_device_get_port_status() == 0x885)
if (usb_ops.usb_device_get_port_in_sleep())
{
ums->set_text(ums->label, "#C7EA46 Status:# EP in sleep");
ums->timeouts += 10;
ums->timeouts += 14;
}
else
else if (!ums->xusb) // Timeout only on USB2.
{
ums->timeouts += 4;
DPRINTF("USB: EP removable\n");
}
}
else
{
gfx_printf("USB: EP disabled\n");
msleep(500);
ums->timeouts += 4;
}
ums->timeouts += 4;
}
if (ums->lun.unmounted)
@ -1592,7 +1610,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{
ums_set_stall(bulk_ctxt->bulk_out);
ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# CBW unknown - Stalled both EP");
ums->set_text(ums->label, "#FFDD00 Error:# CBW unknown - Stalled both EP!");
}
return -22; // Invalid argument.
@ -1634,7 +1652,7 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN;
/* Queue a request to read a Bulk-only CBW */
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED);
/* We will drain the buffer in software, which means we
* can reuse it for the next filling. No need to advance
@ -1659,7 +1677,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
if (ums->phase_error)
{
ums->set_text(ums->label, "#C7EA46 Status:# Phase-error");
ums->set_text(ums->label, "#FFDD00 Error:# Phase-error!");
status = USB_STATUS_PHASE_ERROR;
sd = SS_INVALID_COMMAND;
}
@ -1680,7 +1698,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
csw->Status = status;
bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true);
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
}
static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
@ -1688,8 +1706,8 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
enum ums_state old_state;
/* Clear out the controller's fifos */
usbd_flush_endpoint(bulk_ctxt->bulk_in);
usbd_flush_endpoint(bulk_ctxt->bulk_out);
ums_flush_endpoint(bulk_ctxt->bulk_in);
ums_flush_endpoint(bulk_ctxt->bulk_out);
/* Reset the I/O buffer states and pointers, the SCSI
* state, and the exception. Then invoke the handler. */
@ -1764,26 +1782,32 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
int res = 0;
sdmmc_t sdmmc;
sdmmc_storage_t storage;
usbd_gadget_ums_t ums = {0};
// Get USB Controller ops.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
usb_device_get_ops(&usb_ops);
else
{
ums.xusb = true;
xusb_device_get_ops(&usb_ops);
}
usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB");
if (usb_device_init())
if (usb_ops.usb_device_init())
{
usbd_end(false, true);
usb_ops.usbd_end(false, true);
return 1;
}
usbd_gadget_ums_t ums;
memset(&ums, 0, sizeof(usbd_gadget_ums_t));
ums.bulk_out_maxpacket = usbd_get_max_pkt_length(USB_EP_BULK_IN);
ums.state = UMS_STATE_NORMAL;
ums.can_stall = 0;
ums.bulk_ctxt.bulk_in = 3;
ums.bulk_ctxt.bulk_in = USB_EP_BULK_IN;
ums.bulk_ctxt.bulk_in_buf = (u8 *)USB_EP_BULK_IN_BUF_ADDR;
ums.bulk_ctxt.bulk_out = 2;
ums.bulk_ctxt.bulk_out = USB_EP_BULK_OUT;
ums.bulk_ctxt.bulk_out_buf = (u8 *)USB_EP_BULK_OUT_BUF_ADDR;
// Set LUN parameters.
@ -1820,12 +1844,12 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
ums.set_text(ums.label, "#C7EA46 Status:# Waiting for connection");
// Initialize Control Endpoint.
if (usb_device_ep0_initialize(USB_GADGET_UMS))
if (usb_ops.usb_device_enumerate(USB_GADGET_UMS))
goto error;
ums.set_text(ums.label, "#C7EA46 Status:# Waiting for LUN");
if (usb_device_get_max_lun(0)) // One device for now.
if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now.
goto error;
ums.set_text(ums.label, "#C7EA46 Status:# Started UMS");
@ -1878,14 +1902,14 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
goto exit;
error:
ums.set_text(ums.label, "#C7EA46 Status:# Timed out or canceled");
ums.set_text(ums.label, "#FFDD00 Error:# Timed out or canceled!");
res = 1;
exit:
if (ums.lun.type == MMC_EMMC)
sdmmc_storage_end(ums.lun.storage);
usbd_end(true, false);
usb_ops.usbd_end(true, false);
return res;
}

View file

@ -1,7 +1,7 @@
/*
* USB driver for Tegra X1
* Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -21,14 +21,16 @@
#include <utils/types.h>
/* EHCI USB */
/* General USB registers */
#define USB1_IF_USB_SUSP_CTRL 0x400
#define SUSP_CTRL_USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
#define SUSP_CTRL_USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
#define SUSP_CTRL_USB_PHY_CLK_VALID (1 << 7)
#define SUSP_CTRL_UTMIP_RESET (1 << 11)
#define SUSP_CTRL_UTMIP_PHY_ENB (1 << 12)
#define SUSP_CTRL_UTMIP_UTMIP_SUSPL1_SET (1 << 25)
#define SUSP_CTRL_USB_WAKE_ON_CNNT_EN_DEV BIT(3)
#define SUSP_CTRL_USB_WAKE_ON_DISCON_EN_DEV BIT(4)
#define SUSP_CTRL_USB_PHY_CLK_VALID BIT(7)
#define SUSP_CTRL_UTMIP_RESET BIT(11)
#define SUSP_CTRL_UTMIP_PHY_ENB BIT(12)
#define SUSP_CTRL_UTMIP_UTMIP_SUSPL1_SET BIT(25)
#define USB1_IF_USB_PHY_VBUS_SENSORS 0x404
#define USB1_UTMIP_XCVR_CFG0 0x808
#define USB1_UTMIP_BIAS_CFG0 0x80C
@ -37,6 +39,9 @@
#define USB1_UTMIP_TX_CFG0 0x820
#define USB1_UTMIP_MISC_CFG1 0x828
#define USB1_UTMIP_DEBOUNCE_CFG0 0x82C
#define USB1_UTMIP_BAT_CHRG_CFG0 0x830
#define BAT_CHRG_CFG0_PWRDOWN_CHRG BIT(0)
#define BAT_CHRG_CFG0_OP_SRC_EN BIT(3)
#define USB1_UTMIP_SPARE_CFG0 0x834
#define USB1_UTMIP_XCVR_CFG1 0x838
#define USB1_UTMIP_BIAS_CFG1 0x83C
@ -46,38 +51,38 @@
/* USB Queue Head Descriptor */
#define USB2_QH_USB2D_QH_EP_BASE (USB_BASE + 0x1000)
#define USB_QHD_EP_CAP_IOS_ENABLE (1 << 15)
#define USB_QHD_EP_CAP_IOS_ENABLE BIT(15)
#define USB_QHD_EP_CAP_MAX_PKT_LEN_MASK 0x7FF
#define USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS (1 << 29)
#define USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS BIT(29)
#define USB_QHD_EP_CAP_MULTI_NON_ISO (0 << 30)
#define USB_QHD_EP_CAP_MULTI_1 (1 << 30)
#define USB_QHD_EP_CAP_MULTI_2 (2 << 30)
#define USB_QHD_EP_CAP_MULTI_3 (3 << 30)
#define USB_QHD_TOKEN_XFER_ERROR (1 << 3)
#define USB_QHD_TOKEN_BUFFER_ERROR (1 << 5)
#define USB_QHD_TOKEN_HALTED (1 << 6)
#define USB_QHD_TOKEN_ACTIVE (1 << 7)
#define USB_QHD_TOKEN_XFER_ERROR BIT(3)
#define USB_QHD_TOKEN_BUFFER_ERROR BIT(5)
#define USB_QHD_TOKEN_HALTED BIT(6)
#define USB_QHD_TOKEN_ACTIVE BIT(7)
#define USB_QHD_TOKEN_MULT_OVERR_MASK (2 << 10)
#define USB_QHD_TOKEN_IRQ_ON_COMPLETE (1 << 15)
#define USB_QHD_TOKEN_IRQ_ON_COMPLETE BIT(15)
#define USB_QHD_TOKEN_TOTAL_BYTES_SHIFT 16
/* USB_OTG/USB_1 controllers register bits */
#define USB2D_PORTSC1_SUSP (1 << 7)
#define USB2D_PORTSC1_SUSP BIT(7)
#define USB2D_USBCMD_RUN (1 << 0)
#define USB2D_USBCMD_RESET (1 << 1)
#define USB2D_USBCMD_RUN BIT(0)
#define USB2D_USBCMD_RESET BIT(1)
#define USB2D_USBCMD_ITC_MASK (0xFF << 16)
#define USB2D_USBSTS_UI (1 << 0)
#define USB2D_USBSTS_UEI (1 << 1)
#define USB2D_USBSTS_PCI (1 << 2)
#define USB2D_USBSTS_FRI (1 << 3)
#define USB2D_USBSTS_SEI (1 << 4)
#define USB2D_USBSTS_AAI (1 << 5)
#define USB2D_USBSTS_URI (1 << 6)
#define USB2D_USBSTS_SRI (1 << 7)
#define USB2D_USBSTS_SLI (1 << 8)
#define USB2D_USBSTS_UI BIT(0)
#define USB2D_USBSTS_UEI BIT(1)
#define USB2D_USBSTS_PCI BIT(2)
#define USB2D_USBSTS_FRI BIT(3)
#define USB2D_USBSTS_SEI BIT(4)
#define USB2D_USBSTS_AAI BIT(5)
#define USB2D_USBSTS_URI BIT(6)
#define USB2D_USBSTS_SRI BIT(7)
#define USB2D_USBSTS_SLI BIT(8)
#define USB2D_USBMODE_CM_MASK (3 << 0)
#define USB2D_USBMODE_CM_IDLE 0
@ -85,33 +90,33 @@
#define USB2D_USBMODE_CM_DEVICE 2
#define USB2D_USBMODE_CM_HOST 3
#define USB2D_ENDPT_STATUS_RX_OFFSET (1 << 0)
#define USB2D_ENDPT_STATUS_TX_OFFSET (1 << 16)
#define USB2D_ENDPT_STATUS_RX_OFFSET BIT(0)
#define USB2D_ENDPT_STATUS_TX_OFFSET BIT(16)
#define USB2D_ENDPTCTRL_RX_EP_STALL (1 << 0)
#define USB2D_ENDPTCTRL_RX_EP_STALL BIT(0)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL (0 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_ISO (1 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_BULK (2 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_INTR (3 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_MASK (3 << 2)
#define USB2D_ENDPTCTRL_RX_EP_INHIBIT (1 << 5)
#define USB2D_ENDPTCTRL_RX_EP_RESET (1 << 6)
#define USB2D_ENDPTCTRL_RX_EP_ENABLE (1 << 7)
#define USB2D_ENDPTCTRL_TX_EP_STALL (1 << 16)
#define USB2D_ENDPTCTRL_RX_EP_INHIBIT BIT(5)
#define USB2D_ENDPTCTRL_RX_EP_RESET BIT(6)
#define USB2D_ENDPTCTRL_RX_EP_ENABLE BIT(7)
#define USB2D_ENDPTCTRL_TX_EP_STALL BIT(16)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL (0 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_ISO (1 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_BULK (2 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_INTR (3 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_MASK (3 << 18)
#define USB2D_ENDPTCTRL_TX_EP_INHIBIT (1 << 21)
#define USB2D_ENDPTCTRL_TX_EP_RESET (1 << 22)
#define USB2D_ENDPTCTRL_TX_EP_ENABLE (1 << 23)
#define USB2D_ENDPTCTRL_TX_EP_INHIBIT BIT(21)
#define USB2D_ENDPTCTRL_TX_EP_RESET BIT(22)
#define USB2D_ENDPTCTRL_TX_EP_ENABLE BIT(23)
#define USB2D_HOSTPC1_DEVLC_ASUS (1 << 17)
#define USB2D_HOSTPC1_DEVLC_PHCD (1 << 22)
#define USB2D_HOSTPC1_DEVLC_ASUS BIT(17)
#define USB2D_HOSTPC1_DEVLC_PHCD BIT(22)
#define USB2D_HOSTPC1_DEVLC_PSPD_MASK (3 << 25)
#define USB2D_OTGSC_USB_ID_PULLUP (1 << 5)
#define USB2D_OTGSC_USB_ID_PULLUP BIT(5)
#define USB2D_OTGSC_USB_IRQ_STS_MASK (0x7F << 16)
/* USB_OTG/USB_1 controllers registers */
@ -169,4 +174,119 @@ typedef struct _t210_usb2d_t
vu32 endptctrl[16];
} t210_usb2d_t;
/* XHCI USB */
/* XUSB DEV XHCI registers */
#define XUSB_DEV_XHCI_DB 0x4
#define XUSB_DEV_XHCI_ERSTSZ 0x8
#define XUSB_DEV_XHCI_ERST0BALO 0x10
#define XUSB_DEV_XHCI_ERST0BAHI 0x14
#define XUSB_DEV_XHCI_ERST1BALO 0x18
#define XUSB_DEV_XHCI_ERST1BAHI 0x1C
#define XUSB_DEV_XHCI_ERDPLO 0x20
#define XHCI_ERDPLO_EHB BIT(3)
#define XUSB_DEV_XHCI_ERDPHI 0x24
#define XUSB_DEV_XHCI_EREPLO 0x28
#define XCHI_ECS BIT(0)
#define XUSB_DEV_XHCI_EREPHI 0x2C
#define XUSB_DEV_XHCI_CTRL 0x30
#define XHCI_CTRL_RUN BIT(0)
#define XHCI_CTRL_LSE BIT(1)
#define XHCI_CTRL_IE BIT(4)
#define XHCI_CTRL_ENABLE BIT(31)
#define XUSB_DEV_XHCI_ST 0x34
#define XHCI_ST_RC BIT(0)
#define XHCI_ST_IP BIT(4)
#define XUSB_DEV_XHCI_PORTSC 0x3C
#define XHCI_PORTSC_PR BIT(4)
#define XHCI_PORTSC_PLS_MASK (0xF << 5)
#define XHCI_PORTSC_PLS_U0 (0 << 5)
#define XHCI_PORTSC_PLS_U1 (1 << 5)
#define XHCI_PORTSC_PLS_U2 (2 << 5)
#define XHCI_PORTSC_PLS_U3 (3 << 5)
#define XHCI_PORTSC_PLS_DISABLED (4 << 5)
#define XHCI_PORTSC_PLS_RXDETECT (5 << 5)
#define XHCI_PORTSC_PLS_INACTIVE (6 << 5)
#define XHCI_PORTSC_PLS_POLLING (7 << 5)
#define XHCI_PORTSC_PLS_RECOVERY (8 << 5)
#define XHCI_PORTSC_PLS_HOTRESET (9 << 5)
#define XHCI_PORTSC_PLS_COMPLIANCE (10 << 5)
#define XHCI_PORTSC_PLS_LOOPBACK (11 << 5)
#define XHCI_PORTSC_PLS_RESUME (15 << 5)
#define XHCI_PORTSC_PS (0xF << 10)
#define XHCI_PORTSC_LWS BIT(16)
#define XHCI_PORTSC_CSC BIT(17)
#define XHCI_PORTSC_WRC BIT(19)
#define XHCI_PORTSC_PRC BIT(21)
#define XHCI_PORTSC_PLC BIT(22)
#define XHCI_PORTSC_CEC BIT(23)
#define XHCI_PORTSC_WPR BIT(30)
#define XUSB_DEV_XHCI_ECPLO 0x40
#define XUSB_DEV_XHCI_ECPHI 0x44
#define XUSB_DEV_XHCI_EP_HALT 0x50
#define XHCI_EP_HALT_DCI BIT(0)
#define XUSB_DEV_XHCI_EP_PAUSE 0x54
#define XUSB_DEV_XHCI_EP_RELOAD 0x58
#define XUSB_DEV_XHCI_EP_STCHG 0x5C
#define XUSB_DEV_XHCI_PORTHALT 0x6C
#define XHCI_PORTHALT_HALT_LTSSM BIT(0)
#define XHCI_PORTHALT_STCHG_REQ BIT(20)
#define XUSB_DEV_XHCI_CFG_DEV_FE 0x85C
#define XHCI_CFG_DEV_FE_PORTREGSEL_MASK (3 << 0)
#define XHCI_CFG_DEV_FE_PORTREGSEL_SS (1 << 0)
#define XHCI_CFG_DEV_FE_PORTREGSEL_HSFS (2 << 0)
/* XUSB DEV PCI registers */
#define XUSB_CFG_1 0x4
#define CFG_1_IO_SPACE BIT(0)
#define CFG_1_MEMORY_SPACE BIT(1)
#define CFG_1_BUS_MASTER BIT(2)
#define XUSB_CFG_4 0x10
#define CFG_4_ADDRESS_TYPE_32_BIT (0 << 1)
#define CFG_4_ADDRESS_TYPE_64_BIT (2 << 1)
/* XUSB DEV Device registers */
#define XUSB_DEV_CONFIGURATION 0x180
#define DEV_CONFIGURATION_EN_FPCI BIT(0)
#define XUSB_DEV_INTR_MASK 0x188
#define DEV_INTR_MASK_IP_INT_MASK BIT(16)
/* XUSB Pad Control registers */
#define XUSB_PADCTL_USB2_PAD_MUX 0x4
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_USB2 (0 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_XUSB (1 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_MASK (3 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_USB2 (0 << 18)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB (1 << 18)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK (3 << 18)
#define XUSB_PADCTL_USB2_PORT_CAP 0x8
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DIS (0 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_HOST (1 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DEV (2 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_OTG (3 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_MASK (3 << 0)
#define XUSB_PADCTL_SS_PORT_MAP 0x14
#define PADCTL_SS_PORT_MAP_PORT0_MASK (0xF << 0)
#define XUSB_PADCTL_ELPG_PROGRAM_0 0x20
#define XUSB_PADCTL_ELPG_PROGRAM_1 0x24
#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL0 0x80
#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL1 0x84
#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_0 0x88
#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_1 0x8C
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0 0x284
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1 0x288
#define XUSB_PADCTL_USB2_VBUS_ID 0xC60
#define PADCTL_USB2_VBUS_ID_VBUS_OVR_EN (1 << 12)
#define PADCTL_USB2_VBUS_ID_VBUS_OVR_MASK (3 << 12)
#define PADCTL_USB2_VBUS_ID_VBUS_ON BIT(14)
#define PADCTL_USB2_VBUS_ID_SRC_ID_OVR_EN (1 << 16)
#define PADCTL_USB2_VBUS_ID_SRC_MASK (3 << 16)
#define PADCTL_USB2_VBUS_ID_OVR_GND (0 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_C (1 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_B (2 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_A (4 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_FLOAT (8 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_MASK (0xF << 18)
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* USB Device driver for Tegra X1
* Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*
@ -28,6 +28,155 @@
#define USB_EP_BUFFER_2_TD (USB_TD_BUFFER_MAX_SIZE * 2)
#define USB_EP_BUFFER_4_TD (USB_TD_BUFFER_MAX_SIZE * 4)
#define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD)
#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE)
#define USB_XFER_START false
#define USB_XFER_SYNCED true
typedef enum _usb_hid_type
{
USB_HID_GAMEPAD,
USB_HID_TOUCHPAD
} usb_hid_type;
typedef enum _usb_gadget_type
{
USB_GADGET_UMS = 0,
USB_GADGET_HID_GAMEPAD = 1,
USB_GADGET_HID_TOUCHPAD = 2,
} usb_gadget_type;
typedef enum {
USB_DIR_OUT = 0,
USB_DIR_IN = 1,
} usb_dir_t;
typedef enum
{
XUSB_EP_CTRL_IN = 0, // EP0.
XUSB_EP_CTRL_OUT = 1, // EP0.
USB_EP_CTRL_OUT = 0, // EP0.
USB_EP_CTRL_IN = 1, // EP0.
USB_EP_BULK_OUT = 2, // EP1.
USB_EP_BULK_IN = 3, // EP1.
USB_EP_ALL = 0xFFFFFFFF
} usb_ep_t;
typedef enum
{
USB_EP_ADDR_CTRL_OUT = 0x00,
USB_EP_ADDR_CTRL_IN = 0x80,
USB_EP_ADDR_BULK_OUT = 0x01,
USB_EP_ADDR_BULK_IN = 0x81,
} usb_ep_addr_t;
typedef enum
{
USB_EP_CFG_CLEAR = 0,
USB_EP_CFG_RESET = 0,
USB_EP_CFG_STALL = 1
} usb_ep_cfg_t;
typedef enum {
USB_STATUS_EP_OK = 0,
USB_STATUS_EP_HALTED = 1,
USB_STATUS_DEV_SELF_POWERED = 1,
USB_STATUS_DEV_REMOTE_WAKE = 2,
} usb_set_clear_feature_req_t;
typedef enum {
USB_SETUP_RECIPIENT_DEVICE = 0,
USB_SETUP_RECIPIENT_INTERFACE = 1,
USB_SETUP_RECIPIENT_ENDPOINT = 2,
USB_SETUP_RECIPIENT_OTHER = 3,
USB_SETUP_TYPE_STANDARD = 0x00,
USB_SETUP_TYPE_CLASS = 0x20,
USB_SETUP_TYPE_VENDOR = 0x40,
USB_SETUP_TYPE_RESERVED = 0x60,
USB_SETUP_HOST_TO_DEVICE = 0x00,
USB_SETUP_DEVICE_TO_HOST = 0x80,
} usb_setup_req_type_t;
typedef enum {
USB_REQUEST_GET_STATUS = 0,
USB_REQUEST_CLEAR_FEATURE = 1,
USB_REQUEST_SET_FEATURE = 3,
USB_REQUEST_SET_ADDRESS = 5,
USB_REQUEST_GET_DESCRIPTOR = 6,
USB_REQUEST_SET_DESCRIPTOR = 7,
USB_REQUEST_GET_CONFIGURATION = 8,
USB_REQUEST_SET_CONFIGURATION = 9,
USB_REQUEST_GET_INTERFACE = 10,
USB_REQUEST_SET_INTERFACE = 11,
USB_REQUEST_SYNCH_FRAME = 12,
USB_REQUEST_SET_SEL = 13,
USB_REQUEST_GET_MS_DESCRIPTOR = 0x99,
USB_REQUEST_BULK_GET_MAX_LUN = 0xFE,
USB_REQUEST_BULK_RESET = 0xFF
} usb_standard_req_t;
typedef enum {
USB_FEATURE_ENDPOINT_HALT = 0,
USB_FEATURE_DEVICE_REMOTE_WAKEUP = 1,
USB_FEATURE_TEST_MODE = 2,
} usb_get_status_req_t;
typedef enum _usb_error_t
{
USB_RES_OK = 0,
USB_RES_BULK_RESET = 1,
USB_ERROR_USER_ABORT = 2,
USB_ERROR_TIMEOUT = 3,
USB_ERROR_INIT = 4,
USB_ERROR_XFER_ERROR = 5,
USB2_ERROR_XFER_EP_DISABLED = 28,
USB2_ERROR_XFER_NOT_ALIGNED = 29,
XUSB_ERROR_INVALID_EP = USB_ERROR_XFER_ERROR, // From 2.
XUSB_ERROR_XFER_BULK_IN_RESIDUE = 7,
XUSB_ERROR_INVALID_CYCLE = USB2_ERROR_XFER_EP_DISABLED, // From 8.
XUSB_ERROR_SEQ_NUM = 51,
XUSB_ERROR_XFER_DIR = 52,
XUSB_ERROR_PORT_CFG = 54
} usb_error_t;
typedef struct _usb_ctrl_setup_t
{
u8 bmRequestType;
u8 bRequest;
u16 wValue;
u16 wIndex;
u16 wLength;
} usb_ctrl_setup_t;
typedef struct _usb_ops_t
{
int (*usbd_flush_endpoint)(u32);
int (*usbd_set_ep_stall)(u32, int);
int (*usbd_handle_ep0_ctrl_setup)();
void (*usbd_end)(bool, bool);
int (*usb_device_init)();
int (*usb_device_enumerate)(usb_gadget_type gadget);
int (*usb_device_class_send_max_lun)(u8);
int (*usb_device_class_send_hid_report)();
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, bool);
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
int (*usb_device_ep1_out_reading_finish)(u32 *, int);
int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, bool);
int (*usb_device_ep1_in_writing_finish)(u32 *);
bool (*usb_device_get_suspended)();
bool (*usb_device_get_port_in_sleep)();
} usb_ops_t;
typedef struct _usb_ctxt_t
{
@ -41,46 +190,10 @@ typedef struct _usb_ctxt_t
void (*set_text)(void *, const char *);
} usb_ctxt_t;
typedef enum _usb_hid_type
{
USB_HID_GAMEPAD,
USB_HID_TOUCHPAD
} usb_hid_type;
typedef enum _usb_gadget_type
{
USB_GADGET_UMS,
USB_GADGET_HID_GAMEPAD,
USB_GADGET_HID_TOUCHPAD
} usb_gadget_type;
typedef enum
{
USB_EP_CTRL_OUT = 0, // EP0.
USB_EP_CTRL_IN = 1, // EP0.
USB_EP_BULK_OUT = 2, // EP1.
USB_EP_BULK_IN = 3, // EP1.
USB_EP_ALL = 0xFFFFFFFF
} usb_ep_t;
int usbd_flush_endpoint(u32 ep);
void usbd_set_ep_stall(u32 endpoint, int ep_stall);
int usbd_get_max_pkt_length(int endpoint);
int usbd_handle_ep0_pending_control_transfer();
void usbd_end(bool reset_ep, bool only_controller);
int usb_device_init();
int usb_device_ep0_initialize(usb_gadget_type type);
int usb_device_read_ep1_out(u8 *buf, u32 len, u32 *bytes_read, bool sync);
int usb_device_read_ep1_out_big_reads(u8 *buf, u32 len, u32 *bytes_read);
int usb_device_ep1_out_reading_finish(u32 *pending_bytes);
int usb_device_write_ep1_in(u8 *buf, u32 len, u32 *bytes_written, bool sync);
int usb_device_ep1_in_writing_finish(u32 *pending_bytes);
bool usb_device_get_suspended();
void usb_device_get_ops(usb_ops_t *ops);
void xusb_device_get_ops(usb_ops_t *ops);
int usb_device_gadget_ums(usb_ctxt_t *usbs);
int usb_device_gadget_hid(usb_ctxt_t *usbs);
bool usb_device_get_max_lun(u8 max_lun);
bool usb_device_get_hid_report();
u32 usb_device_get_port_status();
#endif

2022
bdk/usb/xusbd.c Normal file

File diff suppressed because it is too large Load diff