1bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 2bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Copyright (C) 2004 by Thomas Rathbone, HP Labs 3bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Copyright (C) 2005 by Ivan Kokshaysky 4bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Copyright (C) 2006 by SAN People 5bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * 6bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * This program is free software; you can redistribute it and/or modify 7bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * it under the terms of the GNU General Public License as published by 8bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * the Free Software Foundation; either version 2 of the License, or 9bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * (at your option) any later version. 10bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 11bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 12bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#ifndef AT91_UDC_H 13bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDC_H 14bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 15bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 16bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * USB Device Port (UDP) registers. 17bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Based on AT91RM9200 datasheet revision E. 18bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 19bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 20bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_NUM 0x00 /* Frame Number Register */ 21bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_NUM (0x7ff << 0) /* Frame Number */ 22bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_ERR (1 << 16) /* Frame Error */ 23bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_OK (1 << 17) /* Frame OK */ 24bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 25bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_GLB_STAT 0x04 /* Global State Register */ 26bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADDEN (1 << 0) /* Function Address Enable */ 27bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_CONFG (1 << 1) /* Configured */ 28bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ESR (1 << 2) /* Enable Send Resume */ 29bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RSMINPR (1 << 3) /* Resume has been sent */ 30bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RMWUPE (1 << 4) /* Remote Wake Up Enable */ 31bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 32bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADDR 0x08 /* Function Address Register */ 33bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADD (0x7f << 0) /* Function Address Value */ 34bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FEN (1 << 8) /* Function Enable */ 35bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 36bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */ 37bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */ 38bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */ 39bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 40bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ISR 0x1c /* Interrupt Status Register */ 41bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ 42bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ 43bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ 4429ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ 45bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ 46dc0d5c1e5c7532e800fff6e313cd4af44af99976Joe Perches#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrupt Status */ 4729ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ 48bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 49bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ 50bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ 51bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 52bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_CSR(n) (0x30+((n)*4)) /* Endpoint Control/Status Registers 0-7 */ 53bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXCOMP (1 << 0) /* Generates IN packet with data previously written in DPR */ 54bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RX_DATA_BK0 (1 << 1) /* Receive Data Bank 0 */ 55bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXSETUP (1 << 2) /* Send STALL to the host */ 56bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_STALLSENT (1 << 3) /* Stall Sent / Isochronous error (Isochronous endpoints) */ 57bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXPKTRDY (1 << 4) /* Transmit Packet Ready */ 58bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FORCESTALL (1 << 5) /* Force Stall */ 59bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RX_DATA_BK1 (1 << 6) /* Receive Data Bank 1 */ 60bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_DIR (1 << 7) /* Transfer Direction */ 61bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE (7 << 8) /* Endpoint Type */ 62bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_CTRL (0 << 8) 63bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_ISO_OUT (1 << 8) 64bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_BULK_OUT (2 << 8) 65bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_INT_OUT (3 << 8) 66bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_ISO_IN (5 << 8) 67bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_BULK_IN (6 << 8) 68bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_INT_IN (7 << 8) 69bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_DTGLE (1 << 11) /* Data Toggle */ 70bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPEDS (1 << 15) /* Endpoint Enable/Disable */ 71bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXBYTECNT (0x7ff << 16) /* Number of bytes in FIFO */ 72bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 73bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FDR(n) (0x50+((n)*4)) /* Endpoint FIFO Data Registers 0-7 */ 74bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 75bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ 76bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ 7729ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ 78bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 79bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/*-------------------------------------------------------------------------*/ 80bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 81bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 82bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * controller driver data structures 83bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 84bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 85bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define NUM_ENDPOINTS 6 86bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 87bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 88bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * hardware won't disable bus reset, or resume while the controller 89bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * is suspended ... watching suspend helps keep the logic symmetric. 90bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 91bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define MINIMUS_INTERRUPTUS \ 92bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP) 93bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 94bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_ep { 95bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_ep ep; 96bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct list_head queue; 97bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_udc *udc; 98bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell void __iomem *creg; 99bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 100bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned maxpacket:16; 101bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell u8 int_mask; 102bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_pingpong:1; 103bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 104bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned stopped:1; 105bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_in:1; 106bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_iso:1; 107bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned fifo_bank:1; 108bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 109bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell const struct usb_endpoint_descriptor 110bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell *desc; 111bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 112bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 113bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 114bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * driver is non-SMP, and just blocks IRQs whenever it needs 115bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * access protection for chip registers or driver state 116bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 117bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_udc { 118bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_gadget gadget; 119bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_ep ep[NUM_ENDPOINTS]; 120bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_gadget_driver *driver; 121bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned vbus:1; 122bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned enabled:1; 123bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned clocked:1; 124bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned suspended:1; 125bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned req_pending:1; 126bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned wait_for_addr_ack:1; 127bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned wait_for_config_ack:1; 128bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned selfpowered:1; 12966e56ce75e39210415fb12ceacd5f3580ad72d50David Brownell unsigned active_suspend:1; 130bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell u8 addr; 131bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_udc_data board; 132bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct clk *iclk, *fclk; 133bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct platform_device *pdev; 134bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct proc_dir_entry *pde; 135ffd3326bf6282b9f606e92ae57e8f47f2e10e6b5Andrew Victor void __iomem *udp_baseaddr; 1368b2e76687b39213725207b4a4264e11e8c7b86e6David Brownell int udp_irq; 1374f4c5e36e7cd26c9b5bf89d66caeee5fc3d75362Harro Haan spinlock_t lock; 1384037242c4f5ff77afe61bf07ca1e8a99490219e5Ryan Mallon struct timer_list vbus_timer; 1394037242c4f5ff77afe61bf07ca1e8a99490219e5Ryan Mallon struct work_struct vbus_timer_work; 140bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 141bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 142bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstatic inline struct at91_udc *to_udc(struct usb_gadget *g) 143bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell{ 144bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell return container_of(g, struct at91_udc, gadget); 145bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell} 146bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 147bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_request { 148bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_request req; 149bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct list_head queue; 150bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 151bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 152bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/*-------------------------------------------------------------------------*/ 153bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 154f3db6e82034a6ea89191fdcc6b9a984dc0d5d533David Brownell#ifdef VERBOSE_DEBUG 155bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define VDBG DBG 156bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#else 157bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define VDBG(stuff...) do{}while(0) 158bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 159bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 160bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#ifdef PACKET_TRACE 161bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define PACKET VDBG 162bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#else 163bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define PACKET(stuff...) do{}while(0) 164bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 165bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 16600274921a052d3232d9f00856387fb269ac0af11David Brownell#define ERR(stuff...) pr_err("udc: " stuff) 167b6c63937001889af6fe431aaba97e59d04e028e7Arjan van de Ven#define WARNING(stuff...) pr_warning("udc: " stuff) 16800274921a052d3232d9f00856387fb269ac0af11David Brownell#define INFO(stuff...) pr_info("udc: " stuff) 16900274921a052d3232d9f00856387fb269ac0af11David Brownell#define DBG(stuff...) pr_debug("udc: " stuff) 170bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 171bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 172bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 173