diff options
Diffstat (limited to 'include/linux/usb')
58 files changed, 9218 insertions, 0 deletions
diff --git a/include/linux/usb/association.h b/include/linux/usb/association.h new file mode 100644 index 000000000..0a4a18b3c --- /dev/null +++ b/include/linux/usb/association.h @@ -0,0 +1,150 @@ +/* + * Wireless USB - Cable Based Association + * + * Copyright (C) 2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + */ +#ifndef __LINUX_USB_ASSOCIATION_H +#define __LINUX_USB_ASSOCIATION_H + + +/* + * Association attributes + * + * Association Models Supplement to WUSB 1.0 T[3-1] + * + * Each field in the structures has it's ID, it's length and then the + * value. This is the actual definition of the field's ID and its + * length. + */ +struct wusb_am_attr { + __u8 id; + __u8 len; +}; + +/* Different fields defined by the spec */ +#define WUSB_AR_AssociationTypeId { .id = cpu_to_le16(0x0000), .len = cpu_to_le16(2) } +#define WUSB_AR_AssociationSubTypeId { .id = cpu_to_le16(0x0001), .len = cpu_to_le16(2) } +#define WUSB_AR_Length { .id = cpu_to_le16(0x0002), .len = cpu_to_le16(4) } +#define WUSB_AR_AssociationStatus { .id = cpu_to_le16(0x0004), .len = cpu_to_le16(4) } +#define WUSB_AR_LangID { .id = cpu_to_le16(0x0008), .len = cpu_to_le16(2) } +#define WUSB_AR_DeviceFriendlyName { .id = cpu_to_le16(0x000b), .len = cpu_to_le16(64) } /* max */ +#define WUSB_AR_HostFriendlyName { .id = cpu_to_le16(0x000c), .len = cpu_to_le16(64) } /* max */ +#define WUSB_AR_CHID { .id = cpu_to_le16(0x1000), .len = cpu_to_le16(16) } +#define WUSB_AR_CDID { .id = cpu_to_le16(0x1001), .len = cpu_to_le16(16) } +#define WUSB_AR_ConnectionContext { .id = cpu_to_le16(0x1002), .len = cpu_to_le16(48) } +#define WUSB_AR_BandGroups { .id = cpu_to_le16(0x1004), .len = cpu_to_le16(2) } + +/* CBAF Control Requests (AMS1.0[T4-1] */ +enum { + CBAF_REQ_GET_ASSOCIATION_INFORMATION = 0x01, + CBAF_REQ_GET_ASSOCIATION_REQUEST, + CBAF_REQ_SET_ASSOCIATION_RESPONSE +}; + +/* + * CBAF USB-interface defitions + * + * No altsettings, one optional interrupt endpoint. + */ +enum { + CBAF_IFACECLASS = 0xef, + CBAF_IFACESUBCLASS = 0x03, + CBAF_IFACEPROTOCOL = 0x01, +}; + +/* Association Information (AMS1.0[T4-3]) */ +struct wusb_cbaf_assoc_info { + __le16 Length; + __u8 NumAssociationRequests; + __le16 Flags; + __u8 AssociationRequestsArray[]; +} __attribute__((packed)); + +/* Association Request (AMS1.0[T4-4]) */ +struct wusb_cbaf_assoc_request { + __u8 AssociationDataIndex; + __u8 Reserved; + __le16 AssociationTypeId; + __le16 AssociationSubTypeId; + __le32 AssociationTypeInfoSize; +} __attribute__((packed)); + +enum { + AR_TYPE_WUSB = 0x0001, + AR_TYPE_WUSB_RETRIEVE_HOST_INFO = 0x0000, + AR_TYPE_WUSB_ASSOCIATE = 0x0001, +}; + +/* Association Attribute header (AMS1.0[3.8]) */ +struct wusb_cbaf_attr_hdr { + __le16 id; + __le16 len; +} __attribute__((packed)); + +/* Host Info (AMS1.0[T4-7]) (yeah, more headers and fields...) */ +struct wusb_cbaf_host_info { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr CHID_hdr; + struct wusb_ckhdid CHID; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr HostFriendlyName_hdr; + __u8 HostFriendlyName[]; +} __attribute__((packed)); + +/* Device Info (AMS1.0[T4-8]) + * + * I still don't get this tag'n'header stuff for each goddamn + * field... + */ +struct wusb_cbaf_device_info { + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr CDID_hdr; + struct wusb_ckhdid CDID; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr DeviceFriendlyName_hdr; + __u8 DeviceFriendlyName[]; +} __attribute__((packed)); + +/* Connection Context; CC_DATA - Success case (AMS1.0[T4-9]) */ +struct wusb_cbaf_cc_data { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr ConnectionContext_hdr; + struct wusb_ckhdid CHID; + struct wusb_ckhdid CDID; + struct wusb_ckhdid CK; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; +} __attribute__((packed)); + +/* CC_DATA - Failure case (AMS1.0[T4-10]) */ +struct wusb_cbaf_cc_data_fail { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le16 Length; + struct wusb_cbaf_attr_hdr AssociationStatus_hdr; + __u32 AssociationStatus; +} __attribute__((packed)); + +#endif /* __LINUX_USB_ASSOCIATION_H */ diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h new file mode 100644 index 000000000..ba99af275 --- /dev/null +++ b/include/linux/usb/atmel_usba_udc.h @@ -0,0 +1,23 @@ +/* + * Platform data definitions for Atmel USBA gadget driver. + */ +#ifndef __LINUX_USB_USBA_H +#define __LINUX_USB_USBA_H + +struct usba_ep_data { + char *name; + int index; + int fifo_size; + int nr_banks; + int can_dma; + int can_isoc; +}; + +struct usba_platform_data { + int vbus_pin; + int vbus_pin_inverted; + int num_ep; + struct usba_ep_data ep[0]; +}; + +#endif /* __LINUX_USB_USBA_H */ diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h new file mode 100644 index 000000000..c5f2158ab --- /dev/null +++ b/include/linux/usb/audio-v2.h @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2010 Daniel Mack <daniel@caiaq.de> + * + * This software is distributed under the terms of the GNU General Public + * License ("GPL") version 2, as published by the Free Software Foundation. + * + * 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 uac2_control_is_readable(u32 bmControls, u8 control) +{ + return (bmControls >> (control * 2)) & 0x1; +} + +static inline bool uac2_control_is_writeable(u32 bmControls, u8 control) +{ + return (bmControls >> (control * 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 Source Descriptor */ + +struct uac_clock_selector_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bClockID; + __u8 bNrInPins; + __u8 baCSourceID[]; + /* bmControls, bAssocTerminal and iClockSource 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; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bCSourceID; + __u8 bNrChannels; + __u32 bmChannelConfig; + __u8 iChannelNames; + __u16 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; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bSourceID; + __u8 bCSourceID; + __u16 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[0]; /* 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; + __u32 bmFormats; + __u8 bNrChannels; + __u32 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) + +/* 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 */ + diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h new file mode 100644 index 000000000..3d8461911 --- /dev/null +++ b/include/linux/usb/audio.h @@ -0,0 +1,44 @@ +/* + * <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 software is distributed under the terms of the GNU General Public + * License ("GPL") version 2, as published by the Free Software Foundation. + * + * 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 */ diff --git a/include/linux/usb/c67x00.h b/include/linux/usb/c67x00.h new file mode 100644 index 000000000..83c6b4547 --- /dev/null +++ b/include/linux/usb/c67x00.h @@ -0,0 +1,48 @@ +/* + * usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip + * + * Copyright (C) 2006-2008 Barco N.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA. + */ + +#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 */ diff --git a/include/linux/usb/cdc-wdm.h b/include/linux/usb/cdc-wdm.h new file mode 100644 index 000000000..0b3f4295c --- /dev/null +++ b/include/linux/usb/cdc-wdm.h @@ -0,0 +1,21 @@ +/* + * USB CDC Device Management subdriver + * + * Copyright (c) 2012 Bjørn Mork <bjorn@mork.no> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#ifndef __LINUX_USB_CDC_WDM_H +#define __LINUX_USB_CDC_WDM_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, + int (*manage_power)(struct usb_interface *, int)); + +#endif /* __LINUX_USB_CDC_WDM_H */ diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h new file mode 100644 index 000000000..7c9b48473 --- /dev/null +++ b/include/linux/usb/cdc_ncm.h @@ -0,0 +1,145 @@ +/* + * 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.2.1 */ +#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 + +/* Maximum NTB length */ +#define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */ +#define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* 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) + +#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; + + 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; + + u32 timer_interval; + u32 max_ndp_size; + + u32 tx_timer_pending; + u32 tx_curr_frame_num; + u32 rx_max; + u32 tx_max; + 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_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); +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); +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 */ diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h new file mode 100644 index 000000000..27603bcbb --- /dev/null +++ b/include/linux/usb/ch9.h @@ -0,0 +1,55 @@ +/* + * This file holds USB constants and structures that are needed for + * USB device APIs. These are used by the USB device model, which is + * defined in chapter 9 of the USB 2.0 specification and in the + * Wireless USB 1.0 (spread around). Linux has several APIs in C that + * need these: + * + * - the master/host side Linux-USB kernel driver API; + * - the "usbfs" user space API; and + * - the Linux "gadget" slave/device/peripheral side driver API. + * + * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems + * act either as a USB master/host or as a USB slave/device. That means + * the master and slave side APIs benefit from working well together. + * + * There's also "Wireless USB", using low power short range radios for + * peripheral interconnection but otherwise building on the USB framework. + * + * Note all descriptors are declared '__attribute__((packed))' so that: + * + * [a] they never get padded, either internally (USB spec writers + * probably handled that) or externally; + * + * [b] so that accessing bigger-than-a-bytes fields will never + * generate bus errors on any platform, even when the location of + * its descriptor inside a bundle isn't "naturally aligned", and + * + * [c] for consistency, removing all doubt even when it appears to + * someone that the two other points are non-issues for that + * particular descriptor type. + */ +#ifndef __LINUX_USB_CH9_H +#define __LINUX_USB_CH9_H + +#include <uapi/linux/usb/ch9.h> + + +/** + * usb_speed_string() - Returns human readable-name of the speed. + * @speed: The speed to return human-readable name for. If it's not + * any of the speeds defined in usb_device_speed enum, string for + * USB_SPEED_UNKNOWN will be returned. + */ +extern const char *usb_speed_string(enum usb_device_speed speed); + + +/** + * usb_state_string - Returns human readable name for the state. + * @state: The state to return a human-readable name for. If it's not + * any of the states devices in usb_device_state_string enum, + * the string UNKNOWN will be returned. + */ +extern const char *usb_state_string(enum usb_device_state state); + +#endif /* __LINUX_USB_CH9_H */ diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h new file mode 100644 index 000000000..ab94f78c4 --- /dev/null +++ b/include/linux/usb/chipidea.h @@ -0,0 +1,50 @@ +/* + * Platform data for the chipidea USB dual role controller + */ + +#ifndef __LINUX_USB_CHIPIDEA_H +#define __LINUX_USB_CHIPIDEA_H + +#include <linux/usb/otg.h> + +struct ci_hdrc; +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_SUPPORTS_RUNTIME_PM BIT(2) +#define CI_HDRC_DISABLE_STREAMING BIT(3) + /* + * 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) + enum usb_dr_mode dr_mode; +#define CI_HDRC_CONTROLLER_RESET_EVENT 0 +#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 + void (*notify_event) (struct ci_hdrc *ci, unsigned event); + struct regulator *reg_vbus; + bool tpl_support; +}; + +/* 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); + +#endif diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h new file mode 100644 index 000000000..2511469a9 --- /dev/null +++ b/include/linux/usb/composite.h @@ -0,0 +1,627 @@ +/* + * composite.h -- framework for usb gadgets which are composite devices + * + * Copyright (C) 2006-2008 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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/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(). + */ +#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ + +/* big enough to hold our biggest descriptor */ +#define USB_COMP_EP0_BUFSIZ 1024 + +#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. + * @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 + * + * 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_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 *); + 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); + /* private: */ + /* internals */ + struct list_head list; + DECLARE_BITMAP(endpoints, 32); + const struct usb_function_instance *fi; +}; + +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(struct usb_gadget *g, struct usb_function *f, + struct usb_ep *_ep); + +#define MAX_CONFIG_INTERFACES 16 /* arbitrary; max 255 */ + +/** + * 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 consumtion 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; + struct usb_function *interface[MAX_CONFIG_INTERFACES]; +}; + +int usb_add_config(struct usb_composite_dev *, + struct usb_configuration *, + int (*)(struct usb_configuration *)); + +void usb_remove_config(struct usb_composite_dev *, + 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); + +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_device - 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 + * @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. + * + * OPEN ISSUE: it appears that some WUSB devices will need to be + * built by combining a normal (wired) gadget with a wireless one. + * This revision of the gadget framework should probably try to make + * sure doing that won't hurt too much. + * + * One notion for how to handle Wireless USB devices involves: + * (a) a second gadget here, discovery mechanism TBD, but likely + * needing separate "register/unregister WUSB gadget" calls; + * (b) updates to usb_gadget to include flags "is it wireless", + * "is it wired", plus (presumably in a wrapper structure) + * bandgroup and PHY info; + * (c) presumably a wireless_ep wrapping a usb_ep, and reporting + * wireless-specific parameters like maxburst and maxsequence; + * (d) configurations that are specific to wireless links; + * (e) function drivers that understand wireless configs and will + * support wireless for (additional) function instances; + * (f) a function to support association setup (like CBAF), not + * necessarily requiring a wireless adapter; + * (g) composite device setup that can create one or more wireless + * configs, including appropriate association setup support; + * (h) more, TBD. + */ +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; + + /* 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; + + /* 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; + + unsigned setup_pending:1; + unsigned 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 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_CODE >> 16 & 0xff)) << 8; + bcdDevice |= bin2bcd((LINUX_VERSION_CODE >> 8 & 0xff)); + 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 */ diff --git a/include/linux/usb/ehci-dbgp.h b/include/linux/usb/ehci-dbgp.h new file mode 100644 index 000000000..7344d9e59 --- /dev/null +++ b/include/linux/usb/ehci-dbgp.h @@ -0,0 +1,83 @@ +/* + * 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 */ diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h new file mode 100644 index 000000000..966889a20 --- /dev/null +++ b/include/linux/usb/ehci_def.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2001-2002 by David Brownell + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#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 */ + + 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" */ + + /* PORTSC: offset 0x44 */ + u32 port_status[0]; /* 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 */ +/* 11:10 for detecting lowspeed devices (reset vs release ownership) */ +/* 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) + + 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 */ + + u32 reserved4[6]; + +/* 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 + */ + /* HOSTPC: offset 0x84 */ + u32 hostpc[1]; /* HOSTPC extension */ +#define HOSTPC_PHCD (1<<22) /* Phy clock disable */ +#define HOSTPC_PSPD (3<<25) /* Port speed detection */ + + u32 reserved5[16]; + + /* 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 */ diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h new file mode 100644 index 000000000..db0431b39 --- /dev/null +++ b/include/linux/usb/ehci_pdriver.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#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; + + /* 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 */ diff --git a/include/linux/usb/ezusb.h b/include/linux/usb/ezusb.h new file mode 100644 index 000000000..639ee4577 --- /dev/null +++ b/include/linux/usb/ezusb.h @@ -0,0 +1,8 @@ +#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 */ diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h new file mode 100644 index 000000000..71190663f --- /dev/null +++ b/include/linux/usb/functionfs.h @@ -0,0 +1,6 @@ +#ifndef __LINUX_FUNCTIONFS_H__ +#define __LINUX_FUNCTIONFS_H__ 1 + +#include <uapi/linux/usb/functionfs.h> + +#endif diff --git a/include/linux/usb/g_hid.h b/include/linux/usb/g_hid.h new file mode 100644 index 000000000..50f5745df --- /dev/null +++ b/include/linux/usb/g_hid.h @@ -0,0 +1,32 @@ +/* + * g_hid.h -- Header file for USB HID gadget driver + * + * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#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 */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h new file mode 100644 index 000000000..4f3dfb7d0 --- /dev/null +++ b/include/linux/usb/gadget.h @@ -0,0 +1,1054 @@ +/* + * <linux/usb/gadget.h> + * + * We call the USB code inside a Linux-based peripheral device a "gadget" + * driver, except for the hardware-specific bus glue. One USB host can + * master many USB gadgets, but the gadgets are only slaved to one host. + * + * + * (C) Copyright 2002-2004 by David Brownell + * All Rights Reserved. + * + * This software is licensed under the GNU GPL version 2. + */ + +#ifndef __LINUX_USB_GADGET_H +#define __LINUX_USB_GADGET_H + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/scatterlist.h> +#include <linux/types.h> +#include <linux/workqueue.h> +#include <linux/usb/ch9.h> + +struct usb_ep; + +/** + * struct usb_request - describes one i/o request + * @buf: Buffer used for data. Always provide this; some controllers + * only use PIO, or don't use DMA for some endpoints. + * @dma: DMA address corresponding to 'buf'. If you don't set this + * field, and the usb controller needs one, it is responsible + * for mapping and unmapping the buffer. + * @sg: a scatterlist for SG-capable controllers. + * @num_sgs: number of SG entries + * @num_mapped_sgs: number of SG entries mapped to DMA (internal) + * @length: Length of that data + * @stream_id: The stream id, when USB3.0 bulk streams are being used + * @no_interrupt: If true, hints that no completion irq is needed. + * Helpful sometimes with deep request queues that are handled + * directly by DMA controllers. + * @zero: If true, when writing data, makes the last packet be "short" + * by adding a zero length packet as needed; + * @short_not_ok: When reading data, makes short packets be + * treated as errors (queue stops advancing till cleanup). + * @complete: Function called when request completes, so this request and + * its buffer may be re-used. The function will always be called with + * interrupts disabled, and it must not sleep. + * Reads terminate with a short packet, or when the buffer fills, + * whichever comes first. When writes terminate, some data bytes + * will usually still be in flight (often in a hardware fifo). + * Errors (for reads or writes) stop the queue from advancing + * until the completion function returns, so that any transfers + * invalidated by the error may first be dequeued. + * @context: For use by the completion callback + * @list: For use by the gadget driver. + * @status: Reports completion code, zero or a negative errno. + * Normally, faults block the transfer queue from advancing until + * the completion callback returns. + * Code "-ESHUTDOWN" indicates completion caused by device disconnect, + * or when the driver disabled the endpoint. + * @actual: Reports bytes transferred to/from the buffer. For reads (OUT + * transfers) this may be less than the requested length. If the + * short_not_ok flag is set, short reads are treated as errors + * even when status otherwise indicates successful completion. + * Note that for writes (IN transfers) some data bytes may still + * reside in a device-side FIFO when the request is reported as + * complete. + * + * These are allocated/freed through the endpoint they're used with. The + * hardware's driver can add extra per-request data to the memory it returns, + * which often avoids separate memory allocations (potential failures), + * later when the request is queued. + * + * Request flags affect request handling, such as whether a zero length + * packet is written (the "zero" flag), whether a short read should be + * treated as an error (blocking request queue advance, the "short_not_ok" + * flag), or hinting that an interrupt is not required (the "no_interrupt" + * flag, for use with deep request queues). + * + * Bulk endpoints can use any size buffers, and can also be used for interrupt + * transfers. interrupt-only endpoints can be much less functional. + * + * NOTE: this is analogous to 'struct urb' on the host side, except that + * it's thinner and promotes more pre-allocation. + */ + +struct usb_request { + void *buf; + unsigned length; + dma_addr_t dma; + + struct scatterlist *sg; + unsigned num_sgs; + unsigned num_mapped_sgs; + + unsigned stream_id:16; + unsigned no_interrupt:1; + unsigned zero:1; + unsigned short_not_ok:1; + + void (*complete)(struct usb_ep *ep, + struct usb_request *req); + void *context; + struct list_head list; + + int status; + unsigned actual; +}; + +/*-------------------------------------------------------------------------*/ + +/* endpoint-specific parts of the api to the usb controller hardware. + * unlike the urb model, (de)multiplexing layers are not required. + * (so this api could slash overhead if used on the host side...) + * + * note that device side usb controllers commonly differ in how many + * endpoints they support, as well as their capabilities. + */ +struct usb_ep_ops { + int (*enable) (struct usb_ep *ep, + const struct usb_endpoint_descriptor *desc); + int (*disable) (struct usb_ep *ep); + + struct usb_request *(*alloc_request) (struct usb_ep *ep, + gfp_t gfp_flags); + void (*free_request) (struct usb_ep *ep, struct usb_request *req); + + int (*queue) (struct usb_ep *ep, struct usb_request *req, + gfp_t gfp_flags); + int (*dequeue) (struct usb_ep *ep, struct usb_request *req); + + int (*set_halt) (struct usb_ep *ep, int value); + int (*set_wedge) (struct usb_ep *ep); + + int (*fifo_status) (struct usb_ep *ep); + void (*fifo_flush) (struct usb_ep *ep); +}; + +/** + * struct usb_ep - device side representation of USB endpoint + * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk" + * @ops: Function pointers used to access hardware-specific operations. + * @ep_list:the gadget's ep_list holds all of its endpoints + * @maxpacket:The maximum packet size used on this endpoint. The initial + * value can sometimes be reduced (hardware allowing), according to + * the endpoint descriptor used to configure the endpoint. + * @maxpacket_limit:The maximum packet size value which can be handled by this + * endpoint. It's set once by UDC driver when endpoint is initialized, and + * should not be changed. Should not be confused with maxpacket. + * @max_streams: The maximum number of streams supported + * by this EP (0 - 16, actual number is 2^n) + * @mult: multiplier, 'mult' value for SS Isoc EPs + * @maxburst: the maximum number of bursts supported by this EP (for usb3) + * @driver_data:for use by the gadget driver. + * @address: used to identify the endpoint when finding descriptor that + * matches connection speed + * @desc: endpoint descriptor. This pointer is set before the endpoint is + * enabled and remains valid until the endpoint is disabled. + * @comp_desc: In case of SuperSpeed support, this is the endpoint companion + * descriptor that is used to configure the endpoint + * + * the bus controller driver lists all the general purpose endpoints in + * gadget->ep_list. the control endpoint (gadget->ep0) is not in that list, + * and is accessed only in response to a driver setup() callback. + */ +struct usb_ep { + void *driver_data; + + const char *name; + const struct usb_ep_ops *ops; + struct list_head ep_list; + unsigned maxpacket:16; + unsigned maxpacket_limit:16; + unsigned max_streams:16; + unsigned mult:2; + unsigned maxburst:5; + u8 address; + const struct usb_endpoint_descriptor *desc; + const struct usb_ss_ep_comp_descriptor *comp_desc; +}; + +/*-------------------------------------------------------------------------*/ + +/** + * usb_ep_set_maxpacket_limit - set maximum packet size limit for endpoint + * @ep:the endpoint being configured + * @maxpacket_limit:value of maximum packet size limit + * + * This function should be used only in UDC drivers to initialize endpoint + * (usually in probe function). + */ +static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep, + unsigned maxpacket_limit) +{ + ep->maxpacket_limit = maxpacket_limit; + ep->maxpacket = maxpacket_limit; +} + +/** + * usb_ep_enable - configure endpoint, making it usable + * @ep:the endpoint being configured. may not be the endpoint named "ep0". + * drivers discover endpoints through the ep_list of a usb_gadget. + * + * When configurations are set, or when interface settings change, the driver + * will enable or disable the relevant endpoints. while it is enabled, an + * endpoint may be used for i/o until the driver receives a disconnect() from + * the host or until the endpoint is disabled. + * + * the ep0 implementation (which calls this routine) must ensure that the + * hardware capabilities of each endpoint match the descriptor provided + * for it. for example, an endpoint named "ep2in-bulk" would be usable + * for interrupt transfers as well as bulk, but it likely couldn't be used + * for iso transfers or for endpoint 14. some endpoints are fully + * configurable, with more generic names like "ep-a". (remember that for + * USB, "in" means "towards the USB master".) + * + * returns zero, or a negative error code. + */ +static inline int usb_ep_enable(struct usb_ep *ep) +{ + return ep->ops->enable(ep, ep->desc); +} + +/** + * usb_ep_disable - endpoint is no longer usable + * @ep:the endpoint being unconfigured. may not be the endpoint named "ep0". + * + * no other task may be using this endpoint when this is called. + * any pending and uncompleted requests will complete with status + * indicating disconnect (-ESHUTDOWN) before this call returns. + * gadget drivers must call usb_ep_enable() again before queueing + * requests to the endpoint. + * + * returns zero, or a negative error code. + */ +static inline int usb_ep_disable(struct usb_ep *ep) +{ + return ep->ops->disable(ep); +} + +/** + * usb_ep_alloc_request - allocate a request object to use with this endpoint + * @ep:the endpoint to be used with with the request + * @gfp_flags:GFP_* flags to use + * + * Request objects must be allocated with this call, since they normally + * need controller-specific setup and may even need endpoint-specific + * resources such as allocation of DMA descriptors. + * Requests may be submitted with usb_ep_queue(), and receive a single + * completion callback. Free requests with usb_ep_free_request(), when + * they are no longer needed. + * + * Returns the request, or null if one could not be allocated. + */ +static inline struct usb_request *usb_ep_alloc_request(struct usb_ep *ep, + gfp_t gfp_flags) +{ + return ep->ops->alloc_request(ep, gfp_flags); +} + +/** + * usb_ep_free_request - frees a request object + * @ep:the endpoint associated with the request + * @req:the request being freed + * + * Reverses the effect of usb_ep_alloc_request(). + * Caller guarantees the request is not queued, and that it will + * no longer be requeued (or otherwise used). + */ +static inline void usb_ep_free_request(struct usb_ep *ep, + struct usb_request *req) +{ + ep->ops->free_request(ep, req); +} + +/** + * usb_ep_queue - queues (submits) an I/O request to an endpoint. + * @ep:the endpoint associated with the request + * @req:the request being submitted + * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't + * pre-allocate all necessary memory with the request. + * + * This tells the device controller to perform the specified request through + * that endpoint (reading or writing a buffer). When the request completes, + * including being canceled by usb_ep_dequeue(), the request's completion + * routine is called to return the request to the driver. Any endpoint + * (except control endpoints like ep0) may have more than one transfer + * request queued; they complete in FIFO order. Once a gadget driver + * submits a request, that request may not be examined or modified until it + * is given back to that driver through the completion callback. + * + * Each request is turned into one or more packets. The controller driver + * never merges adjacent requests into the same packet. OUT transfers + * will sometimes use data that's already buffered in the hardware. + * Drivers can rely on the fact that the first byte of the request's buffer + * always corresponds to the first byte of some USB packet, for both + * IN and OUT transfers. + * + * Bulk endpoints can queue any amount of data; the transfer is packetized + * automatically. The last packet will be short if the request doesn't fill it + * out completely. Zero length packets (ZLPs) should be avoided in portable + * protocols since not all usb hardware can successfully handle zero length + * packets. (ZLPs may be explicitly written, and may be implicitly written if + * the request 'zero' flag is set.) Bulk endpoints may also be used + * for interrupt transfers; but the reverse is not true, and some endpoints + * won't support every interrupt transfer. (Such as 768 byte packets.) + * + * Interrupt-only endpoints are less functional than bulk endpoints, for + * example by not supporting queueing or not handling buffers that are + * larger than the endpoint's maxpacket size. They may also treat data + * toggle differently. + * + * Control endpoints ... after getting a setup() callback, the driver queues + * one response (even if it would be zero length). That enables the + * status ack, after transferring data as specified in the response. Setup + * functions may return negative error codes to generate protocol stalls. + * (Note that some USB device controllers disallow protocol stall responses + * in some cases.) When control responses are deferred (the response is + * written after the setup callback returns), then usb_ep_set_halt() may be + * used on ep0 to trigger protocol stalls. Depending on the controller, + * it may not be possible to trigger a status-stage protocol stall when the + * data stage is over, that is, from within the response's completion + * routine. + * + * For periodic endpoints, like interrupt or isochronous ones, the usb host + * arranges to poll once per interval, and the gadget driver usually will + * have queued some data to transfer at that time. + * + * Returns zero, or a negative error code. Endpoints that are not enabled + * report errors; errors will also be + * reported when the usb peripheral is disconnected. + */ +static inline int usb_ep_queue(struct usb_ep *ep, + struct usb_request *req, gfp_t gfp_flags) +{ + return ep->ops->queue(ep, req, gfp_flags); +} + +/** + * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint + * @ep:the endpoint associated with the request + * @req:the request being canceled + * + * If the request is still active on the endpoint, it is dequeued and its + * completion routine is called (with status -ECONNRESET); else a negative + * error code is returned. This is guaranteed to happen before the call to + * usb_ep_dequeue() returns. + * + * Note that some hardware can't clear out write fifos (to unlink the request + * at the head of the queue) except as part of disconnecting from usb. Such + * restrictions prevent drivers from supporting configuration changes, + * even to configuration zero (a "chapter 9" requirement). + */ +static inline int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req) +{ + return ep->ops->dequeue(ep, req); +} + +/** + * usb_ep_set_halt - sets the endpoint halt feature. + * @ep: the non-isochronous endpoint being stalled + * + * Use this to stall an endpoint, perhaps as an error report. + * Except for control endpoints, + * the endpoint stays halted (will not stream any data) until the host + * clears this feature; drivers may need to empty the endpoint's request + * queue first, to make sure no inappropriate transfers happen. + * + * Note that while an endpoint CLEAR_FEATURE will be invisible to the + * gadget driver, a SET_INTERFACE will not be. To reset endpoints for the + * current altsetting, see usb_ep_clear_halt(). When switching altsettings, + * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints. + * + * Returns zero, or a negative error code. On success, this call sets + * underlying hardware state that blocks data transfers. + * Attempts to halt IN endpoints will fail (returning -EAGAIN) if any + * transfer requests are still queued, or if the controller hardware + * (usually a FIFO) still holds bytes that the host hasn't collected. + */ +static inline int usb_ep_set_halt(struct usb_ep *ep) +{ + return ep->ops->set_halt(ep, 1); +} + +/** + * usb_ep_clear_halt - clears endpoint halt, and resets toggle + * @ep:the bulk or interrupt endpoint being reset + * + * Use this when responding to the standard usb "set interface" request, + * for endpoints that aren't reconfigured, after clearing any other state + * in the endpoint's i/o queue. + * + * Returns zero, or a negative error code. On success, this call clears + * the underlying hardware state reflecting endpoint halt and data toggle. + * Note that some hardware can't support this request (like pxa2xx_udc), + * and accordingly can't correctly implement interface altsettings. + */ +static inline int usb_ep_clear_halt(struct usb_ep *ep) +{ + return ep->ops->set_halt(ep, 0); +} + +/** + * usb_ep_set_wedge - sets the halt feature and ignores clear requests + * @ep: the endpoint being wedged + * + * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT) + * requests. If the gadget driver clears the halt status, it will + * automatically unwedge the endpoint. + * + * Returns zero on success, else negative errno. + */ +static inline int +usb_ep_set_wedge(struct usb_ep *ep) +{ + if (ep->ops->set_wedge) + return ep->ops->set_wedge(ep); + else + return ep->ops->set_halt(ep, 1); +} + +/** + * usb_ep_fifo_status - returns number of bytes in fifo, or error + * @ep: the endpoint whose fifo status is being checked. + * + * FIFO endpoints may have "unclaimed data" in them in certain cases, + * such as after aborted transfers. Hosts may not have collected all + * the IN data written by the gadget driver (and reported by a request + * completion). The gadget driver may not have collected all the data + * written OUT to it by the host. Drivers that need precise handling for + * fault reporting or recovery may need to use this call. + * + * This returns the number of such bytes in the fifo, or a negative + * errno if the endpoint doesn't use a FIFO or doesn't support such + * precise handling. + */ +static inline int usb_ep_fifo_status(struct usb_ep *ep) +{ + if (ep->ops->fifo_status) + return ep->ops->fifo_status(ep); + else + return -EOPNOTSUPP; +} + +/** + * usb_ep_fifo_flush - flushes contents of a fifo + * @ep: the endpoint whose fifo is being flushed. + * + * This call may be used to flush the "unclaimed data" that may exist in + * an endpoint fifo after abnormal transaction terminations. The call + * must never be used except when endpoint is not being used for any + * protocol translation. + */ +static inline void usb_ep_fifo_flush(struct usb_ep *ep) +{ + if (ep->ops->fifo_flush) + ep->ops->fifo_flush(ep); +} + + +/*-------------------------------------------------------------------------*/ + +struct usb_dcd_config_params { + __u8 bU1devExitLat; /* U1 Device exit Latency */ +#define USB_DEFAULT_U1_DEV_EXIT_LAT 0x01 /* Less then 1 microsec */ + __le16 bU2DevExitLat; /* U2 Device exit Latency */ +#define USB_DEFAULT_U2_DEV_EXIT_LAT 0x1F4 /* Less then 500 microsec */ +}; + + +struct usb_gadget; +struct usb_gadget_driver; +struct usb_udc; + +/* the rest of the api to the controller hardware: device operations, + * which don't involve endpoints (or i/o). + */ +struct usb_gadget_ops { + int (*get_frame)(struct usb_gadget *); + int (*wakeup)(struct usb_gadget *); + int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); + int (*vbus_session) (struct usb_gadget *, int is_active); + int (*vbus_draw) (struct usb_gadget *, unsigned mA); + int (*pullup) (struct usb_gadget *, int is_on); + int (*ioctl)(struct usb_gadget *, + unsigned code, unsigned long param); + void (*get_config_params)(struct usb_dcd_config_params *); + int (*udc_start)(struct usb_gadget *, + struct usb_gadget_driver *); + int (*udc_stop)(struct usb_gadget *); +}; + +/** + * struct usb_gadget - represents a usb slave device + * @work: (internal use) Workqueue to be used for sysfs_notify() + * @udc: struct usb_udc pointer for this gadget + * @ops: Function pointers used to access hardware-specific operations. + * @ep0: Endpoint zero, used when reading or writing responses to + * driver setup() requests + * @ep_list: List of other endpoints supported by the device. + * @speed: Speed of current connection to USB host. + * @max_speed: Maximal speed the UDC can handle. UDC must support this + * and all slower speeds. + * @state: the state we are now (attached, suspended, configured, etc) + * @name: Identifies the controller hardware type. Used in diagnostics + * and sometimes configuration. + * @dev: Driver model state for this abstract device. + * @out_epnum: last used out ep number + * @in_epnum: last used in ep number + * @sg_supported: true if we can handle scatter-gather + * @is_otg: True if the USB device port uses a Mini-AB jack, so that the + * gadget driver must provide a USB OTG descriptor. + * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable + * is in the Mini-AB jack, and HNP has been used to switch roles + * so that the "A" device currently acts as A-Peripheral, not A-Host. + * @a_hnp_support: OTG device feature flag, indicating that the A-Host + * supports HNP at this port. + * @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host + * only supports HNP on a different root port. + * @b_hnp_enable: OTG device feature flag, indicating that the A-Host + * enabled HNP support. + * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to + * MaxPacketSize. + * @is_selfpowered: if the gadget is self-powered. + * + * Gadgets have a mostly-portable "gadget driver" implementing device + * functions, handling all usb configurations and interfaces. Gadget + * drivers talk to hardware-specific code indirectly, through ops vectors. + * That insulates the gadget driver from hardware details, and packages + * the hardware endpoints through generic i/o queues. The "usb_gadget" + * and "usb_ep" interfaces provide that insulation from the hardware. + * + * Except for the driver data, all fields in this structure are + * read-only to the gadget driver. That driver data is part of the + * "driver model" infrastructure in 2.6 (and later) kernels, and for + * earlier systems is grouped in a similar structure that's not known + * to the rest of the kernel. + * + * Values of the three OTG device feature flags are updated before the + * setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before + * driver suspend() calls. They are valid only when is_otg, and when the + * device is acting as a B-Peripheral (so is_a_peripheral is false). + */ +struct usb_gadget { + struct work_struct work; + struct usb_udc *udc; + /* readonly to gadget driver */ + const struct usb_gadget_ops *ops; + struct usb_ep *ep0; + struct list_head ep_list; /* of usb_ep */ + enum usb_device_speed speed; + enum usb_device_speed max_speed; + enum usb_device_state state; + const char *name; + struct device dev; + unsigned out_epnum; + unsigned in_epnum; + + unsigned sg_supported:1; + unsigned is_otg:1; + unsigned is_a_peripheral:1; + unsigned b_hnp_enable:1; + unsigned a_hnp_support:1; + unsigned a_alt_hnp_support:1; + unsigned quirk_ep_out_aligned_size:1; + unsigned is_selfpowered:1; +}; +#define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) + +static inline void set_gadget_data(struct usb_gadget *gadget, void *data) + { dev_set_drvdata(&gadget->dev, data); } +static inline void *get_gadget_data(struct usb_gadget *gadget) + { return dev_get_drvdata(&gadget->dev); } +static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) +{ + return container_of(dev, struct usb_gadget, dev); +} + +/* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ +#define gadget_for_each_ep(tmp, gadget) \ + list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) + + +/** + * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget + * requires quirk_ep_out_aligned_size, otherwise reguens len. + * @g: controller to check for quirk + * @ep: the endpoint whose maxpacketsize is used to align @len + * @len: buffer size's length to align to @ep's maxpacketsize + * + * This helper is used in case it's required for any reason to check and maybe + * align buffer's size to an ep's maxpacketsize. + */ +static inline size_t +usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len) +{ + return !g->quirk_ep_out_aligned_size ? len : + round_up(len, (size_t)ep->desc->wMaxPacketSize); +} + +/** + * gadget_is_dualspeed - return true iff the hardware handles high speed + * @g: controller that might support both high and full speeds + */ +static inline int gadget_is_dualspeed(struct usb_gadget *g) +{ + return g->max_speed >= USB_SPEED_HIGH; +} + +/** + * gadget_is_superspeed() - return true if the hardware handles superspeed + * @g: controller that might support superspeed + */ +static inline int gadget_is_superspeed(struct usb_gadget *g) +{ + return g->max_speed >= USB_SPEED_SUPER; +} + +/** + * gadget_is_otg - return true iff the hardware is OTG-ready + * @g: controller that might have a Mini-AB connector + * + * This is a runtime test, since kernels with a USB-OTG stack sometimes + * run on boards which only have a Mini-B (or Mini-A) connector. + */ +static inline int gadget_is_otg(struct usb_gadget *g) +{ +#ifdef CONFIG_USB_OTG + return g->is_otg; +#else + return 0; +#endif +} + +/** + * usb_gadget_frame_number - returns the current frame number + * @gadget: controller that reports the frame number + * + * Returns the usb frame number, normally eleven bits from a SOF packet, + * or negative errno if this device doesn't support this capability. + */ +static inline int usb_gadget_frame_number(struct usb_gadget *gadget) +{ + return gadget->ops->get_frame(gadget); +} + +/** + * usb_gadget_wakeup - tries to wake up the host connected to this gadget + * @gadget: controller used to wake up the host + * + * Returns zero on success, else negative error code if the hardware + * doesn't support such attempts, or its support has not been enabled + * by the usb host. Drivers must return device descriptors that report + * their ability to support this, or hosts won't enable it. + * + * This may also try to use SRP to wake the host and start enumeration, + * even if OTG isn't otherwise in use. OTG devices may also start + * remote wakeup even when hosts don't explicitly enable it. + */ +static inline int usb_gadget_wakeup(struct usb_gadget *gadget) +{ + if (!gadget->ops->wakeup) + return -EOPNOTSUPP; + return gadget->ops->wakeup(gadget); +} + +/** + * usb_gadget_set_selfpowered - sets the device selfpowered feature. + * @gadget:the device being declared as self-powered + * + * this affects the device status reported by the hardware driver + * to reflect that it now has a local power supply. + * + * returns zero on success, else negative errno. + */ +static inline int usb_gadget_set_selfpowered(struct usb_gadget *gadget) +{ + if (!gadget->ops->set_selfpowered) + return -EOPNOTSUPP; + return gadget->ops->set_selfpowered(gadget, 1); +} + +/** + * usb_gadget_clear_selfpowered - clear the device selfpowered feature. + * @gadget:the device being declared as bus-powered + * + * this affects the device status reported by the hardware driver. + * some hardware may not support bus-powered operation, in which + * case this feature's value can never change. + * + * returns zero on success, else negative errno. + */ +static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget) +{ + if (!gadget->ops->set_selfpowered) + return -EOPNOTSUPP; + return gadget->ops->set_selfpowered(gadget, 0); +} + +/** + * usb_gadget_vbus_connect - Notify controller that VBUS is powered + * @gadget:The device which now has VBUS power. + * Context: can sleep + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session starting. Common responses include + * resuming the controller, activating the D+ (or D-) pullup to let the + * host detect that a USB device is attached, and starting to draw power + * (8mA or possibly more, especially after SET_CONFIGURATION). + * + * Returns zero on success, else negative errno. + */ +static inline int usb_gadget_vbus_connect(struct usb_gadget *gadget) +{ + if (!gadget->ops->vbus_session) + return -EOPNOTSUPP; + return gadget->ops->vbus_session(gadget, 1); +} + +/** + * usb_gadget_vbus_draw - constrain controller's VBUS power usage + * @gadget:The device whose VBUS usage is being described + * @mA:How much current to draw, in milliAmperes. This should be twice + * the value listed in the configuration descriptor bMaxPower field. + * + * This call is used by gadget drivers during SET_CONFIGURATION calls, + * reporting how much power the device may consume. For example, this + * could affect how quickly batteries are recharged. + * + * Returns zero on success, else negative errno. + */ +static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) +{ + if (!gadget->ops->vbus_draw) + return -EOPNOTSUPP; + return gadget->ops->vbus_draw(gadget, mA); +} + +/** + * usb_gadget_vbus_disconnect - notify controller about VBUS session end + * @gadget:the device whose VBUS supply is being described + * Context: can sleep + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session ending. Common responses include + * reversing everything done in usb_gadget_vbus_connect(). + * + * Returns zero on success, else negative errno. + */ +static inline int usb_gadget_vbus_disconnect(struct usb_gadget *gadget) +{ + if (!gadget->ops->vbus_session) + return -EOPNOTSUPP; + return gadget->ops->vbus_session(gadget, 0); +} + +/** + * usb_gadget_connect - software-controlled connect to USB host + * @gadget:the peripheral being connected + * + * Enables the D+ (or potentially D-) pullup. The host will start + * enumerating this gadget when the pullup is active and a VBUS session + * is active (the link is powered). This pullup is always enabled unless + * usb_gadget_disconnect() has been used to disable it. + * + * Returns zero on success, else negative errno. + */ +static inline int usb_gadget_connect(struct usb_gadget *gadget) +{ + if (!gadget->ops->pullup) + return -EOPNOTSUPP; + return gadget->ops->pullup(gadget, 1); +} + +/** + * usb_gadget_disconnect - software-controlled disconnect from USB host + * @gadget:the peripheral being disconnected + * + * Disables the D+ (or potentially D-) pullup, which the host may see + * as a disconnect (when a VBUS session is active). Not all systems + * support software pullup controls. + * + * This routine may be used during the gadget driver bind() call to prevent + * the peripheral from ever being visible to the USB host, unless later + * usb_gadget_connect() is called. For example, user mode components may + * need to be activated before the system can talk to hosts. + * + * Returns zero on success, else negative errno. + */ +static inline int usb_gadget_disconnect(struct usb_gadget *gadget) +{ + if (!gadget->ops->pullup) + return -EOPNOTSUPP; + return gadget->ops->pullup(gadget, 0); +} + + +/*-------------------------------------------------------------------------*/ + +/** + * struct usb_gadget_driver - driver for usb 'slave' devices + * @function: String describing the gadget's function + * @max_speed: Highest speed the driver handles. + * @setup: Invoked for ep0 control requests that aren't handled by + * the hardware level driver. Most calls must be handled by + * the gadget driver, including descriptor and configuration + * management. The 16 bit members of the setup data are in + * USB byte order. Called in_interrupt; this may not sleep. Driver + * queues a response to ep0, or returns negative to stall. + * @disconnect: Invoked after all transfers have been stopped, + * when the host is disconnected. May be called in_interrupt; this + * may not sleep. Some devices can't detect disconnect, so this might + * not be called except as part of controller shutdown. + * @bind: the driver's bind callback + * @unbind: Invoked when the driver is unbound from a gadget, + * usually from rmmod (after a disconnect is reported). + * Called in a context that permits sleeping. + * @suspend: Invoked on USB suspend. May be called in_interrupt. + * @resume: Invoked on USB resume. May be called in_interrupt. + * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers + * and should be called in_interrupt. + * @driver: Driver model state for this driver. + * + * Devices are disabled till a gadget driver successfully bind()s, which + * means the driver will handle setup() requests needed to enumerate (and + * meet "chapter 9" requirements) then do some useful work. + * + * If gadget->is_otg is true, the gadget driver must provide an OTG + * descriptor during enumeration, or else fail the bind() call. In such + * cases, no USB traffic may flow until both bind() returns without + * having called usb_gadget_disconnect(), and the USB host stack has + * initialized. + * + * Drivers use hardware-specific knowledge to configure the usb hardware. + * endpoint addressing is only one of several hardware characteristics that + * are in descriptors the ep0 implementation returns from setup() calls. + * + * Except for ep0 implementation, most driver code shouldn't need change to + * run on top of different usb controllers. It'll use endpoints set up by + * that ep0 implementation. + * + * The usb controller driver handles a few standard usb requests. Those + * include set_address, and feature flags for devices, interfaces, and + * endpoints (the get_status, set_feature, and clear_feature requests). + * + * Accordingly, the driver's setup() callback must always implement all + * get_descriptor requests, returning at least a device descriptor and + * a configuration descriptor. Drivers must make sure the endpoint + * descriptors match any hardware constraints. Some hardware also constrains + * other descriptors. (The pxa250 allows only configurations 1, 2, or 3). + * + * The driver's setup() callback must also implement set_configuration, + * and should also implement set_interface, get_configuration, and + * get_interface. Setting a configuration (or interface) is where + * endpoints should be activated or (config 0) shut down. + * + * (Note that only the default control endpoint is supported. Neither + * hosts nor devices generally support control traffic except to ep0.) + * + * Most devices will ignore USB suspend/resume operations, and so will + * not provide those callbacks. However, some may need to change modes + * when the host is not longer directing those activities. For example, + * local controls (buttons, dials, etc) may need to be re-enabled since + * the (remote) host can't do that any longer; or an error state might + * be cleared, to make the device behave identically whether or not + * power is maintained. + */ +struct usb_gadget_driver { + char *function; + enum usb_device_speed max_speed; + int (*bind)(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); + void (*unbind)(struct usb_gadget *); + int (*setup)(struct usb_gadget *, + const struct usb_ctrlrequest *); + void (*disconnect)(struct usb_gadget *); + void (*suspend)(struct usb_gadget *); + void (*resume)(struct usb_gadget *); + void (*reset)(struct usb_gadget *); + + /* FIXME support safe rmmod */ + struct device_driver driver; +}; + + + +/*-------------------------------------------------------------------------*/ + +/* driver modules register and unregister, as usual. + * these calls must be made in a context that can sleep. + * + * these will usually be implemented directly by the hardware-dependent + * usb bus interface driver, which will only support a single driver. + */ + +/** + * usb_gadget_probe_driver - probe a gadget driver + * @driver: the driver being registered + * Context: can sleep + * + * Call this in your gadget driver's module initialization function, + * to tell the underlying usb controller driver about your driver. + * The @bind() function will be called to bind it to a gadget before this + * registration call returns. It's expected that the @bind() function will + * be in init sections. + */ +int usb_gadget_probe_driver(struct usb_gadget_driver *driver); + +/** + * usb_gadget_unregister_driver - unregister a gadget driver + * @driver:the driver being unregistered + * Context: can sleep + * + * Call this in your gadget driver's module cleanup function, + * to tell the underlying usb controller that your driver is + * going away. If the controller is connected to a USB host, + * it will first disconnect(). The driver is also requested + * to unbind() and clean up any device state, before this procedure + * finally returns. It's expected that the unbind() functions + * will in in exit sections, so may not be linked in some kernels. + */ +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); + +extern int usb_add_gadget_udc_release(struct device *parent, + struct usb_gadget *gadget, void (*release)(struct device *dev)); +extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); +extern void usb_del_gadget_udc(struct usb_gadget *gadget); +extern int usb_udc_attach_driver(const char *name, + struct usb_gadget_driver *driver); + +/*-------------------------------------------------------------------------*/ + +/* utility to simplify dealing with string descriptors */ + +/** + * struct usb_string - wraps a C string and its USB id + * @id:the (nonzero) ID for this string + * @s:the string, in UTF-8 encoding + * + * If you're using usb_gadget_get_string(), use this to wrap a string + * together with its ID. + */ +struct usb_string { + u8 id; + const char *s; +}; + +/** + * struct usb_gadget_strings - a set of USB strings in a given language + * @language:identifies the strings' language (0x0409 for en-us) + * @strings:array of strings with their ids + * + * If you're using usb_gadget_get_string(), use this to wrap all the + * strings for a given language. + */ +struct usb_gadget_strings { + u16 language; /* 0x0409 for en-us */ + struct usb_string *strings; +}; + +struct usb_gadget_string_container { + struct list_head list; + u8 *stash[0]; +}; + +/* put descriptor for string with that id into buf (buflen >= 256) */ +int usb_gadget_get_string(struct usb_gadget_strings *table, int id, u8 *buf); + +/*-------------------------------------------------------------------------*/ + +/* utility to simplify managing config descriptors */ + +/* write vector of descriptors into buffer */ +int usb_descriptor_fillbuf(void *, unsigned, + const struct usb_descriptor_header **); + +/* build config descriptor from single descriptor vector */ +int usb_gadget_config_buf(const struct usb_config_descriptor *config, + void *buf, unsigned buflen, const struct usb_descriptor_header **desc); + +/* copy a NULL-terminated vector of descriptors */ +struct usb_descriptor_header **usb_copy_descriptors( + struct usb_descriptor_header **); + +/** + * usb_free_descriptors - free descriptors returned by usb_copy_descriptors() + * @v: vector of descriptors + */ +static inline void usb_free_descriptors(struct usb_descriptor_header **v) +{ + kfree(v); +} + +struct usb_function; +int usb_assign_descriptors(struct usb_function *f, + struct usb_descriptor_header **fs, + struct usb_descriptor_header **hs, + struct usb_descriptor_header **ss); +void usb_free_all_descriptors(struct usb_function *f); + +/*-------------------------------------------------------------------------*/ + +/* utility to simplify map/unmap of usb_requests to/from DMA */ + +extern int usb_gadget_map_request(struct usb_gadget *gadget, + struct usb_request *req, int is_in); + +extern void usb_gadget_unmap_request(struct usb_gadget *gadget, + struct usb_request *req, int is_in); + +/*-------------------------------------------------------------------------*/ + +/* utility to set gadget state properly */ + +extern void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state); + +/*-------------------------------------------------------------------------*/ + +/* utility to tell udc core that the bus reset occurs */ +extern void usb_gadget_udc_reset(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); + +/*-------------------------------------------------------------------------*/ + +/* utility to give requests back to the gadget layer */ + +extern void usb_gadget_giveback_request(struct usb_ep *ep, + struct usb_request *req); + +/*-------------------------------------------------------------------------*/ + +/* utility to update vbus status for udc core, it may be scheduled */ +extern void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status); + +/*-------------------------------------------------------------------------*/ + +/* utility wrapping a simple endpoint selection policy */ + +extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, + struct usb_endpoint_descriptor *); + + +extern struct usb_ep *usb_ep_autoconfig_ss(struct usb_gadget *, + struct usb_endpoint_descriptor *, + struct usb_ss_ep_comp_descriptor *); + +extern void usb_ep_autoconfig_reset(struct usb_gadget *); + +#endif /* __LINUX_USB_GADGET_H */ diff --git a/include/linux/usb/gadget_configfs.h b/include/linux/usb/gadget_configfs.h new file mode 100644 index 000000000..d74c0ae98 --- /dev/null +++ b/include/linux/usb/gadget_configfs.h @@ -0,0 +1,110 @@ +#ifndef __GADGET_CONFIGFS__ +#define __GADGET_CONFIGFS__ + +#include <linux/configfs.h> + +int check_user_usb_string(const char *name, + struct usb_gadget_strings *stringtab_dev); + +#define GS_STRINGS_W(__struct, __name) \ + static ssize_t __struct##_##__name##_store(struct __struct *gs, \ + const char *page, size_t len) \ +{ \ + 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 __struct *gs, \ + char *page) \ +{ \ + return sprintf(page, "%s\n", gs->__name ?: ""); \ +} + +#define GS_STRING_ITEM_ATTR(struct_name, name) \ + static struct struct_name##_attribute struct_name##_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + struct_name##_##name##_show, \ + struct_name##_##name##_store) + +#define GS_STRINGS_RW(struct_name, _name) \ + GS_STRINGS_R(struct_name, _name) \ + GS_STRINGS_W(struct_name, _name) \ + GS_STRING_ITEM_ATTR(struct_name, _name) + +#define USB_CONFIG_STRING_RW_OPS(struct_in) \ + CONFIGFS_ATTR_OPS(struct_in); \ + \ +static struct configfs_item_operations struct_in##_langid_item_ops = { \ + .release = struct_in##_attr_release, \ + .show_attribute = struct_in##_attr_show, \ + .store_attribute = struct_in##_attr_store, \ +}; \ + \ +static 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 struct configfs_group_operations struct_in##_strings_ops = { \ + .make_group = &struct_in##_strings_make, \ + .drop_item = &struct_in##_strings_drop, \ +}; \ + \ +static struct config_item_type struct_in##_strings_type = { \ + .ct_group_ops = &struct_in##_strings_ops, \ + .ct_owner = THIS_MODULE, \ +} + +#endif diff --git a/include/linux/usb/gpio_vbus.h b/include/linux/usb/gpio_vbus.h new file mode 100644 index 000000000..837bba604 --- /dev/null +++ b/include/linux/usb/gpio_vbus.h @@ -0,0 +1,32 @@ +/* + * A simple GPIO VBUS sensing driver for B peripheral only devices + * with internal transceivers. + * Optionally D+ pullup can be controlled by a second GPIO. + * + * Copyright (c) 2008 Philipp Zabel <philipp.zabel@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +/** + * struct gpio_vbus_mach_info - configuration for gpio_vbus + * @gpio_vbus: VBUS sensing GPIO + * @gpio_pullup: optional D+ or D- pullup GPIO (else negative/invalid) + * @gpio_vbus_inverted: true if gpio_vbus is active low + * @gpio_pullup_inverted: true if gpio_pullup is active low + * @wakeup: configure gpio_vbus as a wake-up source + * + * The VBUS sensing GPIO should have a pulldown, which will normally be + * part of a resistor ladder turning a 4.0V-5.25V level on VBUS into a + * value the GPIO detects as active. Some systems will use comparators. + */ +struct gpio_vbus_mach_info { + int gpio_vbus; + int gpio_pullup; + bool gpio_vbus_inverted; + bool gpio_pullup_inverted; + bool wakeup; +}; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h new file mode 100644 index 000000000..68b1e836d --- /dev/null +++ b/include/linux/usb/hcd.h @@ -0,0 +1,709 @@ +/* + * Copyright (c) 2001-2002 by David Brownell + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __USB_CORE_HCD_H +#define __USB_CORE_HCD_H + +#ifdef __KERNEL__ + +#include <linux/rwsem.h> +#include <linux/interrupt.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 sharable. + * + * @authorized_default: Specifies if new devices are authorized to + * connect by default or they require explicit + * user space authorization; this bit is settable + * through /sys/class/usb_host/X/authorized_default. + * For the rest is RO, so we don't lock to r/w it. + */ + +/*-------------------------------------------------------------------------*/ + +struct giveback_urb_bh { + bool running; + spinlock_t lock; + struct list_head head; + struct tasklet_struct bh; + struct usb_host_endpoint *completing_ep; +}; + +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 + + /* + * 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 phy *phy; + + /* 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? */ + + /* 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)) + + /* 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 remove_phy:1; /* auto-remove USB phy */ + + /* 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 wireless:1; /* Wireless USB HCD */ + unsigned authorized_default: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 *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) + + /* 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[0] + __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 hcd_timeout { /* timeouts we allocate */ + struct list_head timeout_list; + struct timer_list timer; +}; + +/*-------------------------------------------------------------------------*/ + + +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_LOCAL_MEM 0x0002 /* HC needs local memory */ +#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_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/ +#define HCD_USB3 0x0040 /* USB 3.0 */ +#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, bool hibernated); + + /* 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 contraints. 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); + + /* 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 *); + /* Returns the hardware-chosen device address */ + int (*address_device)(struct usb_hcd *, struct usb_device *udev); + /* 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); + +}; + +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; +} + +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); + +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); + +struct platform_device; +extern void usb_hcd_platform_shutdown(struct platform_device *dev); + +#ifdef CONFIG_PCI +struct pci_dev; +struct pci_device_id; +extern int usb_hcd_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id); +extern void usb_hcd_pci_remove(struct pci_dev *dev); +extern void usb_hcd_pci_shutdown(struct pci_dev *dev); + +extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); + +#ifdef CONFIG_PM +extern const struct dev_pm_ops usb_hcd_pci_pm_ops; +#endif +#endif /* CONFIG_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); + +/* 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_INTERFACE)<<8) +#define EndpointOutRequest \ + ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + +/* class requests from the USB 2.0 hub spec, table 11-15 */ +/* GetBusState and SetHubDescriptor are optional, omitted */ +#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) +#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) +#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) +#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS) +#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS) +#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE) +#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE) + + +/*-------------------------------------------------------------------------*/ + +/* class requests from USB 3.0 hub spec, table 10-5 */ +#define SetHubDepth (0x3000 | HUB_SET_DEPTH) +#define GetPortErrorCount (0x8000 | 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 list_head usb_bus_list; +extern struct mutex usb_bus_list_lock; +extern wait_queue_head_t usb_kill_urb_queue; + +extern int usb_find_interface_driver(struct usb_device *dev, + struct usb_interface *interface); + +#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) + +#ifdef CONFIG_PM +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 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 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(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 */ + +#define RUN_CONTEXT (in_irq() ? "in_irq" \ + : (in_interrupt() ? "in_interrupt" : "can sleep")) + + +/* 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; + +/* Keep track of which host controller drivers are loaded */ +#define USB_UHCI_LOADED 0 +#define USB_OHCI_LOADED 1 +#define USB_EHCI_LOADED 2 +extern unsigned long usb_hcds_loaded; + +#endif /* __KERNEL__ */ + +#endif /* __USB_CORE_HCD_H */ diff --git a/include/linux/usb/input.h b/include/linux/usb/input.h new file mode 100644 index 000000000..0e010b220 --- /dev/null +++ b/include/linux/usb/input.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#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 */ diff --git a/include/linux/usb/iowarrior.h b/include/linux/usb/iowarrior.h new file mode 100644 index 000000000..4fd6513d5 --- /dev/null +++ b/include/linux/usb/iowarrior.h @@ -0,0 +1,42 @@ +#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 */ diff --git a/include/linux/usb/irda.h b/include/linux/usb/irda.h new file mode 100644 index 000000000..e345ceaf7 --- /dev/null +++ b/include/linux/usb/irda.h @@ -0,0 +1,151 @@ +/* + * 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 - 5 mbps + * 10..15 - Reserved + */ +#define USB_IRDA_STATUS_LINK_SPEED 0x0f + +/* 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 */ + diff --git a/include/linux/usb/isp116x.h b/include/linux/usb/isp116x.h new file mode 100644 index 000000000..96ca114e8 --- /dev/null +++ b/include/linux/usb/isp116x.h @@ -0,0 +1,33 @@ +/* + * 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 */ diff --git a/include/linux/usb/isp1301.h b/include/linux/usb/isp1301.h new file mode 100644 index 000000000..d3a851c28 --- /dev/null +++ b/include/linux/usb/isp1301.h @@ -0,0 +1,80 @@ +/* + * NXP ISP1301 USB transceiver driver + * + * Copyright (C) 2012 Roland Stigge <stigge@antcom.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#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 */ diff --git a/include/linux/usb/isp1362.h b/include/linux/usb/isp1362.h new file mode 100644 index 000000000..642684bb9 --- /dev/null +++ b/include/linux/usb/isp1362.h @@ -0,0 +1,46 @@ +/* + * board initialization code should put one of these into dev->platform_data + * and place the isp1362 onto platform_bus. + */ + +#ifndef __LINUX_USB_ISP1362_H__ +#define __LINUX_USB_ISP1362_H__ + +struct isp1362_platform_data { + /* Enable internal pulldown resistors on downstream ports */ + unsigned sel15Kres:1; + /* Clock cannot be stopped */ + unsigned clknotstop:1; + /* On-chip overcurrent protection */ + unsigned oc_enable:1; + /* INT output polarity */ + unsigned int_act_high:1; + /* INT edge or level triggered */ + unsigned int_edge_triggered:1; + /* DREQ output polarity */ + unsigned dreq_act_high:1; + /* DACK input polarity */ + unsigned dack_act_high:1; + /* chip can be resumed via H_WAKEUP pin */ + unsigned remote_wakeup_connected:1; + /* Switch or not to switch (keep always powered) */ + unsigned no_power_switching:1; + /* Ganged port power switching (0) or individual port power switching (1) */ + unsigned power_switching_mode:1; + /* Given port_power, msec/2 after power on till power good */ + u8 potpg; + /* Hardware reset set/clear */ + void (*reset) (struct device *dev, int set); + /* Clock start/stop */ + void (*clock) (struct device *dev, int start); + /* Inter-io delay (ns). The chip is picky about access timings; it + * expects at least: + * 110ns delay between consecutive accesses to DATA_REG, + * 300ns delay between access to ADDR_REG and DATA_REG (registers) + * 462ns delay between access to ADDR_REG and DATA_REG (buffer memory) + * WE MUST NOT be activated during these intervals (even without CS!) + */ + void (*delay) (struct device *dev, unsigned int delay); +}; + +#endif diff --git a/include/linux/usb/isp1760.h b/include/linux/usb/isp1760.h new file mode 100644 index 000000000..de7de53c5 --- /dev/null +++ b/include/linux/usb/isp1760.h @@ -0,0 +1,18 @@ +/* + * board initialization should put one of these into dev->platform_data + * and place the isp1760 onto platform_bus named "isp1760-hcd". + */ + +#ifndef __LINUX_USB_ISP1760_H +#define __LINUX_USB_ISP1760_H + +struct isp1760_platform_data { + unsigned is_isp1761:1; /* Chip is ISP1761 */ + unsigned bus_width_16:1; /* 16/32-bit data bus width */ + unsigned port1_otg:1; /* Port 1 supports OTG */ + unsigned analog_oc:1; /* Analog overcurrent */ + unsigned dack_polarity_high:1; /* DACK active high */ + unsigned dreq_polarity_high:1; /* DREQ active high */ +}; + +#endif /* __LINUX_USB_ISP1760_H */ diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h new file mode 100644 index 000000000..a4ba31ab2 --- /dev/null +++ b/include/linux/usb/m66592.h @@ -0,0 +1,46 @@ +/* + * M66592 driver platform data + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#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 */ + diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h new file mode 100644 index 000000000..7dbecf9a4 --- /dev/null +++ b/include/linux/usb/msm_hsusb.h @@ -0,0 +1,171 @@ +/* linux/include/asm-arm/arch-msm/hsusb.h + * + * Copyright (C) 2008 Google, Inc. + * Author: Brian Swetland <swetland@google.com> + * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM_ARCH_MSM_HSUSB_H +#define __ASM_ARCH_MSM_HSUSB_H + +#include <linux/types.h> +#include <linux/usb/otg.h> +#include <linux/clk.h> + +/** + * OTG control + * + * OTG_NO_CONTROL Id/VBUS notifications not required. Useful in host + * only configuration. + * OTG_PHY_CONTROL Id/VBUS notifications comes form USB PHY. + * OTG_PMIC_CONTROL Id/VBUS notifications comes from PMIC hardware. + * OTG_USER_CONTROL Id/VBUS notifcations comes from User via sysfs. + * + */ +enum otg_control_type { + OTG_NO_CONTROL = 0, + OTG_PHY_CONTROL, + OTG_PMIC_CONTROL, + OTG_USER_CONTROL, +}; + +/** + * PHY used in + * + * INVALID_PHY Unsupported PHY + * CI_45NM_INTEGRATED_PHY Chipidea 45nm integrated PHY + * SNPS_28NM_INTEGRATED_PHY Synopsis 28nm integrated PHY + * + */ +enum msm_usb_phy_type { + INVALID_PHY = 0, + CI_45NM_INTEGRATED_PHY, + SNPS_28NM_INTEGRATED_PHY, +}; + +#define IDEV_CHG_MAX 1500 +#define IUNIT 100 + +/** + * Different states involved in USB charger detection. + * + * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection + * process is not yet started. + * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact. + * USB_CHG_STATE_DCD_DONE Data pin contact is detected. + * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects + * between SDP and DCP/CDP). + * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects + * between DCP and CDP). + * USB_CHG_STATE_DETECTED USB charger type is determined. + * + */ +enum usb_chg_state { + USB_CHG_STATE_UNDEFINED = 0, + USB_CHG_STATE_WAIT_FOR_DCD, + USB_CHG_STATE_DCD_DONE, + USB_CHG_STATE_PRIMARY_DONE, + USB_CHG_STATE_SECONDARY_DONE, + USB_CHG_STATE_DETECTED, +}; + +/** + * USB charger types + * + * USB_INVALID_CHARGER Invalid USB charger. + * USB_SDP_CHARGER Standard downstream port. Refers to a downstream port + * on USB2.0 compliant host/hub. + * USB_DCP_CHARGER Dedicated charger port (AC charger/ Wall charger). + * USB_CDP_CHARGER Charging downstream port. Enumeration can happen and + * IDEV_CHG_MAX can be drawn irrespective of USB state. + * + */ +enum usb_chg_type { + USB_INVALID_CHARGER = 0, + USB_SDP_CHARGER, + USB_DCP_CHARGER, + USB_CDP_CHARGER, +}; + +/** + * struct msm_otg_platform_data - platform device data + * for msm_otg driver. + * @phy_init_seq: PHY configuration sequence values. Value of -1 is reserved as + * "do not overwrite default vaule at this address". + * @phy_init_sz: PHY configuration sequence size. + * @vbus_power: VBUS power on/off routine. + * @power_budget: VBUS power budget in mA (0 will be treated as 500mA). + * @mode: Supported mode (OTG/peripheral/host). + * @otg_control: OTG switch controlled by user/Id pin + */ +struct msm_otg_platform_data { + int *phy_init_seq; + int phy_init_sz; + void (*vbus_power)(bool on); + unsigned power_budget; + enum usb_dr_mode mode; + enum otg_control_type otg_control; + enum msm_usb_phy_type phy_type; + void (*setup_gpio)(enum usb_otg_state state); +}; + +/** + * struct msm_otg: OTG driver data. Shared by HCD and DCD. + * @otg: USB OTG Transceiver structure. + * @pdata: otg device platform data. + * @irq: IRQ number assigned for HSUSB controller. + * @clk: clock struct of usb_hs_clk. + * @pclk: clock struct of usb_hs_pclk. + * @core_clk: clock struct of usb_hs_core_clk. + * @regs: ioremapped register base address. + * @inputs: OTG state machine inputs(Id, SessValid etc). + * @sm_work: OTG state machine work. + * @in_lpm: indicates low power mode (LPM) state. + * @async_int: Async interrupt arrived. + * @cur_power: The amount of mA available from downstream port. + * @chg_work: Charger detection work. + * @chg_state: The state of charger detection process. + * @chg_type: The type of charger attached. + * @dcd_retires: The retry count used to track Data contact + * detection process. + */ +struct msm_otg { + struct usb_phy phy; + struct msm_otg_platform_data *pdata; + int irq; + struct clk *clk; + struct clk *pclk; + struct clk *core_clk; + void __iomem *regs; +#define ID 0 +#define B_SESS_VLD 1 + unsigned long inputs; + struct work_struct sm_work; + atomic_t in_lpm; + int async_int; + unsigned cur_power; + int phy_number; + struct delayed_work chg_work; + enum usb_chg_state chg_state; + enum usb_chg_type chg_type; + u8 dcd_retries; + struct regulator *v3p3; + struct regulator *v1p8; + struct regulator *vddcx; + + struct reset_control *phy_rst; + struct reset_control *link_rst; + int vdd_levels[3]; +}; + +#endif diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h new file mode 100644 index 000000000..a29f6030a --- /dev/null +++ b/include/linux/usb/msm_hsusb_hw.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland <swetland@google.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ +#define __LINUX_USB_GADGET_MSM72K_UDC_H__ + +/* USB phy selector - in TCSR address range */ +#define USB2_PHY_SEL 0xfd4ab000 + +#define USB_AHBBURST (MSM_USB_BASE + 0x0090) +#define USB_AHBMODE (MSM_USB_BASE + 0x0098) +#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ + +#define USB_USBCMD (MSM_USB_BASE + 0x0140) +#define USB_PORTSC (MSM_USB_BASE + 0x0184) +#define USB_OTGSC (MSM_USB_BASE + 0x01A4) +#define USB_USBMODE (MSM_USB_BASE + 0x01A8) +#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) +#define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278) + +#define USBCMD_RESET 2 +#define USB_USBINTR (MSM_USB_BASE + 0x0148) + +#define PORTSC_PHCD (1 << 23) /* phy suspend mode */ +#define PORTSC_PTS_MASK (3 << 30) +#define PORTSC_PTS_ULPI (2 << 30) +#define PORTSC_PTS_SERIAL (3 << 30) + +#define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) +#define ULPI_RUN (1 << 30) +#define ULPI_WRITE (1 << 29) +#define ULPI_READ (0 << 29) +#define ULPI_ADDR(n) (((n) & 255) << 16) +#define ULPI_DATA(n) ((n) & 255) +#define ULPI_DATA_READ(n) (((n) >> 8) & 255) + +/* synopsys 28nm phy registers */ +#define ULPI_PWR_CLK_MNG_REG 0x88 +#define OTG_COMP_DISABLE BIT(0) + +#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ +#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ +#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ +#define PHY_POR_ASSERT (1 << 0) /* USB2 28nm PHY POR ASSERT */ + +/* OTG definitions */ +#define OTGSC_INTSTS_MASK (0x7f << 16) +#define OTGSC_ID (1 << 8) +#define OTGSC_BSV (1 << 11) +#define OTGSC_IDIS (1 << 16) +#define OTGSC_BSVIS (1 << 19) +#define OTGSC_IDIE (1 << 24) +#define OTGSC_BSVIE (1 << 27) + +#endif /* __LINUX_USB_GADGET_MSM72K_UDC_H__ */ diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h new file mode 100644 index 000000000..7774c5986 --- /dev/null +++ b/include/linux/usb/musb-omap.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011-2012 by Texas Instruments + * + * The Inventra Controller Driver for Linux is free software; you + * can redistribute it and/or modify it under the terms of the GNU + * General Public License version 2 as published by the Free Software + * Foundation. + */ + +#ifndef __MUSB_OMAP_H__ +#define __MUSB_OMAP_H__ + +enum omap_musb_vbus_id_status { + OMAP_MUSB_UNKNOWN = 0, + OMAP_MUSB_ID_GROUND, + OMAP_MUSB_ID_FLOAT, + OMAP_MUSB_VBUS_VALID, + OMAP_MUSB_VBUS_OFF, +}; + +#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \ + defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)) +void omap_musb_mailbox(enum omap_musb_vbus_id_status status); +#else +static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status) +{ +} +#endif + +#endif /* __MUSB_OMAP_H__ */ diff --git a/include/linux/usb/musb-ux500.h b/include/linux/usb/musb-ux500.h new file mode 100644 index 000000000..1e2c7130f --- /dev/null +++ b/include/linux/usb/musb-ux500.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 ST-Ericsson AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#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__ */ diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h new file mode 100644 index 000000000..a4ee1b582 --- /dev/null +++ b/include/linux/usb/musb.h @@ -0,0 +1,155 @@ +/* + * 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 { + 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 */ + unsigned soft_con:1 __deprecated; /* soft connect required */ + unsigned utm_16:1 __deprecated; /* utm data witdh is 16 bits */ + unsigned big_endian:1; /* true if CPU uses big-endian */ + unsigned mult_bulk_tx:1; /* Tx ep required for multbulk pkts */ + unsigned mult_bulk_rx:1; /* Rx ep required for multbulk pkts */ + unsigned high_iso_tx:1; /* Tx ep required for HB iso */ + unsigned high_iso_rx:1; /* Rx ep required for HD iso */ + unsigned dma:1 __deprecated; /* supports DMA */ + unsigned vendor_req:1 __deprecated; /* vendor registers required */ + + /* 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 dma_channels __deprecated; /* number of dma channels */ + u8 dyn_fifo_size; /* dynamic size in bytes */ + u8 vendor_ctrl __deprecated; /* vendor control reg width */ + u8 vendor_stat __deprecated; /* vendor status reg witdh */ + u8 dma_req_chan __deprecated; /* bitmask for required dma channels */ + u8 ram_bits; /* ram address size */ + + struct musb_hdrc_eps_bits *eps_bits __deprecated; +#ifdef CONFIG_BLACKFIN + /* A GPIO controlling VRSEL in Blackfin */ + unsigned int gpio_vrsel; + unsigned int gpio_vrsel_active; + /* musb CLKIN in Blackfin in MHZ */ + unsigned char clkin; +#endif + +}; + +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; + + /* Power the device on or off */ + int (*set_power)(int state); + + /* MUSB configuration-specific details */ + struct musb_hdrc_config *config; + + /* Architecture specific board data */ + void *board_data; + + /* Platform specific struct musb_ops pointer */ + const void *platform_ops; +}; + + +/* 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 */ + +#ifdef CONFIG_ARCH_OMAP2 + +extern int __init tusb6010_setup_interface( + struct musb_hdrc_platform_data *data, + unsigned ps_refclk, unsigned waitpin, + unsigned async_cs, unsigned sync_cs, + unsigned irq, unsigned dmachan); + +extern int tusb6010_platform_retime(unsigned is_refclk); + +#endif /* OMAP2 */ + +#endif /* __LINUX_USB_MUSB_H */ diff --git a/include/linux/usb/net2280.h b/include/linux/usb/net2280.h new file mode 100644 index 000000000..148b8fa5b --- /dev/null +++ b/include/linux/usb/net2280.h @@ -0,0 +1,443 @@ +/* + * 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 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#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 + 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 */ diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h new file mode 100644 index 000000000..cfe0528cd --- /dev/null +++ b/include/linux/usb/of.h @@ -0,0 +1,45 @@ +/* + * OF helpers for usb devices. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_USB_OF_H +#define __LINUX_USB_OF_H + +#include <linux/usb/ch9.h> +#include <linux/usb/otg.h> +#include <linux/usb/phy.h> + +#if IS_ENABLED(CONFIG_OF) +enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np); +enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np); +bool of_usb_host_tpl_support(struct device_node *np); +#else +static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) +{ + return USB_DR_MODE_UNKNOWN; +} + +static inline enum usb_device_speed +of_usb_get_maximum_speed(struct device_node *np) +{ + return USB_SPEED_UNKNOWN; +} +static inline bool of_usb_host_tpl_support(struct device_node *np) +{ + return false; +} +#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 */ diff --git a/include/linux/usb/ohci_pdriver.h b/include/linux/usb/ohci_pdriver.h new file mode 100644 index 000000000..012f2b7eb --- /dev/null +++ b/include/linux/usb/ohci_pdriver.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#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 */ diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h new file mode 100644 index 000000000..f728f1854 --- /dev/null +++ b/include/linux/usb/otg-fsm.h @@ -0,0 +1,246 @@ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_USB_OTG_FSM_H +#define __LINUX_USB_OTG_FSM_H + +#include <linux/mutex.h> +#include <linux/errno.h> + +#undef VERBOSE + +#ifdef VERBOSE +#define VDBG(fmt, args...) pr_debug("[%s] " fmt , \ + __func__, ## args) +#else +#define VDBG(stuff...) do {} while (0) +#endif + +#ifdef VERBOSE +#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__) +#else +#define MPC_LOC do {} while (0) +#endif + +#define PROTO_UNDEF (0) +#define PROTO_HOST (1) +#define PROTO_GADGET (2) + +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, + + /* Auxiliary timers */ + B_SE0_SRP, + B_SRP_FAIL, + A_WAIT_ENUM, + B_DATA_PLS, + B_SSEND_SRP, + + NUM_OTG_FSM_TIMERS, +}; + +/* OTG state machine according to the OTG spec */ +struct otg_fsm { + /* Input */ + int id; + int adp_change; + int power_up; + int test_device; + int a_bus_drop; + int a_bus_req; + int a_srp_det; + int a_vbus_vld; + int b_conn; + int a_bus_resume; + int a_bus_suspend; + int a_conn; + int b_bus_req; + int b_se0_srp; + int b_ssend_srp; + int b_sess_vld; + /* Auxilary inputs */ + int a_sess_vld; + int b_bus_resume; + int b_bus_suspend; + + /* Output */ + int data_pulse; + int drv_vbus; + int loc_conn; + int loc_sof; + int adp_prb; + int adp_sns; + + /* Internal variables */ + int a_set_b_hnp_en; + int b_srp_done; + int b_hnp_enable; + int a_clr_err; + + /* Informative variables */ + int a_bus_drop_inf; + int a_bus_req_inf; + int a_clr_err_inf; + int b_bus_req_inf; + /* Auxilary 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; +}; + +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 */ diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h new file mode 100644 index 000000000..52661c5da --- /dev/null +++ b/include/linux/usb/otg.h @@ -0,0 +1,107 @@ +/* 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); + +}; + +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, +}; + +#endif /* __LINUX_USB_OTG_H */ diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h new file mode 100644 index 000000000..bc91b5d38 --- /dev/null +++ b/include/linux/usb/phy.h @@ -0,0 +1,329 @@ +/* + * 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/notifier.h> +#include <linux/usb.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 transceivers 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_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; + + /* 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 transceivers */ + struct list_head head; + + /* initialize/shutdown the OTG controller */ + 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 transceiver 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); +}; + +/** + * struct usb_phy_bind - represent the binding for the phy + * @dev_name: the device name of the device that will bind to the phy + * @phy_dev_name: the device name of the phy + * @index: used if a single controller uses multiple phys + * @phy: reference to the phy + * @list: to maintain a linked list of the binding information + */ +struct usb_phy_bind { + const char *dev_name; + const char *phy_dev_name; + u8 index; + struct usb_phy *phy; + struct list_head list; +}; + +/* 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 *usb_get_phy_dev(struct device *dev, u8 index); +extern struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index); +extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, + const char *phandle, u8 index); +extern void usb_put_phy(struct usb_phy *); +extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); +extern int usb_bind_phy(const char *dev_name, u8 index, + const char *phy_dev_name); +extern void usb_phy_set_event(struct usb_phy *x, unsigned long event); +#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 *usb_get_phy_dev(struct device *dev, u8 index) +{ + return ERR_PTR(-ENXIO); +} + +static inline struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) +{ + 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 void usb_put_phy(struct usb_phy *x) +{ +} + +static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x) +{ +} + +static inline int usb_bind_phy(const char *dev_name, u8 index, + const char *phy_dev_name) +{ + return -EOPNOTSUPP; +} + +static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event) +{ +} +#endif + +static inline int +usb_phy_set_power(struct usb_phy *x, unsigned mA) +{ + if (x && 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 */ diff --git a/include/linux/usb/phy_companion.h b/include/linux/usb/phy_companion.h new file mode 100644 index 000000000..edd2ec23d --- /dev/null +++ b/include/linux/usb/phy_companion.h @@ -0,0 +1,34 @@ +/* + * phy-companion.h -- phy companion to indicate the comparator part of PHY + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Author: Kishon Vijay Abraham I <kishon@ti.com> + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#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 */ diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h new file mode 100644 index 000000000..9948c874e --- /dev/null +++ b/include/linux/usb/quirks.h @@ -0,0 +1,50 @@ +/* + * 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 interupt 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) + +#endif /* __LINUX_USB_QUIRKS_H */ diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h new file mode 100644 index 000000000..55805f9dc --- /dev/null +++ b/include/linux/usb/r8a66597.h @@ -0,0 +1,481 @@ +/* + * R8A66597 driver platform data + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#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 */ + diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h new file mode 100644 index 000000000..f06529c14 --- /dev/null +++ b/include/linux/usb/renesas_usbhs.h @@ -0,0 +1,216 @@ +/* + * Renesas USB + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef RENESAS_USB_H +#define RENESAS_USB_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 table for driver + * + * These functions are called from platform for driver. + * Callback function's pointer will be set before + * renesas_usbhs_platform_callback :: hardware_init was called + */ +struct renesas_usbhs_driver_callback { + int (*notify_hotplug)(struct platform_device *pdev); +}; + +/* + * 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); +}; + +/* + * parameters for renesas usbhs + * + * some register needs USB chip specific parameters. + * This struct show it to driver + */ +struct renesas_usbhs_driver_param { + /* + * pipe settings + */ + u32 *pipe_type; /* array of USB_ENDPOINT_XFER_xxx (from ep0) */ + int pipe_size; /* pipe_type 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 */ + + u32 type; + u32 enable_gpio; + + /* + * option: + */ + u32 has_otg:1; /* for controlling PWEN/EXTLP */ + u32 has_sudmac:1; /* for SUDMAC */ + u32 has_usb_dmac:1; /* for USB-DMAC */ +#define USBHS_USB_DMAC_XFER_SIZE 32 /* hardcode the xfer size */ +}; + +#define USBHS_TYPE_R8A7790 1 +#define USBHS_TYPE_R8A7791 2 + +/* + * 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; + + /* + * driver set these callback functions pointer. + * platform can use it on callback functions + */ + struct renesas_usbhs_driver_callback driver_callback; + + /* + * option: + * + * driver use these param for some register + */ + struct renesas_usbhs_driver_param driver_param; +}; + +/* + * macro for platform + */ +#define renesas_usbhs_get_info(pdev)\ + ((struct renesas_usbhs_platform_info *)(pdev)->dev.platform_data) + +#define renesas_usbhs_call_notify_hotplug(pdev) \ + ({ \ + struct renesas_usbhs_driver_callback *dc; \ + dc = &(renesas_usbhs_get_info(pdev)->driver_callback); \ + if (dc && dc->notify_hotplug) \ + dc->notify_hotplug(pdev); \ + }) +#endif /* RENESAS_USB_H */ diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h new file mode 100644 index 000000000..d44ef85db --- /dev/null +++ b/include/linux/usb/rndis_host.h @@ -0,0 +1,210 @@ +/* + * Host Side support for RNDIS Networking Links + * Copyright (C) 2005 by David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#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 */ + +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 */ diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h new file mode 100644 index 000000000..916782699 --- /dev/null +++ b/include/linux/usb/samsung_usb_phy.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * http://www.samsung.com/ + * + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +enum samsung_usb_phy_type { + USB_PHY_TYPE_DEVICE, + USB_PHY_TYPE_HOST, +}; diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h new file mode 100644 index 000000000..704a1ab82 --- /dev/null +++ b/include/linux/usb/serial.h @@ -0,0 +1,414 @@ +/* + * USB Serial Converter stuff + * + * Copyright (C) 1999 - 2012 + * Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + */ + +#ifndef __LINUX_USB_SERIAL_H +#define __LINUX_USB_SERIAL_H + +#include <linux/kref.h> +#include <linux/mutex.h> +#include <linux/serial.h> +#include <linux/sysrq.h> +#include <linux/kfifo.h> + +/* The maximum number of ports one device can grab at once */ +#define MAX_NUM_PORTS 8 + +/* parity check flag */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +/* USB serial flags */ +#define USB_SERIAL_WRITE_BUSY 0 + +/** + * 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 + * @write_wait: a wait_queue_head_t used by the port. + * @work: work queue entry for the line discipline waking up. + * @throttled: nonzero if the read urb is inactive to throttle the device + * @throttle_req: nonzero if the tty wants to throttle us + * @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; + wait_queue_head_t write_wait; + struct work_struct work; + char throttled; + char throttle_req; + 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 + * @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; + unsigned char disconnected:1; + unsigned char suspending:1; + unsigned char attached:1; + unsigned char minors_reserved:1; + unsigned char num_ports; + unsigned char num_port_pointers; + char num_interrupt_in; + char num_interrupt_out; + char num_bulk_in; + 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; +} + +/** + * 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. + * @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 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 + * 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; + char num_ports; + + struct list_head driver_list; + struct device_driver driver; + struct usb_driver *usb_driver; + struct usb_dynids dynids; + + 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); + + void (*disconnect)(struct usb_serial *serial); + void (*release)(struct usb_serial *serial); + + int (*port_probe)(struct usb_serial_port *port); + int (*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 */ + int (*write_room)(struct tty_struct *tty); + int (*ioctl)(struct tty_struct *tty, + unsigned int cmd, unsigned long arg); + void (*set_termios)(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old); + void (*break_ctl)(struct tty_struct *tty, int break_state); + 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) + +extern int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[], + const char *name, const struct usb_device_id *id_table); +extern void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]); +extern void usb_serial_port_softint(struct usb_serial_port *port); + +extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); +extern int usb_serial_resume(struct usb_interface *intf); + +/* USB Serial console functions */ +#ifdef CONFIG_USB_SERIAL_CONSOLE +extern void usb_serial_console_init(int minor); +extern void usb_serial_console_exit(void); +extern 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 */ +extern struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor); +extern void usb_serial_put(struct usb_serial *serial); +extern int usb_serial_generic_open(struct tty_struct *tty, + struct usb_serial_port *port); +extern int usb_serial_generic_write_start(struct usb_serial_port *port, + gfp_t mem_flags); +extern int usb_serial_generic_write(struct tty_struct *tty, + struct usb_serial_port *port, const unsigned char *buf, int count); +extern void usb_serial_generic_close(struct usb_serial_port *port); +extern int usb_serial_generic_resume(struct usb_serial *serial); +extern int usb_serial_generic_write_room(struct tty_struct *tty); +extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); +extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty, + long timeout); +extern void usb_serial_generic_read_bulk_callback(struct urb *urb); +extern void usb_serial_generic_write_bulk_callback(struct urb *urb); +extern void usb_serial_generic_throttle(struct tty_struct *tty); +extern void usb_serial_generic_unthrottle(struct tty_struct *tty); +extern int usb_serial_generic_tiocmiwait(struct tty_struct *tty, + unsigned long arg); +extern int usb_serial_generic_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); +extern int usb_serial_generic_register(void); +extern void usb_serial_generic_deregister(void); +extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, + gfp_t mem_flags); +extern void usb_serial_generic_process_read_urb(struct urb *urb); +extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, + void *dest, size_t size); +extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, + unsigned int ch); +extern int usb_serial_handle_break(struct usb_serial_port *port); +extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, + struct tty_struct *tty, + unsigned int status); + + +extern int usb_serial_bus_register(struct usb_serial_driver *device); +extern void usb_serial_bus_deregister(struct usb_serial_driver *device); + +extern struct usb_serial_driver usb_serial_generic_device; +extern 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 inifinite 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 */ + diff --git a/include/linux/usb/sl811.h b/include/linux/usb/sl811.h new file mode 100644 index 000000000..3afe4d16f --- /dev/null +++ b/include/linux/usb/sl811.h @@ -0,0 +1,29 @@ +/* + * 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 */ diff --git a/include/linux/usb/storage.h b/include/linux/usb/storage.h new file mode 100644 index 000000000..cb33fff2b --- /dev/null +++ b/include/linux/usb/storage.h @@ -0,0 +1,86 @@ +#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 + * + * Distributed under the terms of the GNU GPL, version two. + */ + +/* 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 0 */ + __u8 Lun; /* LUN normally 0 */ + __u8 Length; /* of 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; /* should = '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 + +#endif diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h new file mode 100644 index 000000000..1de16c324 --- /dev/null +++ b/include/linux/usb/tegra_usb_phy.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __TEGRA_USB_PHY_H +#define __TEGRA_USB_PHY_H + +#include <linux/clk.h> +#include <linux/usb/otg.h> + +/* + * 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 + */ + +struct tegra_phy_soc_config { + bool utmi_pll_config_in_car_module; + bool has_hostpc; + bool requires_usbmode_setup; + bool requires_extra_tuning_parameters; +}; + +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 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; + 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; + bool is_ulpi_phy; + int reset_gpio; +}; + +void tegra_usb_phy_preresume(struct usb_phy *phy); + +void tegra_usb_phy_postresume(struct usb_phy *phy); + +void tegra_ehci_phy_restore_start(struct usb_phy *phy, + enum tegra_usb_phy_port_speed port_speed); + +void tegra_ehci_phy_restore_end(struct usb_phy *phy); + +#endif /* __TEGRA_USB_PHY_H */ diff --git a/include/linux/usb/tilegx.h b/include/linux/usb/tilegx.h new file mode 100644 index 000000000..2d65e3435 --- /dev/null +++ b/include/linux/usb/tilegx.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + * + * Structure to contain platform-specific data related to Tile-Gx USB + * controllers. + */ + +#ifndef _LINUX_USB_TILEGX_H +#define _LINUX_USB_TILEGX_H + +#include <gxio/usb_host.h> + +struct tilegx_usb_platform_data { + /* GXIO device index. */ + int dev_index; + + /* GXIO device context. */ + gxio_usb_host_context_t usb_ctx; + + /* Device IRQ. */ + unsigned int irq; +}; + +#endif /* _LINUX_USB_TILEGX_H */ diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h new file mode 100644 index 000000000..3fc8e8b9f --- /dev/null +++ b/include/linux/usb/uas.h @@ -0,0 +1,109 @@ +#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 diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h new file mode 100644 index 000000000..5c295c26a --- /dev/null +++ b/include/linux/usb/ulpi.h @@ -0,0 +1,200 @@ +/* + * ulpi.h -- ULPI defines and function prorotypes + * + * Copyright (C) 2010 Nokia Corporation + * + * This software is distributed under the terms of the GNU General + * Public License ("GPL") as published by the Free Software Foundation, + * version 2 of that License. + */ + +#ifndef __LINUX_USB_ULPI_H +#define __LINUX_USB_ULPI_H + +#include <linux/usb/otg.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) + +/*-------------------------------------------------------------------------*/ + +/* + * Macros for Set and Clear + * See ULPI 1.1 specification to find the registers with Set and Clear offsets + */ +#define ULPI_SET(a) (a + 1) +#define ULPI_CLR(a) (a + 2) + +/*-------------------------------------------------------------------------*/ + +/* + * Register Map + */ +#define ULPI_VENDOR_ID_LOW 0x00 +#define ULPI_VENDOR_ID_HIGH 0x01 +#define ULPI_PRODUCT_ID_LOW 0x02 +#define ULPI_PRODUCT_ID_HIGH 0x03 +#define ULPI_FUNC_CTRL 0x04 +#define ULPI_IFC_CTRL 0x07 +#define ULPI_OTG_CTRL 0x0a +#define ULPI_USB_INT_EN_RISE 0x0d +#define ULPI_USB_INT_EN_FALL 0x10 +#define ULPI_USB_INT_STS 0x13 +#define ULPI_USB_INT_LATCH 0x14 +#define ULPI_DEBUG 0x15 +#define ULPI_SCRATCH 0x16 +/* Optional Carkit Registers */ +#define ULPI_CARCIT_CTRL 0x19 +#define ULPI_CARCIT_INT_DELAY 0x1c +#define ULPI_CARCIT_INT_EN 0x1d +#define ULPI_CARCIT_INT_STS 0x20 +#define ULPI_CARCIT_INT_LATCH 0x21 +#define ULPI_CARCIT_PLS_CTRL 0x22 +/* Other Optional Registers */ +#define ULPI_TX_POS_WIDTH 0x25 +#define ULPI_TX_NEG_WIDTH 0x26 +#define ULPI_POLARITY_RECOVERY 0x27 +/* Access Extended Register Set */ +#define ULPI_ACCESS_EXTENDED 0x2f +/* Vendor Specific */ +#define ULPI_VENDOR_SPECIFIC 0x30 +/* Extended Registers */ +#define ULPI_EXT_VENDOR_SPECIFIC 0x80 + +/*-------------------------------------------------------------------------*/ + +/* + * Register Bits + */ + +/* Function Control */ +#define ULPI_FUNC_CTRL_XCVRSEL (1 << 0) +#define ULPI_FUNC_CTRL_XCVRSEL_MASK (3 << 0) +#define ULPI_FUNC_CTRL_HIGH_SPEED (0 << 0) +#define ULPI_FUNC_CTRL_FULL_SPEED (1 << 0) +#define ULPI_FUNC_CTRL_LOW_SPEED (2 << 0) +#define ULPI_FUNC_CTRL_FS4LS (3 << 0) +#define ULPI_FUNC_CTRL_TERMSELECT (1 << 2) +#define ULPI_FUNC_CTRL_OPMODE (1 << 3) +#define ULPI_FUNC_CTRL_OPMODE_MASK (3 << 3) +#define ULPI_FUNC_CTRL_OPMODE_NORMAL (0 << 3) +#define ULPI_FUNC_CTRL_OPMODE_NONDRIVING (1 << 3) +#define ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI (2 << 3) +#define ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP (3 << 3) +#define ULPI_FUNC_CTRL_RESET (1 << 5) +#define ULPI_FUNC_CTRL_SUSPENDM (1 << 6) + +/* Interface Control */ +#define ULPI_IFC_CTRL_6_PIN_SERIAL_MODE (1 << 0) +#define ULPI_IFC_CTRL_3_PIN_SERIAL_MODE (1 << 1) +#define ULPI_IFC_CTRL_CARKITMODE (1 << 2) +#define ULPI_IFC_CTRL_CLOCKSUSPENDM (1 << 3) +#define ULPI_IFC_CTRL_AUTORESUME (1 << 4) +#define ULPI_IFC_CTRL_EXTERNAL_VBUS (1 << 5) +#define ULPI_IFC_CTRL_PASSTHRU (1 << 6) +#define ULPI_IFC_CTRL_PROTECT_IFC_DISABLE (1 << 7) + +/* OTG Control */ +#define ULPI_OTG_CTRL_ID_PULLUP (1 << 0) +#define ULPI_OTG_CTRL_DP_PULLDOWN (1 << 1) +#define ULPI_OTG_CTRL_DM_PULLDOWN (1 << 2) +#define ULPI_OTG_CTRL_DISCHRGVBUS (1 << 3) +#define ULPI_OTG_CTRL_CHRGVBUS (1 << 4) +#define ULPI_OTG_CTRL_DRVVBUS (1 << 5) +#define ULPI_OTG_CTRL_DRVVBUS_EXT (1 << 6) +#define ULPI_OTG_CTRL_EXTVBUSIND (1 << 7) + +/* USB Interrupt Enable Rising, + * USB Interrupt Enable Falling, + * USB Interrupt Status and + * USB Interrupt Latch + */ +#define ULPI_INT_HOST_DISCONNECT (1 << 0) +#define ULPI_INT_VBUS_VALID (1 << 1) +#define ULPI_INT_SESS_VALID (1 << 2) +#define ULPI_INT_SESS_END (1 << 3) +#define ULPI_INT_IDGRD (1 << 4) + +/* Debug */ +#define ULPI_DEBUG_LINESTATE0 (1 << 0) +#define ULPI_DEBUG_LINESTATE1 (1 << 1) + +/* Carkit Control */ +#define ULPI_CARKIT_CTRL_CARKITPWR (1 << 0) +#define ULPI_CARKIT_CTRL_IDGNDDRV (1 << 1) +#define ULPI_CARKIT_CTRL_TXDEN (1 << 2) +#define ULPI_CARKIT_CTRL_RXDEN (1 << 3) +#define ULPI_CARKIT_CTRL_SPKLEFTEN (1 << 4) +#define ULPI_CARKIT_CTRL_SPKRIGHTEN (1 << 5) +#define ULPI_CARKIT_CTRL_MICEN (1 << 6) + +/* Carkit Interrupt Enable */ +#define ULPI_CARKIT_INT_EN_IDFLOAT_RISE (1 << 0) +#define ULPI_CARKIT_INT_EN_IDFLOAT_FALL (1 << 1) +#define ULPI_CARKIT_INT_EN_CARINTDET (1 << 2) +#define ULPI_CARKIT_INT_EN_DP_RISE (1 << 3) +#define ULPI_CARKIT_INT_EN_DP_FALL (1 << 4) + +/* Carkit Interrupt Status and + * Carkit Interrupt Latch + */ +#define ULPI_CARKIT_INT_IDFLOAT (1 << 0) +#define ULPI_CARKIT_INT_CARINTDET (1 << 1) +#define ULPI_CARKIT_INT_DP (1 << 2) + +/* Carkit Pulse Control*/ +#define ULPI_CARKIT_PLS_CTRL_TXPLSEN (1 << 0) +#define ULPI_CARKIT_PLS_CTRL_RXPLSEN (1 << 1) +#define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN (1 << 2) +#define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN (1 << 3) + +/*-------------------------------------------------------------------------*/ + +#if IS_ENABLED(CONFIG_USB_ULPI) +struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops, + unsigned int flags); +#else +static inline struct usb_phy *otg_ulpi_create(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 */ diff --git a/include/linux/usb/usb338x.h b/include/linux/usb/usb338x.h new file mode 100644 index 000000000..f92eb635b --- /dev/null +++ b/include/linux/usb/usb338x.h @@ -0,0 +1,199 @@ +/* + * 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 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#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 + +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 unused[2]; + 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 + u32 ll_general_ctrl3; + u32 ll_general_ctrl4; + u32 ll_error_gen; +} __packed; + +struct usb338x_ll_lfps_regs { + /* offset 0x748 */ + u32 ll_lfps_5; +#define TIMER_LFPS_6US 16 + u32 ll_lfps_6; +#define TIMER_LFPS_80US 0 +} __packed; + +struct usb338x_ll_tsn_regs { + /* offset 0x77C */ + u32 ll_tsn_counters_2; +#define HOT_TX_NORESET_TS2 24 + u32 ll_tsn_counters_3; +#define HOT_RX_RESET_TS2 0 +} __packed; + +struct usb338x_ll_chi_regs { + /* offset 0x79C */ + 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 */ diff --git a/include/linux/usb/usb_phy_generic.h b/include/linux/usb/usb_phy_generic.h new file mode 100644 index 000000000..c13632d52 --- /dev/null +++ b/include/linux/usb/usb_phy_generic.h @@ -0,0 +1,33 @@ +#ifndef __LINUX_USB_NOP_XCEIV_H +#define __LINUX_USB_NOP_XCEIV_H + +#include <linux/usb/otg.h> +#include <linux/gpio/consumer.h> + +struct usb_phy_generic_platform_data { + enum usb_phy_type type; + unsigned long clk_rate; + + /* if set fails with -EPROBE_DEFER if can't get regulator */ + unsigned int needs_vcc:1; + unsigned int needs_reset:1; /* deprecated */ + int gpio_reset; + struct gpio_desc *gpiod_vbus; +}; + +#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 */ diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h new file mode 100644 index 000000000..6e0ce8c7b --- /dev/null +++ b/include/linux/usb/usbnet.h @@ -0,0 +1,282 @@ +/* + * USB Networking Link Interface + * + * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net> + * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_USB_USBNET_H +#define __LINUX_USB_USBNET_H + +/* interface from usbnet core to each USB networking link we handle */ +struct usbnet { + /* housekeeping */ + struct usb_device *udev; + struct usb_interface *intf; + 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; + + /* 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 tasklet_struct bh; + + 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 +}; + +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 */ + + /* 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 int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); +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 *); + +/* 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); +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_settings(struct net_device *net, + struct ethtool_cmd *cmd); +extern int usbnet_set_settings(struct net_device *net, + struct ethtool_cmd *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_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); +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 */ diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h new file mode 100644 index 000000000..c12571307 --- /dev/null +++ b/include/linux/usb/wusb-wa.h @@ -0,0 +1,303 @@ +/* + * Wireless USB Wire Adapter constants and structures. + * + * Copyright (C) 2005-2006 Intel Corporation. + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + * + * References: + * [WUSB] Wireless Universal Serial Bus Specification, revision 1.0, ch8 + */ +#ifndef __LINUX_USB_WUSB_WA_H +#define __LINUX_USB_WUSB_WA_H + +/** + * Radio Command Request for the Radio Control Interface + * + * Radio Control Interface command and event codes are the same as + * WHCI, and listed in include/linux/uwb.h:UWB_RC_{CMD,EVT}_* + */ +enum { + WA_EXEC_RC_CMD = 40, /* Radio Control command Request */ +}; + +/* Wireless Adapter Requests ([WUSB] table 8-51) */ +enum { + WUSB_REQ_ADD_MMC_IE = 20, + WUSB_REQ_REMOVE_MMC_IE = 21, + WUSB_REQ_SET_NUM_DNTS = 22, + WUSB_REQ_SET_CLUSTER_ID = 23, + WUSB_REQ_SET_DEV_INFO = 24, + WUSB_REQ_GET_TIME = 25, + WUSB_REQ_SET_STREAM_IDX = 26, + WUSB_REQ_SET_WUSB_MAS = 27, + WUSB_REQ_CHAN_STOP = 28, +}; + + +/* Wireless Adapter WUSB Channel Time types ([WUSB] table 8-52) */ +enum { + WUSB_TIME_ADJ = 0, + WUSB_TIME_BPST = 1, + WUSB_TIME_WUSB = 2, +}; + +enum { + WA_ENABLE = 0x01, + WA_RESET = 0x02, + RPIPE_PAUSE = 0x1, + RPIPE_STALL = 0x2, +}; + +/* Responses from Get Status request ([WUSB] section 8.3.1.6) */ +enum { + WA_STATUS_ENABLED = 0x01, + WA_STATUS_RESETTING = 0x02 +}; + +enum rpipe_crs { + RPIPE_CRS_CTL = 0x01, + RPIPE_CRS_ISO = 0x02, + RPIPE_CRS_BULK = 0x04, + RPIPE_CRS_INTR = 0x08 +}; + +/** + * RPipe descriptor ([WUSB] section 8.5.2.11) + * + * FIXME: explain rpipes + */ +struct usb_rpipe_descriptor { + u8 bLength; + u8 bDescriptorType; + __le16 wRPipeIndex; + __le16 wRequests; + __le16 wBlocks; /* rw if 0 */ + __le16 wMaxPacketSize; /* rw */ + union { + u8 dwa_bHSHubAddress; /* rw: DWA. */ + u8 hwa_bMaxBurst; /* rw: HWA. */ + }; + union { + u8 dwa_bHSHubPort; /* rw: DWA. */ + u8 hwa_bDeviceInfoIndex; /* rw: HWA. */ + }; + u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ + union { + u8 dwa_bDeviceAddress; /* rw: DWA Target device address. */ + u8 hwa_reserved; /* rw: HWA. */ + }; + u8 bEndpointAddress; /* rw: Target EP address */ + u8 bDataSequence; /* ro: Current Data sequence */ + __le32 dwCurrentWindow; /* ro */ + u8 bMaxDataSequence; /* ro?: max supported seq */ + u8 bInterval; /* rw: */ + u8 bOverTheAirInterval; /* rw: */ + u8 bmAttribute; /* ro? */ + u8 bmCharacteristics; /* ro? enum rpipe_attr, supported xsactions */ + u8 bmRetryOptions; /* rw? */ + __le16 wNumTransactionErrors; /* rw */ +} __attribute__ ((packed)); + +/** + * Wire Adapter Notification types ([WUSB] sections 8.4.5 & 8.5.4) + * + * These are the notifications coming on the notification endpoint of + * an HWA and a DWA. + */ +enum wa_notif_type { + DWA_NOTIF_RWAKE = 0x91, + DWA_NOTIF_PORTSTATUS = 0x92, + WA_NOTIF_TRANSFER = 0x93, + HWA_NOTIF_BPST_ADJ = 0x94, + HWA_NOTIF_DN = 0x95, +}; + +/** + * Wire Adapter notification header + * + * Notifications coming from a wire adapter use a common header + * defined in [WUSB] sections 8.4.5 & 8.5.4. + */ +struct wa_notif_hdr { + u8 bLength; + u8 bNotifyType; /* enum wa_notif_type */ +} __packed; + +/** + * HWA DN Received notification [(WUSB] section 8.5.4.2) + * + * The DNData is specified in WUSB1.0[7.6]. For each device + * notification we received, we just need to dispatch it. + * + * @dndata: this is really an array of notifications, but all start + * with the same header. + */ +struct hwa_notif_dn { + struct wa_notif_hdr hdr; + u8 bSourceDeviceAddr; /* from errata 2005/07 */ + u8 bmAttributes; + struct wusb_dn_hdr dndata[]; +} __packed; + +/* [WUSB] section 8.3.3 */ +enum wa_xfer_type { + WA_XFER_TYPE_CTL = 0x80, + WA_XFER_TYPE_BI = 0x81, /* bulk/interrupt */ + WA_XFER_TYPE_ISO = 0x82, + WA_XFER_RESULT = 0x83, + WA_XFER_ABORT = 0x84, + WA_XFER_ISO_PACKET_INFO = 0xA0, + WA_XFER_ISO_PACKET_STATUS = 0xA1, +}; + +/* [WUSB] section 8.3.3 */ +struct wa_xfer_hdr { + u8 bLength; /* 0x18 */ + u8 bRequestType; /* 0x80 WA_REQUEST_TYPE_CTL */ + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ + __le32 dwTransferLength; /* Length of data to xfer */ + u8 bTransferSegment; +} __packed; + +struct wa_xfer_ctl { + struct wa_xfer_hdr hdr; + u8 bmAttribute; + __le16 wReserved; + struct usb_ctrlrequest baSetupData; +} __packed; + +struct wa_xfer_bi { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wReserved; +} __packed; + +/* [WUSB] section 8.5.5 */ +struct wa_xfer_hwaiso { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wPresentationTime; + __le32 dwNumOfPackets; +} __packed; + +struct wa_xfer_packet_info_hwaiso { + __le16 wLength; + u8 bPacketType; + u8 bReserved; + __le16 PacketLength[0]; +} __packed; + +struct wa_xfer_packet_status_len_hwaiso { + __le16 PacketLength; + __le16 PacketStatus; +} __packed; + +struct wa_xfer_packet_status_hwaiso { + __le16 wLength; + u8 bPacketType; + u8 bReserved; + struct wa_xfer_packet_status_len_hwaiso PacketStatus[0]; +} __packed; + +/* [WUSB] section 8.3.3.5 */ +struct wa_xfer_abort { + u8 bLength; + u8 bRequestType; + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ +} __packed; + +/** + * WA Transfer Complete notification ([WUSB] section 8.3.3.3) + * + */ +struct wa_notif_xfer { + struct wa_notif_hdr hdr; + u8 bEndpoint; + u8 Reserved; +} __packed; + +/** Transfer result basic codes [WUSB] table 8-15 */ +enum { + WA_XFER_STATUS_SUCCESS, + WA_XFER_STATUS_HALTED, + WA_XFER_STATUS_DATA_BUFFER_ERROR, + WA_XFER_STATUS_BABBLE, + WA_XFER_RESERVED, + WA_XFER_STATUS_NOT_FOUND, + WA_XFER_STATUS_INSUFFICIENT_RESOURCE, + WA_XFER_STATUS_TRANSACTION_ERROR, + WA_XFER_STATUS_ABORTED, + WA_XFER_STATUS_RPIPE_NOT_READY, + WA_XFER_INVALID_FORMAT, + WA_XFER_UNEXPECTED_SEGMENT_NUMBER, + WA_XFER_STATUS_RPIPE_TYPE_MISMATCH, +}; + +/** [WUSB] section 8.3.3.4 */ +struct wa_xfer_result { + struct wa_notif_hdr hdr; + __le32 dwTransferID; + __le32 dwTransferLength; + u8 bTransferSegment; + u8 bTransferStatus; + __le32 dwNumOfPackets; +} __packed; + +/** + * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7). + * + * NOTE: u16 fields are read Little Endian from the hardware. + * + * @bNumPorts is the original max number of devices that the host can + * connect; we might chop this so the stack can handle + * it. In case you need to access it, use wusbhc->ports_max + * if it is a Wireless USB WA. + */ +struct usb_wa_descriptor { + u8 bLength; + u8 bDescriptorType; + __le16 bcdWAVersion; + u8 bNumPorts; /* don't use!! */ + u8 bmAttributes; /* Reserved == 0 */ + __le16 wNumRPipes; + __le16 wRPipeMaxBlock; + u8 bRPipeBlockSize; + u8 bPwrOn2PwrGood; + u8 bNumMMCIEs; + u8 DeviceRemovable; /* FIXME: in DWA this is up to 16 bytes */ +} __packed; + +/** + * HWA Device Information Buffer (WUSB1.0[T8.54]) + */ +struct hwa_dev_info { + u8 bmDeviceAvailability[32]; /* FIXME: ignored for now */ + u8 bDeviceAddress; + __le16 wPHYRates; + u8 bmDeviceAttribute; +} __packed; + +#endif /* #ifndef __LINUX_USB_WUSB_WA_H */ diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h new file mode 100644 index 000000000..eeb28329f --- /dev/null +++ b/include/linux/usb/wusb.h @@ -0,0 +1,377 @@ +/* + * Wireless USB Standard Definitions + * Event Size Tables + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + */ + +#ifndef __WUSB_H__ +#define __WUSB_H__ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/uwb/spec.h> +#include <linux/usb/ch9.h> +#include <linux/param.h> + +/** + * WUSB Information Element header + * + * I don't know why, they decided to make it different to the MBOA MAC + * IE Header; beats me. + */ +struct wuie_hdr { + u8 bLength; + u8 bIEIdentifier; +} __attribute__((packed)); + +enum { + WUIE_ID_WCTA = 0x80, + WUIE_ID_CONNECTACK, + WUIE_ID_HOST_INFO, + WUIE_ID_CHANGE_ANNOUNCE, + WUIE_ID_DEVICE_DISCONNECT, + WUIE_ID_HOST_DISCONNECT, + WUIE_ID_KEEP_ALIVE = 0x89, + WUIE_ID_ISOCH_DISCARD, + WUIE_ID_RESET_DEVICE, +}; + +/** + * Maximum number of array elements in a WUSB IE. + * + * WUSB1.0[7.5 before table 7-38] says that in WUSB IEs that + * are "arrays" have to limited to 4 elements. So we define it + * like that to ease up and submit only the neeed size. + */ +#define WUIE_ELT_MAX 4 + +/** + * Wrapper for the data that defines a CHID, a CDID or a CK + * + * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of + * data. In order to avoid confusion and enforce types, we wrap it. + * + * Make it packed, as we use it in some hw definitions. + */ +struct wusb_ckhdid { + u8 data[16]; +} __attribute__((packed)); + +static const struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } }; + +#define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1) + +/** + * WUSB IE: Host Information (WUSB1.0[7.5.2]) + * + * Used to provide information about the host to the Wireless USB + * devices in range (CHID can be used as an ASCII string). + */ +struct wuie_host_info { + struct wuie_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CHID; +} __attribute__((packed)); + +/** + * WUSB IE: Connect Ack (WUSB1.0[7.5.1]) + * + * Used to acknowledge device connect requests. See note for + * WUIE_ELT_MAX. + */ +struct wuie_connect_ack { + struct wuie_hdr hdr; + struct { + struct wusb_ckhdid CDID; + u8 bDeviceAddress; /* 0 means unused */ + u8 bReserved; + } blk[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE Host Information Element, Connect Availability + * + * WUSB1.0[7.5.2], bmAttributes description + */ +enum { + WUIE_HI_CAP_RECONNECT = 0, + WUIE_HI_CAP_LIMITED, + WUIE_HI_CAP_RESERVED, + WUIE_HI_CAP_ALL, +}; + +/** + * WUSB IE: Channel Stop (WUSB1.0[7.5.8]) + * + * Tells devices the host is going to stop sending MMCs and will disappear. + */ +struct wuie_channel_stop { + struct wuie_hdr hdr; + u8 attributes; + u8 timestamp[3]; +} __attribute__((packed)); + +/** + * WUSB IE: Keepalive (WUSB1.0[7.5.9]) + * + * Ask device(s) to send keepalives. + */ +struct wuie_keep_alive { + struct wuie_hdr hdr; + u8 bDeviceAddress[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE: Reset device (WUSB1.0[7.5.11]) + * + * Tell device to reset; in all truth, we can fit 4 CDIDs, but we only + * use it for one at the time... + * + * In any case, this request is a wee bit silly: why don't they target + * by address?? + */ +struct wuie_reset { + struct wuie_hdr hdr; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +/** + * WUSB IE: Disconnect device (WUSB1.0[7.5.11]) + * + * Tell device to disconnect; we can fit 4 addresses, but we only use + * it for one at the time... + */ +struct wuie_disconnect { + struct wuie_hdr hdr; + u8 bDeviceAddress; + u8 padding; +} __attribute__((packed)); + +/** + * WUSB IE: Host disconnect ([WUSB] section 7.5.5) + * + * Tells all connected devices to disconnect. + */ +struct wuie_host_disconnect { + struct wuie_hdr hdr; +} __attribute__((packed)); + +/** + * WUSB Device Notification header (WUSB1.0[7.6]) + */ +struct wusb_dn_hdr { + u8 bType; + u8 notifdata[]; +} __attribute__((packed)); + +/** Device Notification codes (WUSB1.0[Table 7-54]) */ +enum WUSB_DN { + WUSB_DN_CONNECT = 0x01, + WUSB_DN_DISCONNECT = 0x02, + WUSB_DN_EPRDY = 0x03, + WUSB_DN_MASAVAILCHANGED = 0x04, + WUSB_DN_RWAKE = 0x05, + WUSB_DN_SLEEP = 0x06, + WUSB_DN_ALIVE = 0x07, +}; + +/** WUSB Device Notification Connect */ +struct wusb_dn_connect { + struct wusb_dn_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +static inline int wusb_dn_connect_prev_dev_addr(const struct wusb_dn_connect *dn) +{ + return le16_to_cpu(dn->attributes) & 0xff; +} + +static inline int wusb_dn_connect_new_connection(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 8) & 0x1; +} + +static inline int wusb_dn_connect_beacon_behavior(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 9) & 0x03; +} + +/** Device is alive (aka: pong) (WUSB1.0[7.6.7]) */ +struct wusb_dn_alive { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/** Device is disconnecting (WUSB1.0[7.6.2]) */ +struct wusb_dn_disconnect { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/* General constants */ +enum { + WUSB_TRUST_TIMEOUT_MS = 4000, /* [WUSB] section 4.15.1 */ +}; + +static inline size_t ckhdid_printf(char *pr_ckhdid, size_t size, + const struct wusb_ckhdid *ckhdid) +{ + return scnprintf(pr_ckhdid, size, + "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx " + "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx", + ckhdid->data[0], ckhdid->data[1], + ckhdid->data[2], ckhdid->data[3], + ckhdid->data[4], ckhdid->data[5], + ckhdid->data[6], ckhdid->data[7], + ckhdid->data[8], ckhdid->data[9], + ckhdid->data[10], ckhdid->data[11], + ckhdid->data[12], ckhdid->data[13], + ckhdid->data[14], ckhdid->data[15]); +} + +/* + * WUSB Crypto stuff (WUSB1.0[6]) + */ + +extern const char *wusb_et_name(u8); + +/** + * WUSB key index WUSB1.0[7.3.2.4], for usage when setting keys for + * the host or the device. + */ +static inline u8 wusb_key_index(int index, int type, int originator) +{ + return (originator << 6) | (type << 4) | index; +} + +#define WUSB_KEY_INDEX_TYPE_PTK 0 /* for HWA only */ +#define WUSB_KEY_INDEX_TYPE_ASSOC 1 +#define WUSB_KEY_INDEX_TYPE_GTK 2 +#define WUSB_KEY_INDEX_ORIGINATOR_HOST 0 +#define WUSB_KEY_INDEX_ORIGINATOR_DEVICE 1 +/* bits 0-3 used for the key index. */ +#define WUSB_KEY_INDEX_MAX 15 + +/* A CCM Nonce, defined in WUSB1.0[6.4.1] */ +struct aes_ccm_nonce { + u8 sfn[6]; /* Little Endian */ + u8 tkid[3]; /* LE */ + struct uwb_dev_addr dest_addr; + struct uwb_dev_addr src_addr; +} __attribute__((packed)); + +/* A CCM operation label, defined on WUSB1.0[6.5.x] */ +struct aes_ccm_label { + u8 data[14]; +} __attribute__((packed)); + +/* + * Input to the key derivation sequence defined in + * WUSB1.0[6.5.1]. Rest of the data is in the CCM Nonce passed to the + * PRF function. + */ +struct wusb_keydvt_in { + u8 hnonce[16]; + u8 dnonce[16]; +} __attribute__((packed)); + +/* + * Output from the key derivation sequence defined in + * WUSB1.0[6.5.1]. + */ +struct wusb_keydvt_out { + u8 kck[16]; + u8 ptk[16]; +} __attribute__((packed)); + +/* Pseudo Random Function WUSB1.0[6.5] */ +extern int wusb_crypto_init(void); +extern void wusb_crypto_exit(void); +extern ssize_t wusb_prf(void *out, size_t out_size, + const u8 key[16], const struct aes_ccm_nonce *_n, + const struct aes_ccm_label *a, + const void *b, size_t blen, size_t len); + +static inline int wusb_prf_64(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 64); +} + +static inline int wusb_prf_128(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 128); +} + +static inline int wusb_prf_256(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 256); +} + +/* Key derivation WUSB1.0[6.5.1] */ +static inline int wusb_key_derive(struct wusb_keydvt_out *keydvt_out, + const u8 key[16], + const struct aes_ccm_nonce *n, + const struct wusb_keydvt_in *keydvt_in) +{ + const struct aes_ccm_label a = { .data = "Pair-wise keys" }; + return wusb_prf_256(keydvt_out, sizeof(*keydvt_out), key, n, &a, + keydvt_in, sizeof(*keydvt_in)); +} + +/* + * Out-of-band MIC Generation WUSB1.0[6.5.2] + * + * Compute the MIC over @key, @n and @hs and place it in @mic_out. + * + * @mic_out: Where to place the 8 byte MIC tag + * @key: KCK from the derivation process + * @n: CCM nonce, n->sfn == 0, TKID as established in the + * process. + * @hs: Handshake struct for phase 2 of the 4-way. + * hs->bStatus and hs->bReserved are zero. + * hs->bMessageNumber is 2 (WUSB1.0[7.3.2.5.2] + * hs->dest_addr is the device's USB address padded with 0 + * hs->src_addr is the hosts's UWB device address + * hs->mic is ignored (as we compute that value). + */ +static inline int wusb_oob_mic(u8 mic_out[8], const u8 key[16], + const struct aes_ccm_nonce *n, + const struct usb_handshake *hs) +{ + const struct aes_ccm_label a = { .data = "out-of-bandMIC" }; + return wusb_prf_64(mic_out, 8, key, n, &a, + hs, sizeof(*hs) - sizeof(hs->MIC)); +} + +#endif /* #ifndef __WUSB_H__ */ diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h new file mode 100644 index 000000000..376654b5b --- /dev/null +++ b/include/linux/usb/xhci_pdriver.h @@ -0,0 +1,27 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ + +#ifndef __USB_CORE_XHCI_PDRIVER_H +#define __USB_CORE_XHCI_PDRIVER_H + +/** + * struct usb_xhci_pdata - platform_data for generic xhci platform driver + * + * @usb3_lpm_capable: determines if this xhci platform supports USB3 + * LPM capability + * + */ +struct usb_xhci_pdata { + unsigned usb3_lpm_capable:1; +}; + +#endif /* __USB_CORE_XHCI_PDRIVER_H */ |