USB: Add Intel Langwell USB Device Controller driver

Intel Langwell USB Device Controller is a High-Speed USB OTG device
controller in Intel Moorestown platform. It can work in OTG device mode
with Intel Langwell USB OTG transceiver driver as well as device-only
mode. The number of programmable endpoints is different through
controller revision.

NOTE:
This patch is the first version Intel Langwell USB OTG device controller
driver. The bug fixing is on going for some hardware and software
issues.  Intel Langwell USB OTG transceiver driver and EHCI driver
patches will be submitted later.

Supported features:
 - USB OTG protocol support with Intel Langwell USB OTG transceiver
   driver (turn on CONFIG_USB_LANGWELL_OTG)
 - Support control, bulk, interrupt and isochronous endpoints
   (isochronous not tested)
 - PCI D0/D3 power management support
 - Link Power Management (LPM) support

Tested gadget drivers:
 - g_file_storage
 - g_ether
 - g_zero

The passed tests:
 - g_file_storage: USBCV Chapter 9 tests
 - g_file_storage: USBCV MSC tests
 - g_file_storage: from/to host files copying
 - g_ether: ping, ftp and scp files from/to host
 - Hotplug, with and without hubs

Known issues:
 - g_ether: failed part of USBCV chap9 tests
 - LPM support not fully tested

TODO:
 - g_ether: pass all USBCV chap9 tests
 - g_zero: pass usbtest tests
 - Stress tests on different gadget drivers
 - On-chip private SRAM caching support

Signed-off-by: Xiaochen Shen <xiaochen.shen@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Xiaochen Shen 2009-06-04 15:34:49 +08:00 committed by Greg Kroah-Hartman
parent f9c99bb8b3
commit 5be19a9daa
6 changed files with 3941 additions and 0 deletions

View File

@ -474,6 +474,27 @@ config USB_GOKU
default USB_GADGET
select USB_GADGET_SELECTED
config USB_GADGET_LANGWELL
boolean "Intel Langwell USB Device Controller"
depends on PCI
select USB_GADGET_DUALSPEED
help
Intel Langwell USB Device Controller is a High-Speed USB
On-The-Go device controller.
The number of programmable endpoints is different through
controller revision.
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "langwell_udc" and force all
gadget drivers to also be dynamically linked.
config USB_LANGWELL
tristate
depends on USB_GADGET_LANGWELL
default USB_GADGET
select USB_GADGET_SELECTED
#
# LAST -- dummy/emulated controller

View File

@ -26,6 +26,7 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o
obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o
#
# USB gadget drivers

View File

@ -137,6 +137,12 @@
#define gadget_is_musbhdrc(g) 0
#endif
#ifdef CONFIG_USB_GADGET_LANGWELL
#define gadget_is_langwell(g) (!strcmp("langwell_udc", (g)->name))
#else
#define gadget_is_langwell(g) 0
#endif
/* from Montavista kernel (?) */
#ifdef CONFIG_USB_GADGET_MPC8272
#define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name)
@ -231,6 +237,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x22;
else if (gadget_is_ci13xxx(gadget))
return 0x23;
else if (gadget_is_langwell(gadget))
return 0x24;
return -ENOENT;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,228 @@
/*
* Intel Langwell USB Device Controller driver
* Copyright (C) 2008-2009, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/usb/langwell_udc.h>
#if defined(CONFIG_USB_LANGWELL_OTG)
#include <linux/usb/langwell_otg.h>
#endif
/*-------------------------------------------------------------------------*/
/* driver data structures and utilities */
/*
* dTD: Device Endpoint Transfer Descriptor
* describe to the device controller the location and quantity of
* data to be send/received for given transfer
*/
struct langwell_dtd {
u32 dtd_next;
/* bits 31:5, next transfer element pointer */
#define DTD_NEXT(d) (((d)>>5)&0x7ffffff)
#define DTD_NEXT_MASK (0x7ffffff << 5)
/* terminate */
#define DTD_TERM BIT(0)
/* bits 7:0, execution back states */
u32 dtd_status:8;
#define DTD_STATUS(d) (((d)>>0)&0xff)
#define DTD_STS_ACTIVE BIT(7) /* active */
#define DTD_STS_HALTED BIT(6) /* halted */
#define DTD_STS_DBE BIT(5) /* data buffer error */
#define DTD_STS_TRE BIT(3) /* transaction error */
/* bits 9:8 */
u32 dtd_res0:2;
/* bits 11:10, multipier override */
u32 dtd_multo:2;
#define DTD_MULTO (BIT(11) | BIT(10))
/* bits 14:12 */
u32 dtd_res1:3;
/* bit 15, interrupt on complete */
u32 dtd_ioc:1;
#define DTD_IOC BIT(15)
/* bits 30:16, total bytes */
u32 dtd_total:15;
#define DTD_TOTAL(d) (((d)>>16)&0x7fff)
#define DTD_MAX_TRANSFER_LENGTH 0x4000
/* bit 31 */
u32 dtd_res2:1;
/* dTD buffer pointer page 0 to 4 */
u32 dtd_buf[5];
#define DTD_OFFSET_MASK 0xfff
/* bits 31:12, buffer pointer */
#define DTD_BUFFER(d) (((d)>>12)&0x3ff)
/* bits 11:0, current offset */
#define DTD_C_OFFSET(d) (((d)>>0)&0xfff)
/* bits 10:0, frame number */
#define DTD_FRAME(d) (((d)>>0)&0x7ff)
/* driver-private parts */
/* dtd dma address */
dma_addr_t dtd_dma;
/* next dtd virtual address */
struct langwell_dtd *next_dtd_virt;
};
/*
* dQH: Device Endpoint Queue Head
* describe where all transfers are managed
* 48-byte data structure, aligned on 64-byte boundary
*
* These are associated with dTD structure
*/
struct langwell_dqh {
/* endpoint capabilities and characteristics */
u32 dqh_res0:15; /* bits 14:0 */
u32 dqh_ios:1; /* bit 15, interrupt on setup */
#define DQH_IOS BIT(15)
u32 dqh_mpl:11; /* bits 26:16, maximum packet length */
#define DQH_MPL (0x7ff << 16)
u32 dqh_res1:2; /* bits 28:27 */
u32 dqh_zlt:1; /* bit 29, zero length termination */
#define DQH_ZLT BIT(29)
u32 dqh_mult:2; /* bits 31:30 */
#define DQH_MULT (BIT(30) | BIT(31))
/* current dTD pointer */
u32 dqh_current; /* locate the transfer in progress */
#define DQH_C_DTD(e) \
(((e)>>5)&0x7ffffff) /* bits 31:5, current dTD pointer */
/* transfer overlay, hardware parts of a struct langwell_dtd */
u32 dtd_next;
u32 dtd_status:8; /* bits 7:0, execution back states */
u32 dtd_res0:2; /* bits 9:8 */
u32 dtd_multo:2; /* bits 11:10, multipier override */
u32 dtd_res1:3; /* bits 14:12 */
u32 dtd_ioc:1; /* bit 15, interrupt on complete */
u32 dtd_total:15; /* bits 30:16, total bytes */
u32 dtd_res2:1; /* bit 31 */
u32 dtd_buf[5]; /* dTD buffer pointer page 0 to 4 */
u32 dqh_res2;
struct usb_ctrlrequest dqh_setup; /* setup packet buffer */
} __attribute__ ((aligned(64)));
/* endpoint data structure */
struct langwell_ep {
struct usb_ep ep;
dma_addr_t dma;
struct langwell_udc *dev;
unsigned long irqs;
struct list_head queue;
struct langwell_dqh *dqh;
const struct usb_endpoint_descriptor *desc;
char name[14];
unsigned stopped:1,
ep_type:2,
ep_num:8;
};
/* request data structure */
struct langwell_request {
struct usb_request req;
struct langwell_dtd *dtd, *head, *tail;
struct langwell_ep *ep;
dma_addr_t dtd_dma;
struct list_head queue;
unsigned dtd_count;
unsigned mapped:1;
};
/* ep0 transfer state */
enum ep0_state {
WAIT_FOR_SETUP,
DATA_STATE_XMIT,
DATA_STATE_NEED_ZLP,
WAIT_FOR_OUT_STATUS,
DATA_STATE_RECV,
};
/* device suspend state */
enum lpm_state {
LPM_L0, /* on */
LPM_L1, /* LPM L1 sleep */
LPM_L2, /* suspend */
LPM_L3, /* off */
};
/* device data structure */
struct langwell_udc {
/* each pci device provides one gadget, several endpoints */
struct usb_gadget gadget;
spinlock_t lock; /* device lock */
struct langwell_ep *ep;
struct usb_gadget_driver *driver;
struct otg_transceiver *transceiver;
u8 dev_addr;
u32 usb_state;
u32 resume_state;
u32 bus_reset;
enum lpm_state lpm_state;
enum ep0_state ep0_state;
u32 ep0_dir;
u16 dciversion;
unsigned ep_max;
unsigned devcap:1,
enabled:1,
region:1,
got_irq:1,
powered:1,
remote_wakeup:1,
rate:1,
is_reset:1,
softconnected:1,
vbus_active:1,
suspended:1,
stopped:1,
lpm:1; /* LPM capability */
/* pci state used to access those endpoints */
struct pci_dev *pdev;
/* Langwell otg transceiver */
struct langwell_otg *lotg;
/* control registers */
struct langwell_cap_regs __iomem *cap_regs;
struct langwell_op_regs __iomem *op_regs;
struct usb_ctrlrequest local_setup_buff;
struct langwell_dqh *ep_dqh;
size_t ep_dqh_size;
dma_addr_t ep_dqh_dma;
/* ep0 status request */
struct langwell_request *status_req;
/* dma pool */
struct dma_pool *dtd_pool;
/* make sure release() is done */
struct completion *done;
};

