You aint taking this down
This commit is contained in:
parent
0bcd59d0cb
commit
a2679d92c9
398 changed files with 116325 additions and 35 deletions
238
bdk/usb/usb_descriptor_types.h
Normal file
238
bdk/usb/usb_descriptor_types.h
Normal 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
|
558
bdk/usb/usb_descriptors.c
Normal file
558
bdk/usb/usb_descriptors.c
Normal file
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <usb/usb_descriptor_types.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
static usb_dev_descr_t usb_device_descriptor_ums =
|
||||
{
|
||||
.bLength = 18,
|
||||
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
|
||||
.bcdUSB = 0x210,
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize = 0x40,
|
||||
.idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955
|
||||
.idProduct = 0xA7E0, // Switch: 0x2000, usbd: 0x3000
|
||||
.bcdDevice = 0x0101,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigs = 1
|
||||
};
|
||||
|
||||
static usb_dev_qual_descr_t usb_device_qualifier_descriptor =
|
||||
{
|
||||
.bLength = 10,
|
||||
.bDescriptorType = USB_DESCRIPTOR_DEVICE_QUALIFIER,
|
||||
.bcdUSB = 0x210,
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize = 0x40,
|
||||
.bNumOtherConfigs = 0x01,
|
||||
.bReserved = 0x00
|
||||
};
|
||||
|
||||
static usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
|
||||
{
|
||||
/* Configuration descriptor structure */
|
||||
.config.bLength = 9,
|
||||
.config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION,
|
||||
.config.wTotalLength = 0x20,
|
||||
.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 = 0x08, // Mass Storage Class.
|
||||
.interface.bInterfaceSubClass = 0x06, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x50, // Bulk-Only Transport.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
/* 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_BULK,
|
||||
.endpoint[0].wMaxPacketSize = 0x200,
|
||||
.endpoint[0].bInterval = 0x00,
|
||||
|
||||
/* 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_BULK,
|
||||
.endpoint[1].wMaxPacketSize = 0x200,
|
||||
.endpoint[1].bInterval = 0x00
|
||||
};
|
||||
|
||||
static usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
|
||||
{
|
||||
/* Other Speed Configuration descriptor structure */
|
||||
.config.bLength = 9,
|
||||
.config.bDescriptorType = USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION,
|
||||
.config.wTotalLength = 0x20,
|
||||
.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 = 0x00,
|
||||
.interface.bAlternateSetting = 0x00,
|
||||
.interface.bNumEndpoints = 2,
|
||||
.interface.bInterfaceClass = 0x08, // Mass Storage Class.
|
||||
.interface.bInterfaceSubClass = 0x06, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x50, // Bulk-Only Transport.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
/* 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_BULK,
|
||||
.endpoint[0].wMaxPacketSize = 0x40,
|
||||
.endpoint[0].bInterval = 0,
|
||||
|
||||
/* 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_BULK,
|
||||
.endpoint[1].wMaxPacketSize = 0x40,
|
||||
.endpoint[1].bInterval = 0
|
||||
};
|
||||
|
||||
static usb_dev_bot_t usb_device_binary_object_descriptor =
|
||||
{
|
||||
.bLength = 5,
|
||||
.bDescriptorType = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT,
|
||||
.wTotalLength = 22,
|
||||
.bNumDeviceCaps = 2,
|
||||
|
||||
/* Device Capability USB 2.0 Extension Descriptor */
|
||||
.bLengthCap0 = 7,
|
||||
.bDescriptorTypeCap0 = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP,
|
||||
.bDevCapabilityTypeCap0 = 2, // USB2.
|
||||
.bmAttributesCap0 = 0,
|
||||
|
||||
/* Device Capability SuperSpeed Descriptor */
|
||||
/* Needed for a USB2.10 device. */
|
||||
.bLengthCap1 = 10,
|
||||
.bDescriptorTypeCap1 = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP,
|
||||
.bDevCapabilityTypeCap1 = 3, // USB3.
|
||||
.bmAttributesCap1 = 0,
|
||||
.wSpeedsSupported = 0x6, // FS | HS.
|
||||
.bFunctionalitySupport = 1, // FS and above.
|
||||
.bU1DevExitLat = 0,
|
||||
.wU2DevExitLat = 0
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
static u8 usb_product_string_descriptor_ums[22] =
|
||||
{
|
||||
8, 0x03,
|
||||
'U', 0, 'M', 0, 'S', 0
|
||||
};
|
||||
|
||||
static usb_ms_os_descr_t usb_ms_os_descriptor =
|
||||
{
|
||||
.bLength = 0x28,
|
||||
.bDescriptorType = 0x03,
|
||||
.wSignature[0] = 'M',
|
||||
.wSignature[1] = 'S',
|
||||
.wSignature[2] = 'F',
|
||||
.wSignature[3] = 'T',
|
||||
.wSignature[4] = '1',
|
||||
.wSignature[5] = '0',
|
||||
.wSignature[6] = '0',
|
||||
.bVendorCode = 0x99,
|
||||
};
|
||||
|
||||
static usb_ms_cid_descr_t usb_ms_cid_descriptor =
|
||||
{
|
||||
.dLength = 0x28,
|
||||
.wVersion = 0x100,
|
||||
.wCompatibilityId = USB_DESCRIPTOR_MS_COMPAT_ID,
|
||||
.bSections = 1,
|
||||
.bInterfaceNumber = 0,
|
||||
.bReserved1 = 1,
|
||||
|
||||
.bCompatibleId[0] = 'N',
|
||||
.bCompatibleId[1] = 'Y',
|
||||
.bCompatibleId[2] = 'X',
|
||||
.bCompatibleId[3] = 'U',
|
||||
.bCompatibleId[4] = 'S',
|
||||
.bCompatibleId[5] = 'B',
|
||||
};
|
||||
|
||||
static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
|
||||
{
|
||||
.dLength = 0x48,
|
||||
.wVersion = 0x100,
|
||||
.wExtendedProperty = USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES,
|
||||
.wSections = 1,
|
||||
|
||||
.dPropertySize = 0x3E,
|
||||
.dPropertyType = 4, // DWORD
|
||||
|
||||
.wPropertyNameLength = 0x2C,
|
||||
.wPropertyName[0] = 'M', // MaximumTransferLength.
|
||||
.wPropertyName[1] = 'a',
|
||||
.wPropertyName[2] = 'x',
|
||||
.wPropertyName[3] = 'i',
|
||||
.wPropertyName[4] = 'm',
|
||||
.wPropertyName[5] = 'u',
|
||||
.wPropertyName[6] = 'm',
|
||||
.wPropertyName[7] = 'T',
|
||||
.wPropertyName[8] = 'r',
|
||||
.wPropertyName[9] = 'a',
|
||||
.wPropertyName[10] = 'n',
|
||||
.wPropertyName[11] = 's',
|
||||
.wPropertyName[12] = 'f',
|
||||
.wPropertyName[13] = 'e',
|
||||
.wPropertyName[14] = 'r',
|
||||
.wPropertyName[15] = 'L',
|
||||
.wPropertyName[16] = 'e',
|
||||
.wPropertyName[17] = 'n',
|
||||
.wPropertyName[18] = 'g',
|
||||
.wPropertyName[19] = 't',
|
||||
.wPropertyName[20] = 'h',
|
||||
.wPropertyName[21] = 0,
|
||||
|
||||
.dPropertyDataLength = 0x4,
|
||||
.wPropertyData[0] = 0x00, // 1MB.
|
||||
.wPropertyData[1] = 0x10,
|
||||
};
|
||||
|
||||
static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
|
||||
{
|
||||
.dLength = 7,
|
||||
.wVersion = 0x100,
|
||||
.wExtendedProperty = USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES,
|
||||
.wSections = 0,
|
||||
};
|
||||
|
||||
static usb_dev_descr_t usb_device_descriptor_hid_jc =
|
||||
{
|
||||
.bLength = 18,
|
||||
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
|
||||
.bcdUSB = 0x210,
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize = 0x40,
|
||||
.idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955
|
||||
.idProduct = 0xA7E1, // Switch: 0x2000, usbd: 0x3000
|
||||
.bcdDevice = 0x0101,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigs = 1
|
||||
};
|
||||
|
||||
static usb_dev_descr_t usb_device_descriptor_hid_touch =
|
||||
{
|
||||
.bLength = 18,
|
||||
.bDescriptorType = USB_DESCRIPTOR_DEVICE,
|
||||
.bcdUSB = 0x210,
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize = 0x40,
|
||||
.idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955
|
||||
.idProduct = 0xA7E2, // Switch: 0x2000, usbd: 0x3000
|
||||
.bcdDevice = 0x0101,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigs = 1
|
||||
};
|
||||
|
||||
u8 hid_report_descriptor_jc[] =
|
||||
{
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop),
|
||||
0x09, 0x04, // USAGE (Joystick),
|
||||
0xa1, 0x01, // COLLECTION (Application),
|
||||
0xa1, 0x02, // COLLECTION (Logical),
|
||||
0x75, 0x08, // REPORT_SIZE (8),
|
||||
0x95, 0x04, // REPORT_COUNT (4),
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0),
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255),
|
||||
0x35, 0x00, // PHYSICAL_MINIMUM (0),
|
||||
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255),
|
||||
0x09, 0x30, // USAGE (X_ID),
|
||||
0x09, 0x31, // USAGE (Y_ID),
|
||||
0x09, 0x32, // USAGE (Z_ID),
|
||||
0x09, 0x35, // USAGE (Rz_ID),
|
||||
0x81, 0x02, // INPUT (IOF_Variable),
|
||||
0x75, 0x04, // REPORT_SIZE (4),
|
||||
0x95, 0x01, // REPORT_COUNT (1),
|
||||
0x25, 0x07, // LOGICAL_MAXIMUM (7),
|
||||
0x46, 0x3b, 0x01, // PHYSICAL_MAXIMUM (315),
|
||||
0x65, 0x14, // UNIT (Eng_Rot_Angular_Pos),
|
||||
0x09, 0x39, // USAGE (Hat_Switch),
|
||||
0x81, 0x42, // INPUT (IOF_NullposVar),
|
||||
0x65, 0x00, // UNIT (Unit_None),
|
||||
0x75, 0x01, // REPORT_SIZE (1),
|
||||
0x95, 0x0c, // REPORT_COUNT (12),
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1),
|
||||
0x45, 0x01, // PHYSICAL_MAXIMUM (1),
|
||||
0x05, 0x09, // USAGE_PAGE (Button_ID),
|
||||
0x19, 0x01, // USAGE_MINIMUM (1),
|
||||
0x29, 0x0c, // USAGE_MAXIMUM (12),
|
||||
0x81, 0x02, // INPUT (IOF_Variable),
|
||||
0xc0, // END_COLLECTION(),
|
||||
0xc0 // END_COLLECTION(),
|
||||
};
|
||||
|
||||
u32 hid_report_descriptor_jc_size = sizeof(hid_report_descriptor_jc);
|
||||
|
||||
u8 hid_report_descriptor_touch[] =
|
||||
{
|
||||
0x05, 0x0d, // USAGE_PAGE (Digitizers)
|
||||
0x09, 0x05, // USAGE (Touch Pad)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x05, // REPORT_ID (Touch pad)
|
||||
0x09, 0x22, // USAGE (Finger)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x09, 0x42, // USAGE (Tip switch)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x07, // REPORT_COUNT (7)
|
||||
0x09, 0x54, // USAGE (Contact Count)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x0A, // LOGICAL_MAXIMUM (10)
|
||||
0x09, 0x51, // USAGE (Contact Identifier)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
// 0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
// 0x26, 0xF8, 0x2A, // LOGICAL_MAXIMUM (11000)
|
||||
// 0x95, 0x01, // REPORT_COUNT (1)
|
||||
// 0x75, 0x08, // REPORT_SIZE (16)
|
||||
// 0x09, 0x30, // USAGE (Pressure)
|
||||
// 0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desk..
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x04, // LOGICAL_MAXIMUM (1279)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x55, 0x0e, // UNIT_EXPONENT (-2)
|
||||
0x65, 0x13, // UNIT(Inch,EngLinear)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x35, 0x00, // PHYSICAL_MINIMUM (0)
|
||||
0x46, 0xFF, 0x04, // PHYSICAL_MAXIMUM (1279)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x26, 0xCF, 0x02, // LOGICAL_MAXIMUM (719)
|
||||
0x46, 0xCF, 0x02, // PHYSICAL_MAXIMUM (719)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x05, 0x0d, // USAGE PAGE (Digitizers)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
u32 hid_report_descriptor_touch_size = sizeof(hid_report_descriptor_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,
|
||||
.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 = 0x111,
|
||||
.hid.bCountryCode = 0,
|
||||
.hid.bNumDescriptors = 1,
|
||||
.hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT,
|
||||
.hid.bDescriptorLength = sizeof(hid_report_descriptor_touch),
|
||||
|
||||
/* 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 = 3, // 4ms 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 = 3 // 4ms on HS.
|
||||
};
|
||||
|
||||
usb_desc_t usb_gadget_ums_descriptors =
|
||||
{
|
||||
.dev = &usb_device_descriptor_ums,
|
||||
.dev_qual = &usb_device_qualifier_descriptor,
|
||||
.cfg = &usb_configuration_descriptor_ums,
|
||||
.cfg_other = &usb_other_speed_config_descriptor_ums,
|
||||
.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
|
||||
};
|
||||
|
||||
usb_desc_t usb_gadget_hid_jc_descriptors =
|
||||
{
|
||||
.dev = &usb_device_descriptor_hid_jc,
|
||||
.dev_qual = &usb_device_qualifier_descriptor,
|
||||
.cfg = (usb_cfg_simple_descr_t *)&usb_configuration_descriptor_hid_jc,
|
||||
.cfg_other = NULL,
|
||||
.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
|
||||
};
|
||||
|
||||
usb_desc_t usb_gadget_hid_touch_descriptors =
|
||||
{
|
||||
.dev = &usb_device_descriptor_hid_touch,
|
||||
.dev_qual = &usb_device_qualifier_descriptor,
|
||||
.cfg = (usb_cfg_simple_descr_t *)&usb_configuration_descriptor_hid_touch,
|
||||
.cfg_other = NULL,
|
||||
.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
|
||||
};
|
441
bdk/usb/usb_gadget_hid.c
Normal file
441
bdk/usb/usb_gadget_hid.c
Normal file
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
* USB Gadget HID 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <usb/usbd.h>
|
||||
#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>
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
typedef struct _gamepad_report_t
|
||||
{
|
||||
u8 x;
|
||||
u8 y;
|
||||
u8 z;
|
||||
u8 rz;
|
||||
|
||||
u8 hat:4;
|
||||
u8 btn1:1;
|
||||
u8 btn2:1;
|
||||
u8 btn3:1;
|
||||
u8 btn4:1;
|
||||
|
||||
u8 btn5:1;
|
||||
u8 btn6:1;
|
||||
u8 btn7:1;
|
||||
u8 btn8:1;
|
||||
u8 btn9:1;
|
||||
u8 btn10:1;
|
||||
u8 btn11:1;
|
||||
u8 btn12:1;
|
||||
} __attribute__((packed)) gamepad_report_t;
|
||||
|
||||
typedef struct _jc_cal_t
|
||||
{
|
||||
bool cl_done;
|
||||
bool cr_done;
|
||||
u16 clx_max;
|
||||
u16 clx_min;
|
||||
u16 cly_max;
|
||||
u16 cly_min;
|
||||
u16 crx_max;
|
||||
u16 crx_min;
|
||||
u16 cry_max;
|
||||
u16 cry_min;
|
||||
} 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)
|
||||
{
|
||||
// Calibrate left stick.
|
||||
if (!jc_cal_ctx.cl_done)
|
||||
{
|
||||
if (jc_pad->conn_l
|
||||
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
|
||||
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
|
||||
{
|
||||
jc_cal_ctx.clx_max = jc_pad->lstick_x + 0x72;
|
||||
jc_cal_ctx.clx_min = jc_pad->lstick_x - 0x72;
|
||||
jc_cal_ctx.cly_max = jc_pad->lstick_y + 0x72;
|
||||
jc_cal_ctx.cly_min = jc_pad->lstick_y - 0x72;
|
||||
jc_cal_ctx.cl_done = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calibrate right stick.
|
||||
if (!jc_cal_ctx.cr_done)
|
||||
{
|
||||
if (jc_pad->conn_r
|
||||
&& jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400
|
||||
&& jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00)
|
||||
{
|
||||
jc_cal_ctx.crx_max = jc_pad->rstick_x + 0x72;
|
||||
jc_cal_ctx.crx_min = jc_pad->rstick_x - 0x72;
|
||||
jc_cal_ctx.cry_max = jc_pad->rstick_y + 0x72;
|
||||
jc_cal_ctx.cry_min = jc_pad->rstick_y - 0x72;
|
||||
jc_cal_ctx.cr_done = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _jc_poll(gamepad_report_t *rpt)
|
||||
{
|
||||
// Poll Joy-Con.
|
||||
jc_gamepad_rpt_t *jc_pad = joycon_poll();
|
||||
|
||||
if (!jc_pad)
|
||||
return false;
|
||||
|
||||
// Exit emulation if Left stick and Home are pressed.
|
||||
if (jc_pad->l3 && jc_pad->home)
|
||||
return true;
|
||||
|
||||
if (!jc_cal_ctx.cl_done || !jc_cal_ctx.cr_done)
|
||||
{
|
||||
if (!_jc_calibration(jc_pad))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Re-calibrate on disconnection.
|
||||
if (!jc_pad->conn_l)
|
||||
jc_cal_ctx.cl_done = false;
|
||||
if (!jc_pad->conn_r)
|
||||
jc_cal_ctx.cr_done = false;
|
||||
|
||||
// Calculate left analog stick.
|
||||
if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min)
|
||||
rpt->x = 0x7F;
|
||||
else if (jc_pad->lstick_x > jc_cal_ctx.clx_max)
|
||||
{
|
||||
u16 x_raw = (jc_pad->lstick_x - jc_cal_ctx.clx_max) / 7;
|
||||
if (x_raw > 0x7F)
|
||||
x_raw = 0x7F;
|
||||
rpt->x = 0x7F + x_raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 x_raw = (jc_cal_ctx.clx_min - jc_pad->lstick_x) / 7;
|
||||
if (x_raw > 0x7F)
|
||||
x_raw = 0x7F;
|
||||
rpt->x = 0x7F - x_raw;
|
||||
}
|
||||
|
||||
if (jc_pad->lstick_y <= jc_cal_ctx.cly_max && jc_pad->lstick_y >= jc_cal_ctx.cly_min)
|
||||
rpt->y = 0x7F;
|
||||
else if (jc_pad->lstick_y > jc_cal_ctx.cly_max)
|
||||
{
|
||||
u16 y_raw = (jc_pad->lstick_y - jc_cal_ctx.cly_max) / 7;
|
||||
if (y_raw > 0x7F)
|
||||
y_raw = 0x7F;
|
||||
rpt->y = 0x7F - y_raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 y_raw = (jc_cal_ctx.cly_min - jc_pad->lstick_y) / 7;
|
||||
if (y_raw > 0x7F)
|
||||
y_raw = 0x7F;
|
||||
rpt->y = 0x7F + y_raw;
|
||||
}
|
||||
|
||||
// Calculate right analog stick.
|
||||
if (jc_pad->rstick_x <= jc_cal_ctx.crx_max && jc_pad->rstick_x >= jc_cal_ctx.crx_min)
|
||||
rpt->z = 0x7F;
|
||||
else if (jc_pad->rstick_x > jc_cal_ctx.crx_max)
|
||||
{
|
||||
u16 x_raw = (jc_pad->rstick_x - jc_cal_ctx.crx_max) / 7;
|
||||
if (x_raw > 0x7F)
|
||||
x_raw = 0x7F;
|
||||
rpt->z = 0x7F + x_raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 x_raw = (jc_cal_ctx.crx_min - jc_pad->rstick_x) / 7;
|
||||
if (x_raw > 0x7F)
|
||||
x_raw = 0x7F;
|
||||
rpt->z = 0x7F - x_raw;
|
||||
}
|
||||
|
||||
if (jc_pad->rstick_y <= jc_cal_ctx.cry_max && jc_pad->rstick_y >= jc_cal_ctx.cry_min)
|
||||
rpt->rz = 0x7F;
|
||||
else if (jc_pad->rstick_y > jc_cal_ctx.cry_max)
|
||||
{
|
||||
u16 y_raw = (jc_pad->rstick_y - jc_cal_ctx.cry_max) / 7;
|
||||
if (y_raw > 0x7F)
|
||||
y_raw = 0x7F;
|
||||
rpt->rz = 0x7F - y_raw;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 y_raw = (jc_cal_ctx.cry_min - jc_pad->rstick_y) / 7;
|
||||
if (y_raw > 0x7F)
|
||||
y_raw = 0x7F;
|
||||
rpt->rz = 0x7F + y_raw;
|
||||
}
|
||||
|
||||
// Set D-pad.
|
||||
switch ((jc_pad->buttons >> 16) & 0xF)
|
||||
{
|
||||
case 0: // none
|
||||
rpt->hat = 0xF;
|
||||
break;
|
||||
case 1: // down
|
||||
rpt->hat = 4;
|
||||
break;
|
||||
case 2: // up
|
||||
rpt->hat = 0;
|
||||
break;
|
||||
case 4: // right
|
||||
rpt->hat = 2;
|
||||
break;
|
||||
case 5: // down + right
|
||||
rpt->hat = 3;
|
||||
break;
|
||||
case 6: // up + right
|
||||
rpt->hat = 1;
|
||||
break;
|
||||
case 8: // left
|
||||
rpt->hat = 6;
|
||||
break;
|
||||
case 9: // down + left
|
||||
rpt->hat = 5;
|
||||
break;
|
||||
case 10: // up + left
|
||||
rpt->hat = 7;
|
||||
break;
|
||||
default:
|
||||
rpt->hat = 0xF;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set buttons.
|
||||
rpt->btn1 = jc_pad->b; // x.
|
||||
rpt->btn2 = jc_pad->a; // a.
|
||||
rpt->btn3 = jc_pad->y; // b.
|
||||
rpt->btn4 = jc_pad->x; // y.
|
||||
|
||||
rpt->btn5 = jc_pad->l;
|
||||
rpt->btn6 = jc_pad->r;
|
||||
rpt->btn7 = jc_pad->zl;
|
||||
rpt->btn8 = jc_pad->zr;
|
||||
rpt->btn9 = jc_pad->minus;
|
||||
rpt->btn10 = jc_pad->plus;
|
||||
rpt->btn11 = jc_pad->l3;
|
||||
rpt->btn12 = jc_pad->r3;
|
||||
|
||||
//rpt->btn13 = jc_pad->cap;
|
||||
//rpt->btn14 = jc_pad->home;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct _touchpad_report_t
|
||||
{
|
||||
u8 rpt_id;
|
||||
u8 tip_switch:1;
|
||||
u8 count:7;
|
||||
|
||||
u8 id;
|
||||
|
||||
//u16 z;
|
||||
u16 x;
|
||||
u16 y;
|
||||
} __attribute__((packed)) touchpad_report_t;
|
||||
|
||||
static bool _fts_touch_read(touchpad_report_t *rpt)
|
||||
{
|
||||
static touch_event touchpad;
|
||||
|
||||
touch_poll(&touchpad);
|
||||
|
||||
rpt->rpt_id = 5;
|
||||
rpt->count = 1;
|
||||
|
||||
// Decide touch enable.
|
||||
switch (touchpad.type & STMFTS_MASK_EVENT_ID)
|
||||
{
|
||||
//case STMFTS_EV_MULTI_TOUCH_ENTER:
|
||||
case STMFTS_EV_MULTI_TOUCH_MOTION:
|
||||
rpt->x = touchpad.x;
|
||||
rpt->y = touchpad.y;
|
||||
//rpt->z = touchpad.z;
|
||||
rpt->id = touchpad.fingers ? touchpad.fingers - 1 : 0;
|
||||
rpt->tip_switch = 1;
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_LEAVE:
|
||||
rpt->x = touchpad.x;
|
||||
rpt->y = touchpad.y;
|
||||
//rpt->z = touchpad.z;
|
||||
rpt->id = touchpad.fingers ? touchpad.fingers - 1 : 0;
|
||||
rpt->tip_switch = 0;
|
||||
break;
|
||||
case STMFTS_EV_NO_EVENT:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
|
||||
{
|
||||
u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED_CMD);
|
||||
if (status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
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 == USB_ERROR_TIMEOUT)
|
||||
return 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool _hid_poll_jc(usb_ctxt_t *usbs)
|
||||
{
|
||||
if (_jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR))
|
||||
return true;
|
||||
|
||||
// Send HID report.
|
||||
if (_hid_transfer_start(usbs, sizeof(gamepad_report_t)))
|
||||
return true; // EP Error.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _hid_poll_touch(usb_ctxt_t *usbs)
|
||||
{
|
||||
_fts_touch_read((touchpad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
|
||||
|
||||
// Send HID report.
|
||||
if (_hid_transfer_start(usbs, sizeof(touchpad_report_t)))
|
||||
return true; // EP Error.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
{
|
||||
int res = 0;
|
||||
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;
|
||||
gadget_type = USB_GADGET_HID_GAMEPAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
polling_time = 4000;
|
||||
gadget_type = USB_GADGET_HID_TOUCHPAD;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB");
|
||||
|
||||
if (usb_ops.usb_device_init())
|
||||
{
|
||||
usb_ops.usbd_end(false, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection");
|
||||
|
||||
// Initialize Control Endpoint.
|
||||
if (usb_ops.usb_device_enumerate(gadget_type))
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for HID report request");
|
||||
|
||||
if (usb_ops.usb_device_class_send_hid_report())
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation");
|
||||
|
||||
u32 timer_sys = get_tmr_ms() + 5000;
|
||||
while (true)
|
||||
{
|
||||
u32 timer = get_tmr_us();
|
||||
|
||||
// Parse input device.
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
{
|
||||
if (_hid_poll_jc(usbs))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_hid_poll_touch(usbs))
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for suspended USB in case the cable was pulled.
|
||||
if (usb_ops.usb_device_get_suspended())
|
||||
break; // Disconnected.
|
||||
|
||||
// Handle control endpoint.
|
||||
usb_ops.usbd_handle_ep0_ctrl_setup();
|
||||
|
||||
// Wait max gadget timing.
|
||||
timer = get_tmr_us() - timer;
|
||||
if (timer < polling_time)
|
||||
usleep(polling_time - timer);
|
||||
|
||||
if (timer_sys < get_tmr_ms())
|
||||
{
|
||||
usbs->system_maintenance(true);
|
||||
timer_sys = get_tmr_ms() + 5000;
|
||||
}
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 Status:# HID ended");
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
usbs->set_text(usbs->label, "#FFDD00 Error:# Timed out or canceled");
|
||||
res = 1;
|
||||
|
||||
exit:
|
||||
usb_ops.usbd_end(true, false);
|
||||
|
||||
return res;
|
||||
}
|
1949
bdk/usb/usb_gadget_ums.c
Normal file
1949
bdk/usb/usb_gadget_ums.c
Normal file
File diff suppressed because it is too large
Load diff
296
bdk/usb/usb_t210.h
Normal file
296
bdk/usb/usb_t210.h
Normal file
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 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_T210_H_
|
||||
#define _USB_T210_H_
|
||||
|
||||
#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 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
|
||||
#define USB1_UTMIP_HSRX_CFG0 0x810
|
||||
#define USB1_UTMIP_HSRX_CFG1 0x814
|
||||
#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
|
||||
#define USB1_UTMIP_BIAS_CFG2 0x850
|
||||
#define USB1_UTMIP_XCVR_CFG2 0x854
|
||||
#define USB1_UTMIP_XCVR_CFG3 0x858
|
||||
|
||||
/* USB Queue Head Descriptor */
|
||||
#define USB2_QH_USB2D_QH_EP_BASE (USB_BASE + 0x1000)
|
||||
#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 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 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 BIT(15)
|
||||
#define USB_QHD_TOKEN_TOTAL_BYTES_SHIFT 16
|
||||
|
||||
/* USB_OTG/USB_1 controllers register bits */
|
||||
#define USB2D_PORTSC1_SUSP BIT(7)
|
||||
|
||||
#define USB2D_USBCMD_RUN BIT(0)
|
||||
#define USB2D_USBCMD_RESET BIT(1)
|
||||
#define USB2D_USBCMD_ITC_MASK (0xFF << 16)
|
||||
|
||||
#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
|
||||
#define USB2D_USBMODE_CM_RSVD 1
|
||||
#define USB2D_USBMODE_CM_DEVICE 2
|
||||
#define USB2D_USBMODE_CM_HOST 3
|
||||
|
||||
#define USB2D_ENDPT_STATUS_RX_OFFSET BIT(0)
|
||||
#define USB2D_ENDPT_STATUS_TX_OFFSET BIT(16)
|
||||
|
||||
#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 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 BIT(21)
|
||||
#define USB2D_ENDPTCTRL_TX_EP_RESET BIT(22)
|
||||
#define USB2D_ENDPTCTRL_TX_EP_ENABLE BIT(23)
|
||||
|
||||
#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 BIT(5)
|
||||
#define USB2D_OTGSC_USB_IRQ_STS_MASK (0x7F << 16)
|
||||
|
||||
/* USB_OTG/USB_1 controllers registers */
|
||||
typedef struct _t210_usb2d_t
|
||||
{
|
||||
vu32 id;
|
||||
vu32 unk0;
|
||||
vu32 hw_host;
|
||||
vu32 hw_device;
|
||||
vu32 hw_txbuf;
|
||||
vu32 hw_rxbuf;
|
||||
vu32 unk1[26];
|
||||
vu32 gptimer0ld;
|
||||
vu32 gptimer0ctrl;
|
||||
vu32 gptimer1ld;
|
||||
vu32 gptimer1ctrl;
|
||||
vu32 unk2[28];
|
||||
vu16 caplength;
|
||||
vu16 hciversion;
|
||||
vu32 hcsparams;
|
||||
vu32 hccparams;
|
||||
vu32 unk3[5];
|
||||
vu32 dciversion;
|
||||
vu32 dccparams;
|
||||
vu32 extsts;
|
||||
vu32 usbextintr;
|
||||
vu32 usbcmd;
|
||||
vu32 usbsts;
|
||||
vu32 usbintr;
|
||||
vu32 frindex;
|
||||
vu32 unk4;
|
||||
vu32 periodiclistbase;
|
||||
vu32 asynclistaddr;
|
||||
vu32 asyncttsts;
|
||||
vu32 burstsize;
|
||||
vu32 txfilltuning;
|
||||
vu32 unk6;
|
||||
vu32 icusb_ctrl;
|
||||
vu32 ulpi_viewport;
|
||||
vu32 rsvd0[4];
|
||||
vu32 portsc1;
|
||||
vu32 rsvd1[15];
|
||||
vu32 hostpc1_devlc;
|
||||
vu32 rsvd2[15];
|
||||
vu32 otgsc;
|
||||
vu32 usbmode;
|
||||
vu32 unk10;
|
||||
vu32 endptnak;
|
||||
vu32 endptnak_enable;
|
||||
vu32 endptsetupstat;
|
||||
vu32 endptprime;
|
||||
vu32 endptflush;
|
||||
vu32 endptstatus;
|
||||
vu32 endptcomplete;
|
||||
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_RT_IMOD 0x38
|
||||
#define XUSB_DEV_XHCI_PORTSC 0x3C
|
||||
#define XHCI_PORTSC_CCS BIT(0)
|
||||
#define XHCI_PORTSC_PED BIT(1)
|
||||
#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_EP0_IN 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 XUSB_DEV_XHCI_EP_STOPPED 0x78
|
||||
#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
|
1595
bdk/usb/usbd.c
Normal file
1595
bdk/usb/usbd.c
Normal file
File diff suppressed because it is too large
Load diff
204
bdk/usb/usbd.h
Normal file
204
bdk/usb/usbd.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 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_H_
|
||||
#define _USB_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define USB_TD_BUFFER_PAGE_SIZE 0x1000
|
||||
#define USB_TD_BUFFER_MAX_SIZE (USB_TD_BUFFER_PAGE_SIZE * 4)
|
||||
//#define USB_HW_BUFFER_5_PAGES 0x5000
|
||||
#define USB_EP_BUFFER_1_TD (USB_TD_BUFFER_MAX_SIZE)
|
||||
#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 0
|
||||
#define USB_XFER_SYNCED_ENUM 1000000
|
||||
#define USB_XFER_SYNCED_CMD 1000000
|
||||
#define USB_XFER_SYNCED_DATA 2000000
|
||||
#define USB_XFER_SYNCED_CLASS 5000000
|
||||
#define USB_XFER_SYNCED -1
|
||||
|
||||
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_BABBLE_DETECTED = 50,
|
||||
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 *, u32);
|
||||
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
|
||||
int (*usb_device_ep1_out_reading_finish)(u32 *, u32);
|
||||
int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, u32);
|
||||
int (*usb_device_ep1_in_writing_finish)(u32 *, u32);
|
||||
bool (*usb_device_get_suspended)();
|
||||
bool (*usb_device_get_port_in_sleep)();
|
||||
} usb_ops_t;
|
||||
|
||||
typedef struct _usb_ctxt_t
|
||||
{
|
||||
u32 type;
|
||||
u32 partition;
|
||||
u32 offset;
|
||||
u32 sectors;
|
||||
u32 ro;
|
||||
void (*system_maintenance)(bool);
|
||||
void *label;
|
||||
void (*set_text)(void *, const char *);
|
||||
} usb_ctxt_t;
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
2108
bdk/usb/xusbd.c
Normal file
2108
bdk/usb/xusbd.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue