restore lost packages from 0.2.3 + fix overwritten 0.2.4 files
- Restore 29 recipe symlinks (libdrm, qtbase, dbus, sddm, pipewire, etc.) - Restore 33 patches (KDE, libdrm, mesa, pipewire, sddm, wireplumber) - Restore 20+ local/scripts (audit, lint, test, build helpers) - Restore src/cook/scheduler.rs, status.rs, gnu-config/ - Restore scripts/patch-inclusion-gate.sh, run_mini1.sh, validate-collision-log.sh - Recover TLC source from HEAD (was overwritten by 0.2.3 checkout) - Recover 11 local/docs plans from HEAD (were overwritten) - Recover qt6-wayland-smoke symlink from HEAD - Fix MOTD: remove garbled ASCII art, use clean text - Update version: 0.2.0 -> 0.2.4 in os-release, motd, config - Reduce filesystem_size: 1536 -> 512 MiB - Add ABSOLUTE RULE to AGENTS.md: never delete/ignore packages - Reduce pcid scheme log verbosity: info -> debug
This commit is contained in:
@@ -0,0 +1,492 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2010 Daniel Mack <daniel@caiaq.de>
|
||||
*
|
||||
* This file holds USB constants and structures defined
|
||||
* by the USB Device Class Definition for Audio Devices in version 2.0.
|
||||
* Comments below reference relevant sections of the documents contained
|
||||
* in http://www.usb.org/developers/devclass_docs/Audio2.0_final.zip
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_AUDIO_V2_H
|
||||
#define __LINUX_USB_AUDIO_V2_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* v1.0 and v2.0 of this standard have many things in common. For the rest
|
||||
* of the definitions, please refer to audio.h */
|
||||
|
||||
/*
|
||||
* bmControl field decoders
|
||||
*
|
||||
* From the USB Audio spec v2.0:
|
||||
*
|
||||
* bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
|
||||
* each containing a set of bit pairs. If a Control is present,
|
||||
* it must be Host readable. If a certain Control is not
|
||||
* present then the bit pair must be set to 0b00.
|
||||
* If a Control is present but read-only, the bit pair must be
|
||||
* set to 0b01. If a Control is also Host programmable, the bit
|
||||
* pair must be set to 0b11. The value 0b10 is not allowed.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline bool uac_v2v3_control_is_readable(u32 bmControls, u8 control)
|
||||
{
|
||||
return (bmControls >> ((control - 1) * 2)) & 0x1;
|
||||
}
|
||||
|
||||
static inline bool uac_v2v3_control_is_writeable(u32 bmControls, u8 control)
|
||||
{
|
||||
return (bmControls >> ((control - 1) * 2)) & 0x2;
|
||||
}
|
||||
|
||||
/* 4.7.2 Class-Specific AC Interface Descriptor */
|
||||
struct uac2_ac_header_descriptor {
|
||||
__u8 bLength; /* 9 */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
|
||||
__u8 bDescriptorSubtype; /* UAC_MS_HEADER */
|
||||
__le16 bcdADC; /* 0x0200 */
|
||||
__u8 bCategory;
|
||||
__le16 wTotalLength; /* includes Unit and Terminal desc. */
|
||||
__u8 bmControls;
|
||||
} __packed;
|
||||
|
||||
/* 2.3.1.6 Type I Format Type Descriptor (Frmts20 final.pdf)*/
|
||||
struct uac2_format_type_i_descriptor {
|
||||
__u8 bLength; /* in bytes: 6 */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
|
||||
__u8 bDescriptorSubtype; /* FORMAT_TYPE */
|
||||
__u8 bFormatType; /* FORMAT_TYPE_1 */
|
||||
__u8 bSubslotSize; /* {1,2,3,4} */
|
||||
__u8 bBitResolution;
|
||||
} __packed;
|
||||
|
||||
/* 4.7.2.1 Clock Source Descriptor */
|
||||
|
||||
struct uac_clock_source_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bmAttributes;
|
||||
__u8 bmControls;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 iClockSource;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* bmAttribute fields */
|
||||
#define UAC_CLOCK_SOURCE_TYPE_EXT 0x0
|
||||
#define UAC_CLOCK_SOURCE_TYPE_INT_FIXED 0x1
|
||||
#define UAC_CLOCK_SOURCE_TYPE_INT_VAR 0x2
|
||||
#define UAC_CLOCK_SOURCE_TYPE_INT_PROG 0x3
|
||||
#define UAC_CLOCK_SOURCE_SYNCED_TO_SOF (1 << 2)
|
||||
|
||||
/* 4.7.2.2 Clock Selector Descriptor */
|
||||
|
||||
struct uac_clock_selector_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bNrInPins;
|
||||
__u8 baCSourceID[];
|
||||
/* bmControls and iClockSelector omitted */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.3 Clock Multiplier Descriptor */
|
||||
|
||||
struct uac_clock_multiplier_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bCSourceID;
|
||||
__u8 bmControls;
|
||||
__u8 iClockMultiplier;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.4 Input terminal descriptor */
|
||||
|
||||
struct uac2_input_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__le16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bCSourceID;
|
||||
__u8 bNrChannels;
|
||||
__le32 bmChannelConfig;
|
||||
__u8 iChannelNames;
|
||||
__le16 bmControls;
|
||||
__u8 iTerminal;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.5 Output terminal descriptor */
|
||||
|
||||
struct uac2_output_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__le16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bSourceID;
|
||||
__u8 bCSourceID;
|
||||
__le16 bmControls;
|
||||
__u8 iTerminal;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
/* 4.7.2.8 Feature Unit Descriptor */
|
||||
|
||||
struct uac2_feature_unit_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bUnitID;
|
||||
__u8 bSourceID;
|
||||
/* bmaControls is actually u32,
|
||||
* but u8 is needed for the hybrid parser */
|
||||
__u8 bmaControls[]; /* variable length */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define UAC2_DT_FEATURE_UNIT_SIZE(ch) (6 + ((ch) + 1) * 4)
|
||||
|
||||
/* As above, but more useful for defining your own descriptors: */
|
||||
#define DECLARE_UAC2_FEATURE_UNIT_DESCRIPTOR(ch) \
|
||||
struct uac2_feature_unit_descriptor_##ch { \
|
||||
__u8 bLength; \
|
||||
__u8 bDescriptorType; \
|
||||
__u8 bDescriptorSubtype; \
|
||||
__u8 bUnitID; \
|
||||
__u8 bSourceID; \
|
||||
__le32 bmaControls[ch + 1]; \
|
||||
__u8 iFeature; \
|
||||
} __packed
|
||||
|
||||
/* 4.7.2.10 Effect Unit Descriptor */
|
||||
|
||||
struct uac2_effect_unit_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bUnitID;
|
||||
__le16 wEffectType;
|
||||
__u8 bSourceID;
|
||||
__u8 bmaControls[]; /* variable length */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.9.2 Class-Specific AS Interface Descriptor */
|
||||
|
||||
struct uac2_as_header_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalLink;
|
||||
__u8 bmControls;
|
||||
__u8 bFormatType;
|
||||
__le32 bmFormats;
|
||||
__u8 bNrChannels;
|
||||
__le32 bmChannelConfig;
|
||||
__u8 iChannelNames;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define UAC2_FORMAT_TYPE_I_RAW_DATA (1 << 31)
|
||||
|
||||
/* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
|
||||
|
||||
struct uac2_iso_endpoint_descriptor {
|
||||
__u8 bLength; /* in bytes: 8 */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
|
||||
__u8 bDescriptorSubtype; /* EP_GENERAL */
|
||||
__u8 bmAttributes;
|
||||
__u8 bmControls;
|
||||
__u8 bLockDelayUnits;
|
||||
__le16 wLockDelay;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define UAC2_CONTROL_PITCH (3 << 0)
|
||||
#define UAC2_CONTROL_DATA_OVERRUN (3 << 2)
|
||||
#define UAC2_CONTROL_DATA_UNDERRUN (3 << 4)
|
||||
|
||||
/* 5.2.5.4.2 Connector Control Parameter Block */
|
||||
struct uac2_connectors_ctl_blk {
|
||||
__u8 bNrChannels;
|
||||
__le32 bmChannelConfig;
|
||||
__u8 iChannelNames;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 6.1 Interrupt Data Message */
|
||||
|
||||
#define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0)
|
||||
#define UAC2_INTERRUPT_DATA_MSG_EP (1 << 1)
|
||||
|
||||
struct uac2_interrupt_data_msg {
|
||||
__u8 bInfo;
|
||||
__u8 bAttribute;
|
||||
__le16 wValue;
|
||||
__le16 wIndex;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* A.7 Audio Function Category Codes */
|
||||
#define UAC2_FUNCTION_SUBCLASS_UNDEFINED 0x00
|
||||
#define UAC2_FUNCTION_DESKTOP_SPEAKER 0x01
|
||||
#define UAC2_FUNCTION_HOME_THEATER 0x02
|
||||
#define UAC2_FUNCTION_MICROPHONE 0x03
|
||||
#define UAC2_FUNCTION_HEADSET 0x04
|
||||
#define UAC2_FUNCTION_TELEPHONE 0x05
|
||||
#define UAC2_FUNCTION_CONVERTER 0x06
|
||||
#define UAC2_FUNCTION_SOUND_RECORDER 0x07
|
||||
#define UAC2_FUNCTION_IO_BOX 0x08
|
||||
#define UAC2_FUNCTION_MUSICAL_INSTRUMENT 0x09
|
||||
#define UAC2_FUNCTION_PRO_AUDIO 0x0a
|
||||
#define UAC2_FUNCTION_AUDIO_VIDEO 0x0b
|
||||
#define UAC2_FUNCTION_CONTROL_PANEL 0x0c
|
||||
#define UAC2_FUNCTION_OTHER 0xff
|
||||
|
||||
/* A.9 Audio Class-Specific AC Interface Descriptor Subtypes */
|
||||
/* see audio.h for the rest, which is identical to v1 */
|
||||
#define UAC2_EFFECT_UNIT 0x07
|
||||
#define UAC2_PROCESSING_UNIT_V2 0x08
|
||||
#define UAC2_EXTENSION_UNIT_V2 0x09
|
||||
#define UAC2_CLOCK_SOURCE 0x0a
|
||||
#define UAC2_CLOCK_SELECTOR 0x0b
|
||||
#define UAC2_CLOCK_MULTIPLIER 0x0c
|
||||
#define UAC2_SAMPLE_RATE_CONVERTER 0x0d
|
||||
|
||||
/* A.10 Audio Class-Specific AS Interface Descriptor Subtypes */
|
||||
/* see audio.h for the rest, which is identical to v1 */
|
||||
#define UAC2_ENCODER 0x03
|
||||
#define UAC2_DECODER 0x04
|
||||
|
||||
/* A.11 Effect Unit Effect Types */
|
||||
#define UAC2_EFFECT_UNDEFINED 0x00
|
||||
#define UAC2_EFFECT_PARAM_EQ 0x01
|
||||
#define UAC2_EFFECT_REVERB 0x02
|
||||
#define UAC2_EFFECT_MOD_DELAY 0x03
|
||||
#define UAC2_EFFECT_DYN_RANGE_COMP 0x04
|
||||
|
||||
/* A.12 Processing Unit Process Types */
|
||||
#define UAC2_PROCESS_UNDEFINED 0x00
|
||||
#define UAC2_PROCESS_UP_DOWNMIX 0x01
|
||||
#define UAC2_PROCESS_DOLBY_PROLOCIC 0x02
|
||||
#define UAC2_PROCESS_STEREO_EXTENDER 0x03
|
||||
|
||||
/* A.14 Audio Class-Specific Request Codes */
|
||||
#define UAC2_CS_CUR 0x01
|
||||
#define UAC2_CS_RANGE 0x02
|
||||
#define UAC2_CS_MEM 0x03
|
||||
|
||||
/* A.15 Encoder Type Codes */
|
||||
#define UAC2_ENCODER_UNDEFINED 0x00
|
||||
#define UAC2_ENCODER_OTHER 0x01
|
||||
#define UAC2_ENCODER_MPEG 0x02
|
||||
#define UAC2_ENCODER_AC3 0x03
|
||||
#define UAC2_ENCODER_WMA 0x04
|
||||
#define UAC2_ENCODER_DTS 0x05
|
||||
|
||||
/* A.16 Decoder Type Codes */
|
||||
#define UAC2_DECODER_UNDEFINED 0x00
|
||||
#define UAC2_DECODER_OTHER 0x01
|
||||
#define UAC2_DECODER_MPEG 0x02
|
||||
#define UAC2_DECODER_AC3 0x03
|
||||
#define UAC2_DECODER_WMA 0x04
|
||||
#define UAC2_DECODER_DTS 0x05
|
||||
|
||||
/* A.17.1 Clock Source Control Selectors */
|
||||
#define UAC2_CS_UNDEFINED 0x00
|
||||
#define UAC2_CS_CONTROL_SAM_FREQ 0x01
|
||||
#define UAC2_CS_CONTROL_CLOCK_VALID 0x02
|
||||
|
||||
/* A.17.2 Clock Selector Control Selectors */
|
||||
#define UAC2_CX_UNDEFINED 0x00
|
||||
#define UAC2_CX_CLOCK_SELECTOR 0x01
|
||||
|
||||
/* A.17.3 Clock Multiplier Control Selectors */
|
||||
#define UAC2_CM_UNDEFINED 0x00
|
||||
#define UAC2_CM_NUMERATOR 0x01
|
||||
#define UAC2_CM_DENOMINTATOR 0x02
|
||||
|
||||
/* A.17.4 Terminal Control Selectors */
|
||||
#define UAC2_TE_UNDEFINED 0x00
|
||||
#define UAC2_TE_COPY_PROTECT 0x01
|
||||
#define UAC2_TE_CONNECTOR 0x02
|
||||
#define UAC2_TE_OVERLOAD 0x03
|
||||
#define UAC2_TE_CLUSTER 0x04
|
||||
#define UAC2_TE_UNDERFLOW 0x05
|
||||
#define UAC2_TE_OVERFLOW 0x06
|
||||
#define UAC2_TE_LATENCY 0x07
|
||||
|
||||
/* A.17.5 Mixer Control Selectors */
|
||||
#define UAC2_MU_UNDEFINED 0x00
|
||||
#define UAC2_MU_MIXER 0x01
|
||||
#define UAC2_MU_CLUSTER 0x02
|
||||
#define UAC2_MU_UNDERFLOW 0x03
|
||||
#define UAC2_MU_OVERFLOW 0x04
|
||||
#define UAC2_MU_LATENCY 0x05
|
||||
|
||||
/* A.17.6 Selector Control Selectors */
|
||||
#define UAC2_SU_UNDEFINED 0x00
|
||||
#define UAC2_SU_SELECTOR 0x01
|
||||
#define UAC2_SU_LATENCY 0x02
|
||||
|
||||
/* A.17.7 Feature Unit Control Selectors */
|
||||
/* see audio.h for the rest, which is identical to v1 */
|
||||
#define UAC2_FU_INPUT_GAIN 0x0b
|
||||
#define UAC2_FU_INPUT_GAIN_PAD 0x0c
|
||||
#define UAC2_FU_PHASE_INVERTER 0x0d
|
||||
#define UAC2_FU_UNDERFLOW 0x0e
|
||||
#define UAC2_FU_OVERFLOW 0x0f
|
||||
#define UAC2_FU_LATENCY 0x10
|
||||
|
||||
/* A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors */
|
||||
#define UAC2_PE_UNDEFINED 0x00
|
||||
#define UAC2_PE_ENABLE 0x01
|
||||
#define UAC2_PE_CENTERFREQ 0x02
|
||||
#define UAC2_PE_QFACTOR 0x03
|
||||
#define UAC2_PE_GAIN 0x04
|
||||
#define UAC2_PE_UNDERFLOW 0x05
|
||||
#define UAC2_PE_OVERFLOW 0x06
|
||||
#define UAC2_PE_LATENCY 0x07
|
||||
|
||||
/* A.17.8.2 Reverberation Effect Unit Control Selectors */
|
||||
#define UAC2_RV_UNDEFINED 0x00
|
||||
#define UAC2_RV_ENABLE 0x01
|
||||
#define UAC2_RV_TYPE 0x02
|
||||
#define UAC2_RV_LEVEL 0x03
|
||||
#define UAC2_RV_TIME 0x04
|
||||
#define UAC2_RV_FEEDBACK 0x05
|
||||
#define UAC2_RV_PREDELAY 0x06
|
||||
#define UAC2_RV_DENSITY 0x07
|
||||
#define UAC2_RV_HIFREQ_ROLLOFF 0x08
|
||||
#define UAC2_RV_UNDERFLOW 0x09
|
||||
#define UAC2_RV_OVERFLOW 0x0a
|
||||
#define UAC2_RV_LATENCY 0x0b
|
||||
|
||||
/* A.17.8.3 Modulation Delay Effect Control Selectors */
|
||||
#define UAC2_MD_UNDEFINED 0x00
|
||||
#define UAC2_MD_ENABLE 0x01
|
||||
#define UAC2_MD_BALANCE 0x02
|
||||
#define UAC2_MD_RATE 0x03
|
||||
#define UAC2_MD_DEPTH 0x04
|
||||
#define UAC2_MD_TIME 0x05
|
||||
#define UAC2_MD_FEEDBACK 0x06
|
||||
#define UAC2_MD_UNDERFLOW 0x07
|
||||
#define UAC2_MD_OVERFLOW 0x08
|
||||
#define UAC2_MD_LATENCY 0x09
|
||||
|
||||
/* A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors */
|
||||
#define UAC2_DR_UNDEFINED 0x00
|
||||
#define UAC2_DR_ENABLE 0x01
|
||||
#define UAC2_DR_COMPRESSION_RATE 0x02
|
||||
#define UAC2_DR_MAXAMPL 0x03
|
||||
#define UAC2_DR_THRESHOLD 0x04
|
||||
#define UAC2_DR_ATTACK_TIME 0x05
|
||||
#define UAC2_DR_RELEASE_TIME 0x06
|
||||
#define UAC2_DR_UNDEFLOW 0x07
|
||||
#define UAC2_DR_OVERFLOW 0x08
|
||||
#define UAC2_DR_LATENCY 0x09
|
||||
|
||||
/* A.17.9.1 Up/Down-mix Processing Unit Control Selectors */
|
||||
#define UAC2_UD_UNDEFINED 0x00
|
||||
#define UAC2_UD_ENABLE 0x01
|
||||
#define UAC2_UD_MODE_SELECT 0x02
|
||||
#define UAC2_UD_CLUSTER 0x03
|
||||
#define UAC2_UD_UNDERFLOW 0x04
|
||||
#define UAC2_UD_OVERFLOW 0x05
|
||||
#define UAC2_UD_LATENCY 0x06
|
||||
|
||||
/* A.17.9.2 Dolby Prologic[tm] Processing Unit Control Selectors */
|
||||
#define UAC2_DP_UNDEFINED 0x00
|
||||
#define UAC2_DP_ENABLE 0x01
|
||||
#define UAC2_DP_MODE_SELECT 0x02
|
||||
#define UAC2_DP_CLUSTER 0x03
|
||||
#define UAC2_DP_UNDERFFLOW 0x04
|
||||
#define UAC2_DP_OVERFLOW 0x05
|
||||
#define UAC2_DP_LATENCY 0x06
|
||||
|
||||
/* A.17.9.3 Stereo Expander Processing Unit Control Selectors */
|
||||
#define UAC2_ST_EXT_UNDEFINED 0x00
|
||||
#define UAC2_ST_EXT_ENABLE 0x01
|
||||
#define UAC2_ST_EXT_WIDTH 0x02
|
||||
#define UAC2_ST_EXT_UNDEFLOW 0x03
|
||||
#define UAC2_ST_EXT_OVERFLOW 0x04
|
||||
#define UAC2_ST_EXT_LATENCY 0x05
|
||||
|
||||
/* A.17.10 Extension Unit Control Selectors */
|
||||
#define UAC2_XU_UNDEFINED 0x00
|
||||
#define UAC2_XU_ENABLE 0x01
|
||||
#define UAC2_XU_CLUSTER 0x02
|
||||
#define UAC2_XU_UNDERFLOW 0x03
|
||||
#define UAC2_XU_OVERFLOW 0x04
|
||||
#define UAC2_XU_LATENCY 0x05
|
||||
|
||||
/* A.17.11 AudioStreaming Interface Control Selectors */
|
||||
#define UAC2_AS_UNDEFINED 0x00
|
||||
#define UAC2_AS_ACT_ALT_SETTING 0x01
|
||||
#define UAC2_AS_VAL_ALT_SETTINGS 0x02
|
||||
#define UAC2_AS_AUDIO_DATA_FORMAT 0x03
|
||||
|
||||
/* A.17.12 Encoder Control Selectors */
|
||||
#define UAC2_EN_UNDEFINED 0x00
|
||||
#define UAC2_EN_BIT_RATE 0x01
|
||||
#define UAC2_EN_QUALITY 0x02
|
||||
#define UAC2_EN_VBR 0x03
|
||||
#define UAC2_EN_TYPE 0x04
|
||||
#define UAC2_EN_UNDERFLOW 0x05
|
||||
#define UAC2_EN_OVERFLOW 0x06
|
||||
#define UAC2_EN_ENCODER_ERROR 0x07
|
||||
#define UAC2_EN_PARAM1 0x08
|
||||
#define UAC2_EN_PARAM2 0x09
|
||||
#define UAC2_EN_PARAM3 0x0a
|
||||
#define UAC2_EN_PARAM4 0x0b
|
||||
#define UAC2_EN_PARAM5 0x0c
|
||||
#define UAC2_EN_PARAM6 0x0d
|
||||
#define UAC2_EN_PARAM7 0x0e
|
||||
#define UAC2_EN_PARAM8 0x0f
|
||||
|
||||
/* A.17.13.1 MPEG Decoder Control Selectors */
|
||||
#define UAC2_MPEG_UNDEFINED 0x00
|
||||
#define UAC2_MPEG_DUAL_CHANNEL 0x01
|
||||
#define UAC2_MPEG_SECOND_STEREO 0x02
|
||||
#define UAC2_MPEG_MULTILINGUAL 0x03
|
||||
#define UAC2_MPEG_DYN_RANGE 0x04
|
||||
#define UAC2_MPEG_SCALING 0x05
|
||||
#define UAC2_MPEG_HILO_SCALING 0x06
|
||||
#define UAC2_MPEG_UNDERFLOW 0x07
|
||||
#define UAC2_MPEG_OVERFLOW 0x08
|
||||
#define UAC2_MPEG_DECODER_ERROR 0x09
|
||||
|
||||
/* A17.13.2 AC3 Decoder Control Selectors */
|
||||
#define UAC2_AC3_UNDEFINED 0x00
|
||||
#define UAC2_AC3_MODE 0x01
|
||||
#define UAC2_AC3_DYN_RANGE 0x02
|
||||
#define UAC2_AC3_SCALING 0x03
|
||||
#define UAC2_AC3_HILO_SCALING 0x04
|
||||
#define UAC2_AC3_UNDERFLOW 0x05
|
||||
#define UAC2_AC3_OVERFLOW 0x06
|
||||
#define UAC2_AC3_DECODER_ERROR 0x07
|
||||
|
||||
/* A17.13.3 WMA Decoder Control Selectors */
|
||||
#define UAC2_WMA_UNDEFINED 0x00
|
||||
#define UAC2_WMA_UNDERFLOW 0x01
|
||||
#define UAC2_WMA_OVERFLOW 0x02
|
||||
#define UAC2_WMA_DECODER_ERROR 0x03
|
||||
|
||||
/* A17.13.4 DTS Decoder Control Selectors */
|
||||
#define UAC2_DTS_UNDEFINED 0x00
|
||||
#define UAC2_DTS_UNDERFLOW 0x01
|
||||
#define UAC2_DTS_OVERFLOW 0x02
|
||||
#define UAC2_DTS_DECODER_ERROR 0x03
|
||||
|
||||
/* A17.14 Endpoint Control Selectors */
|
||||
#define UAC2_EP_CS_UNDEFINED 0x00
|
||||
#define UAC2_EP_CS_PITCH 0x01
|
||||
#define UAC2_EP_CS_DATA_OVERRUN 0x02
|
||||
#define UAC2_EP_CS_DATA_UNDERRUN 0x03
|
||||
|
||||
#endif /* __LINUX_USB_AUDIO_V2_H */
|
||||
|
||||
@@ -0,0 +1,454 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2017 Ruslan Bilovol <ruslan.bilovol@gmail.com>
|
||||
*
|
||||
* This file holds USB constants and structures defined
|
||||
* by the USB DEVICE CLASS DEFINITION FOR AUDIO DEVICES Release 3.0.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_AUDIO_V3_H
|
||||
#define __LINUX_USB_AUDIO_V3_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* v1.0, v2.0 and v3.0 of this standard have many things in common. For the rest
|
||||
* of the definitions, please refer to audio.h and audio-v2.h
|
||||
*/
|
||||
|
||||
/* All High Capability descriptors have these 2 fields at the beginning */
|
||||
struct uac3_hc_descriptor_header {
|
||||
__le16 wLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__le16 wDescriptorID;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.3.1 CLUSTER DESCRIPTOR HEADER */
|
||||
struct uac3_cluster_header_descriptor {
|
||||
__le16 wLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__le16 wDescriptorID;
|
||||
__u8 bNrChannels;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.3.2.1 SEGMENTS */
|
||||
struct uac3_cluster_segment_descriptor {
|
||||
__le16 wLength;
|
||||
__u8 bSegmentType;
|
||||
/* __u8[0]; segment-specific data */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.3.2.1.1 END SEGMENT */
|
||||
struct uac3_cluster_end_segment_descriptor {
|
||||
__le16 wLength;
|
||||
__u8 bSegmentType; /* Constant END_SEGMENT */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.3.2.1.3.1 INFORMATION SEGMENT */
|
||||
struct uac3_cluster_information_segment_descriptor {
|
||||
__le16 wLength;
|
||||
__u8 bSegmentType;
|
||||
__u8 bChPurpose;
|
||||
__u8 bChRelationship;
|
||||
__u8 bChGroupID;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.5.2 CLASS-SPECIFIC AC INTERFACE DESCRIPTOR */
|
||||
struct uac3_ac_header_descriptor {
|
||||
__u8 bLength; /* 10 */
|
||||
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
|
||||
__u8 bDescriptorSubtype; /* HEADER descriptor subtype */
|
||||
__u8 bCategory;
|
||||
|
||||
/* includes Clock Source, Unit, Terminal, and Power Domain desc. */
|
||||
__le16 wTotalLength;
|
||||
|
||||
__le32 bmControls;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 4.5.2.1 INPUT TERMINAL DESCRIPTOR */
|
||||
struct uac3_input_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__le16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bCSourceID;
|
||||
__le32 bmControls;
|
||||
__le16 wClusterDescrID;
|
||||
__le16 wExTerminalDescrID;
|
||||
__le16 wConnectorsDescrID;
|
||||
__le16 wTerminalDescrStr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.5.2.2 OUTPUT TERMINAL DESCRIPTOR */
|
||||
struct uac3_output_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__le16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bSourceID;
|
||||
__u8 bCSourceID;
|
||||
__le32 bmControls;
|
||||
__le16 wExTerminalDescrID;
|
||||
__le16 wConnectorsDescrID;
|
||||
__le16 wTerminalDescrStr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.5.2.7 FEATURE UNIT DESCRIPTOR */
|
||||
struct uac3_feature_unit_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bUnitID;
|
||||
__u8 bSourceID;
|
||||
/* bmaControls is actually u32,
|
||||
* but u8 is needed for the hybrid parser */
|
||||
__u8 bmaControls[]; /* variable length */
|
||||
/* wFeatureDescrStr omitted */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define UAC3_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 4)
|
||||
|
||||
/* As above, but more useful for defining your own descriptors */
|
||||
#define DECLARE_UAC3_FEATURE_UNIT_DESCRIPTOR(ch) \
|
||||
struct uac3_feature_unit_descriptor_##ch { \
|
||||
__u8 bLength; \
|
||||
__u8 bDescriptorType; \
|
||||
__u8 bDescriptorSubtype; \
|
||||
__u8 bUnitID; \
|
||||
__u8 bSourceID; \
|
||||
__le32 bmaControls[ch + 1]; \
|
||||
__le16 wFeatureDescrStr; \
|
||||
} __attribute__ ((packed))
|
||||
|
||||
/* 4.5.2.12 CLOCK SOURCE DESCRIPTOR */
|
||||
struct uac3_clock_source_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bmAttributes;
|
||||
__le32 bmControls;
|
||||
__u8 bReferenceTerminal;
|
||||
__le16 wClockSourceStr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* bmAttribute fields */
|
||||
#define UAC3_CLOCK_SOURCE_TYPE_EXT 0x0
|
||||
#define UAC3_CLOCK_SOURCE_TYPE_INT 0x1
|
||||
#define UAC3_CLOCK_SOURCE_ASYNC (0 << 2)
|
||||
#define UAC3_CLOCK_SOURCE_SYNCED_TO_SOF (1 << 1)
|
||||
|
||||
/* 4.5.2.13 CLOCK SELECTOR DESCRIPTOR */
|
||||
struct uac3_clock_selector_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bNrInPins;
|
||||
__u8 baCSourceID[];
|
||||
/* bmControls and wCSelectorDescrStr omitted */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.5.2.14 CLOCK MULTIPLIER DESCRIPTOR */
|
||||
struct uac3_clock_multiplier_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bClockID;
|
||||
__u8 bCSourceID;
|
||||
__le32 bmControls;
|
||||
__le16 wCMultiplierDescrStr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.5.2.15 POWER DOMAIN DESCRIPTOR */
|
||||
struct uac3_power_domain_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bPowerDomainID;
|
||||
__le16 waRecoveryTime1;
|
||||
__le16 waRecoveryTime2;
|
||||
__u8 bNrEntities;
|
||||
__u8 baEntityID[];
|
||||
/* wPDomainDescrStr omitted */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* As above, but more useful for defining your own descriptors */
|
||||
#define DECLARE_UAC3_POWER_DOMAIN_DESCRIPTOR(n) \
|
||||
struct uac3_power_domain_descriptor_##n { \
|
||||
__u8 bLength; \
|
||||
__u8 bDescriptorType; \
|
||||
__u8 bDescriptorSubtype; \
|
||||
__u8 bPowerDomainID; \
|
||||
__le16 waRecoveryTime1; \
|
||||
__le16 waRecoveryTime2; \
|
||||
__u8 bNrEntities; \
|
||||
__u8 baEntityID[n]; \
|
||||
__le16 wPDomainDescrStr; \
|
||||
} __attribute__ ((packed))
|
||||
|
||||
/* 4.7.2 CLASS-SPECIFIC AS INTERFACE DESCRIPTOR */
|
||||
struct uac3_as_header_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalLink;
|
||||
__le32 bmControls;
|
||||
__le16 wClusterDescrID;
|
||||
__le64 bmFormats;
|
||||
__u8 bSubslotSize;
|
||||
__u8 bBitResolution;
|
||||
__le16 bmAuxProtocols;
|
||||
__u8 bControlSize;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define UAC3_FORMAT_TYPE_I_RAW_DATA (1 << 6)
|
||||
|
||||
/* 4.8.1.2 CLASS-SPECIFIC AS ISOCHRONOUS AUDIO DATA ENDPOINT DESCRIPTOR */
|
||||
struct uac3_iso_endpoint_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__le32 bmControls;
|
||||
__u8 bLockDelayUnits;
|
||||
__le16 wLockDelay;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 5.2.1.6.1 INSERTION CONTROL PARAMETER BLOCK */
|
||||
struct uac3_insertion_ctl_blk {
|
||||
__u8 bSize;
|
||||
__u8 bmConInserted;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 6.1 INTERRUPT DATA MESSAGE */
|
||||
struct uac3_interrupt_data_msg {
|
||||
__u8 bInfo;
|
||||
__u8 bSourceType;
|
||||
__le16 wValue;
|
||||
__le16 wIndex;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* A.2 AUDIO AUDIO FUNCTION SUBCLASS CODES */
|
||||
#define UAC3_FUNCTION_SUBCLASS_UNDEFINED 0x00
|
||||
#define UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 0x01
|
||||
/* BADD profiles */
|
||||
#define UAC3_FUNCTION_SUBCLASS_GENERIC_IO 0x20
|
||||
#define UAC3_FUNCTION_SUBCLASS_HEADPHONE 0x21
|
||||
#define UAC3_FUNCTION_SUBCLASS_SPEAKER 0x22
|
||||
#define UAC3_FUNCTION_SUBCLASS_MICROPHONE 0x23
|
||||
#define UAC3_FUNCTION_SUBCLASS_HEADSET 0x24
|
||||
#define UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER 0x25
|
||||
#define UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE 0x26
|
||||
|
||||
/* A.7 AUDIO FUNCTION CATEGORY CODES */
|
||||
#define UAC3_FUNCTION_SUBCLASS_UNDEFINED 0x00
|
||||
#define UAC3_FUNCTION_DESKTOP_SPEAKER 0x01
|
||||
#define UAC3_FUNCTION_HOME_THEATER 0x02
|
||||
#define UAC3_FUNCTION_MICROPHONE 0x03
|
||||
#define UAC3_FUNCTION_HEADSET 0x04
|
||||
#define UAC3_FUNCTION_TELEPHONE 0x05
|
||||
#define UAC3_FUNCTION_CONVERTER 0x06
|
||||
#define UAC3_FUNCTION_SOUND_RECORDER 0x07
|
||||
#define UAC3_FUNCTION_IO_BOX 0x08
|
||||
#define UAC3_FUNCTION_MUSICAL_INSTRUMENT 0x09
|
||||
#define UAC3_FUNCTION_PRO_AUDIO 0x0a
|
||||
#define UAC3_FUNCTION_AUDIO_VIDEO 0x0b
|
||||
#define UAC3_FUNCTION_CONTROL_PANEL 0x0c
|
||||
#define UAC3_FUNCTION_HEADPHONE 0x0d
|
||||
#define UAC3_FUNCTION_GENERIC_SPEAKER 0x0e
|
||||
#define UAC3_FUNCTION_HEADSET_ADAPTER 0x0f
|
||||
#define UAC3_FUNCTION_SPEAKERPHONE 0x10
|
||||
#define UAC3_FUNCTION_OTHER 0xff
|
||||
|
||||
/* A.8 AUDIO CLASS-SPECIFIC DESCRIPTOR TYPES */
|
||||
#define UAC3_CS_UNDEFINED 0x20
|
||||
#define UAC3_CS_DEVICE 0x21
|
||||
#define UAC3_CS_CONFIGURATION 0x22
|
||||
#define UAC3_CS_STRING 0x23
|
||||
#define UAC3_CS_INTERFACE 0x24
|
||||
#define UAC3_CS_ENDPOINT 0x25
|
||||
#define UAC3_CS_CLUSTER 0x26
|
||||
|
||||
/* A.10 CLUSTER DESCRIPTOR SEGMENT TYPES */
|
||||
#define UAC3_SEGMENT_UNDEFINED 0x00
|
||||
#define UAC3_CLUSTER_DESCRIPTION 0x01
|
||||
#define UAC3_CLUSTER_VENDOR_DEFINED 0x1F
|
||||
#define UAC3_CHANNEL_INFORMATION 0x20
|
||||
#define UAC3_CHANNEL_AMBISONIC 0x21
|
||||
#define UAC3_CHANNEL_DESCRIPTION 0x22
|
||||
#define UAC3_CHANNEL_VENDOR_DEFINED 0xFE
|
||||
#define UAC3_END_SEGMENT 0xFF
|
||||
|
||||
/* A.11 CHANNEL PURPOSE DEFINITIONS */
|
||||
#define UAC3_PURPOSE_UNDEFINED 0x00
|
||||
#define UAC3_PURPOSE_GENERIC_AUDIO 0x01
|
||||
#define UAC3_PURPOSE_VOICE 0x02
|
||||
#define UAC3_PURPOSE_SPEECH 0x03
|
||||
#define UAC3_PURPOSE_AMBIENT 0x04
|
||||
#define UAC3_PURPOSE_REFERENCE 0x05
|
||||
#define UAC3_PURPOSE_ULTRASONIC 0x06
|
||||
#define UAC3_PURPOSE_VIBROKINETIC 0x07
|
||||
#define UAC3_PURPOSE_NON_AUDIO 0xFF
|
||||
|
||||
/* A.12 CHANNEL RELATIONSHIP DEFINITIONS */
|
||||
#define UAC3_CH_RELATIONSHIP_UNDEFINED 0x00
|
||||
#define UAC3_CH_MONO 0x01
|
||||
#define UAC3_CH_LEFT 0x02
|
||||
#define UAC3_CH_RIGHT 0x03
|
||||
#define UAC3_CH_ARRAY 0x04
|
||||
#define UAC3_CH_PATTERN_X 0x20
|
||||
#define UAC3_CH_PATTERN_Y 0x21
|
||||
#define UAC3_CH_PATTERN_A 0x22
|
||||
#define UAC3_CH_PATTERN_B 0x23
|
||||
#define UAC3_CH_PATTERN_M 0x24
|
||||
#define UAC3_CH_PATTERN_S 0x25
|
||||
#define UAC3_CH_FRONT_LEFT 0x80
|
||||
#define UAC3_CH_FRONT_RIGHT 0x81
|
||||
#define UAC3_CH_FRONT_CENTER 0x82
|
||||
#define UAC3_CH_FRONT_LEFT_OF_CENTER 0x83
|
||||
#define UAC3_CH_FRONT_RIGHT_OF_CENTER 0x84
|
||||
#define UAC3_CH_FRONT_WIDE_LEFT 0x85
|
||||
#define UAC3_CH_FRONT_WIDE_RIGHT 0x86
|
||||
#define UAC3_CH_SIDE_LEFT 0x87
|
||||
#define UAC3_CH_SIDE_RIGHT 0x88
|
||||
#define UAC3_CH_SURROUND_ARRAY_LEFT 0x89
|
||||
#define UAC3_CH_SURROUND_ARRAY_RIGHT 0x8A
|
||||
#define UAC3_CH_BACK_LEFT 0x8B
|
||||
#define UAC3_CH_BACK_RIGHT 0x8C
|
||||
#define UAC3_CH_BACK_CENTER 0x8D
|
||||
#define UAC3_CH_BACK_LEFT_OF_CENTER 0x8E
|
||||
#define UAC3_CH_BACK_RIGHT_OF_CENTER 0x8F
|
||||
#define UAC3_CH_BACK_WIDE_LEFT 0x90
|
||||
#define UAC3_CH_BACK_WIDE_RIGHT 0x91
|
||||
#define UAC3_CH_TOP_CENTER 0x92
|
||||
#define UAC3_CH_TOP_FRONT_LEFT 0x93
|
||||
#define UAC3_CH_TOP_FRONT_RIGHT 0x94
|
||||
#define UAC3_CH_TOP_FRONT_CENTER 0x95
|
||||
#define UAC3_CH_TOP_FRONT_LOC 0x96
|
||||
#define UAC3_CH_TOP_FRONT_ROC 0x97
|
||||
#define UAC3_CH_TOP_FRONT_WIDE_LEFT 0x98
|
||||
#define UAC3_CH_TOP_FRONT_WIDE_RIGHT 0x99
|
||||
#define UAC3_CH_TOP_SIDE_LEFT 0x9A
|
||||
#define UAC3_CH_TOP_SIDE_RIGHT 0x9B
|
||||
#define UAC3_CH_TOP_SURR_ARRAY_LEFT 0x9C
|
||||
#define UAC3_CH_TOP_SURR_ARRAY_RIGHT 0x9D
|
||||
#define UAC3_CH_TOP_BACK_LEFT 0x9E
|
||||
#define UAC3_CH_TOP_BACK_RIGHT 0x9F
|
||||
#define UAC3_CH_TOP_BACK_CENTER 0xA0
|
||||
#define UAC3_CH_TOP_BACK_LOC 0xA1
|
||||
#define UAC3_CH_TOP_BACK_ROC 0xA2
|
||||
#define UAC3_CH_TOP_BACK_WIDE_LEFT 0xA3
|
||||
#define UAC3_CH_TOP_BACK_WIDE_RIGHT 0xA4
|
||||
#define UAC3_CH_BOTTOM_CENTER 0xA5
|
||||
#define UAC3_CH_BOTTOM_FRONT_LEFT 0xA6
|
||||
#define UAC3_CH_BOTTOM_FRONT_RIGHT 0xA7
|
||||
#define UAC3_CH_BOTTOM_FRONT_CENTER 0xA8
|
||||
#define UAC3_CH_BOTTOM_FRONT_LOC 0xA9
|
||||
#define UAC3_CH_BOTTOM_FRONT_ROC 0xAA
|
||||
#define UAC3_CH_BOTTOM_FRONT_WIDE_LEFT 0xAB
|
||||
#define UAC3_CH_BOTTOM_FRONT_WIDE_RIGHT 0xAC
|
||||
#define UAC3_CH_BOTTOM_SIDE_LEFT 0xAD
|
||||
#define UAC3_CH_BOTTOM_SIDE_RIGHT 0xAE
|
||||
#define UAC3_CH_BOTTOM_SURR_ARRAY_LEFT 0xAF
|
||||
#define UAC3_CH_BOTTOM_SURR_ARRAY_RIGHT 0xB0
|
||||
#define UAC3_CH_BOTTOM_BACK_LEFT 0xB1
|
||||
#define UAC3_CH_BOTTOM_BACK_RIGHT 0xB2
|
||||
#define UAC3_CH_BOTTOM_BACK_CENTER 0xB3
|
||||
#define UAC3_CH_BOTTOM_BACK_LOC 0xB4
|
||||
#define UAC3_CH_BOTTOM_BACK_ROC 0xB5
|
||||
#define UAC3_CH_BOTTOM_BACK_WIDE_LEFT 0xB6
|
||||
#define UAC3_CH_BOTTOM_BACK_WIDE_RIGHT 0xB7
|
||||
#define UAC3_CH_LOW_FREQUENCY_EFFECTS 0xB8
|
||||
#define UAC3_CH_LFE_LEFT 0xB9
|
||||
#define UAC3_CH_LFE_RIGHT 0xBA
|
||||
#define UAC3_CH_HEADPHONE_LEFT 0xBB
|
||||
#define UAC3_CH_HEADPHONE_RIGHT 0xBC
|
||||
|
||||
/* A.15 AUDIO CLASS-SPECIFIC AC INTERFACE DESCRIPTOR SUBTYPES */
|
||||
/* see audio.h for the rest, which is identical to v1 */
|
||||
#define UAC3_EXTENDED_TERMINAL 0x04
|
||||
#define UAC3_MIXER_UNIT 0x05
|
||||
#define UAC3_SELECTOR_UNIT 0x06
|
||||
#define UAC3_FEATURE_UNIT 0x07
|
||||
#define UAC3_EFFECT_UNIT 0x08
|
||||
#define UAC3_PROCESSING_UNIT 0x09
|
||||
#define UAC3_EXTENSION_UNIT 0x0a
|
||||
#define UAC3_CLOCK_SOURCE 0x0b
|
||||
#define UAC3_CLOCK_SELECTOR 0x0c
|
||||
#define UAC3_CLOCK_MULTIPLIER 0x0d
|
||||
#define UAC3_SAMPLE_RATE_CONVERTER 0x0e
|
||||
#define UAC3_CONNECTORS 0x0f
|
||||
#define UAC3_POWER_DOMAIN 0x10
|
||||
|
||||
/* A.20 PROCESSING UNIT PROCESS TYPES */
|
||||
#define UAC3_PROCESS_UNDEFINED 0x00
|
||||
#define UAC3_PROCESS_UP_DOWNMIX 0x01
|
||||
#define UAC3_PROCESS_STEREO_EXTENDER 0x02
|
||||
#define UAC3_PROCESS_MULTI_FUNCTION 0x03
|
||||
|
||||
/* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */
|
||||
/* see audio-v2.h for the rest, which is identical to v2 */
|
||||
#define UAC3_CS_REQ_INTEN 0x04
|
||||
#define UAC3_CS_REQ_STRING 0x05
|
||||
#define UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR 0x06
|
||||
|
||||
/* A.23.1 AUDIOCONTROL INTERFACE CONTROL SELECTORS */
|
||||
#define UAC3_AC_CONTROL_UNDEFINED 0x00
|
||||
#define UAC3_AC_ACTIVE_INTERFACE_CONTROL 0x01
|
||||
#define UAC3_AC_POWER_DOMAIN_CONTROL 0x02
|
||||
|
||||
/* A.23.5 TERMINAL CONTROL SELECTORS */
|
||||
#define UAC3_TE_UNDEFINED 0x00
|
||||
#define UAC3_TE_INSERTION 0x01
|
||||
#define UAC3_TE_OVERLOAD 0x02
|
||||
#define UAC3_TE_UNDERFLOW 0x03
|
||||
#define UAC3_TE_OVERFLOW 0x04
|
||||
#define UAC3_TE_LATENCY 0x05
|
||||
|
||||
/* A.23.10 PROCESSING UNITS CONTROL SELECTROS */
|
||||
|
||||
/* Up/Down Mixer */
|
||||
#define UAC3_UD_MODE_SELECT 0x01
|
||||
|
||||
/* Stereo Extender */
|
||||
#define UAC3_EXT_WIDTH_CONTROL 0x01
|
||||
|
||||
|
||||
/* BADD predefined Unit/Terminal values */
|
||||
#define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */
|
||||
#define UAC3_BADD_FU_ID2 2 /* Feature Unit ID2: bUnitID = 2 */
|
||||
#define UAC3_BADD_OT_ID3 3 /* Output Terminal ID3: bTerminalID = 3 */
|
||||
#define UAC3_BADD_IT_ID4 4 /* Input Terminal ID4: bTerminalID = 4 */
|
||||
#define UAC3_BADD_FU_ID5 5 /* Feature Unit ID5: bUnitID = 5 */
|
||||
#define UAC3_BADD_OT_ID6 6 /* Output Terminal ID6: bTerminalID = 6 */
|
||||
#define UAC3_BADD_FU_ID7 7 /* Feature Unit ID7: bUnitID = 7 */
|
||||
#define UAC3_BADD_MU_ID8 8 /* Mixer Unit ID8: bUnitID = 8 */
|
||||
#define UAC3_BADD_CS_ID9 9 /* Clock Source Entity ID9: bClockID = 9 */
|
||||
#define UAC3_BADD_PD_ID10 10 /* Power Domain ID10: bPowerDomainID = 10 */
|
||||
#define UAC3_BADD_PD_ID11 11 /* Power Domain ID11: bPowerDomainID = 11 */
|
||||
|
||||
/* BADD wMaxPacketSize of AS endpoints */
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16 0x0060
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16 0x0062
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24 0x0090
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24 0x0093
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16 0x00C0
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16 0x00C4
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24 0x0120
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24 0x0126
|
||||
|
||||
/* BADD sample rate is always fixed to 48kHz */
|
||||
#define UAC3_BADD_SAMPLING_RATE 48000
|
||||
|
||||
/* BADD power domains recovery times in 50us increments */
|
||||
#define UAC3_BADD_PD_RECOVER_D1D0 0x0258 /* 30ms */
|
||||
#define UAC3_BADD_PD_RECOVER_D2D0 0x1770 /* 300ms */
|
||||
|
||||
#endif /* __LINUX_USB_AUDIO_V3_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* <linux/usb/audio.h> -- USB Audio definitions.
|
||||
*
|
||||
* Copyright (C) 2006 Thumtronics Pty Ltd.
|
||||
* Developed for Thumtronics by Grey Innovation
|
||||
* Ben Williamson <ben.williamson@greyinnovation.com>
|
||||
*
|
||||
* This file holds USB constants and structures defined
|
||||
* by the USB Device Class Definition for Audio Devices.
|
||||
* Comments below reference relevant sections of that document:
|
||||
*
|
||||
* http://www.usb.org/developers/devclass_docs/audio10.pdf
|
||||
*
|
||||
* Types and defines in this file are either specific to version 1.0 of
|
||||
* this standard or common for newer versions.
|
||||
*/
|
||||
#ifndef __LINUX_USB_AUDIO_H
|
||||
#define __LINUX_USB_AUDIO_H
|
||||
|
||||
#include <uapi/linux/usb/audio.h>
|
||||
|
||||
|
||||
struct usb_audio_control {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
u8 type;
|
||||
int data[5];
|
||||
int (*set)(struct usb_audio_control *con, u8 cmd, int value);
|
||||
int (*get)(struct usb_audio_control *con, u8 cmd);
|
||||
};
|
||||
|
||||
struct usb_audio_control_selector {
|
||||
struct list_head list;
|
||||
struct list_head control;
|
||||
u8 id;
|
||||
const char *name;
|
||||
u8 type;
|
||||
struct usb_descriptor_header *desc;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_AUDIO_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip
|
||||
*
|
||||
* Copyright (C) 2006-2008 Barco N.V.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_USB_C67X00_H
|
||||
#define _LINUX_USB_C67X00_H
|
||||
|
||||
/* SIE configuration */
|
||||
#define C67X00_SIE_UNUSED 0
|
||||
#define C67X00_SIE_HOST 1
|
||||
#define C67X00_SIE_PERIPHERAL_A 2 /* peripheral on A port */
|
||||
#define C67X00_SIE_PERIPHERAL_B 3 /* peripheral on B port */
|
||||
|
||||
#define c67x00_sie_config(config, n) (((config)>>(4*(n)))&0x3)
|
||||
|
||||
#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0)
|
||||
#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0)
|
||||
#define C67X00_SIE1_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 0)
|
||||
#define C67X00_SIE1_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 0)
|
||||
|
||||
#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4)
|
||||
#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4)
|
||||
#define C67X00_SIE2_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 4)
|
||||
#define C67X00_SIE2_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 4)
|
||||
|
||||
struct c67x00_platform_data {
|
||||
int sie_config; /* SIEs config (C67X00_SIEx_*) */
|
||||
unsigned long hpi_regstep; /* Step between HPI registers */
|
||||
};
|
||||
|
||||
#endif /* _LINUX_USB_C67X00_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2018 Vincent Pelletier
|
||||
*/
|
||||
/*
|
||||
*/
|
||||
#ifndef __CCID_H
|
||||
#define __CCID_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define USB_INTERFACE_CLASS_CCID 0x0b
|
||||
|
||||
struct ccid_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__le16 bcdCCID;
|
||||
__u8 bMaxSlotIndex;
|
||||
__u8 bVoltageSupport;
|
||||
__le32 dwProtocols;
|
||||
__le32 dwDefaultClock;
|
||||
__le32 dwMaximumClock;
|
||||
__u8 bNumClockSupported;
|
||||
__le32 dwDataRate;
|
||||
__le32 dwMaxDataRate;
|
||||
__u8 bNumDataRatesSupported;
|
||||
__le32 dwMaxIFSD;
|
||||
__le32 dwSynchProtocols;
|
||||
__le32 dwMechanical;
|
||||
__le32 dwFeatures;
|
||||
__le32 dwMaxCCIDMessageLength;
|
||||
__u8 bClassGetResponse;
|
||||
__u8 bClassEnvelope;
|
||||
__le16 wLcdLayout;
|
||||
__u8 bPINSupport;
|
||||
__u8 bMaxCCIDBusySlots;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* __CCID_H */
|
||||
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* USB CDC Device Management subdriver
|
||||
*
|
||||
* Copyright (c) 2012 Bjørn Mork <bjorn@mork.no>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_CDC_WDM_H
|
||||
#define __LINUX_USB_CDC_WDM_H
|
||||
|
||||
#include <linux/wwan.h>
|
||||
#include <uapi/linux/usb/cdc-wdm.h>
|
||||
|
||||
extern struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf,
|
||||
struct usb_endpoint_descriptor *ep,
|
||||
int bufsize, enum wwan_port_type type,
|
||||
int (*manage_power)(struct usb_interface *, int));
|
||||
|
||||
#endif /* __LINUX_USB_CDC_WDM_H */
|
||||
@@ -0,0 +1,48 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* USB CDC common helpers
|
||||
*
|
||||
* Copyright (c) 2015 Oliver Neukum <oneukum@suse.com>
|
||||
*/
|
||||
#ifndef __LINUX_USB_CDC_H
|
||||
#define __LINUX_USB_CDC_H
|
||||
|
||||
#include <uapi/linux/usb/cdc.h>
|
||||
|
||||
/*
|
||||
* inofficial magic numbers
|
||||
*/
|
||||
|
||||
#define CDC_PHONET_MAGIC_NUMBER 0xAB
|
||||
|
||||
/*
|
||||
* parsing CDC headers
|
||||
*/
|
||||
|
||||
struct usb_cdc_parsed_header {
|
||||
struct usb_cdc_union_desc *usb_cdc_union_desc;
|
||||
struct usb_cdc_header_desc *usb_cdc_header_desc;
|
||||
|
||||
struct usb_cdc_call_mgmt_descriptor *usb_cdc_call_mgmt_descriptor;
|
||||
struct usb_cdc_acm_descriptor *usb_cdc_acm_descriptor;
|
||||
struct usb_cdc_country_functional_desc *usb_cdc_country_functional_desc;
|
||||
struct usb_cdc_network_terminal_desc *usb_cdc_network_terminal_desc;
|
||||
struct usb_cdc_ether_desc *usb_cdc_ether_desc;
|
||||
struct usb_cdc_dmm_desc *usb_cdc_dmm_desc;
|
||||
struct usb_cdc_mdlm_desc *usb_cdc_mdlm_desc;
|
||||
struct usb_cdc_mdlm_detail_desc *usb_cdc_mdlm_detail_desc;
|
||||
struct usb_cdc_obex_desc *usb_cdc_obex_desc;
|
||||
struct usb_cdc_ncm_desc *usb_cdc_ncm_desc;
|
||||
struct usb_cdc_mbim_desc *usb_cdc_mbim_desc;
|
||||
struct usb_cdc_mbim_extended_desc *usb_cdc_mbim_extended_desc;
|
||||
|
||||
bool phonet_magic_present;
|
||||
};
|
||||
|
||||
struct usb_interface;
|
||||
int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
|
||||
struct usb_interface *intf,
|
||||
u8 *buffer,
|
||||
int buflen);
|
||||
|
||||
#endif /* __LINUX_USB_CDC_H */
|
||||
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson 2010-2012
|
||||
* Contact: Alexey Orishko <alexey.orishko@stericsson.com>
|
||||
* Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
|
||||
*
|
||||
* USB Host Driver for Network Control Model (NCM)
|
||||
* http://www.usb.org/developers/devclass_docs/NCM10.zip
|
||||
*
|
||||
* The NCM encoding, decoding and initialization logic
|
||||
* derives from FreeBSD 8.x. if_cdce.c and if_cdcereg.h
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose this file to be licensed under the terms
|
||||
* of the GNU General Public License (GPL) Version 2 or the 2-clause
|
||||
* BSD license listed below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_CDC_NCM_H
|
||||
#define __LINUX_USB_CDC_NCM_H
|
||||
|
||||
#define CDC_NCM_COMM_ALTSETTING_NCM 0
|
||||
#define CDC_NCM_COMM_ALTSETTING_MBIM 1
|
||||
|
||||
#define CDC_NCM_DATA_ALTSETTING_NCM 1
|
||||
#define CDC_NCM_DATA_ALTSETTING_MBIM 2
|
||||
|
||||
/* CDC NCM subclass 3.3.1 */
|
||||
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
|
||||
|
||||
/* CDC NCM subclass 3.3.2 */
|
||||
#define USB_CDC_NCM_NDP32_LENGTH_MIN 0x20
|
||||
|
||||
/* Maximum NTB length */
|
||||
#define CDC_NCM_NTB_MAX_SIZE_TX 65536 /* bytes */
|
||||
#define CDC_NCM_NTB_MAX_SIZE_RX 65536 /* bytes */
|
||||
|
||||
/* Initial NTB length */
|
||||
#define CDC_NCM_NTB_DEF_SIZE_TX 16384 /* bytes */
|
||||
#define CDC_NCM_NTB_DEF_SIZE_RX 16384 /* bytes */
|
||||
|
||||
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
|
||||
#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
|
||||
|
||||
/* Minimum value for MaxDatagramSize, ch. 8.1.3 */
|
||||
#define CDC_MBIM_MIN_DATAGRAM_SIZE 2048 /* bytes */
|
||||
|
||||
#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
|
||||
|
||||
/* Default value for MaxDatagramSize */
|
||||
#define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */
|
||||
|
||||
/*
|
||||
* Maximum amount of datagrams in NCM Datagram Pointer Table, not counting
|
||||
* the last NULL entry.
|
||||
*/
|
||||
#define CDC_NCM_DPT_DATAGRAMS_MAX 40
|
||||
|
||||
/* Restart the timer, if amount of datagrams is less than given value */
|
||||
#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3
|
||||
#define CDC_NCM_TIMER_PENDING_CNT 2
|
||||
#define CDC_NCM_TIMER_INTERVAL_USEC 400UL
|
||||
#define CDC_NCM_TIMER_INTERVAL_MIN 5UL
|
||||
#define CDC_NCM_TIMER_INTERVAL_MAX (U32_MAX / NSEC_PER_USEC)
|
||||
|
||||
/* Driver flags */
|
||||
#define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */
|
||||
#define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04 /* Avoid altsetting toggle during init */
|
||||
#define CDC_NCM_FLAG_PREFER_NTB32 0x08 /* prefer NDP32 over NDP16 */
|
||||
|
||||
#define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
|
||||
(x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
|
||||
#define cdc_ncm_data_intf_is_mbim(x) ((x)->desc.bInterfaceProtocol == USB_CDC_MBIM_PROTO_NTB)
|
||||
|
||||
struct cdc_ncm_ctx {
|
||||
struct usb_cdc_ncm_ntb_parameters ncm_parm;
|
||||
struct hrtimer tx_timer;
|
||||
struct tasklet_struct bh;
|
||||
|
||||
struct usbnet *dev;
|
||||
|
||||
const struct usb_cdc_ncm_desc *func_desc;
|
||||
const struct usb_cdc_mbim_desc *mbim_desc;
|
||||
const struct usb_cdc_mbim_extended_desc *mbim_extended_desc;
|
||||
const struct usb_cdc_ether_desc *ether_desc;
|
||||
|
||||
struct usb_interface *control;
|
||||
struct usb_interface *data;
|
||||
|
||||
struct sk_buff *tx_curr_skb;
|
||||
struct sk_buff *tx_rem_skb;
|
||||
__le32 tx_rem_sign;
|
||||
|
||||
spinlock_t mtx;
|
||||
atomic_t stop;
|
||||
int drvflags;
|
||||
|
||||
u32 timer_interval;
|
||||
u32 max_ndp_size;
|
||||
bool is_ndp16;
|
||||
bool filtering_supported;
|
||||
union {
|
||||
struct usb_cdc_ncm_ndp16 *delayed_ndp16;
|
||||
struct usb_cdc_ncm_ndp32 *delayed_ndp32;
|
||||
};
|
||||
|
||||
u32 tx_timer_pending;
|
||||
u32 tx_curr_frame_num;
|
||||
u32 rx_max;
|
||||
u32 tx_max;
|
||||
u32 tx_curr_size;
|
||||
u32 tx_low_mem_max_cnt;
|
||||
u32 tx_low_mem_val;
|
||||
u32 max_datagram_size;
|
||||
u16 tx_max_datagrams;
|
||||
u16 tx_remainder;
|
||||
u16 tx_modulus;
|
||||
u16 tx_ndp_modulus;
|
||||
u16 tx_seq;
|
||||
u16 rx_seq;
|
||||
u16 min_tx_pkt;
|
||||
|
||||
/* statistics */
|
||||
u32 tx_curr_frame_payload;
|
||||
u32 tx_reason_ntb_full;
|
||||
u32 tx_reason_ndp_full;
|
||||
u32 tx_reason_timeout;
|
||||
u32 tx_reason_max_datagram;
|
||||
u64 tx_overhead;
|
||||
u64 tx_ntbs;
|
||||
u64 rx_overhead;
|
||||
u64 rx_ntbs;
|
||||
};
|
||||
|
||||
u8 cdc_ncm_select_altsetting(struct usb_interface *intf);
|
||||
int cdc_ncm_change_mtu(struct net_device *net, int new_mtu);
|
||||
int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags);
|
||||
void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
|
||||
struct sk_buff *cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign);
|
||||
int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in);
|
||||
int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset);
|
||||
int cdc_ncm_rx_verify_nth32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in);
|
||||
int cdc_ncm_rx_verify_ndp32(struct sk_buff *skb_in, int ndpoffset);
|
||||
struct sk_buff *
|
||||
cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
|
||||
int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in);
|
||||
|
||||
#endif /* __LINUX_USB_CDC_NCM_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This file holds USB constants and structures that are needed for
|
||||
* USB device APIs. These are used by the USB device model, which is
|
||||
* defined in chapter 9 of the USB 2.0 specification and in the
|
||||
* Wireless USB 1.0 spec (now defunct). Linux has several APIs in C that
|
||||
* need these:
|
||||
*
|
||||
* - the host side Linux-USB kernel driver API;
|
||||
* - the "usbfs" user space API; and
|
||||
* - the Linux "gadget" device/peripheral side driver API.
|
||||
*
|
||||
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
|
||||
* act either as a USB host or as a USB device. That means the host and
|
||||
* device side APIs benefit from working well together.
|
||||
*
|
||||
* Note all descriptors are declared '__attribute__((packed))' so that:
|
||||
*
|
||||
* [a] they never get padded, either internally (USB spec writers
|
||||
* probably handled that) or externally;
|
||||
*
|
||||
* [b] so that accessing bigger-than-a-bytes fields will never
|
||||
* generate bus errors on any platform, even when the location of
|
||||
* its descriptor inside a bundle isn't "naturally aligned", and
|
||||
*
|
||||
* [c] for consistency, removing all doubt even when it appears to
|
||||
* someone that the two other points are non-issues for that
|
||||
* particular descriptor type.
|
||||
*/
|
||||
#ifndef __LINUX_USB_CH9_H
|
||||
#define __LINUX_USB_CH9_H
|
||||
|
||||
#include <uapi/linux/usb/ch9.h>
|
||||
|
||||
/* USB 3.2 SuperSpeed Plus phy signaling rate generation and lane count */
|
||||
|
||||
enum usb_ssp_rate {
|
||||
USB_SSP_GEN_UNKNOWN = 0,
|
||||
USB_SSP_GEN_2x1,
|
||||
USB_SSP_GEN_1x2,
|
||||
USB_SSP_GEN_2x2,
|
||||
};
|
||||
|
||||
struct device;
|
||||
|
||||
extern const char *usb_ep_type_string(int ep_type);
|
||||
extern const char *usb_speed_string(enum usb_device_speed speed);
|
||||
extern enum usb_device_speed usb_get_maximum_speed(struct device *dev);
|
||||
extern enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev);
|
||||
extern const char *usb_state_string(enum usb_device_state state);
|
||||
unsigned int usb_decode_interval(const struct usb_endpoint_descriptor *epd,
|
||||
enum usb_device_speed speed);
|
||||
|
||||
#ifdef CONFIG_TRACING
|
||||
extern const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
|
||||
__u8 bRequest, __u16 wValue, __u16 wIndex,
|
||||
__u16 wLength);
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_CH9_H */
|
||||
@@ -0,0 +1,117 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Platform data for the chipidea USB dual role controller
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_CHIPIDEA_H
|
||||
#define __LINUX_USB_CHIPIDEA_H
|
||||
|
||||
#include <linux/extcon.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
struct ci_hdrc;
|
||||
|
||||
/**
|
||||
* struct ci_hdrc_cable - structure for external connector cable state tracking
|
||||
* @connected: true if cable is connected, false otherwise
|
||||
* @changed: set to true when extcon event happen
|
||||
* @enabled: set to true if we've enabled the vbus or id interrupt
|
||||
* @edev: device which generate events
|
||||
* @ci: driver state of the chipidea device
|
||||
* @nb: hold event notification callback
|
||||
* @conn: used for notification registration
|
||||
*/
|
||||
struct ci_hdrc_cable {
|
||||
bool connected;
|
||||
bool changed;
|
||||
bool enabled;
|
||||
struct extcon_dev *edev;
|
||||
struct ci_hdrc *ci;
|
||||
struct notifier_block nb;
|
||||
};
|
||||
|
||||
struct ci_hdrc_platform_data {
|
||||
const char *name;
|
||||
/* offset of the capability registers */
|
||||
uintptr_t capoffset;
|
||||
unsigned power_budget;
|
||||
struct phy *phy;
|
||||
/* old usb_phy interface */
|
||||
struct usb_phy *usb_phy;
|
||||
enum usb_phy_interface phy_mode;
|
||||
unsigned long flags;
|
||||
#define CI_HDRC_REGS_SHARED BIT(0)
|
||||
#define CI_HDRC_DISABLE_DEVICE_STREAMING BIT(1)
|
||||
#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
|
||||
#define CI_HDRC_DISABLE_HOST_STREAMING BIT(3)
|
||||
#define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING | \
|
||||
CI_HDRC_DISABLE_HOST_STREAMING)
|
||||
/*
|
||||
* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
|
||||
* but otg is not supported (no register otgsc).
|
||||
*/
|
||||
#define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)
|
||||
#define CI_HDRC_IMX28_WRITE_FIX BIT(5)
|
||||
#define CI_HDRC_FORCE_FULLSPEED BIT(6)
|
||||
#define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7)
|
||||
#define CI_HDRC_SET_NON_ZERO_TTHA BIT(8)
|
||||
#define CI_HDRC_OVERRIDE_AHB_BURST BIT(9)
|
||||
#define CI_HDRC_OVERRIDE_TX_BURST BIT(10)
|
||||
#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
|
||||
#define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */
|
||||
#define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13)
|
||||
#define CI_HDRC_IMX_IS_HSIC BIT(14)
|
||||
#define CI_HDRC_PMQOS BIT(15)
|
||||
#define CI_HDRC_PHY_VBUS_CONTROL BIT(16)
|
||||
#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17)
|
||||
#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18)
|
||||
#define CI_HDRC_HAS_SHORT_PKT_LIMIT BIT(19)
|
||||
#define CI_HDRC_OUT_BAND_WAKEUP BIT(20)
|
||||
enum usb_dr_mode dr_mode;
|
||||
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
|
||||
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
|
||||
#define CI_HDRC_IMX_HSIC_ACTIVE_EVENT 2
|
||||
#define CI_HDRC_IMX_HSIC_SUSPEND_EVENT 3
|
||||
#define CI_HDRC_CONTROLLER_VBUS_EVENT 4
|
||||
#define CI_HDRC_CONTROLLER_PULLUP_EVENT 5
|
||||
int (*notify_event) (struct ci_hdrc *ci, unsigned event);
|
||||
struct regulator *reg_vbus;
|
||||
struct usb_otg_caps ci_otg_caps;
|
||||
bool tpl_support;
|
||||
/* interrupt threshold setting */
|
||||
u32 itc_setting;
|
||||
u32 ahb_burst_config;
|
||||
u32 tx_burst_size;
|
||||
u32 rx_burst_size;
|
||||
|
||||
/* VBUS and ID signal state tracking, using extcon framework */
|
||||
struct ci_hdrc_cable vbus_extcon;
|
||||
struct ci_hdrc_cable id_extcon;
|
||||
u32 phy_clkgate_delay_us;
|
||||
|
||||
/* pins */
|
||||
struct pinctrl *pctl;
|
||||
struct pinctrl_state *pins_default;
|
||||
struct pinctrl_state *pins_host;
|
||||
struct pinctrl_state *pins_device;
|
||||
|
||||
/* platform-specific hooks */
|
||||
int (*hub_control)(struct ci_hdrc *ci, u16 typeReq, u16 wValue,
|
||||
u16 wIndex, char *buf, u16 wLength,
|
||||
bool *done, unsigned long *flags);
|
||||
void (*enter_lpm)(struct ci_hdrc *ci, bool enable);
|
||||
};
|
||||
|
||||
/* Default offset of capability registers */
|
||||
#define DEF_CAPOFFSET 0x100
|
||||
|
||||
/* Add ci hdrc device */
|
||||
struct platform_device *ci_hdrc_add_device(struct device *dev,
|
||||
struct resource *res, int nres,
|
||||
struct ci_hdrc_platform_data *platdata);
|
||||
/* Remove ci hdrc device */
|
||||
void ci_hdrc_remove_device(struct platform_device *pdev);
|
||||
/* Get current available role */
|
||||
enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,635 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* composite.h -- framework for usb gadgets which are composite devices
|
||||
*
|
||||
* Copyright (C) 2006-2008 David Brownell
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_COMPOSITE_H
|
||||
#define __LINUX_USB_COMPOSITE_H
|
||||
|
||||
/*
|
||||
* This framework is an optional layer on top of the USB Gadget interface,
|
||||
* making it easier to build (a) Composite devices, supporting multiple
|
||||
* functions within any single configuration, and (b) Multi-configuration
|
||||
* devices, also supporting multiple functions but without necessarily
|
||||
* having more than one function per configuration.
|
||||
*
|
||||
* Example: a device with a single configuration supporting both network
|
||||
* link and mass storage functions is a composite device. Those functions
|
||||
* might alternatively be packaged in individual configurations, but in
|
||||
* the composite model the host can use both functions at the same time.
|
||||
*/
|
||||
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/usb/webusb.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/configfs.h>
|
||||
|
||||
/*
|
||||
* USB function drivers should return USB_GADGET_DELAYED_STATUS if they
|
||||
* wish to delay the data/status stages of the control transfer till they
|
||||
* are ready. The control transfer will then be kept from completing till
|
||||
* all the function drivers that requested for USB_GADGET_DELAYED_STAUS
|
||||
* invoke usb_composite_setup_continue().
|
||||
*
|
||||
* NOTE: USB_GADGET_DELAYED_STATUS must not be used in UDC drivers: they
|
||||
* must delay completing the status stage for 0-length control transfers
|
||||
* regardless of the whether USB_GADGET_DELAYED_STATUS is returned from
|
||||
* the gadget driver's setup() callback.
|
||||
* Currently, a number of UDC drivers rely on USB_GADGET_DELAYED_STATUS,
|
||||
* which is a bug. These drivers must be fixed and USB_GADGET_DELAYED_STATUS
|
||||
* must be contained within the composite framework.
|
||||
*/
|
||||
#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */
|
||||
|
||||
/* big enough to hold our biggest descriptor */
|
||||
#define USB_COMP_EP0_BUFSIZ 4096
|
||||
|
||||
/* OS feature descriptor length <= 4kB */
|
||||
#define USB_COMP_EP0_OS_DESC_BUFSIZ 4096
|
||||
|
||||
#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1)
|
||||
struct usb_configuration;
|
||||
|
||||
/**
|
||||
* struct usb_os_desc_ext_prop - describes one "Extended Property"
|
||||
* @entry: used to keep a list of extended properties
|
||||
* @type: Extended Property type
|
||||
* @name_len: Extended Property unicode name length, including terminating '\0'
|
||||
* @name: Extended Property name
|
||||
* @data_len: Length of Extended Property blob (for unicode store double len)
|
||||
* @data: Extended Property blob
|
||||
* @item: Represents this Extended Property in configfs
|
||||
*/
|
||||
struct usb_os_desc_ext_prop {
|
||||
struct list_head entry;
|
||||
u8 type;
|
||||
int name_len;
|
||||
char *name;
|
||||
int data_len;
|
||||
char *data;
|
||||
struct config_item item;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_os_desc - describes OS descriptors associated with one interface
|
||||
* @ext_compat_id: 16 bytes of "Compatible ID" and "Subcompatible ID"
|
||||
* @ext_prop: Extended Properties list
|
||||
* @ext_prop_len: Total length of Extended Properties blobs
|
||||
* @ext_prop_count: Number of Extended Properties
|
||||
* @opts_mutex: Optional mutex protecting config data of a usb_function_instance
|
||||
* @group: Represents OS descriptors associated with an interface in configfs
|
||||
* @owner: Module associated with this OS descriptor
|
||||
*/
|
||||
struct usb_os_desc {
|
||||
char *ext_compat_id;
|
||||
struct list_head ext_prop;
|
||||
int ext_prop_len;
|
||||
int ext_prop_count;
|
||||
struct mutex *opts_mutex;
|
||||
struct config_group group;
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_os_desc_table - describes OS descriptors associated with one
|
||||
* interface of a usb_function
|
||||
* @if_id: Interface id
|
||||
* @os_desc: "Extended Compatibility ID" and "Extended Properties" of the
|
||||
* interface
|
||||
*
|
||||
* Each interface can have at most one "Extended Compatibility ID" and a
|
||||
* number of "Extended Properties".
|
||||
*/
|
||||
struct usb_os_desc_table {
|
||||
int if_id;
|
||||
struct usb_os_desc *os_desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_function - describes one function of a configuration
|
||||
* @name: For diagnostics, identifies the function.
|
||||
* @strings: tables of strings, keyed by identifiers assigned during bind()
|
||||
* and by language IDs provided in control requests
|
||||
* @fs_descriptors: Table of full (or low) speed descriptors, using interface and
|
||||
* string identifiers assigned during @bind(). If this pointer is null,
|
||||
* the function will not be available at full speed (or at low speed).
|
||||
* @hs_descriptors: Table of high speed descriptors, using interface and
|
||||
* string identifiers assigned during @bind(). If this pointer is null,
|
||||
* the function will not be available at high speed.
|
||||
* @ss_descriptors: Table of super speed descriptors, using interface and
|
||||
* string identifiers assigned during @bind(). If this
|
||||
* pointer is null after initiation, the function will not
|
||||
* be available at super speed.
|
||||
* @ssp_descriptors: Table of super speed plus descriptors, using
|
||||
* interface and string identifiers assigned during @bind(). If
|
||||
* this pointer is null after initiation, the function will not
|
||||
* be available at super speed plus.
|
||||
* @config: assigned when @usb_add_function() is called; this is the
|
||||
* configuration with which this function is associated.
|
||||
* @os_desc_table: Table of (interface id, os descriptors) pairs. The function
|
||||
* can expose more than one interface. If an interface is a member of
|
||||
* an IAD, only the first interface of IAD has its entry in the table.
|
||||
* @os_desc_n: Number of entries in os_desc_table
|
||||
* @bind: Before the gadget can register, all of its functions bind() to the
|
||||
* available resources including string and interface identifiers used
|
||||
* in interface or class descriptors; endpoints; I/O buffers; and so on.
|
||||
* @unbind: Reverses @bind; called as a side effect of unregistering the
|
||||
* driver which added this function.
|
||||
* @free_func: free the struct usb_function.
|
||||
* @mod: (internal) points to the module that created this structure.
|
||||
* @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
|
||||
* initialize usb_ep.driver data at this time (when it is used).
|
||||
* Note that setting an interface to its current altsetting resets
|
||||
* interface state, and that all interfaces have a disabled state.
|
||||
* @get_alt: Returns the active altsetting. If this is not provided,
|
||||
* then only altsetting zero is supported.
|
||||
* @disable: (REQUIRED) Indicates the function should be disabled. Reasons
|
||||
* include host resetting or reconfiguring the gadget, and disconnection.
|
||||
* @setup: Used for interface-specific control requests.
|
||||
* @req_match: Tests if a given class request can be handled by this function.
|
||||
* @suspend: Notifies functions when the host stops sending USB traffic.
|
||||
* @resume: Notifies functions when the host restarts USB traffic.
|
||||
* @get_status: Returns function status as a reply to
|
||||
* GetStatus() request when the recipient is Interface.
|
||||
* @func_suspend: callback to be called when
|
||||
* SetFeature(FUNCTION_SUSPEND) is reseived
|
||||
* @func_suspended: Indicates whether the function is in function suspend state.
|
||||
* @func_wakeup_armed: Indicates whether the function is armed by the host for
|
||||
* wakeup signaling.
|
||||
*
|
||||
* A single USB function uses one or more interfaces, and should in most
|
||||
* cases support operation at both full and high speeds. Each function is
|
||||
* associated by @usb_add_function() with a one configuration; that function
|
||||
* causes @bind() to be called so resources can be allocated as part of
|
||||
* setting up a gadget driver. Those resources include endpoints, which
|
||||
* should be allocated using @usb_ep_autoconfig().
|
||||
*
|
||||
* To support dual speed operation, a function driver provides descriptors
|
||||
* for both high and full speed operation. Except in rare cases that don't
|
||||
* involve bulk endpoints, each speed needs different endpoint descriptors.
|
||||
*
|
||||
* Function drivers choose their own strategies for managing instance data.
|
||||
* The simplest strategy just declares it "static', which means the function
|
||||
* can only be activated once. If the function needs to be exposed in more
|
||||
* than one configuration at a given speed, it needs to support multiple
|
||||
* usb_function structures (one for each configuration).
|
||||
*
|
||||
* A more complex strategy might encapsulate a @usb_function structure inside
|
||||
* a driver-specific instance structure to allows multiple activations. An
|
||||
* example of multiple activations might be a CDC ACM function that supports
|
||||
* two or more distinct instances within the same configuration, providing
|
||||
* several independent logical data links to a USB host.
|
||||
*/
|
||||
|
||||
struct usb_function {
|
||||
const char *name;
|
||||
struct usb_gadget_strings **strings;
|
||||
struct usb_descriptor_header **fs_descriptors;
|
||||
struct usb_descriptor_header **hs_descriptors;
|
||||
struct usb_descriptor_header **ss_descriptors;
|
||||
struct usb_descriptor_header **ssp_descriptors;
|
||||
|
||||
struct usb_configuration *config;
|
||||
|
||||
struct usb_os_desc_table *os_desc_table;
|
||||
unsigned os_desc_n;
|
||||
|
||||
/* REVISIT: bind() functions can be marked __init, which
|
||||
* makes trouble for section mismatch analysis. See if
|
||||
* we can't restructure things to avoid mismatching.
|
||||
* Related: unbind() may kfree() but bind() won't...
|
||||
*/
|
||||
|
||||
/* configuration management: bind/unbind */
|
||||
int (*bind)(struct usb_configuration *,
|
||||
struct usb_function *);
|
||||
void (*unbind)(struct usb_configuration *,
|
||||
struct usb_function *);
|
||||
void (*free_func)(struct usb_function *f);
|
||||
struct module *mod;
|
||||
|
||||
/* runtime state management */
|
||||
int (*set_alt)(struct usb_function *,
|
||||
unsigned interface, unsigned alt);
|
||||
int (*get_alt)(struct usb_function *,
|
||||
unsigned interface);
|
||||
void (*disable)(struct usb_function *);
|
||||
int (*setup)(struct usb_function *,
|
||||
const struct usb_ctrlrequest *);
|
||||
bool (*req_match)(struct usb_function *,
|
||||
const struct usb_ctrlrequest *,
|
||||
bool config0);
|
||||
void (*suspend)(struct usb_function *);
|
||||
void (*resume)(struct usb_function *);
|
||||
|
||||
/* USB 3.0 additions */
|
||||
int (*get_status)(struct usb_function *);
|
||||
int (*func_suspend)(struct usb_function *,
|
||||
u8 suspend_opt);
|
||||
bool func_suspended;
|
||||
bool func_wakeup_armed;
|
||||
/* private: */
|
||||
/* internals */
|
||||
struct list_head list;
|
||||
DECLARE_BITMAP(endpoints, 32);
|
||||
struct usb_function_instance *fi;
|
||||
|
||||
unsigned int bind_deactivated:1;
|
||||
};
|
||||
|
||||
int usb_add_function(struct usb_configuration *, struct usb_function *);
|
||||
|
||||
int usb_function_deactivate(struct usb_function *);
|
||||
int usb_function_activate(struct usb_function *);
|
||||
|
||||
int usb_interface_id(struct usb_configuration *, struct usb_function *);
|
||||
|
||||
int config_ep_by_speed_and_alt(struct usb_gadget *g, struct usb_function *f,
|
||||
struct usb_ep *_ep, u8 alt);
|
||||
|
||||
int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f,
|
||||
struct usb_ep *_ep);
|
||||
int usb_func_wakeup(struct usb_function *func);
|
||||
|
||||
#define MAX_CONFIG_INTERFACES 32
|
||||
|
||||
/**
|
||||
* struct usb_configuration - represents one gadget configuration
|
||||
* @label: For diagnostics, describes the configuration.
|
||||
* @strings: Tables of strings, keyed by identifiers assigned during @bind()
|
||||
* and by language IDs provided in control requests.
|
||||
* @descriptors: Table of descriptors preceding all function descriptors.
|
||||
* Examples include OTG and vendor-specific descriptors.
|
||||
* @unbind: Reverses @bind; called as a side effect of unregistering the
|
||||
* driver which added this configuration.
|
||||
* @setup: Used to delegate control requests that aren't handled by standard
|
||||
* device infrastructure or directed at a specific interface.
|
||||
* @bConfigurationValue: Copied into configuration descriptor.
|
||||
* @iConfiguration: Copied into configuration descriptor.
|
||||
* @bmAttributes: Copied into configuration descriptor.
|
||||
* @MaxPower: Power consumption in mA. Used to compute bMaxPower in the
|
||||
* configuration descriptor after considering the bus speed.
|
||||
* @cdev: assigned by @usb_add_config() before calling @bind(); this is
|
||||
* the device associated with this configuration.
|
||||
*
|
||||
* Configurations are building blocks for gadget drivers structured around
|
||||
* function drivers. Simple USB gadgets require only one function and one
|
||||
* configuration, and handle dual-speed hardware by always providing the same
|
||||
* functionality. Slightly more complex gadgets may have more than one
|
||||
* single-function configuration at a given speed; or have configurations
|
||||
* that only work at one speed.
|
||||
*
|
||||
* Composite devices are, by definition, ones with configurations which
|
||||
* include more than one function.
|
||||
*
|
||||
* The lifecycle of a usb_configuration includes allocation, initialization
|
||||
* of the fields described above, and calling @usb_add_config() to set up
|
||||
* internal data and bind it to a specific device. The configuration's
|
||||
* @bind() method is then used to initialize all the functions and then
|
||||
* call @usb_add_function() for them.
|
||||
*
|
||||
* Those functions would normally be independent of each other, but that's
|
||||
* not mandatory. CDC WMC devices are an example where functions often
|
||||
* depend on other functions, with some functions subsidiary to others.
|
||||
* Such interdependency may be managed in any way, so long as all of the
|
||||
* descriptors complete by the time the composite driver returns from
|
||||
* its bind() routine.
|
||||
*/
|
||||
struct usb_configuration {
|
||||
const char *label;
|
||||
struct usb_gadget_strings **strings;
|
||||
const struct usb_descriptor_header **descriptors;
|
||||
|
||||
/* REVISIT: bind() functions can be marked __init, which
|
||||
* makes trouble for section mismatch analysis. See if
|
||||
* we can't restructure things to avoid mismatching...
|
||||
*/
|
||||
|
||||
/* configuration management: unbind/setup */
|
||||
void (*unbind)(struct usb_configuration *);
|
||||
int (*setup)(struct usb_configuration *,
|
||||
const struct usb_ctrlrequest *);
|
||||
|
||||
/* fields in the config descriptor */
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
u8 bmAttributes;
|
||||
u16 MaxPower;
|
||||
|
||||
struct usb_composite_dev *cdev;
|
||||
|
||||
/* private: */
|
||||
/* internals */
|
||||
struct list_head list;
|
||||
struct list_head functions;
|
||||
u8 next_interface_id;
|
||||
unsigned superspeed:1;
|
||||
unsigned highspeed:1;
|
||||
unsigned fullspeed:1;
|
||||
unsigned superspeed_plus:1;
|
||||
struct usb_function *interface[MAX_CONFIG_INTERFACES];
|
||||
};
|
||||
|
||||
int usb_add_config(struct usb_composite_dev *,
|
||||
struct usb_configuration *,
|
||||
int (*)(struct usb_configuration *));
|
||||
|
||||
/* predefined index for usb_composite_driver */
|
||||
enum {
|
||||
USB_GADGET_MANUFACTURER_IDX = 0,
|
||||
USB_GADGET_PRODUCT_IDX,
|
||||
USB_GADGET_SERIAL_IDX,
|
||||
USB_GADGET_FIRST_AVAIL_IDX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_composite_driver - groups configurations into a gadget
|
||||
* @name: For diagnostics, identifies the driver.
|
||||
* @dev: Template descriptor for the device, including default device
|
||||
* identifiers.
|
||||
* @strings: tables of strings, keyed by identifiers assigned during @bind
|
||||
* and language IDs provided in control requests. Note: The first entries
|
||||
* are predefined. The first entry that may be used is
|
||||
* USB_GADGET_FIRST_AVAIL_IDX
|
||||
* @max_speed: Highest speed the driver supports.
|
||||
* @needs_serial: set to 1 if the gadget needs userspace to provide
|
||||
* a serial number. If one is not provided, warning will be printed.
|
||||
* @bind: (REQUIRED) Used to allocate resources that are shared across the
|
||||
* whole device, such as string IDs, and add its configurations using
|
||||
* @usb_add_config(). This may fail by returning a negative errno
|
||||
* value; it should return zero on successful initialization.
|
||||
* @unbind: Reverses @bind; called as a side effect of unregistering
|
||||
* this driver.
|
||||
* @disconnect: optional driver disconnect method
|
||||
* @suspend: Notifies when the host stops sending USB traffic,
|
||||
* after function notifications
|
||||
* @resume: Notifies configuration when the host restarts USB traffic,
|
||||
* before function notifications
|
||||
* @gadget_driver: Gadget driver controlling this driver
|
||||
*
|
||||
* Devices default to reporting self powered operation. Devices which rely
|
||||
* on bus powered operation should report this in their @bind method.
|
||||
*
|
||||
* Before returning from @bind, various fields in the template descriptor
|
||||
* may be overridden. These include the idVendor/idProduct/bcdDevice values
|
||||
* normally to bind the appropriate host side driver, and the three strings
|
||||
* (iManufacturer, iProduct, iSerialNumber) normally used to provide user
|
||||
* meaningful device identifiers. (The strings will not be defined unless
|
||||
* they are defined in @dev and @strings.) The correct ep0 maxpacket size
|
||||
* is also reported, as defined by the underlying controller driver.
|
||||
*/
|
||||
struct usb_composite_driver {
|
||||
const char *name;
|
||||
const struct usb_device_descriptor *dev;
|
||||
struct usb_gadget_strings **strings;
|
||||
enum usb_device_speed max_speed;
|
||||
unsigned needs_serial:1;
|
||||
|
||||
int (*bind)(struct usb_composite_dev *cdev);
|
||||
int (*unbind)(struct usb_composite_dev *);
|
||||
|
||||
void (*disconnect)(struct usb_composite_dev *);
|
||||
|
||||
/* global suspend hooks */
|
||||
void (*suspend)(struct usb_composite_dev *);
|
||||
void (*resume)(struct usb_composite_dev *);
|
||||
struct usb_gadget_driver gadget_driver;
|
||||
};
|
||||
|
||||
extern int usb_composite_probe(struct usb_composite_driver *driver);
|
||||
extern void usb_composite_unregister(struct usb_composite_driver *driver);
|
||||
|
||||
/**
|
||||
* module_usb_composite_driver() - Helper macro for registering a USB gadget
|
||||
* composite driver
|
||||
* @__usb_composite_driver: usb_composite_driver struct
|
||||
*
|
||||
* Helper macro for USB gadget composite drivers which do not do anything
|
||||
* special in module init/exit. This eliminates a lot of boilerplate. Each
|
||||
* module may only use this macro once, and calling it replaces module_init()
|
||||
* and module_exit()
|
||||
*/
|
||||
#define module_usb_composite_driver(__usb_composite_driver) \
|
||||
module_driver(__usb_composite_driver, usb_composite_probe, \
|
||||
usb_composite_unregister)
|
||||
|
||||
extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
|
||||
extern int composite_dev_prepare(struct usb_composite_driver *composite,
|
||||
struct usb_composite_dev *cdev);
|
||||
extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *ep0);
|
||||
void composite_dev_cleanup(struct usb_composite_dev *cdev);
|
||||
void check_remote_wakeup_config(struct usb_gadget *g,
|
||||
struct usb_configuration *c);
|
||||
|
||||
static inline struct usb_composite_driver *to_cdriver(
|
||||
struct usb_gadget_driver *gdrv)
|
||||
{
|
||||
return container_of(gdrv, struct usb_composite_driver, gadget_driver);
|
||||
}
|
||||
|
||||
#define OS_STRING_QW_SIGN_LEN 14
|
||||
#define OS_STRING_IDX 0xEE
|
||||
|
||||
/**
|
||||
* struct usb_composite_dev - represents one composite usb gadget
|
||||
* @gadget: read-only, abstracts the gadget's usb peripheral controller
|
||||
* @req: used for control responses; buffer is pre-allocated
|
||||
* @os_desc_req: used for OS descriptors responses; buffer is pre-allocated
|
||||
* @config: the currently active configuration
|
||||
* @qw_sign: qwSignature part of the OS string
|
||||
* @b_vendor_code: bMS_VendorCode part of the OS string
|
||||
* @use_os_string: false by default, interested gadgets set it
|
||||
* @bcd_webusb_version: 0x0100 by default, WebUSB specification version
|
||||
* @b_webusb_vendor_code: 0x0 by default, vendor code for WebUSB
|
||||
* @landing_page: empty by default, landing page to announce in WebUSB
|
||||
* @use_webusb: false by default, interested gadgets set it
|
||||
* @os_desc_config: the configuration to be used with OS descriptors
|
||||
* @setup_pending: true when setup request is queued but not completed
|
||||
* @os_desc_pending: true when os_desc request is queued but not completed
|
||||
*
|
||||
* One of these devices is allocated and initialized before the
|
||||
* associated device driver's bind() is called.
|
||||
*/
|
||||
struct usb_composite_dev {
|
||||
struct usb_gadget *gadget;
|
||||
struct usb_request *req;
|
||||
struct usb_request *os_desc_req;
|
||||
|
||||
struct usb_configuration *config;
|
||||
|
||||
/* OS String is a custom (yet popular) extension to the USB standard. */
|
||||
u8 qw_sign[OS_STRING_QW_SIGN_LEN];
|
||||
u8 b_vendor_code;
|
||||
struct usb_configuration *os_desc_config;
|
||||
unsigned int use_os_string:1;
|
||||
|
||||
/* WebUSB */
|
||||
u16 bcd_webusb_version;
|
||||
u8 b_webusb_vendor_code;
|
||||
char landing_page[WEBUSB_URL_RAW_MAX_LENGTH];
|
||||
unsigned int use_webusb:1;
|
||||
|
||||
/* private: */
|
||||
/* internals */
|
||||
unsigned int suspended:1;
|
||||
struct usb_device_descriptor desc;
|
||||
struct list_head configs;
|
||||
struct list_head gstrings;
|
||||
struct usb_composite_driver *driver;
|
||||
u8 next_string_id;
|
||||
char *def_manufacturer;
|
||||
struct usb_string *usb_strings;
|
||||
|
||||
/* the gadget driver won't enable the data pullup
|
||||
* while the deactivation count is nonzero.
|
||||
*/
|
||||
unsigned deactivations;
|
||||
|
||||
/* the composite driver won't complete the control transfer's
|
||||
* data/status stages till delayed_status is zero.
|
||||
*/
|
||||
int delayed_status;
|
||||
|
||||
/* protects deactivations and delayed_status counts*/
|
||||
spinlock_t lock;
|
||||
|
||||
/* public: */
|
||||
unsigned int setup_pending:1;
|
||||
unsigned int os_desc_pending:1;
|
||||
};
|
||||
|
||||
extern int usb_string_id(struct usb_composite_dev *c);
|
||||
extern int usb_string_ids_tab(struct usb_composite_dev *c,
|
||||
struct usb_string *str);
|
||||
extern struct usb_string *usb_gstrings_attach(struct usb_composite_dev *cdev,
|
||||
struct usb_gadget_strings **sp, unsigned n_strings);
|
||||
|
||||
extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n);
|
||||
|
||||
extern void composite_disconnect(struct usb_gadget *gadget);
|
||||
extern void composite_reset(struct usb_gadget *gadget);
|
||||
|
||||
extern int composite_setup(struct usb_gadget *gadget,
|
||||
const struct usb_ctrlrequest *ctrl);
|
||||
extern void composite_suspend(struct usb_gadget *gadget);
|
||||
extern void composite_resume(struct usb_gadget *gadget);
|
||||
|
||||
/*
|
||||
* Some systems will need runtime overrides for the product identifiers
|
||||
* published in the device descriptor, either numbers or strings or both.
|
||||
* String parameters are in UTF-8 (superset of ASCII's 7 bit characters).
|
||||
*/
|
||||
struct usb_composite_overwrite {
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
u16 bcdDevice;
|
||||
char *serial_number;
|
||||
char *manufacturer;
|
||||
char *product;
|
||||
};
|
||||
#define USB_GADGET_COMPOSITE_OPTIONS() \
|
||||
static struct usb_composite_overwrite coverwrite; \
|
||||
\
|
||||
module_param_named(idVendor, coverwrite.idVendor, ushort, S_IRUGO); \
|
||||
MODULE_PARM_DESC(idVendor, "USB Vendor ID"); \
|
||||
\
|
||||
module_param_named(idProduct, coverwrite.idProduct, ushort, S_IRUGO); \
|
||||
MODULE_PARM_DESC(idProduct, "USB Product ID"); \
|
||||
\
|
||||
module_param_named(bcdDevice, coverwrite.bcdDevice, ushort, S_IRUGO); \
|
||||
MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); \
|
||||
\
|
||||
module_param_named(iSerialNumber, coverwrite.serial_number, charp, \
|
||||
S_IRUGO); \
|
||||
MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); \
|
||||
\
|
||||
module_param_named(iManufacturer, coverwrite.manufacturer, charp, \
|
||||
S_IRUGO); \
|
||||
MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); \
|
||||
\
|
||||
module_param_named(iProduct, coverwrite.product, charp, S_IRUGO); \
|
||||
MODULE_PARM_DESC(iProduct, "USB Product string")
|
||||
|
||||
void usb_composite_overwrite_options(struct usb_composite_dev *cdev,
|
||||
struct usb_composite_overwrite *covr);
|
||||
|
||||
static inline u16 get_default_bcdDevice(void)
|
||||
{
|
||||
u16 bcdDevice;
|
||||
|
||||
bcdDevice = bin2bcd(LINUX_VERSION_MAJOR) << 8;
|
||||
bcdDevice |= bin2bcd(LINUX_VERSION_PATCHLEVEL);
|
||||
return bcdDevice;
|
||||
}
|
||||
|
||||
struct usb_function_driver {
|
||||
const char *name;
|
||||
struct module *mod;
|
||||
struct list_head list;
|
||||
struct usb_function_instance *(*alloc_inst)(void);
|
||||
struct usb_function *(*alloc_func)(struct usb_function_instance *inst);
|
||||
};
|
||||
|
||||
struct usb_function_instance {
|
||||
struct config_group group;
|
||||
struct list_head cfs_list;
|
||||
struct usb_function_driver *fd;
|
||||
int (*set_inst_name)(struct usb_function_instance *inst,
|
||||
const char *name);
|
||||
void (*free_func_inst)(struct usb_function_instance *inst);
|
||||
};
|
||||
|
||||
void usb_function_unregister(struct usb_function_driver *f);
|
||||
int usb_function_register(struct usb_function_driver *newf);
|
||||
void usb_put_function_instance(struct usb_function_instance *fi);
|
||||
void usb_put_function(struct usb_function *f);
|
||||
struct usb_function_instance *usb_get_function_instance(const char *name);
|
||||
struct usb_function *usb_get_function(struct usb_function_instance *fi);
|
||||
|
||||
struct usb_configuration *usb_get_config(struct usb_composite_dev *cdev,
|
||||
int val);
|
||||
int usb_add_config_only(struct usb_composite_dev *cdev,
|
||||
struct usb_configuration *config);
|
||||
void usb_remove_function(struct usb_configuration *c, struct usb_function *f);
|
||||
|
||||
#define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \
|
||||
static struct usb_function_driver _name ## usb_func = { \
|
||||
.name = __stringify(_name), \
|
||||
.mod = THIS_MODULE, \
|
||||
.alloc_inst = _inst_alloc, \
|
||||
.alloc_func = _func_alloc, \
|
||||
}; \
|
||||
MODULE_ALIAS("usbfunc:"__stringify(_name));
|
||||
|
||||
#define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc) \
|
||||
DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \
|
||||
static int __init _name ## mod_init(void) \
|
||||
{ \
|
||||
return usb_function_register(&_name ## usb_func); \
|
||||
} \
|
||||
static void __exit _name ## mod_exit(void) \
|
||||
{ \
|
||||
usb_function_unregister(&_name ## usb_func); \
|
||||
} \
|
||||
module_init(_name ## mod_init); \
|
||||
module_exit(_name ## mod_exit)
|
||||
|
||||
/* messaging utils */
|
||||
#define DBG(d, fmt, args...) \
|
||||
dev_dbg(&(d)->gadget->dev , fmt , ## args)
|
||||
#define VDBG(d, fmt, args...) \
|
||||
dev_vdbg(&(d)->gadget->dev , fmt , ## args)
|
||||
#define ERROR(d, fmt, args...) \
|
||||
dev_err(&(d)->gadget->dev , fmt , ## args)
|
||||
#define WARNING(d, fmt, args...) \
|
||||
dev_warn(&(d)->gadget->dev , fmt , ## args)
|
||||
#define INFO(d, fmt, args...) \
|
||||
dev_info(&(d)->gadget->dev , fmt , ## args)
|
||||
|
||||
#endif /* __LINUX_USB_COMPOSITE_H */
|
||||
@@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Standalone EHCI usb debug driver
|
||||
*
|
||||
* Originally written by:
|
||||
* Eric W. Biederman" <ebiederm@xmission.com> and
|
||||
* Yinghai Lu <yhlu.kernel@gmail.com>
|
||||
*
|
||||
* Changes for early/late printk and HW errata:
|
||||
* Jason Wessel <jason.wessel@windriver.com>
|
||||
* Copyright (C) 2009 Wind River Systems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_EHCI_DBGP_H
|
||||
#define __LINUX_USB_EHCI_DBGP_H
|
||||
|
||||
#include <linux/console.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Appendix C, Debug port ... intended for use with special "debug devices"
|
||||
* that can help if there's no serial console. (nonstandard enumeration.)
|
||||
*/
|
||||
struct ehci_dbg_port {
|
||||
u32 control;
|
||||
#define DBGP_OWNER (1<<30)
|
||||
#define DBGP_ENABLED (1<<28)
|
||||
#define DBGP_DONE (1<<16)
|
||||
#define DBGP_INUSE (1<<10)
|
||||
#define DBGP_ERRCODE(x) (((x)>>7)&0x07)
|
||||
# define DBGP_ERR_BAD 1
|
||||
# define DBGP_ERR_SIGNAL 2
|
||||
#define DBGP_ERROR (1<<6)
|
||||
#define DBGP_GO (1<<5)
|
||||
#define DBGP_OUT (1<<4)
|
||||
#define DBGP_LEN(x) (((x)>>0)&0x0f)
|
||||
u32 pids;
|
||||
#define DBGP_PID_GET(x) (((x)>>16)&0xff)
|
||||
#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok))
|
||||
u32 data03;
|
||||
u32 data47;
|
||||
u32 address;
|
||||
#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep))
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK_DBGP
|
||||
extern int early_dbgp_init(char *s);
|
||||
extern struct console early_dbgp_console;
|
||||
#endif /* CONFIG_EARLY_PRINTK_DBGP */
|
||||
|
||||
struct usb_hcd;
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
extern int xen_dbgp_reset_prep(struct usb_hcd *);
|
||||
extern int xen_dbgp_external_startup(struct usb_hcd *);
|
||||
#else
|
||||
static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd)
|
||||
{
|
||||
return 1; /* Shouldn't this be 0? */
|
||||
}
|
||||
|
||||
static inline int xen_dbgp_external_startup(struct usb_hcd *hcd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK_DBGP
|
||||
/* Call backs from ehci host driver to ehci debug driver */
|
||||
extern int dbgp_external_startup(struct usb_hcd *);
|
||||
extern int dbgp_reset_prep(struct usb_hcd *);
|
||||
#else
|
||||
static inline int dbgp_reset_prep(struct usb_hcd *hcd)
|
||||
{
|
||||
return xen_dbgp_reset_prep(hcd);
|
||||
}
|
||||
|
||||
static inline int dbgp_external_startup(struct usb_hcd *hcd)
|
||||
{
|
||||
return xen_dbgp_external_startup(hcd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_EHCI_DBGP_H */
|
||||
@@ -0,0 +1,191 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2001-2002 by David Brownell
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_EHCI_DEF_H
|
||||
#define __LINUX_USB_EHCI_DEF_H
|
||||
|
||||
#include <linux/usb/ehci-dbgp.h>
|
||||
|
||||
/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
|
||||
|
||||
/* Section 2.2 Host Controller Capability Registers */
|
||||
struct ehci_caps {
|
||||
/* these fields are specified as 8 and 16 bit registers,
|
||||
* but some hosts can't perform 8 or 16 bit PCI accesses.
|
||||
* some hosts treat caplength and hciversion as parts of a 32-bit
|
||||
* register, others treat them as two separate registers, this
|
||||
* affects the memory map for big endian controllers.
|
||||
*/
|
||||
u32 hc_capbase;
|
||||
#define HC_LENGTH(ehci, p) (0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
|
||||
(ehci_big_endian_capbase(ehci) ? 24 : 0)))
|
||||
#define HC_VERSION(ehci, p) (0xffff&((p) >> /* bits 31:16 / offset 02h */ \
|
||||
(ehci_big_endian_capbase(ehci) ? 0 : 16)))
|
||||
u32 hcs_params; /* HCSPARAMS - offset 0x4 */
|
||||
#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */
|
||||
#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */
|
||||
#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
|
||||
#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */
|
||||
#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */
|
||||
#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */
|
||||
#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
|
||||
#define HCS_N_PORTS_MAX 15 /* N_PORTS valid 0x1-0xF */
|
||||
|
||||
u32 hcc_params; /* HCCPARAMS - offset 0x8 */
|
||||
/* EHCI 1.1 addendum */
|
||||
#define HCC_32FRAME_PERIODIC_LIST(p) ((p)&(1 << 19))
|
||||
#define HCC_PER_PORT_CHANGE_EVENT(p) ((p)&(1 << 18))
|
||||
#define HCC_LPM(p) ((p)&(1 << 17))
|
||||
#define HCC_HW_PREFETCH(p) ((p)&(1 << 16))
|
||||
|
||||
#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
|
||||
#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
|
||||
#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
|
||||
#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
|
||||
#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
|
||||
#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
|
||||
u8 portroute[8]; /* nibbles for routing - offset 0xC */
|
||||
};
|
||||
|
||||
|
||||
/* Section 2.3 Host Controller Operational Registers */
|
||||
struct ehci_regs {
|
||||
|
||||
/* USBCMD: offset 0x00 */
|
||||
u32 command;
|
||||
|
||||
/* EHCI 1.1 addendum */
|
||||
#define CMD_HIRD (0xf<<24) /* host initiated resume duration */
|
||||
#define CMD_PPCEE (1<<15) /* per port change event enable */
|
||||
#define CMD_FSP (1<<14) /* fully synchronized prefetch */
|
||||
#define CMD_ASPE (1<<13) /* async schedule prefetch enable */
|
||||
#define CMD_PSPE (1<<12) /* periodic schedule prefetch enable */
|
||||
/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
|
||||
#define CMD_PARK (1<<11) /* enable "park" on async qh */
|
||||
#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
|
||||
#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */
|
||||
#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
|
||||
#define CMD_ASE (1<<5) /* async schedule enable */
|
||||
#define CMD_PSE (1<<4) /* periodic schedule enable */
|
||||
/* 3:2 is periodic frame list size */
|
||||
#define CMD_RESET (1<<1) /* reset HC not bus */
|
||||
#define CMD_RUN (1<<0) /* start/stop HC */
|
||||
|
||||
/* USBSTS: offset 0x04 */
|
||||
u32 status;
|
||||
#define STS_PPCE_MASK (0xff<<16) /* Per-Port change event 1-16 */
|
||||
#define STS_ASS (1<<15) /* Async Schedule Status */
|
||||
#define STS_PSS (1<<14) /* Periodic Schedule Status */
|
||||
#define STS_RECL (1<<13) /* Reclamation */
|
||||
#define STS_HALT (1<<12) /* Not running (any reason) */
|
||||
/* some bits reserved */
|
||||
/* these STS_* flags are also intr_enable bits (USBINTR) */
|
||||
#define STS_IAA (1<<5) /* Interrupted on async advance */
|
||||
#define STS_FATAL (1<<4) /* such as some PCI access errors */
|
||||
#define STS_FLR (1<<3) /* frame list rolled over */
|
||||
#define STS_PCD (1<<2) /* port change detect */
|
||||
#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
|
||||
#define STS_INT (1<<0) /* "normal" completion (short, ...) */
|
||||
|
||||
/* USBINTR: offset 0x08 */
|
||||
u32 intr_enable;
|
||||
|
||||
/* FRINDEX: offset 0x0C */
|
||||
u32 frame_index; /* current microframe number */
|
||||
/* CTRLDSSEGMENT: offset 0x10 */
|
||||
u32 segment; /* address bits 63:32 if needed */
|
||||
/* PERIODICLISTBASE: offset 0x14 */
|
||||
u32 frame_list; /* points to periodic list */
|
||||
/* ASYNCLISTADDR: offset 0x18 */
|
||||
u32 async_next; /* address of next async queue head */
|
||||
|
||||
u32 reserved1[2];
|
||||
|
||||
/* TXFILLTUNING: offset 0x24 */
|
||||
u32 txfill_tuning; /* TX FIFO Tuning register */
|
||||
#define TXFIFO_DEFAULT (8<<16) /* FIFO burst threshold 8 */
|
||||
|
||||
u32 reserved2[6];
|
||||
|
||||
/* CONFIGFLAG: offset 0x40 */
|
||||
u32 configured_flag;
|
||||
#define FLAG_CF (1<<0) /* true: we'll support "high speed" */
|
||||
|
||||
union {
|
||||
/* PORTSC: offset 0x44 */
|
||||
u32 port_status[HCS_N_PORTS_MAX]; /* up to N_PORTS */
|
||||
/* EHCI 1.1 addendum */
|
||||
#define PORTSC_SUSPEND_STS_ACK 0
|
||||
#define PORTSC_SUSPEND_STS_NYET 1
|
||||
#define PORTSC_SUSPEND_STS_STALL 2
|
||||
#define PORTSC_SUSPEND_STS_ERR 3
|
||||
|
||||
#define PORT_DEV_ADDR (0x7f<<25) /* device address */
|
||||
#define PORT_SSTS (0x3<<23) /* suspend status */
|
||||
/* 31:23 reserved */
|
||||
#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
|
||||
#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
|
||||
#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
|
||||
/* 19:16 for port testing */
|
||||
#define PORT_TEST(x) (((x)&0xf)<<16) /* Port Test Control */
|
||||
#define PORT_TEST_PKT PORT_TEST(0x4) /* Port Test Control - packet test */
|
||||
#define PORT_TEST_FORCE PORT_TEST(0x5) /* Port Test Control - force enable */
|
||||
#define PORT_LED_OFF (0<<14)
|
||||
#define PORT_LED_AMBER (1<<14)
|
||||
#define PORT_LED_GREEN (2<<14)
|
||||
#define PORT_LED_MASK (3<<14)
|
||||
#define PORT_OWNER (1<<13) /* true: companion hc owns this port */
|
||||
#define PORT_POWER (1<<12) /* true: has power (see PPC) */
|
||||
#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
|
||||
#define PORT_LS_MASK (3<<10) /* Link status (SE0, K or J */
|
||||
/* 9 reserved */
|
||||
#define PORT_LPM (1<<9) /* LPM transaction */
|
||||
#define PORT_RESET (1<<8) /* reset port */
|
||||
#define PORT_SUSPEND (1<<7) /* suspend port */
|
||||
#define PORT_RESUME (1<<6) /* resume it */
|
||||
#define PORT_OCC (1<<5) /* over current change */
|
||||
#define PORT_OC (1<<4) /* over current active */
|
||||
#define PORT_PEC (1<<3) /* port enable change */
|
||||
#define PORT_PE (1<<2) /* port enable */
|
||||
#define PORT_CSC (1<<1) /* connect status change */
|
||||
#define PORT_CONNECT (1<<0) /* device connected */
|
||||
#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
|
||||
struct {
|
||||
u32 reserved3[9];
|
||||
/* USBMODE: offset 0x68 */
|
||||
u32 usbmode; /* USB Device mode */
|
||||
};
|
||||
#define USBMODE_SDIS (1<<3) /* Stream disable */
|
||||
#define USBMODE_BE (1<<2) /* BE/LE endianness select */
|
||||
#define USBMODE_CM_HC (3<<0) /* host controller mode */
|
||||
#define USBMODE_CM_IDLE (0<<0) /* idle state */
|
||||
};
|
||||
|
||||
/* Moorestown has some non-standard registers, partially due to the fact that
|
||||
* its EHCI controller has both TT and LPM support. HOSTPCx are extensions to
|
||||
* PORTSCx
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
u32 reserved4;
|
||||
/* HOSTPC: offset 0x84 */
|
||||
u32 hostpc[HCS_N_PORTS_MAX];
|
||||
#define HOSTPC_PHCD (1<<22) /* Phy clock disable */
|
||||
#define HOSTPC_PSPD (3<<25) /* Port speed detection */
|
||||
};
|
||||
|
||||
/* Broadcom-proprietary USB_EHCI_INSNREG00 @ 0x80 */
|
||||
u32 brcm_insnreg[4];
|
||||
};
|
||||
|
||||
u32 reserved5[2];
|
||||
|
||||
/* USBMODE_EX: offset 0xc8 */
|
||||
u32 usbmode_ex; /* USB Device mode extension */
|
||||
#define USBMODE_EX_VBPS (1<<5) /* VBus Power Select On */
|
||||
#define USBMODE_EX_HC (3<<0) /* host controller mode */
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_EHCI_DEF_H */
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*/
|
||||
|
||||
#ifndef __USB_CORE_EHCI_PDRIVER_H
|
||||
#define __USB_CORE_EHCI_PDRIVER_H
|
||||
|
||||
struct platform_device;
|
||||
struct usb_hcd;
|
||||
|
||||
/**
|
||||
* struct usb_ehci_pdata - platform_data for generic ehci driver
|
||||
*
|
||||
* @caps_offset: offset of the EHCI Capability Registers to the start of
|
||||
* the io memory region provided to the driver.
|
||||
* @has_tt: set to 1 if TT is integrated in root hub.
|
||||
* @port_power_on: set to 1 if the controller needs a power up after
|
||||
* initialization.
|
||||
* @port_power_off: set to 1 if the controller needs to be powered down
|
||||
* after initialization.
|
||||
* @no_io_watchdog: set to 1 if the controller does not need the I/O
|
||||
* watchdog to run.
|
||||
* @reset_on_resume: set to 1 if the controller needs to be reset after
|
||||
* a suspend / resume cycle (but can't detect that itself).
|
||||
*
|
||||
* These are general configuration options for the EHCI controller. All of
|
||||
* these options are activating more or less workarounds for some hardware.
|
||||
*/
|
||||
struct usb_ehci_pdata {
|
||||
int caps_offset;
|
||||
unsigned has_tt:1;
|
||||
unsigned has_synopsys_hc_bug:1;
|
||||
unsigned big_endian_desc:1;
|
||||
unsigned big_endian_mmio:1;
|
||||
unsigned no_io_watchdog:1;
|
||||
unsigned reset_on_resume:1;
|
||||
unsigned dma_mask_64:1;
|
||||
unsigned spurious_oc:1;
|
||||
|
||||
/* Turn on all power and clocks */
|
||||
int (*power_on)(struct platform_device *pdev);
|
||||
/* Turn off all power and clocks */
|
||||
void (*power_off)(struct platform_device *pdev);
|
||||
/* Turn on only VBUS suspend power and hotplug detection,
|
||||
* turn off everything else */
|
||||
void (*power_suspend)(struct platform_device *pdev);
|
||||
int (*pre_setup)(struct usb_hcd *hcd);
|
||||
};
|
||||
|
||||
#endif /* __USB_CORE_EHCI_PDRIVER_H */
|
||||
@@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __EZUSB_H
|
||||
#define __EZUSB_H
|
||||
|
||||
extern int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit);
|
||||
extern int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
|
||||
const char *firmware_path);
|
||||
|
||||
#endif /* __EZUSB_H */
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* func_utils.h
|
||||
*
|
||||
* Utility definitions for USB functions
|
||||
*
|
||||
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _FUNC_UTILS_H_
|
||||
#define _FUNC_UTILS_H_
|
||||
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
/* Variable Length Array Macros **********************************************/
|
||||
#define vla_group(groupname) size_t groupname##__next = 0
|
||||
#define vla_group_size(groupname) groupname##__next
|
||||
|
||||
#define vla_item(groupname, type, name, n) \
|
||||
size_t groupname##_##name##__offset = ({ \
|
||||
size_t offset = 0; \
|
||||
if (groupname##__next != SIZE_MAX) { \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
size_t size = array_size(n, sizeof(type)); \
|
||||
offset = (groupname##__next + align_mask) & \
|
||||
~align_mask; \
|
||||
if (check_add_overflow(offset, size, \
|
||||
&groupname##__next)) { \
|
||||
groupname##__next = SIZE_MAX; \
|
||||
offset = 0; \
|
||||
} \
|
||||
} \
|
||||
offset; \
|
||||
})
|
||||
|
||||
#define vla_item_with_sz(groupname, type, name, n) \
|
||||
size_t groupname##_##name##__sz = array_size(n, sizeof(type)); \
|
||||
size_t groupname##_##name##__offset = ({ \
|
||||
size_t offset = 0; \
|
||||
if (groupname##__next != SIZE_MAX) { \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
offset = (groupname##__next + align_mask) & \
|
||||
~align_mask; \
|
||||
if (check_add_overflow(offset, groupname##_##name##__sz,\
|
||||
&groupname##__next)) { \
|
||||
groupname##__next = SIZE_MAX; \
|
||||
offset = 0; \
|
||||
} \
|
||||
} \
|
||||
offset; \
|
||||
})
|
||||
|
||||
#define vla_ptr(ptr, groupname, name) \
|
||||
((void *) ((char *)ptr + groupname##_##name##__offset))
|
||||
|
||||
struct usb_ep;
|
||||
struct usb_request;
|
||||
|
||||
/**
|
||||
* alloc_ep_req - returns a usb_request allocated by the gadget driver and
|
||||
* allocates the request's buffer.
|
||||
*
|
||||
* @ep: the endpoint to allocate a usb_request
|
||||
* @len: usb_requests's buffer suggested size
|
||||
*
|
||||
* In case @ep direction is OUT, the @len will be aligned to ep's
|
||||
* wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
|
||||
* usb_requests's length (req->length) to refer to the allocated buffer size.
|
||||
* Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
|
||||
*/
|
||||
struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len);
|
||||
|
||||
/* Frees a usb_request previously allocated by alloc_ep_req() */
|
||||
static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
WARN_ON(req->buf == NULL);
|
||||
kfree(req->buf);
|
||||
req->buf = NULL;
|
||||
usb_ep_free_request(ep, req);
|
||||
}
|
||||
|
||||
#endif /* _FUNC_UTILS_H_ */
|
||||
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_FUNCTIONFS_H__
|
||||
#define __LINUX_FUNCTIONFS_H__ 1
|
||||
|
||||
#include <uapi/linux/usb/functionfs.h>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* g_hid.h -- Header file for USB HID gadget driver
|
||||
*
|
||||
* Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_G_HID_H
|
||||
#define __LINUX_USB_G_HID_H
|
||||
|
||||
struct hidg_func_descriptor {
|
||||
unsigned char subclass;
|
||||
unsigned char protocol;
|
||||
unsigned short report_length;
|
||||
unsigned short report_desc_length;
|
||||
unsigned char report_desc[];
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_G_HID_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __GADGET_CONFIGFS__
|
||||
#define __GADGET_CONFIGFS__
|
||||
|
||||
#include <linux/configfs.h>
|
||||
|
||||
#define GS_STRINGS_W(__struct, __name) \
|
||||
static ssize_t __struct##_##__name##_store(struct config_item *item, \
|
||||
const char *page, size_t len) \
|
||||
{ \
|
||||
struct __struct *gs = to_##__struct(item); \
|
||||
int ret; \
|
||||
\
|
||||
ret = usb_string_copy(page, &gs->__name); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
return len; \
|
||||
}
|
||||
|
||||
#define GS_STRINGS_R(__struct, __name) \
|
||||
static ssize_t __struct##_##__name##_show(struct config_item *item, char *page) \
|
||||
{ \
|
||||
struct __struct *gs = to_##__struct(item); \
|
||||
return sprintf(page, "%s\n", gs->__name ?: ""); \
|
||||
}
|
||||
|
||||
#define GS_STRINGS_RW(struct_name, _name) \
|
||||
GS_STRINGS_R(struct_name, _name) \
|
||||
GS_STRINGS_W(struct_name, _name) \
|
||||
CONFIGFS_ATTR(struct_name##_, _name)
|
||||
|
||||
#define USB_CONFIG_STRING_RW_OPS(struct_in) \
|
||||
static const struct configfs_item_operations struct_in##_langid_item_ops = { \
|
||||
.release = struct_in##_attr_release, \
|
||||
}; \
|
||||
\
|
||||
static const struct config_item_type struct_in##_langid_type = { \
|
||||
.ct_item_ops = &struct_in##_langid_item_ops, \
|
||||
.ct_attrs = struct_in##_langid_attrs, \
|
||||
.ct_owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#define USB_CONFIG_STRINGS_LANG(struct_in, struct_member) \
|
||||
static struct config_group *struct_in##_strings_make( \
|
||||
struct config_group *group, \
|
||||
const char *name) \
|
||||
{ \
|
||||
struct struct_member *gi; \
|
||||
struct struct_in *gs; \
|
||||
struct struct_in *new; \
|
||||
int langs = 0; \
|
||||
int ret; \
|
||||
\
|
||||
new = kzalloc(sizeof(*new), GFP_KERNEL); \
|
||||
if (!new) \
|
||||
return ERR_PTR(-ENOMEM); \
|
||||
\
|
||||
ret = check_user_usb_string(name, &new->stringtab_dev); \
|
||||
if (ret) \
|
||||
goto err; \
|
||||
config_group_init_type_name(&new->group, name, \
|
||||
&struct_in##_langid_type); \
|
||||
\
|
||||
gi = container_of(group, struct struct_member, strings_group); \
|
||||
ret = -EEXIST; \
|
||||
list_for_each_entry(gs, &gi->string_list, list) { \
|
||||
if (gs->stringtab_dev.language == new->stringtab_dev.language) \
|
||||
goto err; \
|
||||
langs++; \
|
||||
} \
|
||||
ret = -EOVERFLOW; \
|
||||
if (langs >= MAX_USB_STRING_LANGS) \
|
||||
goto err; \
|
||||
\
|
||||
list_add_tail(&new->list, &gi->string_list); \
|
||||
return &new->group; \
|
||||
err: \
|
||||
kfree(new); \
|
||||
return ERR_PTR(ret); \
|
||||
} \
|
||||
\
|
||||
static void struct_in##_strings_drop( \
|
||||
struct config_group *group, \
|
||||
struct config_item *item) \
|
||||
{ \
|
||||
config_item_put(item); \
|
||||
} \
|
||||
\
|
||||
static const struct configfs_group_operations struct_in##_strings_ops = { \
|
||||
.make_group = &struct_in##_strings_make, \
|
||||
.drop_item = &struct_in##_strings_drop, \
|
||||
}; \
|
||||
\
|
||||
static const struct config_item_type struct_in##_strings_type = { \
|
||||
.ct_group_ops = &struct_in##_strings_ops, \
|
||||
.ct_owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,765 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2001-2002 by David Brownell
|
||||
*/
|
||||
|
||||
#ifndef __USB_CORE_HCD_H
|
||||
#define __USB_CORE_HCD_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/idr.h>
|
||||
|
||||
#define MAX_TOPO_LEVEL 6
|
||||
|
||||
/* This file contains declarations of usbcore internals that are mostly
|
||||
* used or exposed by Host Controller Drivers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* USB Packet IDs (PIDs)
|
||||
*/
|
||||
#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */
|
||||
#define USB_PID_OUT 0xe1
|
||||
#define USB_PID_ACK 0xd2
|
||||
#define USB_PID_DATA0 0xc3
|
||||
#define USB_PID_PING 0xb4 /* USB 2.0 */
|
||||
#define USB_PID_SOF 0xa5
|
||||
#define USB_PID_NYET 0x96 /* USB 2.0 */
|
||||
#define USB_PID_DATA2 0x87 /* USB 2.0 */
|
||||
#define USB_PID_SPLIT 0x78 /* USB 2.0 */
|
||||
#define USB_PID_IN 0x69
|
||||
#define USB_PID_NAK 0x5a
|
||||
#define USB_PID_DATA1 0x4b
|
||||
#define USB_PID_PREAMBLE 0x3c /* Token mode */
|
||||
#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
|
||||
#define USB_PID_SETUP 0x2d
|
||||
#define USB_PID_STALL 0x1e
|
||||
#define USB_PID_MDATA 0x0f /* USB 2.0 */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* USB Host Controller Driver (usb_hcd) framework
|
||||
*
|
||||
* Since "struct usb_bus" is so thin, you can't share much code in it.
|
||||
* This framework is a layer over that, and should be more shareable.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
struct giveback_urb_bh {
|
||||
bool running;
|
||||
bool high_prio;
|
||||
spinlock_t lock;
|
||||
struct list_head head;
|
||||
struct work_struct bh;
|
||||
struct usb_host_endpoint *completing_ep;
|
||||
};
|
||||
|
||||
enum usb_dev_authorize_policy {
|
||||
USB_DEVICE_AUTHORIZE_NONE = 0,
|
||||
USB_DEVICE_AUTHORIZE_ALL = 1,
|
||||
USB_DEVICE_AUTHORIZE_INTERNAL = 2,
|
||||
};
|
||||
|
||||
struct usb_hcd {
|
||||
|
||||
/*
|
||||
* housekeeping
|
||||
*/
|
||||
struct usb_bus self; /* hcd is-a bus */
|
||||
struct kref kref; /* reference counter */
|
||||
|
||||
const char *product_desc; /* product/vendor string */
|
||||
int speed; /* Speed for this roothub.
|
||||
* May be different from
|
||||
* hcd->driver->flags & HCD_MASK
|
||||
*/
|
||||
char irq_descr[24]; /* driver + bus # */
|
||||
|
||||
struct timer_list rh_timer; /* drives root-hub polling */
|
||||
struct urb *status_urb; /* the current status urb */
|
||||
#ifdef CONFIG_PM
|
||||
struct work_struct wakeup_work; /* for remote wakeup */
|
||||
#endif
|
||||
struct work_struct died_work; /* for when the device dies */
|
||||
|
||||
/*
|
||||
* hardware info/state
|
||||
*/
|
||||
const struct hc_driver *driver; /* hw-specific hooks */
|
||||
|
||||
/*
|
||||
* OTG and some Host controllers need software interaction with phys;
|
||||
* other external phys should be software-transparent
|
||||
*/
|
||||
struct usb_phy *usb_phy;
|
||||
struct usb_phy_roothub *phy_roothub;
|
||||
|
||||
/* Flags that need to be manipulated atomically because they can
|
||||
* change while the host controller is running. Always use
|
||||
* set_bit() or clear_bit() to change their values.
|
||||
*/
|
||||
unsigned long flags;
|
||||
#define HCD_FLAG_HW_ACCESSIBLE 0 /* at full power */
|
||||
#define HCD_FLAG_POLL_RH 2 /* poll for rh status? */
|
||||
#define HCD_FLAG_POLL_PENDING 3 /* status has changed? */
|
||||
#define HCD_FLAG_WAKEUP_PENDING 4 /* root hub is resuming? */
|
||||
#define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */
|
||||
#define HCD_FLAG_DEAD 6 /* controller has died? */
|
||||
#define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */
|
||||
#define HCD_FLAG_DEFER_RH_REGISTER 8 /* Defer roothub registration */
|
||||
|
||||
/* The flags can be tested using these macros; they are likely to
|
||||
* be slightly faster than test_bit().
|
||||
*/
|
||||
#define HCD_HW_ACCESSIBLE(hcd) ((hcd)->flags & (1U << HCD_FLAG_HW_ACCESSIBLE))
|
||||
#define HCD_POLL_RH(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_RH))
|
||||
#define HCD_POLL_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING))
|
||||
#define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING))
|
||||
#define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING))
|
||||
#define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD))
|
||||
#define HCD_DEFER_RH_REGISTER(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEFER_RH_REGISTER))
|
||||
|
||||
/*
|
||||
* Specifies if interfaces are authorized by default
|
||||
* or they require explicit user space authorization; this bit is
|
||||
* settable through /sys/class/usb_host/X/interface_authorized_default
|
||||
*/
|
||||
#define HCD_INTF_AUTHORIZED(hcd) \
|
||||
((hcd)->flags & (1U << HCD_FLAG_INTF_AUTHORIZED))
|
||||
|
||||
/*
|
||||
* Specifies if devices are authorized by default
|
||||
* or they require explicit user space authorization; this bit is
|
||||
* settable through /sys/class/usb_host/X/authorized_default
|
||||
*/
|
||||
enum usb_dev_authorize_policy dev_policy;
|
||||
|
||||
/* Flags that get set only during HCD registration or removal. */
|
||||
unsigned rh_registered:1;/* is root hub registered? */
|
||||
unsigned rh_pollable:1; /* may we poll the root hub? */
|
||||
unsigned msix_enabled:1; /* driver has MSI-X enabled? */
|
||||
unsigned msi_enabled:1; /* driver has MSI enabled? */
|
||||
/*
|
||||
* do not manage the PHY state in the HCD core, instead let the driver
|
||||
* handle this (for example if the PHY can only be turned on after a
|
||||
* specific event)
|
||||
*/
|
||||
unsigned skip_phy_initialization:1;
|
||||
|
||||
/* The next flag is a stopgap, to be removed when all the HCDs
|
||||
* support the new root-hub polling mechanism. */
|
||||
unsigned uses_new_polling:1;
|
||||
unsigned has_tt:1; /* Integrated TT in root hub */
|
||||
unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */
|
||||
unsigned can_do_streams:1; /* HC supports streams */
|
||||
unsigned tpl_support:1; /* OTG & EH TPL support */
|
||||
unsigned cant_recv_wakeups:1;
|
||||
/* wakeup requests from downstream aren't received */
|
||||
|
||||
unsigned int irq; /* irq allocated */
|
||||
void __iomem *regs; /* device memory/io */
|
||||
resource_size_t rsrc_start; /* memory/io resource start */
|
||||
resource_size_t rsrc_len; /* memory/io resource length */
|
||||
unsigned power_budget; /* in mA, 0 = no limit */
|
||||
|
||||
struct giveback_urb_bh high_prio_bh;
|
||||
struct giveback_urb_bh low_prio_bh;
|
||||
|
||||
/* bandwidth_mutex should be taken before adding or removing
|
||||
* any new bus bandwidth constraints:
|
||||
* 1. Before adding a configuration for a new device.
|
||||
* 2. Before removing the configuration to put the device into
|
||||
* the addressed state.
|
||||
* 3. Before selecting a different configuration.
|
||||
* 4. Before selecting an alternate interface setting.
|
||||
*
|
||||
* bandwidth_mutex should be dropped after a successful control message
|
||||
* to the device, or resetting the bandwidth after a failed attempt.
|
||||
*/
|
||||
struct mutex *address0_mutex;
|
||||
struct mutex *bandwidth_mutex;
|
||||
struct usb_hcd *shared_hcd;
|
||||
struct usb_hcd *primary_hcd;
|
||||
|
||||
|
||||
#define HCD_BUFFER_POOLS 4
|
||||
struct dma_pool *pool[HCD_BUFFER_POOLS];
|
||||
|
||||
int state;
|
||||
# define __ACTIVE 0x01
|
||||
# define __SUSPEND 0x04
|
||||
# define __TRANSIENT 0x80
|
||||
|
||||
# define HC_STATE_HALT 0
|
||||
# define HC_STATE_RUNNING (__ACTIVE)
|
||||
# define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
|
||||
# define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
|
||||
# define HC_STATE_SUSPENDED (__SUSPEND)
|
||||
|
||||
#define HC_IS_RUNNING(state) ((state) & __ACTIVE)
|
||||
#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
|
||||
|
||||
/* memory pool for HCs having local memory, or %NULL */
|
||||
struct gen_pool *localmem_pool;
|
||||
|
||||
/* more shared queuing code would be good; it should support
|
||||
* smarter scheduling, handle transaction translators, etc;
|
||||
* input size of periodic table to an interrupt scheduler.
|
||||
* (ohci 32, uhci 1024, ehci 256/512/1024).
|
||||
*/
|
||||
|
||||
/* The HC driver's private data is stored at the end of
|
||||
* this structure.
|
||||
*/
|
||||
unsigned long hcd_priv[]
|
||||
__attribute__ ((aligned(sizeof(s64))));
|
||||
};
|
||||
|
||||
/* 2.4 does this a bit differently ... */
|
||||
static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd)
|
||||
{
|
||||
return &hcd->self;
|
||||
}
|
||||
|
||||
static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
|
||||
{
|
||||
return container_of(bus, struct usb_hcd, self);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
struct hc_driver {
|
||||
const char *description; /* "ehci-hcd" etc */
|
||||
const char *product_desc; /* product/vendor string */
|
||||
size_t hcd_priv_size; /* size of private data */
|
||||
|
||||
/* irq handler */
|
||||
irqreturn_t (*irq) (struct usb_hcd *hcd);
|
||||
|
||||
int flags;
|
||||
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
|
||||
#define HCD_DMA 0x0002 /* HC uses DMA */
|
||||
#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
|
||||
#define HCD_USB11 0x0010 /* USB 1.1 */
|
||||
#define HCD_USB2 0x0020 /* USB 2.0 */
|
||||
#define HCD_USB3 0x0040 /* USB 3.0 */
|
||||
#define HCD_USB31 0x0050 /* USB 3.1 */
|
||||
#define HCD_USB32 0x0060 /* USB 3.2 */
|
||||
#define HCD_MASK 0x0070
|
||||
#define HCD_BH 0x0100 /* URB complete in BH context */
|
||||
|
||||
/* called to init HCD and root hub */
|
||||
int (*reset) (struct usb_hcd *hcd);
|
||||
int (*start) (struct usb_hcd *hcd);
|
||||
|
||||
/* NOTE: these suspend/resume calls relate to the HC as
|
||||
* a whole, not just the root hub; they're for PCI bus glue.
|
||||
*/
|
||||
/* called after suspending the hub, before entering D3 etc */
|
||||
int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);
|
||||
|
||||
/* called after entering D0 (etc), before resuming the hub */
|
||||
int (*pci_resume)(struct usb_hcd *hcd, pm_message_t state);
|
||||
|
||||
/* called just before hibernate final D3 state, allows host to poweroff parts */
|
||||
int (*pci_poweroff_late)(struct usb_hcd *hcd, bool do_wakeup);
|
||||
|
||||
/* cleanly make HCD stop writing memory and doing I/O */
|
||||
void (*stop) (struct usb_hcd *hcd);
|
||||
|
||||
/* shutdown HCD */
|
||||
void (*shutdown) (struct usb_hcd *hcd);
|
||||
|
||||
/* return current frame number */
|
||||
int (*get_frame_number) (struct usb_hcd *hcd);
|
||||
|
||||
/* manage i/o requests, device state */
|
||||
int (*urb_enqueue)(struct usb_hcd *hcd,
|
||||
struct urb *urb, gfp_t mem_flags);
|
||||
int (*urb_dequeue)(struct usb_hcd *hcd,
|
||||
struct urb *urb, int status);
|
||||
|
||||
/*
|
||||
* (optional) these hooks allow an HCD to override the default DMA
|
||||
* mapping and unmapping routines. In general, they shouldn't be
|
||||
* necessary unless the host controller has special DMA requirements,
|
||||
* such as alignment constraints. If these are not specified, the
|
||||
* general usb_hcd_(un)?map_urb_for_dma functions will be used instead
|
||||
* (and it may be a good idea to call these functions in your HCD
|
||||
* implementation)
|
||||
*/
|
||||
int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,
|
||||
gfp_t mem_flags);
|
||||
void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);
|
||||
|
||||
/* hw synch, freeing endpoint resources that urb_dequeue can't */
|
||||
void (*endpoint_disable)(struct usb_hcd *hcd,
|
||||
struct usb_host_endpoint *ep);
|
||||
|
||||
/* (optional) reset any endpoint state such as sequence number
|
||||
and current window */
|
||||
void (*endpoint_reset)(struct usb_hcd *hcd,
|
||||
struct usb_host_endpoint *ep);
|
||||
|
||||
/* root hub support */
|
||||
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
|
||||
int (*hub_control) (struct usb_hcd *hcd,
|
||||
u16 typeReq, u16 wValue, u16 wIndex,
|
||||
char *buf, u16 wLength);
|
||||
int (*bus_suspend)(struct usb_hcd *);
|
||||
int (*bus_resume)(struct usb_hcd *);
|
||||
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
|
||||
unsigned long (*get_resuming_ports)(struct usb_hcd *);
|
||||
|
||||
/* force handover of high-speed port to full-speed companion */
|
||||
void (*relinquish_port)(struct usb_hcd *, int);
|
||||
/* has a port been handed over to a companion? */
|
||||
int (*port_handed_over)(struct usb_hcd *, int);
|
||||
|
||||
/* CLEAR_TT_BUFFER completion callback */
|
||||
void (*clear_tt_buffer_complete)(struct usb_hcd *,
|
||||
struct usb_host_endpoint *);
|
||||
|
||||
/* xHCI specific functions */
|
||||
/* Called by usb_alloc_dev to alloc HC device structures */
|
||||
int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
|
||||
/* Called by usb_disconnect to free HC device structures */
|
||||
void (*free_dev)(struct usb_hcd *, struct usb_device *);
|
||||
/* Change a group of bulk endpoints to support multiple stream IDs */
|
||||
int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
struct usb_host_endpoint **eps, unsigned int num_eps,
|
||||
unsigned int num_streams, gfp_t mem_flags);
|
||||
/* Reverts a group of bulk endpoints back to not using stream IDs.
|
||||
* Can fail if we run out of memory.
|
||||
*/
|
||||
int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
struct usb_host_endpoint **eps, unsigned int num_eps,
|
||||
gfp_t mem_flags);
|
||||
|
||||
/* Bandwidth computation functions */
|
||||
/* Note that add_endpoint() can only be called once per endpoint before
|
||||
* check_bandwidth() or reset_bandwidth() must be called.
|
||||
* drop_endpoint() can only be called once per endpoint also.
|
||||
* A call to xhci_drop_endpoint() followed by a call to
|
||||
* xhci_add_endpoint() will add the endpoint to the schedule with
|
||||
* possibly new parameters denoted by a different endpoint descriptor
|
||||
* in usb_host_endpoint. A call to xhci_add_endpoint() followed by a
|
||||
* call to xhci_drop_endpoint() is not allowed.
|
||||
*/
|
||||
/* Allocate endpoint resources and add them to a new schedule */
|
||||
int (*add_endpoint)(struct usb_hcd *, struct usb_device *,
|
||||
struct usb_host_endpoint *);
|
||||
/* Drop an endpoint from a new schedule */
|
||||
int (*drop_endpoint)(struct usb_hcd *, struct usb_device *,
|
||||
struct usb_host_endpoint *);
|
||||
/* Check that a new hardware configuration, set using
|
||||
* endpoint_enable and endpoint_disable, does not exceed bus
|
||||
* bandwidth. This must be called before any set configuration
|
||||
* or set interface requests are sent to the device.
|
||||
*/
|
||||
int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
|
||||
/* Reset the device schedule to the last known good schedule,
|
||||
* which was set from a previous successful call to
|
||||
* check_bandwidth(). This reverts any add_endpoint() and
|
||||
* drop_endpoint() calls since that last successful call.
|
||||
* Used for when a check_bandwidth() call fails due to resource
|
||||
* or bandwidth constraints.
|
||||
*/
|
||||
void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
|
||||
/* Set the hardware-chosen device address */
|
||||
int (*address_device)(struct usb_hcd *, struct usb_device *udev,
|
||||
unsigned int timeout_ms);
|
||||
/* prepares the hardware to send commands to the device */
|
||||
int (*enable_device)(struct usb_hcd *, struct usb_device *udev);
|
||||
/* Notifies the HCD after a hub descriptor is fetched.
|
||||
* Will block.
|
||||
*/
|
||||
int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,
|
||||
struct usb_tt *tt, gfp_t mem_flags);
|
||||
int (*reset_device)(struct usb_hcd *, struct usb_device *);
|
||||
/* Notifies the HCD after a device is connected and its
|
||||
* address is set
|
||||
*/
|
||||
int (*update_device)(struct usb_hcd *, struct usb_device *);
|
||||
int (*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int);
|
||||
/* USB 3.0 Link Power Management */
|
||||
/* Returns the USB3 hub-encoded value for the U1/U2 timeout. */
|
||||
int (*enable_usb3_lpm_timeout)(struct usb_hcd *,
|
||||
struct usb_device *, enum usb3_link_state state);
|
||||
/* The xHCI host controller can still fail the command to
|
||||
* disable the LPM timeouts, so this can return an error code.
|
||||
*/
|
||||
int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
|
||||
struct usb_device *, enum usb3_link_state state);
|
||||
int (*find_raw_port_number)(struct usb_hcd *, int);
|
||||
/* Call for power on/off the port if necessary */
|
||||
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
|
||||
/* Call for SINGLE_STEP_SET_FEATURE Test for USB2 EH certification */
|
||||
#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
|
||||
int (*submit_single_step_set_feature)(struct usb_hcd *,
|
||||
struct urb *, int);
|
||||
};
|
||||
|
||||
static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
|
||||
{
|
||||
return hcd->driver->flags & HCD_BH;
|
||||
}
|
||||
|
||||
static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
return hcd->high_prio_bh.completing_ep == ep;
|
||||
}
|
||||
|
||||
static inline bool hcd_uses_dma(struct usb_hcd *hcd)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_HAS_DMA) && (hcd->driver->flags & HCD_DMA);
|
||||
}
|
||||
|
||||
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
|
||||
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
|
||||
int status);
|
||||
extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);
|
||||
|
||||
extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags);
|
||||
extern int usb_hcd_unlink_urb(struct urb *urb, int status);
|
||||
extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
|
||||
int status);
|
||||
extern int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
|
||||
gfp_t mem_flags);
|
||||
extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *);
|
||||
extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *);
|
||||
extern void usb_hcd_flush_endpoint(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep);
|
||||
extern void usb_hcd_disable_endpoint(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep);
|
||||
extern void usb_hcd_reset_endpoint(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep);
|
||||
extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
|
||||
extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
|
||||
struct usb_host_config *new_config,
|
||||
struct usb_host_interface *old_alt,
|
||||
struct usb_host_interface *new_alt);
|
||||
extern int usb_hcd_get_frame_number(struct usb_device *udev);
|
||||
|
||||
struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
|
||||
struct device *sysdev, struct device *dev, const char *bus_name,
|
||||
struct usb_hcd *primary_hcd);
|
||||
extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
|
||||
struct device *dev, const char *bus_name);
|
||||
extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
|
||||
struct device *dev, const char *bus_name,
|
||||
struct usb_hcd *shared_hcd);
|
||||
extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd);
|
||||
extern void usb_put_hcd(struct usb_hcd *hcd);
|
||||
extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
|
||||
extern int usb_add_hcd(struct usb_hcd *hcd,
|
||||
unsigned int irqnum, unsigned long irqflags);
|
||||
extern void usb_remove_hcd(struct usb_hcd *hcd);
|
||||
extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
|
||||
int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
|
||||
dma_addr_t dma, size_t size);
|
||||
|
||||
struct platform_device;
|
||||
extern void usb_hcd_platform_shutdown(struct platform_device *dev);
|
||||
#ifdef CONFIG_USB_HCD_TEST_MODE
|
||||
extern int ehset_single_step_set_feature(struct usb_hcd *hcd, int port);
|
||||
#else
|
||||
static inline int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_USB_HCD_TEST_MODE */
|
||||
|
||||
#ifdef CONFIG_USB_PCI
|
||||
struct pci_dev;
|
||||
struct pci_device_id;
|
||||
extern int usb_hcd_pci_probe(struct pci_dev *dev,
|
||||
const struct hc_driver *driver);
|
||||
extern void usb_hcd_pci_remove(struct pci_dev *dev);
|
||||
extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
|
||||
|
||||
#ifdef CONFIG_USB_PCI_AMD
|
||||
extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
|
||||
|
||||
static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev,
|
||||
const struct hc_driver *driver)
|
||||
{
|
||||
if (!usb_hcd_amd_remote_wakeup_quirk(dev))
|
||||
return false;
|
||||
if (driver->flags & (HCD_USB11 | HCD_USB3))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#else /* CONFIG_USB_PCI_AMD */
|
||||
static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev,
|
||||
const struct hc_driver *driver)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
|
||||
#endif /* CONFIG_USB_PCI */
|
||||
|
||||
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
|
||||
void usb_init_pool_max(void);
|
||||
int hcd_buffer_create(struct usb_hcd *hcd);
|
||||
void hcd_buffer_destroy(struct usb_hcd *hcd);
|
||||
|
||||
void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
|
||||
gfp_t mem_flags, dma_addr_t *dma);
|
||||
void hcd_buffer_free(struct usb_bus *bus, size_t size,
|
||||
void *addr, dma_addr_t dma);
|
||||
|
||||
void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
|
||||
size_t size, gfp_t mem_flags, dma_addr_t *dma);
|
||||
void hcd_buffer_free_pages(struct usb_hcd *hcd,
|
||||
size_t size, void *addr, dma_addr_t dma);
|
||||
|
||||
/* generic bus glue, needed for host controllers that don't use PCI */
|
||||
extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
|
||||
|
||||
extern void usb_hc_died(struct usb_hcd *hcd);
|
||||
extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
|
||||
extern void usb_wakeup_notification(struct usb_device *hdev,
|
||||
unsigned int portnum);
|
||||
|
||||
extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum);
|
||||
extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum);
|
||||
|
||||
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
|
||||
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
|
||||
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
|
||||
#define usb_settoggle(dev, ep, out, bit) \
|
||||
((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
|
||||
((bit) << (ep)))
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
|
||||
extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
|
||||
struct usb_bus *, unsigned port);
|
||||
extern int usb_new_device(struct usb_device *dev);
|
||||
extern void usb_disconnect(struct usb_device **);
|
||||
|
||||
extern int usb_get_configuration(struct usb_device *dev);
|
||||
extern void usb_destroy_configuration(struct usb_device *dev);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* HCD Root Hub support
|
||||
*/
|
||||
|
||||
#include <linux/usb/ch11.h>
|
||||
|
||||
/*
|
||||
* As of USB 2.0, full/low speed devices are segregated into trees.
|
||||
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
|
||||
* The other type grows from high speed hubs when they connect to
|
||||
* full/low speed devices using "Transaction Translators" (TTs).
|
||||
*
|
||||
* TTs should only be known to the hub driver, and high speed bus
|
||||
* drivers (only EHCI for now). They affect periodic scheduling and
|
||||
* sometimes control/bulk error recovery.
|
||||
*/
|
||||
|
||||
struct usb_device;
|
||||
|
||||
struct usb_tt {
|
||||
struct usb_device *hub; /* upstream highspeed hub */
|
||||
int multi; /* true means one TT per port */
|
||||
unsigned think_time; /* think time in ns */
|
||||
void *hcpriv; /* HCD private data */
|
||||
|
||||
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
|
||||
spinlock_t lock;
|
||||
struct list_head clear_list; /* of usb_tt_clear */
|
||||
struct work_struct clear_work;
|
||||
};
|
||||
|
||||
struct usb_tt_clear {
|
||||
struct list_head clear_list;
|
||||
unsigned tt;
|
||||
u16 devinfo;
|
||||
struct usb_hcd *hcd;
|
||||
struct usb_host_endpoint *ep;
|
||||
};
|
||||
|
||||
extern int usb_hub_clear_tt_buffer(struct urb *urb);
|
||||
extern void usb_ep0_reinit(struct usb_device *);
|
||||
|
||||
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
|
||||
#define DeviceRequest \
|
||||
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
|
||||
#define DeviceOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
|
||||
|
||||
#define InterfaceRequest \
|
||||
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
|
||||
|
||||
#define EndpointRequest \
|
||||
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
|
||||
#define EndpointOutRequest \
|
||||
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
|
||||
|
||||
/* class requests from the USB 2.0 hub spec, table 11-15 */
|
||||
#define HUB_CLASS_REQ(dir, type, request) ((((dir) | (type)) << 8) | (request))
|
||||
/* GetBusState and SetHubDescriptor are optional, omitted */
|
||||
#define ClearHubFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, USB_REQ_CLEAR_FEATURE)
|
||||
#define ClearPortFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, USB_REQ_CLEAR_FEATURE)
|
||||
#define GetHubDescriptor HUB_CLASS_REQ(USB_DIR_IN, USB_RT_HUB, USB_REQ_GET_DESCRIPTOR)
|
||||
#define GetHubStatus HUB_CLASS_REQ(USB_DIR_IN, USB_RT_HUB, USB_REQ_GET_STATUS)
|
||||
#define GetPortStatus HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, USB_REQ_GET_STATUS)
|
||||
#define SetHubFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, USB_REQ_SET_FEATURE)
|
||||
#define SetPortFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, USB_REQ_SET_FEATURE)
|
||||
#define ClearTTBuffer HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_CLEAR_TT_BUFFER)
|
||||
#define ResetTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_RESET_TT)
|
||||
#define GetTTState HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, HUB_GET_TT_STATE)
|
||||
#define StopTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_STOP_TT)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* class requests from USB 3.1 hub spec, table 10-7 */
|
||||
#define SetHubDepth HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, HUB_SET_DEPTH)
|
||||
#define GetPortErrorCount HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, HUB_GET_PORT_ERR_COUNT)
|
||||
|
||||
/*
|
||||
* Generic bandwidth allocation constants/support
|
||||
*/
|
||||
#define FRAME_TIME_USECS 1000L
|
||||
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
|
||||
/* Trying not to use worst-case bit-stuffing
|
||||
* of (7/6 * 8 * bytecount) = 9.33 * bytecount */
|
||||
/* bytecount = data payload byte count */
|
||||
|
||||
#define NS_TO_US(ns) DIV_ROUND_UP(ns, 1000L)
|
||||
/* convert nanoseconds to microseconds, rounding up */
|
||||
|
||||
/*
|
||||
* Full/low speed bandwidth allocation constants/support.
|
||||
*/
|
||||
#define BW_HOST_DELAY 1000L /* nanoseconds */
|
||||
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
|
||||
/* 4 full-speed bit times (est.) */
|
||||
|
||||
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
|
||||
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
|
||||
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
|
||||
|
||||
/*
|
||||
* Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
|
||||
* ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
|
||||
* to preallocate bandwidth)
|
||||
*/
|
||||
#define USB2_HOST_DELAY 5 /* nsec, guess */
|
||||
#define HS_NSECS(bytes) (((55 * 8 * 2083) \
|
||||
+ (2083UL * (3 + BitTime(bytes))))/1000 \
|
||||
+ USB2_HOST_DELAY)
|
||||
#define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \
|
||||
+ (2083UL * (3 + BitTime(bytes))))/1000 \
|
||||
+ USB2_HOST_DELAY)
|
||||
#define HS_USECS(bytes) NS_TO_US(HS_NSECS(bytes))
|
||||
#define HS_USECS_ISO(bytes) NS_TO_US(HS_NSECS_ISO(bytes))
|
||||
|
||||
extern long usb_calc_bus_time(int speed, int is_input,
|
||||
int isoc, int bytecount);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
extern void usb_set_device_state(struct usb_device *udev,
|
||||
enum usb_device_state new_state);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* exported only within usbcore */
|
||||
|
||||
extern struct idr usb_bus_idr;
|
||||
extern struct mutex usb_bus_idr_lock;
|
||||
extern wait_queue_head_t usb_kill_urb_queue;
|
||||
|
||||
|
||||
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern unsigned usb_wakeup_enabled_descendants(struct usb_device *udev);
|
||||
extern void usb_root_hub_lost_power(struct usb_device *rhdev);
|
||||
extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg);
|
||||
extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg);
|
||||
extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
|
||||
#else
|
||||
static inline unsigned usb_wakeup_enabled_descendants(struct usb_device *udev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
|
||||
|
||||
struct usb_mon_operations {
|
||||
void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
|
||||
void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
|
||||
void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status);
|
||||
/* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
|
||||
};
|
||||
|
||||
extern const struct usb_mon_operations *mon_ops;
|
||||
|
||||
static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
|
||||
{
|
||||
if (bus->monitored)
|
||||
(*mon_ops->urb_submit)(bus, urb);
|
||||
}
|
||||
|
||||
static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
|
||||
int error)
|
||||
{
|
||||
if (bus->monitored)
|
||||
(*mon_ops->urb_submit_error)(bus, urb, error);
|
||||
}
|
||||
|
||||
static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
|
||||
int status)
|
||||
{
|
||||
if (bus->monitored)
|
||||
(*mon_ops->urb_complete)(bus, urb, status);
|
||||
}
|
||||
|
||||
int usb_mon_register(const struct usb_mon_operations *ops);
|
||||
void usb_mon_deregister(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
|
||||
static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
|
||||
int error) {}
|
||||
static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
|
||||
int status) {}
|
||||
|
||||
#endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* random stuff */
|
||||
|
||||
/* This rwsem is for use only by the hub driver and ehci-hcd.
|
||||
* Nobody else should touch it.
|
||||
*/
|
||||
extern struct rw_semaphore ehci_cf_port_reset_rwsem;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __USB_CORE_HCD_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2005 Dmitry Torokhov
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_INPUT_H
|
||||
#define __LINUX_USB_INPUT_H
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/input.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
static inline void
|
||||
usb_to_input_id(const struct usb_device *dev, struct input_id *id)
|
||||
{
|
||||
id->bustype = BUS_USB;
|
||||
id->vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
id->product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
id->version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
}
|
||||
|
||||
#endif /* __LINUX_USB_INPUT_H */
|
||||
@@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_USB_IOWARRIOR_H
|
||||
#define __LINUX_USB_IOWARRIOR_H
|
||||
|
||||
#define CODEMERCS_MAGIC_NUMBER 0xC0 /* like COde Mercenaries */
|
||||
|
||||
/* Define the ioctl commands for reading and writing data */
|
||||
#define IOW_WRITE _IOW(CODEMERCS_MAGIC_NUMBER, 1, __u8 *)
|
||||
#define IOW_READ _IOW(CODEMERCS_MAGIC_NUMBER, 2, __u8 *)
|
||||
|
||||
/*
|
||||
A struct for available device info which is read
|
||||
with the ioctl IOW_GETINFO.
|
||||
To be compatible with 2.4 userspace which didn't have an easy way to get
|
||||
this information.
|
||||
*/
|
||||
struct iowarrior_info {
|
||||
/* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */
|
||||
__u32 vendor;
|
||||
/* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_X) */
|
||||
__u32 product;
|
||||
/* the serial number of our chip (if a serial-number is not available
|
||||
* this is empty string) */
|
||||
__u8 serial[9];
|
||||
/* revision number of the chip */
|
||||
__u32 revision;
|
||||
/* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */
|
||||
__u32 speed;
|
||||
/* power consumption of the device in mA */
|
||||
__u32 power;
|
||||
/* the number of the endpoint */
|
||||
__u32 if_num;
|
||||
/* size of the data-packets on this interface */
|
||||
__u32 report_size;
|
||||
};
|
||||
|
||||
/*
|
||||
Get some device-information (product-id , serial-number etc.)
|
||||
in order to identify a chip.
|
||||
*/
|
||||
#define IOW_GETINFO _IOR(CODEMERCS_MAGIC_NUMBER, 3, struct iowarrior_info)
|
||||
|
||||
#endif /* __LINUX_USB_IOWARRIOR_H */
|
||||
@@ -0,0 +1,163 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* USB IrDA Bridge Device Definition
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_IRDA_H
|
||||
#define __LINUX_USB_IRDA_H
|
||||
|
||||
/* This device should use Application-specific class */
|
||||
|
||||
#define USB_SUBCLASS_IRDA 0x02
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Class-Specific requests (bRequest field) */
|
||||
|
||||
#define USB_REQ_CS_IRDA_RECEIVING 1
|
||||
#define USB_REQ_CS_IRDA_CHECK_MEDIA_BUSY 3
|
||||
#define USB_REQ_CS_IRDA_RATE_SNIFF 4
|
||||
#define USB_REQ_CS_IRDA_UNICAST_LIST 5
|
||||
#define USB_REQ_CS_IRDA_GET_CLASS_DESC 6
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Class-Specific descriptor */
|
||||
|
||||
#define USB_DT_CS_IRDA 0x21
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Data sizes */
|
||||
|
||||
#define USB_IRDA_DS_2048 (1 << 5)
|
||||
#define USB_IRDA_DS_1024 (1 << 4)
|
||||
#define USB_IRDA_DS_512 (1 << 3)
|
||||
#define USB_IRDA_DS_256 (1 << 2)
|
||||
#define USB_IRDA_DS_128 (1 << 1)
|
||||
#define USB_IRDA_DS_64 (1 << 0)
|
||||
|
||||
/* Window sizes */
|
||||
|
||||
#define USB_IRDA_WS_7 (1 << 6)
|
||||
#define USB_IRDA_WS_6 (1 << 5)
|
||||
#define USB_IRDA_WS_5 (1 << 4)
|
||||
#define USB_IRDA_WS_4 (1 << 3)
|
||||
#define USB_IRDA_WS_3 (1 << 2)
|
||||
#define USB_IRDA_WS_2 (1 << 1)
|
||||
#define USB_IRDA_WS_1 (1 << 0)
|
||||
|
||||
/* Min turnaround times in usecs */
|
||||
|
||||
#define USB_IRDA_MTT_0 (1 << 7)
|
||||
#define USB_IRDA_MTT_10 (1 << 6)
|
||||
#define USB_IRDA_MTT_50 (1 << 5)
|
||||
#define USB_IRDA_MTT_100 (1 << 4)
|
||||
#define USB_IRDA_MTT_500 (1 << 3)
|
||||
#define USB_IRDA_MTT_1000 (1 << 2)
|
||||
#define USB_IRDA_MTT_5000 (1 << 1)
|
||||
#define USB_IRDA_MTT_10000 (1 << 0)
|
||||
|
||||
/* Baud rates */
|
||||
|
||||
#define USB_IRDA_BR_4000000 (1 << 8)
|
||||
#define USB_IRDA_BR_1152000 (1 << 7)
|
||||
#define USB_IRDA_BR_576000 (1 << 6)
|
||||
#define USB_IRDA_BR_115200 (1 << 5)
|
||||
#define USB_IRDA_BR_57600 (1 << 4)
|
||||
#define USB_IRDA_BR_38400 (1 << 3)
|
||||
#define USB_IRDA_BR_19200 (1 << 2)
|
||||
#define USB_IRDA_BR_9600 (1 << 1)
|
||||
#define USB_IRDA_BR_2400 (1 << 0)
|
||||
|
||||
/* Additional BOFs */
|
||||
|
||||
#define USB_IRDA_AB_0 (1 << 7)
|
||||
#define USB_IRDA_AB_1 (1 << 6)
|
||||
#define USB_IRDA_AB_2 (1 << 5)
|
||||
#define USB_IRDA_AB_3 (1 << 4)
|
||||
#define USB_IRDA_AB_6 (1 << 3)
|
||||
#define USB_IRDA_AB_12 (1 << 2)
|
||||
#define USB_IRDA_AB_24 (1 << 1)
|
||||
#define USB_IRDA_AB_48 (1 << 0)
|
||||
|
||||
/* IRDA Rate Sniff */
|
||||
|
||||
#define USB_IRDA_RATE_SNIFF 1
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
struct usb_irda_cs_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 bcdSpecRevision;
|
||||
__u8 bmDataSize;
|
||||
__u8 bmWindowSize;
|
||||
__u8 bmMinTurnaroundTime;
|
||||
__le16 wBaudRate;
|
||||
__u8 bmAdditionalBOFs;
|
||||
__u8 bIrdaRateSniff;
|
||||
__u8 bMaxUnicastList;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Data Format */
|
||||
|
||||
#define USB_IRDA_STATUS_MEDIA_BUSY (1 << 7)
|
||||
|
||||
/* The following is a 4-bit value used for both
|
||||
* inbound and outbound headers:
|
||||
*
|
||||
* 0 - speed ignored
|
||||
* 1 - 2400 bps
|
||||
* 2 - 9600 bps
|
||||
* 3 - 19200 bps
|
||||
* 4 - 38400 bps
|
||||
* 5 - 57600 bps
|
||||
* 6 - 115200 bps
|
||||
* 7 - 576000 bps
|
||||
* 8 - 1.152 Mbps
|
||||
* 9 - 4 Mbps
|
||||
* 10..15 - Reserved
|
||||
*/
|
||||
#define USB_IRDA_STATUS_LINK_SPEED 0x0f
|
||||
|
||||
#define USB_IRDA_LS_NO_CHANGE 0
|
||||
#define USB_IRDA_LS_2400 1
|
||||
#define USB_IRDA_LS_9600 2
|
||||
#define USB_IRDA_LS_19200 3
|
||||
#define USB_IRDA_LS_38400 4
|
||||
#define USB_IRDA_LS_57600 5
|
||||
#define USB_IRDA_LS_115200 6
|
||||
#define USB_IRDA_LS_576000 7
|
||||
#define USB_IRDA_LS_1152000 8
|
||||
#define USB_IRDA_LS_4000000 9
|
||||
|
||||
/* The following is a 4-bit value used only for
|
||||
* outbound header:
|
||||
*
|
||||
* 0 - No change (BOF ignored)
|
||||
* 1 - 48 BOFs
|
||||
* 2 - 24 BOFs
|
||||
* 3 - 12 BOFs
|
||||
* 4 - 6 BOFs
|
||||
* 5 - 3 BOFs
|
||||
* 6 - 2 BOFs
|
||||
* 7 - 1 BOFs
|
||||
* 8 - 0 BOFs
|
||||
* 9..15 - Reserved
|
||||
*/
|
||||
#define USB_IRDA_EXTRA_BOFS 0xf0
|
||||
|
||||
struct usb_irda_inbound_header {
|
||||
__u8 bmStatus;
|
||||
};
|
||||
|
||||
struct usb_irda_outbound_header {
|
||||
__u8 bmChange;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_IRDA_H */
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Board initialization code should put one of these into dev->platform_data
|
||||
* and place the isp116x onto platform_bus.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_ISP116X_H
|
||||
#define __LINUX_USB_ISP116X_H
|
||||
|
||||
struct isp116x_platform_data {
|
||||
/* Enable internal resistors on downstream ports */
|
||||
unsigned sel15Kres:1;
|
||||
/* On-chip overcurrent detection */
|
||||
unsigned oc_enable:1;
|
||||
/* INT output polarity */
|
||||
unsigned int_act_high:1;
|
||||
/* INT edge or level triggered */
|
||||
unsigned int_edge_triggered:1;
|
||||
/* Enable wakeup by devices on usb bus (e.g. wakeup
|
||||
by attachment/detachment or by device activity
|
||||
such as moving a mouse). When chosen, this option
|
||||
prevents stopping internal clock, increasing
|
||||
thereby power consumption in suspended state. */
|
||||
unsigned remote_wakeup_enable:1;
|
||||
/* Inter-io delay (ns). The chip is picky about access timings; it
|
||||
expects at least:
|
||||
150ns delay between consecutive accesses to DATA_REG,
|
||||
300ns delay between access to ADDR_REG and DATA_REG
|
||||
OE, WE MUST NOT be changed during these intervals
|
||||
*/
|
||||
void (*delay) (struct device *dev, int delay);
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_ISP116X_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* NXP ISP1301 USB transceiver driver
|
||||
*
|
||||
* Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_ISP1301_H
|
||||
#define __LINUX_USB_ISP1301_H
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
/* I2C Register definitions: */
|
||||
|
||||
#define ISP1301_I2C_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */
|
||||
|
||||
#define MC1_SPEED_REG (1 << 0)
|
||||
#define MC1_SUSPEND_REG (1 << 1)
|
||||
#define MC1_DAT_SE0 (1 << 2)
|
||||
#define MC1_TRANSPARENT (1 << 3)
|
||||
#define MC1_BDIS_ACON_EN (1 << 4)
|
||||
#define MC1_OE_INT_EN (1 << 5)
|
||||
#define MC1_UART_EN (1 << 6)
|
||||
#define MC1_MASK 0x7f
|
||||
|
||||
#define ISP1301_I2C_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */
|
||||
|
||||
#define MC2_GLOBAL_PWR_DN (1 << 0)
|
||||
#define MC2_SPD_SUSP_CTRL (1 << 1)
|
||||
#define MC2_BI_DI (1 << 2)
|
||||
#define MC2_TRANSP_BDIR0 (1 << 3)
|
||||
#define MC2_TRANSP_BDIR1 (1 << 4)
|
||||
#define MC2_AUDIO_EN (1 << 5)
|
||||
#define MC2_PSW_EN (1 << 6)
|
||||
#define MC2_EN2V7 (1 << 7)
|
||||
|
||||
#define ISP1301_I2C_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */
|
||||
|
||||
#define OTG1_DP_PULLUP (1 << 0)
|
||||
#define OTG1_DM_PULLUP (1 << 1)
|
||||
#define OTG1_DP_PULLDOWN (1 << 2)
|
||||
#define OTG1_DM_PULLDOWN (1 << 3)
|
||||
#define OTG1_ID_PULLDOWN (1 << 4)
|
||||
#define OTG1_VBUS_DRV (1 << 5)
|
||||
#define OTG1_VBUS_DISCHRG (1 << 6)
|
||||
#define OTG1_VBUS_CHRG (1 << 7)
|
||||
|
||||
#define ISP1301_I2C_OTG_CONTROL_2 0x10 /* u8 readonly */
|
||||
|
||||
#define OTG_B_SESS_END (1 << 6)
|
||||
#define OTG_B_SESS_VLD (1 << 7)
|
||||
|
||||
#define ISP1301_I2C_INTERRUPT_SOURCE 0x8
|
||||
#define ISP1301_I2C_INTERRUPT_LATCH 0xA
|
||||
#define ISP1301_I2C_INTERRUPT_FALLING 0xC
|
||||
#define ISP1301_I2C_INTERRUPT_RISING 0xE
|
||||
|
||||
#define INT_VBUS_VLD (1 << 0)
|
||||
#define INT_SESS_VLD (1 << 1)
|
||||
#define INT_DP_HI (1 << 2)
|
||||
#define INT_ID_GND (1 << 3)
|
||||
#define INT_DM_HI (1 << 4)
|
||||
#define INT_ID_FLOAT (1 << 5)
|
||||
#define INT_BDIS_ACON (1 << 6)
|
||||
#define INT_CR_INT (1 << 7)
|
||||
|
||||
#define ISP1301_I2C_REG_CLEAR_ADDR 1 /* Register Address Modifier */
|
||||
|
||||
struct i2c_client *isp1301_get_client(struct device_node *node);
|
||||
|
||||
#endif /* __LINUX_USB_ISP1301_H */
|
||||
@@ -0,0 +1,145 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2023, Intel Corporation. All rights reserved.
|
||||
*/
|
||||
#ifndef _LINUX_USB_LJCA_H_
|
||||
#define _LINUX_USB_LJCA_H_
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define LJCA_MAX_GPIO_NUM 64
|
||||
|
||||
#define auxiliary_dev_to_ljca_client(auxiliary_dev) \
|
||||
container_of(auxiliary_dev, struct ljca_client, auxdev)
|
||||
|
||||
struct ljca_adapter;
|
||||
|
||||
/**
|
||||
* typedef ljca_event_cb_t - event callback function signature
|
||||
*
|
||||
* @context: the execution context of who registered this callback
|
||||
* @cmd: the command from device for this event
|
||||
* @evt_data: the event data payload
|
||||
* @len: the event data payload length
|
||||
*
|
||||
* The callback function is called in interrupt context and the data payload is
|
||||
* only valid during the call. If the user needs later access of the data, it
|
||||
* must copy it.
|
||||
*/
|
||||
typedef void (*ljca_event_cb_t)(void *context, u8 cmd, const void *evt_data, int len);
|
||||
|
||||
/**
|
||||
* struct ljca_client - represent a ljca client device
|
||||
*
|
||||
* @type: ljca client type
|
||||
* @id: ljca client id within same client type
|
||||
* @link: ljca client on the same ljca adapter
|
||||
* @auxdev: auxiliary device object
|
||||
* @adapter: ljca adapter the ljca client sit on
|
||||
* @context: the execution context of the event callback
|
||||
* @event_cb: ljca client driver register this callback to get
|
||||
* firmware asynchronous rx buffer pending notifications
|
||||
* @event_cb_lock: spinlock to protect event callback
|
||||
*/
|
||||
struct ljca_client {
|
||||
u8 type;
|
||||
u8 id;
|
||||
struct list_head link;
|
||||
struct auxiliary_device auxdev;
|
||||
struct ljca_adapter *adapter;
|
||||
|
||||
void *context;
|
||||
ljca_event_cb_t event_cb;
|
||||
/* lock to protect event_cb */
|
||||
spinlock_t event_cb_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ljca_gpio_info - ljca gpio client device info
|
||||
*
|
||||
* @num: ljca gpio client device pin number
|
||||
* @valid_pin_map: ljca gpio client device valid pin mapping
|
||||
*/
|
||||
struct ljca_gpio_info {
|
||||
unsigned int num;
|
||||
DECLARE_BITMAP(valid_pin_map, LJCA_MAX_GPIO_NUM);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ljca_i2c_info - ljca i2c client device info
|
||||
*
|
||||
* @id: ljca i2c client device identification number
|
||||
* @capacity: ljca i2c client device capacity
|
||||
* @intr_pin: ljca i2c client device interrupt pin number if exists
|
||||
*/
|
||||
struct ljca_i2c_info {
|
||||
u8 id;
|
||||
u8 capacity;
|
||||
u8 intr_pin;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ljca_spi_info - ljca spi client device info
|
||||
*
|
||||
* @id: ljca spi client device identification number
|
||||
* @capacity: ljca spi client device capacity
|
||||
*/
|
||||
struct ljca_spi_info {
|
||||
u8 id;
|
||||
u8 capacity;
|
||||
};
|
||||
|
||||
/**
|
||||
* ljca_register_event_cb - register a callback function to receive events
|
||||
*
|
||||
* @client: ljca client device
|
||||
* @event_cb: callback function
|
||||
* @context: execution context of event callback
|
||||
*
|
||||
* Return: 0 in case of success, negative value in case of error
|
||||
*/
|
||||
int ljca_register_event_cb(struct ljca_client *client, ljca_event_cb_t event_cb, void *context);
|
||||
|
||||
/**
|
||||
* ljca_unregister_event_cb - unregister the callback function for an event
|
||||
*
|
||||
* @client: ljca client device
|
||||
*/
|
||||
void ljca_unregister_event_cb(struct ljca_client *client);
|
||||
|
||||
/**
|
||||
* ljca_transfer - issue a LJCA command and wait for a response
|
||||
*
|
||||
* @client: ljca client device
|
||||
* @cmd: the command to be sent to the device
|
||||
* @obuf: the buffer to be sent to the device; it can be NULL if the user
|
||||
* doesn't need to transmit data with this command
|
||||
* @obuf_len: the size of the buffer to be sent to the device; it should
|
||||
* be 0 when obuf is NULL
|
||||
* @ibuf: any data associated with the response will be copied here; it can be
|
||||
* NULL if the user doesn't need the response data
|
||||
* @ibuf_len: must be initialized to the input buffer size
|
||||
*
|
||||
* Return: the actual length of response data for success, negative value for errors
|
||||
*/
|
||||
int ljca_transfer(struct ljca_client *client, u8 cmd, const u8 *obuf,
|
||||
u8 obuf_len, u8 *ibuf, u8 ibuf_len);
|
||||
|
||||
/**
|
||||
* ljca_transfer_noack - issue a LJCA command without a response
|
||||
*
|
||||
* @client: ljca client device
|
||||
* @cmd: the command to be sent to the device
|
||||
* @obuf: the buffer to be sent to the device; it can be NULL if the user
|
||||
* doesn't need to transmit data with this command
|
||||
* @obuf_len: the size of the buffer to be sent to the device
|
||||
*
|
||||
* Return: 0 for success, negative value for errors
|
||||
*/
|
||||
int ljca_transfer_noack(struct ljca_client *client, u8 cmd, const u8 *obuf,
|
||||
u8 obuf_len);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* M66592 driver platform data
|
||||
*
|
||||
* Copyright (C) 2009 Renesas Solutions Corp.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_M66592_H
|
||||
#define __LINUX_USB_M66592_H
|
||||
|
||||
#define M66592_PLATDATA_XTAL_12MHZ 0x01
|
||||
#define M66592_PLATDATA_XTAL_24MHZ 0x02
|
||||
#define M66592_PLATDATA_XTAL_48MHZ 0x03
|
||||
|
||||
struct m66592_platdata {
|
||||
/* one = on chip controller, zero = external controller */
|
||||
unsigned on_chip:1;
|
||||
|
||||
/* one = big endian, zero = little endian */
|
||||
unsigned endian:1;
|
||||
|
||||
/* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */
|
||||
unsigned xtal:2;
|
||||
|
||||
/* (external controller only) one = 3.3V, zero = 1.5V */
|
||||
unsigned vif:1;
|
||||
|
||||
/* (external controller only) set one = WR0_N shorted to WR1_N */
|
||||
unsigned wr0_shorted_to_wr1:1;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_M66592_H */
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* mctp-usb.h - MCTP USB transport binding: common definitions,
|
||||
* based on DMTF0283 specification:
|
||||
* https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.1.pdf
|
||||
*
|
||||
* These are protocol-level definitions, that may be shared between host
|
||||
* and gadget drivers.
|
||||
*
|
||||
* Copyright (C) 2024-2025 Code Construct Pty Ltd
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_MCTP_USB_H
|
||||
#define __LINUX_USB_MCTP_USB_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct mctp_usb_hdr {
|
||||
__be16 id;
|
||||
u8 rsvd;
|
||||
u8 len;
|
||||
} __packed;
|
||||
|
||||
#define MCTP_USB_XFER_SIZE 512
|
||||
#define MCTP_USB_BTU 68
|
||||
#define MCTP_USB_MTU_MIN MCTP_USB_BTU
|
||||
#define MCTP_USB_MTU_MAX (U8_MAX - sizeof(struct mctp_usb_hdr))
|
||||
#define MCTP_USB_DMTF_ID 0x1ab4
|
||||
|
||||
#endif /* __LINUX_USB_MCTP_USB_H */
|
||||
@@ -0,0 +1,94 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* <linux/usb/midi-v2.h> -- USB MIDI 2.0 definitions.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_MIDI_V2_H
|
||||
#define __LINUX_USB_MIDI_V2_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb/midi.h>
|
||||
|
||||
/* A.1 MS Class-Specific Interface Descriptor Types */
|
||||
#define USB_DT_CS_GR_TRM_BLOCK 0x26
|
||||
|
||||
/* A.1 MS Class-Specific Interface Descriptor Subtypes */
|
||||
/* same as MIDI 1.0 */
|
||||
|
||||
/* A.2 MS Class-Specific Endpoint Descriptor Subtypes */
|
||||
#define USB_MS_GENERAL_2_0 0x02
|
||||
|
||||
/* A.3 MS Class-Specific Group Terminal Block Descriptor Subtypes */
|
||||
#define USB_MS_GR_TRM_BLOCK_UNDEFINED 0x00
|
||||
#define USB_MS_GR_TRM_BLOCK_HEADER 0x01
|
||||
#define USB_MS_GR_TRM_BLOCK 0x02
|
||||
|
||||
/* A.4 MS Interface Header MIDIStreaming Class Revision */
|
||||
#define USB_MS_REV_MIDI_1_0 0x0100
|
||||
#define USB_MS_REV_MIDI_2_0 0x0200
|
||||
|
||||
/* A.5 MS MIDI IN and OUT Jack Types */
|
||||
/* same as MIDI 1.0 */
|
||||
|
||||
/* A.6 Group Terminal Block Types */
|
||||
#define USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL 0x00
|
||||
#define USB_MS_GR_TRM_BLOCK_TYPE_INPUT_ONLY 0x01
|
||||
#define USB_MS_GR_TRM_BLOCK_TYPE_OUTPUT_ONLY 0x02
|
||||
|
||||
/* A.7 Group Terminal Default MIDI Protocol */
|
||||
#define USB_MS_MIDI_PROTO_UNKNOWN 0x00 /* Unknown (Use MIDI-CI) */
|
||||
#define USB_MS_MIDI_PROTO_1_0_64 0x01 /* MIDI 1.0, UMP up to 64bits */
|
||||
#define USB_MS_MIDI_PROTO_1_0_64_JRTS 0x02 /* MIDI 1.0, UMP up to 64bits, Jitter Reduction Timestamps */
|
||||
#define USB_MS_MIDI_PROTO_1_0_128 0x03 /* MIDI 1.0, UMP up to 128bits */
|
||||
#define USB_MS_MIDI_PROTO_1_0_128_JRTS 0x04 /* MIDI 1.0, UMP up to 128bits, Jitter Reduction Timestamps */
|
||||
#define USB_MS_MIDI_PROTO_2_0 0x11 /* MIDI 2.0 */
|
||||
#define USB_MS_MIDI_PROTO_2_0_JRTS 0x12 /* MIDI 2.0, Jitter Reduction Timestamps */
|
||||
|
||||
/* 5.2.2.1 Class-Specific MS Interface Header Descriptor */
|
||||
/* Same as MIDI 1.0, use struct usb_ms_header_descriptor */
|
||||
|
||||
/* 5.3.2 Class-Specific MIDI Streaming Data Endpoint Descriptor */
|
||||
struct usb_ms20_endpoint_descriptor {
|
||||
__u8 bLength; /* 4+n */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
|
||||
__u8 bDescriptorSubtype; /* USB_MS_GENERAL_2_0 */
|
||||
__u8 bNumGrpTrmBlock; /* Number of Group Terminal Blocks: n */
|
||||
__u8 baAssoGrpTrmBlkID[]; /* ID of the Group Terminal Blocks [n] */
|
||||
} __packed;
|
||||
|
||||
#define USB_DT_MS20_ENDPOINT_SIZE(n) (4 + (n))
|
||||
|
||||
/* As above, but more useful for defining your own descriptors: */
|
||||
#define DECLARE_USB_MS20_ENDPOINT_DESCRIPTOR(n) \
|
||||
struct usb_ms20_endpoint_descriptor_##n { \
|
||||
__u8 bLength; \
|
||||
__u8 bDescriptorType; \
|
||||
__u8 bDescriptorSubtype; \
|
||||
__u8 bNumGrpTrmBlock; \
|
||||
__u8 baAssoGrpTrmBlkID[n]; \
|
||||
} __packed
|
||||
|
||||
/* 5.4.1 Class-Specific Group Terminal Block Header Descriptor */
|
||||
struct usb_ms20_gr_trm_block_header_descriptor {
|
||||
__u8 bLength; /* 5 */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_GR_TRM_BLOCK */
|
||||
__u8 bDescriptorSubtype; /* USB_MS_GR_TRM_BLOCK_HEADER */
|
||||
__le16 wTotalLength; /* Total number of bytes */
|
||||
} __packed;
|
||||
|
||||
/* 5.4.2.1 Group Terminal Block Descriptor */
|
||||
struct usb_ms20_gr_trm_block_descriptor {
|
||||
__u8 bLength; /* 13 */
|
||||
__u8 bDescriptorType; /* USB_DT_CS_GR_TRM_BLOCK */
|
||||
__u8 bDescriptorSubtype; /* USB_MS_GR_TRM_BLOCK */
|
||||
__u8 bGrpTrmBlkID; /* ID of this Group Terminal Block */
|
||||
__u8 bGrpTrmBlkType; /* Group Terminal Block Type */
|
||||
__u8 nGroupTrm; /* The first member Group Terminal in this block */
|
||||
__u8 nNumGroupTrm; /* Number of member Group Terminals spanned */
|
||||
__u8 iBlockItem; /* String ID of Block item */
|
||||
__u8 bMIDIProtocol; /* Default MIDI protocol */
|
||||
__le16 wMaxInputBandwidth; /* Max input bandwidth capability in 4kB/s */
|
||||
__le16 wMaxOutputBandwidth; /* Max output bandwidth capability in 4kB/s */
|
||||
} __packed;
|
||||
|
||||
#endif /* __LINUX_USB_MIDI_V2_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2013 ST-Ericsson AB
|
||||
*/
|
||||
|
||||
#ifndef __MUSB_UX500_H__
|
||||
#define __MUSB_UX500_H__
|
||||
|
||||
enum ux500_musb_vbus_id_status {
|
||||
UX500_MUSB_NONE = 0,
|
||||
UX500_MUSB_VBUS,
|
||||
UX500_MUSB_ID,
|
||||
UX500_MUSB_CHARGER,
|
||||
UX500_MUSB_ENUMERATED,
|
||||
UX500_MUSB_RIDA,
|
||||
UX500_MUSB_RIDB,
|
||||
UX500_MUSB_RIDC,
|
||||
UX500_MUSB_PREPARE,
|
||||
UX500_MUSB_CLEAN,
|
||||
};
|
||||
|
||||
#endif /* __MUSB_UX500_H__ */
|
||||
@@ -0,0 +1,135 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This is used to for host and peripheral modes of the driver for
|
||||
* Inventra (Multidrop) Highspeed Dual-Role Controllers: (M)HDRC.
|
||||
*
|
||||
* Board initialization should put one of these into dev->platform_data,
|
||||
* probably on some platform_device named "musb-hdrc". It encapsulates
|
||||
* key configuration differences between boards.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_MUSB_H
|
||||
#define __LINUX_USB_MUSB_H
|
||||
|
||||
/* The USB role is defined by the connector used on the board, so long as
|
||||
* standards are being followed. (Developer boards sometimes won't.)
|
||||
*/
|
||||
enum musb_mode {
|
||||
MUSB_UNDEFINED = 0,
|
||||
MUSB_HOST, /* A or Mini-A connector */
|
||||
MUSB_PERIPHERAL, /* B or Mini-B connector */
|
||||
MUSB_OTG /* Mini-AB connector */
|
||||
};
|
||||
|
||||
struct clk;
|
||||
|
||||
enum musb_fifo_style {
|
||||
FIFO_RXTX,
|
||||
FIFO_TX,
|
||||
FIFO_RX
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum musb_buf_mode {
|
||||
BUF_SINGLE,
|
||||
BUF_DOUBLE
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct musb_fifo_cfg {
|
||||
u8 hw_ep_num;
|
||||
enum musb_fifo_style style;
|
||||
enum musb_buf_mode mode;
|
||||
u16 maxpacket;
|
||||
};
|
||||
|
||||
#define MUSB_EP_FIFO(ep, st, m, pkt) \
|
||||
{ \
|
||||
.hw_ep_num = ep, \
|
||||
.style = st, \
|
||||
.mode = m, \
|
||||
.maxpacket = pkt, \
|
||||
}
|
||||
|
||||
#define MUSB_EP_FIFO_SINGLE(ep, st, pkt) \
|
||||
MUSB_EP_FIFO(ep, st, BUF_SINGLE, pkt)
|
||||
|
||||
#define MUSB_EP_FIFO_DOUBLE(ep, st, pkt) \
|
||||
MUSB_EP_FIFO(ep, st, BUF_DOUBLE, pkt)
|
||||
|
||||
struct musb_hdrc_eps_bits {
|
||||
const char name[16];
|
||||
u8 bits;
|
||||
};
|
||||
|
||||
struct musb_hdrc_config {
|
||||
const struct musb_fifo_cfg *fifo_cfg; /* board fifo configuration */
|
||||
unsigned fifo_cfg_size; /* size of the fifo configuration */
|
||||
|
||||
/* MUSB configuration-specific details */
|
||||
unsigned multipoint:1; /* multipoint device */
|
||||
unsigned dyn_fifo:1 __deprecated; /* supports dynamic fifo sizing */
|
||||
|
||||
/* need to explicitly de-assert the port reset after resume? */
|
||||
unsigned host_port_deassert_reset_at_resume:1;
|
||||
|
||||
u8 num_eps; /* number of endpoints _with_ ep0 */
|
||||
u8 ram_bits; /* ram address size */
|
||||
|
||||
u32 maximum_speed;
|
||||
};
|
||||
|
||||
struct musb_hdrc_platform_data {
|
||||
/* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
|
||||
u8 mode;
|
||||
|
||||
/* for clk_get() */
|
||||
const char *clock;
|
||||
|
||||
/* (HOST or OTG) switch VBUS on/off */
|
||||
int (*set_vbus)(struct device *dev, int is_on);
|
||||
|
||||
/* (HOST or OTG) mA/2 power supplied on (default = 8mA) */
|
||||
u8 power;
|
||||
|
||||
/* (PERIPHERAL) mA/2 max power consumed (default = 100mA) */
|
||||
u8 min_power;
|
||||
|
||||
/* (HOST or OTG) msec/2 after VBUS on till power good */
|
||||
u8 potpgt;
|
||||
|
||||
/* (HOST or OTG) program PHY for external Vbus */
|
||||
unsigned extvbus:1;
|
||||
|
||||
/* MUSB configuration-specific details */
|
||||
const struct musb_hdrc_config *config;
|
||||
|
||||
/* Architecture specific board data */
|
||||
void *board_data;
|
||||
|
||||
/* Platform specific struct musb_ops pointer */
|
||||
const void *platform_ops;
|
||||
};
|
||||
|
||||
enum musb_vbus_id_status {
|
||||
MUSB_UNKNOWN = 0,
|
||||
MUSB_ID_GROUND,
|
||||
MUSB_ID_FLOAT,
|
||||
MUSB_VBUS_VALID,
|
||||
MUSB_VBUS_OFF,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
|
||||
int musb_mailbox(enum musb_vbus_id_status status);
|
||||
#else
|
||||
static inline int musb_mailbox(enum musb_vbus_id_status status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TUSB 6010 support */
|
||||
|
||||
#define TUSB6010_OSCCLK_60 16667 /* psec/clk @ 60.0 MHz */
|
||||
#define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */
|
||||
#define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */
|
||||
|
||||
#endif /* __LINUX_USB_MUSB_H */
|
||||
@@ -0,0 +1,433 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* NetChip 2280 high/full speed USB device controller.
|
||||
* Unlike many such controllers, this one talks PCI.
|
||||
*
|
||||
* Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
|
||||
* Copyright (C) 2003 David Brownell
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_NET2280_H
|
||||
#define __LINUX_USB_NET2280_H
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* NET2280 MEMORY MAPPED REGISTERS
|
||||
*
|
||||
* The register layout came from the chip documentation, and the bit
|
||||
* number definitions were extracted from chip specification.
|
||||
*
|
||||
* Use the shift operator ('<<') to build bit masks, with readl/writel
|
||||
* to access the registers through PCI.
|
||||
*/
|
||||
|
||||
/* main registers, BAR0 + 0x0000 */
|
||||
struct net2280_regs {
|
||||
/* offset 0x0000 */
|
||||
u32 devinit;
|
||||
#define LOCAL_CLOCK_FREQUENCY 8
|
||||
#define FORCE_PCI_RESET 7
|
||||
#define PCI_ID 6
|
||||
#define PCI_ENABLE 5
|
||||
#define FIFO_SOFT_RESET 4
|
||||
#define CFG_SOFT_RESET 3
|
||||
#define PCI_SOFT_RESET 2
|
||||
#define USB_SOFT_RESET 1
|
||||
#define M8051_RESET 0
|
||||
u32 eectl;
|
||||
#define EEPROM_ADDRESS_WIDTH 23
|
||||
#define EEPROM_CHIP_SELECT_ACTIVE 22
|
||||
#define EEPROM_PRESENT 21
|
||||
#define EEPROM_VALID 20
|
||||
#define EEPROM_BUSY 19
|
||||
#define EEPROM_CHIP_SELECT_ENABLE 18
|
||||
#define EEPROM_BYTE_READ_START 17
|
||||
#define EEPROM_BYTE_WRITE_START 16
|
||||
#define EEPROM_READ_DATA 8
|
||||
#define EEPROM_WRITE_DATA 0
|
||||
u32 eeclkfreq;
|
||||
u32 _unused0;
|
||||
/* offset 0x0010 */
|
||||
|
||||
u32 pciirqenb0; /* interrupt PCI master ... */
|
||||
#define SETUP_PACKET_INTERRUPT_ENABLE 7
|
||||
#define ENDPOINT_F_INTERRUPT_ENABLE 6
|
||||
#define ENDPOINT_E_INTERRUPT_ENABLE 5
|
||||
#define ENDPOINT_D_INTERRUPT_ENABLE 4
|
||||
#define ENDPOINT_C_INTERRUPT_ENABLE 3
|
||||
#define ENDPOINT_B_INTERRUPT_ENABLE 2
|
||||
#define ENDPOINT_A_INTERRUPT_ENABLE 1
|
||||
#define ENDPOINT_0_INTERRUPT_ENABLE 0
|
||||
u32 pciirqenb1;
|
||||
#define PCI_INTERRUPT_ENABLE 31
|
||||
#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
|
||||
#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
|
||||
#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
|
||||
#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
|
||||
#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
|
||||
#define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18
|
||||
#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
|
||||
#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
|
||||
#define GPIO_INTERRUPT_ENABLE 13
|
||||
#define DMA_D_INTERRUPT_ENABLE 12
|
||||
#define DMA_C_INTERRUPT_ENABLE 11
|
||||
#define DMA_B_INTERRUPT_ENABLE 10
|
||||
#define DMA_A_INTERRUPT_ENABLE 9
|
||||
#define EEPROM_DONE_INTERRUPT_ENABLE 8
|
||||
#define VBUS_INTERRUPT_ENABLE 7
|
||||
#define CONTROL_STATUS_INTERRUPT_ENABLE 6
|
||||
#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
|
||||
#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
|
||||
#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
|
||||
#define RESUME_INTERRUPT_ENABLE 1
|
||||
#define SOF_INTERRUPT_ENABLE 0
|
||||
u32 cpu_irqenb0; /* ... or onboard 8051 */
|
||||
#define SETUP_PACKET_INTERRUPT_ENABLE 7
|
||||
#define ENDPOINT_F_INTERRUPT_ENABLE 6
|
||||
#define ENDPOINT_E_INTERRUPT_ENABLE 5
|
||||
#define ENDPOINT_D_INTERRUPT_ENABLE 4
|
||||
#define ENDPOINT_C_INTERRUPT_ENABLE 3
|
||||
#define ENDPOINT_B_INTERRUPT_ENABLE 2
|
||||
#define ENDPOINT_A_INTERRUPT_ENABLE 1
|
||||
#define ENDPOINT_0_INTERRUPT_ENABLE 0
|
||||
u32 cpu_irqenb1;
|
||||
#define CPU_INTERRUPT_ENABLE 31
|
||||
#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
|
||||
#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
|
||||
#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
|
||||
#define PCI_INTA_INTERRUPT_ENABLE 24
|
||||
#define PCI_PME_INTERRUPT_ENABLE 23
|
||||
#define PCI_SERR_INTERRUPT_ENABLE 22
|
||||
#define PCI_PERR_INTERRUPT_ENABLE 21
|
||||
#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
|
||||
#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
|
||||
#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
|
||||
#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
|
||||
#define GPIO_INTERRUPT_ENABLE 13
|
||||
#define DMA_D_INTERRUPT_ENABLE 12
|
||||
#define DMA_C_INTERRUPT_ENABLE 11
|
||||
#define DMA_B_INTERRUPT_ENABLE 10
|
||||
#define DMA_A_INTERRUPT_ENABLE 9
|
||||
#define EEPROM_DONE_INTERRUPT_ENABLE 8
|
||||
#define VBUS_INTERRUPT_ENABLE 7
|
||||
#define CONTROL_STATUS_INTERRUPT_ENABLE 6
|
||||
#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
|
||||
#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
|
||||
#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
|
||||
#define RESUME_INTERRUPT_ENABLE 1
|
||||
#define SOF_INTERRUPT_ENABLE 0
|
||||
|
||||
/* offset 0x0020 */
|
||||
u32 _unused1;
|
||||
u32 usbirqenb1;
|
||||
#define USB_INTERRUPT_ENABLE 31
|
||||
#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
|
||||
#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
|
||||
#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
|
||||
#define PCI_INTA_INTERRUPT_ENABLE 24
|
||||
#define PCI_PME_INTERRUPT_ENABLE 23
|
||||
#define PCI_SERR_INTERRUPT_ENABLE 22
|
||||
#define PCI_PERR_INTERRUPT_ENABLE 21
|
||||
#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
|
||||
#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
|
||||
#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
|
||||
#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
|
||||
#define GPIO_INTERRUPT_ENABLE 13
|
||||
#define DMA_D_INTERRUPT_ENABLE 12
|
||||
#define DMA_C_INTERRUPT_ENABLE 11
|
||||
#define DMA_B_INTERRUPT_ENABLE 10
|
||||
#define DMA_A_INTERRUPT_ENABLE 9
|
||||
#define EEPROM_DONE_INTERRUPT_ENABLE 8
|
||||
#define VBUS_INTERRUPT_ENABLE 7
|
||||
#define CONTROL_STATUS_INTERRUPT_ENABLE 6
|
||||
#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
|
||||
#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
|
||||
#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
|
||||
#define RESUME_INTERRUPT_ENABLE 1
|
||||
#define SOF_INTERRUPT_ENABLE 0
|
||||
u32 irqstat0;
|
||||
#define INTA_ASSERTED 12
|
||||
#define SETUP_PACKET_INTERRUPT 7
|
||||
#define ENDPOINT_F_INTERRUPT 6
|
||||
#define ENDPOINT_E_INTERRUPT 5
|
||||
#define ENDPOINT_D_INTERRUPT 4
|
||||
#define ENDPOINT_C_INTERRUPT 3
|
||||
#define ENDPOINT_B_INTERRUPT 2
|
||||
#define ENDPOINT_A_INTERRUPT 1
|
||||
#define ENDPOINT_0_INTERRUPT 0
|
||||
#define USB3380_IRQSTAT0_EP_INTR_MASK_IN (0xF << 17)
|
||||
#define USB3380_IRQSTAT0_EP_INTR_MASK_OUT (0xF << 1)
|
||||
|
||||
u32 irqstat1;
|
||||
#define POWER_STATE_CHANGE_INTERRUPT 27
|
||||
#define PCI_ARBITER_TIMEOUT_INTERRUPT 26
|
||||
#define PCI_PARITY_ERROR_INTERRUPT 25
|
||||
#define PCI_INTA_INTERRUPT 24
|
||||
#define PCI_PME_INTERRUPT 23
|
||||
#define PCI_SERR_INTERRUPT 22
|
||||
#define PCI_PERR_INTERRUPT 21
|
||||
#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20
|
||||
#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19
|
||||
#define PCI_RETRY_ABORT_INTERRUPT 17
|
||||
#define PCI_MASTER_CYCLE_DONE_INTERRUPT 16
|
||||
#define SOF_DOWN_INTERRUPT 14
|
||||
#define GPIO_INTERRUPT 13
|
||||
#define DMA_D_INTERRUPT 12
|
||||
#define DMA_C_INTERRUPT 11
|
||||
#define DMA_B_INTERRUPT 10
|
||||
#define DMA_A_INTERRUPT 9
|
||||
#define EEPROM_DONE_INTERRUPT 8
|
||||
#define VBUS_INTERRUPT 7
|
||||
#define CONTROL_STATUS_INTERRUPT 6
|
||||
#define ROOT_PORT_RESET_INTERRUPT 4
|
||||
#define SUSPEND_REQUEST_INTERRUPT 3
|
||||
#define SUSPEND_REQUEST_CHANGE_INTERRUPT 2
|
||||
#define RESUME_INTERRUPT 1
|
||||
#define SOF_INTERRUPT 0
|
||||
/* offset 0x0030 */
|
||||
u32 idxaddr;
|
||||
u32 idxdata;
|
||||
u32 fifoctl;
|
||||
#define PCI_BASE2_RANGE 16
|
||||
#define IGNORE_FIFO_AVAILABILITY 3
|
||||
#define PCI_BASE2_SELECT 2
|
||||
#define FIFO_CONFIGURATION_SELECT 0
|
||||
u32 _unused2;
|
||||
/* offset 0x0040 */
|
||||
u32 memaddr;
|
||||
#define START 28
|
||||
#define DIRECTION 27
|
||||
#define FIFO_DIAGNOSTIC_SELECT 24
|
||||
#define MEMORY_ADDRESS 0
|
||||
u32 memdata0;
|
||||
u32 memdata1;
|
||||
u32 _unused3;
|
||||
/* offset 0x0050 */
|
||||
u32 gpioctl;
|
||||
#define GPIO3_LED_SELECT 12
|
||||
#define GPIO3_INTERRUPT_ENABLE 11
|
||||
#define GPIO2_INTERRUPT_ENABLE 10
|
||||
#define GPIO1_INTERRUPT_ENABLE 9
|
||||
#define GPIO0_INTERRUPT_ENABLE 8
|
||||
#define GPIO3_OUTPUT_ENABLE 7
|
||||
#define GPIO2_OUTPUT_ENABLE 6
|
||||
#define GPIO1_OUTPUT_ENABLE 5
|
||||
#define GPIO0_OUTPUT_ENABLE 4
|
||||
#define GPIO3_DATA 3
|
||||
#define GPIO2_DATA 2
|
||||
#define GPIO1_DATA 1
|
||||
#define GPIO0_DATA 0
|
||||
u32 gpiostat;
|
||||
#define GPIO3_INTERRUPT 3
|
||||
#define GPIO2_INTERRUPT 2
|
||||
#define GPIO1_INTERRUPT 1
|
||||
#define GPIO0_INTERRUPT 0
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* usb control, BAR0 + 0x0080 */
|
||||
struct net2280_usb_regs {
|
||||
/* offset 0x0080 */
|
||||
u32 stdrsp;
|
||||
#define STALL_UNSUPPORTED_REQUESTS 31
|
||||
#define SET_TEST_MODE 16
|
||||
#define GET_OTHER_SPEED_CONFIGURATION 15
|
||||
#define GET_DEVICE_QUALIFIER 14
|
||||
#define SET_ADDRESS 13
|
||||
#define ENDPOINT_SET_CLEAR_HALT 12
|
||||
#define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11
|
||||
#define GET_STRING_DESCRIPTOR_2 10
|
||||
#define GET_STRING_DESCRIPTOR_1 9
|
||||
#define GET_STRING_DESCRIPTOR_0 8
|
||||
#define GET_SET_INTERFACE 6
|
||||
#define GET_SET_CONFIGURATION 5
|
||||
#define GET_CONFIGURATION_DESCRIPTOR 4
|
||||
#define GET_DEVICE_DESCRIPTOR 3
|
||||
#define GET_ENDPOINT_STATUS 2
|
||||
#define GET_INTERFACE_STATUS 1
|
||||
#define GET_DEVICE_STATUS 0
|
||||
u32 prodvendid;
|
||||
#define PRODUCT_ID 16
|
||||
#define VENDOR_ID 0
|
||||
u32 relnum;
|
||||
u32 usbctl;
|
||||
#define SERIAL_NUMBER_INDEX 16
|
||||
#define PRODUCT_ID_STRING_ENABLE 13
|
||||
#define VENDOR_ID_STRING_ENABLE 12
|
||||
#define USB_ROOT_PORT_WAKEUP_ENABLE 11
|
||||
#define VBUS_PIN 10
|
||||
#define TIMED_DISCONNECT 9
|
||||
#define SUSPEND_IMMEDIATELY 7
|
||||
#define SELF_POWERED_USB_DEVICE 6
|
||||
#define REMOTE_WAKEUP_SUPPORT 5
|
||||
#define PME_POLARITY 4
|
||||
#define USB_DETECT_ENABLE 3
|
||||
#define PME_WAKEUP_ENABLE 2
|
||||
#define DEVICE_REMOTE_WAKEUP_ENABLE 1
|
||||
#define SELF_POWERED_STATUS 0
|
||||
/* offset 0x0090 */
|
||||
u32 usbstat;
|
||||
#define HIGH_SPEED 7
|
||||
#define FULL_SPEED 6
|
||||
#define GENERATE_RESUME 5
|
||||
#define GENERATE_DEVICE_REMOTE_WAKEUP 4
|
||||
u32 xcvrdiag;
|
||||
#define FORCE_HIGH_SPEED_MODE 31
|
||||
#define FORCE_FULL_SPEED_MODE 30
|
||||
#define USB_TEST_MODE 24
|
||||
#define LINE_STATE 16
|
||||
#define TRANSCEIVER_OPERATION_MODE 2
|
||||
#define TRANSCEIVER_SELECT 1
|
||||
#define TERMINATION_SELECT 0
|
||||
u32 setup0123;
|
||||
u32 setup4567;
|
||||
/* offset 0x0090 */
|
||||
u32 _unused0;
|
||||
u32 ouraddr;
|
||||
#define FORCE_IMMEDIATE 7
|
||||
#define OUR_USB_ADDRESS 0
|
||||
u32 ourconfig;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* pci control, BAR0 + 0x0100 */
|
||||
struct net2280_pci_regs {
|
||||
/* offset 0x0100 */
|
||||
u32 pcimstctl;
|
||||
#define PCI_ARBITER_PARK_SELECT 13
|
||||
#define PCI_MULTI LEVEL_ARBITER 12
|
||||
#define PCI_RETRY_ABORT_ENABLE 11
|
||||
#define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10
|
||||
#define DMA_READ_MULTIPLE_ENABLE 9
|
||||
#define DMA_READ_LINE_ENABLE 8
|
||||
#define PCI_MASTER_COMMAND_SELECT 6
|
||||
#define MEM_READ_OR_WRITE 0
|
||||
#define IO_READ_OR_WRITE 1
|
||||
#define CFG_READ_OR_WRITE 2
|
||||
#define PCI_MASTER_START 5
|
||||
#define PCI_MASTER_READ_WRITE 4
|
||||
#define PCI_MASTER_WRITE 0
|
||||
#define PCI_MASTER_READ 1
|
||||
#define PCI_MASTER_BYTE_WRITE_ENABLES 0
|
||||
u32 pcimstaddr;
|
||||
u32 pcimstdata;
|
||||
u32 pcimststat;
|
||||
#define PCI_ARBITER_CLEAR 2
|
||||
#define PCI_EXTERNAL_ARBITER 1
|
||||
#define PCI_HOST_MODE 0
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* dma control, BAR0 + 0x0180 ... array of four structs like this,
|
||||
* for channels 0..3. see also struct net2280_dma: descriptor
|
||||
* that can be loaded into some of these registers.
|
||||
*/
|
||||
struct net2280_dma_regs { /* [11.7] */
|
||||
/* offset 0x0180, 0x01a0, 0x01c0, 0x01e0, */
|
||||
u32 dmactl;
|
||||
#define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25
|
||||
#define DMA_CLEAR_COUNT_ENABLE 21
|
||||
#define DESCRIPTOR_POLLING_RATE 19
|
||||
#define POLL_CONTINUOUS 0
|
||||
#define POLL_1_USEC 1
|
||||
#define POLL_100_USEC 2
|
||||
#define POLL_1_MSEC 3
|
||||
#define DMA_VALID_BIT_POLLING_ENABLE 18
|
||||
#define DMA_VALID_BIT_ENABLE 17
|
||||
#define DMA_SCATTER_GATHER_ENABLE 16
|
||||
#define DMA_OUT_AUTO_START_ENABLE 4
|
||||
#define DMA_PREEMPT_ENABLE 3
|
||||
#define DMA_FIFO_VALIDATE 2
|
||||
#define DMA_ENABLE 1
|
||||
#define DMA_ADDRESS_HOLD 0
|
||||
u32 dmastat;
|
||||
#define DMA_ABORT_DONE_INTERRUPT 27
|
||||
#define DMA_SCATTER_GATHER_DONE_INTERRUPT 25
|
||||
#define DMA_TRANSACTION_DONE_INTERRUPT 24
|
||||
#define DMA_ABORT 1
|
||||
#define DMA_START 0
|
||||
u32 _unused0[2];
|
||||
/* offset 0x0190, 0x01b0, 0x01d0, 0x01f0, */
|
||||
u32 dmacount;
|
||||
#define VALID_BIT 31
|
||||
#define DMA_DIRECTION 30
|
||||
#define DMA_DONE_INTERRUPT_ENABLE 29
|
||||
#define END_OF_CHAIN 28
|
||||
#define DMA_BYTE_COUNT_MASK ((1<<24)-1)
|
||||
#define DMA_BYTE_COUNT 0
|
||||
u32 dmaaddr;
|
||||
u32 dmadesc;
|
||||
u32 _unused1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* dedicated endpoint registers, BAR0 + 0x0200 */
|
||||
|
||||
struct net2280_dep_regs { /* [11.8] */
|
||||
/* offset 0x0200, 0x0210, 0x220, 0x230, 0x240 */
|
||||
u32 dep_cfg;
|
||||
/* offset 0x0204, 0x0214, 0x224, 0x234, 0x244 */
|
||||
u32 dep_rsp;
|
||||
u32 _unused[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs
|
||||
* like this, for ep0 then the configurable endpoints A..F
|
||||
* ep0 reserved for control; E and F have only 64 bytes of fifo
|
||||
*/
|
||||
struct net2280_ep_regs { /* [11.9] */
|
||||
/* offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 */
|
||||
u32 ep_cfg;
|
||||
#define ENDPOINT_BYTE_COUNT 16
|
||||
#define ENDPOINT_ENABLE 10
|
||||
#define ENDPOINT_TYPE 8
|
||||
#define ENDPOINT_DIRECTION 7
|
||||
#define ENDPOINT_NUMBER 0
|
||||
u32 ep_rsp;
|
||||
#define SET_NAK_OUT_PACKETS 15
|
||||
#define SET_EP_HIDE_STATUS_PHASE 14
|
||||
#define SET_EP_FORCE_CRC_ERROR 13
|
||||
#define SET_INTERRUPT_MODE 12
|
||||
#define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11
|
||||
#define SET_NAK_OUT_PACKETS_MODE 10
|
||||
#define SET_ENDPOINT_TOGGLE 9
|
||||
#define SET_ENDPOINT_HALT 8
|
||||
#define CLEAR_NAK_OUT_PACKETS 7
|
||||
#define CLEAR_EP_HIDE_STATUS_PHASE 6
|
||||
#define CLEAR_EP_FORCE_CRC_ERROR 5
|
||||
#define CLEAR_INTERRUPT_MODE 4
|
||||
#define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3
|
||||
#define CLEAR_NAK_OUT_PACKETS_MODE 2
|
||||
#define CLEAR_ENDPOINT_TOGGLE 1
|
||||
#define CLEAR_ENDPOINT_HALT 0
|
||||
u32 ep_irqenb;
|
||||
#define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6
|
||||
#define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5
|
||||
#define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3
|
||||
#define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2
|
||||
#define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1
|
||||
#define DATA_IN_TOKEN_INTERRUPT_ENABLE 0
|
||||
u32 ep_stat;
|
||||
#define FIFO_VALID_COUNT 24
|
||||
#define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22
|
||||
#define TIMEOUT 21
|
||||
#define USB_STALL_SENT 20
|
||||
#define USB_IN_NAK_SENT 19
|
||||
#define USB_IN_ACK_RCVD 18
|
||||
#define USB_OUT_PING_NAK_SENT 17
|
||||
#define USB_OUT_ACK_SENT 16
|
||||
#define FIFO_OVERFLOW 13
|
||||
#define FIFO_UNDERFLOW 12
|
||||
#define FIFO_FULL 11
|
||||
#define FIFO_EMPTY 10
|
||||
#define FIFO_FLUSH 9
|
||||
#define SHORT_PACKET_OUT_DONE_INTERRUPT 6
|
||||
#define SHORT_PACKET_TRANSFERRED_INTERRUPT 5
|
||||
#define NAK_OUT_PACKETS 4
|
||||
#define DATA_PACKET_RECEIVED_INTERRUPT 3
|
||||
#define DATA_PACKET_TRANSMITTED_INTERRUPT 2
|
||||
#define DATA_OUT_PING_TOKEN_INTERRUPT 1
|
||||
#define DATA_IN_TOKEN_INTERRUPT 0
|
||||
/* offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 */
|
||||
u32 ep_avail;
|
||||
u32 ep_data;
|
||||
u32 _unused0[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* __LINUX_USB_NET2280_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* OF helpers for usb devices.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_OF_H
|
||||
#define __LINUX_USB_OF_H
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
struct usb_device;
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0);
|
||||
bool of_usb_host_tpl_support(struct device_node *np);
|
||||
int of_usb_update_otg_caps(struct device_node *np,
|
||||
struct usb_otg_caps *otg_caps);
|
||||
enum usb_port_connect_type usb_of_get_connect_type(struct usb_device *hub, int port1);
|
||||
struct device_node *usb_of_get_device_node(struct usb_device *hub, int port1);
|
||||
bool usb_of_has_combined_node(struct usb_device *udev);
|
||||
struct device_node *usb_of_get_interface_node(struct usb_device *udev,
|
||||
u8 config, u8 ifnum);
|
||||
struct device *usb_of_get_companion_dev(struct device *dev);
|
||||
#else
|
||||
static inline enum usb_dr_mode
|
||||
of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0)
|
||||
{
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
}
|
||||
static inline bool of_usb_host_tpl_support(struct device_node *np)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int of_usb_update_otg_caps(struct device_node *np,
|
||||
struct usb_otg_caps *otg_caps)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline enum usb_port_connect_type
|
||||
usb_of_get_connect_type(const struct usb_device *hub, int port1)
|
||||
{
|
||||
return USB_PORT_CONNECT_TYPE_UNKNOWN;
|
||||
}
|
||||
static inline struct device_node *
|
||||
usb_of_get_device_node(struct usb_device *hub, int port1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline bool usb_of_has_combined_node(struct usb_device *udev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline struct device_node *
|
||||
usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct device *usb_of_get_companion_dev(struct device *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT)
|
||||
enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np);
|
||||
#else
|
||||
static inline enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np)
|
||||
{
|
||||
return USBPHY_INTERFACE_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_OF_H */
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*/
|
||||
|
||||
#ifndef __USB_CORE_OHCI_PDRIVER_H
|
||||
#define __USB_CORE_OHCI_PDRIVER_H
|
||||
|
||||
/**
|
||||
* struct usb_ohci_pdata - platform_data for generic ohci driver
|
||||
*
|
||||
* @big_endian_desc: BE descriptors
|
||||
* @big_endian_mmio: BE registers
|
||||
* @no_big_frame_no: no big endian frame_no shift
|
||||
* @num_ports: number of ports
|
||||
*
|
||||
* These are general configuration options for the OHCI controller. All of
|
||||
* these options are activating more or less workarounds for some hardware.
|
||||
*/
|
||||
struct usb_ohci_pdata {
|
||||
unsigned big_endian_desc:1;
|
||||
unsigned big_endian_mmio:1;
|
||||
unsigned no_big_frame_no:1;
|
||||
unsigned int num_ports;
|
||||
|
||||
/* Turn on all power and clocks */
|
||||
int (*power_on)(struct platform_device *pdev);
|
||||
/* Turn off all power and clocks */
|
||||
void (*power_off)(struct platform_device *pdev);
|
||||
/* Turn on only VBUS suspend power and hotplug detection,
|
||||
* turn off everything else */
|
||||
void (*power_suspend)(struct platform_device *pdev);
|
||||
};
|
||||
|
||||
#endif /* __USB_CORE_OHCI_PDRIVER_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __LINUX_USB_ONBOARD_DEV_H
|
||||
#define __LINUX_USB_ONBOARD_DEV_H
|
||||
|
||||
struct usb_device;
|
||||
struct list_head;
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV)
|
||||
void onboard_dev_create_pdevs(struct usb_device *parent_dev, struct list_head *pdev_list);
|
||||
void onboard_dev_destroy_pdevs(struct list_head *pdev_list);
|
||||
#else
|
||||
static inline void onboard_dev_create_pdevs(struct usb_device *parent_dev,
|
||||
struct list_head *pdev_list) {}
|
||||
static inline void onboard_dev_destroy_pdevs(struct list_head *pdev_list) {}
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_ONBOARD_DEV_H */
|
||||
@@ -0,0 +1,312 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_OTG_FSM_H
|
||||
#define __LINUX_USB_OTG_FSM_H
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define PROTO_UNDEF (0)
|
||||
#define PROTO_HOST (1)
|
||||
#define PROTO_GADGET (2)
|
||||
|
||||
#define OTG_STS_SELECTOR 0xF000 /* OTG status selector, according to
|
||||
* OTG and EH 2.0 Chapter 6.2.3
|
||||
* Table:6-4
|
||||
*/
|
||||
|
||||
#define HOST_REQUEST_FLAG 1 /* Host request flag, according to
|
||||
* OTG and EH 2.0 Charpter 6.2.3
|
||||
* Table:6-5
|
||||
*/
|
||||
|
||||
#define T_HOST_REQ_POLL (1500) /* 1500ms, HNP polling interval */
|
||||
|
||||
enum otg_fsm_timer {
|
||||
/* Standard OTG timers */
|
||||
A_WAIT_VRISE,
|
||||
A_WAIT_VFALL,
|
||||
A_WAIT_BCON,
|
||||
A_AIDL_BDIS,
|
||||
B_ASE0_BRST,
|
||||
A_BIDL_ADIS,
|
||||
B_AIDL_BDIS,
|
||||
|
||||
/* Auxiliary timers */
|
||||
B_SE0_SRP,
|
||||
B_SRP_FAIL,
|
||||
A_WAIT_ENUM,
|
||||
B_DATA_PLS,
|
||||
B_SSEND_SRP,
|
||||
|
||||
NUM_OTG_FSM_TIMERS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct otg_fsm - OTG state machine according to the OTG spec
|
||||
*
|
||||
* OTG hardware Inputs
|
||||
*
|
||||
* Common inputs for A and B device
|
||||
* @id: TRUE for B-device, FALSE for A-device.
|
||||
* @adp_change: TRUE when current ADP measurement (n) value, compared to the
|
||||
* ADP measurement taken at n-2, differs by more than CADP_THR
|
||||
* @power_up: TRUE when the OTG device first powers up its USB system and
|
||||
* ADP measurement taken if ADP capable
|
||||
*
|
||||
* A-Device state inputs
|
||||
* @a_srp_det: TRUE if the A-device detects SRP
|
||||
* @a_vbus_vld: TRUE when VBUS voltage is in regulation
|
||||
* @b_conn: TRUE if the A-device detects connection from the B-device
|
||||
* @a_bus_resume: TRUE when the B-device detects that the A-device is signaling
|
||||
* a resume (K state)
|
||||
* B-Device state inputs
|
||||
* @a_bus_suspend: TRUE when the B-device detects that the A-device has put the
|
||||
* bus into suspend
|
||||
* @a_conn: TRUE if the B-device detects a connection from the A-device
|
||||
* @b_se0_srp: TRUE when the line has been at SE0 for more than the minimum
|
||||
* time before generating SRP
|
||||
* @b_ssend_srp: TRUE when the VBUS has been below VOTG_SESS_VLD for more than
|
||||
* the minimum time before generating SRP
|
||||
* @b_sess_vld: TRUE when the B-device detects that the voltage on VBUS is
|
||||
* above VOTG_SESS_VLD
|
||||
* @test_device: TRUE when the B-device switches to B-Host and detects an OTG
|
||||
* test device. This must be set by host/hub driver
|
||||
*
|
||||
* Application inputs (A-Device)
|
||||
* @a_bus_drop: TRUE when A-device application needs to power down the bus
|
||||
* @a_bus_req: TRUE when A-device application wants to use the bus.
|
||||
* FALSE to suspend the bus
|
||||
*
|
||||
* Application inputs (B-Device)
|
||||
* @b_bus_req: TRUE during the time that the Application running on the
|
||||
* B-device wants to use the bus
|
||||
*
|
||||
* Auxiliary inputs (OTG v1.3 only. Obsolete now.)
|
||||
* @a_sess_vld: TRUE if the A-device detects that VBUS is above VA_SESS_VLD
|
||||
* @b_bus_suspend: TRUE when the A-device detects that the B-device has put
|
||||
* the bus into suspend
|
||||
* @b_bus_resume: TRUE when the A-device detects that the B-device is signaling
|
||||
* resume on the bus
|
||||
*
|
||||
* OTG Output status. Read only for users. Updated by OTG FSM helpers defined
|
||||
* in this file
|
||||
*
|
||||
* Outputs for Both A and B device
|
||||
* @drv_vbus: TRUE when A-device is driving VBUS
|
||||
* @loc_conn: TRUE when the local device has signaled that it is connected
|
||||
* to the bus
|
||||
* @loc_sof: TRUE when the local device is generating activity on the bus
|
||||
* @adp_prb: TRUE when the local device is in the process of doing
|
||||
* ADP probing
|
||||
*
|
||||
* Outputs for B-device state
|
||||
* @adp_sns: TRUE when the B-device is in the process of carrying out
|
||||
* ADP sensing
|
||||
* @data_pulse: TRUE when the B-device is performing data line pulsing
|
||||
*
|
||||
* Internal Variables
|
||||
*
|
||||
* a_set_b_hnp_en: TRUE when the A-device has successfully set the
|
||||
* b_hnp_enable bit in the B-device.
|
||||
* Unused as OTG fsm uses otg->host->b_hnp_enable instead
|
||||
* b_srp_done: TRUE when the B-device has completed initiating SRP
|
||||
* b_hnp_enable: TRUE when the B-device has accepted the
|
||||
* SetFeature(b_hnp_enable) B-device.
|
||||
* Unused as OTG fsm uses otg->gadget->b_hnp_enable instead
|
||||
* a_clr_err: Asserted (by application ?) to clear a_vbus_err due to an
|
||||
* overcurrent condition and causes the A-device to transition
|
||||
* to a_wait_vfall
|
||||
*/
|
||||
struct otg_fsm {
|
||||
/* Input */
|
||||
int id;
|
||||
int adp_change;
|
||||
int power_up;
|
||||
int a_srp_det;
|
||||
int a_vbus_vld;
|
||||
int b_conn;
|
||||
int a_bus_resume;
|
||||
int a_bus_suspend;
|
||||
int a_conn;
|
||||
int b_se0_srp;
|
||||
int b_ssend_srp;
|
||||
int b_sess_vld;
|
||||
int test_device;
|
||||
int a_bus_drop;
|
||||
int a_bus_req;
|
||||
int b_bus_req;
|
||||
|
||||
/* Auxiliary inputs */
|
||||
int a_sess_vld;
|
||||
int b_bus_resume;
|
||||
int b_bus_suspend;
|
||||
|
||||
/* Output */
|
||||
int drv_vbus;
|
||||
int loc_conn;
|
||||
int loc_sof;
|
||||
int adp_prb;
|
||||
int adp_sns;
|
||||
int data_pulse;
|
||||
|
||||
/* Internal variables */
|
||||
int a_set_b_hnp_en;
|
||||
int b_srp_done;
|
||||
int b_hnp_enable;
|
||||
int a_clr_err;
|
||||
|
||||
/* Informative variables. All unused as of now */
|
||||
int a_bus_drop_inf;
|
||||
int a_bus_req_inf;
|
||||
int a_clr_err_inf;
|
||||
int b_bus_req_inf;
|
||||
/* Auxiliary informative variables */
|
||||
int a_suspend_req_inf;
|
||||
|
||||
/* Timeout indicator for timers */
|
||||
int a_wait_vrise_tmout;
|
||||
int a_wait_vfall_tmout;
|
||||
int a_wait_bcon_tmout;
|
||||
int a_aidl_bdis_tmout;
|
||||
int b_ase0_brst_tmout;
|
||||
int a_bidl_adis_tmout;
|
||||
|
||||
struct otg_fsm_ops *ops;
|
||||
struct usb_otg *otg;
|
||||
|
||||
/* Current usb protocol used: 0:undefine; 1:host; 2:client */
|
||||
int protocol;
|
||||
struct mutex lock;
|
||||
u8 *host_req_flag;
|
||||
struct delayed_work hnp_polling_work;
|
||||
bool hnp_work_inited;
|
||||
bool state_changed;
|
||||
};
|
||||
|
||||
struct otg_fsm_ops {
|
||||
void (*chrg_vbus)(struct otg_fsm *fsm, int on);
|
||||
void (*drv_vbus)(struct otg_fsm *fsm, int on);
|
||||
void (*loc_conn)(struct otg_fsm *fsm, int on);
|
||||
void (*loc_sof)(struct otg_fsm *fsm, int on);
|
||||
void (*start_pulse)(struct otg_fsm *fsm);
|
||||
void (*start_adp_prb)(struct otg_fsm *fsm);
|
||||
void (*start_adp_sns)(struct otg_fsm *fsm);
|
||||
void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
|
||||
void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
|
||||
int (*start_host)(struct otg_fsm *fsm, int on);
|
||||
int (*start_gadget)(struct otg_fsm *fsm, int on);
|
||||
};
|
||||
|
||||
|
||||
static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->chrg_vbus)
|
||||
return -EOPNOTSUPP;
|
||||
fsm->ops->chrg_vbus(fsm, on);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_drv_vbus(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->drv_vbus)
|
||||
return -EOPNOTSUPP;
|
||||
if (fsm->drv_vbus != on) {
|
||||
fsm->drv_vbus = on;
|
||||
fsm->ops->drv_vbus(fsm, on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_loc_conn(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->loc_conn)
|
||||
return -EOPNOTSUPP;
|
||||
if (fsm->loc_conn != on) {
|
||||
fsm->loc_conn = on;
|
||||
fsm->ops->loc_conn(fsm, on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_loc_sof(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->loc_sof)
|
||||
return -EOPNOTSUPP;
|
||||
if (fsm->loc_sof != on) {
|
||||
fsm->loc_sof = on;
|
||||
fsm->ops->loc_sof(fsm, on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_start_pulse(struct otg_fsm *fsm)
|
||||
{
|
||||
if (!fsm->ops->start_pulse)
|
||||
return -EOPNOTSUPP;
|
||||
if (!fsm->data_pulse) {
|
||||
fsm->data_pulse = 1;
|
||||
fsm->ops->start_pulse(fsm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_start_adp_prb(struct otg_fsm *fsm)
|
||||
{
|
||||
if (!fsm->ops->start_adp_prb)
|
||||
return -EOPNOTSUPP;
|
||||
if (!fsm->adp_prb) {
|
||||
fsm->adp_sns = 0;
|
||||
fsm->adp_prb = 1;
|
||||
fsm->ops->start_adp_prb(fsm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_start_adp_sns(struct otg_fsm *fsm)
|
||||
{
|
||||
if (!fsm->ops->start_adp_sns)
|
||||
return -EOPNOTSUPP;
|
||||
if (!fsm->adp_sns) {
|
||||
fsm->adp_sns = 1;
|
||||
fsm->ops->start_adp_sns(fsm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
|
||||
{
|
||||
if (!fsm->ops->add_timer)
|
||||
return -EOPNOTSUPP;
|
||||
fsm->ops->add_timer(fsm, timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
|
||||
{
|
||||
if (!fsm->ops->del_timer)
|
||||
return -EOPNOTSUPP;
|
||||
fsm->ops->del_timer(fsm, timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int otg_start_host(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->start_host)
|
||||
return -EOPNOTSUPP;
|
||||
return fsm->ops->start_host(fsm, on);
|
||||
}
|
||||
|
||||
static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
|
||||
{
|
||||
if (!fsm->ops->start_gadget)
|
||||
return -EOPNOTSUPP;
|
||||
return fsm->ops->start_gadget(fsm, on);
|
||||
}
|
||||
|
||||
int otg_statemachine(struct otg_fsm *fsm);
|
||||
|
||||
#endif /* __LINUX_USB_OTG_FSM_H */
|
||||
@@ -0,0 +1,133 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* USB OTG (On The Go) defines */
|
||||
/*
|
||||
*
|
||||
* These APIs may be used between USB controllers. USB device drivers
|
||||
* (for either host or peripheral roles) don't use these calls; they
|
||||
* continue to use just usb_device and usb_gadget.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_OTG_H
|
||||
#define __LINUX_USB_OTG_H
|
||||
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
struct usb_otg {
|
||||
u8 default_a;
|
||||
|
||||
struct phy *phy;
|
||||
/* old usb_phy interface */
|
||||
struct usb_phy *usb_phy;
|
||||
struct usb_bus *host;
|
||||
struct usb_gadget *gadget;
|
||||
|
||||
enum usb_otg_state state;
|
||||
|
||||
/* bind/unbind the host controller */
|
||||
int (*set_host)(struct usb_otg *otg, struct usb_bus *host);
|
||||
|
||||
/* bind/unbind the peripheral controller */
|
||||
int (*set_peripheral)(struct usb_otg *otg,
|
||||
struct usb_gadget *gadget);
|
||||
|
||||
/* effective for A-peripheral, ignored for B devices */
|
||||
int (*set_vbus)(struct usb_otg *otg, bool enabled);
|
||||
|
||||
/* for B devices only: start session with A-Host */
|
||||
int (*start_srp)(struct usb_otg *otg);
|
||||
|
||||
/* start or continue HNP role switch */
|
||||
int (*start_hnp)(struct usb_otg *otg);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct usb_otg_caps - describes the otg capabilities of the device
|
||||
* @otg_rev: The OTG revision number the device is compliant with, it's
|
||||
* in binary-coded decimal (i.e. 2.0 is 0200H).
|
||||
* @hnp_support: Indicates if the device supports HNP.
|
||||
* @srp_support: Indicates if the device supports SRP.
|
||||
* @adp_support: Indicates if the device supports ADP.
|
||||
*/
|
||||
struct usb_otg_caps {
|
||||
u16 otg_rev;
|
||||
bool hnp_support;
|
||||
bool srp_support;
|
||||
bool adp_support;
|
||||
};
|
||||
|
||||
extern const char *usb_otg_state_string(enum usb_otg_state state);
|
||||
|
||||
/* Context: can sleep */
|
||||
static inline int
|
||||
otg_start_hnp(struct usb_otg *otg)
|
||||
{
|
||||
if (otg && otg->start_hnp)
|
||||
return otg->start_hnp(otg);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* Context: can sleep */
|
||||
static inline int
|
||||
otg_set_vbus(struct usb_otg *otg, bool enabled)
|
||||
{
|
||||
if (otg && otg->set_vbus)
|
||||
return otg->set_vbus(otg, enabled);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* for HCDs */
|
||||
static inline int
|
||||
otg_set_host(struct usb_otg *otg, struct usb_bus *host)
|
||||
{
|
||||
if (otg && otg->set_host)
|
||||
return otg->set_host(otg, host);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* for usb peripheral controller drivers */
|
||||
|
||||
/* Context: can sleep */
|
||||
static inline int
|
||||
otg_set_peripheral(struct usb_otg *otg, struct usb_gadget *periph)
|
||||
{
|
||||
if (otg && otg->set_peripheral)
|
||||
return otg->set_peripheral(otg, periph);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int
|
||||
otg_start_srp(struct usb_otg *otg)
|
||||
{
|
||||
if (otg && otg->start_srp)
|
||||
return otg->start_srp(otg);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* for OTG controller drivers (and maybe other stuff) */
|
||||
extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
|
||||
|
||||
enum usb_dr_mode {
|
||||
USB_DR_MODE_UNKNOWN,
|
||||
USB_DR_MODE_HOST,
|
||||
USB_DR_MODE_PERIPHERAL,
|
||||
USB_DR_MODE_OTG,
|
||||
};
|
||||
|
||||
/**
|
||||
* usb_get_dr_mode - Get dual role mode for given device
|
||||
* @dev: Pointer to the given device
|
||||
*
|
||||
* The function gets phy interface string from property 'dr_mode',
|
||||
* and returns the corresponding enum usb_dr_mode
|
||||
*/
|
||||
extern enum usb_dr_mode usb_get_dr_mode(struct device *dev);
|
||||
extern enum usb_dr_mode usb_get_role_switch_default_mode(struct device *dev);
|
||||
|
||||
#endif /* __LINUX_USB_OTG_H */
|
||||
@@ -0,0 +1,727 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright 2015-2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PD_H
|
||||
#define __LINUX_USB_PD_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb/typec.h>
|
||||
|
||||
/* USB PD Messages */
|
||||
enum pd_ctrl_msg_type {
|
||||
/* 0 Reserved */
|
||||
PD_CTRL_GOOD_CRC = 1,
|
||||
PD_CTRL_GOTO_MIN = 2,
|
||||
PD_CTRL_ACCEPT = 3,
|
||||
PD_CTRL_REJECT = 4,
|
||||
PD_CTRL_PING = 5,
|
||||
PD_CTRL_PS_RDY = 6,
|
||||
PD_CTRL_GET_SOURCE_CAP = 7,
|
||||
PD_CTRL_GET_SINK_CAP = 8,
|
||||
PD_CTRL_DR_SWAP = 9,
|
||||
PD_CTRL_PR_SWAP = 10,
|
||||
PD_CTRL_VCONN_SWAP = 11,
|
||||
PD_CTRL_WAIT = 12,
|
||||
PD_CTRL_SOFT_RESET = 13,
|
||||
/* 14-15 Reserved */
|
||||
PD_CTRL_NOT_SUPP = 16,
|
||||
PD_CTRL_GET_SOURCE_CAP_EXT = 17,
|
||||
PD_CTRL_GET_STATUS = 18,
|
||||
PD_CTRL_FR_SWAP = 19,
|
||||
PD_CTRL_GET_PPS_STATUS = 20,
|
||||
PD_CTRL_GET_COUNTRY_CODES = 21,
|
||||
PD_CTRL_GET_SINK_CAP_EXT = 22,
|
||||
/* 23 Reserved */
|
||||
PD_CTRL_GET_REVISION = 24,
|
||||
/* 25-31 Reserved */
|
||||
};
|
||||
|
||||
enum pd_data_msg_type {
|
||||
/* 0 Reserved */
|
||||
PD_DATA_SOURCE_CAP = 1,
|
||||
PD_DATA_REQUEST = 2,
|
||||
PD_DATA_BIST = 3,
|
||||
PD_DATA_SINK_CAP = 4,
|
||||
PD_DATA_BATT_STATUS = 5,
|
||||
PD_DATA_ALERT = 6,
|
||||
PD_DATA_GET_COUNTRY_INFO = 7,
|
||||
PD_DATA_ENTER_USB = 8,
|
||||
/* 9-11 Reserved */
|
||||
PD_DATA_REVISION = 12,
|
||||
/* 13-14 Reserved */
|
||||
PD_DATA_VENDOR_DEF = 15,
|
||||
/* 16-31 Reserved */
|
||||
};
|
||||
|
||||
enum pd_ext_msg_type {
|
||||
/* 0 Reserved */
|
||||
PD_EXT_SOURCE_CAP_EXT = 1,
|
||||
PD_EXT_STATUS = 2,
|
||||
PD_EXT_GET_BATT_CAP = 3,
|
||||
PD_EXT_GET_BATT_STATUS = 4,
|
||||
PD_EXT_BATT_CAP = 5,
|
||||
PD_EXT_GET_MANUFACTURER_INFO = 6,
|
||||
PD_EXT_MANUFACTURER_INFO = 7,
|
||||
PD_EXT_SECURITY_REQUEST = 8,
|
||||
PD_EXT_SECURITY_RESPONSE = 9,
|
||||
PD_EXT_FW_UPDATE_REQUEST = 10,
|
||||
PD_EXT_FW_UPDATE_RESPONSE = 11,
|
||||
PD_EXT_PPS_STATUS = 12,
|
||||
PD_EXT_COUNTRY_INFO = 13,
|
||||
PD_EXT_COUNTRY_CODES = 14,
|
||||
PD_EXT_SINK_CAP_EXT = 15,
|
||||
/* 16-31 Reserved */
|
||||
};
|
||||
|
||||
#define PD_REV10 0x0
|
||||
#define PD_REV20 0x1
|
||||
#define PD_REV30 0x2
|
||||
#define PD_MAX_REV PD_REV30
|
||||
|
||||
#define PD_HEADER_EXT_HDR BIT(15)
|
||||
#define PD_HEADER_CNT_SHIFT 12
|
||||
#define PD_HEADER_CNT_MASK 0x7
|
||||
#define PD_HEADER_ID_SHIFT 9
|
||||
#define PD_HEADER_ID_MASK 0x7
|
||||
#define PD_HEADER_PWR_ROLE BIT(8)
|
||||
#define PD_HEADER_REV_SHIFT 6
|
||||
#define PD_HEADER_REV_MASK 0x3
|
||||
#define PD_HEADER_DATA_ROLE BIT(5)
|
||||
#define PD_HEADER_TYPE_SHIFT 0
|
||||
#define PD_HEADER_TYPE_MASK 0x1f
|
||||
|
||||
#define PD_HEADER(type, pwr, data, rev, id, cnt, ext_hdr) \
|
||||
((((type) & PD_HEADER_TYPE_MASK) << PD_HEADER_TYPE_SHIFT) | \
|
||||
((pwr) == TYPEC_SOURCE ? PD_HEADER_PWR_ROLE : 0) | \
|
||||
((data) == TYPEC_HOST ? PD_HEADER_DATA_ROLE : 0) | \
|
||||
(rev << PD_HEADER_REV_SHIFT) | \
|
||||
(((id) & PD_HEADER_ID_MASK) << PD_HEADER_ID_SHIFT) | \
|
||||
(((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT) | \
|
||||
((ext_hdr) ? PD_HEADER_EXT_HDR : 0))
|
||||
|
||||
#define PD_HEADER_LE(type, pwr, data, rev, id, cnt) \
|
||||
cpu_to_le16(PD_HEADER((type), (pwr), (data), (rev), (id), (cnt), (0)))
|
||||
|
||||
static inline unsigned int pd_header_cnt(u16 header)
|
||||
{
|
||||
return (header >> PD_HEADER_CNT_SHIFT) & PD_HEADER_CNT_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_cnt_le(__le16 header)
|
||||
{
|
||||
return pd_header_cnt(le16_to_cpu(header));
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_type(u16 header)
|
||||
{
|
||||
return (header >> PD_HEADER_TYPE_SHIFT) & PD_HEADER_TYPE_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_type_le(__le16 header)
|
||||
{
|
||||
return pd_header_type(le16_to_cpu(header));
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_msgid(u16 header)
|
||||
{
|
||||
return (header >> PD_HEADER_ID_SHIFT) & PD_HEADER_ID_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_msgid_le(__le16 header)
|
||||
{
|
||||
return pd_header_msgid(le16_to_cpu(header));
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_rev(u16 header)
|
||||
{
|
||||
return (header >> PD_HEADER_REV_SHIFT) & PD_HEADER_REV_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_header_rev_le(__le16 header)
|
||||
{
|
||||
return pd_header_rev(le16_to_cpu(header));
|
||||
}
|
||||
|
||||
#define PD_EXT_HDR_CHUNKED BIT(15)
|
||||
#define PD_EXT_HDR_CHUNK_NUM_SHIFT 11
|
||||
#define PD_EXT_HDR_CHUNK_NUM_MASK 0xf
|
||||
#define PD_EXT_HDR_REQ_CHUNK BIT(10)
|
||||
#define PD_EXT_HDR_DATA_SIZE_SHIFT 0
|
||||
#define PD_EXT_HDR_DATA_SIZE_MASK 0x1ff
|
||||
|
||||
#define PD_EXT_HDR(data_size, req_chunk, chunk_num, chunked) \
|
||||
((((data_size) & PD_EXT_HDR_DATA_SIZE_MASK) << PD_EXT_HDR_DATA_SIZE_SHIFT) | \
|
||||
((req_chunk) ? PD_EXT_HDR_REQ_CHUNK : 0) | \
|
||||
(((chunk_num) & PD_EXT_HDR_CHUNK_NUM_MASK) << PD_EXT_HDR_CHUNK_NUM_SHIFT) | \
|
||||
((chunked) ? PD_EXT_HDR_CHUNKED : 0))
|
||||
|
||||
#define PD_EXT_HDR_LE(data_size, req_chunk, chunk_num, chunked) \
|
||||
cpu_to_le16(PD_EXT_HDR((data_size), (req_chunk), (chunk_num), (chunked)))
|
||||
|
||||
static inline unsigned int pd_ext_header_chunk_num(u16 ext_header)
|
||||
{
|
||||
return (ext_header >> PD_EXT_HDR_CHUNK_NUM_SHIFT) &
|
||||
PD_EXT_HDR_CHUNK_NUM_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_ext_header_data_size(u16 ext_header)
|
||||
{
|
||||
return (ext_header >> PD_EXT_HDR_DATA_SIZE_SHIFT) &
|
||||
PD_EXT_HDR_DATA_SIZE_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pd_ext_header_data_size_le(__le16 ext_header)
|
||||
{
|
||||
return pd_ext_header_data_size(le16_to_cpu(ext_header));
|
||||
}
|
||||
|
||||
#define PD_MAX_PAYLOAD 7
|
||||
#define PD_EXT_MAX_CHUNK_DATA 26
|
||||
|
||||
/**
|
||||
* struct pd_chunked_ext_message_data - PD chunked extended message data as
|
||||
* seen on wire
|
||||
* @header: PD extended message header
|
||||
* @data: PD extended message data
|
||||
*/
|
||||
struct pd_chunked_ext_message_data {
|
||||
__le16 header;
|
||||
u8 data[PD_EXT_MAX_CHUNK_DATA];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct pd_message - PD message as seen on wire
|
||||
* @header: PD message header
|
||||
* @payload: PD message payload
|
||||
* @ext_msg: PD message chunked extended message data
|
||||
*/
|
||||
struct pd_message {
|
||||
__le16 header;
|
||||
union {
|
||||
__le32 payload[PD_MAX_PAYLOAD];
|
||||
struct pd_chunked_ext_message_data ext_msg;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* count_chunked_data_objs - Helper to calculate number of Data Objects on a 4
|
||||
* byte boundary.
|
||||
* @size: Size of data block for extended message. Should *not* include extended
|
||||
* header size.
|
||||
*/
|
||||
static inline u8 count_chunked_data_objs(u32 size)
|
||||
{
|
||||
size += offsetof(struct pd_chunked_ext_message_data, data);
|
||||
return ((size / 4) + (size % 4 ? 1 : 0));
|
||||
}
|
||||
|
||||
/* Sink Caps Extended Data Block Version */
|
||||
#define SKEDB_VER_1_0 1
|
||||
|
||||
/* Sink Caps Extended Sink Modes */
|
||||
#define SINK_MODE_PPS BIT(0)
|
||||
#define SINK_MODE_VBUS BIT(1)
|
||||
#define SINK_MODE_AC_SUPPLY BIT(2)
|
||||
#define SINK_MODE_BATT BIT(3)
|
||||
#define SINK_MODE_BATT_UL BIT(4) /* Unlimited battery power supply */
|
||||
#define SINK_MODE_AVS BIT(5)
|
||||
|
||||
/**
|
||||
* struct sink_caps_ext_msg - Sink extended capability PD message
|
||||
* @vid: Vendor ID
|
||||
* @pid: Product ID
|
||||
* @xid: Value assigned by USB-IF for product
|
||||
* @fw: Firmware version
|
||||
* @hw: Hardware version
|
||||
* @skedb_ver: Sink Caps Extended Data Block (SKEDB) Version
|
||||
* @load_step: Indicates the load step slew rate.
|
||||
* @load_char: Sink overload characteristics
|
||||
* @compliance: Types of sources the sink has been tested & certified on
|
||||
* @touch_temp: Indicates the IEC standard to which the touch temperature
|
||||
* conforms to (if applicable).
|
||||
* @batt_info: Indicates number batteries and hot swappable ports
|
||||
* @modes: Charging caps & power sources supported
|
||||
* @spr_min_pdp: Sink Minimum PDP for SPR mode
|
||||
* @spr_op_pdp: Sink Operational PDP for SPR mode
|
||||
* @spr_max_pdp: Sink Maximum PDP for SPR mode
|
||||
* @epr_min_pdp: Sink Minimum PDP for EPR mode
|
||||
* @epr_op_pdp: Sink Operational PDP for EPR mode
|
||||
* @epr_max_pdp: Sink Maximum PDP for EPR mode
|
||||
*/
|
||||
struct sink_caps_ext_msg {
|
||||
__le16 vid;
|
||||
__le16 pid;
|
||||
__le32 xid;
|
||||
u8 fw;
|
||||
u8 hw;
|
||||
u8 skedb_ver;
|
||||
u8 load_step;
|
||||
__le16 load_char;
|
||||
u8 compliance;
|
||||
u8 touch_temp;
|
||||
u8 batt_info;
|
||||
u8 modes;
|
||||
u8 spr_min_pdp;
|
||||
u8 spr_op_pdp;
|
||||
u8 spr_max_pdp;
|
||||
u8 epr_min_pdp;
|
||||
u8 epr_op_pdp;
|
||||
u8 epr_max_pdp;
|
||||
} __packed;
|
||||
|
||||
/* PDO: Power Data Object */
|
||||
#define PDO_MAX_OBJECTS 7
|
||||
|
||||
enum pd_pdo_type {
|
||||
PDO_TYPE_FIXED = 0,
|
||||
PDO_TYPE_BATT = 1,
|
||||
PDO_TYPE_VAR = 2,
|
||||
PDO_TYPE_APDO = 3,
|
||||
};
|
||||
|
||||
#define PDO_TYPE_SHIFT 30
|
||||
#define PDO_TYPE_MASK 0x3
|
||||
|
||||
#define PDO_TYPE(t) ((t) << PDO_TYPE_SHIFT)
|
||||
|
||||
#define PDO_VOLT_MASK 0x3ff
|
||||
#define PDO_CURR_MASK 0x3ff
|
||||
#define PDO_PWR_MASK 0x3ff
|
||||
|
||||
#define PDO_FIXED_DUAL_ROLE BIT(29) /* Power role swap supported */
|
||||
#define PDO_FIXED_SUSPEND BIT(28) /* USB Suspend supported (Source) */
|
||||
#define PDO_FIXED_HIGHER_CAP BIT(28) /* Requires more than vSafe5V (Sink) */
|
||||
#define PDO_FIXED_EXTPOWER BIT(27) /* Externally powered */
|
||||
#define PDO_FIXED_USB_COMM BIT(26) /* USB communications capable */
|
||||
#define PDO_FIXED_DATA_SWAP BIT(25) /* Data role swap supported */
|
||||
#define PDO_FIXED_UNCHUNK_EXT BIT(24) /* Unchunked Extended Message supported (Source) */
|
||||
#define PDO_FIXED_FRS_CURR_MASK (BIT(24) | BIT(23)) /* FR_Swap Current (Sink) */
|
||||
#define PDO_FIXED_FRS_CURR_SHIFT 23
|
||||
#define PDO_FIXED_PEAK_CURR_SHIFT 20
|
||||
#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */
|
||||
#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */
|
||||
|
||||
#define PDO_FIXED_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT)
|
||||
#define PDO_FIXED_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT)
|
||||
|
||||
#define PDO_FIXED(mv, ma, flags) \
|
||||
(PDO_TYPE(PDO_TYPE_FIXED) | (flags) | \
|
||||
PDO_FIXED_VOLT(mv) | PDO_FIXED_CURR(ma))
|
||||
|
||||
#define VSAFE5V 5000 /* mv units */
|
||||
|
||||
#define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */
|
||||
#define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */
|
||||
#define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */
|
||||
|
||||
#define PDO_BATT_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MIN_VOLT_SHIFT)
|
||||
#define PDO_BATT_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MAX_VOLT_SHIFT)
|
||||
#define PDO_BATT_MAX_POWER(mw) ((((mw) / 250) & PDO_PWR_MASK) << PDO_BATT_MAX_PWR_SHIFT)
|
||||
|
||||
#define PDO_BATT(min_mv, max_mv, max_mw) \
|
||||
(PDO_TYPE(PDO_TYPE_BATT) | PDO_BATT_MIN_VOLT(min_mv) | \
|
||||
PDO_BATT_MAX_VOLT(max_mv) | PDO_BATT_MAX_POWER(max_mw))
|
||||
|
||||
#define PDO_VAR_MAX_VOLT_SHIFT 20 /* 50mV units */
|
||||
#define PDO_VAR_MIN_VOLT_SHIFT 10 /* 50mV units */
|
||||
#define PDO_VAR_MAX_CURR_SHIFT 0 /* 10mA units */
|
||||
|
||||
#define PDO_VAR_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MIN_VOLT_SHIFT)
|
||||
#define PDO_VAR_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MAX_VOLT_SHIFT)
|
||||
#define PDO_VAR_MAX_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_VAR_MAX_CURR_SHIFT)
|
||||
|
||||
#define PDO_VAR(min_mv, max_mv, max_ma) \
|
||||
(PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \
|
||||
PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma))
|
||||
|
||||
enum pd_apdo_type {
|
||||
APDO_TYPE_PPS = 0,
|
||||
APDO_TYPE_EPR_AVS = 1,
|
||||
APDO_TYPE_SPR_AVS = 2,
|
||||
};
|
||||
|
||||
#define PDO_APDO_TYPE_SHIFT 28
|
||||
#define PDO_APDO_TYPE_MASK 0x3
|
||||
|
||||
#define PDO_APDO_TYPE(t) ((t) << PDO_APDO_TYPE_SHIFT)
|
||||
|
||||
#define PDO_PPS_APDO_MAX_VOLT_SHIFT 17 /* 100mV units */
|
||||
#define PDO_PPS_APDO_MIN_VOLT_SHIFT 8 /* 100mV units */
|
||||
#define PDO_PPS_APDO_MAX_CURR_SHIFT 0 /* 50mA units */
|
||||
|
||||
#define PDO_PPS_APDO_VOLT_MASK 0xff
|
||||
#define PDO_PPS_APDO_CURR_MASK 0x7f
|
||||
|
||||
#define PDO_PPS_APDO_MIN_VOLT(mv) \
|
||||
((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MIN_VOLT_SHIFT)
|
||||
#define PDO_PPS_APDO_MAX_VOLT(mv) \
|
||||
((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MAX_VOLT_SHIFT)
|
||||
#define PDO_PPS_APDO_MAX_CURR(ma) \
|
||||
((((ma) / 50) & PDO_PPS_APDO_CURR_MASK) << PDO_PPS_APDO_MAX_CURR_SHIFT)
|
||||
|
||||
#define PDO_PPS_APDO(min_mv, max_mv, max_ma) \
|
||||
(PDO_TYPE(PDO_TYPE_APDO) | PDO_APDO_TYPE(APDO_TYPE_PPS) | \
|
||||
PDO_PPS_APDO_MIN_VOLT(min_mv) | PDO_PPS_APDO_MAX_VOLT(max_mv) | \
|
||||
PDO_PPS_APDO_MAX_CURR(max_ma))
|
||||
|
||||
/*
|
||||
* Applicable only to EPR AVS APDO source cap as per
|
||||
* Table 6.15 EPR Adjustable Voltage Supply APDO – Source
|
||||
*/
|
||||
#define PDO_EPR_AVS_APDO_PEAK_CURRENT GENMASK(27, 26)
|
||||
|
||||
/*
|
||||
* Applicable to both EPR AVS APDO source and sink cap as per
|
||||
* Table 6.15 EPR Adjustable Voltage Supply APDO – Source
|
||||
* Table 6.22 EPR Adjustable Voltage Supply APDO – Sink
|
||||
*/
|
||||
#define PDO_EPR_AVS_APDO_MAX_VOLT GENMASK(25, 17) /* 100mV unit */
|
||||
#define PDO_EPR_AVS_APDO_MIN_VOLT GENMASK(15, 8) /* 100mV unit */
|
||||
#define PDO_EPR_AVS_APDO_PDP GENMASK(7, 0) /* 1W unit */
|
||||
|
||||
/*
|
||||
* Applicable only SPR AVS APDO source cap as per
|
||||
* Table 6.14 SPR Adjustable Voltage Supply APDO – Source
|
||||
*/
|
||||
#define PDO_SPR_AVS_APDO_PEAK_CURRENT GENMASK(27, 26)
|
||||
|
||||
/*
|
||||
* Applicable to both SPR AVS APDO source and sink cap as per
|
||||
* Table 6.14 SPR Adjustable Voltage Supply APDO – Source
|
||||
* Table 6.21 SPR Adjustable Voltage Supply APDO – Sink
|
||||
*/
|
||||
#define PDO_SPR_AVS_APDO_9V_TO_15V_MAX_CURR GENMASK(19, 10) /* 10mA unit */
|
||||
#define PDO_SPR_AVS_APDO_15V_TO_20V_MAX_CURR GENMASK(9, 0) /* 10mA unit */
|
||||
|
||||
/* SPR AVS has two different current ranges 9V - 15V, 15V - 20V */
|
||||
#define SPR_AVS_TIER1_MIN_VOLT_MV 9000
|
||||
#define SPR_AVS_TIER1_MAX_VOLT_MV 15000
|
||||
#define SPR_AVS_TIER2_MAX_VOLT_MV 20000
|
||||
|
||||
#define SPR_AVS_AVS_SMALL_STEP_V 1
|
||||
/* vAvsStep - 100mv */
|
||||
#define SPR_AVS_VOLT_MV_STEP 100
|
||||
/* SPR AVS RDO Operating Current is in 50mA step */
|
||||
#define RDO_SPR_AVS_CURR_MA_STEP 50
|
||||
/* SPR AVS RDO Output voltage is in 25mV step */
|
||||
#define RDO_SPR_AVS_OUT_VOLT_MV_STEP 25
|
||||
|
||||
#define RDO_SPR_AVS_VOLT GENMASK(20, 9)
|
||||
#define RDO_SPR_AVS_CURR GENMASK(6, 0)
|
||||
|
||||
#define RDO_SPR_AVS_OUT_VOLT(mv) \
|
||||
FIELD_PREP(RDO_SPR_AVS_VOLT, ((mv) / RDO_SPR_AVS_OUT_VOLT_MV_STEP))
|
||||
|
||||
#define RDO_SPR_AVS_OP_CURR(ma) \
|
||||
FIELD_PREP(RDO_SPR_AVS_CURR, ((ma) / RDO_SPR_AVS_CURR_MA_STEP))
|
||||
|
||||
#define RDO_AVS(idx, out_mv, op_ma, flags) \
|
||||
(RDO_OBJ(idx) | (flags) | \
|
||||
RDO_SPR_AVS_OUT_VOLT(out_mv) | RDO_SPR_AVS_OP_CURR(op_ma))
|
||||
|
||||
static inline enum pd_pdo_type pdo_type(u32 pdo)
|
||||
{
|
||||
return (pdo >> PDO_TYPE_SHIFT) & PDO_TYPE_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_fixed_voltage(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_FIXED_VOLT_SHIFT) & PDO_VOLT_MASK) * 50;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_fixed_current(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_FIXED_CURR_SHIFT) & PDO_CURR_MASK) * 10;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_min_voltage(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_VAR_MIN_VOLT_SHIFT) & PDO_VOLT_MASK) * 50;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_max_voltage(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_VAR_MAX_VOLT_SHIFT) & PDO_VOLT_MASK) * 50;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_max_current(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_VAR_MAX_CURR_SHIFT) & PDO_CURR_MASK) * 10;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_max_power(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_BATT_MAX_PWR_SHIFT) & PDO_PWR_MASK) * 250;
|
||||
}
|
||||
|
||||
static inline enum pd_apdo_type pdo_apdo_type(u32 pdo)
|
||||
{
|
||||
return (pdo >> PDO_APDO_TYPE_SHIFT) & PDO_APDO_TYPE_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_pps_apdo_min_voltage(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_PPS_APDO_MIN_VOLT_SHIFT) &
|
||||
PDO_PPS_APDO_VOLT_MASK) * 100;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_pps_apdo_max_voltage(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_PPS_APDO_MAX_VOLT_SHIFT) &
|
||||
PDO_PPS_APDO_VOLT_MASK) * 100;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_pps_apdo_max_current(u32 pdo)
|
||||
{
|
||||
return ((pdo >> PDO_PPS_APDO_MAX_CURR_SHIFT) &
|
||||
PDO_PPS_APDO_CURR_MASK) * 50;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_epr_avs_apdo_src_peak_current(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_EPR_AVS_APDO_PEAK_CURRENT, pdo);
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_epr_avs_apdo_min_voltage_mv(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_EPR_AVS_APDO_MIN_VOLT, pdo) * 100;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_epr_avs_apdo_max_voltage_mv(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_EPR_AVS_APDO_MIN_VOLT, pdo) * 100;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_epr_avs_apdo_pdp_w(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_EPR_AVS_APDO_PDP, pdo);
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_spr_avs_apdo_src_peak_current(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_SPR_AVS_APDO_PEAK_CURRENT, pdo);
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_spr_avs_apdo_9v_to_15v_max_current_ma(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_SPR_AVS_APDO_9V_TO_15V_MAX_CURR, pdo) * 10;
|
||||
}
|
||||
|
||||
static inline unsigned int pdo_spr_avs_apdo_15v_to_20v_max_current_ma(u32 pdo)
|
||||
{
|
||||
return FIELD_GET(PDO_SPR_AVS_APDO_15V_TO_20V_MAX_CURR, pdo) * 10;
|
||||
}
|
||||
|
||||
/* RDO: Request Data Object */
|
||||
#define RDO_OBJ_POS_SHIFT 28
|
||||
#define RDO_OBJ_POS_MASK 0x7
|
||||
#define RDO_GIVE_BACK BIT(27) /* Supports reduced operating current */
|
||||
#define RDO_CAP_MISMATCH BIT(26) /* Not satisfied by source caps */
|
||||
#define RDO_USB_COMM BIT(25) /* USB communications capable */
|
||||
#define RDO_NO_SUSPEND BIT(24) /* USB Suspend not supported */
|
||||
|
||||
#define RDO_PWR_MASK 0x3ff
|
||||
#define RDO_CURR_MASK 0x3ff
|
||||
|
||||
#define RDO_FIXED_OP_CURR_SHIFT 10
|
||||
#define RDO_FIXED_MAX_CURR_SHIFT 0
|
||||
|
||||
#define RDO_OBJ(idx) (((idx) & RDO_OBJ_POS_MASK) << RDO_OBJ_POS_SHIFT)
|
||||
|
||||
#define PDO_FIXED_OP_CURR(ma) ((((ma) / 10) & RDO_CURR_MASK) << RDO_FIXED_OP_CURR_SHIFT)
|
||||
#define PDO_FIXED_MAX_CURR(ma) ((((ma) / 10) & RDO_CURR_MASK) << RDO_FIXED_MAX_CURR_SHIFT)
|
||||
|
||||
#define RDO_FIXED(idx, op_ma, max_ma, flags) \
|
||||
(RDO_OBJ(idx) | (flags) | \
|
||||
PDO_FIXED_OP_CURR(op_ma) | PDO_FIXED_MAX_CURR(max_ma))
|
||||
|
||||
#define RDO_BATT_OP_PWR_SHIFT 10 /* 250mW units */
|
||||
#define RDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */
|
||||
|
||||
#define RDO_BATT_OP_PWR(mw) ((((mw) / 250) & RDO_PWR_MASK) << RDO_BATT_OP_PWR_SHIFT)
|
||||
#define RDO_BATT_MAX_PWR(mw) ((((mw) / 250) & RDO_PWR_MASK) << RDO_BATT_MAX_PWR_SHIFT)
|
||||
|
||||
#define RDO_BATT(idx, op_mw, max_mw, flags) \
|
||||
(RDO_OBJ(idx) | (flags) | \
|
||||
RDO_BATT_OP_PWR(op_mw) | RDO_BATT_MAX_PWR(max_mw))
|
||||
|
||||
#define RDO_PROG_VOLT_MASK 0x7ff
|
||||
#define RDO_PROG_CURR_MASK 0x7f
|
||||
|
||||
#define RDO_PROG_VOLT_SHIFT 9
|
||||
#define RDO_PROG_CURR_SHIFT 0
|
||||
|
||||
#define RDO_PROG_VOLT_MV_STEP 20
|
||||
#define RDO_PROG_CURR_MA_STEP 50
|
||||
|
||||
#define PDO_PROG_OUT_VOLT(mv) \
|
||||
((((mv) / RDO_PROG_VOLT_MV_STEP) & RDO_PROG_VOLT_MASK) << RDO_PROG_VOLT_SHIFT)
|
||||
#define PDO_PROG_OP_CURR(ma) \
|
||||
((((ma) / RDO_PROG_CURR_MA_STEP) & RDO_PROG_CURR_MASK) << RDO_PROG_CURR_SHIFT)
|
||||
|
||||
#define RDO_PROG(idx, out_mv, op_ma, flags) \
|
||||
(RDO_OBJ(idx) | (flags) | \
|
||||
PDO_PROG_OUT_VOLT(out_mv) | PDO_PROG_OP_CURR(op_ma))
|
||||
|
||||
static inline unsigned int rdo_index(u32 rdo)
|
||||
{
|
||||
return (rdo >> RDO_OBJ_POS_SHIFT) & RDO_OBJ_POS_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int rdo_op_current(u32 rdo)
|
||||
{
|
||||
return ((rdo >> RDO_FIXED_OP_CURR_SHIFT) & RDO_CURR_MASK) * 10;
|
||||
}
|
||||
|
||||
static inline unsigned int rdo_max_current(u32 rdo)
|
||||
{
|
||||
return ((rdo >> RDO_FIXED_MAX_CURR_SHIFT) &
|
||||
RDO_CURR_MASK) * 10;
|
||||
}
|
||||
|
||||
static inline unsigned int rdo_op_power(u32 rdo)
|
||||
{
|
||||
return ((rdo >> RDO_BATT_OP_PWR_SHIFT) & RDO_PWR_MASK) * 250;
|
||||
}
|
||||
|
||||
static inline unsigned int rdo_max_power(u32 rdo)
|
||||
{
|
||||
return ((rdo >> RDO_BATT_MAX_PWR_SHIFT) & RDO_PWR_MASK) * 250;
|
||||
}
|
||||
|
||||
/* Enter_USB Data Object */
|
||||
#define EUDO_USB_MODE_MASK GENMASK(30, 28)
|
||||
#define EUDO_USB_MODE_SHIFT 28
|
||||
#define EUDO_USB_MODE_USB2 0
|
||||
#define EUDO_USB_MODE_USB3 1
|
||||
#define EUDO_USB_MODE_USB4 2
|
||||
#define EUDO_USB4_DRD BIT(26)
|
||||
#define EUDO_USB3_DRD BIT(25)
|
||||
#define EUDO_CABLE_SPEED_MASK GENMASK(23, 21)
|
||||
#define EUDO_CABLE_SPEED_SHIFT 21
|
||||
#define EUDO_CABLE_SPEED_USB2 0
|
||||
#define EUDO_CABLE_SPEED_USB3_GEN1 1
|
||||
#define EUDO_CABLE_SPEED_USB4_GEN2 2
|
||||
#define EUDO_CABLE_SPEED_USB4_GEN3 3
|
||||
#define EUDO_CABLE_TYPE_MASK GENMASK(20, 19)
|
||||
#define EUDO_CABLE_TYPE_SHIFT 19
|
||||
#define EUDO_CABLE_TYPE_PASSIVE 0
|
||||
#define EUDO_CABLE_TYPE_RE_TIMER 1
|
||||
#define EUDO_CABLE_TYPE_RE_DRIVER 2
|
||||
#define EUDO_CABLE_TYPE_OPTICAL 3
|
||||
#define EUDO_CABLE_CURRENT_MASK GENMASK(18, 17)
|
||||
#define EUDO_CABLE_CURRENT_SHIFT 17
|
||||
#define EUDO_CABLE_CURRENT_NOTSUPP 0
|
||||
#define EUDO_CABLE_CURRENT_3A 2
|
||||
#define EUDO_CABLE_CURRENT_5A 3
|
||||
#define EUDO_PCIE_SUPPORT BIT(16)
|
||||
#define EUDO_DP_SUPPORT BIT(15)
|
||||
#define EUDO_TBT_SUPPORT BIT(14)
|
||||
#define EUDO_HOST_PRESENT BIT(13)
|
||||
|
||||
/*
|
||||
* Request Message Data Object (PD Revision 3.1+ only)
|
||||
* --------
|
||||
* <31:28> :: Revision Major
|
||||
* <27:24> :: Revision Minor
|
||||
* <23:20> :: Version Major
|
||||
* <19:16> :: Version Minor
|
||||
* <15:0> :: Reserved, Shall be set to zero
|
||||
*/
|
||||
|
||||
#define RMDO(rev_maj, rev_min, ver_maj, ver_min) \
|
||||
(((rev_maj) & 0xf) << 28 | ((rev_min) & 0xf) << 24 | \
|
||||
((ver_maj) & 0xf) << 20 | ((ver_min) & 0xf) << 16)
|
||||
|
||||
/* USB PD timers and counters */
|
||||
#define PD_T_NO_RESPONSE 5000 /* 4.5 - 5.5 seconds */
|
||||
#define PD_T_DB_DETECT 10000 /* 10 - 15 seconds */
|
||||
#define PD_T_SEND_SOURCE_CAP 150 /* 100 - 200 ms */
|
||||
#define PD_T_SENDER_RESPONSE 60 /* 24 - 30 ms, relaxed */
|
||||
#define PD_T_RECEIVER_RESPONSE 15 /* 15ms max */
|
||||
#define PD_T_SOURCE_ACTIVITY 45
|
||||
#define PD_T_SINK_ACTIVITY 135
|
||||
#define PD_T_SINK_WAIT_CAP 310 /* 310 - 620 ms */
|
||||
#define PD_T_PS_TRANSITION 500
|
||||
#define PD_T_SRC_TRANSITION 35
|
||||
#define PD_T_DRP_SNK 40
|
||||
#define PD_T_DRP_SRC 30
|
||||
#define PD_T_PS_SOURCE_OFF 920
|
||||
#define PD_T_PS_SOURCE_ON 480
|
||||
#define PD_T_PS_SOURCE_ON_PRS 450 /* 390 - 480ms */
|
||||
#define PD_T_PS_HARD_RESET 30
|
||||
#define PD_T_SRC_RECOVER 760
|
||||
#define PD_T_SRC_RECOVER_MAX 1000
|
||||
#define PD_T_SRC_TURN_ON 275
|
||||
#define PD_T_SAFE_0V 650
|
||||
#define PD_T_VCONN_SOURCE_ON 100
|
||||
#define PD_T_SINK_REQUEST 100 /* 100 ms minimum */
|
||||
#define PD_T_ERROR_RECOVERY 100 /* minimum 25 is insufficient */
|
||||
#define PD_T_SRCSWAPSTDBY 625 /* Maximum of 650ms */
|
||||
#define PD_T_NEWSRC 250 /* Maximum of 275ms */
|
||||
#define PD_T_SWAP_SRC_START 20 /* Minimum of 20ms */
|
||||
#define PD_T_BIST_CONT_MODE 50 /* 30 - 60 ms */
|
||||
#define PD_T_SINK_TX 16 /* 16 - 20 ms */
|
||||
#define PD_T_CHUNK_NOT_SUPP 42 /* 40 - 50 ms */
|
||||
#define PD_T_VCONN_STABLE 50
|
||||
|
||||
#define PD_T_DRP_TRY 100 /* 75 - 150 ms */
|
||||
#define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */
|
||||
|
||||
#define PD_T_CC_DEBOUNCE 200 /* 100 - 200 ms */
|
||||
#define PD_T_PD_DEBOUNCE 20 /* 10 - 20 ms */
|
||||
#define PD_T_TRY_CC_DEBOUNCE 15 /* 10 - 20 ms */
|
||||
|
||||
#define PD_N_CAPS_COUNT (PD_T_NO_RESPONSE / PD_T_SEND_SOURCE_CAP)
|
||||
#define PD_N_HARD_RESET_COUNT 2
|
||||
|
||||
#define PD_P_SNK_STDBY_MW 2500 /* 2500 mW */
|
||||
|
||||
#define PD_I_SNK_STBY_MA 500 /* 500 mA */
|
||||
|
||||
#define PD_T_AVS_SRC_TRANS_SMALL 50 /* 50 ms */
|
||||
#define PD_T_AVS_SRC_TRANS_LARGE 700 /* 700 ms */
|
||||
|
||||
#if IS_ENABLED(CONFIG_TYPEC)
|
||||
|
||||
struct usb_power_delivery;
|
||||
|
||||
/**
|
||||
* usb_power_delivery_desc - USB Power Delivery Descriptor
|
||||
* @revision: USB Power Delivery Specification Revision
|
||||
* @version: USB Power Delivery Specicication Version - optional
|
||||
*/
|
||||
struct usb_power_delivery_desc {
|
||||
u16 revision;
|
||||
u16 version;
|
||||
};
|
||||
|
||||
/**
|
||||
* usb_power_delivery_capabilities_desc - Description of USB Power Delivery Capabilities Message
|
||||
* @pdo: The Power Data Objects in the Capability Message
|
||||
* @role: Power role of the capabilities
|
||||
*/
|
||||
struct usb_power_delivery_capabilities_desc {
|
||||
u32 pdo[PDO_MAX_OBJECTS];
|
||||
enum typec_role role;
|
||||
};
|
||||
|
||||
struct usb_power_delivery_capabilities *
|
||||
usb_power_delivery_register_capabilities(struct usb_power_delivery *pd,
|
||||
struct usb_power_delivery_capabilities_desc *desc);
|
||||
void usb_power_delivery_unregister_capabilities(struct usb_power_delivery_capabilities *cap);
|
||||
|
||||
struct usb_power_delivery *usb_power_delivery_register(struct device *parent,
|
||||
struct usb_power_delivery_desc *desc);
|
||||
void usb_power_delivery_unregister(struct usb_power_delivery *pd);
|
||||
|
||||
int usb_power_delivery_link_device(struct usb_power_delivery *pd, struct device *dev);
|
||||
void usb_power_delivery_unlink_device(struct usb_power_delivery *pd, struct device *dev);
|
||||
|
||||
#endif /* CONFIG_TYPEC */
|
||||
|
||||
#endif /* __LINUX_USB_PD_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2017 Dialog Semiconductor
|
||||
*
|
||||
* Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PD_ADO_H
|
||||
#define __LINUX_USB_PD_ADO_H
|
||||
|
||||
/* ADO : Alert Data Object */
|
||||
#define USB_PD_ADO_TYPE_SHIFT 24
|
||||
#define USB_PD_ADO_TYPE_MASK 0xff
|
||||
#define USB_PD_ADO_FIXED_BATT_SHIFT 20
|
||||
#define USB_PD_ADO_FIXED_BATT_MASK 0xf
|
||||
#define USB_PD_ADO_HOT_SWAP_BATT_SHIFT 16
|
||||
#define USB_PD_ADO_HOT_SWAP_BATT_MASK 0xf
|
||||
|
||||
#define USB_PD_ADO_TYPE_BATT_STATUS_CHANGE BIT(1)
|
||||
#define USB_PD_ADO_TYPE_OCP BIT(2)
|
||||
#define USB_PD_ADO_TYPE_OTP BIT(3)
|
||||
#define USB_PD_ADO_TYPE_OP_COND_CHANGE BIT(4)
|
||||
#define USB_PD_ADO_TYPE_SRC_INPUT_CHANGE BIT(5)
|
||||
#define USB_PD_ADO_TYPE_OVP BIT(6)
|
||||
|
||||
static inline unsigned int usb_pd_ado_type(u32 ado)
|
||||
{
|
||||
return (ado >> USB_PD_ADO_TYPE_SHIFT) & USB_PD_ADO_TYPE_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int usb_pd_ado_fixed_batt(u32 ado)
|
||||
{
|
||||
return (ado >> USB_PD_ADO_FIXED_BATT_SHIFT) &
|
||||
USB_PD_ADO_FIXED_BATT_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int usb_pd_ado_hot_swap_batt(u32 ado)
|
||||
{
|
||||
return (ado >> USB_PD_ADO_HOT_SWAP_BATT_SHIFT) &
|
||||
USB_PD_ADO_HOT_SWAP_BATT_MASK;
|
||||
}
|
||||
#endif /* __LINUX_USB_PD_ADO_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright 2015-2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PD_BDO_H
|
||||
#define __LINUX_USB_PD_BDO_H
|
||||
|
||||
/* BDO : BIST Data Object */
|
||||
#define BDO_MODE_RECV (0 << 28)
|
||||
#define BDO_MODE_TRANSMIT (1 << 28)
|
||||
#define BDO_MODE_COUNTERS (2 << 28)
|
||||
#define BDO_MODE_CARRIER0 (3 << 28)
|
||||
#define BDO_MODE_CARRIER1 (4 << 28)
|
||||
#define BDO_MODE_CARRIER2 (5 << 28)
|
||||
#define BDO_MODE_CARRIER3 (6 << 28)
|
||||
#define BDO_MODE_EYE (7 << 28)
|
||||
#define BDO_MODE_TESTDATA (8U << 28)
|
||||
|
||||
#define BDO_MODE_MASK(mode) ((mode) & 0xf0000000)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2017 Dialog Semiconductor
|
||||
*
|
||||
* Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PD_EXT_SDB_H
|
||||
#define __LINUX_USB_PD_EXT_SDB_H
|
||||
|
||||
/* SDB : Status Data Block */
|
||||
enum usb_pd_ext_sdb_fields {
|
||||
USB_PD_EXT_SDB_INTERNAL_TEMP = 0,
|
||||
USB_PD_EXT_SDB_PRESENT_INPUT,
|
||||
USB_PD_EXT_SDB_PRESENT_BATT_INPUT,
|
||||
USB_PD_EXT_SDB_EVENT_FLAGS,
|
||||
USB_PD_EXT_SDB_TEMP_STATUS,
|
||||
USB_PD_EXT_SDB_DATA_SIZE,
|
||||
};
|
||||
|
||||
/* Event Flags */
|
||||
#define USB_PD_EXT_SDB_EVENT_OCP BIT(1)
|
||||
#define USB_PD_EXT_SDB_EVENT_OTP BIT(2)
|
||||
#define USB_PD_EXT_SDB_EVENT_OVP BIT(3)
|
||||
#define USB_PD_EXT_SDB_EVENT_CF_CV_MODE BIT(4)
|
||||
|
||||
#endif /* __LINUX_USB_PD_EXT_SDB_H */
|
||||
@@ -0,0 +1,527 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright 2015-2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PD_VDO_H
|
||||
#define __LINUX_USB_PD_VDO_H
|
||||
|
||||
#include "pd.h"
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
/*
|
||||
* VDO : Vendor Defined Message Object
|
||||
* VDM object is minimum of VDM header + 6 additional data objects.
|
||||
*/
|
||||
|
||||
#define VDO_MAX_OBJECTS 6
|
||||
#define VDO_MAX_SIZE (VDO_MAX_OBJECTS + 1)
|
||||
|
||||
/*
|
||||
* VDM header
|
||||
* ----------
|
||||
* <31:16> :: SVID
|
||||
* <15> :: VDM type ( 1b == structured, 0b == unstructured )
|
||||
* <14:13> :: Structured VDM version
|
||||
* <12:11> :: reserved
|
||||
* <10:8> :: object position (1-7 valid ... used for enter/exit mode only)
|
||||
* <7:6> :: command type (SVDM only?)
|
||||
* <5> :: reserved (SVDM), command type (UVDM)
|
||||
* <4:0> :: command
|
||||
*/
|
||||
#define VDO(vid, type, ver, custom) \
|
||||
(((vid) << 16) | \
|
||||
((type) << 15) | \
|
||||
((ver) << 13) | \
|
||||
((custom) & 0x7FFF))
|
||||
|
||||
#define VDO_SVDM_TYPE (1 << 15)
|
||||
#define VDO_SVDM_VERS(x) ((x) << 13)
|
||||
#define VDO_OPOS(x) ((x) << 8)
|
||||
#define VDO_CMDT(x) ((x) << 6)
|
||||
#define VDO_SVDM_VERS_MASK VDO_SVDM_VERS(0x3)
|
||||
#define VDO_OPOS_MASK VDO_OPOS(0x7)
|
||||
#define VDO_CMDT_MASK VDO_CMDT(0x3)
|
||||
|
||||
#define CMDT_INIT 0
|
||||
#define CMDT_RSP_ACK 1
|
||||
#define CMDT_RSP_NAK 2
|
||||
#define CMDT_RSP_BUSY 3
|
||||
|
||||
/* reserved for SVDM ... for Google UVDM */
|
||||
#define VDO_SRC_INITIATOR (0 << 5)
|
||||
#define VDO_SRC_RESPONDER (1 << 5)
|
||||
|
||||
#define CMD_DISCOVER_IDENT 1
|
||||
#define CMD_DISCOVER_SVID 2
|
||||
#define CMD_DISCOVER_MODES 3
|
||||
#define CMD_ENTER_MODE 4
|
||||
#define CMD_EXIT_MODE 5
|
||||
#define CMD_ATTENTION 6
|
||||
|
||||
#define VDO_CMD_VENDOR(x) (((0x10 + (x)) & 0x1f))
|
||||
|
||||
/* ChromeOS specific commands */
|
||||
#define VDO_CMD_VERSION VDO_CMD_VENDOR(0)
|
||||
#define VDO_CMD_SEND_INFO VDO_CMD_VENDOR(1)
|
||||
#define VDO_CMD_READ_INFO VDO_CMD_VENDOR(2)
|
||||
#define VDO_CMD_REBOOT VDO_CMD_VENDOR(5)
|
||||
#define VDO_CMD_FLASH_ERASE VDO_CMD_VENDOR(6)
|
||||
#define VDO_CMD_FLASH_WRITE VDO_CMD_VENDOR(7)
|
||||
#define VDO_CMD_ERASE_SIG VDO_CMD_VENDOR(8)
|
||||
#define VDO_CMD_PING_ENABLE VDO_CMD_VENDOR(10)
|
||||
#define VDO_CMD_CURRENT VDO_CMD_VENDOR(11)
|
||||
#define VDO_CMD_FLIP VDO_CMD_VENDOR(12)
|
||||
#define VDO_CMD_GET_LOG VDO_CMD_VENDOR(13)
|
||||
#define VDO_CMD_CCD_EN VDO_CMD_VENDOR(14)
|
||||
|
||||
#define PD_VDO_VID(vdo) ((vdo) >> 16)
|
||||
#define PD_VDO_SVDM(vdo) (((vdo) >> 15) & 1)
|
||||
#define PD_VDO_SVDM_VER(vdo) (((vdo) >> 13) & 0x3)
|
||||
#define PD_VDO_OPOS(vdo) (((vdo) >> 8) & 0x7)
|
||||
#define PD_VDO_CMD(vdo) ((vdo) & 0x1f)
|
||||
#define PD_VDO_CMDT(vdo) (((vdo) >> 6) & 0x3)
|
||||
|
||||
/*
|
||||
* SVDM Identity request -> response
|
||||
*
|
||||
* Request is simply properly formatted SVDM header
|
||||
*
|
||||
* Response is 4 data objects for Power Delivery 2.0 and Passive Cables for
|
||||
* Power Delivery 3.0. Active Cables in Power Delivery 3.0 have 5 data objects.
|
||||
* [0] :: SVDM header
|
||||
* [1] :: Identitiy header
|
||||
* [2] :: Cert Stat VDO
|
||||
* [3] :: (Product | Cable) VDO
|
||||
* [4] :: Cable VDO 1
|
||||
* [4] :: AMA VDO
|
||||
* [5] :: Cable VDO 2
|
||||
*
|
||||
*/
|
||||
#define VDO_INDEX_HDR 0
|
||||
#define VDO_INDEX_IDH 1
|
||||
#define VDO_INDEX_CSTAT 2
|
||||
#define VDO_INDEX_CABLE 3
|
||||
#define VDO_INDEX_PRODUCT 3
|
||||
#define VDO_INDEX_AMA 4
|
||||
#define VDO_INDEX_CABLE_1 4
|
||||
#define VDO_INDEX_CABLE_2 5
|
||||
|
||||
/*
|
||||
* SVDM Identity Header
|
||||
* --------------------
|
||||
* <31> :: data capable as a USB host
|
||||
* <30> :: data capable as a USB device
|
||||
* <29:27> :: product type (UFP / Cable / VPD)
|
||||
* <26> :: modal operation supported (1b == yes)
|
||||
* <25:23> :: product type (DFP) (SVDM version 2.0+ only; set to zero in version 1.0)
|
||||
* <22:21> :: connector type (SVDM version 2.0+ only; set to zero in version 1.0)
|
||||
* <20:16> :: Reserved, Shall be set to zero
|
||||
* <15:0> :: USB-IF assigned VID for this cable vendor
|
||||
*/
|
||||
|
||||
/* PD Rev2.0 definition */
|
||||
#define IDH_PTYPE_UNDEF 0
|
||||
|
||||
/* SOP Product Type (UFP) */
|
||||
#define IDH_PTYPE_NOT_UFP 0
|
||||
#define IDH_PTYPE_HUB 1
|
||||
#define IDH_PTYPE_PERIPH 2
|
||||
#define IDH_PTYPE_PSD 3
|
||||
#define IDH_PTYPE_AMA 5
|
||||
|
||||
/* SOP' Product Type (Cable Plug / VPD) */
|
||||
#define IDH_PTYPE_NOT_CABLE 0
|
||||
#define IDH_PTYPE_PCABLE 3
|
||||
#define IDH_PTYPE_ACABLE 4
|
||||
#define IDH_PTYPE_VPD 6
|
||||
|
||||
/* SOP Product Type (DFP) */
|
||||
#define IDH_PTYPE_NOT_DFP 0
|
||||
#define IDH_PTYPE_DFP_HUB 1
|
||||
#define IDH_PTYPE_DFP_HOST 2
|
||||
#define IDH_PTYPE_DFP_PB 3
|
||||
|
||||
/* ID Header Mask */
|
||||
#define IDH_DFP_MASK GENMASK(25, 23)
|
||||
#define IDH_CONN_MASK GENMASK(22, 21)
|
||||
|
||||
#define VDO_IDH(usbh, usbd, ufp_cable, is_modal, dfp, conn, vid) \
|
||||
((usbh) << 31 | (usbd) << 30 | ((ufp_cable) & 0x7) << 27 \
|
||||
| (is_modal) << 26 | ((dfp) & 0x7) << 23 | ((conn) & 0x3) << 21 \
|
||||
| ((vid) & 0xffff))
|
||||
|
||||
#define PD_IDH_PTYPE(vdo) (((vdo) >> 27) & 0x7)
|
||||
#define PD_IDH_VID(vdo) ((vdo) & 0xffff)
|
||||
#define PD_IDH_MODAL_SUPP(vdo) ((vdo) & (1 << 26))
|
||||
#define PD_IDH_DFP_PTYPE(vdo) (((vdo) >> 23) & 0x7)
|
||||
#define PD_IDH_CONN_TYPE(vdo) (((vdo) >> 21) & 0x3)
|
||||
#define PD_IDH_HOST_SUPP(vdo) ((vdo) & (1 << 31))
|
||||
|
||||
/*
|
||||
* Cert Stat VDO
|
||||
* -------------
|
||||
* <31:0> : USB-IF assigned XID for this cable
|
||||
*/
|
||||
#define PD_CSTAT_XID(vdo) (vdo)
|
||||
#define VDO_CERT(xid) ((xid) & 0xffffffff)
|
||||
|
||||
/*
|
||||
* Product VDO
|
||||
* -----------
|
||||
* <31:16> : USB Product ID
|
||||
* <15:0> : USB bcdDevice
|
||||
*/
|
||||
#define VDO_PRODUCT(pid, bcd) (((pid) & 0xffff) << 16 | ((bcd) & 0xffff))
|
||||
#define PD_PRODUCT_PID(vdo) (((vdo) >> 16) & 0xffff)
|
||||
|
||||
/*
|
||||
* UFP VDO (PD Revision 3.0+ only)
|
||||
* --------
|
||||
* <31:29> :: UFP VDO version
|
||||
* <28> :: Reserved
|
||||
* <27:24> :: Device capability
|
||||
* <23:22> :: Connector type (10b == receptacle, 11b == captive plug)
|
||||
* <21:11> :: Reserved
|
||||
* <10:8> :: Vconn power (AMA only)
|
||||
* <7> :: Vconn required (AMA only, 0b == no, 1b == yes)
|
||||
* <6> :: Vbus required (AMA only, 0b == yes, 1b == no)
|
||||
* <5:3> :: Alternate modes
|
||||
* <2:0> :: USB highest speed
|
||||
*/
|
||||
#define PD_VDO_UFP_DEVCAP(vdo) FIELD_GET(GENMASK(27, 24), vdo)
|
||||
|
||||
/* UFP VDO Version */
|
||||
#define UFP_VDO_VER1_2 2
|
||||
|
||||
/* Device Capability */
|
||||
#define DEV_USB2_CAPABLE BIT(0)
|
||||
#define DEV_USB2_BILLBOARD BIT(1)
|
||||
#define DEV_USB3_CAPABLE BIT(2)
|
||||
#define DEV_USB4_CAPABLE BIT(3)
|
||||
|
||||
/* Connector Type */
|
||||
#define UFP_RECEPTACLE 2
|
||||
#define UFP_CAPTIVE 3
|
||||
|
||||
/* Vconn Power (AMA only, set to AMA_VCONN_NOT_REQ if Vconn is not required) */
|
||||
#define AMA_VCONN_PWR_1W 0
|
||||
#define AMA_VCONN_PWR_1W5 1
|
||||
#define AMA_VCONN_PWR_2W 2
|
||||
#define AMA_VCONN_PWR_3W 3
|
||||
#define AMA_VCONN_PWR_4W 4
|
||||
#define AMA_VCONN_PWR_5W 5
|
||||
#define AMA_VCONN_PWR_6W 6
|
||||
|
||||
/* Vconn Required (AMA only) */
|
||||
#define AMA_VCONN_NOT_REQ 0
|
||||
#define AMA_VCONN_REQ 1
|
||||
|
||||
/* Vbus Required (AMA only) */
|
||||
#define AMA_VBUS_REQ 0
|
||||
#define AMA_VBUS_NOT_REQ 1
|
||||
|
||||
/* Alternate Modes */
|
||||
#define UFP_ALTMODE_NOT_SUPP 0
|
||||
#define UFP_ALTMODE_TBT3 BIT(0)
|
||||
#define UFP_ALTMODE_RECFG BIT(1)
|
||||
#define UFP_ALTMODE_NO_RECFG BIT(2)
|
||||
|
||||
/* USB Highest Speed */
|
||||
#define UFP_USB2_ONLY 0
|
||||
#define UFP_USB32_GEN1 1
|
||||
#define UFP_USB32_4_GEN2 2
|
||||
#define UFP_USB4_GEN3 3
|
||||
|
||||
#define VDO_UFP(ver, cap, conn, vcpwr, vcr, vbr, alt, spd) \
|
||||
(((ver) & 0x7) << 29 | ((cap) & 0xf) << 24 | ((conn) & 0x3) << 22 \
|
||||
| ((vcpwr) & 0x7) << 8 | (vcr) << 7 | (vbr) << 6 | ((alt) & 0x7) << 3 \
|
||||
| ((spd) & 0x7))
|
||||
|
||||
/*
|
||||
* DFP VDO (PD Revision 3.0+ only)
|
||||
* --------
|
||||
* <31:29> :: DFP VDO version
|
||||
* <28:27> :: Reserved
|
||||
* <26:24> :: Host capability
|
||||
* <23:22> :: Connector type (10b == receptacle, 11b == captive plug)
|
||||
* <21:5> :: Reserved
|
||||
* <4:0> :: Port number
|
||||
*/
|
||||
#define PD_VDO_DFP_HOSTCAP(vdo) FIELD_GET(GENMASK(26, 24), vdo)
|
||||
|
||||
#define DFP_VDO_VER1_1 1
|
||||
#define HOST_USB2_CAPABLE BIT(0)
|
||||
#define HOST_USB3_CAPABLE BIT(1)
|
||||
#define HOST_USB4_CAPABLE BIT(2)
|
||||
#define DFP_RECEPTACLE 2
|
||||
#define DFP_CAPTIVE 3
|
||||
|
||||
#define VDO_DFP(ver, cap, conn, pnum) \
|
||||
(((ver) & 0x7) << 29 | ((cap) & 0x7) << 24 | ((conn) & 0x3) << 22 \
|
||||
| ((pnum) & 0x1f))
|
||||
|
||||
/*
|
||||
* Cable VDO (for both Passive and Active Cable VDO in PD Rev2.0)
|
||||
* ---------
|
||||
* <31:28> :: Cable HW version
|
||||
* <27:24> :: Cable FW version
|
||||
* <23:20> :: Reserved, Shall be set to zero
|
||||
* <19:18> :: type-C to Type-A/B/C/Captive (00b == A, 01 == B, 10 == C, 11 == Captive)
|
||||
* <17> :: Reserved, Shall be set to zero
|
||||
* <16:13> :: cable latency (0001 == <10ns(~1m length))
|
||||
* <12:11> :: cable termination type (11b == both ends active VCONN req)
|
||||
* <10> :: SSTX1 Directionality support (0b == fixed, 1b == cfgable)
|
||||
* <9> :: SSTX2 Directionality support
|
||||
* <8> :: SSRX1 Directionality support
|
||||
* <7> :: SSRX2 Directionality support
|
||||
* <6:5> :: Vbus current handling capability (01b == 3A, 10b == 5A)
|
||||
* <4> :: Vbus through cable (0b == no, 1b == yes)
|
||||
* <3> :: SOP" controller present? (0b == no, 1b == yes)
|
||||
* <2:0> :: USB SS Signaling support
|
||||
*
|
||||
* Passive Cable VDO (PD Rev3.0+)
|
||||
* ---------
|
||||
* <31:28> :: Cable HW version
|
||||
* <27:24> :: Cable FW version
|
||||
* <23:21> :: VDO version
|
||||
* <20> :: Reserved, Shall be set to zero
|
||||
* <19:18> :: Type-C to Type-C/Captive (10b == C, 11b == Captive)
|
||||
* <17> :: Reserved, Shall be set to zero
|
||||
* <16:13> :: cable latency (0001 == <10ns(~1m length))
|
||||
* <12:11> :: cable termination type (10b == Vconn not req, 01b == Vconn req)
|
||||
* <10:9> :: Maximum Vbus voltage (00b == 20V, 01b == 30V, 10b == 40V, 11b == 50V)
|
||||
* <8:7> :: Reserved, Shall be set to zero
|
||||
* <6:5> :: Vbus current handling capability (01b == 3A, 10b == 5A)
|
||||
* <4:3> :: Reserved, Shall be set to zero
|
||||
* <2:0> :: USB highest speed
|
||||
*
|
||||
* Active Cable VDO 1 (PD Rev3.0+)
|
||||
* ---------
|
||||
* <31:28> :: Cable HW version
|
||||
* <27:24> :: Cable FW version
|
||||
* <23:21> :: VDO version
|
||||
* <20> :: Reserved, Shall be set to zero
|
||||
* <19:18> :: Connector type (10b == C, 11b == Captive)
|
||||
* <17> :: Reserved, Shall be set to zero
|
||||
* <16:13> :: cable latency (0001 == <10ns(~1m length))
|
||||
* <12:11> :: cable termination type (10b == one end active, 11b == both ends active VCONN req)
|
||||
* <10:9> :: Maximum Vbus voltage (00b == 20V, 01b == 30V, 10b == 40V, 11b == 50V)
|
||||
* <8> :: SBU supported (0b == supported, 1b == not supported)
|
||||
* <7> :: SBU type (0b == passive, 1b == active)
|
||||
* <6:5> :: Vbus current handling capability (01b == 3A, 10b == 5A)
|
||||
* <4> :: Vbus through cable (0b == no, 1b == yes)
|
||||
* <3> :: SOP" controller present? (0b == no, 1b == yes)
|
||||
* <2:0> :: USB highest speed
|
||||
*/
|
||||
/* Cable VDO Version */
|
||||
#define CABLE_VDO_VER1_0 0
|
||||
#define CABLE_VDO_VER1_3 3
|
||||
|
||||
/* Connector Type (_ATYPE and _BTYPE are for PD Rev2.0 only) */
|
||||
#define CABLE_ATYPE 0
|
||||
#define CABLE_BTYPE 1
|
||||
#define CABLE_CTYPE 2
|
||||
#define CABLE_CAPTIVE 3
|
||||
|
||||
/* Cable Latency */
|
||||
#define CABLE_LATENCY_1M 1
|
||||
#define CABLE_LATENCY_2M 2
|
||||
#define CABLE_LATENCY_3M 3
|
||||
#define CABLE_LATENCY_4M 4
|
||||
#define CABLE_LATENCY_5M 5
|
||||
#define CABLE_LATENCY_6M 6
|
||||
#define CABLE_LATENCY_7M 7
|
||||
#define CABLE_LATENCY_7M_PLUS 8
|
||||
|
||||
/* Cable Termination Type */
|
||||
#define PCABLE_VCONN_NOT_REQ 0
|
||||
#define PCABLE_VCONN_REQ 1
|
||||
#define ACABLE_ONE_END 2
|
||||
#define ACABLE_BOTH_END 3
|
||||
|
||||
/* Maximum Vbus Voltage */
|
||||
#define CABLE_MAX_VBUS_20V 0
|
||||
#define CABLE_MAX_VBUS_30V 1
|
||||
#define CABLE_MAX_VBUS_40V 2
|
||||
#define CABLE_MAX_VBUS_50V 3
|
||||
|
||||
/* Active Cable SBU Supported/Type */
|
||||
#define ACABLE_SBU_SUPP 0
|
||||
#define ACABLE_SBU_NOT_SUPP 1
|
||||
#define ACABLE_SBU_PASSIVE 0
|
||||
#define ACABLE_SBU_ACTIVE 1
|
||||
|
||||
/* Vbus Current Handling Capability */
|
||||
#define CABLE_CURR_DEF 0
|
||||
#define CABLE_CURR_3A 1
|
||||
#define CABLE_CURR_5A 2
|
||||
|
||||
/* USB SuperSpeed Signaling Support (PD Rev2.0) */
|
||||
#define CABLE_USBSS_U2_ONLY 0
|
||||
#define CABLE_USBSS_U31_GEN1 1
|
||||
#define CABLE_USBSS_U31_GEN2 2
|
||||
|
||||
/* USB Highest Speed */
|
||||
#define CABLE_USB2_ONLY 0
|
||||
#define CABLE_USB32_GEN1 1
|
||||
#define CABLE_USB32_4_GEN2 2
|
||||
#define CABLE_USB4_GEN3 3
|
||||
|
||||
#define VDO_CABLE(hw, fw, cbl, lat, term, tx1d, tx2d, rx1d, rx2d, cur, vps, sopp, usbss) \
|
||||
(((hw) & 0x7) << 28 | ((fw) & 0x7) << 24 | ((cbl) & 0x3) << 18 \
|
||||
| ((lat) & 0x7) << 13 | ((term) & 0x3) << 11 | (tx1d) << 10 \
|
||||
| (tx2d) << 9 | (rx1d) << 8 | (rx2d) << 7 | ((cur) & 0x3) << 5 \
|
||||
| (vps) << 4 | (sopp) << 3 | ((usbss) & 0x7))
|
||||
#define VDO_PCABLE(hw, fw, ver, conn, lat, term, vbm, cur, spd) \
|
||||
(((hw) & 0xf) << 28 | ((fw) & 0xf) << 24 | ((ver) & 0x7) << 21 \
|
||||
| ((conn) & 0x3) << 18 | ((lat) & 0xf) << 13 | ((term) & 0x3) << 11 \
|
||||
| ((vbm) & 0x3) << 9 | ((cur) & 0x3) << 5 | ((spd) & 0x7))
|
||||
#define VDO_ACABLE1(hw, fw, ver, conn, lat, term, vbm, sbu, sbut, cur, vbt, sopp, spd) \
|
||||
(((hw) & 0xf) << 28 | ((fw) & 0xf) << 24 | ((ver) & 0x7) << 21 \
|
||||
| ((conn) & 0x3) << 18 | ((lat) & 0xf) << 13 | ((term) & 0x3) << 11 \
|
||||
| ((vbm) & 0x3) << 9 | (sbu) << 8 | (sbut) << 7 | ((cur) & 0x3) << 5 \
|
||||
| (vbt) << 4 | (sopp) << 3 | ((spd) & 0x7))
|
||||
|
||||
#define VDO_TYPEC_CABLE_SPEED(vdo) ((vdo) & 0x7)
|
||||
#define VDO_TYPEC_CABLE_TYPE(vdo) (((vdo) >> 18) & 0x3)
|
||||
|
||||
/*
|
||||
* Active Cable VDO 2
|
||||
* ---------
|
||||
* <31:24> :: Maximum operating temperature
|
||||
* <23:16> :: Shutdown temperature
|
||||
* <15> :: Reserved, Shall be set to zero
|
||||
* <14:12> :: U3/CLd power
|
||||
* <11> :: U3 to U0 transition mode (0b == direct, 1b == through U3S)
|
||||
* <10> :: Physical connection (0b == copper, 1b == optical)
|
||||
* <9> :: Active element (0b == redriver, 1b == retimer)
|
||||
* <8> :: USB4 supported (0b == yes, 1b == no)
|
||||
* <7:6> :: USB2 hub hops consumed
|
||||
* <5> :: USB2 supported (0b == yes, 1b == no)
|
||||
* <4> :: USB3.2 supported (0b == yes, 1b == no)
|
||||
* <3> :: USB lanes supported (0b == one lane, 1b == two lanes)
|
||||
* <2> :: Optically isolated active cable (0b == no, 1b == yes)
|
||||
* <1> :: Reserved, Shall be set to zero
|
||||
* <0> :: USB gen (0b == gen1, 1b == gen2+)
|
||||
*/
|
||||
/* U3/CLd Power*/
|
||||
#define ACAB2_U3_CLD_10MW_PLUS 0
|
||||
#define ACAB2_U3_CLD_10MW 1
|
||||
#define ACAB2_U3_CLD_5MW 2
|
||||
#define ACAB2_U3_CLD_1MW 3
|
||||
#define ACAB2_U3_CLD_500UW 4
|
||||
#define ACAB2_U3_CLD_200UW 5
|
||||
#define ACAB2_U3_CLD_50UW 6
|
||||
|
||||
/* Other Active Cable VDO 2 Fields */
|
||||
#define ACAB2_U3U0_DIRECT 0
|
||||
#define ACAB2_U3U0_U3S 1
|
||||
#define ACAB2_PHY_COPPER 0
|
||||
#define ACAB2_PHY_OPTICAL 1
|
||||
#define ACAB2_REDRIVER 0
|
||||
#define ACAB2_RETIMER 1
|
||||
#define ACAB2_USB4_SUPP 0
|
||||
#define ACAB2_USB4_NOT_SUPP 1
|
||||
#define ACAB2_USB2_SUPP 0
|
||||
#define ACAB2_USB2_NOT_SUPP 1
|
||||
#define ACAB2_USB32_SUPP 0
|
||||
#define ACAB2_USB32_NOT_SUPP 1
|
||||
#define ACAB2_LANES_ONE 0
|
||||
#define ACAB2_LANES_TWO 1
|
||||
#define ACAB2_OPT_ISO_NO 0
|
||||
#define ACAB2_OPT_ISO_YES 1
|
||||
#define ACAB2_GEN_1 0
|
||||
#define ACAB2_GEN_2_PLUS 1
|
||||
|
||||
#define VDO_ACABLE2(mtemp, stemp, u3p, trans, phy, ele, u4, hops, u2, u32, lane, iso, gen) \
|
||||
(((mtemp) & 0xff) << 24 | ((stemp) & 0xff) << 16 | ((u3p) & 0x7) << 12 \
|
||||
| (trans) << 11 | (phy) << 10 | (ele) << 9 | (u4) << 8 \
|
||||
| ((hops) & 0x3) << 6 | (u2) << 5 | (u32) << 4 | (lane) << 3 \
|
||||
| (iso) << 2 | (gen))
|
||||
|
||||
/*
|
||||
* AMA VDO (PD Rev2.0)
|
||||
* ---------
|
||||
* <31:28> :: Cable HW version
|
||||
* <27:24> :: Cable FW version
|
||||
* <23:12> :: Reserved, Shall be set to zero
|
||||
* <11> :: SSTX1 Directionality support (0b == fixed, 1b == cfgable)
|
||||
* <10> :: SSTX2 Directionality support
|
||||
* <9> :: SSRX1 Directionality support
|
||||
* <8> :: SSRX2 Directionality support
|
||||
* <7:5> :: Vconn power
|
||||
* <4> :: Vconn power required
|
||||
* <3> :: Vbus power required
|
||||
* <2:0> :: USB SS Signaling support
|
||||
*/
|
||||
#define VDO_AMA(hw, fw, tx1d, tx2d, rx1d, rx2d, vcpwr, vcr, vbr, usbss) \
|
||||
(((hw) & 0x7) << 28 | ((fw) & 0x7) << 24 \
|
||||
| (tx1d) << 11 | (tx2d) << 10 | (rx1d) << 9 | (rx2d) << 8 \
|
||||
| ((vcpwr) & 0x7) << 5 | (vcr) << 4 | (vbr) << 3 \
|
||||
| ((usbss) & 0x7))
|
||||
|
||||
#define PD_VDO_AMA_VCONN_REQ(vdo) (((vdo) >> 4) & 1)
|
||||
#define PD_VDO_AMA_VBUS_REQ(vdo) (((vdo) >> 3) & 1)
|
||||
|
||||
#define AMA_USBSS_U2_ONLY 0
|
||||
#define AMA_USBSS_U31_GEN1 1
|
||||
#define AMA_USBSS_U31_GEN2 2
|
||||
#define AMA_USBSS_BBONLY 3
|
||||
|
||||
/*
|
||||
* VPD VDO
|
||||
* ---------
|
||||
* <31:28> :: HW version
|
||||
* <27:24> :: FW version
|
||||
* <23:21> :: VDO version
|
||||
* <20:17> :: Reserved, Shall be set to zero
|
||||
* <16:15> :: Maximum Vbus voltage (00b == 20V, 01b == 30V, 10b == 40V, 11b == 50V)
|
||||
* <14> :: Charge through current support (0b == 3A, 1b == 5A)
|
||||
* <13> :: Reserved, Shall be set to zero
|
||||
* <12:7> :: Vbus impedance
|
||||
* <6:1> :: Ground impedance
|
||||
* <0> :: Charge through support (0b == no, 1b == yes)
|
||||
*/
|
||||
#define VPD_VDO_VER1_0 0
|
||||
#define VPD_MAX_VBUS_20V 0
|
||||
#define VPD_MAX_VBUS_30V 1
|
||||
#define VPD_MAX_VBUS_40V 2
|
||||
#define VPD_MAX_VBUS_50V 3
|
||||
#define VPDCT_CURR_3A 0
|
||||
#define VPDCT_CURR_5A 1
|
||||
#define VPDCT_NOT_SUPP 0
|
||||
#define VPDCT_SUPP 1
|
||||
|
||||
#define VDO_VPD(hw, fw, ver, vbm, curr, vbi, gi, ct) \
|
||||
(((hw) & 0xf) << 28 | ((fw) & 0xf) << 24 | ((ver) & 0x7) << 21 \
|
||||
| ((vbm) & 0x3) << 15 | (curr) << 14 | ((vbi) & 0x3f) << 7 \
|
||||
| ((gi) & 0x3f) << 1 | (ct))
|
||||
|
||||
/*
|
||||
* SVDM Discover SVIDs request -> response
|
||||
*
|
||||
* Request is properly formatted VDM Header with discover SVIDs command.
|
||||
* Response is a set of SVIDs of all supported SVIDs with all zero's to
|
||||
* mark the end of SVIDs. If more than 12 SVIDs are supported command SHOULD be
|
||||
* repeated.
|
||||
*/
|
||||
#define VDO_SVID(svid0, svid1) (((svid0) & 0xffff) << 16 | ((svid1) & 0xffff))
|
||||
#define PD_VDO_SVID_SVID0(vdo) ((vdo) >> 16)
|
||||
#define PD_VDO_SVID_SVID1(vdo) ((vdo) & 0xffff)
|
||||
|
||||
/* USB-IF SIDs */
|
||||
#define USB_SID_PD 0xff00 /* power delivery */
|
||||
#define USB_SID_DISPLAYPORT 0xff01
|
||||
#define USB_SID_MHL 0xff02 /* Mobile High-Definition Link */
|
||||
|
||||
/* VDM command timeouts (in ms) */
|
||||
|
||||
#define PD_T_VDM_UNSTRUCTURED 500
|
||||
#define PD_T_VDM_BUSY 100
|
||||
#define PD_T_VDM_WAIT_MODE_E 100
|
||||
#define PD_T_VDM_SNDR_RSP 30
|
||||
#define PD_T_VDM_E_MODE 25
|
||||
#define PD_T_VDM_RCVR_RSP 15
|
||||
|
||||
#endif /* __LINUX_USB_PD_VDO_H */
|
||||
@@ -0,0 +1,356 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* USB PHY defines
|
||||
*
|
||||
* These APIs may be used between USB controllers. USB device drivers
|
||||
* (for either host or peripheral roles) don't use these calls; they
|
||||
* continue to use just usb_device and usb_gadget.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_PHY_H
|
||||
#define __LINUX_USB_PHY_H
|
||||
|
||||
#include <linux/extcon.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/usb.h>
|
||||
#include <uapi/linux/usb/charger.h>
|
||||
|
||||
enum usb_phy_interface {
|
||||
USBPHY_INTERFACE_MODE_UNKNOWN,
|
||||
USBPHY_INTERFACE_MODE_UTMI,
|
||||
USBPHY_INTERFACE_MODE_UTMIW,
|
||||
USBPHY_INTERFACE_MODE_ULPI,
|
||||
USBPHY_INTERFACE_MODE_SERIAL,
|
||||
USBPHY_INTERFACE_MODE_HSIC,
|
||||
};
|
||||
|
||||
enum usb_phy_events {
|
||||
USB_EVENT_NONE, /* no events or cable disconnected */
|
||||
USB_EVENT_VBUS, /* vbus valid event */
|
||||
USB_EVENT_ID, /* id was grounded */
|
||||
USB_EVENT_CHARGER, /* usb dedicated charger */
|
||||
USB_EVENT_ENUMERATED, /* gadget driver enumerated */
|
||||
};
|
||||
|
||||
/* associate a type with PHY */
|
||||
enum usb_phy_type {
|
||||
USB_PHY_TYPE_UNDEFINED,
|
||||
USB_PHY_TYPE_USB2,
|
||||
USB_PHY_TYPE_USB3,
|
||||
};
|
||||
|
||||
/* OTG defines lots of enumeration states before device reset */
|
||||
enum usb_otg_state {
|
||||
OTG_STATE_UNDEFINED = 0,
|
||||
|
||||
/* single-role peripheral, and dual-role default-b */
|
||||
OTG_STATE_B_IDLE,
|
||||
OTG_STATE_B_SRP_INIT,
|
||||
OTG_STATE_B_PERIPHERAL,
|
||||
|
||||
/* extra dual-role default-b states */
|
||||
OTG_STATE_B_WAIT_ACON,
|
||||
OTG_STATE_B_HOST,
|
||||
|
||||
/* dual-role default-a */
|
||||
OTG_STATE_A_IDLE,
|
||||
OTG_STATE_A_WAIT_VRISE,
|
||||
OTG_STATE_A_WAIT_BCON,
|
||||
OTG_STATE_A_HOST,
|
||||
OTG_STATE_A_SUSPEND,
|
||||
OTG_STATE_A_PERIPHERAL,
|
||||
OTG_STATE_A_WAIT_VFALL,
|
||||
OTG_STATE_A_VBUS_ERR,
|
||||
};
|
||||
|
||||
struct usb_phy;
|
||||
struct usb_otg;
|
||||
|
||||
/* for phys connected thru an ULPI interface, the user must
|
||||
* provide access ops
|
||||
*/
|
||||
struct usb_phy_io_ops {
|
||||
int (*read)(struct usb_phy *x, u32 reg);
|
||||
int (*write)(struct usb_phy *x, u32 val, u32 reg);
|
||||
};
|
||||
|
||||
struct usb_charger_current {
|
||||
unsigned int sdp_min;
|
||||
unsigned int sdp_max;
|
||||
unsigned int dcp_min;
|
||||
unsigned int dcp_max;
|
||||
unsigned int cdp_min;
|
||||
unsigned int cdp_max;
|
||||
unsigned int aca_min;
|
||||
unsigned int aca_max;
|
||||
};
|
||||
|
||||
struct usb_phy {
|
||||
struct device *dev;
|
||||
const char *label;
|
||||
unsigned int flags;
|
||||
|
||||
enum usb_phy_type type;
|
||||
enum usb_phy_events last_event;
|
||||
|
||||
struct usb_otg *otg;
|
||||
|
||||
struct device *io_dev;
|
||||
struct usb_phy_io_ops *io_ops;
|
||||
void __iomem *io_priv;
|
||||
|
||||
/* to support extcon device */
|
||||
struct extcon_dev *edev;
|
||||
struct extcon_dev *id_edev;
|
||||
struct notifier_block vbus_nb;
|
||||
struct notifier_block id_nb;
|
||||
struct notifier_block type_nb;
|
||||
|
||||
/* Support USB charger */
|
||||
enum usb_charger_type chg_type;
|
||||
enum usb_charger_state chg_state;
|
||||
struct usb_charger_current chg_cur;
|
||||
struct work_struct chg_work;
|
||||
|
||||
/* for notification of usb_phy_events */
|
||||
struct atomic_notifier_head notifier;
|
||||
|
||||
/* to pass extra port status to the root hub */
|
||||
u16 port_status;
|
||||
u16 port_change;
|
||||
|
||||
/* to support controllers that have multiple phys */
|
||||
struct list_head head;
|
||||
|
||||
/* initialize/shutdown the phy */
|
||||
int (*init)(struct usb_phy *x);
|
||||
void (*shutdown)(struct usb_phy *x);
|
||||
|
||||
/* enable/disable VBUS */
|
||||
int (*set_vbus)(struct usb_phy *x, int on);
|
||||
|
||||
/* effective for B devices, ignored for A-peripheral */
|
||||
int (*set_power)(struct usb_phy *x,
|
||||
unsigned mA);
|
||||
|
||||
/* Set phy into suspend mode */
|
||||
int (*set_suspend)(struct usb_phy *x,
|
||||
int suspend);
|
||||
|
||||
/*
|
||||
* Set wakeup enable for PHY, in that case, the PHY can be
|
||||
* woken up from suspend status due to external events,
|
||||
* like vbus change, dp/dm change and id.
|
||||
*/
|
||||
int (*set_wakeup)(struct usb_phy *x, bool enabled);
|
||||
|
||||
/* notify phy connect status change */
|
||||
int (*notify_connect)(struct usb_phy *x,
|
||||
enum usb_device_speed speed);
|
||||
int (*notify_disconnect)(struct usb_phy *x,
|
||||
enum usb_device_speed speed);
|
||||
|
||||
/*
|
||||
* Charger detection method can be implemented if you need to
|
||||
* manually detect the charger type.
|
||||
*/
|
||||
enum usb_charger_type (*charger_detect)(struct usb_phy *x);
|
||||
};
|
||||
|
||||
/* for board-specific init logic */
|
||||
extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
|
||||
extern int usb_add_phy_dev(struct usb_phy *);
|
||||
extern void usb_remove_phy(struct usb_phy *);
|
||||
|
||||
/* helpers for direct access thru low-level io interface */
|
||||
static inline int usb_phy_io_read(struct usb_phy *x, u32 reg)
|
||||
{
|
||||
if (x && x->io_ops && x->io_ops->read)
|
||||
return x->io_ops->read(x, reg);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg)
|
||||
{
|
||||
if (x && x->io_ops && x->io_ops->write)
|
||||
return x->io_ops->write(x, val, reg);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_init(struct usb_phy *x)
|
||||
{
|
||||
if (x && x->init)
|
||||
return x->init(x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
usb_phy_shutdown(struct usb_phy *x)
|
||||
{
|
||||
if (x && x->shutdown)
|
||||
x->shutdown(x);
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_vbus_on(struct usb_phy *x)
|
||||
{
|
||||
if (!x || !x->set_vbus)
|
||||
return 0;
|
||||
|
||||
return x->set_vbus(x, true);
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_vbus_off(struct usb_phy *x)
|
||||
{
|
||||
if (!x || !x->set_vbus)
|
||||
return 0;
|
||||
|
||||
return x->set_vbus(x, false);
|
||||
}
|
||||
|
||||
/* for usb host and peripheral controller drivers */
|
||||
#if IS_ENABLED(CONFIG_USB_PHY)
|
||||
extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
|
||||
extern struct usb_phy *devm_usb_get_phy(struct device *dev,
|
||||
enum usb_phy_type type);
|
||||
extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
|
||||
const char *phandle, u8 index);
|
||||
extern struct usb_phy *devm_usb_get_phy_by_node(struct device *dev,
|
||||
struct device_node *node, struct notifier_block *nb);
|
||||
extern void usb_put_phy(struct usb_phy *);
|
||||
extern void usb_phy_set_event(struct usb_phy *x, unsigned long event);
|
||||
extern void usb_phy_set_charger_current(struct usb_phy *usb_phy,
|
||||
unsigned int mA);
|
||||
extern void usb_phy_get_charger_current(struct usb_phy *usb_phy,
|
||||
unsigned int *min, unsigned int *max);
|
||||
extern void usb_phy_set_charger_state(struct usb_phy *usb_phy,
|
||||
enum usb_charger_state state);
|
||||
#else
|
||||
static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
|
||||
enum usb_phy_type type)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
|
||||
const char *phandle, u8 index)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline struct usb_phy *devm_usb_get_phy_by_node(struct device *dev,
|
||||
struct device_node *node, struct notifier_block *nb)
|
||||
{
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
||||
static inline void usb_put_phy(struct usb_phy *x)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void usb_phy_set_charger_current(struct usb_phy *usb_phy,
|
||||
unsigned int mA)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void usb_phy_get_charger_current(struct usb_phy *usb_phy,
|
||||
unsigned int *min,
|
||||
unsigned int *max)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void usb_phy_set_charger_state(struct usb_phy *usb_phy,
|
||||
enum usb_charger_state state)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
usb_phy_set_power(struct usb_phy *x, unsigned mA)
|
||||
{
|
||||
if (!x)
|
||||
return 0;
|
||||
|
||||
usb_phy_set_charger_current(x, mA);
|
||||
|
||||
if (x->set_power)
|
||||
return x->set_power(x, mA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Context: can sleep */
|
||||
static inline int
|
||||
usb_phy_set_suspend(struct usb_phy *x, int suspend)
|
||||
{
|
||||
if (x && x->set_suspend != NULL)
|
||||
return x->set_suspend(x, suspend);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_set_wakeup(struct usb_phy *x, bool enabled)
|
||||
{
|
||||
if (x && x->set_wakeup)
|
||||
return x->set_wakeup(x, enabled);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed)
|
||||
{
|
||||
if (x && x->notify_connect)
|
||||
return x->notify_connect(x, speed);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed)
|
||||
{
|
||||
if (x && x->notify_disconnect)
|
||||
return x->notify_disconnect(x, speed);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* notifiers */
|
||||
static inline int
|
||||
usb_register_notifier(struct usb_phy *x, struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_register(&x->notifier, nb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
|
||||
{
|
||||
atomic_notifier_chain_unregister(&x->notifier, nb);
|
||||
}
|
||||
|
||||
static inline const char *usb_phy_type_string(enum usb_phy_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case USB_PHY_TYPE_USB2:
|
||||
return "USB2 PHY";
|
||||
case USB_PHY_TYPE_USB3:
|
||||
return "USB3 PHY";
|
||||
default:
|
||||
return "UNKNOWN PHY TYPE";
|
||||
}
|
||||
}
|
||||
#endif /* __LINUX_USB_PHY_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* phy-companion.h -- phy companion to indicate the comparator part of PHY
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
|
||||
*
|
||||
* Author: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_PHY_COMPANION_H
|
||||
#define __DRIVERS_PHY_COMPANION_H
|
||||
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
/* phy_companion to take care of VBUS, ID and srp capabilities */
|
||||
struct phy_companion {
|
||||
|
||||
/* effective for A-peripheral, ignored for B devices */
|
||||
int (*set_vbus)(struct phy_companion *x, bool enabled);
|
||||
|
||||
/* for B devices only: start session with A-Host */
|
||||
int (*start_srp)(struct phy_companion *x);
|
||||
};
|
||||
|
||||
#endif /* __DRIVERS_PHY_COMPANION_H */
|
||||
@@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This file holds the definitions of quirks found in USB devices.
|
||||
* Only quirks that affect the whole device, not an interface,
|
||||
* belong here.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_QUIRKS_H
|
||||
#define __LINUX_USB_QUIRKS_H
|
||||
|
||||
/* string descriptors must not be fetched using a 255-byte read */
|
||||
#define USB_QUIRK_STRING_FETCH_255 BIT(0)
|
||||
|
||||
/* device can't resume correctly so reset it instead */
|
||||
#define USB_QUIRK_RESET_RESUME BIT(1)
|
||||
|
||||
/* device can't handle Set-Interface requests */
|
||||
#define USB_QUIRK_NO_SET_INTF BIT(2)
|
||||
|
||||
/* device can't handle its Configuration or Interface strings */
|
||||
#define USB_QUIRK_CONFIG_INTF_STRINGS BIT(3)
|
||||
|
||||
/* device can't be reset(e.g morph devices), don't use reset */
|
||||
#define USB_QUIRK_RESET BIT(4)
|
||||
|
||||
/* device has more interface descriptions than the bNumInterfaces count,
|
||||
and can't handle talking to these interfaces */
|
||||
#define USB_QUIRK_HONOR_BNUMINTERFACES BIT(5)
|
||||
|
||||
/* device needs a pause during initialization, after we read the device
|
||||
descriptor */
|
||||
#define USB_QUIRK_DELAY_INIT BIT(6)
|
||||
|
||||
/*
|
||||
* For high speed and super speed interrupt endpoints, the USB 2.0 and
|
||||
* USB 3.0 spec require the interval in microframes
|
||||
* (1 microframe = 125 microseconds) to be calculated as
|
||||
* interval = 2 ^ (bInterval-1).
|
||||
*
|
||||
* Devices with this quirk report their bInterval as the result of this
|
||||
* calculation instead of the exponent variable used in the calculation.
|
||||
*/
|
||||
#define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL BIT(7)
|
||||
|
||||
/* device can't handle device_qualifier descriptor requests */
|
||||
#define USB_QUIRK_DEVICE_QUALIFIER BIT(8)
|
||||
|
||||
/* device generates spurious wakeup, ignore remote wakeup capability */
|
||||
#define USB_QUIRK_IGNORE_REMOTE_WAKEUP BIT(9)
|
||||
|
||||
/* device can't handle Link Power Management */
|
||||
#define USB_QUIRK_NO_LPM BIT(10)
|
||||
|
||||
/*
|
||||
* Device reports its bInterval as linear frames instead of the
|
||||
* USB 2.0 calculation.
|
||||
*/
|
||||
#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
|
||||
|
||||
/*
|
||||
* Device needs to be disconnected before suspend to prevent spurious
|
||||
* wakeup.
|
||||
*/
|
||||
#define USB_QUIRK_DISCONNECT_SUSPEND BIT(12)
|
||||
|
||||
/* Device needs a pause after every control message. */
|
||||
#define USB_QUIRK_DELAY_CTRL_MSG BIT(13)
|
||||
|
||||
/* Hub needs extra delay after resetting its port. */
|
||||
#define USB_QUIRK_HUB_SLOW_RESET BIT(14)
|
||||
|
||||
/* device has endpoints that should be ignored */
|
||||
#define USB_QUIRK_ENDPOINT_IGNORE BIT(15)
|
||||
|
||||
/* short SET_ADDRESS request timeout */
|
||||
#define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT BIT(16)
|
||||
|
||||
/* skip BOS descriptor request */
|
||||
#define USB_QUIRK_NO_BOS BIT(17)
|
||||
|
||||
/* Device claims zero configurations, forcing to 1 */
|
||||
#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18)
|
||||
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_R8152_H
|
||||
#define __LINUX_R8152_H
|
||||
|
||||
#define RTL8152_REQT_READ 0xc0
|
||||
#define RTL8152_REQT_WRITE 0x40
|
||||
#define RTL8152_REQ_GET_REGS 0x05
|
||||
#define RTL8152_REQ_SET_REGS 0x05
|
||||
|
||||
#define BYTE_EN_DWORD 0xff
|
||||
#define BYTE_EN_WORD 0x33
|
||||
#define BYTE_EN_BYTE 0x11
|
||||
#define BYTE_EN_SIX_BYTES 0x3f
|
||||
#define BYTE_EN_START_MASK 0x0f
|
||||
#define BYTE_EN_END_MASK 0xf0
|
||||
|
||||
#define MCU_TYPE_PLA 0x0100
|
||||
#define MCU_TYPE_USB 0x0000
|
||||
|
||||
/* Define these values to match your device */
|
||||
#define VENDOR_ID_REALTEK 0x0bda
|
||||
#define VENDOR_ID_MICROSOFT 0x045e
|
||||
#define VENDOR_ID_SAMSUNG 0x04e8
|
||||
#define VENDOR_ID_LENOVO 0x17ef
|
||||
#define VENDOR_ID_LINKSYS 0x13b1
|
||||
#define VENDOR_ID_NVIDIA 0x0955
|
||||
#define VENDOR_ID_TPLINK 0x2357
|
||||
#define VENDOR_ID_DLINK 0x2001
|
||||
#define VENDOR_ID_DELL 0x413c
|
||||
#define VENDOR_ID_ASUS 0x0b05
|
||||
#define VENDOR_ID_TRENDNET 0x20f4
|
||||
|
||||
#if IS_REACHABLE(CONFIG_USB_RTL8152)
|
||||
extern u8 rtl8152_get_version(struct usb_interface *intf);
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_R8152_H */
|
||||
@@ -0,0 +1,468 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* R8A66597 driver platform data
|
||||
*
|
||||
* Copyright (C) 2009 Renesas Solutions Corp.
|
||||
*
|
||||
* Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_R8A66597_H
|
||||
#define __LINUX_USB_R8A66597_H
|
||||
|
||||
#define R8A66597_PLATDATA_XTAL_12MHZ 0x01
|
||||
#define R8A66597_PLATDATA_XTAL_24MHZ 0x02
|
||||
#define R8A66597_PLATDATA_XTAL_48MHZ 0x03
|
||||
|
||||
struct r8a66597_platdata {
|
||||
/* This callback can control port power instead of DVSTCTR register. */
|
||||
void (*port_power)(int port, int power);
|
||||
|
||||
/* This parameter is for BUSWAIT */
|
||||
u16 buswait;
|
||||
|
||||
/* set one = on chip controller, set zero = external controller */
|
||||
unsigned on_chip:1;
|
||||
|
||||
/* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */
|
||||
unsigned xtal:2;
|
||||
|
||||
/* set one = 3.3V, set zero = 1.5V */
|
||||
unsigned vif:1;
|
||||
|
||||
/* set one = big endian, set zero = little endian */
|
||||
unsigned endian:1;
|
||||
|
||||
/* (external controller only) set one = WR0_N shorted to WR1_N */
|
||||
unsigned wr0_shorted_to_wr1:1;
|
||||
|
||||
/* set one = using SUDMAC */
|
||||
unsigned sudmac:1;
|
||||
};
|
||||
|
||||
/* Register definitions */
|
||||
#define SYSCFG0 0x00
|
||||
#define SYSCFG1 0x02
|
||||
#define SYSSTS0 0x04
|
||||
#define SYSSTS1 0x06
|
||||
#define DVSTCTR0 0x08
|
||||
#define DVSTCTR1 0x0A
|
||||
#define TESTMODE 0x0C
|
||||
#define PINCFG 0x0E
|
||||
#define DMA0CFG 0x10
|
||||
#define DMA1CFG 0x12
|
||||
#define CFIFO 0x14
|
||||
#define D0FIFO 0x18
|
||||
#define D1FIFO 0x1C
|
||||
#define CFIFOSEL 0x20
|
||||
#define CFIFOCTR 0x22
|
||||
#define CFIFOSIE 0x24
|
||||
#define D0FIFOSEL 0x28
|
||||
#define D0FIFOCTR 0x2A
|
||||
#define D1FIFOSEL 0x2C
|
||||
#define D1FIFOCTR 0x2E
|
||||
#define INTENB0 0x30
|
||||
#define INTENB1 0x32
|
||||
#define INTENB2 0x34
|
||||
#define BRDYENB 0x36
|
||||
#define NRDYENB 0x38
|
||||
#define BEMPENB 0x3A
|
||||
#define SOFCFG 0x3C
|
||||
#define INTSTS0 0x40
|
||||
#define INTSTS1 0x42
|
||||
#define INTSTS2 0x44
|
||||
#define BRDYSTS 0x46
|
||||
#define NRDYSTS 0x48
|
||||
#define BEMPSTS 0x4A
|
||||
#define FRMNUM 0x4C
|
||||
#define UFRMNUM 0x4E
|
||||
#define USBADDR 0x50
|
||||
#define USBREQ 0x54
|
||||
#define USBVAL 0x56
|
||||
#define USBINDX 0x58
|
||||
#define USBLENG 0x5A
|
||||
#define DCPCFG 0x5C
|
||||
#define DCPMAXP 0x5E
|
||||
#define DCPCTR 0x60
|
||||
#define PIPESEL 0x64
|
||||
#define PIPECFG 0x68
|
||||
#define PIPEBUF 0x6A
|
||||
#define PIPEMAXP 0x6C
|
||||
#define PIPEPERI 0x6E
|
||||
#define PIPE1CTR 0x70
|
||||
#define PIPE2CTR 0x72
|
||||
#define PIPE3CTR 0x74
|
||||
#define PIPE4CTR 0x76
|
||||
#define PIPE5CTR 0x78
|
||||
#define PIPE6CTR 0x7A
|
||||
#define PIPE7CTR 0x7C
|
||||
#define PIPE8CTR 0x7E
|
||||
#define PIPE9CTR 0x80
|
||||
#define PIPE1TRE 0x90
|
||||
#define PIPE1TRN 0x92
|
||||
#define PIPE2TRE 0x94
|
||||
#define PIPE2TRN 0x96
|
||||
#define PIPE3TRE 0x98
|
||||
#define PIPE3TRN 0x9A
|
||||
#define PIPE4TRE 0x9C
|
||||
#define PIPE4TRN 0x9E
|
||||
#define PIPE5TRE 0xA0
|
||||
#define PIPE5TRN 0xA2
|
||||
#define DEVADD0 0xD0
|
||||
#define DEVADD1 0xD2
|
||||
#define DEVADD2 0xD4
|
||||
#define DEVADD3 0xD6
|
||||
#define DEVADD4 0xD8
|
||||
#define DEVADD5 0xDA
|
||||
#define DEVADD6 0xDC
|
||||
#define DEVADD7 0xDE
|
||||
#define DEVADD8 0xE0
|
||||
#define DEVADD9 0xE2
|
||||
#define DEVADDA 0xE4
|
||||
|
||||
/* System Configuration Control Register */
|
||||
#define XTAL 0xC000 /* b15-14: Crystal selection */
|
||||
#define XTAL48 0x8000 /* 48MHz */
|
||||
#define XTAL24 0x4000 /* 24MHz */
|
||||
#define XTAL12 0x0000 /* 12MHz */
|
||||
#define XCKE 0x2000 /* b13: External clock enable */
|
||||
#define PLLC 0x0800 /* b11: PLL control */
|
||||
#define SCKE 0x0400 /* b10: USB clock enable */
|
||||
#define PCSDIS 0x0200 /* b9: not CS wakeup */
|
||||
#define LPSME 0x0100 /* b8: Low power sleep mode */
|
||||
#define HSE 0x0080 /* b7: Hi-speed enable */
|
||||
#define DCFM 0x0040 /* b6: Controller function select */
|
||||
#define DRPD 0x0020 /* b5: D+/- pull down control */
|
||||
#define DPRPU 0x0010 /* b4: D+ pull up control */
|
||||
#define USBE 0x0001 /* b0: USB module operation enable */
|
||||
|
||||
/* System Configuration Status Register */
|
||||
#define OVCBIT 0x8000 /* b15-14: Over-current bit */
|
||||
#define OVCMON 0xC000 /* b15-14: Over-current monitor */
|
||||
#define SOFEA 0x0020 /* b5: SOF monitor */
|
||||
#define IDMON 0x0004 /* b3: ID-pin monitor */
|
||||
#define LNST 0x0003 /* b1-0: D+, D- line status */
|
||||
#define SE1 0x0003 /* SE1 */
|
||||
#define FS_KSTS 0x0002 /* Full-Speed K State */
|
||||
#define FS_JSTS 0x0001 /* Full-Speed J State */
|
||||
#define LS_JSTS 0x0002 /* Low-Speed J State */
|
||||
#define LS_KSTS 0x0001 /* Low-Speed K State */
|
||||
#define SE0 0x0000 /* SE0 */
|
||||
|
||||
/* Device State Control Register */
|
||||
#define EXTLP0 0x0400 /* b10: External port */
|
||||
#define VBOUT 0x0200 /* b9: VBUS output */
|
||||
#define WKUP 0x0100 /* b8: Remote wakeup */
|
||||
#define RWUPE 0x0080 /* b7: Remote wakeup sense */
|
||||
#define USBRST 0x0040 /* b6: USB reset enable */
|
||||
#define RESUME 0x0020 /* b5: Resume enable */
|
||||
#define UACT 0x0010 /* b4: USB bus enable */
|
||||
#define RHST 0x0007 /* b1-0: Reset handshake status */
|
||||
#define HSPROC 0x0004 /* HS handshake is processing */
|
||||
#define HSMODE 0x0003 /* Hi-Speed mode */
|
||||
#define FSMODE 0x0002 /* Full-Speed mode */
|
||||
#define LSMODE 0x0001 /* Low-Speed mode */
|
||||
#define UNDECID 0x0000 /* Undecided */
|
||||
|
||||
/* Test Mode Register */
|
||||
#define UTST 0x000F /* b3-0: Test select */
|
||||
#define H_TST_PACKET 0x000C /* HOST TEST Packet */
|
||||
#define H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */
|
||||
#define H_TST_K 0x000A /* HOST TEST K */
|
||||
#define H_TST_J 0x0009 /* HOST TEST J */
|
||||
#define H_TST_NORMAL 0x0000 /* HOST Normal Mode */
|
||||
#define P_TST_PACKET 0x0004 /* PERI TEST Packet */
|
||||
#define P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */
|
||||
#define P_TST_K 0x0002 /* PERI TEST K */
|
||||
#define P_TST_J 0x0001 /* PERI TEST J */
|
||||
#define P_TST_NORMAL 0x0000 /* PERI Normal Mode */
|
||||
|
||||
/* Data Pin Configuration Register */
|
||||
#define LDRV 0x8000 /* b15: Drive Current Adjust */
|
||||
#define VIF1 0x0000 /* VIF = 1.8V */
|
||||
#define VIF3 0x8000 /* VIF = 3.3V */
|
||||
#define INTA 0x0001 /* b1: USB INT-pin active */
|
||||
|
||||
/* DMAx Pin Configuration Register */
|
||||
#define DREQA 0x4000 /* b14: Dreq active select */
|
||||
#define BURST 0x2000 /* b13: Burst mode */
|
||||
#define DACKA 0x0400 /* b10: Dack active select */
|
||||
#define DFORM 0x0380 /* b9-7: DMA mode select */
|
||||
#define CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */
|
||||
#define CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */
|
||||
#define CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */
|
||||
#define SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */
|
||||
#define DENDA 0x0040 /* b6: Dend active select */
|
||||
#define PKTM 0x0020 /* b5: Packet mode */
|
||||
#define DENDE 0x0010 /* b4: Dend enable */
|
||||
#define OBUS 0x0004 /* b2: OUTbus mode */
|
||||
|
||||
/* CFIFO/DxFIFO Port Select Register */
|
||||
#define RCNT 0x8000 /* b15: Read count mode */
|
||||
#define REW 0x4000 /* b14: Buffer rewind */
|
||||
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
|
||||
#define DREQE 0x1000 /* b12: DREQ output enable */
|
||||
#define MBW_8 0x0000 /* 8bit */
|
||||
#define MBW_16 0x0400 /* 16bit */
|
||||
#define MBW_32 0x0800 /* 32bit */
|
||||
#define BIGEND 0x0100 /* b8: Big endian mode */
|
||||
#define BYTE_LITTLE 0x0000 /* little dendian */
|
||||
#define BYTE_BIG 0x0100 /* big endifan */
|
||||
#define ISEL 0x0020 /* b5: DCP FIFO port direction select */
|
||||
#define CURPIPE 0x000F /* b2-0: PIPE select */
|
||||
|
||||
/* CFIFO/DxFIFO Port Control Register */
|
||||
#define BVAL 0x8000 /* b15: Buffer valid flag */
|
||||
#define BCLR 0x4000 /* b14: Buffer clear */
|
||||
#define FRDY 0x2000 /* b13: FIFO ready */
|
||||
#define DTLN 0x0FFF /* b11-0: FIFO received data length */
|
||||
|
||||
/* Interrupt Enable Register 0 */
|
||||
#define VBSE 0x8000 /* b15: VBUS interrupt */
|
||||
#define RSME 0x4000 /* b14: Resume interrupt */
|
||||
#define SOFE 0x2000 /* b13: Frame update interrupt */
|
||||
#define DVSE 0x1000 /* b12: Device state transition interrupt */
|
||||
#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */
|
||||
#define BEMPE 0x0400 /* b10: Buffer empty interrupt */
|
||||
#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */
|
||||
#define BRDYE 0x0100 /* b8: Buffer ready interrupt */
|
||||
|
||||
/* Interrupt Enable Register 1 */
|
||||
#define OVRCRE 0x8000 /* b15: Over-current interrupt */
|
||||
#define BCHGE 0x4000 /* b14: USB us chenge interrupt */
|
||||
#define DTCHE 0x1000 /* b12: Detach sense interrupt */
|
||||
#define ATTCHE 0x0800 /* b11: Attach sense interrupt */
|
||||
#define EOFERRE 0x0040 /* b6: EOF error interrupt */
|
||||
#define SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */
|
||||
#define SACKE 0x0010 /* b4: SETUP ACK interrupt */
|
||||
|
||||
/* BRDY Interrupt Enable/Status Register */
|
||||
#define BRDY9 0x0200 /* b9: PIPE9 */
|
||||
#define BRDY8 0x0100 /* b8: PIPE8 */
|
||||
#define BRDY7 0x0080 /* b7: PIPE7 */
|
||||
#define BRDY6 0x0040 /* b6: PIPE6 */
|
||||
#define BRDY5 0x0020 /* b5: PIPE5 */
|
||||
#define BRDY4 0x0010 /* b4: PIPE4 */
|
||||
#define BRDY3 0x0008 /* b3: PIPE3 */
|
||||
#define BRDY2 0x0004 /* b2: PIPE2 */
|
||||
#define BRDY1 0x0002 /* b1: PIPE1 */
|
||||
#define BRDY0 0x0001 /* b1: PIPE0 */
|
||||
|
||||
/* NRDY Interrupt Enable/Status Register */
|
||||
#define NRDY9 0x0200 /* b9: PIPE9 */
|
||||
#define NRDY8 0x0100 /* b8: PIPE8 */
|
||||
#define NRDY7 0x0080 /* b7: PIPE7 */
|
||||
#define NRDY6 0x0040 /* b6: PIPE6 */
|
||||
#define NRDY5 0x0020 /* b5: PIPE5 */
|
||||
#define NRDY4 0x0010 /* b4: PIPE4 */
|
||||
#define NRDY3 0x0008 /* b3: PIPE3 */
|
||||
#define NRDY2 0x0004 /* b2: PIPE2 */
|
||||
#define NRDY1 0x0002 /* b1: PIPE1 */
|
||||
#define NRDY0 0x0001 /* b1: PIPE0 */
|
||||
|
||||
/* BEMP Interrupt Enable/Status Register */
|
||||
#define BEMP9 0x0200 /* b9: PIPE9 */
|
||||
#define BEMP8 0x0100 /* b8: PIPE8 */
|
||||
#define BEMP7 0x0080 /* b7: PIPE7 */
|
||||
#define BEMP6 0x0040 /* b6: PIPE6 */
|
||||
#define BEMP5 0x0020 /* b5: PIPE5 */
|
||||
#define BEMP4 0x0010 /* b4: PIPE4 */
|
||||
#define BEMP3 0x0008 /* b3: PIPE3 */
|
||||
#define BEMP2 0x0004 /* b2: PIPE2 */
|
||||
#define BEMP1 0x0002 /* b1: PIPE1 */
|
||||
#define BEMP0 0x0001 /* b0: PIPE0 */
|
||||
|
||||
/* SOF Pin Configuration Register */
|
||||
#define TRNENSEL 0x0100 /* b8: Select transaction enable period */
|
||||
#define BRDYM 0x0040 /* b6: BRDY clear timing */
|
||||
#define INTL 0x0020 /* b5: Interrupt sense select */
|
||||
#define EDGESTS 0x0010 /* b4: */
|
||||
#define SOFMODE 0x000C /* b3-2: SOF pin select */
|
||||
#define SOF_125US 0x0008 /* SOF OUT 125us Frame Signal */
|
||||
#define SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */
|
||||
#define SOF_DISABLE 0x0000 /* SOF OUT Disable */
|
||||
|
||||
/* Interrupt Status Register 0 */
|
||||
#define VBINT 0x8000 /* b15: VBUS interrupt */
|
||||
#define RESM 0x4000 /* b14: Resume interrupt */
|
||||
#define SOFR 0x2000 /* b13: SOF frame update interrupt */
|
||||
#define DVST 0x1000 /* b12: Device state transition interrupt */
|
||||
#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */
|
||||
#define BEMP 0x0400 /* b10: Buffer empty interrupt */
|
||||
#define NRDY 0x0200 /* b9: Buffer not ready interrupt */
|
||||
#define BRDY 0x0100 /* b8: Buffer ready interrupt */
|
||||
#define VBSTS 0x0080 /* b7: VBUS input port */
|
||||
#define DVSQ 0x0070 /* b6-4: Device state */
|
||||
#define DS_SPD_CNFG 0x0070 /* Suspend Configured */
|
||||
#define DS_SPD_ADDR 0x0060 /* Suspend Address */
|
||||
#define DS_SPD_DFLT 0x0050 /* Suspend Default */
|
||||
#define DS_SPD_POWR 0x0040 /* Suspend Powered */
|
||||
#define DS_SUSP 0x0040 /* Suspend */
|
||||
#define DS_CNFG 0x0030 /* Configured */
|
||||
#define DS_ADDS 0x0020 /* Address */
|
||||
#define DS_DFLT 0x0010 /* Default */
|
||||
#define DS_POWR 0x0000 /* Powered */
|
||||
#define DVSQS 0x0030 /* b5-4: Device state */
|
||||
#define VALID 0x0008 /* b3: Setup packet detected flag */
|
||||
#define CTSQ 0x0007 /* b2-0: Control transfer stage */
|
||||
#define CS_SQER 0x0006 /* Sequence error */
|
||||
#define CS_WRND 0x0005 /* Control write nodata status stage */
|
||||
#define CS_WRSS 0x0004 /* Control write status stage */
|
||||
#define CS_WRDS 0x0003 /* Control write data stage */
|
||||
#define CS_RDSS 0x0002 /* Control read status stage */
|
||||
#define CS_RDDS 0x0001 /* Control read data stage */
|
||||
#define CS_IDST 0x0000 /* Idle or setup stage */
|
||||
|
||||
/* Interrupt Status Register 1 */
|
||||
#define OVRCR 0x8000 /* b15: Over-current interrupt */
|
||||
#define BCHG 0x4000 /* b14: USB bus chenge interrupt */
|
||||
#define DTCH 0x1000 /* b12: Detach sense interrupt */
|
||||
#define ATTCH 0x0800 /* b11: Attach sense interrupt */
|
||||
#define EOFERR 0x0040 /* b6: EOF-error interrupt */
|
||||
#define SIGN 0x0020 /* b5: Setup ignore interrupt */
|
||||
#define SACK 0x0010 /* b4: Setup acknowledge interrupt */
|
||||
|
||||
/* Frame Number Register */
|
||||
#define OVRN 0x8000 /* b15: Overrun error */
|
||||
#define CRCE 0x4000 /* b14: Received data error */
|
||||
#define FRNM 0x07FF /* b10-0: Frame number */
|
||||
|
||||
/* Micro Frame Number Register */
|
||||
#define UFRNM 0x0007 /* b2-0: Micro frame number */
|
||||
|
||||
/* Default Control Pipe Maxpacket Size Register */
|
||||
/* Pipe Maxpacket Size Register */
|
||||
#define DEVSEL 0xF000 /* b15-14: Device address select */
|
||||
#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */
|
||||
|
||||
/* Default Control Pipe Control Register */
|
||||
#define BSTS 0x8000 /* b15: Buffer status */
|
||||
#define SUREQ 0x4000 /* b14: Send USB request */
|
||||
#define CSCLR 0x2000 /* b13: complete-split status clear */
|
||||
#define CSSTS 0x1000 /* b12: complete-split status */
|
||||
#define SUREQCLR 0x0800 /* b11: stop setup request */
|
||||
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
|
||||
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
|
||||
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
|
||||
#define PBUSY 0x0020 /* b5: pipe busy */
|
||||
#define PINGE 0x0010 /* b4: ping enable */
|
||||
#define CCPL 0x0004 /* b2: Enable control transfer complete */
|
||||
#define PID 0x0003 /* b1-0: Response PID */
|
||||
#define PID_STALL11 0x0003 /* STALL */
|
||||
#define PID_STALL 0x0002 /* STALL */
|
||||
#define PID_BUF 0x0001 /* BUF */
|
||||
#define PID_NAK 0x0000 /* NAK */
|
||||
|
||||
/* Pipe Window Select Register */
|
||||
#define PIPENM 0x0007 /* b2-0: Pipe select */
|
||||
|
||||
/* Pipe Configuration Register */
|
||||
#define R8A66597_TYP 0xC000 /* b15-14: Transfer type */
|
||||
#define R8A66597_ISO 0xC000 /* Isochronous */
|
||||
#define R8A66597_INT 0x8000 /* Interrupt */
|
||||
#define R8A66597_BULK 0x4000 /* Bulk */
|
||||
#define R8A66597_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */
|
||||
#define R8A66597_DBLB 0x0200 /* b9: Double buffer mode select */
|
||||
#define R8A66597_CNTMD 0x0100 /* b8: Continuous transfer mode select */
|
||||
#define R8A66597_SHTNAK 0x0080 /* b7: Transfer end NAK */
|
||||
#define R8A66597_DIR 0x0010 /* b4: Transfer direction select */
|
||||
#define R8A66597_EPNUM 0x000F /* b3-0: Eendpoint number select */
|
||||
|
||||
/* Pipe Buffer Configuration Register */
|
||||
#define BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */
|
||||
#define BUFNMB 0x007F /* b6-0: Pipe buffer number */
|
||||
#define PIPE0BUF 256
|
||||
#define PIPExBUF 64
|
||||
|
||||
/* Pipe Maxpacket Size Register */
|
||||
#define MXPS 0x07FF /* b10-0: Maxpacket size */
|
||||
|
||||
/* Pipe Cycle Configuration Register */
|
||||
#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */
|
||||
#define IITV 0x0007 /* b2-0: Isochronous interval */
|
||||
|
||||
/* Pipex Control Register */
|
||||
#define BSTS 0x8000 /* b15: Buffer status */
|
||||
#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */
|
||||
#define CSCLR 0x2000 /* b13: complete-split status clear */
|
||||
#define CSSTS 0x1000 /* b12: complete-split status */
|
||||
#define ATREPM 0x0400 /* b10: Auto repeat mode */
|
||||
#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */
|
||||
#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */
|
||||
#define SQSET 0x0080 /* b7: Sequence toggle bit set */
|
||||
#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */
|
||||
#define PBUSY 0x0020 /* b5: pipe busy */
|
||||
#define PID 0x0003 /* b1-0: Response PID */
|
||||
|
||||
/* PIPExTRE */
|
||||
#define TRENB 0x0200 /* b9: Transaction counter enable */
|
||||
#define TRCLR 0x0100 /* b8: Transaction counter clear */
|
||||
|
||||
/* PIPExTRN */
|
||||
#define TRNCNT 0xFFFF /* b15-0: Transaction counter */
|
||||
|
||||
/* DEVADDx */
|
||||
#define UPPHUB 0x7800
|
||||
#define HUBPORT 0x0700
|
||||
#define USBSPD 0x00C0
|
||||
#define RTPORT 0x0001
|
||||
|
||||
/* SUDMAC registers */
|
||||
#define CH0CFG 0x00
|
||||
#define CH1CFG 0x04
|
||||
#define CH0BA 0x10
|
||||
#define CH1BA 0x14
|
||||
#define CH0BBC 0x18
|
||||
#define CH1BBC 0x1C
|
||||
#define CH0CA 0x20
|
||||
#define CH1CA 0x24
|
||||
#define CH0CBC 0x28
|
||||
#define CH1CBC 0x2C
|
||||
#define CH0DEN 0x30
|
||||
#define CH1DEN 0x34
|
||||
#define DSTSCLR 0x38
|
||||
#define DBUFCTRL 0x3C
|
||||
#define DINTCTRL 0x40
|
||||
#define DINTSTS 0x44
|
||||
#define DINTSTSCLR 0x48
|
||||
#define CH0SHCTRL 0x50
|
||||
#define CH1SHCTRL 0x54
|
||||
|
||||
/* SUDMAC Configuration Registers */
|
||||
#define SENDBUFM 0x1000 /* b12: Transmit Buffer Mode */
|
||||
#define RCVENDM 0x0100 /* b8: Receive Data Transfer End Mode */
|
||||
#define LBA_WAIT 0x0030 /* b5-4: Local Bus Access Wait */
|
||||
|
||||
/* DMA Enable Registers */
|
||||
#define DEN 0x0001 /* b1: DMA Transfer Enable */
|
||||
|
||||
/* DMA Status Clear Register */
|
||||
#define CH1STCLR 0x0002 /* b2: Ch1 DMA Status Clear */
|
||||
#define CH0STCLR 0x0001 /* b1: Ch0 DMA Status Clear */
|
||||
|
||||
/* DMA Buffer Control Register */
|
||||
#define CH1BUFW 0x0200 /* b9: Ch1 DMA Buffer Data Transfer Enable */
|
||||
#define CH0BUFW 0x0100 /* b8: Ch0 DMA Buffer Data Transfer Enable */
|
||||
#define CH1BUFS 0x0002 /* b2: Ch1 DMA Buffer Data Status */
|
||||
#define CH0BUFS 0x0001 /* b1: Ch0 DMA Buffer Data Status */
|
||||
|
||||
/* DMA Interrupt Control Register */
|
||||
#define CH1ERRE 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Enable */
|
||||
#define CH0ERRE 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Enable */
|
||||
#define CH1ENDE 0x0002 /* b2: Ch1 DMA Transfer End Int Enable */
|
||||
#define CH0ENDE 0x0001 /* b1: Ch0 DMA Transfer End Int Enable */
|
||||
|
||||
/* DMA Interrupt Status Register */
|
||||
#define CH1ERRS 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Status */
|
||||
#define CH0ERRS 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Status */
|
||||
#define CH1ENDS 0x0002 /* b2: Ch1 DMA Transfer End Int Status */
|
||||
#define CH0ENDS 0x0001 /* b1: Ch0 DMA Transfer End Int Status */
|
||||
|
||||
/* DMA Interrupt Status Clear Register */
|
||||
#define CH1ERRC 0x0200 /* b9: Ch1 SHwy Res Err Detect Int Stat Clear */
|
||||
#define CH0ERRC 0x0100 /* b8: Ch0 SHwy Res Err Detect Int Stat Clear */
|
||||
#define CH1ENDC 0x0002 /* b2: Ch1 DMA Transfer End Int Stat Clear */
|
||||
#define CH0ENDC 0x0001 /* b1: Ch0 DMA Transfer End Int Stat Clear */
|
||||
|
||||
#endif /* __LINUX_USB_R8A66597_H */
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
// SPDX-License-Identifier: GPL-1.0+
|
||||
/*
|
||||
* Renesas USB
|
||||
*
|
||||
* Copyright (C) 2011 Renesas Solutions Corp.
|
||||
* Copyright (C) 2019 Renesas Electronics Corporation
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
*/
|
||||
#ifndef RENESAS_USB_H
|
||||
#define RENESAS_USB_H
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
/*
|
||||
* module type
|
||||
*
|
||||
* it will be return value from get_id
|
||||
*/
|
||||
enum {
|
||||
USBHS_HOST = 0,
|
||||
USBHS_GADGET,
|
||||
USBHS_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* callback functions for platform
|
||||
*
|
||||
* These functions are called from driver for platform
|
||||
*/
|
||||
struct renesas_usbhs_platform_callback {
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* Hardware init function for platform.
|
||||
* it is called when driver was probed.
|
||||
*/
|
||||
int (*hardware_init)(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* Hardware exit function for platform.
|
||||
* it is called when driver was removed
|
||||
*/
|
||||
int (*hardware_exit)(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* for board specific clock control
|
||||
*/
|
||||
int (*power_ctrl)(struct platform_device *pdev,
|
||||
void __iomem *base, int enable);
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* Phy reset for platform
|
||||
*/
|
||||
int (*phy_reset)(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* get USB ID function
|
||||
* - USBHS_HOST
|
||||
* - USBHS_GADGET
|
||||
*/
|
||||
int (*get_id)(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* get VBUS status function.
|
||||
*/
|
||||
int (*get_vbus)(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* VBUS control is needed for Host
|
||||
*/
|
||||
int (*set_vbus)(struct platform_device *pdev, int enable);
|
||||
|
||||
/*
|
||||
* option:
|
||||
* extcon notifier to set host/peripheral mode.
|
||||
*/
|
||||
int (*notifier)(struct notifier_block *nb, unsigned long event,
|
||||
void *data);
|
||||
};
|
||||
|
||||
/*
|
||||
* parameters for renesas usbhs
|
||||
*
|
||||
* some register needs USB chip specific parameters.
|
||||
* This struct show it to driver
|
||||
*/
|
||||
|
||||
struct renesas_usbhs_driver_pipe_config {
|
||||
u8 type; /* USB_ENDPOINT_XFER_xxx */
|
||||
u16 bufsize;
|
||||
u8 bufnum;
|
||||
bool double_buf;
|
||||
};
|
||||
#define RENESAS_USBHS_PIPE(_type, _size, _num, _double_buf) { \
|
||||
.type = (_type), \
|
||||
.bufsize = (_size), \
|
||||
.bufnum = (_num), \
|
||||
.double_buf = (_double_buf), \
|
||||
}
|
||||
|
||||
struct renesas_usbhs_driver_param {
|
||||
/*
|
||||
* pipe settings
|
||||
*/
|
||||
struct renesas_usbhs_driver_pipe_config *pipe_configs;
|
||||
int pipe_size; /* pipe_configs array size */
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* for BUSWAIT :: BWAIT
|
||||
* see
|
||||
* renesas_usbhs/common.c :: usbhsc_set_buswait()
|
||||
* */
|
||||
int buswait_bwait;
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* delay time from notify_hotplug callback
|
||||
*/
|
||||
int detection_delay; /* msec */
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* dma id for dmaengine
|
||||
* The data transfer direction on D0FIFO/D1FIFO should be
|
||||
* fixed for keeping consistency.
|
||||
* So, the platform id settings will be..
|
||||
* .d0_tx_id = xx_TX,
|
||||
* .d1_rx_id = xx_RX,
|
||||
* or
|
||||
* .d1_tx_id = xx_TX,
|
||||
* .d0_rx_id = xx_RX,
|
||||
*/
|
||||
int d0_tx_id;
|
||||
int d0_rx_id;
|
||||
int d1_tx_id;
|
||||
int d1_rx_id;
|
||||
int d2_tx_id;
|
||||
int d2_rx_id;
|
||||
int d3_tx_id;
|
||||
int d3_rx_id;
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* pio <--> dma border.
|
||||
*/
|
||||
int pio_dma_border; /* default is 64byte */
|
||||
|
||||
/*
|
||||
* option:
|
||||
*/
|
||||
u32 has_usb_dmac:1; /* for USB-DMAC */
|
||||
u32 runtime_pwctrl:1;
|
||||
u32 has_cnen:1;
|
||||
u32 cfifo_byte_addr:1; /* CFIFO is byte addressable */
|
||||
#define USBHS_USB_DMAC_XFER_SIZE 32 /* hardcode the xfer size */
|
||||
u32 multi_clks:1;
|
||||
u32 has_new_pipe_configs:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* platform information for renesas_usbhs driver.
|
||||
*/
|
||||
struct renesas_usbhs_platform_info {
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* platform set these functions before
|
||||
* call platform_add_devices if needed
|
||||
*/
|
||||
struct renesas_usbhs_platform_callback platform_callback;
|
||||
|
||||
/*
|
||||
* option:
|
||||
*
|
||||
* driver use these param for some register
|
||||
*/
|
||||
struct renesas_usbhs_driver_param driver_param;
|
||||
};
|
||||
|
||||
#endif /* RENESAS_USB_H */
|
||||
@@ -0,0 +1,198 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Host Side support for RNDIS Networking Links
|
||||
* Copyright (C) 2005 by David Brownell
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_RNDIS_HOST_H
|
||||
#define __LINUX_USB_RNDIS_HOST_H
|
||||
|
||||
#include <linux/rndis.h>
|
||||
|
||||
/*
|
||||
* CONTROL uses CDC "encapsulated commands" with funky notifications.
|
||||
* - control-out: SEND_ENCAPSULATED
|
||||
* - interrupt-in: RESPONSE_AVAILABLE
|
||||
* - control-in: GET_ENCAPSULATED
|
||||
*
|
||||
* We'll try to ignore the RESPONSE_AVAILABLE notifications.
|
||||
*
|
||||
* REVISIT some RNDIS implementations seem to have curious issues still
|
||||
* to be resolved.
|
||||
*/
|
||||
struct rndis_msg_hdr {
|
||||
__le32 msg_type; /* RNDIS_MSG_* */
|
||||
__le32 msg_len;
|
||||
/* followed by data that varies between messages */
|
||||
__le32 request_id;
|
||||
__le32 status;
|
||||
/* ... and more */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
|
||||
#define CONTROL_BUFFER_SIZE 1025
|
||||
|
||||
/* RNDIS defines an (absurdly huge) 10 second control timeout,
|
||||
* but ActiveSync seems to use a more usual 5 second timeout
|
||||
* (which matches the USB 2.0 spec).
|
||||
*/
|
||||
#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
|
||||
|
||||
struct rndis_data_hdr {
|
||||
__le32 msg_type; /* RNDIS_MSG_PACKET */
|
||||
__le32 msg_len; /* rndis_data_hdr + data_len + pad */
|
||||
__le32 data_offset; /* 36 -- right after header */
|
||||
__le32 data_len; /* ... real packet size */
|
||||
|
||||
__le32 oob_data_offset; /* zero */
|
||||
__le32 oob_data_len; /* zero */
|
||||
__le32 num_oob; /* zero */
|
||||
__le32 packet_data_offset; /* zero */
|
||||
|
||||
__le32 packet_data_len; /* zero */
|
||||
__le32 vc_handle; /* zero */
|
||||
__le32 reserved; /* zero */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_init { /* OUT */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_INIT */
|
||||
__le32 msg_len; /* 24 */
|
||||
__le32 request_id;
|
||||
__le32 major_version; /* of rndis (1.0) */
|
||||
__le32 minor_version;
|
||||
__le32 max_transfer_size;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_init_c { /* IN */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_INIT_C */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 status;
|
||||
__le32 major_version; /* of rndis (1.0) */
|
||||
__le32 minor_version;
|
||||
__le32 device_flags;
|
||||
__le32 medium; /* zero == 802.3 */
|
||||
__le32 max_packets_per_message;
|
||||
__le32 max_transfer_size;
|
||||
__le32 packet_alignment; /* max 7; (1<<n) bytes */
|
||||
__le32 af_list_offset; /* zero */
|
||||
__le32 af_list_size; /* zero */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_halt { /* OUT (no reply) */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_HALT */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_query { /* OUT */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_QUERY */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 oid;
|
||||
__le32 len;
|
||||
__le32 offset;
|
||||
/*?*/ __le32 handle; /* zero */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_query_c { /* IN */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_QUERY_C */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 status;
|
||||
__le32 len;
|
||||
__le32 offset;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_set { /* OUT */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_SET */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 oid;
|
||||
__le32 len;
|
||||
__le32 offset;
|
||||
/*?*/ __le32 handle; /* zero */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_set_c { /* IN */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_SET_C */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_reset { /* IN */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_RESET */
|
||||
__le32 msg_len;
|
||||
__le32 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_reset_c { /* OUT */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_RESET_C */
|
||||
__le32 msg_len;
|
||||
__le32 status;
|
||||
__le32 addressing_lost;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_indicate { /* IN (unrequested) */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_INDICATE */
|
||||
__le32 msg_len;
|
||||
__le32 status;
|
||||
__le32 length;
|
||||
__le32 offset;
|
||||
/**/ __le32 diag_status;
|
||||
__le32 error_offset;
|
||||
/**/ __le32 message;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_keepalive { /* OUT (optionally IN) */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_keepalive_c { /* IN (optionally OUT) */
|
||||
/* header and: */
|
||||
__le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
|
||||
__le32 msg_len;
|
||||
__le32 request_id;
|
||||
__le32 status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* default filter used with RNDIS devices */
|
||||
#define RNDIS_DEFAULT_FILTER ( \
|
||||
RNDIS_PACKET_TYPE_DIRECTED | \
|
||||
RNDIS_PACKET_TYPE_BROADCAST | \
|
||||
RNDIS_PACKET_TYPE_ALL_MULTICAST | \
|
||||
RNDIS_PACKET_TYPE_PROMISCUOUS)
|
||||
|
||||
/* Flags to require specific physical medium type for generic_rndis_bind() */
|
||||
#define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001
|
||||
#define FLAG_RNDIS_PHYM_WIRELESS 0x0002
|
||||
|
||||
/* Flags for driver_info::data */
|
||||
#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */
|
||||
#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP 2 /* device ignores configured MAC address */
|
||||
|
||||
extern void rndis_status(struct usbnet *dev, struct urb *urb);
|
||||
extern int
|
||||
rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen);
|
||||
extern int
|
||||
generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags);
|
||||
extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
|
||||
extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
|
||||
extern struct sk_buff *
|
||||
rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
|
||||
|
||||
#endif /* __LINUX_USB_RNDIS_HOST_H */
|
||||
@@ -0,0 +1,126 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#ifndef __LINUX_USB_ROLE_H
|
||||
#define __LINUX_USB_ROLE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
struct usb_role_switch;
|
||||
|
||||
enum usb_role {
|
||||
USB_ROLE_NONE,
|
||||
USB_ROLE_HOST,
|
||||
USB_ROLE_DEVICE,
|
||||
};
|
||||
|
||||
typedef int (*usb_role_switch_set_t)(struct usb_role_switch *sw,
|
||||
enum usb_role role);
|
||||
typedef enum usb_role (*usb_role_switch_get_t)(struct usb_role_switch *sw);
|
||||
|
||||
/**
|
||||
* struct usb_role_switch_desc - USB Role Switch Descriptor
|
||||
* @fwnode: The device node to be associated with the role switch
|
||||
* @usb2_port: Optional reference to the host controller port device (USB2)
|
||||
* @usb3_port: Optional reference to the host controller port device (USB3)
|
||||
* @udc: Optional reference to the peripheral controller device
|
||||
* @set: Callback for setting the role
|
||||
* @get: Callback for getting the role (optional)
|
||||
* @allow_userspace_control: If true userspace may change the role through sysfs
|
||||
* @driver_data: Private data pointer
|
||||
* @name: Name for the switch (optional)
|
||||
*
|
||||
* @usb2_port and @usb3_port will point to the USB host port and @udc to the USB
|
||||
* device controller behind the USB connector with the role switch. If
|
||||
* @usb2_port, @usb3_port and @udc are included in the description, the
|
||||
* reference count for them should be incremented by the caller of
|
||||
* usb_role_switch_register() before registering the switch.
|
||||
*/
|
||||
struct usb_role_switch_desc {
|
||||
struct fwnode_handle *fwnode;
|
||||
struct device *usb2_port;
|
||||
struct device *usb3_port;
|
||||
struct device *udc;
|
||||
usb_role_switch_set_t set;
|
||||
usb_role_switch_get_t get;
|
||||
bool allow_userspace_control;
|
||||
void *driver_data;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
|
||||
int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role);
|
||||
enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw);
|
||||
struct usb_role_switch *usb_role_switch_get(struct device *dev);
|
||||
struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *node);
|
||||
void usb_role_switch_put(struct usb_role_switch *sw);
|
||||
|
||||
struct usb_role_switch *
|
||||
usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode);
|
||||
|
||||
struct usb_role_switch *
|
||||
usb_role_switch_register(struct device *parent,
|
||||
const struct usb_role_switch_desc *desc);
|
||||
void usb_role_switch_unregister(struct usb_role_switch *sw);
|
||||
|
||||
void usb_role_switch_set_drvdata(struct usb_role_switch *sw, void *data);
|
||||
void *usb_role_switch_get_drvdata(struct usb_role_switch *sw);
|
||||
const char *usb_role_string(enum usb_role role);
|
||||
#else
|
||||
static inline int usb_role_switch_set_role(struct usb_role_switch *sw,
|
||||
enum usb_role role)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
|
||||
{
|
||||
return USB_ROLE_NONE;
|
||||
}
|
||||
|
||||
static inline struct usb_role_switch *usb_role_switch_get(struct device *dev)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline struct usb_role_switch *
|
||||
fwnode_usb_role_switch_get(struct fwnode_handle *node)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void usb_role_switch_put(struct usb_role_switch *sw) { }
|
||||
|
||||
static inline struct usb_role_switch *
|
||||
usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct usb_role_switch *
|
||||
usb_role_switch_register(struct device *parent,
|
||||
const struct usb_role_switch_desc *desc)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void usb_role_switch_unregister(struct usb_role_switch *sw) { }
|
||||
|
||||
static inline void
|
||||
usb_role_switch_set_drvdata(struct usb_role_switch *sw, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void *usb_role_switch_get_drvdata(struct usb_role_switch *sw)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline const char *usb_role_string(enum usb_role role)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_ROLE_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RZV2M_USB3DRD_H
|
||||
#define __RZV2M_USB3DRD_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct rzv2m_usb3drd {
|
||||
void __iomem *reg;
|
||||
int drd_irq;
|
||||
struct device *dev;
|
||||
struct reset_control *drd_rstc;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_RZV2M_USB3DRD)
|
||||
void rzv2m_usb3drd_reset(struct device *dev, bool host);
|
||||
#else
|
||||
static inline void rzv2m_usb3drd_reset(struct device *dev, bool host) { }
|
||||
#endif
|
||||
|
||||
#endif /* __RZV2M_USB3DRD_H */
|
||||
@@ -0,0 +1,438 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* USB Serial Converter stuff
|
||||
*
|
||||
* Copyright (C) 1999 - 2012
|
||||
* Greg Kroah-Hartman (greg@kroah.com)
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_SERIAL_H
|
||||
#define __LINUX_USB_SERIAL_H
|
||||
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
/* The maximum number of ports one device can grab at once */
|
||||
#define MAX_NUM_PORTS 16
|
||||
|
||||
/* USB serial flags */
|
||||
#define USB_SERIAL_WRITE_BUSY 0
|
||||
#define USB_SERIAL_THROTTLED 1
|
||||
|
||||
/**
|
||||
* usb_serial_port: structure for the specific ports of a device.
|
||||
* @serial: pointer back to the struct usb_serial owner of this port.
|
||||
* @port: pointer to the corresponding tty_port for this port.
|
||||
* @lock: spinlock to grab when updating portions of this structure.
|
||||
* @minor: the minor number of the port
|
||||
* @port_number: the struct usb_serial port number of this port (starts at 0)
|
||||
* @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
|
||||
* @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
|
||||
* @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
|
||||
* for this port.
|
||||
* @interrupt_out_buffer: pointer to the interrupt out buffer for this port.
|
||||
* @interrupt_out_size: the size of the interrupt_out_buffer, in bytes.
|
||||
* @interrupt_out_urb: pointer to the interrupt out struct urb for this port.
|
||||
* @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
|
||||
* for this port.
|
||||
* @bulk_in_buffer: pointer to the bulk in buffer for this port.
|
||||
* @bulk_in_size: the size of the bulk_in_buffer, in bytes.
|
||||
* @read_urb: pointer to the bulk in struct urb for this port.
|
||||
* @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
|
||||
* port.
|
||||
* @bulk_in_buffers: pointers to the bulk in buffers for this port
|
||||
* @read_urbs: pointers to the bulk in urbs for this port
|
||||
* @read_urbs_free: status bitmap the for bulk in urbs
|
||||
* @bulk_out_buffer: pointer to the bulk out buffer for this port.
|
||||
* @bulk_out_size: the size of the bulk_out_buffer, in bytes.
|
||||
* @write_urb: pointer to the bulk out struct urb for this port.
|
||||
* @write_fifo: kfifo used to buffer outgoing data
|
||||
* @bulk_out_buffers: pointers to the bulk out buffers for this port
|
||||
* @write_urbs: pointers to the bulk out urbs for this port
|
||||
* @write_urbs_free: status bitmap the for bulk out urbs
|
||||
* @icount: interrupt counters
|
||||
* @tx_bytes: number of bytes currently in host stack queues
|
||||
* @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
|
||||
* port.
|
||||
* @flags: usb serial port flags
|
||||
* @work: work queue entry for the line discipline waking up.
|
||||
* @dev: pointer to the serial device
|
||||
*
|
||||
* This structure is used by the usb-serial core and drivers for the specific
|
||||
* ports of a device.
|
||||
*/
|
||||
struct usb_serial_port {
|
||||
struct usb_serial *serial;
|
||||
struct tty_port port;
|
||||
spinlock_t lock;
|
||||
u32 minor;
|
||||
u8 port_number;
|
||||
|
||||
unsigned char *interrupt_in_buffer;
|
||||
struct urb *interrupt_in_urb;
|
||||
__u8 interrupt_in_endpointAddress;
|
||||
|
||||
unsigned char *interrupt_out_buffer;
|
||||
int interrupt_out_size;
|
||||
struct urb *interrupt_out_urb;
|
||||
__u8 interrupt_out_endpointAddress;
|
||||
|
||||
unsigned char *bulk_in_buffer;
|
||||
int bulk_in_size;
|
||||
struct urb *read_urb;
|
||||
__u8 bulk_in_endpointAddress;
|
||||
|
||||
unsigned char *bulk_in_buffers[2];
|
||||
struct urb *read_urbs[2];
|
||||
unsigned long read_urbs_free;
|
||||
|
||||
unsigned char *bulk_out_buffer;
|
||||
int bulk_out_size;
|
||||
struct urb *write_urb;
|
||||
struct kfifo write_fifo;
|
||||
|
||||
unsigned char *bulk_out_buffers[2];
|
||||
struct urb *write_urbs[2];
|
||||
unsigned long write_urbs_free;
|
||||
__u8 bulk_out_endpointAddress;
|
||||
|
||||
struct async_icount icount;
|
||||
int tx_bytes;
|
||||
|
||||
unsigned long flags;
|
||||
struct work_struct work;
|
||||
unsigned long sysrq; /* sysrq timeout */
|
||||
struct device dev;
|
||||
};
|
||||
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
|
||||
|
||||
/* get and set the port private data pointer helper functions */
|
||||
static inline void *usb_get_serial_port_data(struct usb_serial_port *port)
|
||||
{
|
||||
return dev_get_drvdata(&port->dev);
|
||||
}
|
||||
|
||||
static inline void usb_set_serial_port_data(struct usb_serial_port *port,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(&port->dev, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_serial - structure used by the usb-serial core for a device
|
||||
* @dev: pointer to the struct usb_device for this device
|
||||
* @type: pointer to the struct usb_serial_driver for this device
|
||||
* @interface: pointer to the struct usb_interface for this device
|
||||
* @sibling: pointer to the struct usb_interface of any sibling interface
|
||||
* @suspend_count: number of suspended (sibling) interfaces
|
||||
* @num_ports: the number of ports this device has
|
||||
* @num_interrupt_in: number of interrupt in endpoints we have
|
||||
* @num_interrupt_out: number of interrupt out endpoints we have
|
||||
* @num_bulk_in: number of bulk in endpoints we have
|
||||
* @num_bulk_out: number of bulk out endpoints we have
|
||||
* @port: array of struct usb_serial_port structures for the different ports.
|
||||
* @private: place to put any driver specific information that is needed. The
|
||||
* usb-serial driver is required to manage this data, the usb-serial core
|
||||
* will not touch this. Use usb_get_serial_data() and
|
||||
* usb_set_serial_data() to access this.
|
||||
*/
|
||||
struct usb_serial {
|
||||
struct usb_device *dev;
|
||||
struct usb_serial_driver *type;
|
||||
struct usb_interface *interface;
|
||||
struct usb_interface *sibling;
|
||||
unsigned int suspend_count;
|
||||
unsigned char disconnected:1;
|
||||
unsigned char attached:1;
|
||||
unsigned char minors_reserved:1;
|
||||
unsigned char num_ports;
|
||||
unsigned char num_port_pointers;
|
||||
unsigned char num_interrupt_in;
|
||||
unsigned char num_interrupt_out;
|
||||
unsigned char num_bulk_in;
|
||||
unsigned char num_bulk_out;
|
||||
struct usb_serial_port *port[MAX_NUM_PORTS];
|
||||
struct kref kref;
|
||||
struct mutex disc_mutex;
|
||||
void *private;
|
||||
};
|
||||
#define to_usb_serial(d) container_of(d, struct usb_serial, kref)
|
||||
|
||||
/* get and set the serial private data pointer helper functions */
|
||||
static inline void *usb_get_serial_data(struct usb_serial *serial)
|
||||
{
|
||||
return serial->private;
|
||||
}
|
||||
|
||||
static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
|
||||
{
|
||||
serial->private = data;
|
||||
}
|
||||
|
||||
struct usb_serial_endpoints {
|
||||
unsigned char num_bulk_in;
|
||||
unsigned char num_bulk_out;
|
||||
unsigned char num_interrupt_in;
|
||||
unsigned char num_interrupt_out;
|
||||
struct usb_endpoint_descriptor *bulk_in[MAX_NUM_PORTS];
|
||||
struct usb_endpoint_descriptor *bulk_out[MAX_NUM_PORTS];
|
||||
struct usb_endpoint_descriptor *interrupt_in[MAX_NUM_PORTS];
|
||||
struct usb_endpoint_descriptor *interrupt_out[MAX_NUM_PORTS];
|
||||
};
|
||||
|
||||
/**
|
||||
* usb_serial_driver - describes a usb serial driver
|
||||
* @description: pointer to a string that describes this driver. This string
|
||||
* used in the syslog messages when a device is inserted or removed.
|
||||
* @id_table: pointer to a list of usb_device_id structures that define all
|
||||
* of the devices this structure can support.
|
||||
* @num_ports: the number of different ports this device will have.
|
||||
* @num_bulk_in: minimum number of bulk-in endpoints
|
||||
* @num_bulk_out: minimum number of bulk-out endpoints
|
||||
* @num_interrupt_in: minimum number of interrupt-in endpoints
|
||||
* @num_interrupt_out: minimum number of interrupt-out endpoints
|
||||
* @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer
|
||||
* (0 = end-point size)
|
||||
* @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size)
|
||||
* @calc_num_ports: pointer to a function to determine how many ports this
|
||||
* device has dynamically. It can also be used to verify the number of
|
||||
* endpoints or to modify the port-endpoint mapping. It will be called
|
||||
* after the probe() callback is called, but before attach().
|
||||
* @probe: pointer to the driver's probe function.
|
||||
* This will be called when the device is inserted into the system,
|
||||
* but before the device has been fully initialized by the usb_serial
|
||||
* subsystem. Use this function to download any firmware to the device,
|
||||
* or any other early initialization that might be needed.
|
||||
* Return 0 to continue on with the initialization sequence. Anything
|
||||
* else will abort it.
|
||||
* @attach: pointer to the driver's attach function.
|
||||
* This will be called when the struct usb_serial structure is fully
|
||||
* set up. Do any local initialization of the device, or any private
|
||||
* memory structure allocation at this point in time.
|
||||
* @disconnect: pointer to the driver's disconnect function. This will be
|
||||
* called when the device is unplugged or unbound from the driver.
|
||||
* @release: pointer to the driver's release function. This will be called
|
||||
* when the usb_serial data structure is about to be destroyed.
|
||||
* @usb_driver: pointer to the struct usb_driver that controls this
|
||||
* device. This is necessary to allow dynamic ids to be added to
|
||||
* the driver from sysfs.
|
||||
*
|
||||
* This structure is defines a USB Serial driver. It provides all of
|
||||
* the information that the USB serial core code needs. If the function
|
||||
* pointers are defined, then the USB serial core code will call them when
|
||||
* the corresponding tty port functions are called. If they are not
|
||||
* called, the generic serial function will be used instead.
|
||||
*
|
||||
* The driver.owner field should be set to the module owner of this driver.
|
||||
* The driver.name field should be set to the name of this driver (remember
|
||||
* it will show up in sysfs, so it needs to be short and to the point.
|
||||
* Using the module name is a good idea.)
|
||||
*/
|
||||
struct usb_serial_driver {
|
||||
const char *description;
|
||||
const struct usb_device_id *id_table;
|
||||
|
||||
struct list_head driver_list;
|
||||
struct device_driver driver;
|
||||
struct usb_driver *usb_driver;
|
||||
struct usb_dynids dynids;
|
||||
|
||||
unsigned char num_ports;
|
||||
|
||||
unsigned char num_bulk_in;
|
||||
unsigned char num_bulk_out;
|
||||
unsigned char num_interrupt_in;
|
||||
unsigned char num_interrupt_out;
|
||||
|
||||
size_t bulk_in_size;
|
||||
size_t bulk_out_size;
|
||||
|
||||
int (*probe)(struct usb_serial *serial, const struct usb_device_id *id);
|
||||
int (*attach)(struct usb_serial *serial);
|
||||
int (*calc_num_ports)(struct usb_serial *serial,
|
||||
struct usb_serial_endpoints *epds);
|
||||
|
||||
void (*disconnect)(struct usb_serial *serial);
|
||||
void (*release)(struct usb_serial *serial);
|
||||
|
||||
int (*port_probe)(struct usb_serial_port *port);
|
||||
void (*port_remove)(struct usb_serial_port *port);
|
||||
|
||||
int (*suspend)(struct usb_serial *serial, pm_message_t message);
|
||||
int (*resume)(struct usb_serial *serial);
|
||||
int (*reset_resume)(struct usb_serial *serial);
|
||||
|
||||
/* serial function calls */
|
||||
/* Called by console and by the tty layer */
|
||||
int (*open)(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
void (*close)(struct usb_serial_port *port);
|
||||
int (*write)(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count);
|
||||
/* Called only by the tty layer */
|
||||
unsigned int (*write_room)(struct tty_struct *tty);
|
||||
int (*ioctl)(struct tty_struct *tty,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
void (*get_serial)(struct tty_struct *tty, struct serial_struct *ss);
|
||||
int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss);
|
||||
void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
const struct ktermios *old);
|
||||
int (*break_ctl)(struct tty_struct *tty, int break_state);
|
||||
unsigned int (*chars_in_buffer)(struct tty_struct *tty);
|
||||
void (*wait_until_sent)(struct tty_struct *tty, long timeout);
|
||||
bool (*tx_empty)(struct usb_serial_port *port);
|
||||
void (*throttle)(struct tty_struct *tty);
|
||||
void (*unthrottle)(struct tty_struct *tty);
|
||||
int (*tiocmget)(struct tty_struct *tty);
|
||||
int (*tiocmset)(struct tty_struct *tty,
|
||||
unsigned int set, unsigned int clear);
|
||||
int (*tiocmiwait)(struct tty_struct *tty, unsigned long arg);
|
||||
int (*get_icount)(struct tty_struct *tty,
|
||||
struct serial_icounter_struct *icount);
|
||||
/* Called by the tty layer for port level work. There may or may not
|
||||
be an attached tty at this point */
|
||||
void (*dtr_rts)(struct usb_serial_port *port, int on);
|
||||
int (*carrier_raised)(struct usb_serial_port *port);
|
||||
/* Called by the usb serial hooks to allow the user to rework the
|
||||
termios state */
|
||||
void (*init_termios)(struct tty_struct *tty);
|
||||
/* USB events */
|
||||
void (*read_int_callback)(struct urb *urb);
|
||||
void (*write_int_callback)(struct urb *urb);
|
||||
void (*read_bulk_callback)(struct urb *urb);
|
||||
void (*write_bulk_callback)(struct urb *urb);
|
||||
/* Called by the generic read bulk callback */
|
||||
void (*process_read_urb)(struct urb *urb);
|
||||
/* Called by the generic write implementation */
|
||||
int (*prepare_write_buffer)(struct usb_serial_port *port,
|
||||
void *dest, size_t size);
|
||||
};
|
||||
#define to_usb_serial_driver(d) \
|
||||
container_of(d, struct usb_serial_driver, driver)
|
||||
|
||||
#define usb_serial_register_drivers(serial_drivers, name, id_table) \
|
||||
__usb_serial_register_drivers(serial_drivers, THIS_MODULE, name, id_table)
|
||||
int __usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
|
||||
struct module *owner, const char *name,
|
||||
const struct usb_device_id *id_table);
|
||||
void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]);
|
||||
void usb_serial_port_softint(struct usb_serial_port *port);
|
||||
|
||||
int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
|
||||
int usb_serial_resume(struct usb_interface *intf);
|
||||
|
||||
/* USB Serial console functions */
|
||||
#ifdef CONFIG_USB_SERIAL_CONSOLE
|
||||
void usb_serial_console_init(int minor);
|
||||
void usb_serial_console_exit(void);
|
||||
void usb_serial_console_disconnect(struct usb_serial *serial);
|
||||
#else
|
||||
static inline void usb_serial_console_init(int minor) { }
|
||||
static inline void usb_serial_console_exit(void) { }
|
||||
static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
|
||||
#endif
|
||||
|
||||
/* Functions needed by other parts of the usbserial core */
|
||||
struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor);
|
||||
void usb_serial_put(struct usb_serial *serial);
|
||||
|
||||
int usb_serial_claim_interface(struct usb_serial *serial, struct usb_interface *intf);
|
||||
|
||||
int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
int usb_serial_generic_write_start(struct usb_serial_port *port, gfp_t mem_flags);
|
||||
int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count);
|
||||
void usb_serial_generic_close(struct usb_serial_port *port);
|
||||
int usb_serial_generic_resume(struct usb_serial *serial);
|
||||
unsigned int usb_serial_generic_write_room(struct tty_struct *tty);
|
||||
unsigned int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
|
||||
void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout);
|
||||
void usb_serial_generic_read_bulk_callback(struct urb *urb);
|
||||
void usb_serial_generic_write_bulk_callback(struct urb *urb);
|
||||
void usb_serial_generic_throttle(struct tty_struct *tty);
|
||||
void usb_serial_generic_unthrottle(struct tty_struct *tty);
|
||||
int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg);
|
||||
int usb_serial_generic_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount);
|
||||
int usb_serial_generic_register(void);
|
||||
void usb_serial_generic_deregister(void);
|
||||
int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, gfp_t mem_flags);
|
||||
void usb_serial_generic_process_read_urb(struct urb *urb);
|
||||
int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, void *dest, size_t size);
|
||||
|
||||
#if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch);
|
||||
int usb_serial_handle_break(struct usb_serial_port *port);
|
||||
#else
|
||||
static inline int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int usb_serial_handle_break(struct usb_serial_port *port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
|
||||
struct tty_struct *tty, unsigned int status);
|
||||
|
||||
|
||||
int usb_serial_bus_register(struct usb_serial_driver *device);
|
||||
void usb_serial_bus_deregister(struct usb_serial_driver *device);
|
||||
|
||||
extern const struct bus_type usb_serial_bus_type;
|
||||
extern struct tty_driver *usb_serial_tty_driver;
|
||||
|
||||
static inline void usb_serial_debug_data(struct device *dev,
|
||||
const char *function, int size,
|
||||
const unsigned char *data)
|
||||
{
|
||||
dev_dbg(dev, "%s - length = %d, data = %*ph\n",
|
||||
function, size, size, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro for reporting errors in write path to avoid infinite loop
|
||||
* when port is used as a console.
|
||||
*/
|
||||
#define dev_err_console(usport, fmt, ...) \
|
||||
do { \
|
||||
static bool __print_once; \
|
||||
struct usb_serial_port *__port = (usport); \
|
||||
\
|
||||
if (!__port->port.console || !__print_once) { \
|
||||
__print_once = true; \
|
||||
dev_err(&__port->dev, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* module_usb_serial_driver() - Helper macro for registering a USB Serial driver
|
||||
* @__serial_drivers: list of usb_serial drivers to register
|
||||
* @__ids: all device ids that @__serial_drivers bind to
|
||||
*
|
||||
* Helper macro for USB serial drivers which do not do anything special
|
||||
* in module init/exit. This eliminates a lot of boilerplate. Each
|
||||
* module may only use this macro once, and calling it replaces
|
||||
* module_init() and module_exit()
|
||||
*
|
||||
*/
|
||||
#define usb_serial_module_driver(__name, __serial_drivers, __ids) \
|
||||
static int __init usb_serial_module_init(void) \
|
||||
{ \
|
||||
return usb_serial_register_drivers(__serial_drivers, \
|
||||
__name, __ids); \
|
||||
} \
|
||||
module_init(usb_serial_module_init); \
|
||||
static void __exit usb_serial_module_exit(void) \
|
||||
{ \
|
||||
usb_serial_deregister_drivers(__serial_drivers); \
|
||||
} \
|
||||
module_exit(usb_serial_module_exit);
|
||||
|
||||
#define module_usb_serial_driver(__serial_drivers, __ids) \
|
||||
usb_serial_module_driver(KBUILD_MODNAME, __serial_drivers, __ids)
|
||||
|
||||
#endif /* __LINUX_USB_SERIAL_H */
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* board initialization should put one of these into dev->platform_data
|
||||
* and place the sl811hs onto platform_bus named "sl811-hcd".
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_SL811_H
|
||||
#define __LINUX_USB_SL811_H
|
||||
|
||||
struct sl811_platform_data {
|
||||
unsigned can_wakeup:1;
|
||||
|
||||
/* given port_power, msec/2 after power on till power good */
|
||||
u8 potpg;
|
||||
|
||||
/* mA/2 power supplied on this port (max = default = 250) */
|
||||
u8 power;
|
||||
|
||||
/* sl811 relies on an external source of VBUS current */
|
||||
void (*port_power)(struct device *dev, int is_on);
|
||||
|
||||
/* pulse sl811 nRST (probably with a GPIO) */
|
||||
void (*reset)(struct device *dev);
|
||||
|
||||
/* some boards need something like these: */
|
||||
/* int (*check_overcurrent)(struct device *dev); */
|
||||
/* void (*clock_enable)(struct device *dev, int is_on); */
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_SL811_H */
|
||||
@@ -0,0 +1,93 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef __LINUX_USB_STORAGE_H
|
||||
#define __LINUX_USB_STORAGE_H
|
||||
|
||||
/*
|
||||
* linux/usb/storage.h
|
||||
*
|
||||
* Copyright Matthew Wilcox for Intel Corp, 2010
|
||||
*
|
||||
* This file contains definitions taken from the
|
||||
* USB Mass Storage Class Specification Overview
|
||||
*/
|
||||
|
||||
/* Storage subclass codes */
|
||||
|
||||
#define USB_SC_RBC 0x01 /* Typically, flash devices */
|
||||
#define USB_SC_8020 0x02 /* CD-ROM */
|
||||
#define USB_SC_QIC 0x03 /* QIC-157 Tapes */
|
||||
#define USB_SC_UFI 0x04 /* Floppy */
|
||||
#define USB_SC_8070 0x05 /* Removable media */
|
||||
#define USB_SC_SCSI 0x06 /* Transparent */
|
||||
#define USB_SC_LOCKABLE 0x07 /* Password-protected */
|
||||
|
||||
#define USB_SC_ISD200 0xf0 /* ISD200 ATA */
|
||||
#define USB_SC_CYP_ATACB 0xf1 /* Cypress ATACB */
|
||||
#define USB_SC_DEVICE 0xff /* Use device's value */
|
||||
|
||||
/* Storage protocol codes */
|
||||
|
||||
#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */
|
||||
#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */
|
||||
#define USB_PR_BULK 0x50 /* bulk only */
|
||||
#define USB_PR_UAS 0x62 /* USB Attached SCSI */
|
||||
|
||||
#define USB_PR_USBAT 0x80 /* SCM-ATAPI bridge */
|
||||
#define USB_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
|
||||
#define USB_PR_SDDR55 0x82 /* SDDR-55 (made up) */
|
||||
#define USB_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
|
||||
#define USB_PR_FREECOM 0xf1 /* Freecom */
|
||||
#define USB_PR_DATAFAB 0xf2 /* Datafab chipsets */
|
||||
#define USB_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
|
||||
#define USB_PR_ALAUDA 0xf4 /* Alauda chipsets */
|
||||
#define USB_PR_KARMA 0xf5 /* Rio Karma */
|
||||
|
||||
#define USB_PR_DEVICE 0xff /* Use device's value */
|
||||
|
||||
/*
|
||||
* Bulk only data structures
|
||||
*/
|
||||
|
||||
/* command block wrapper */
|
||||
struct bulk_cb_wrap {
|
||||
__le32 Signature; /* contains 'USBC' */
|
||||
__u32 Tag; /* unique per command id */
|
||||
__le32 DataTransferLength; /* size of data */
|
||||
__u8 Flags; /* direction in bit 7 */
|
||||
__u8 Lun; /* LUN normally 0 */
|
||||
__u8 Length; /* length of the CDB */
|
||||
__u8 CDB[16]; /* max command */
|
||||
};
|
||||
|
||||
#define US_BULK_CB_WRAP_LEN 31
|
||||
#define US_BULK_CB_SIGN 0x43425355 /* spells out 'USBC' */
|
||||
#define US_BULK_FLAG_IN (1 << 7)
|
||||
#define US_BULK_FLAG_OUT 0
|
||||
|
||||
/* command status wrapper */
|
||||
struct bulk_cs_wrap {
|
||||
__le32 Signature; /* contains 'USBS' */
|
||||
__u32 Tag; /* same as original command */
|
||||
__le32 Residue; /* amount not transferred */
|
||||
__u8 Status; /* see below */
|
||||
};
|
||||
|
||||
#define US_BULK_CS_WRAP_LEN 13
|
||||
#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */
|
||||
#define US_BULK_STAT_OK 0
|
||||
#define US_BULK_STAT_FAIL 1
|
||||
#define US_BULK_STAT_PHASE 2
|
||||
|
||||
/* bulk-only class specific requests */
|
||||
#define US_BULK_RESET_REQUEST 0xff
|
||||
#define US_BULK_GET_MAX_LUN 0xfe
|
||||
|
||||
/*
|
||||
* If 4 LUNs are supported then the LUNs would be
|
||||
* numbered from 0 to 3, and the return value for
|
||||
* US_BULK_GET_MAX_LUN request would be 3. The valid
|
||||
* LUN field is 4 bits wide, the upper limit is 0x0f.
|
||||
*/
|
||||
#define US_BULK_MAX_LUN_LIMIT 0x0f
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,255 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2015-2017 Google, Inc
|
||||
*
|
||||
* USB Type-C Port Controller Interface.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_TCPCI_H
|
||||
#define __LINUX_USB_TCPCI_H
|
||||
|
||||
#include <linux/usb/typec.h>
|
||||
#include <linux/usb/tcpm.h>
|
||||
|
||||
#define TCPC_VENDOR_ID 0x0
|
||||
#define TCPC_PRODUCT_ID 0x2
|
||||
#define TCPC_BCD_DEV 0x4
|
||||
#define TCPC_TC_REV 0x6
|
||||
#define TCPC_PD_REV 0x8
|
||||
#define TCPC_PD_INT_REV 0xa
|
||||
|
||||
#define TCPC_ALERT 0x10
|
||||
#define TCPC_ALERT_EXTND BIT(14)
|
||||
#define TCPC_ALERT_EXTENDED_STATUS BIT(13)
|
||||
#define TCPC_ALERT_VBUS_DISCNCT BIT(11)
|
||||
#define TCPC_ALERT_RX_BUF_OVF BIT(10)
|
||||
#define TCPC_ALERT_FAULT BIT(9)
|
||||
#define TCPC_ALERT_V_ALARM_LO BIT(8)
|
||||
#define TCPC_ALERT_V_ALARM_HI BIT(7)
|
||||
#define TCPC_ALERT_TX_SUCCESS BIT(6)
|
||||
#define TCPC_ALERT_TX_DISCARDED BIT(5)
|
||||
#define TCPC_ALERT_TX_FAILED BIT(4)
|
||||
#define TCPC_ALERT_RX_HARD_RST BIT(3)
|
||||
#define TCPC_ALERT_RX_STATUS BIT(2)
|
||||
#define TCPC_ALERT_POWER_STATUS BIT(1)
|
||||
#define TCPC_ALERT_CC_STATUS BIT(0)
|
||||
|
||||
#define TCPC_ALERT_MASK 0x12
|
||||
#define TCPC_POWER_STATUS_MASK 0x14
|
||||
|
||||
#define TCPC_FAULT_STATUS_MASK 0x15
|
||||
#define TCPC_FAULT_STATUS_MASK_VCONN_OC BIT(1)
|
||||
|
||||
#define TCPC_EXTENDED_STATUS_MASK 0x16
|
||||
#define TCPC_EXTENDED_STATUS_MASK_VSAFE0V BIT(0)
|
||||
|
||||
#define TCPC_ALERT_EXTENDED_MASK 0x17
|
||||
#define TCPC_SINK_FAST_ROLE_SWAP BIT(0)
|
||||
|
||||
#define TCPC_CONFIG_STD_OUTPUT 0x18
|
||||
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_MASK BIT(0)
|
||||
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_NORMAL 0
|
||||
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_FLIPPED 1
|
||||
|
||||
#define TCPC_TCPC_CTRL 0x19
|
||||
#define TCPC_TCPC_CTRL_ORIENTATION BIT(0)
|
||||
#define PLUG_ORNT_CC1 0
|
||||
#define PLUG_ORNT_CC2 1
|
||||
#define TCPC_TCPC_CTRL_BIST_TM BIT(1)
|
||||
#define TCPC_TCPC_CTRL_EN_LK4CONN_ALRT BIT(6)
|
||||
|
||||
#define TCPC_EXTENDED_STATUS 0x20
|
||||
#define TCPC_EXTENDED_STATUS_VSAFE0V BIT(0)
|
||||
|
||||
#define TCPC_ROLE_CTRL 0x1a
|
||||
#define TCPC_ROLE_CTRL_DRP BIT(6)
|
||||
#define TCPC_ROLE_CTRL_RP_VAL GENMASK(5, 4)
|
||||
#define TCPC_ROLE_CTRL_RP_VAL_DEF 0x0
|
||||
#define TCPC_ROLE_CTRL_RP_VAL_1_5 0x1
|
||||
#define TCPC_ROLE_CTRL_RP_VAL_3_0 0x2
|
||||
#define TCPC_ROLE_CTRL_CC2 GENMASK(3, 2)
|
||||
#define TCPC_ROLE_CTRL_CC1 GENMASK(1, 0)
|
||||
#define TCPC_ROLE_CTRL_CC_RA 0x0
|
||||
#define TCPC_ROLE_CTRL_CC_RP 0x1
|
||||
#define TCPC_ROLE_CTRL_CC_RD 0x2
|
||||
#define TCPC_ROLE_CTRL_CC_OPEN 0x3
|
||||
|
||||
#define TCPC_FAULT_CTRL 0x1b
|
||||
|
||||
#define TCPC_POWER_CTRL 0x1c
|
||||
#define TCPC_POWER_CTRL_VCONN_ENABLE BIT(0)
|
||||
#define TCPC_POWER_CTRL_BLEED_DISCHARGE BIT(3)
|
||||
#define TCPC_POWER_CTRL_AUTO_DISCHARGE BIT(4)
|
||||
#define TCPC_DIS_VOLT_ALRM BIT(5)
|
||||
#define TCPC_POWER_CTRL_VBUS_VOLT_MON BIT(6)
|
||||
#define TCPC_FAST_ROLE_SWAP_EN BIT(7)
|
||||
|
||||
#define TCPC_CC_STATUS 0x1d
|
||||
#define TCPC_CC_STATUS_TOGGLING BIT(5)
|
||||
#define TCPC_CC_STATUS_TERM BIT(4)
|
||||
#define TCPC_CC_STATUS_TERM_RP 0
|
||||
#define TCPC_CC_STATUS_TERM_RD 1
|
||||
#define TCPC_CC_STATUS_CC2 GENMASK(3, 2)
|
||||
#define TCPC_CC_STATUS_CC1 GENMASK(1, 0)
|
||||
#define TCPC_CC_STATE_SRC_OPEN 0
|
||||
|
||||
#define TCPC_POWER_STATUS 0x1e
|
||||
#define TCPC_POWER_STATUS_DBG_ACC_CON BIT(7)
|
||||
#define TCPC_POWER_STATUS_UNINIT BIT(6)
|
||||
#define TCPC_POWER_STATUS_SOURCING_VBUS BIT(4)
|
||||
#define TCPC_POWER_STATUS_VBUS_DET BIT(3)
|
||||
#define TCPC_POWER_STATUS_VBUS_PRES BIT(2)
|
||||
#define TCPC_POWER_STATUS_VCONN_PRES BIT(1)
|
||||
#define TCPC_POWER_STATUS_SINKING_VBUS BIT(0)
|
||||
|
||||
#define TCPC_FAULT_STATUS 0x1f
|
||||
#define TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT BIT(7)
|
||||
#define TCPC_FAULT_STATUS_VCONN_OC BIT(1)
|
||||
|
||||
#define TCPC_ALERT_EXTENDED 0x21
|
||||
|
||||
#define TCPC_COMMAND 0x23
|
||||
#define TCPC_CMD_WAKE_I2C 0x11
|
||||
#define TCPC_CMD_DISABLE_VBUS_DETECT 0x22
|
||||
#define TCPC_CMD_ENABLE_VBUS_DETECT 0x33
|
||||
#define TCPC_CMD_DISABLE_SINK_VBUS 0x44
|
||||
#define TCPC_CMD_SINK_VBUS 0x55
|
||||
#define TCPC_CMD_DISABLE_SRC_VBUS 0x66
|
||||
#define TCPC_CMD_SRC_VBUS_DEFAULT 0x77
|
||||
#define TCPC_CMD_SRC_VBUS_HIGH 0x88
|
||||
#define TCPC_CMD_LOOK4CONNECTION 0x99
|
||||
#define TCPC_CMD_RXONEMORE 0xAA
|
||||
#define TCPC_CMD_I2C_IDLE 0xFF
|
||||
|
||||
#define TCPC_DEV_CAP_1 0x24
|
||||
#define TCPC_DEV_CAP_2 0x26
|
||||
#define TCPC_STD_INPUT_CAP 0x28
|
||||
#define TCPC_STD_OUTPUT_CAP 0x29
|
||||
#define TCPC_STD_OUTPUT_CAP_ORIENTATION BIT(0)
|
||||
|
||||
#define TCPC_MSG_HDR_INFO 0x2e
|
||||
#define TCPC_MSG_HDR_INFO_DATA_ROLE BIT(3)
|
||||
#define TCPC_MSG_HDR_INFO_REV GENMASK(2, 1)
|
||||
#define TCPC_MSG_HDR_INFO_PWR_ROLE BIT(0)
|
||||
|
||||
#define TCPC_RX_DETECT 0x2f
|
||||
#define TCPC_RX_DETECT_HARD_RESET BIT(5)
|
||||
#define TCPC_RX_DETECT_SOP BIT(0)
|
||||
#define TCPC_RX_DETECT_SOP1 BIT(1)
|
||||
#define TCPC_RX_DETECT_SOP2 BIT(2)
|
||||
#define TCPC_RX_DETECT_DBG1 BIT(3)
|
||||
#define TCPC_RX_DETECT_DBG2 BIT(4)
|
||||
|
||||
#define TCPC_RX_BYTE_CNT 0x30
|
||||
#define TCPC_RX_BUF_FRAME_TYPE 0x31
|
||||
#define TCPC_RX_BUF_FRAME_TYPE_SOP 0
|
||||
#define TCPC_RX_BUF_FRAME_TYPE_SOP1 1
|
||||
#define TCPC_RX_HDR 0x32
|
||||
#define TCPC_RX_DATA 0x34 /* through 0x4f */
|
||||
|
||||
#define TCPC_TRANSMIT 0x50
|
||||
#define TCPC_TRANSMIT_RETRY GENMASK(5, 4)
|
||||
#define TCPC_TRANSMIT_TYPE GENMASK(2, 0)
|
||||
|
||||
#define TCPC_TX_BYTE_CNT 0x51
|
||||
#define TCPC_TX_HDR 0x52
|
||||
#define TCPC_TX_DATA 0x54 /* through 0x6f */
|
||||
|
||||
#define TCPC_VBUS_VOLTAGE 0x70
|
||||
#define TCPC_VBUS_VOLTAGE_MASK 0x3ff
|
||||
#define TCPC_VBUS_VOLTAGE_LSB_MV 25
|
||||
#define TCPC_VBUS_SINK_DISCONNECT_THRESH 0x72
|
||||
#define TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB_MV 25
|
||||
#define TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX 0x3ff
|
||||
#define TCPC_VBUS_STOP_DISCHARGE_THRESH 0x74
|
||||
#define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG 0x76
|
||||
#define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG 0x78
|
||||
|
||||
/* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */
|
||||
#define TCPC_TRANSMIT_BUFFER_MAX_LEN 31
|
||||
|
||||
#define tcpc_presenting_rd(reg, cc) \
|
||||
(!(TCPC_ROLE_CTRL_DRP & (reg)) && \
|
||||
FIELD_GET(TCPC_ROLE_CTRL_## cc, reg) == TCPC_ROLE_CTRL_CC_RD)
|
||||
|
||||
struct tcpci;
|
||||
|
||||
/*
|
||||
* @TX_BUF_BYTE_x_hidden:
|
||||
* optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT.
|
||||
* @frs_sourcing_vbus:
|
||||
* Optional; Callback to perform chip specific operations when FRS
|
||||
* is sourcing vbus.
|
||||
* @auto_discharge_disconnect:
|
||||
* Optional; Enables TCPC to autonomously discharge vbus on disconnect.
|
||||
* @vbus_vsafe0v:
|
||||
* optional; Set when TCPC can detect whether vbus is at VSAFE0V.
|
||||
* @set_partner_usb_comm_capable:
|
||||
* Optional; The USB Communications Capable bit indicates if port
|
||||
* partner is capable of communication over the USB data lines
|
||||
* (e.g. D+/- or SS Tx/Rx). Called to notify the status of the bit.
|
||||
* @check_contaminant:
|
||||
* Optional; The callback is invoked when chiplevel drivers indicated
|
||||
* that the USB port needs to be checked for contaminant presence.
|
||||
* Chip level drivers are expected to check for contaminant and call
|
||||
* tcpm_clean_port when the port is clean to put the port back into
|
||||
* toggling state.
|
||||
* @cable_comm_capable
|
||||
* optional; Set when TCPC can communicate with cable plugs over SOP'
|
||||
* @attempt_vconn_swap_discovery:
|
||||
* Optional; The callback is called by the TCPM when the result of
|
||||
* a Discover Identity request indicates that the port partner is
|
||||
* a receptacle capable of modal operation. Chip level TCPCI drivers
|
||||
* can implement their own policy to determine if and when a Vconn
|
||||
* swap following Discover Identity on SOP' occurs.
|
||||
* Return true when the TCPM is allowed to request a Vconn swap
|
||||
* after Discovery Identity on SOP.
|
||||
* @set_orientation:
|
||||
* Optional; Enable setting the connector orientation
|
||||
* CONFIG_STANDARD_OUTPUT (0x18) bit0.
|
||||
*/
|
||||
struct tcpci_data {
|
||||
struct regmap *regmap;
|
||||
unsigned char TX_BUF_BYTE_x_hidden:1;
|
||||
unsigned char auto_discharge_disconnect:1;
|
||||
unsigned char vbus_vsafe0v:1;
|
||||
unsigned char cable_comm_capable:1;
|
||||
unsigned char set_orientation:1;
|
||||
|
||||
int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
|
||||
int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
|
||||
bool enable);
|
||||
int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data,
|
||||
enum typec_cc_status cc);
|
||||
int (*set_vbus)(struct tcpci *tcpci, struct tcpci_data *data, bool source, bool sink);
|
||||
void (*frs_sourcing_vbus)(struct tcpci *tcpci, struct tcpci_data *data);
|
||||
void (*set_partner_usb_comm_capable)(struct tcpci *tcpci, struct tcpci_data *data,
|
||||
bool capable);
|
||||
void (*check_contaminant)(struct tcpci *tcpci, struct tcpci_data *data);
|
||||
bool (*attempt_vconn_swap_discovery)(struct tcpci *tcpci, struct tcpci_data *data);
|
||||
};
|
||||
|
||||
struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);
|
||||
void tcpci_unregister_port(struct tcpci *tcpci);
|
||||
irqreturn_t tcpci_irq(struct tcpci *tcpci);
|
||||
|
||||
struct tcpm_port;
|
||||
struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci);
|
||||
|
||||
static inline enum typec_cc_status tcpci_to_typec_cc(unsigned int cc, bool sink)
|
||||
{
|
||||
switch (cc) {
|
||||
case 0x1:
|
||||
return sink ? TYPEC_CC_RP_DEF : TYPEC_CC_RA;
|
||||
case 0x2:
|
||||
return sink ? TYPEC_CC_RP_1_5 : TYPEC_CC_RD;
|
||||
case 0x3:
|
||||
if (sink)
|
||||
return TYPEC_CC_RP_3_0;
|
||||
fallthrough;
|
||||
case TCPC_CC_STATE_SRC_OPEN:
|
||||
default:
|
||||
return TYPEC_CC_OPEN;
|
||||
}
|
||||
}
|
||||
#endif /* __LINUX_USB_TCPCI_H */
|
||||
@@ -0,0 +1,195 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright 2015-2017 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_TCPM_H
|
||||
#define __LINUX_USB_TCPM_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/usb/typec.h>
|
||||
#include "pd.h"
|
||||
|
||||
enum typec_cc_status {
|
||||
TYPEC_CC_OPEN,
|
||||
TYPEC_CC_RA,
|
||||
TYPEC_CC_RD,
|
||||
TYPEC_CC_RP_DEF,
|
||||
TYPEC_CC_RP_1_5,
|
||||
TYPEC_CC_RP_3_0,
|
||||
};
|
||||
|
||||
/* Collision Avoidance */
|
||||
#define SINK_TX_NG TYPEC_CC_RP_1_5
|
||||
#define SINK_TX_OK TYPEC_CC_RP_3_0
|
||||
|
||||
enum typec_cc_polarity {
|
||||
TYPEC_POLARITY_CC1,
|
||||
TYPEC_POLARITY_CC2,
|
||||
};
|
||||
|
||||
/* Time to wait for TCPC to complete transmit */
|
||||
#define PD_T_TCPC_TX_TIMEOUT 100 /* in ms */
|
||||
#define PD_ROLE_SWAP_TIMEOUT (MSEC_PER_SEC * 10)
|
||||
#define PD_AUG_PSY_CTRL_TIMEOUT (MSEC_PER_SEC * 10)
|
||||
|
||||
enum tcpm_transmit_status {
|
||||
TCPC_TX_SUCCESS = 0,
|
||||
TCPC_TX_DISCARDED = 1,
|
||||
TCPC_TX_FAILED = 2,
|
||||
};
|
||||
|
||||
enum tcpm_transmit_type {
|
||||
TCPC_TX_SOP = 0,
|
||||
TCPC_TX_SOP_PRIME = 1,
|
||||
TCPC_TX_SOP_PRIME_PRIME = 2,
|
||||
TCPC_TX_SOP_DEBUG_PRIME = 3,
|
||||
TCPC_TX_SOP_DEBUG_PRIME_PRIME = 4,
|
||||
TCPC_TX_HARD_RESET = 5,
|
||||
TCPC_TX_CABLE_RESET = 6,
|
||||
TCPC_TX_BIST_MODE_2 = 7
|
||||
};
|
||||
|
||||
/* Mux state attributes */
|
||||
#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */
|
||||
#define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */
|
||||
#define TCPC_MUX_POLARITY_INVERTED BIT(2) /* Polarity inverted */
|
||||
|
||||
/**
|
||||
* struct tcpc_dev - Port configuration and callback functions
|
||||
* @fwnode: Pointer to port fwnode
|
||||
* @get_vbus: Called to read current VBUS state
|
||||
* @get_current_limit:
|
||||
* Optional; called by the tcpm core when configured as a snk
|
||||
* and cc=Rp-def. This allows the tcpm to provide a fallback
|
||||
* current-limit detection method for the cc=Rp-def case.
|
||||
* For example, some tcpcs may include BC1.2 charger detection
|
||||
* and use that in this case.
|
||||
* @set_cc: Called to set value of CC pins
|
||||
* @apply_rc: Optional; Needed to move TCPCI based chipset to APPLY_RC state
|
||||
* as stated by the TCPCI specification.
|
||||
* @get_cc: Called to read current CC pin values
|
||||
* @set_polarity:
|
||||
* Called to set polarity
|
||||
* @set_vconn: Called to enable or disable VCONN
|
||||
* @set_vbus: Called to enable or disable VBUS
|
||||
* @set_current_limit:
|
||||
* Optional; called to set current limit as negotiated
|
||||
* with partner.
|
||||
* @set_pd_rx: Called to enable or disable reception of PD messages
|
||||
* @set_roles: Called to set power and data roles
|
||||
* @start_toggling:
|
||||
* Optional; if supported by hardware, called to start dual-role
|
||||
* toggling or single-role connection detection. Toggling stops
|
||||
* automatically if a connection is established.
|
||||
* @try_role: Optional; called to set a preferred role
|
||||
* @pd_transmit:Called to transmit PD message
|
||||
* @set_bist_data: Turn on/off bist data mode for compliance testing
|
||||
* @enable_frs:
|
||||
* Optional; Called to enable/disable PD 3.0 fast role swap.
|
||||
* Enabling frs is accessory dependent as not all PD3.0
|
||||
* accessories support fast role swap.
|
||||
* @frs_sourcing_vbus:
|
||||
* Optional; Called to notify that vbus is now being sourced.
|
||||
* Low level drivers can perform chip specific operations, if any.
|
||||
* @enable_auto_vbus_discharge:
|
||||
* Optional; TCPCI spec based TCPC implementations can optionally
|
||||
* support hardware to autonomously dischrge vbus upon disconnecting
|
||||
* as sink or source. TCPM signals TCPC to enable the mechanism upon
|
||||
* entering connected state and signals disabling upon disconnect.
|
||||
* @set_auto_vbus_discharge_threshold:
|
||||
* Mandatory when enable_auto_vbus_discharge is implemented. TCPM
|
||||
* calls this function to allow lower levels drivers to program the
|
||||
* vbus threshold voltage below which the vbus discharge circuit
|
||||
* will be turned on. requested_vbus_voltage is set to 0 when vbus
|
||||
* is going to disappear knowingly i.e. during PR_SWAP and
|
||||
* HARD_RESET etc.
|
||||
* @is_vbus_vsafe0v:
|
||||
* Optional; TCPCI spec based TCPC implementations are expected to
|
||||
* detect VSAFE0V voltage level at vbus. When detection of VSAFE0V
|
||||
* is supported by TCPC, set this callback for TCPM to query
|
||||
* whether vbus is at VSAFE0V when needed.
|
||||
* Returns true when vbus is at VSAFE0V, false otherwise.
|
||||
* @set_partner_usb_comm_capable:
|
||||
* Optional; The USB Communications Capable bit indicates if port
|
||||
* partner is capable of communication over the USB data lines
|
||||
* (e.g. D+/- or SS Tx/Rx). Called to notify the status of the bit.
|
||||
* @check_contaminant:
|
||||
* Optional; The callback is called when CC pins report open status
|
||||
* at the end of the deboumce period or when the port is still
|
||||
* toggling. Chip level drivers are expected to check for contaminant
|
||||
* and call tcpm_clean_port when the port is clean.
|
||||
* @cable_comm_capable
|
||||
* Optional; Returns whether cable communication over SOP' is supported
|
||||
* by the tcpc
|
||||
* @attempt_vconn_swap_discovery:
|
||||
* Optional; The callback is called by the TCPM when the result of
|
||||
* a Discover Identity request indicates that the port partner is
|
||||
* a receptacle capable of modal operation. Chip level TCPCI drivers
|
||||
* can implement their own policy to determine if and when a Vconn
|
||||
* swap following Discover Identity on SOP' occurs.
|
||||
* Return true when the TCPM is allowed to request a Vconn swap
|
||||
* after Discovery Identity on SOP.
|
||||
*/
|
||||
struct tcpc_dev {
|
||||
struct fwnode_handle *fwnode;
|
||||
|
||||
int (*init)(struct tcpc_dev *dev);
|
||||
int (*get_vbus)(struct tcpc_dev *dev);
|
||||
int (*get_current_limit)(struct tcpc_dev *dev);
|
||||
int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc);
|
||||
int (*apply_rc)(struct tcpc_dev *dev, enum typec_cc_status cc,
|
||||
enum typec_cc_polarity polarity);
|
||||
int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1,
|
||||
enum typec_cc_status *cc2);
|
||||
int (*set_polarity)(struct tcpc_dev *dev,
|
||||
enum typec_cc_polarity polarity);
|
||||
int (*set_orientation)(struct tcpc_dev *dev,
|
||||
enum typec_orientation orientation);
|
||||
int (*set_vconn)(struct tcpc_dev *dev, bool on);
|
||||
int (*set_vbus)(struct tcpc_dev *dev, bool on, bool charge);
|
||||
int (*set_current_limit)(struct tcpc_dev *dev, u32 max_ma, u32 mv);
|
||||
int (*set_pd_rx)(struct tcpc_dev *dev, bool on);
|
||||
int (*set_roles)(struct tcpc_dev *dev, bool attached,
|
||||
enum typec_role role, enum typec_data_role data);
|
||||
int (*start_toggling)(struct tcpc_dev *dev,
|
||||
enum typec_port_type port_type,
|
||||
enum typec_cc_status cc);
|
||||
int (*try_role)(struct tcpc_dev *dev, int role);
|
||||
int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type,
|
||||
const struct pd_message *msg, unsigned int negotiated_rev);
|
||||
int (*set_bist_data)(struct tcpc_dev *dev, bool on);
|
||||
int (*enable_frs)(struct tcpc_dev *dev, bool enable);
|
||||
void (*frs_sourcing_vbus)(struct tcpc_dev *dev);
|
||||
int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable);
|
||||
int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_pwr_opmode mode,
|
||||
bool pps_active, u32 requested_vbus_voltage,
|
||||
u32 pps_apdo_min_voltage);
|
||||
bool (*is_vbus_vsafe0v)(struct tcpc_dev *dev);
|
||||
void (*set_partner_usb_comm_capable)(struct tcpc_dev *dev, bool enable);
|
||||
void (*check_contaminant)(struct tcpc_dev *dev);
|
||||
bool (*cable_comm_capable)(struct tcpc_dev *dev);
|
||||
bool (*attempt_vconn_swap_discovery)(struct tcpc_dev *dev);
|
||||
};
|
||||
|
||||
struct tcpm_port;
|
||||
|
||||
struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc);
|
||||
void tcpm_unregister_port(struct tcpm_port *port);
|
||||
|
||||
void tcpm_vbus_change(struct tcpm_port *port);
|
||||
void tcpm_cc_change(struct tcpm_port *port);
|
||||
void tcpm_sink_frs(struct tcpm_port *port);
|
||||
void tcpm_sourcing_vbus(struct tcpm_port *port);
|
||||
void tcpm_pd_receive(struct tcpm_port *port,
|
||||
const struct pd_message *msg,
|
||||
enum tcpm_transmit_type rx_sop_type);
|
||||
void tcpm_pd_transmit_complete(struct tcpm_port *port,
|
||||
enum tcpm_transmit_status status);
|
||||
void tcpm_pd_hard_reset(struct tcpm_port *port);
|
||||
void tcpm_tcpc_reset(struct tcpm_port *port);
|
||||
void tcpm_port_clean(struct tcpm_port *port);
|
||||
bool tcpm_port_is_toggling(struct tcpm_port *port);
|
||||
void tcpm_port_error_recovery(struct tcpm_port *port);
|
||||
|
||||
#endif /* __LINUX_USB_TCPM_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_USB_PHY_H
|
||||
#define __TEGRA_USB_PHY_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
struct gpio_desc;
|
||||
|
||||
/*
|
||||
* utmi_pll_config_in_car_module: true if the UTMI PLL configuration registers
|
||||
* should be set up by clk-tegra, false if by the PHY code
|
||||
* has_hostpc: true if the USB controller has the HOSTPC extension, which
|
||||
* changes the location of the PHCD and PTS fields
|
||||
* requires_usbmode_setup: true if the USBMODE register needs to be set to
|
||||
* enter host mode
|
||||
* requires_extra_tuning_parameters: true if xcvr_hsslew, hssquelch_level
|
||||
* and hsdiscon_level should be set for adequate signal quality
|
||||
* requires_pmc_ao_power_up: true if USB AO is powered down by default
|
||||
* uhsic_registers_offset: for Tegra30+ where HSIC registers were offset
|
||||
* comparing to Tegra20 by 0x400, since Tegra20 has no UTMIP on PHY2
|
||||
* uhsic_tx_rtune: fine tuned 50 Ohm termination resistor for NMOS/PMOS driver
|
||||
* uhsic_pts_value: parallel transceiver select enumeration value
|
||||
* portsc1_offset: register offset of PORTSC1
|
||||
*/
|
||||
|
||||
struct tegra_phy_soc_config {
|
||||
bool utmi_pll_config_in_car_module;
|
||||
bool has_hostpc;
|
||||
bool requires_usbmode_setup;
|
||||
bool requires_extra_tuning_parameters;
|
||||
bool requires_pmc_ao_power_up;
|
||||
u32 uhsic_registers_offset;
|
||||
u32 uhsic_tx_rtune;
|
||||
u32 uhsic_pts_value;
|
||||
u32 portsc1_offset;
|
||||
};
|
||||
|
||||
struct tegra_utmip_config {
|
||||
u8 hssync_start_delay;
|
||||
u8 elastic_limit;
|
||||
u8 idle_wait_delay;
|
||||
u8 term_range_adj;
|
||||
bool xcvr_setup_use_fuses;
|
||||
u8 xcvr_setup;
|
||||
u8 xcvr_lsfslew;
|
||||
u8 xcvr_lsrslew;
|
||||
u8 xcvr_hsslew;
|
||||
u8 hssquelch_level;
|
||||
u8 hsdiscon_level;
|
||||
};
|
||||
|
||||
enum tegra_usb_phy_port_speed {
|
||||
TEGRA_USB_PHY_PORT_SPEED_FULL = 0,
|
||||
TEGRA_USB_PHY_PORT_SPEED_LOW,
|
||||
TEGRA_USB_PHY_PORT_SPEED_HIGH,
|
||||
};
|
||||
|
||||
struct tegra_xtal_freq;
|
||||
|
||||
struct tegra_usb_phy {
|
||||
int irq;
|
||||
int instance;
|
||||
const struct tegra_xtal_freq *freq;
|
||||
void __iomem *regs;
|
||||
void __iomem *pad_regs;
|
||||
struct clk *clk;
|
||||
struct clk *pll_u;
|
||||
struct clk *pad_clk;
|
||||
struct regulator *vbus;
|
||||
struct regmap *pmc_regmap;
|
||||
enum usb_dr_mode mode;
|
||||
void *config;
|
||||
const struct tegra_phy_soc_config *soc_config;
|
||||
struct usb_phy *ulpi;
|
||||
struct usb_phy u_phy;
|
||||
bool is_legacy_phy;
|
||||
enum usb_phy_interface phy_type;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct reset_control *pad_rst;
|
||||
bool wakeup_enabled;
|
||||
bool pad_wakeup;
|
||||
bool powered_on;
|
||||
};
|
||||
|
||||
#endif /* __TEGRA_USB_PHY_H */
|
||||
@@ -0,0 +1,416 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __LINUX_USB_TYPEC_H
|
||||
#define __LINUX_USB_TYPEC_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* USB Type-C Specification releases */
|
||||
#define USB_TYPEC_REV_1_0 0x100 /* 1.0 */
|
||||
#define USB_TYPEC_REV_1_1 0x110 /* 1.1 */
|
||||
#define USB_TYPEC_REV_1_2 0x120 /* 1.2 */
|
||||
#define USB_TYPEC_REV_1_3 0x130 /* 1.3 */
|
||||
#define USB_TYPEC_REV_1_4 0x140 /* 1.4 */
|
||||
#define USB_TYPEC_REV_2_0 0x200 /* 2.0 */
|
||||
|
||||
struct typec_partner;
|
||||
struct typec_cable;
|
||||
struct typec_plug;
|
||||
struct typec_port;
|
||||
struct typec_altmode_ops;
|
||||
struct typec_cable_ops;
|
||||
|
||||
struct bus_type;
|
||||
struct fwnode_handle;
|
||||
struct device;
|
||||
|
||||
struct usb_power_delivery;
|
||||
struct usb_power_delivery_desc;
|
||||
|
||||
extern const struct bus_type typec_bus;
|
||||
|
||||
enum typec_port_type {
|
||||
TYPEC_PORT_SRC,
|
||||
TYPEC_PORT_SNK,
|
||||
TYPEC_PORT_DRP,
|
||||
};
|
||||
|
||||
enum typec_port_data {
|
||||
TYPEC_PORT_DFP,
|
||||
TYPEC_PORT_UFP,
|
||||
TYPEC_PORT_DRD,
|
||||
};
|
||||
|
||||
enum typec_plug_type {
|
||||
USB_PLUG_NONE,
|
||||
USB_PLUG_TYPE_A,
|
||||
USB_PLUG_TYPE_B,
|
||||
USB_PLUG_TYPE_C,
|
||||
USB_PLUG_CAPTIVE,
|
||||
};
|
||||
|
||||
enum typec_data_role {
|
||||
TYPEC_DEVICE,
|
||||
TYPEC_HOST,
|
||||
};
|
||||
|
||||
enum typec_role {
|
||||
TYPEC_SINK,
|
||||
TYPEC_SOURCE,
|
||||
};
|
||||
|
||||
static inline int is_sink(enum typec_role role)
|
||||
{
|
||||
return role == TYPEC_SINK;
|
||||
}
|
||||
|
||||
static inline int is_source(enum typec_role role)
|
||||
{
|
||||
return role == TYPEC_SOURCE;
|
||||
}
|
||||
|
||||
enum typec_pwr_opmode {
|
||||
TYPEC_PWR_MODE_USB,
|
||||
TYPEC_PWR_MODE_1_5A,
|
||||
TYPEC_PWR_MODE_3_0A,
|
||||
TYPEC_PWR_MODE_PD,
|
||||
};
|
||||
|
||||
enum typec_accessory {
|
||||
TYPEC_ACCESSORY_NONE,
|
||||
TYPEC_ACCESSORY_AUDIO,
|
||||
TYPEC_ACCESSORY_DEBUG,
|
||||
};
|
||||
|
||||
#define TYPEC_MAX_ACCESSORY 3
|
||||
|
||||
enum typec_orientation {
|
||||
TYPEC_ORIENTATION_NONE,
|
||||
TYPEC_ORIENTATION_NORMAL,
|
||||
TYPEC_ORIENTATION_REVERSE,
|
||||
};
|
||||
|
||||
enum usb_mode {
|
||||
USB_MODE_NONE,
|
||||
USB_MODE_USB2,
|
||||
USB_MODE_USB3,
|
||||
USB_MODE_USB4
|
||||
};
|
||||
|
||||
#define USB_CAPABILITY_USB2 BIT(0)
|
||||
#define USB_CAPABILITY_USB3 BIT(1)
|
||||
#define USB_CAPABILITY_USB4 BIT(2)
|
||||
|
||||
/*
|
||||
* struct enter_usb_data - Enter_USB Message details
|
||||
* @eudo: Enter_USB Data Object
|
||||
* @active_link_training: Active Cable Plug Link Training
|
||||
*
|
||||
* @active_link_training is a flag that should be set with uni-directional SBRX
|
||||
* communication, and left 0 with passive cables and with bi-directional SBRX
|
||||
* communication.
|
||||
*/
|
||||
struct enter_usb_data {
|
||||
u32 eudo;
|
||||
unsigned char active_link_training:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct usb_pd_identity - USB Power Delivery identity data
|
||||
* @id_header: ID Header VDO
|
||||
* @cert_stat: Cert Stat VDO
|
||||
* @product: Product VDO
|
||||
* @vdo: Product Type Specific VDOs
|
||||
*
|
||||
* USB power delivery Discover Identity command response data.
|
||||
*
|
||||
* REVISIT: This is USB Power Delivery specific information, so this structure
|
||||
* probable belongs to USB Power Delivery header file once we have them.
|
||||
*/
|
||||
struct usb_pd_identity {
|
||||
u32 id_header;
|
||||
u32 cert_stat;
|
||||
u32 product;
|
||||
u32 vdo[3];
|
||||
};
|
||||
|
||||
int typec_partner_set_identity(struct typec_partner *partner);
|
||||
int typec_cable_set_identity(struct typec_cable *cable);
|
||||
|
||||
/*
|
||||
* struct typec_altmode_desc - USB Type-C Alternate Mode Descriptor
|
||||
* @svid: Standard or Vendor ID
|
||||
* @mode: Index of the Mode
|
||||
* @vdo: VDO returned by Discover Modes USB PD command
|
||||
* @roles: Only for ports. DRP if the mode is available in both roles
|
||||
* @inactive: Only for ports. Make this port inactive (default is active).
|
||||
*
|
||||
* Description of an Alternate Mode which a connector, cable plug or partner
|
||||
* supports.
|
||||
*/
|
||||
struct typec_altmode_desc {
|
||||
u16 svid;
|
||||
u8 mode;
|
||||
u32 vdo;
|
||||
/* Only used with ports */
|
||||
enum typec_port_data roles;
|
||||
bool inactive;
|
||||
bool mode_selection;
|
||||
};
|
||||
|
||||
void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision);
|
||||
int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmodes);
|
||||
struct typec_altmode
|
||||
*typec_partner_register_altmode(struct typec_partner *partner,
|
||||
const struct typec_altmode_desc *desc);
|
||||
int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes);
|
||||
struct typec_altmode
|
||||
*typec_plug_register_altmode(struct typec_plug *plug,
|
||||
const struct typec_altmode_desc *desc);
|
||||
struct typec_altmode
|
||||
*typec_port_register_altmode(struct typec_port *port,
|
||||
const struct typec_altmode_desc *desc);
|
||||
|
||||
void typec_port_register_altmodes(struct typec_port *port,
|
||||
const struct typec_altmode_ops *ops, void *drvdata,
|
||||
struct typec_altmode **altmodes, size_t n);
|
||||
|
||||
void typec_port_register_cable_ops(struct typec_altmode **altmodes, int max_altmodes,
|
||||
const struct typec_cable_ops *ops);
|
||||
|
||||
void typec_unregister_altmode(struct typec_altmode *altmode);
|
||||
|
||||
struct typec_port *typec_altmode2port(struct typec_altmode *alt);
|
||||
|
||||
void typec_altmode_update_active(struct typec_altmode *alt, bool active);
|
||||
|
||||
void typec_altmode_set_ops(struct typec_altmode *alt,
|
||||
const struct typec_altmode_ops *ops);
|
||||
|
||||
enum typec_plug_index {
|
||||
TYPEC_PLUG_SOP_P,
|
||||
TYPEC_PLUG_SOP_PP,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct typec_plug_desc - USB Type-C Cable Plug Descriptor
|
||||
* @index: SOP Prime for the plug connected to DFP and SOP Double Prime for the
|
||||
* plug connected to UFP
|
||||
*
|
||||
* Represents USB Type-C Cable Plug.
|
||||
*/
|
||||
struct typec_plug_desc {
|
||||
enum typec_plug_index index;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct typec_cable_desc - USB Type-C Cable Descriptor
|
||||
* @type: The plug type from USB PD Cable VDO
|
||||
* @active: Is the cable active or passive
|
||||
* @identity: Result of Discover Identity command
|
||||
* @pd_revision: USB Power Delivery Specification revision if supported
|
||||
*
|
||||
* Represents USB Type-C Cable attached to USB Type-C port.
|
||||
*/
|
||||
struct typec_cable_desc {
|
||||
enum typec_plug_type type;
|
||||
unsigned int active:1;
|
||||
struct usb_pd_identity *identity;
|
||||
u16 pd_revision; /* 0300H = "3.0" */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* struct typec_partner_desc - USB Type-C Partner Descriptor
|
||||
* @usb_pd: USB Power Delivery support
|
||||
* @accessory: Audio, Debug or none.
|
||||
* @identity: Discover Identity command data
|
||||
* @pd_revision: USB Power Delivery Specification Revision if supported
|
||||
* @usb_capability: Supported USB Modes
|
||||
* @attach: Notification about attached USB device
|
||||
* @deattach: Notification about removed USB device
|
||||
*
|
||||
* Details about a partner that is attached to USB Type-C port. If @identity
|
||||
* member exists when partner is registered, a directory named "identity" is
|
||||
* created to sysfs for the partner device.
|
||||
*
|
||||
* @pd_revision is based on the setting of the "Specification Revision" field
|
||||
* in the message header on the initial "Source Capabilities" message received
|
||||
* from the partner, or a "Request" message received from the partner, depending
|
||||
* on whether our port is a Sink or a Source.
|
||||
*/
|
||||
struct typec_partner_desc {
|
||||
unsigned int usb_pd:1;
|
||||
enum typec_accessory accessory;
|
||||
struct usb_pd_identity *identity;
|
||||
u16 pd_revision; /* 0300H = "3.0" */
|
||||
u8 usb_capability;
|
||||
|
||||
void (*attach)(struct typec_partner *partner, struct device *dev);
|
||||
void (*deattach)(struct typec_partner *partner, struct device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct typec_operations - USB Type-C Port Operations
|
||||
* @try_role: Set data role preference for DRP port
|
||||
* @dr_set: Set Data Role
|
||||
* @pr_set: Set Power Role
|
||||
* @vconn_set: Source VCONN
|
||||
* @port_type_set: Set port type
|
||||
* @pd_get: Get available USB Power Delivery Capabilities.
|
||||
* @pd_set: Set USB Power Delivery Capabilities.
|
||||
* @default_usb_mode_set: USB Mode to be used by default with Enter_USB Message
|
||||
* @enter_usb_mode: Change the active USB Mode
|
||||
*/
|
||||
struct typec_operations {
|
||||
int (*try_role)(struct typec_port *port, int role);
|
||||
int (*dr_set)(struct typec_port *port, enum typec_data_role role);
|
||||
int (*pr_set)(struct typec_port *port, enum typec_role role);
|
||||
int (*vconn_set)(struct typec_port *port, enum typec_role role);
|
||||
int (*port_type_set)(struct typec_port *port,
|
||||
enum typec_port_type type);
|
||||
struct usb_power_delivery **(*pd_get)(struct typec_port *port);
|
||||
int (*pd_set)(struct typec_port *port, struct usb_power_delivery *pd);
|
||||
int (*default_usb_mode_set)(struct typec_port *port, enum usb_mode mode);
|
||||
int (*enter_usb_mode)(struct typec_port *port, enum usb_mode mode);
|
||||
};
|
||||
|
||||
enum usb_pd_svdm_ver {
|
||||
SVDM_VER_1_0 = 0,
|
||||
SVDM_VER_2_0 = 1,
|
||||
SVDM_VER_MAX = SVDM_VER_2_0,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct typec_capability - USB Type-C Port Capabilities
|
||||
* @type: Supported power role of the port
|
||||
* @data: Supported data role of the port
|
||||
* @revision: USB Type-C Specification release. Binary coded decimal
|
||||
* @pd_revision: USB Power Delivery Specification revision if supported
|
||||
* @svdm_version: USB PD Structured VDM version if supported
|
||||
* @prefer_role: Initial role preference (DRP ports).
|
||||
* @accessory: Supported Accessory Modes
|
||||
* @usb_capability: Supported USB Modes
|
||||
* @no_mode_control: Ability to manage Alternate Modes
|
||||
* @fwnode: Optional fwnode of the port
|
||||
* @driver_data: Private pointer for driver specific info
|
||||
* @pd: Optional USB Power Delivery Support
|
||||
* @ops: Port operations vector
|
||||
*
|
||||
* Static capabilities of a single USB Type-C port.
|
||||
*/
|
||||
struct typec_capability {
|
||||
enum typec_port_type type;
|
||||
enum typec_port_data data;
|
||||
u16 revision; /* 0120H = "1.2" */
|
||||
u16 pd_revision; /* 0300H = "3.0" */
|
||||
enum usb_pd_svdm_ver svdm_version;
|
||||
int prefer_role;
|
||||
enum typec_accessory accessory[TYPEC_MAX_ACCESSORY];
|
||||
unsigned int orientation_aware:1;
|
||||
u8 usb_capability;
|
||||
bool no_mode_control;
|
||||
|
||||
struct fwnode_handle *fwnode;
|
||||
void *driver_data;
|
||||
|
||||
struct usb_power_delivery *pd;
|
||||
|
||||
const struct typec_operations *ops;
|
||||
};
|
||||
|
||||
/* Specific to try_role(). Indicates the user want's to clear the preference. */
|
||||
#define TYPEC_NO_PREFERRED_ROLE (-1)
|
||||
|
||||
struct typec_port *typec_register_port(struct device *parent,
|
||||
const struct typec_capability *cap);
|
||||
void typec_unregister_port(struct typec_port *port);
|
||||
|
||||
struct typec_partner *typec_register_partner(struct typec_port *port,
|
||||
struct typec_partner_desc *desc);
|
||||
void typec_unregister_partner(struct typec_partner *partner);
|
||||
|
||||
struct typec_cable *typec_register_cable(struct typec_port *port,
|
||||
struct typec_cable_desc *desc);
|
||||
void typec_unregister_cable(struct typec_cable *cable);
|
||||
|
||||
struct typec_cable *typec_cable_get(struct typec_port *port);
|
||||
void typec_cable_put(struct typec_cable *cable);
|
||||
int typec_cable_is_active(struct typec_cable *cable);
|
||||
|
||||
struct typec_plug *typec_register_plug(struct typec_cable *cable,
|
||||
struct typec_plug_desc *desc);
|
||||
void typec_unregister_plug(struct typec_plug *plug);
|
||||
|
||||
void typec_set_data_role(struct typec_port *port, enum typec_data_role role);
|
||||
enum typec_data_role typec_get_data_role(struct typec_port *port);
|
||||
void typec_set_pwr_role(struct typec_port *port, enum typec_role role);
|
||||
void typec_set_vconn_role(struct typec_port *port, enum typec_role role);
|
||||
void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode);
|
||||
|
||||
int typec_set_orientation(struct typec_port *port,
|
||||
enum typec_orientation orientation);
|
||||
enum typec_orientation typec_get_orientation(struct typec_port *port);
|
||||
int typec_set_mode(struct typec_port *port, int mode);
|
||||
|
||||
void *typec_get_drvdata(struct typec_port *port);
|
||||
|
||||
int typec_get_fw_cap(struct typec_capability *cap,
|
||||
struct fwnode_handle *fwnode);
|
||||
|
||||
int typec_find_pwr_opmode(const char *name);
|
||||
int typec_find_orientation(const char *name);
|
||||
int typec_find_port_power_role(const char *name);
|
||||
int typec_find_power_role(const char *name);
|
||||
int typec_find_port_data_role(const char *name);
|
||||
|
||||
void typec_partner_set_svdm_version(struct typec_partner *partner,
|
||||
enum usb_pd_svdm_ver svdm_version);
|
||||
int typec_get_negotiated_svdm_version(struct typec_port *port);
|
||||
|
||||
int typec_get_cable_svdm_version(struct typec_port *port);
|
||||
void typec_cable_set_svdm_version(struct typec_cable *cable, enum usb_pd_svdm_ver svdm_version);
|
||||
|
||||
struct usb_power_delivery *typec_partner_usb_power_delivery_register(struct typec_partner *partner,
|
||||
struct usb_power_delivery_desc *desc);
|
||||
|
||||
int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_delivery *pd);
|
||||
int typec_partner_set_usb_power_delivery(struct typec_partner *partner,
|
||||
struct usb_power_delivery *pd);
|
||||
|
||||
void typec_partner_set_usb_mode(struct typec_partner *partner, enum usb_mode usb_mode);
|
||||
void typec_port_set_usb_mode(struct typec_port *port, enum usb_mode mode);
|
||||
|
||||
/**
|
||||
* struct typec_connector - Representation of Type-C port for external drivers
|
||||
* @attach: notification about device removal
|
||||
* @deattach: notification about device removal
|
||||
*
|
||||
* Drivers that control the USB and other ports (DisplayPorts, etc.), that are
|
||||
* connected to the Type-C connectors, can use these callbacks to inform the
|
||||
* Type-C connector class about connections and disconnections. That information
|
||||
* can then be used by the typec-port drivers to power on or off parts that are
|
||||
* needed or not needed - as an example, in USB mode if USB2 device is
|
||||
* enumerated, USB3 components (retimers, phys, and what have you) do not need
|
||||
* to be powered on.
|
||||
*
|
||||
* The attached (enumerated) devices will be liked with the typec-partner device.
|
||||
*/
|
||||
struct typec_connector {
|
||||
void (*attach)(struct typec_connector *con, struct device *dev);
|
||||
void (*deattach)(struct typec_connector *con, struct device *dev);
|
||||
};
|
||||
|
||||
static inline void typec_attach(struct typec_connector *con, struct device *dev)
|
||||
{
|
||||
if (con && con->attach)
|
||||
con->attach(con, dev);
|
||||
}
|
||||
|
||||
static inline void typec_deattach(struct typec_connector *con, struct device *dev)
|
||||
{
|
||||
if (con && con->deattach)
|
||||
con->deattach(con, dev);
|
||||
}
|
||||
|
||||
#endif /* __LINUX_USB_TYPEC_H */
|
||||
@@ -0,0 +1,287 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __USB_TYPEC_ALTMODE_H
|
||||
#define __USB_TYPEC_ALTMODE_H
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/usb/typec.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#define MODE_DISCOVERY_MAX 6
|
||||
|
||||
extern const struct device_type typec_port_altmode_dev_type;
|
||||
extern const struct device_type typec_plug_altmode_dev_type;
|
||||
extern const struct device_type typec_partner_altmode_dev_type;
|
||||
|
||||
#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
|
||||
#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
|
||||
#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
|
||||
|
||||
struct typec_altmode_ops;
|
||||
|
||||
/**
|
||||
* struct typec_altmode - USB Type-C alternate mode device
|
||||
* @dev: Driver model's view of this device
|
||||
* @svid: Standard or Vendor ID (SVID) of the alternate mode
|
||||
* @mode: Index of the Mode
|
||||
* @vdo: VDO returned by Discover Modes USB PD command
|
||||
* @active: Tells has the mode been entered or not
|
||||
* @priority: Priority used by the automatic alternate mode selection process
|
||||
* @mode_selection: Whether entry to this alternate mode is managed by the
|
||||
* automatic alternate mode selection process or by the specific driver
|
||||
* @desc: Optional human readable description of the mode
|
||||
* @ops: Operations vector from the driver
|
||||
* @cable_ops: Cable operations vector from the driver.
|
||||
*/
|
||||
struct typec_altmode {
|
||||
struct device dev;
|
||||
u16 svid;
|
||||
int mode;
|
||||
u32 vdo;
|
||||
unsigned int active:1;
|
||||
u8 priority;
|
||||
bool mode_selection;
|
||||
|
||||
char *desc;
|
||||
const struct typec_altmode_ops *ops;
|
||||
const struct typec_cable_ops *cable_ops;
|
||||
};
|
||||
|
||||
#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev)
|
||||
|
||||
static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(&altmode->dev, data);
|
||||
}
|
||||
|
||||
static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode)
|
||||
{
|
||||
return dev_get_drvdata(&altmode->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct typec_altmode_ops - Alternate mode specific operations vector
|
||||
* @enter: Operations to be executed with Enter Mode Command
|
||||
* @exit: Operations to be executed with Exit Mode Command
|
||||
* @attention: Callback for Attention Command
|
||||
* @vdm: Callback for SVID specific commands
|
||||
* @notify: Communication channel for platform and the alternate mode
|
||||
* @activate: User callback for Enter/Exit Mode
|
||||
*/
|
||||
struct typec_altmode_ops {
|
||||
int (*enter)(struct typec_altmode *altmode, u32 *vdo);
|
||||
int (*exit)(struct typec_altmode *altmode);
|
||||
void (*attention)(struct typec_altmode *altmode, u32 vdo);
|
||||
int (*vdm)(struct typec_altmode *altmode, const u32 hdr,
|
||||
const u32 *vdo, int cnt);
|
||||
int (*notify)(struct typec_altmode *altmode, unsigned long conf,
|
||||
void *data);
|
||||
int (*activate)(struct typec_altmode *altmode, int activate);
|
||||
};
|
||||
|
||||
int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo);
|
||||
int typec_altmode_exit(struct typec_altmode *altmode);
|
||||
int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
|
||||
int typec_altmode_vdm(struct typec_altmode *altmode,
|
||||
const u32 header, const u32 *vdo, int count);
|
||||
int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
|
||||
void *data);
|
||||
const struct typec_altmode *
|
||||
typec_altmode_get_partner(struct typec_altmode *altmode);
|
||||
|
||||
/**
|
||||
* struct typec_cable_ops - Cable alternate mode operations vector
|
||||
* @enter: Operations to be executed with Enter Mode Command
|
||||
* @exit: Operations to be executed with Exit Mode Command
|
||||
* @vdm: Callback for SVID specific commands
|
||||
*/
|
||||
struct typec_cable_ops {
|
||||
int (*enter)(struct typec_altmode *altmode, enum typec_plug_index sop, u32 *vdo);
|
||||
int (*exit)(struct typec_altmode *altmode, enum typec_plug_index sop);
|
||||
int (*vdm)(struct typec_altmode *altmode, enum typec_plug_index sop,
|
||||
const u32 hdr, const u32 *vdo, int cnt);
|
||||
};
|
||||
|
||||
int typec_cable_altmode_enter(struct typec_altmode *altmode, enum typec_plug_index sop, u32 *vdo);
|
||||
int typec_cable_altmode_exit(struct typec_altmode *altmode, enum typec_plug_index sop);
|
||||
int typec_cable_altmode_vdm(struct typec_altmode *altmode, enum typec_plug_index sop,
|
||||
const u32 header, const u32 *vdo, int count);
|
||||
|
||||
/**
|
||||
* typec_altmode_get_cable_svdm_version - Get negotiated SVDM version for cable plug
|
||||
* @altmode: Handle to the alternate mode
|
||||
*/
|
||||
static inline int
|
||||
typec_altmode_get_cable_svdm_version(struct typec_altmode *altmode)
|
||||
{
|
||||
return typec_get_cable_svdm_version(typec_altmode2port(altmode));
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the connector states (USB, Safe and Alt Mode) defined in USB Type-C
|
||||
* Specification. SVID specific connector states are expected to follow and
|
||||
* start from the value TYPEC_STATE_MODAL.
|
||||
*/
|
||||
enum {
|
||||
TYPEC_STATE_SAFE, /* USB Safe State */
|
||||
TYPEC_STATE_USB, /* USB Operation */
|
||||
TYPEC_STATE_MODAL, /* Alternate Modes */
|
||||
};
|
||||
|
||||
/*
|
||||
* For the muxes there is no difference between Accessory Modes and Alternate
|
||||
* Modes, so the Accessory Modes are supplied with specific modal state values
|
||||
* here. Unlike with Alternate Modes, where the mux will be linked with the
|
||||
* alternate mode device, the mux for Accessory Modes will be linked with the
|
||||
* port device instead.
|
||||
*
|
||||
* Port drivers can use TYPEC_MODE_AUDIO and TYPEC_MODE_DEBUG as the mode
|
||||
* value for typec_set_mode() when accessory modes are supported.
|
||||
*
|
||||
* USB4 also requires that the pins on the connector are repurposed, just like
|
||||
* Alternate Modes. USB4 mode is however not entered with the Enter Mode Command
|
||||
* like the Alternate Modes are, but instead with a special Enter_USB Message.
|
||||
* The Enter_USB Message can also be used for setting to connector to operate in
|
||||
* USB 3.2 or in USB 2.0 mode instead of USB4.
|
||||
*
|
||||
* The Enter_USB specific "USB Modes" are also supplied here as special modal
|
||||
* state values, just like the Accessory Modes.
|
||||
*/
|
||||
enum {
|
||||
TYPEC_MODE_USB2 = TYPEC_STATE_MODAL, /* USB 2.0 mode */
|
||||
TYPEC_MODE_USB3, /* USB 3.2 mode */
|
||||
TYPEC_MODE_USB4, /* USB4 mode */
|
||||
TYPEC_MODE_AUDIO, /* Audio Accessory */
|
||||
TYPEC_MODE_DEBUG, /* Debug Accessory */
|
||||
};
|
||||
|
||||
#define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL)
|
||||
|
||||
struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode,
|
||||
enum typec_plug_index index);
|
||||
void typec_altmode_put_plug(struct typec_altmode *plug);
|
||||
|
||||
struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
|
||||
size_t n, u16 svid, u8 mode);
|
||||
|
||||
/**
|
||||
* typec_altmode_get_orientation - Get cable plug orientation
|
||||
* @altmode: Handle to the alternate mode
|
||||
*/
|
||||
static inline enum typec_orientation
|
||||
typec_altmode_get_orientation(struct typec_altmode *altmode)
|
||||
{
|
||||
return typec_get_orientation(typec_altmode2port(altmode));
|
||||
}
|
||||
|
||||
/**
|
||||
* typec_altmode_get_svdm_version - Get negotiated SVDM version
|
||||
* @altmode: Handle to the alternate mode
|
||||
*/
|
||||
static inline int
|
||||
typec_altmode_get_svdm_version(struct typec_altmode *altmode)
|
||||
{
|
||||
return typec_get_negotiated_svdm_version(typec_altmode2port(altmode));
|
||||
}
|
||||
|
||||
/**
|
||||
* typec_altmode_get_data_role - Get port data role
|
||||
* @altmode: Handle to the alternate mode
|
||||
*
|
||||
* Alt Mode drivers should only issue Enter Mode through the port if they are
|
||||
* the DFP.
|
||||
*/
|
||||
static inline enum typec_data_role
|
||||
typec_altmode_get_data_role(struct typec_altmode *altmode)
|
||||
{
|
||||
return typec_get_data_role(typec_altmode2port(altmode));
|
||||
}
|
||||
|
||||
/**
|
||||
* struct typec_altmode_driver - USB Type-C alternate mode device driver
|
||||
* @id_table: Null terminated array of SVIDs
|
||||
* @probe: Callback for device binding
|
||||
* @remove: Callback for device unbinding
|
||||
* @driver: Device driver model driver
|
||||
*
|
||||
* These drivers will be bind to the partner alternate mode devices. They will
|
||||
* handle all SVID specific communication.
|
||||
*/
|
||||
struct typec_altmode_driver {
|
||||
const struct typec_device_id *id_table;
|
||||
int (*probe)(struct typec_altmode *altmode);
|
||||
void (*remove)(struct typec_altmode *altmode);
|
||||
struct device_driver driver;
|
||||
};
|
||||
|
||||
#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \
|
||||
driver)
|
||||
|
||||
/**
|
||||
* typec_altmode_register_driver - registers a USB Type-C alternate mode
|
||||
* device driver
|
||||
* @drv: pointer to struct typec_altmode_driver
|
||||
*
|
||||
* These drivers will be bind to the partner alternate mode devices. They will
|
||||
* handle all SVID specific communication.
|
||||
*/
|
||||
#define typec_altmode_register_driver(drv) \
|
||||
__typec_altmode_register_driver(drv, THIS_MODULE)
|
||||
int __typec_altmode_register_driver(struct typec_altmode_driver *drv,
|
||||
struct module *module);
|
||||
/**
|
||||
* typec_altmode_unregister_driver - unregisters a USB Type-C alternate mode
|
||||
* device driver
|
||||
* @drv: pointer to struct typec_altmode_driver
|
||||
*
|
||||
* These drivers will be bind to the partner alternate mode devices. They will
|
||||
* handle all SVID specific communication.
|
||||
*/
|
||||
void typec_altmode_unregister_driver(struct typec_altmode_driver *drv);
|
||||
|
||||
#define module_typec_altmode_driver(__typec_altmode_driver) \
|
||||
module_driver(__typec_altmode_driver, typec_altmode_register_driver, \
|
||||
typec_altmode_unregister_driver)
|
||||
|
||||
/**
|
||||
* typec_mode_selection_start - Start an alternate mode selection process
|
||||
* @partner: Handle to the Type-C partner device
|
||||
* @delay: Delay between mode entry/exit attempts, ms
|
||||
* @timeout: Timeout for a mode entry attempt, ms
|
||||
*
|
||||
* This function initiates the process of attempting to enter an Alternate Mode
|
||||
* supported by the connected Type-C partner.
|
||||
* Returns 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int typec_mode_selection_start(struct typec_partner *partner,
|
||||
const unsigned int delay, const unsigned int timeout);
|
||||
|
||||
/**
|
||||
* typec_altmode_state_update - Report the current status of an Alternate Mode
|
||||
* negotiation
|
||||
* @partner: Handle to the Type-C partner device
|
||||
* @svid: Standard or Vendor ID of the Alternate Mode. A value of 0 should be
|
||||
* passed if no mode is currently active
|
||||
* @result: Result of the entry operation. This should be 0 on success, or a
|
||||
* negative error code if the negotiation failed
|
||||
*
|
||||
* This function should be called by an Alternate Mode driver to report the
|
||||
* result of an asynchronous alternate mode entry request. It signals what the
|
||||
* current active SVID is (or 0 if none) and the success or failure status of
|
||||
* the last attempt.
|
||||
*/
|
||||
void typec_altmode_state_update(struct typec_partner *partner, const u16 svid,
|
||||
const int result);
|
||||
|
||||
/**
|
||||
* typec_mode_selection_delete - Delete an alternate mode selection instance
|
||||
* @partner: Handle to the Type-C partner device.
|
||||
*
|
||||
* This function cancels a pending alternate mode selection request that was
|
||||
* previously started with typec_mode_selection_start().
|
||||
* This is typically called when the partner disconnects.
|
||||
*/
|
||||
void typec_mode_selection_delete(struct typec_partner *partner);
|
||||
|
||||
#endif /* __USB_TYPEC_ALTMODE_H */
|
||||
@@ -0,0 +1,131 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __USB_TYPEC_DP_H
|
||||
#define __USB_TYPEC_DP_H
|
||||
|
||||
#include <linux/usb/typec_altmode.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#define USB_TYPEC_DP_SID 0xff01
|
||||
/* USB IF has not assigned a Standard ID (SID) for VirtualLink,
|
||||
* so the manufacturers of VirtualLink adapters use their Vendor
|
||||
* IDs as the SVID.
|
||||
*/
|
||||
#define USB_TYPEC_NVIDIA_VLINK_SID 0x955 /* NVIDIA VirtualLink */
|
||||
#define USB_TYPEC_DP_MODE 1
|
||||
|
||||
/*
|
||||
* Connector states matching the pin assignments in DisplayPort Alt Mode
|
||||
* Specification.
|
||||
*
|
||||
* These values are meant primarily to be used by the mux drivers, but they are
|
||||
* also used as the "value" part in the alternate mode notification chain, so
|
||||
* receivers of those notifications will always see them.
|
||||
*
|
||||
* Note. DisplayPort USB Type-C Alt Mode Specification version 1.0b deprecated
|
||||
* pin assignments A, B and F, but they are still defined here for legacy
|
||||
* purposes.
|
||||
*/
|
||||
enum {
|
||||
TYPEC_DP_STATE_A = TYPEC_STATE_MODAL, /* Not supported after v1.0b */
|
||||
TYPEC_DP_STATE_B, /* Not supported after v1.0b */
|
||||
TYPEC_DP_STATE_C,
|
||||
TYPEC_DP_STATE_D,
|
||||
TYPEC_DP_STATE_E,
|
||||
TYPEC_DP_STATE_F, /* Not supported after v1.0b */
|
||||
};
|
||||
|
||||
/*
|
||||
* struct typec_displayport_data - DisplayPort Alt Mode specific data
|
||||
* @status: Status Update command VDO content
|
||||
* @conf: Configure command VDO content
|
||||
*
|
||||
* This structure is delivered as the data part with the notifications. It
|
||||
* contains the VDOs from the two DisplayPort Type-C alternate mode specific
|
||||
* commands: Status Update and Configure.
|
||||
*
|
||||
* @status will show for example the status of the HPD signal.
|
||||
*/
|
||||
struct typec_displayport_data {
|
||||
u32 status;
|
||||
u32 conf;
|
||||
};
|
||||
|
||||
enum {
|
||||
DP_PIN_ASSIGN_A, /* Not supported after v1.0b */
|
||||
DP_PIN_ASSIGN_B, /* Not supported after v1.0b */
|
||||
DP_PIN_ASSIGN_C,
|
||||
DP_PIN_ASSIGN_D,
|
||||
DP_PIN_ASSIGN_E,
|
||||
DP_PIN_ASSIGN_F, /* Not supported after v1.0b */
|
||||
DP_PIN_ASSIGN_MAX,
|
||||
};
|
||||
|
||||
/* DisplayPort alt mode specific commands */
|
||||
#define DP_CMD_STATUS_UPDATE VDO_CMD_VENDOR(0)
|
||||
#define DP_CMD_CONFIGURE VDO_CMD_VENDOR(1)
|
||||
|
||||
/* DisplayPort Capabilities VDO bits (returned with Discover Modes) */
|
||||
#define DP_CAP_CAPABILITY(_cap_) ((_cap_) & 3)
|
||||
#define DP_CAP_UFP_D 1
|
||||
#define DP_CAP_DFP_D 2
|
||||
#define DP_CAP_DFP_D_AND_UFP_D 3
|
||||
#define DP_CAP_DP_SIGNALLING(_cap_) FIELD_GET(GENMASK(5, 2), _cap_)
|
||||
#define DP_CAP_SIGNALLING_HBR3 1
|
||||
#define DP_CAP_SIGNALLING_UHBR10 2
|
||||
#define DP_CAP_SIGNALLING_UHBR20 3
|
||||
#define DP_CAP_RECEPTACLE BIT(6)
|
||||
#define DP_CAP_USB BIT(7)
|
||||
#define DP_CAP_DFP_D_PIN_ASSIGN(_cap_) FIELD_GET(GENMASK(15, 8), _cap_)
|
||||
#define DP_CAP_UFP_D_PIN_ASSIGN(_cap_) FIELD_GET(GENMASK(23, 16), _cap_)
|
||||
/* Get pin assignment taking plug & receptacle into consideration */
|
||||
#define DP_CAP_PIN_ASSIGN_UFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \
|
||||
DP_CAP_UFP_D_PIN_ASSIGN(_cap_) : DP_CAP_DFP_D_PIN_ASSIGN(_cap_))
|
||||
#define DP_CAP_PIN_ASSIGN_DFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \
|
||||
DP_CAP_DFP_D_PIN_ASSIGN(_cap_) : DP_CAP_UFP_D_PIN_ASSIGN(_cap_))
|
||||
#define DP_CAP_UHBR_13_5_SUPPORT BIT(26)
|
||||
#define DP_CAP_CABLE_TYPE(_cap_) FIELD_GET(GENMASK(29, 28), _cap_)
|
||||
#define DP_CAP_CABLE_TYPE_PASSIVE 0
|
||||
#define DP_CAP_CABLE_TYPE_RE_TIMER 1
|
||||
#define DP_CAP_CABLE_TYPE_RE_DRIVER 2
|
||||
#define DP_CAP_CABLE_TYPE_OPTICAL 3
|
||||
#define DP_CAP_DPAM_VERSION BIT(30)
|
||||
|
||||
/* DisplayPort Status Update VDO bits */
|
||||
#define DP_STATUS_CONNECTION(_status_) ((_status_) & 3)
|
||||
#define DP_STATUS_CON_DISABLED 0
|
||||
#define DP_STATUS_CON_DFP_D 1
|
||||
#define DP_STATUS_CON_UFP_D 2
|
||||
#define DP_STATUS_CON_BOTH 3
|
||||
#define DP_STATUS_POWER_LOW BIT(2)
|
||||
#define DP_STATUS_ENABLED BIT(3)
|
||||
#define DP_STATUS_PREFER_MULTI_FUNC BIT(4)
|
||||
#define DP_STATUS_SWITCH_TO_USB BIT(5)
|
||||
#define DP_STATUS_EXIT_DP_MODE BIT(6)
|
||||
#define DP_STATUS_HPD_STATE BIT(7) /* 0 = HPD_Low, 1 = HPD_High */
|
||||
#define DP_STATUS_IRQ_HPD BIT(8)
|
||||
|
||||
/* DisplayPort Configurations VDO bits */
|
||||
#define DP_CONF_CURRENTLY(_conf_) ((_conf_) & 3)
|
||||
#define DP_CONF_UFP_U_AS_DFP_D BIT(0)
|
||||
#define DP_CONF_UFP_U_AS_UFP_D BIT(1)
|
||||
#define DP_CONF_SIGNALLING_MASK GENMASK(5, 2)
|
||||
#define DP_CONF_SIGNALLING_SHIFT 2
|
||||
#define DP_CONF_SIGNALLING_HBR3 1
|
||||
#define DP_CONF_SIGNALLING_UHBR10 2
|
||||
#define DP_CONF_SIGNALLING_UHBR20 3
|
||||
#define DP_CONF_PIN_ASSIGNEMENT_SHIFT 8
|
||||
#define DP_CONF_PIN_ASSIGNEMENT_MASK GENMASK(15, 8)
|
||||
|
||||
/* Helper for setting/getting the pin assignment value to the configuration */
|
||||
#define DP_CONF_SET_PIN_ASSIGN(_a_) ((_a_) << 8)
|
||||
#define DP_CONF_GET_PIN_ASSIGN(_conf_) FIELD_GET(GENMASK(15, 8), _conf_)
|
||||
#define DP_CONF_UHBR13_5_SUPPORT BIT(26)
|
||||
#define DP_CONF_CABLE_TYPE_MASK GENMASK(29, 28)
|
||||
#define DP_CONF_CABLE_TYPE_SHIFT 28
|
||||
#define DP_CONF_CABLE_TYPE_PASSIVE 0
|
||||
#define DP_CONF_CABLE_TYPE_RE_TIMER 1
|
||||
#define DP_CONF_CABLE_TYPE_RE_DRIVER 2
|
||||
#define DP_CONF_CABLE_TYPE_OPTICAL 3
|
||||
#define DP_CONF_DPAM_VERSION BIT(30)
|
||||
|
||||
#endif /* __USB_TYPEC_DP_H */
|
||||
@@ -0,0 +1,144 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#ifndef __USB_TYPEC_MUX
|
||||
#define __USB_TYPEC_MUX
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/usb/typec.h>
|
||||
|
||||
struct device;
|
||||
struct typec_mux;
|
||||
struct typec_mux_dev;
|
||||
struct typec_switch;
|
||||
struct typec_switch_dev;
|
||||
struct typec_altmode;
|
||||
struct fwnode_handle;
|
||||
|
||||
typedef int (*typec_switch_set_fn_t)(struct typec_switch_dev *sw,
|
||||
enum typec_orientation orientation);
|
||||
|
||||
struct typec_switch_desc {
|
||||
struct fwnode_handle *fwnode;
|
||||
typec_switch_set_fn_t set;
|
||||
const char *name;
|
||||
void *drvdata;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_TYPEC)
|
||||
|
||||
struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode);
|
||||
void typec_switch_put(struct typec_switch *sw);
|
||||
int typec_switch_set(struct typec_switch *sw,
|
||||
enum typec_orientation orientation);
|
||||
|
||||
struct typec_switch_dev *
|
||||
typec_switch_register(struct device *parent,
|
||||
const struct typec_switch_desc *desc);
|
||||
void typec_switch_unregister(struct typec_switch_dev *sw);
|
||||
|
||||
void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data);
|
||||
void *typec_switch_get_drvdata(struct typec_switch_dev *sw);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct typec_switch *
|
||||
fwnode_typec_switch_get(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void typec_switch_put(struct typec_switch *sw) {}
|
||||
|
||||
static inline int typec_switch_set(struct typec_switch *sw,
|
||||
enum typec_orientation orientation)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct typec_switch_dev *
|
||||
typec_switch_register(struct device *parent,
|
||||
const struct typec_switch_desc *desc)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void typec_switch_unregister(struct typec_switch_dev *sw) {}
|
||||
|
||||
static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {}
|
||||
static inline void *typec_switch_get_drvdata(struct typec_switch_dev *sw)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TYPEC */
|
||||
|
||||
static inline struct typec_switch *typec_switch_get(struct device *dev)
|
||||
{
|
||||
return fwnode_typec_switch_get(dev_fwnode(dev));
|
||||
}
|
||||
|
||||
struct typec_mux_state {
|
||||
struct typec_altmode *alt;
|
||||
unsigned long mode;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef int (*typec_mux_set_fn_t)(struct typec_mux_dev *mux,
|
||||
struct typec_mux_state *state);
|
||||
|
||||
struct typec_mux_desc {
|
||||
struct fwnode_handle *fwnode;
|
||||
typec_mux_set_fn_t set;
|
||||
const char *name;
|
||||
void *drvdata;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_TYPEC)
|
||||
|
||||
struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode);
|
||||
void typec_mux_put(struct typec_mux *mux);
|
||||
int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state);
|
||||
|
||||
struct typec_mux_dev *
|
||||
typec_mux_register(struct device *parent, const struct typec_mux_desc *desc);
|
||||
void typec_mux_unregister(struct typec_mux_dev *mux);
|
||||
|
||||
void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data);
|
||||
void *typec_mux_get_drvdata(struct typec_mux_dev *mux);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void typec_mux_put(struct typec_mux *mux) {}
|
||||
|
||||
static inline int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct typec_mux_dev *
|
||||
typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
static inline void typec_mux_unregister(struct typec_mux_dev *mux) {}
|
||||
|
||||
static inline void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data) {}
|
||||
static inline void *typec_mux_get_drvdata(struct typec_mux_dev *mux)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TYPEC */
|
||||
|
||||
static inline struct typec_mux *typec_mux_get(struct device *dev)
|
||||
{
|
||||
return fwnode_typec_mux_get(dev_fwnode(dev));
|
||||
}
|
||||
|
||||
#endif /* __USB_TYPEC_MUX */
|
||||
@@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __USB_TYPEC_RETIMER
|
||||
#define __USB_TYPEC_RETIMER
|
||||
|
||||
#include <linux/property.h>
|
||||
#include <linux/usb/typec.h>
|
||||
|
||||
struct device;
|
||||
struct typec_retimer;
|
||||
struct typec_altmode;
|
||||
struct fwnode_handle;
|
||||
|
||||
struct typec_retimer_state {
|
||||
struct typec_altmode *alt;
|
||||
unsigned long mode;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef int (*typec_retimer_set_fn_t)(struct typec_retimer *retimer,
|
||||
struct typec_retimer_state *state);
|
||||
|
||||
struct typec_retimer_desc {
|
||||
struct fwnode_handle *fwnode;
|
||||
typec_retimer_set_fn_t set;
|
||||
const char *name;
|
||||
void *drvdata;
|
||||
};
|
||||
|
||||
struct typec_retimer *fwnode_typec_retimer_get(struct fwnode_handle *fwnode);
|
||||
void typec_retimer_put(struct typec_retimer *retimer);
|
||||
int typec_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state);
|
||||
|
||||
static inline struct typec_retimer *typec_retimer_get(struct device *dev)
|
||||
{
|
||||
return fwnode_typec_retimer_get(dev_fwnode(dev));
|
||||
}
|
||||
|
||||
struct typec_retimer *
|
||||
typec_retimer_register(struct device *parent, const struct typec_retimer_desc *desc);
|
||||
void typec_retimer_unregister(struct typec_retimer *retimer);
|
||||
|
||||
void *typec_retimer_get_drvdata(struct typec_retimer *retimer);
|
||||
|
||||
#endif /* __USB_TYPEC_RETIMER */
|
||||
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __USB_TYPEC_TBT_H
|
||||
#define __USB_TYPEC_TBT_H
|
||||
|
||||
#include <linux/usb/typec_altmode.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#define USB_TYPEC_VENDOR_INTEL 0x8087
|
||||
/* Alias for convenience */
|
||||
#define USB_TYPEC_TBT_SID USB_TYPEC_VENDOR_INTEL
|
||||
|
||||
/* Connector state for Thunderbolt3 */
|
||||
#define TYPEC_TBT_MODE TYPEC_STATE_MODAL
|
||||
|
||||
/**
|
||||
* struct typec_thunderbolt_data - Thundebolt3 Alt Mode specific data
|
||||
* @device_mode: Device Discover Mode VDO
|
||||
* @cable_mode: Cable Discover Mode VDO
|
||||
* @enter_vdo: Enter Mode VDO
|
||||
*/
|
||||
struct typec_thunderbolt_data {
|
||||
u32 device_mode;
|
||||
u32 cable_mode;
|
||||
u32 enter_vdo;
|
||||
};
|
||||
|
||||
/* TBT3 Device Discover Mode VDO bits */
|
||||
#define TBT_MODE BIT(0)
|
||||
#define TBT_ADAPTER(_vdo_) FIELD_GET(BIT(16), _vdo_)
|
||||
#define TBT_ADAPTER_LEGACY 0
|
||||
#define TBT_ADAPTER_TBT3 1
|
||||
#define TBT_INTEL_SPECIFIC_B0 BIT(26)
|
||||
#define TBT_VENDOR_SPECIFIC_B0 BIT(30)
|
||||
#define TBT_VENDOR_SPECIFIC_B1 BIT(31)
|
||||
|
||||
#define TBT_SET_ADAPTER(a) (((a) & 1) << 16)
|
||||
|
||||
/* TBT3 Cable Discover Mode VDO bits */
|
||||
#define TBT_CABLE_SPEED(_vdo_) FIELD_GET(GENMASK(18, 16), _vdo_)
|
||||
#define TBT_CABLE_USB3_GEN1 1
|
||||
#define TBT_CABLE_USB3_PASSIVE 2
|
||||
#define TBT_CABLE_10_AND_20GBPS 3
|
||||
#define TBT_CABLE_ROUNDED_SUPPORT(_vdo_) FIELD_GET(GENMASK(20, 19), _vdo_)
|
||||
|
||||
#define TBT_GEN3_NON_ROUNDED 0
|
||||
#define TBT_GEN3_GEN4_ROUNDED_NON_ROUNDED 1
|
||||
#define TBT_CABLE_ROUNDED BIT(19)
|
||||
#define TBT_CABLE_OPTICAL BIT(21)
|
||||
#define TBT_CABLE_RETIMER BIT(22)
|
||||
#define TBT_CABLE_LINK_TRAINING BIT(23)
|
||||
#define TBT_CABLE_ACTIVE_PASSIVE BIT(25)
|
||||
|
||||
#define TBT_SET_CABLE_SPEED(_s_) (((_s_) & GENMASK(2, 0)) << 16)
|
||||
#define TBT_SET_CABLE_ROUNDED(_g_) (((_g_) & GENMASK(1, 0)) << 19)
|
||||
|
||||
/* TBT3 Device Enter Mode VDO bits */
|
||||
#define TBT_ENTER_MODE_CABLE_SPEED(s) TBT_SET_CABLE_SPEED(s)
|
||||
#define TBT_ENTER_MODE_UNI_DIR_LSRX BIT(23)
|
||||
#define TBT_ENTER_MODE_ACTIVE_CABLE BIT(24)
|
||||
|
||||
#endif /* __USB_TYPEC_TBT_H */
|
||||
@@ -0,0 +1,110 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __USB_UAS_H__
|
||||
#define __USB_UAS_H__
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
||||
/* Common header for all IUs */
|
||||
struct iu {
|
||||
__u8 iu_id;
|
||||
__u8 rsvd1;
|
||||
__be16 tag;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
enum {
|
||||
IU_ID_COMMAND = 0x01,
|
||||
IU_ID_STATUS = 0x03,
|
||||
IU_ID_RESPONSE = 0x04,
|
||||
IU_ID_TASK_MGMT = 0x05,
|
||||
IU_ID_READ_READY = 0x06,
|
||||
IU_ID_WRITE_READY = 0x07,
|
||||
};
|
||||
|
||||
enum {
|
||||
TMF_ABORT_TASK = 0x01,
|
||||
TMF_ABORT_TASK_SET = 0x02,
|
||||
TMF_CLEAR_TASK_SET = 0x04,
|
||||
TMF_LOGICAL_UNIT_RESET = 0x08,
|
||||
TMF_I_T_NEXUS_RESET = 0x10,
|
||||
TMF_CLEAR_ACA = 0x40,
|
||||
TMF_QUERY_TASK = 0x80,
|
||||
TMF_QUERY_TASK_SET = 0x81,
|
||||
TMF_QUERY_ASYNC_EVENT = 0x82,
|
||||
};
|
||||
|
||||
enum {
|
||||
RC_TMF_COMPLETE = 0x00,
|
||||
RC_INVALID_INFO_UNIT = 0x02,
|
||||
RC_TMF_NOT_SUPPORTED = 0x04,
|
||||
RC_TMF_FAILED = 0x05,
|
||||
RC_TMF_SUCCEEDED = 0x08,
|
||||
RC_INCORRECT_LUN = 0x09,
|
||||
RC_OVERLAPPED_TAG = 0x0a,
|
||||
};
|
||||
|
||||
struct command_iu {
|
||||
__u8 iu_id;
|
||||
__u8 rsvd1;
|
||||
__be16 tag;
|
||||
__u8 prio_attr;
|
||||
__u8 rsvd5;
|
||||
__u8 len;
|
||||
__u8 rsvd7;
|
||||
struct scsi_lun lun;
|
||||
__u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct task_mgmt_iu {
|
||||
__u8 iu_id;
|
||||
__u8 rsvd1;
|
||||
__be16 tag;
|
||||
__u8 function;
|
||||
__u8 rsvd2;
|
||||
__be16 task_tag;
|
||||
struct scsi_lun lun;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/*
|
||||
* Also used for the Read Ready and Write Ready IUs since they have the
|
||||
* same first four bytes
|
||||
*/
|
||||
struct sense_iu {
|
||||
__u8 iu_id;
|
||||
__u8 rsvd1;
|
||||
__be16 tag;
|
||||
__be16 status_qual;
|
||||
__u8 status;
|
||||
__u8 rsvd7[7];
|
||||
__be16 len;
|
||||
__u8 sense[SCSI_SENSE_BUFFERSIZE];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct response_iu {
|
||||
__u8 iu_id;
|
||||
__u8 rsvd1;
|
||||
__be16 tag;
|
||||
__u8 add_response_info[3];
|
||||
__u8 response_code;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct usb_pipe_usage_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bPipeID;
|
||||
__u8 Reserved;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
enum {
|
||||
CMD_PIPE_ID = 1,
|
||||
STATUS_PIPE_ID = 2,
|
||||
DATA_IN_PIPE_ID = 3,
|
||||
DATA_OUT_PIPE_ID = 4,
|
||||
|
||||
UAS_SIMPLE_TAG = 0,
|
||||
UAS_HEAD_TAG = 1,
|
||||
UAS_ORDERED_TAG = 2,
|
||||
UAS_ACA = 4,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ulpi.h -- ULPI defines and function prorotypes
|
||||
*
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_ULPI_H
|
||||
#define __LINUX_USB_ULPI_H
|
||||
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/ulpi/regs.h>
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* ULPI Flags
|
||||
*/
|
||||
#define ULPI_OTG_ID_PULLUP (1 << 0)
|
||||
#define ULPI_OTG_DP_PULLDOWN_DIS (1 << 1)
|
||||
#define ULPI_OTG_DM_PULLDOWN_DIS (1 << 2)
|
||||
#define ULPI_OTG_DISCHRGVBUS (1 << 3)
|
||||
#define ULPI_OTG_CHRGVBUS (1 << 4)
|
||||
#define ULPI_OTG_DRVVBUS (1 << 5)
|
||||
#define ULPI_OTG_DRVVBUS_EXT (1 << 6)
|
||||
#define ULPI_OTG_EXTVBUSIND (1 << 7)
|
||||
|
||||
#define ULPI_IC_6PIN_SERIAL (1 << 8)
|
||||
#define ULPI_IC_3PIN_SERIAL (1 << 9)
|
||||
#define ULPI_IC_CARKIT (1 << 10)
|
||||
#define ULPI_IC_CLKSUSPM (1 << 11)
|
||||
#define ULPI_IC_AUTORESUME (1 << 12)
|
||||
#define ULPI_IC_EXTVBUS_INDINV (1 << 13)
|
||||
#define ULPI_IC_IND_PASSTHRU (1 << 14)
|
||||
#define ULPI_IC_PROTECT_DIS (1 << 15)
|
||||
|
||||
#define ULPI_FC_HS (1 << 16)
|
||||
#define ULPI_FC_FS (1 << 17)
|
||||
#define ULPI_FC_LS (1 << 18)
|
||||
#define ULPI_FC_FS4LS (1 << 19)
|
||||
#define ULPI_FC_TERMSEL (1 << 20)
|
||||
#define ULPI_FC_OP_NORM (1 << 21)
|
||||
#define ULPI_FC_OP_NODRV (1 << 22)
|
||||
#define ULPI_FC_OP_DIS_NRZI (1 << 23)
|
||||
#define ULPI_FC_OP_NSYNC_NEOP (1 << 24)
|
||||
#define ULPI_FC_RST (1 << 25)
|
||||
#define ULPI_FC_SUSPM (1 << 26)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_ULPI)
|
||||
struct usb_phy *devm_otg_ulpi_create(struct device *dev,
|
||||
struct usb_phy_io_ops *ops,
|
||||
unsigned int flags);
|
||||
#else
|
||||
static inline struct usb_phy *devm_otg_ulpi_create(struct device *dev,
|
||||
struct usb_phy_io_ops *ops,
|
||||
unsigned int flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_ULPI_VIEWPORT
|
||||
/* access ops for controllers with a viewport register */
|
||||
extern struct usb_phy_io_ops ulpi_viewport_access_ops;
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_ULPI_H */
|
||||
@@ -0,0 +1,208 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* USB 338x super/high/full speed USB device controller.
|
||||
* Unlike many such controllers, this one talks PCI.
|
||||
*
|
||||
* Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
|
||||
* Copyright (C) 2003 David Brownell
|
||||
* Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_USB338X_H
|
||||
#define __LINUX_USB_USB338X_H
|
||||
|
||||
#include <linux/usb/net2280.h>
|
||||
|
||||
/*
|
||||
* Extra defined bits for net2280 registers
|
||||
*/
|
||||
#define SCRATCH 0x0b
|
||||
|
||||
#define DEFECT7374_FSM_FIELD 28
|
||||
#define SUPER_SPEED 8
|
||||
#define DMA_REQUEST_OUTSTANDING 5
|
||||
#define DMA_PAUSE_DONE_INTERRUPT 26
|
||||
#define SET_ISOCHRONOUS_DELAY 24
|
||||
#define SET_SEL 22
|
||||
#define SUPER_SPEED_MODE 8
|
||||
|
||||
/*ep_cfg*/
|
||||
#define MAX_BURST_SIZE 24
|
||||
#define EP_FIFO_BYTE_COUNT 16
|
||||
#define IN_ENDPOINT_ENABLE 14
|
||||
#define IN_ENDPOINT_TYPE 12
|
||||
#define OUT_ENDPOINT_ENABLE 10
|
||||
#define OUT_ENDPOINT_TYPE 8
|
||||
#define USB3380_EP_CFG_MASK_IN ((0x3 << IN_ENDPOINT_TYPE) | \
|
||||
BIT(IN_ENDPOINT_ENABLE))
|
||||
#define USB3380_EP_CFG_MASK_OUT ((0x3 << OUT_ENDPOINT_TYPE) | \
|
||||
BIT(OUT_ENDPOINT_ENABLE))
|
||||
|
||||
struct usb338x_usb_ext_regs {
|
||||
u32 usbclass;
|
||||
#define DEVICE_PROTOCOL 16
|
||||
#define DEVICE_SUB_CLASS 8
|
||||
#define DEVICE_CLASS 0
|
||||
u32 ss_sel;
|
||||
#define U2_SYSTEM_EXIT_LATENCY 8
|
||||
#define U1_SYSTEM_EXIT_LATENCY 0
|
||||
u32 ss_del;
|
||||
#define U2_DEVICE_EXIT_LATENCY 8
|
||||
#define U1_DEVICE_EXIT_LATENCY 0
|
||||
u32 usb2lpm;
|
||||
#define USB_L1_LPM_HIRD 2
|
||||
#define USB_L1_LPM_REMOTE_WAKE 1
|
||||
#define USB_L1_LPM_SUPPORT 0
|
||||
u32 usb3belt;
|
||||
#define BELT_MULTIPLIER 10
|
||||
#define BEST_EFFORT_LATENCY_TOLERANCE 0
|
||||
u32 usbctl2;
|
||||
#define LTM_ENABLE 7
|
||||
#define U2_ENABLE 6
|
||||
#define U1_ENABLE 5
|
||||
#define FUNCTION_SUSPEND 4
|
||||
#define USB3_CORE_ENABLE 3
|
||||
#define USB2_CORE_ENABLE 2
|
||||
#define SERIAL_NUMBER_STRING_ENABLE 0
|
||||
u32 in_timeout;
|
||||
#define GPEP3_TIMEOUT 19
|
||||
#define GPEP2_TIMEOUT 18
|
||||
#define GPEP1_TIMEOUT 17
|
||||
#define GPEP0_TIMEOUT 16
|
||||
#define GPEP3_TIMEOUT_VALUE 13
|
||||
#define GPEP3_TIMEOUT_ENABLE 12
|
||||
#define GPEP2_TIMEOUT_VALUE 9
|
||||
#define GPEP2_TIMEOUT_ENABLE 8
|
||||
#define GPEP1_TIMEOUT_VALUE 5
|
||||
#define GPEP1_TIMEOUT_ENABLE 4
|
||||
#define GPEP0_TIMEOUT_VALUE 1
|
||||
#define GPEP0_TIMEOUT_ENABLE 0
|
||||
u32 isodelay;
|
||||
#define ISOCHRONOUS_DELAY 0
|
||||
} __packed;
|
||||
|
||||
struct usb338x_fifo_regs {
|
||||
/* offset 0x0500, 0x0520, 0x0540, 0x0560, 0x0580 */
|
||||
u32 ep_fifo_size_base;
|
||||
#define IN_FIFO_BASE_ADDRESS 22
|
||||
#define IN_FIFO_SIZE 16
|
||||
#define OUT_FIFO_BASE_ADDRESS 6
|
||||
#define OUT_FIFO_SIZE 0
|
||||
u32 ep_fifo_out_wrptr;
|
||||
u32 ep_fifo_out_rdptr;
|
||||
u32 ep_fifo_in_wrptr;
|
||||
u32 ep_fifo_in_rdptr;
|
||||
u32 unused[3];
|
||||
} __packed;
|
||||
|
||||
|
||||
/* Link layer */
|
||||
struct usb338x_ll_regs {
|
||||
/* offset 0x700 */
|
||||
u32 ll_ltssm_ctrl1;
|
||||
u32 ll_ltssm_ctrl2;
|
||||
u32 ll_ltssm_ctrl3;
|
||||
u32 unused1;
|
||||
|
||||
/* 0x710 */
|
||||
u32 unused2;
|
||||
u32 ll_general_ctrl0;
|
||||
u32 ll_general_ctrl1;
|
||||
#define PM_U3_AUTO_EXIT 29
|
||||
#define PM_U2_AUTO_EXIT 28
|
||||
#define PM_U1_AUTO_EXIT 27
|
||||
#define PM_FORCE_U2_ENTRY 26
|
||||
#define PM_FORCE_U1_ENTRY 25
|
||||
#define PM_LGO_COLLISION_SEND_LAU 24
|
||||
#define PM_DIR_LINK_REJECT 23
|
||||
#define PM_FORCE_LINK_ACCEPT 22
|
||||
#define PM_DIR_ENTRY_U3 20
|
||||
#define PM_DIR_ENTRY_U2 19
|
||||
#define PM_DIR_ENTRY_U1 18
|
||||
#define PM_U2_ENABLE 17
|
||||
#define PM_U1_ENABLE 16
|
||||
#define SKP_THRESHOLD_ADJUST_FMW 8
|
||||
#define RESEND_DPP_ON_LRTY_FMW 7
|
||||
#define DL_BIT_VALUE_FMW 6
|
||||
#define FORCE_DL_BIT 5
|
||||
u32 ll_general_ctrl2;
|
||||
#define SELECT_INVERT_LANE_POLARITY 7
|
||||
#define FORCE_INVERT_LANE_POLARITY 6
|
||||
|
||||
/* 0x720 */
|
||||
u32 ll_general_ctrl3;
|
||||
u32 ll_general_ctrl4;
|
||||
u32 ll_error_gen;
|
||||
u32 unused3;
|
||||
|
||||
/* 0x730 */
|
||||
u32 unused4[4];
|
||||
|
||||
/* 0x740 */
|
||||
u32 unused5[2];
|
||||
u32 ll_lfps_5;
|
||||
#define TIMER_LFPS_6US 16
|
||||
u32 ll_lfps_6;
|
||||
#define TIMER_LFPS_80US 0
|
||||
|
||||
/* 0x750 */
|
||||
u32 unused6[8];
|
||||
|
||||
/* 0x770 */
|
||||
u32 unused7[3];
|
||||
u32 ll_tsn_counters_2;
|
||||
#define HOT_TX_NORESET_TS2 24
|
||||
|
||||
/* 0x780 */
|
||||
u32 ll_tsn_counters_3;
|
||||
#define HOT_RX_RESET_TS2 0
|
||||
u32 unused8[3];
|
||||
|
||||
/* 0x790 */
|
||||
u32 unused9;
|
||||
u32 ll_lfps_timers_2;
|
||||
#define LFPS_TIMERS_2_WORKAROUND_VALUE 0x084d
|
||||
u32 unused10;
|
||||
u32 ll_tsn_chicken_bit;
|
||||
#define RECOVERY_IDLE_TO_RECOVER_FMW 3
|
||||
} __packed;
|
||||
|
||||
/* protocol layer */
|
||||
struct usb338x_pl_regs {
|
||||
/* offset 0x800 */
|
||||
u32 pl_reg_1;
|
||||
u32 pl_reg_2;
|
||||
u32 pl_reg_3;
|
||||
u32 pl_reg_4;
|
||||
u32 pl_ep_ctrl;
|
||||
/* Protocol Layer Endpoint Control*/
|
||||
#define PL_EP_CTRL 0x810
|
||||
#define ENDPOINT_SELECT 0
|
||||
/* [4:0] */
|
||||
#define EP_INITIALIZED 16
|
||||
#define SEQUENCE_NUMBER_RESET 17
|
||||
#define CLEAR_ACK_ERROR_CODE 20
|
||||
u32 pl_reg_6;
|
||||
u32 pl_reg_7;
|
||||
u32 pl_reg_8;
|
||||
u32 pl_ep_status_1;
|
||||
/* Protocol Layer Endpoint Status 1*/
|
||||
#define PL_EP_STATUS_1 0x820
|
||||
#define STATE 16
|
||||
#define ACK_GOOD_NORMAL 0x11
|
||||
#define ACK_GOOD_MORE_ACKS_TO_COME 0x16
|
||||
u32 pl_ep_status_2;
|
||||
u32 pl_ep_status_3;
|
||||
/* Protocol Layer Endpoint Status 3*/
|
||||
#define PL_EP_STATUS_3 0x828
|
||||
#define SEQUENCE_NUMBER 0
|
||||
u32 pl_ep_status_4;
|
||||
/* Protocol Layer Endpoint Status 4*/
|
||||
#define PL_EP_STATUS_4 0x82c
|
||||
u32 pl_ep_cfg_4;
|
||||
/* Protocol Layer Endpoint Configuration 4*/
|
||||
#define PL_EP_CFG_4 0x830
|
||||
#define NON_CTRL_IN_TOLERATE_BAD_DIR 6
|
||||
} __packed;
|
||||
|
||||
#endif /* __LINUX_USB_USB338X_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_USB_NOP_XCEIV_H
|
||||
#define __LINUX_USB_NOP_XCEIV_H
|
||||
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_NOP_USB_XCEIV)
|
||||
/* sometimes transceivers are accessed only through e.g. ULPI */
|
||||
extern struct platform_device *usb_phy_generic_register(void);
|
||||
extern void usb_phy_generic_unregister(struct platform_device *);
|
||||
#else
|
||||
static inline struct platform_device *usb_phy_generic_register(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void usb_phy_generic_unregister(struct platform_device *pdev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_USB_NOP_XCEIV_H */
|
||||
@@ -0,0 +1,177 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Intel Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_USBIO_H_
|
||||
#define _LINUX_USBIO_H_
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/***********************
|
||||
* USBIO Clients Names *
|
||||
***********************/
|
||||
#define USBIO_GPIO_CLIENT "usbio-gpio"
|
||||
#define USBIO_I2C_CLIENT "usbio-i2c"
|
||||
|
||||
/****************
|
||||
* USBIO quirks *
|
||||
****************/
|
||||
#define USBIO_QUIRK_BULK_MAXP_63 BIT(0) /* Force bulk endpoint maxp to 63 */
|
||||
#define USBIO_QUIRK_I2C_NO_INIT_ACK BIT(8) /* Do not ask for ack on I2C init */
|
||||
#define USBIO_QUIRK_I2C_MAX_RW_LEN_52 BIT(9) /* Set i2c-adapter max r/w len to 52 */
|
||||
#define USBIO_QUIRK_I2C_USE_CHUNK_LEN BIT(10) /* Send chunk-len for split xfers */
|
||||
#define USBIO_QUIRK_I2C_ALLOW_400KHZ BIT(11) /* Override desc, allowing 400 KHz */
|
||||
|
||||
/**************************
|
||||
* USBIO Type Definitions *
|
||||
**************************/
|
||||
|
||||
/* USBIO Packet Type */
|
||||
#define USBIO_PKTTYPE_CTRL 1
|
||||
#define USBIO_PKTTYPE_DBG 2
|
||||
#define USBIO_PKTTYPE_GPIO 3
|
||||
#define USBIO_PKTTYPE_I2C 4
|
||||
|
||||
/* USBIO Packet Header */
|
||||
struct usbio_packet_header {
|
||||
u8 type;
|
||||
u8 cmd;
|
||||
u8 flags;
|
||||
} __packed;
|
||||
|
||||
/* USBIO Control Transfer Packet */
|
||||
struct usbio_ctrl_packet {
|
||||
struct usbio_packet_header header;
|
||||
u8 len;
|
||||
u8 data[] __counted_by(len);
|
||||
} __packed;
|
||||
|
||||
/* USBIO Bulk Transfer Packet */
|
||||
struct usbio_bulk_packet {
|
||||
struct usbio_packet_header header;
|
||||
__le16 len;
|
||||
u8 data[] __counted_by(len);
|
||||
} __packed;
|
||||
|
||||
/* USBIO GPIO commands */
|
||||
enum usbio_gpio_cmd {
|
||||
USBIO_GPIOCMD_DEINIT,
|
||||
USBIO_GPIOCMD_INIT,
|
||||
USBIO_GPIOCMD_READ,
|
||||
USBIO_GPIOCMD_WRITE,
|
||||
USBIO_GPIOCMD_END
|
||||
};
|
||||
|
||||
/* USBIO GPIO config */
|
||||
enum usbio_gpio_pincfg {
|
||||
USBIO_GPIO_PINCFG_DEFAULT,
|
||||
USBIO_GPIO_PINCFG_PULLUP,
|
||||
USBIO_GPIO_PINCFG_PULLDOWN,
|
||||
USBIO_GPIO_PINCFG_PUSHPULL
|
||||
};
|
||||
|
||||
#define USBIO_GPIO_PINCFG_SHIFT 2
|
||||
#define USBIO_GPIO_PINCFG_MASK (0x3 << USBIO_GPIO_PINCFG_SHIFT)
|
||||
#define USBIO_GPIO_SET_PINCFG(pincfg) \
|
||||
(((pincfg) << USBIO_GPIO_PINCFG_SHIFT) & USBIO_GPIO_PINCFG_MASK)
|
||||
|
||||
enum usbio_gpio_pinmode {
|
||||
USBIO_GPIO_PINMOD_INVAL,
|
||||
USBIO_GPIO_PINMOD_INPUT,
|
||||
USBIO_GPIO_PINMOD_OUTPUT,
|
||||
USBIO_GPIO_PINMOD_MAXVAL
|
||||
};
|
||||
|
||||
#define USBIO_GPIO_PINMOD_MASK 0x3
|
||||
#define USBIO_GPIO_SET_PINMOD(pin) (pin & USBIO_GPIO_PINMOD_MASK)
|
||||
|
||||
/*************************
|
||||
* USBIO GPIO Controller *
|
||||
*************************/
|
||||
|
||||
#define USBIO_MAX_GPIOBANKS 5
|
||||
#define USBIO_GPIOSPERBANK 32
|
||||
|
||||
struct usbio_gpio_bank_desc {
|
||||
u8 id;
|
||||
u8 pins;
|
||||
__le32 bmap;
|
||||
} __packed;
|
||||
|
||||
struct usbio_gpio_init {
|
||||
u8 bankid;
|
||||
u8 config;
|
||||
u8 pincount;
|
||||
u8 pin;
|
||||
} __packed;
|
||||
|
||||
struct usbio_gpio_rw {
|
||||
u8 bankid;
|
||||
u8 pincount;
|
||||
u8 pin;
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
/* USBIO I2C commands */
|
||||
enum usbio_i2c_cmd {
|
||||
USBIO_I2CCMD_UNINIT,
|
||||
USBIO_I2CCMD_INIT,
|
||||
USBIO_I2CCMD_READ,
|
||||
USBIO_I2CCMD_WRITE,
|
||||
USBIO_I2CCMD_END
|
||||
};
|
||||
|
||||
/************************
|
||||
* USBIO I2C Controller *
|
||||
************************/
|
||||
|
||||
#define USBIO_MAX_I2CBUSES 5
|
||||
|
||||
#define USBIO_I2C_BUS_ADDR_CAP_10B BIT(3) /* 10bit address support */
|
||||
#define USBIO_I2C_BUS_MODE_CAP_MASK 0x3
|
||||
#define USBIO_I2C_BUS_MODE_CAP_SM 0 /* Standard Mode */
|
||||
#define USBIO_I2C_BUS_MODE_CAP_FM 1 /* Fast Mode */
|
||||
#define USBIO_I2C_BUS_MODE_CAP_FMP 2 /* Fast Mode+ */
|
||||
#define USBIO_I2C_BUS_MODE_CAP_HSM 3 /* High-Speed Mode */
|
||||
|
||||
struct usbio_i2c_bus_desc {
|
||||
u8 id;
|
||||
u8 caps;
|
||||
} __packed;
|
||||
|
||||
struct usbio_i2c_uninit {
|
||||
u8 busid;
|
||||
__le16 config;
|
||||
} __packed;
|
||||
|
||||
struct usbio_i2c_init {
|
||||
u8 busid;
|
||||
__le16 config;
|
||||
__le32 speed;
|
||||
} __packed;
|
||||
|
||||
struct usbio_i2c_rw {
|
||||
u8 busid;
|
||||
__le16 config;
|
||||
__le16 size;
|
||||
u8 data[] __counted_by(size);
|
||||
} __packed;
|
||||
|
||||
int usbio_control_msg(struct auxiliary_device *adev, u8 type, u8 cmd,
|
||||
const void *obuf, u16 obuf_len, void *ibuf, u16 ibuf_len);
|
||||
|
||||
int usbio_bulk_msg(struct auxiliary_device *adev, u8 type, u8 cmd, bool last,
|
||||
const void *obuf, u16 obuf_len, void *ibuf, u16 ibuf_len);
|
||||
|
||||
int usbio_acquire(struct auxiliary_device *adev);
|
||||
void usbio_release(struct auxiliary_device *adev);
|
||||
void usbio_get_txrxbuf_len(struct auxiliary_device *adev, u16 *txbuf_len, u16 *rxbuf_len);
|
||||
unsigned long usbio_get_quirks(struct auxiliary_device *adev);
|
||||
void usbio_acpi_bind(struct auxiliary_device *adev, const struct acpi_device_id *hids);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,305 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* USB Networking Link Interface
|
||||
*
|
||||
* Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
|
||||
* Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_USBNET_H
|
||||
#define __LINUX_USB_USBNET_H
|
||||
|
||||
#include <linux/mii.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
/* interface from usbnet core to each USB networking link we handle */
|
||||
struct usbnet {
|
||||
/* housekeeping */
|
||||
struct usb_device *udev;
|
||||
struct usb_interface *intf;
|
||||
const struct driver_info *driver_info;
|
||||
const char *driver_name;
|
||||
void *driver_priv;
|
||||
wait_queue_head_t wait;
|
||||
struct mutex phy_mutex;
|
||||
unsigned char suspend_count;
|
||||
unsigned char pkt_cnt, pkt_err;
|
||||
unsigned short rx_qlen, tx_qlen;
|
||||
unsigned can_dma_sg:1;
|
||||
|
||||
/* i/o info: pipes etc */
|
||||
unsigned in, out;
|
||||
struct usb_host_endpoint *status;
|
||||
unsigned maxpacket;
|
||||
struct timer_list delay;
|
||||
const char *padding_pkt;
|
||||
|
||||
/* protocol/interface state */
|
||||
struct net_device *net;
|
||||
int msg_enable;
|
||||
unsigned long data[5];
|
||||
u32 xid;
|
||||
u32 hard_mtu; /* count any extra framing */
|
||||
size_t rx_urb_size; /* size for rx urbs */
|
||||
struct mii_if_info mii;
|
||||
long rx_speed; /* If MII not used */
|
||||
long tx_speed; /* If MII not used */
|
||||
# define SPEED_UNSET -1
|
||||
|
||||
/* various kinds of pending driver work */
|
||||
struct sk_buff_head rxq;
|
||||
struct sk_buff_head txq;
|
||||
struct sk_buff_head done;
|
||||
struct sk_buff_head rxq_pause;
|
||||
struct urb *interrupt;
|
||||
unsigned interrupt_count;
|
||||
struct mutex interrupt_mutex;
|
||||
struct usb_anchor deferred;
|
||||
struct work_struct bh_work;
|
||||
spinlock_t bql_spinlock;
|
||||
|
||||
struct work_struct kevent;
|
||||
unsigned long flags;
|
||||
# define EVENT_TX_HALT 0
|
||||
# define EVENT_RX_HALT 1
|
||||
# define EVENT_RX_MEMORY 2
|
||||
# define EVENT_STS_SPLIT 3
|
||||
# define EVENT_LINK_RESET 4
|
||||
# define EVENT_RX_PAUSED 5
|
||||
# define EVENT_DEV_ASLEEP 6
|
||||
# define EVENT_DEV_OPEN 7
|
||||
# define EVENT_DEVICE_REPORT_IDLE 8
|
||||
# define EVENT_NO_RUNTIME_PM 9
|
||||
# define EVENT_RX_KILL 10
|
||||
# define EVENT_LINK_CHANGE 11
|
||||
# define EVENT_SET_RX_MODE 12
|
||||
# define EVENT_NO_IP_ALIGN 13
|
||||
# define EVENT_LINK_CARRIER_ON 14
|
||||
/* This one is special, as it indicates that the device is going away
|
||||
* there are cyclic dependencies between tasklet, timer and bh
|
||||
* that must be broken
|
||||
*/
|
||||
# define EVENT_UNPLUG 31
|
||||
};
|
||||
|
||||
static inline bool usbnet_going_away(struct usbnet *ubn)
|
||||
{
|
||||
return test_bit(EVENT_UNPLUG, &ubn->flags);
|
||||
}
|
||||
|
||||
static inline void usbnet_mark_going_away(struct usbnet *ubn)
|
||||
{
|
||||
set_bit(EVENT_UNPLUG, &ubn->flags);
|
||||
}
|
||||
|
||||
static inline struct usb_driver *driver_of(struct usb_interface *intf)
|
||||
{
|
||||
return to_usb_driver(intf->dev.driver);
|
||||
}
|
||||
|
||||
/* interface from the device/framing level "minidriver" to core */
|
||||
struct driver_info {
|
||||
char *description;
|
||||
|
||||
int flags;
|
||||
/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
|
||||
#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
|
||||
#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */
|
||||
#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */
|
||||
#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */
|
||||
|
||||
#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
|
||||
#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
|
||||
|
||||
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
|
||||
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
|
||||
#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */
|
||||
#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */
|
||||
#define FLAG_WWAN 0x0400 /* use "wwan%d" names */
|
||||
|
||||
#define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */
|
||||
|
||||
#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */
|
||||
|
||||
/*
|
||||
* Indicates to usbnet, that USB driver accumulates multiple IP packets.
|
||||
* Affects statistic (counters) and short packet handling.
|
||||
*/
|
||||
#define FLAG_MULTI_PACKET 0x2000
|
||||
#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
|
||||
#define FLAG_NOARP 0x8000 /* device can't do ARP */
|
||||
#define FLAG_NOMAXMTU 0x10000 /* allow max_mtu above hard_mtu */
|
||||
|
||||
/* init device ... can sleep, or cause probe() failure */
|
||||
int (*bind)(struct usbnet *, struct usb_interface *);
|
||||
|
||||
/* cleanup device ... can sleep, but can't fail */
|
||||
void (*unbind)(struct usbnet *, struct usb_interface *);
|
||||
|
||||
/* reset device ... can sleep */
|
||||
int (*reset)(struct usbnet *);
|
||||
|
||||
/* stop device ... can sleep */
|
||||
int (*stop)(struct usbnet *);
|
||||
|
||||
/* see if peer is connected ... can sleep */
|
||||
int (*check_connect)(struct usbnet *);
|
||||
|
||||
/* (dis)activate runtime power management */
|
||||
int (*manage_power)(struct usbnet *, int);
|
||||
|
||||
/* for status polling */
|
||||
void (*status)(struct usbnet *, struct urb *);
|
||||
|
||||
/* link reset handling, called from defer_kevent */
|
||||
int (*link_reset)(struct usbnet *);
|
||||
|
||||
/* fixup rx packet (strip framing) */
|
||||
int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
|
||||
|
||||
/* fixup tx packet (add framing) */
|
||||
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
|
||||
struct sk_buff *skb, gfp_t flags);
|
||||
|
||||
/* recover from timeout */
|
||||
void (*recover)(struct usbnet *dev);
|
||||
|
||||
/* early initialization code, can sleep. This is for minidrivers
|
||||
* having 'subminidrivers' that need to do extra initialization
|
||||
* right after minidriver have initialized hardware. */
|
||||
int (*early_init)(struct usbnet *dev);
|
||||
|
||||
/* called by minidriver when receiving indication */
|
||||
void (*indication)(struct usbnet *dev, void *ind, int indlen);
|
||||
|
||||
/* rx mode change (device changes address list filtering) */
|
||||
void (*set_rx_mode)(struct usbnet *dev);
|
||||
|
||||
/* for new devices, use the descriptor-reading code instead */
|
||||
int in; /* rx endpoint */
|
||||
int out; /* tx endpoint */
|
||||
|
||||
unsigned long data; /* Misc driver specific data */
|
||||
};
|
||||
|
||||
/* Minidrivers are just drivers using the "usbnet" core as a powerful
|
||||
* network-specific subroutine library ... that happens to do pretty
|
||||
* much everything except custom framing and chip-specific stuff.
|
||||
*/
|
||||
extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
|
||||
extern int usbnet_suspend(struct usb_interface *, pm_message_t);
|
||||
extern int usbnet_resume(struct usb_interface *);
|
||||
extern void usbnet_disconnect(struct usb_interface *);
|
||||
extern void usbnet_device_suggests_idle(struct usbnet *dev);
|
||||
|
||||
extern int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
u16 value, u16 index, void *data, u16 size);
|
||||
extern int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
u16 value, u16 index, const void *data, u16 size);
|
||||
extern int usbnet_read_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
u16 value, u16 index, void *data, u16 size);
|
||||
extern int usbnet_write_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
u16 value, u16 index, const void *data, u16 size);
|
||||
extern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
u16 value, u16 index, const void *data, u16 size);
|
||||
|
||||
/* Drivers that reuse some of the standard USB CDC infrastructure
|
||||
* (notably, using multiple interfaces according to the CDC
|
||||
* union descriptor) get some helper code.
|
||||
*/
|
||||
struct cdc_state {
|
||||
struct usb_cdc_header_desc *header;
|
||||
struct usb_cdc_union_desc *u;
|
||||
struct usb_cdc_ether_desc *ether;
|
||||
struct usb_interface *control;
|
||||
struct usb_interface *data;
|
||||
};
|
||||
|
||||
extern void usbnet_cdc_update_filter(struct usbnet *dev);
|
||||
extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
|
||||
extern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf);
|
||||
extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
|
||||
extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
|
||||
extern void usbnet_cdc_status(struct usbnet *, struct urb *);
|
||||
extern int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
|
||||
|
||||
/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
|
||||
#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
|
||||
|USB_CDC_PACKET_TYPE_ALL_MULTICAST \
|
||||
|USB_CDC_PACKET_TYPE_PROMISCUOUS \
|
||||
|USB_CDC_PACKET_TYPE_DIRECTED)
|
||||
|
||||
|
||||
/* we record the state for each of our queued skbs */
|
||||
enum skb_state {
|
||||
illegal = 0,
|
||||
tx_start, tx_done,
|
||||
rx_start, rx_done, rx_cleanup,
|
||||
unlink_start
|
||||
};
|
||||
|
||||
struct skb_data { /* skb->cb is one of these */
|
||||
struct urb *urb;
|
||||
struct usbnet *dev;
|
||||
enum skb_state state;
|
||||
long length;
|
||||
unsigned long packets;
|
||||
};
|
||||
|
||||
/* Drivers that set FLAG_MULTI_PACKET must call this in their
|
||||
* tx_fixup method before returning an skb.
|
||||
*/
|
||||
static inline void
|
||||
usbnet_set_skb_tx_stats(struct sk_buff *skb,
|
||||
unsigned long packets, long bytes_delta)
|
||||
{
|
||||
struct skb_data *entry = (struct skb_data *) skb->cb;
|
||||
|
||||
entry->packets = packets;
|
||||
entry->length = bytes_delta;
|
||||
}
|
||||
|
||||
extern int usbnet_open(struct net_device *net);
|
||||
extern int usbnet_stop(struct net_device *net);
|
||||
extern netdev_tx_t usbnet_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *net);
|
||||
extern void usbnet_tx_timeout(struct net_device *net, unsigned int txqueue);
|
||||
extern int usbnet_change_mtu(struct net_device *net, int new_mtu);
|
||||
|
||||
extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
|
||||
extern int usbnet_get_ethernet_addr(struct usbnet *, int);
|
||||
extern void usbnet_defer_kevent(struct usbnet *, int);
|
||||
extern void usbnet_skb_return(struct usbnet *, struct sk_buff *);
|
||||
extern void usbnet_unlink_rx_urbs(struct usbnet *);
|
||||
|
||||
extern void usbnet_pause_rx(struct usbnet *);
|
||||
extern void usbnet_resume_rx(struct usbnet *);
|
||||
extern void usbnet_purge_paused_rxq(struct usbnet *);
|
||||
|
||||
extern int usbnet_get_link_ksettings_mii(struct net_device *net,
|
||||
struct ethtool_link_ksettings *cmd);
|
||||
extern int usbnet_set_link_ksettings_mii(struct net_device *net,
|
||||
const struct ethtool_link_ksettings *cmd);
|
||||
extern int usbnet_get_link_ksettings_internal(struct net_device *net,
|
||||
struct ethtool_link_ksettings *cmd);
|
||||
extern u32 usbnet_get_link(struct net_device *net);
|
||||
extern u32 usbnet_get_msglevel(struct net_device *);
|
||||
extern void usbnet_set_msglevel(struct net_device *, u32);
|
||||
extern void usbnet_set_rx_mode(struct net_device *net);
|
||||
extern void usbnet_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
|
||||
extern int usbnet_mii_ioctl(struct net_device *net, struct ifreq *rq, int cmd);
|
||||
extern int usbnet_nway_reset(struct net_device *net);
|
||||
|
||||
extern int usbnet_manage_power(struct usbnet *, int);
|
||||
extern void usbnet_link_change(struct usbnet *, bool, bool);
|
||||
|
||||
extern int usbnet_status_start(struct usbnet *dev, gfp_t mem_flags);
|
||||
extern void usbnet_status_stop(struct usbnet *dev);
|
||||
|
||||
extern void usbnet_update_max_qlen(struct usbnet *dev);
|
||||
|
||||
#endif /* __LINUX_USB_USBNET_H */
|
||||
@@ -0,0 +1,200 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* v4l2 uvc internal API header
|
||||
*
|
||||
* Some commonly needed functions for uvc drivers
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_V4L2_UVC_H
|
||||
#define __LINUX_V4L2_UVC_H
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* GUIDs
|
||||
*
|
||||
* The GUID returned by lsusb can be converted to this format with the
|
||||
* following python snippet:
|
||||
*
|
||||
* import uuid
|
||||
* id = "{01234567-89ab-cdef-0123-456789abcdef}"
|
||||
* le = uuid.UUID(id).bytes_le
|
||||
* print("{" + ", ".join([f"0x{b:02x}" for b in le]) + "}")
|
||||
*/
|
||||
#define UVC_GUID_UVC_CAMERA \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
|
||||
#define UVC_GUID_UVC_OUTPUT \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
|
||||
#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
|
||||
#define UVC_GUID_UVC_PROCESSING \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}
|
||||
#define UVC_GUID_UVC_SELECTOR \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
|
||||
#define UVC_GUID_EXT_GPIO_CONTROLLER \
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03}
|
||||
#define UVC_GUID_CHROMEOS_XU \
|
||||
{0x24, 0xe9, 0xd7, 0x74, 0xc9, 0x49, 0x45, 0x4a, \
|
||||
0x98, 0xa3, 0xc8, 0x07, 0x7e, 0x05, 0x1c, 0xa3}
|
||||
#define UVC_GUID_MSXU_1_5 \
|
||||
{0xdc, 0x95, 0x3f, 0x0f, 0x32, 0x26, 0x4e, 0x4c, \
|
||||
0x92, 0xc9, 0xa0, 0x47, 0x82, 0xf4, 0x3b, 0xc8}
|
||||
|
||||
/* https://learn.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5#222-extension-unit-controls */
|
||||
#define UVC_MSXU_CONTROL_FOCUS 0x01
|
||||
#define UVC_MSXU_CONTROL_EXPOSURE 0x02
|
||||
#define UVC_MSXU_CONTROL_EVCOMPENSATION 0x03
|
||||
#define UVC_MSXU_CONTROL_WHITEBALANCE 0x04
|
||||
#define UVC_MSXU_CONTROL_FACE_AUTHENTICATION 0x06
|
||||
#define UVC_MSXU_CONTROL_CAMERA_EXTRINSICS 0x07
|
||||
#define UVC_MSXU_CONTROL_CAMERA_INTRINSICS 0x08
|
||||
#define UVC_MSXU_CONTROL_METADATA 0x09
|
||||
#define UVC_MSXU_CONTROL_IR_TORCH 0x0a
|
||||
#define UVC_MSXU_CONTROL_DIGITALWINDOW 0x0b
|
||||
#define UVC_MSXU_CONTROL_DIGITALWINDOW_CONFIG 0x0c
|
||||
#define UVC_MSXU_CONTROL_VIDEO_HDR 0x0d
|
||||
#define UVC_MSXU_CONTROL_FRAMERATE_THROTTLE 0x0e
|
||||
#define UVC_MSXU_CONTROL_FIELDOFVIEW2_CONFIG 0x0f
|
||||
#define UVC_MSXU_CONTROL_FIELDOFVIEW2 0x10
|
||||
|
||||
#define UVC_CROSXU_CONTROL_IQ_PROFILE 0x04
|
||||
|
||||
#define UVC_GUID_FORMAT_MJPEG \
|
||||
{ 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_YUY2 \
|
||||
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_YUY2_ISIGHT \
|
||||
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_NV12 \
|
||||
{ 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_YV12 \
|
||||
{ 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_I420 \
|
||||
{ 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_UYVY \
|
||||
{ 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y800 \
|
||||
{ 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y8 \
|
||||
{ 'Y', '8', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y10 \
|
||||
{ 'Y', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y12 \
|
||||
{ 'Y', '1', '2', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y16 \
|
||||
{ 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_BY8 \
|
||||
{ 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_BA81 \
|
||||
{ 'B', 'A', '8', '1', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_GBRG \
|
||||
{ 'G', 'B', 'R', 'G', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_GRBG \
|
||||
{ 'G', 'R', 'B', 'G', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_RGGB \
|
||||
{ 'R', 'G', 'G', 'B', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_BG16 \
|
||||
{ 'B', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_GB16 \
|
||||
{ 'G', 'B', '1', '6', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_RG16 \
|
||||
{ 'R', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_GR16 \
|
||||
{ 'G', 'R', '1', '6', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_RGBP \
|
||||
{ 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_BGR3 \
|
||||
{ 0x7d, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
|
||||
0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
|
||||
#define UVC_GUID_FORMAT_BGR4 \
|
||||
{ 0x7e, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
|
||||
0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
|
||||
#define UVC_GUID_FORMAT_M420 \
|
||||
{ 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_P010 \
|
||||
{ 'P', '0', '1', '0', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
|
||||
#define UVC_GUID_FORMAT_H264 \
|
||||
{ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_H265 \
|
||||
{ 'H', '2', '6', '5', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y8I \
|
||||
{ 'Y', '8', 'I', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y12I \
|
||||
{ 'Y', '1', '2', 'I', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Y16I \
|
||||
{ 'Y', '1', '6', 'I', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_Z16 \
|
||||
{ 'Z', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_RW10 \
|
||||
{ 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_INVZ \
|
||||
{ 'I', 'N', 'V', 'Z', 0x90, 0x2d, 0x58, 0x4a, \
|
||||
0x92, 0x0b, 0x77, 0x3f, 0x1f, 0x2c, 0x55, 0x6b}
|
||||
#define UVC_GUID_FORMAT_INZI \
|
||||
{ 'I', 'N', 'Z', 'I', 0x66, 0x1a, 0x42, 0xa2, \
|
||||
0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a}
|
||||
#define UVC_GUID_FORMAT_INVI \
|
||||
{ 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \
|
||||
0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f}
|
||||
#define UVC_GUID_FORMAT_CNF4 \
|
||||
{ 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
|
||||
#define UVC_GUID_FORMAT_D3DFMT_L8 \
|
||||
{0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
#define UVC_GUID_FORMAT_D3DFMT_R5G6B5 \
|
||||
{0x7b, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
|
||||
0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
|
||||
#define UVC_GUID_FORMAT_KSMEDIA_L8_IR \
|
||||
{0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
|
||||
#define UVC_GUID_FORMAT_HEVC \
|
||||
{ 'H', 'E', 'V', 'C', 0x00, 0x00, 0x10, 0x00, \
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
|
||||
struct uvc_format_desc {
|
||||
u8 guid[16];
|
||||
u32 fcc;
|
||||
};
|
||||
|
||||
const struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16]);
|
||||
|
||||
#endif /* __LINUX_V4L2_UVC_H */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* WebUSB descriptors and constants
|
||||
*
|
||||
* Copyright (C) 2023 Jó Ágila Bitsch <jgilab@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_WEBUSB_H
|
||||
#define __LINUX_USB_WEBUSB_H
|
||||
|
||||
#include "uapi/linux/usb/ch9.h"
|
||||
|
||||
/*
|
||||
* Little Endian PlatformCapablityUUID for WebUSB
|
||||
* 3408b638-09a9-47a0-8bfd-a0768815b665
|
||||
* to identify Platform Device Capability descriptors as referring to WebUSB.
|
||||
*/
|
||||
#define WEBUSB_UUID \
|
||||
GUID_INIT(0x3408b638, 0x09a9, 0x47a0, 0x8b, 0xfd, 0xa0, 0x76, 0x88, 0x15, 0xb6, 0x65)
|
||||
|
||||
/*
|
||||
* WebUSB Platform Capability data
|
||||
*
|
||||
* A device announces support for the
|
||||
* WebUSB command set by including the following Platform Descriptor Data in its
|
||||
* Binary Object Store associated with the WebUSB_UUID above.
|
||||
* See: https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
|
||||
*/
|
||||
struct usb_webusb_cap_data {
|
||||
__le16 bcdVersion;
|
||||
#define WEBUSB_VERSION_1_00 cpu_to_le16(0x0100) /* currently only version 1.00 is defined */
|
||||
u8 bVendorCode;
|
||||
u8 iLandingPage;
|
||||
#define WEBUSB_LANDING_PAGE_NOT_PRESENT 0
|
||||
#define WEBUSB_LANDING_PAGE_PRESENT 1 /* we chose the fixed index 1 for the URL descriptor */
|
||||
} __packed;
|
||||
|
||||
#define USB_WEBUSB_CAP_DATA_SIZE 4
|
||||
|
||||
/*
|
||||
* Get URL Request
|
||||
*
|
||||
* The request to fetch an URL is defined in https://wicg.github.io/webusb/#get-url as:
|
||||
* bmRequestType: (USB_DIR_IN | USB_TYPE_VENDOR) = 11000000B
|
||||
* bRequest: bVendorCode
|
||||
* wValue: iLandingPage
|
||||
* wIndex: GET_URL = 2
|
||||
* wLength: Descriptor Length (typically U8_MAX = 255)
|
||||
* Data: URL Descriptor
|
||||
*/
|
||||
#define WEBUSB_GET_URL 2
|
||||
|
||||
/*
|
||||
* This descriptor contains a single URL and is returned by the Get URL request.
|
||||
*
|
||||
* See: https://wicg.github.io/webusb/#url-descriptor
|
||||
*/
|
||||
struct webusb_url_descriptor {
|
||||
u8 bLength;
|
||||
#define WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH 3
|
||||
u8 bDescriptorType;
|
||||
#define WEBUSB_URL_DESCRIPTOR_TYPE 3
|
||||
u8 bScheme;
|
||||
#define WEBUSB_URL_SCHEME_HTTP 0
|
||||
#define WEBUSB_URL_SCHEME_HTTPS 1
|
||||
#define WEBUSB_URL_SCHEME_NONE 255
|
||||
u8 URL[U8_MAX - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Buffer size to hold the longest URL that can be in an URL descriptor
|
||||
*
|
||||
* The descriptor can be U8_MAX bytes long.
|
||||
* WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH bytes are used for a header.
|
||||
* Since the longest prefix that might be stripped is "https://", we may accommodate an additional
|
||||
* 8 bytes.
|
||||
*/
|
||||
#define WEBUSB_URL_RAW_MAX_LENGTH (U8_MAX - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + 8)
|
||||
|
||||
#endif /* __LINUX_USB_USBNET_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Standalone xHCI debug capability driver
|
||||
*
|
||||
* Copyright (C) 2016 Intel Corporation
|
||||
*
|
||||
* Author: Lu Baolu <baolu.lu@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_XHCI_DBGP_H
|
||||
#define __LINUX_XHCI_DBGP_H
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK_USB_XDBC
|
||||
int __init early_xdbc_parse_parameter(char *s, int keep_early);
|
||||
int __init early_xdbc_setup_hardware(void);
|
||||
void __init early_xdbc_register_console(void);
|
||||
#else
|
||||
static inline int __init early_xdbc_setup_hardware(void)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void __init early_xdbc_register_console(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_EARLY_PRINTK_USB_XDBC */
|
||||
#endif /* __LINUX_XHCI_DBGP_H */
|
||||
@@ -0,0 +1,111 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* xHCI host controller sideband support
|
||||
*
|
||||
* Copyright (c) 2023-2025, Intel Corporation.
|
||||
*
|
||||
* Author: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
*/
|
||||
#ifndef __LINUX_XHCI_SIDEBAND_H
|
||||
#define __LINUX_XHCI_SIDEBAND_H
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
#define EP_CTX_PER_DEV 31 /* FIXME defined twice, from xhci.h */
|
||||
|
||||
struct xhci_sideband;
|
||||
|
||||
enum xhci_sideband_type {
|
||||
XHCI_SIDEBAND_AUDIO,
|
||||
XHCI_SIDEBAND_VENDOR,
|
||||
};
|
||||
|
||||
enum xhci_sideband_notify_type {
|
||||
XHCI_SIDEBAND_XFER_RING_FREE,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct xhci_sideband_event - sideband event
|
||||
* @type: notifier type
|
||||
* @evt_data: event data
|
||||
*/
|
||||
struct xhci_sideband_event {
|
||||
enum xhci_sideband_notify_type type;
|
||||
void *evt_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct xhci_sideband - representation of a sideband accessed usb device.
|
||||
* @xhci: The xhci host controller the usb device is connected to
|
||||
* @vdev: the usb device accessed via sideband
|
||||
* @eps: array of endpoints controlled via sideband
|
||||
* @ir: event handling and buffer for sideband accessed device
|
||||
* @type: xHCI sideband type
|
||||
* @mutex: mutex for sideband operations
|
||||
* @intf: USB sideband client interface
|
||||
* @notify_client: callback for xHCI sideband sequences
|
||||
*
|
||||
* FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices.
|
||||
*/
|
||||
struct xhci_sideband {
|
||||
struct xhci_hcd *xhci;
|
||||
struct xhci_virt_device *vdev;
|
||||
struct xhci_virt_ep *eps[EP_CTX_PER_DEV];
|
||||
struct xhci_interrupter *ir;
|
||||
enum xhci_sideband_type type;
|
||||
|
||||
/* Synchronizing xHCI sideband operations with client drivers operations */
|
||||
struct mutex mutex;
|
||||
|
||||
struct usb_interface *intf;
|
||||
int (*notify_client)(struct usb_interface *intf,
|
||||
struct xhci_sideband_event *evt);
|
||||
};
|
||||
|
||||
struct xhci_sideband *
|
||||
xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type,
|
||||
int (*notify_client)(struct usb_interface *intf,
|
||||
struct xhci_sideband_event *evt));
|
||||
void
|
||||
xhci_sideband_unregister(struct xhci_sideband *sb);
|
||||
int
|
||||
xhci_sideband_add_endpoint(struct xhci_sideband *sb,
|
||||
struct usb_host_endpoint *host_ep);
|
||||
int
|
||||
xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
|
||||
struct usb_host_endpoint *host_ep);
|
||||
int
|
||||
xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
|
||||
struct usb_host_endpoint *host_ep);
|
||||
struct sg_table *
|
||||
xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
|
||||
struct usb_host_endpoint *host_ep);
|
||||
struct sg_table *
|
||||
xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
|
||||
bool xhci_sideband_check(struct usb_hcd *hcd);
|
||||
#else
|
||||
static inline bool xhci_sideband_check(struct usb_hcd *hcd)
|
||||
{ return false; }
|
||||
#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
|
||||
|
||||
int
|
||||
xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
|
||||
bool ip_autoclear, u32 imod_interval, int intr_num);
|
||||
void
|
||||
xhci_sideband_remove_interrupter(struct xhci_sideband *sb);
|
||||
int
|
||||
xhci_sideband_interrupter_id(struct xhci_sideband *sb);
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
|
||||
void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
|
||||
unsigned int ep_index);
|
||||
#else
|
||||
static inline void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
|
||||
unsigned int ep_index)
|
||||
{ }
|
||||
#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
|
||||
#endif /* __LINUX_XHCI_SIDEBAND_H */
|
||||
Reference in New Issue
Block a user