View File

@ -0,0 +1,310 @@
/*
* Intel Langwell USB Device Controller driver
* Copyright (C) 2008-2009, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef __LANGWELL_UDC_H
#define __LANGWELL_UDC_H
/* MACRO defines */
#define CAP_REG_OFFSET 0x0
#define OP_REG_OFFSET 0x28
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
#define DQH_ALIGNMENT 2048
#define DTD_ALIGNMENT 64
#define DMA_BOUNDARY 4096
#define EP0_MAX_PKT_SIZE 64
#define EP_DIR_IN 1
#define EP_DIR_OUT 0
#define FLUSH_TIMEOUT 1000
#define RESET_TIMEOUT 1000
#define SETUPSTAT_TIMEOUT 100
#define PRIME_TIMEOUT 100
/* device memory space registers */
/* Capability Registers, BAR0 + CAP_REG_OFFSET */
struct langwell_cap_regs {
/* offset: 0x0 */
u8 caplength; /* offset of Operational Register */
u8 _reserved3;
u16 hciversion; /* H: BCD encoding of host version */
u32 hcsparams; /* H: host port steering logic capability */
u32 hccparams; /* H: host multiple mode control capability */
#define HCC_LEN BIT(17) /* Link power management (LPM) capability */
u8 _reserved4[0x20-0xc];
/* offset: 0x20 */
u16 dciversion; /* BCD encoding of device version */
u8 _reserved5[0x24-0x22];
u32 dccparams; /* overall device controller capability */
#define HOSTCAP BIT(8) /* host capable */
#define DEVCAP BIT(7) /* device capable */
#define DEN(d) \
(((d)>>0)&0x1f) /* bits 4:0, device endpoint number */
} __attribute__ ((packed));
/* Operational Registers, BAR0 + OP_REG_OFFSET */
struct langwell_op_regs {
/* offset: 0x28 */
u32 extsts;
#define EXTS_TI1 BIT(4) /* general purpose timer interrupt 1 */
#define EXTS_TI1TI0 BIT(3) /* general purpose timer interrupt 0 */
#define EXTS_TI1UPI BIT(2) /* USB host periodic interrupt */
#define EXTS_TI1UAI BIT(1) /* USB host asynchronous interrupt */
#define EXTS_TI1NAKI BIT(0) /* NAK interrupt */
u32 extintr;
#define EXTI_TIE1 BIT(4) /* general purpose timer interrupt enable 1 */
#define EXTI_TIE0 BIT(3) /* general purpose timer interrupt enable 0 */
#define EXTI_UPIE BIT(2) /* USB host periodic interrupt enable */
#define EXTI_UAIE BIT(1) /* USB host asynchronous interrupt enable */
#define EXTI_NAKE BIT(0) /* NAK interrupt enable */
/* offset: 0x30 */
u32 usbcmd;
#define CMD_HIRD(u) \
(((u)>>24)&0xf) /* bits 27:24, host init resume duration */
#define CMD_ITC(u) \
(((u)>>16)&0xff) /* bits 23:16, interrupt threshold control */
#define CMD_PPE BIT(15) /* per-port change events enable */
#define CMD_ATDTW BIT(14) /* add dTD tripwire */
#define CMD_SUTW BIT(13) /* setup tripwire */
#define CMD_ASPE BIT(11) /* asynchronous schedule park mode enable */
#define CMD_FS2 BIT(10) /* frame list size */
#define CMD_ASP1 BIT(9) /* asynchronous schedule park mode count */
#define CMD_ASP0 BIT(8)
#define CMD_LR BIT(7) /* light host/device controller reset */
#define CMD_IAA BIT(6) /* interrupt on async advance doorbell */
#define CMD_ASE BIT(5) /* asynchronous schedule enable */
#define CMD_PSE BIT(4) /* periodic schedule enable */
#define CMD_FS1 BIT(3)
#define CMD_FS0 BIT(2)
#define CMD_RST BIT(1) /* controller reset */
#define CMD_RUNSTOP BIT(0) /* run/stop */
u32 usbsts;
#define STS_PPCI(u) \
(((u)>>16)&0xffff) /* bits 31:16, port-n change detect */
#define STS_AS BIT(15) /* asynchronous schedule status */
#define STS_PS BIT(14) /* periodic schedule status */
#define STS_RCL BIT(13) /* reclamation */
#define STS_HCH BIT(12) /* HC halted */
#define STS_ULPII BIT(10) /* ULPI interrupt */
#define STS_SLI BIT(8) /* DC suspend */
#define STS_SRI BIT(7) /* SOF received */
#define STS_URI BIT(6) /* USB reset received */
#define STS_AAI BIT(5) /* interrupt on async advance */
#define STS_SEI BIT(4) /* system error */
#define STS_FRI BIT(3) /* frame list rollover */
#define STS_PCI BIT(2) /* port change detect */
#define STS_UEI BIT(1) /* USB error interrupt */
#define STS_UI BIT(0) /* USB interrupt */
u32 usbintr;
/* bits 31:16, per-port interrupt enable */
#define INTR_PPCE(u) (((u)>>16)&0xffff)
#define INTR_ULPIE BIT(10) /* ULPI enable */
#define INTR_SLE BIT(8) /* DC sleep/suspend enable */
#define INTR_SRE BIT(7) /* SOF received enable */
#define INTR_URE BIT(6) /* USB reset enable */
#define INTR_AAE BIT(5) /* interrupt on async advance enable */
#define INTR_SEE BIT(4) /* system error enable */
#define INTR_FRE BIT(3) /* frame list rollover enable */
#define INTR_PCE BIT(2) /* port change detect enable */
#define INTR_UEE BIT(1) /* USB error interrupt enable */
#define INTR_UE BIT(0) /* USB interrupt enable */
u32 frindex; /* frame index */
#define FRINDEX_MASK (0x3fff << 0)
u32 ctrldssegment; /* not used */
u32 deviceaddr;
#define USBADR_SHIFT 25
#define USBADR(d) \
(((d)>>25)&0x7f) /* bits 31:25, device address */
#define USBADR_MASK (0x7f << 25)
#define USBADRA BIT(24) /* device address advance */
u32 endpointlistaddr;/* endpoint list top memory address */
/* bits 31:11, endpoint list pointer */
#define EPBASE(d) (((d)>>11)&0x1fffff)
#define ENDPOINTLISTADDR_MASK (0x1fffff << 11)
u32 ttctrl; /* H: TT operatin, not used */
/* offset: 0x50 */
u32 burstsize; /* burst size of data movement */
#define TXPBURST(b) \
(((b)>>8)&0xff) /* bits 15:8, TX burst length */
#define RXPBURST(b) \
(((b)>>0)&0xff) /* bits 7:0, RX burst length */
u32 txfilltuning; /* TX tuning */
u32 txttfilltuning; /* H: TX TT tuning */
u32 ic_usb; /* control the IC_USB FS/LS transceiver */
/* offset: 0x60 */
u32 ulpi_viewport; /* indirect access to ULPI PHY */
#define ULPIWU BIT(31) /* ULPI wakeup */
#define ULPIRUN BIT(30) /* ULPI read/write run */
#define ULPIRW BIT(29) /* ULPI read/write control */
#define ULPISS BIT(27) /* ULPI sync state */
#define ULPIPORT(u) \
(((u)>>24)&7) /* bits 26:24, ULPI port number */
#define ULPIADDR(u) \
(((u)>>16)&0xff) /* bits 23:16, ULPI data address */
#define ULPIDATRD(u) \
(((u)>>8)&0xff) /* bits 15:8, ULPI data read */
#define ULPIDATWR(u) \
(((u)>>0)&0xff) /* bits 7:0, ULPI date write */
u8 _reserved6[0x70-0x64];
/* offset: 0x70 */
u32 configflag; /* H: not used */
u32 portsc1; /* port status */
#define DA(p) \
(((p)>>25)&0x7f) /* bits 31:25, device address */
#define PORTS_SSTS (BIT(24) | BIT(23)) /* suspend status */
#define PORTS_WKOC BIT(22) /* wake on over-current enable */
#define PORTS_WKDS BIT(21) /* wake on disconnect enable */
#define PORTS_WKCN BIT(20) /* wake on connect enable */
#define PORTS_PTC(p) (((p)>>16)&0xf) /* bits 19:16, port test control */
#define PORTS_PIC (BIT(15) | BIT(14)) /* port indicator control */
#define PORTS_PO BIT(13) /* port owner */
#define PORTS_PP BIT(12) /* port power */
#define PORTS_LS (BIT(11) | BIT(10)) /* line status */
#define PORTS_SLP BIT(9) /* suspend using L1 */
#define PORTS_PR BIT(8) /* port reset */
#define PORTS_SUSP BIT(7) /* suspend */
#define PORTS_FPR BIT(6) /* force port resume */
#define PORTS_OCC BIT(5) /* over-current change */
#define PORTS_OCA BIT(4) /* over-current active */
#define PORTS_PEC BIT(3) /* port enable/disable change */
#define PORTS_PE BIT(2) /* port enable/disable */
#define PORTS_CSC BIT(1) /* connect status change */
#define PORTS_CCS BIT(0) /* current connect status */
u8 _reserved7[0xb4-0x78];
/* offset: 0xb4 */
u32 devlc; /* control LPM and each USB port behavior */
/* bits 31:29, parallel transceiver select */
#define LPM_PTS(d) (((d)>>29)&7)
#define LPM_STS BIT(28) /* serial transceiver select */
#define LPM_PTW BIT(27) /* parallel transceiver width */
#define LPM_PSPD(d) (((d)>>25)&3) /* bits 26:25, port speed */
#define LPM_PSPD_MASK (BIT(26) | BIT(25))
#define LPM_SPEED_FULL 0
#define LPM_SPEED_LOW 1
#define LPM_SPEED_HIGH 2
#define LPM_SRT BIT(24) /* shorten reset time */
#define LPM_PFSC BIT(23) /* port force full speed connect */
#define LPM_PHCD BIT(22) /* PHY low power suspend clock disable */
#define LPM_STL BIT(16) /* STALL reply to LPM token */
#define LPM_BA(d) \
(((d)>>1)&0x7ff) /* bits 11:1, BmAttributes */
#define LPM_NYT_ACK BIT(0) /* NYET/ACK reply to LPM token */
u8 _reserved8[0xf4-0xb8];
/* offset: 0xf4 */
u32 otgsc; /* On-The-Go status and control */
#define OTGSC_DPIE BIT(30) /* data pulse interrupt enable */
#define OTGSC_MSE BIT(29) /* 1 ms timer interrupt enable */
#define OTGSC_BSEIE BIT(28) /* B session end interrupt enable */
#define OTGSC_BSVIE BIT(27) /* B session valid interrupt enable */
#define OTGSC_ASVIE BIT(26) /* A session valid interrupt enable */
#define OTGSC_AVVIE BIT(25) /* A VBUS valid interrupt enable */
#define OTGSC_IDIE BIT(24) /* USB ID interrupt enable */
#define OTGSC_DPIS BIT(22) /* data pulse interrupt status */
#define OTGSC_MSS BIT(21) /* 1 ms timer interrupt status */
#define OTGSC_BSEIS BIT(20) /* B session end interrupt status */
#define OTGSC_BSVIS BIT(19) /* B session valid interrupt status */
#define OTGSC_ASVIS BIT(18) /* A session valid interrupt status */
#define OTGSC_AVVIS BIT(17) /* A VBUS valid interrupt status */
#define OTGSC_IDIS BIT(16) /* USB ID interrupt status */
#define OTGSC_DPS BIT(14) /* data bus pulsing status */
#define OTGSC_MST BIT(13) /* 1 ms timer toggle */
#define OTGSC_BSE BIT(12) /* B session end */
#define OTGSC_BSV BIT(11) /* B session valid */
#define OTGSC_ASV BIT(10) /* A session valid */
#define OTGSC_AVV BIT(9) /* A VBUS valid */
#define OTGSC_USBID BIT(8) /* USB ID */
#define OTGSC_HABA BIT(7) /* hw assist B-disconnect to A-connect */
#define OTGSC_HADP BIT(6) /* hw assist data pulse */
#define OTGSC_IDPU BIT(5) /* ID pullup */
#define OTGSC_DP BIT(4) /* data pulsing */
#define OTGSC_OT BIT(3) /* OTG termination */
#define OTGSC_HAAR BIT(2) /* hw assist auto reset */
#define OTGSC_VC BIT(1) /* VBUS charge */
#define OTGSC_VD BIT(0) /* VBUS discharge */
u32 usbmode;
#define MODE_VBPS BIT(5) /* R/W VBUS power select */
#define MODE_SDIS BIT(4) /* R/W stream disable mode */
#define MODE_SLOM BIT(3) /* R/W setup lockout mode */
#define MODE_ENSE BIT(2) /* endian select */
#define MODE_CM(u) (((u)>>0)&3) /* bits 1:0, controller mode */
#define MODE_IDLE 0
#define MODE_DEVICE 2
#define MODE_HOST 3
u8 _reserved9[0x100-0xfc];
/* offset: 0x100 */
u32 endptnak;
#define EPTN(e) \
(((e)>>16)&0xffff) /* bits 31:16, TX endpoint NAK */
#define EPRN(e) \
(((e)>>0)&0xffff) /* bits 15:0, RX endpoint NAK */
u32 endptnaken;
#define EPTNE(e) \
(((e)>>16)&0xffff) /* bits 31:16, TX endpoint NAK enable */
#define EPRNE(e) \
(((e)>>0)&0xffff) /* bits 15:0, RX endpoint NAK enable */
u32 endptsetupstat;
#define SETUPSTAT_MASK (0xffff << 0) /* bits 15:0 */
#define EP0SETUPSTAT_MASK 1
u32 endptprime;
/* bits 31:16, prime endpoint transmit buffer */
#define PETB(e) (((e)>>16)&0xffff)
/* bits 15:0, prime endpoint receive buffer */
#define PERB(e) (((e)>>0)&0xffff)
/* offset: 0x110 */
u32 endptflush;
/* bits 31:16, flush endpoint transmit buffer */
#define FETB(e) (((e)>>16)&0xffff)
/* bits 15:0, flush endpoint receive buffer */
#define FERB(e) (((e)>>0)&0xffff)
u32 endptstat;
/* bits 31:16, endpoint transmit buffer ready */
#define ETBR(e) (((e)>>16)&0xffff)
/* bits 15:0, endpoint receive buffer ready */
#define ERBR(e) (((e)>>0)&0xffff)
u32 endptcomplete;
/* bits 31:16, endpoint transmit complete event */
#define ETCE(e) (((e)>>16)&0xffff)
/* bits 15:0, endpoint receive complete event */
#define ERCE(e) (((e)>>0)&0xffff)
/* offset: 0x11c */
u32 endptctrl[16];
#define EPCTRL_TXE BIT(23) /* TX endpoint enable */
#define EPCTRL_TXR BIT(22) /* TX data toggle reset */
#define EPCTRL_TXI BIT(21) /* TX data toggle inhibit */
#define EPCTRL_TXT(e) (((e)>>18)&3) /* bits 19:18, TX endpoint type */
#define EPCTRL_TXT_SHIFT 18
#define EPCTRL_TXD BIT(17) /* TX endpoint data source */
#define EPCTRL_TXS BIT(16) /* TX endpoint STALL */
#define EPCTRL_RXE BIT(7) /* RX endpoint enable */
#define EPCTRL_RXR BIT(6) /* RX data toggle reset */
#define EPCTRL_RXI BIT(5) /* RX data toggle inhibit */
#define EPCTRL_RXT(e) (((e)>>2)&3) /* bits 3:2, RX endpoint type */
#define EPCTRL_RXT_SHIFT 2 /* bits 19:18, TX endpoint type */
#define EPCTRL_RXD BIT(1) /* RX endpoint data sink */
#define EPCTRL_RXS BIT(0) /* RX endpoint STALL */
} __attribute__ ((packed));
#endif /* __LANGWELL_UDC_H */