at91_udc.h revision 4f4c5e36e7cd26c9b5bf89d66caeee5fc3d75362
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 * This program is distributed in the hope that it will be useful, 12bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * but WITHOUT ANY WARRANTY; without even the implied warranty of 13bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * GNU General Public License for more details. 15bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * 16bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * You should have received a copy of the GNU General Public License 17bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * along with this program; if not, write to the 18bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Free Software Foundation, Inc., 19bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 21bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 22bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#ifndef AT91_UDC_H 23bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDC_H 24bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 25bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 26bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * USB Device Port (UDP) registers. 27bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * Based on AT91RM9200 datasheet revision E. 28bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 29bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 30bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_NUM 0x00 /* Frame Number Register */ 31bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_NUM (0x7ff << 0) /* Frame Number */ 32bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_ERR (1 << 16) /* Frame Error */ 33bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FRM_OK (1 << 17) /* Frame OK */ 34bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 35bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_GLB_STAT 0x04 /* Global State Register */ 36bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADDEN (1 << 0) /* Function Address Enable */ 37bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_CONFG (1 << 1) /* Configured */ 38bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ESR (1 << 2) /* Enable Send Resume */ 39bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RSMINPR (1 << 3) /* Resume has been sent */ 40bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RMWUPE (1 << 4) /* Remote Wake Up Enable */ 41bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 42bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADDR 0x08 /* Function Address Register */ 43bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FADD (0x7f << 0) /* Function Address Value */ 44bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FEN (1 << 8) /* Function Enable */ 45bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 46bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */ 47bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */ 48bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */ 49bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 50bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ISR 0x1c /* Interrupt Status Register */ 51bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ 52bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ 53bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ 5429ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ 55bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ 56dc0d5c1e5c7532e800fff6e313cd4af44af99976Joe Perches#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrupt Status */ 5729ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ 58bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 59bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ 60bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ 61bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 62bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_CSR(n) (0x30+((n)*4)) /* Endpoint Control/Status Registers 0-7 */ 63bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXCOMP (1 << 0) /* Generates IN packet with data previously written in DPR */ 64bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RX_DATA_BK0 (1 << 1) /* Receive Data Bank 0 */ 65bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXSETUP (1 << 2) /* Send STALL to the host */ 66bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_STALLSENT (1 << 3) /* Stall Sent / Isochronous error (Isochronous endpoints) */ 67bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXPKTRDY (1 << 4) /* Transmit Packet Ready */ 68bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FORCESTALL (1 << 5) /* Force Stall */ 69bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RX_DATA_BK1 (1 << 6) /* Receive Data Bank 1 */ 70bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_DIR (1 << 7) /* Transfer Direction */ 71bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE (7 << 8) /* Endpoint Type */ 72bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_CTRL (0 << 8) 73bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_ISO_OUT (1 << 8) 74bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_BULK_OUT (2 << 8) 75bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_INT_OUT (3 << 8) 76bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_ISO_IN (5 << 8) 77bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_BULK_IN (6 << 8) 78bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPTYPE_INT_IN (7 << 8) 79bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_DTGLE (1 << 11) /* Data Toggle */ 80bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_EPEDS (1 << 15) /* Endpoint Enable/Disable */ 81bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_RXBYTECNT (0x7ff << 16) /* Number of bytes in FIFO */ 82bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 83bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_FDR(n) (0x50+((n)*4)) /* Endpoint FIFO Data Registers 0-7 */ 84bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 85bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ 86bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ 8729ba4b533b677f3cd7f2fc901d51054555a8f243Andrew Victor#define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ 88bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 89bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/*-------------------------------------------------------------------------*/ 90bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 91bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 92bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * controller driver data structures 93bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 94bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 95bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define NUM_ENDPOINTS 6 96bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 97bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 98bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * hardware won't disable bus reset, or resume while the controller 99bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * is suspended ... watching suspend helps keep the logic symmetric. 100bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 101bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#define MINIMUS_INTERRUPTUS \ 102bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP) 103bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 104bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_ep { 105bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_ep ep; 106bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct list_head queue; 107bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_udc *udc; 108bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell void __iomem *creg; 109bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 110bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned maxpacket:16; 111bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell u8 int_mask; 112bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_pingpong:1; 113bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 114bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned stopped:1; 115bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_in:1; 116bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned is_iso:1; 117bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned fifo_bank:1; 118bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 119bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell const struct usb_endpoint_descriptor 120bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell *desc; 121bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 122bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 123bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/* 124bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * driver is non-SMP, and just blocks IRQs whenever it needs 125bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell * access protection for chip registers or driver state 126bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell */ 127bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_udc { 128bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_gadget gadget; 129bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_ep ep[NUM_ENDPOINTS]; 130bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_gadget_driver *driver; 131bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned vbus:1; 132bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned enabled:1; 133bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned clocked:1; 134bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned suspended:1; 135bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned req_pending:1; 136bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned wait_for_addr_ack:1; 137bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned wait_for_config_ack:1; 138bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell unsigned selfpowered:1; 13966e56ce75e39210415fb12ceacd5f3580ad72d50David Brownell unsigned active_suspend:1; 140bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell u8 addr; 141bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct at91_udc_data board; 142bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct clk *iclk, *fclk; 143bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct platform_device *pdev; 144bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct proc_dir_entry *pde; 145ffd3326bf6282b9f606e92ae57e8f47f2e10e6b5Andrew Victor void __iomem *udp_baseaddr; 1468b2e76687b39213725207b4a4264e11e8c7b86e6David Brownell int udp_irq; 1474f4c5e36e7cd26c9b5bf89d66caeee5fc3d75362Harro Haan spinlock_t lock; 148bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 149bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 150bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstatic inline struct at91_udc *to_udc(struct usb_gadget *g) 151bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell{ 152bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell return container_of(g, struct at91_udc, gadget); 153bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell} 154bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 155bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownellstruct at91_request { 156bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct usb_request req; 157bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell struct list_head queue; 158bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell}; 159bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 160bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell/*-------------------------------------------------------------------------*/ 161bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 162f3db6e82034a6ea89191fdcc6b9a984dc0d5d533David Brownell#ifdef VERBOSE_DEBUG 163bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define VDBG DBG 164bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#else 165bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define VDBG(stuff...) do{}while(0) 166bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 167bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 168bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#ifdef PACKET_TRACE 169bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define PACKET VDBG 170bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#else 171bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell# define PACKET(stuff...) do{}while(0) 172bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 173bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 17400274921a052d3232d9f00856387fb269ac0af11David Brownell#define ERR(stuff...) pr_err("udc: " stuff) 175b6c63937001889af6fe431aaba97e59d04e028e7Arjan van de Ven#define WARNING(stuff...) pr_warning("udc: " stuff) 17600274921a052d3232d9f00856387fb269ac0af11David Brownell#define INFO(stuff...) pr_info("udc: " stuff) 17700274921a052d3232d9f00856387fb269ac0af11David Brownell#define DBG(stuff...) pr_debug("udc: " stuff) 178bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 179bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell#endif 180bae4bd848dc0b7e6defc7a5d62834a35d1eed06dDavid Brownell 181