15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+ 290fccb52SAndrzej Pietrasiewicz /* 390fccb52SAndrzej Pietrasiewicz * Copyright (C) 2004 by Thomas Rathbone, HP Labs 490fccb52SAndrzej Pietrasiewicz * Copyright (C) 2005 by Ivan Kokshaysky 590fccb52SAndrzej Pietrasiewicz * Copyright (C) 2006 by SAN People 690fccb52SAndrzej Pietrasiewicz */ 790fccb52SAndrzej Pietrasiewicz 890fccb52SAndrzej Pietrasiewicz #ifndef AT91_UDC_H 990fccb52SAndrzej Pietrasiewicz #define AT91_UDC_H 1090fccb52SAndrzej Pietrasiewicz 1190fccb52SAndrzej Pietrasiewicz /* 1290fccb52SAndrzej Pietrasiewicz * USB Device Port (UDP) registers. 1390fccb52SAndrzej Pietrasiewicz * Based on AT91RM9200 datasheet revision E. 1490fccb52SAndrzej Pietrasiewicz */ 1590fccb52SAndrzej Pietrasiewicz 1690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FRM_NUM 0x00 /* Frame Number Register */ 1790fccb52SAndrzej Pietrasiewicz #define AT91_UDP_NUM (0x7ff << 0) /* Frame Number */ 1890fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FRM_ERR (1 << 16) /* Frame Error */ 1990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FRM_OK (1 << 17) /* Frame OK */ 2090fccb52SAndrzej Pietrasiewicz 2190fccb52SAndrzej Pietrasiewicz #define AT91_UDP_GLB_STAT 0x04 /* Global State Register */ 2290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FADDEN (1 << 0) /* Function Address Enable */ 2390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_CONFG (1 << 1) /* Configured */ 2490fccb52SAndrzej Pietrasiewicz #define AT91_UDP_ESR (1 << 2) /* Enable Send Resume */ 2590fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RSMINPR (1 << 3) /* Resume has been sent */ 2690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RMWUPE (1 << 4) /* Remote Wake Up Enable */ 2790fccb52SAndrzej Pietrasiewicz 2890fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FADDR 0x08 /* Function Address Register */ 2990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FADD (0x7f << 0) /* Function Address Value */ 3090fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FEN (1 << 8) /* Function Enable */ 3190fccb52SAndrzej Pietrasiewicz 3290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_IER 0x10 /* Interrupt Enable Register */ 3390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */ 3490fccb52SAndrzej Pietrasiewicz #define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */ 3590fccb52SAndrzej Pietrasiewicz 3690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_ISR 0x1c /* Interrupt Status Register */ 3790fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ 3890fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ 3990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ 4090fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ 4190fccb52SAndrzej Pietrasiewicz #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ 4290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrupt Status */ 4390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ 4490fccb52SAndrzej Pietrasiewicz 4590fccb52SAndrzej Pietrasiewicz #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ 4690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ 4790fccb52SAndrzej Pietrasiewicz 4890fccb52SAndrzej Pietrasiewicz #define AT91_UDP_CSR(n) (0x30+((n)*4)) /* Endpoint Control/Status Registers 0-7 */ 4990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_TXCOMP (1 << 0) /* Generates IN packet with data previously written in DPR */ 5090fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RX_DATA_BK0 (1 << 1) /* Receive Data Bank 0 */ 5190fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RXSETUP (1 << 2) /* Send STALL to the host */ 5290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_STALLSENT (1 << 3) /* Stall Sent / Isochronous error (Isochronous endpoints) */ 5390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_TXPKTRDY (1 << 4) /* Transmit Packet Ready */ 5490fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FORCESTALL (1 << 5) /* Force Stall */ 5590fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RX_DATA_BK1 (1 << 6) /* Receive Data Bank 1 */ 5690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_DIR (1 << 7) /* Transfer Direction */ 5790fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE (7 << 8) /* Endpoint Type */ 5890fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_CTRL (0 << 8) 5990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_ISO_OUT (1 << 8) 6090fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_BULK_OUT (2 << 8) 6190fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_INT_OUT (3 << 8) 6290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_ISO_IN (5 << 8) 6390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_BULK_IN (6 << 8) 6490fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPTYPE_INT_IN (7 << 8) 6590fccb52SAndrzej Pietrasiewicz #define AT91_UDP_DTGLE (1 << 11) /* Data Toggle */ 6690fccb52SAndrzej Pietrasiewicz #define AT91_UDP_EPEDS (1 << 15) /* Endpoint Enable/Disable */ 6790fccb52SAndrzej Pietrasiewicz #define AT91_UDP_RXBYTECNT (0x7ff << 16) /* Number of bytes in FIFO */ 6890fccb52SAndrzej Pietrasiewicz 6990fccb52SAndrzej Pietrasiewicz #define AT91_UDP_FDR(n) (0x50+((n)*4)) /* Endpoint FIFO Data Registers 0-7 */ 7090fccb52SAndrzej Pietrasiewicz 7190fccb52SAndrzej Pietrasiewicz #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ 7290fccb52SAndrzej Pietrasiewicz #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ 7390fccb52SAndrzej Pietrasiewicz #define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ 7490fccb52SAndrzej Pietrasiewicz 7590fccb52SAndrzej Pietrasiewicz /*-------------------------------------------------------------------------*/ 7690fccb52SAndrzej Pietrasiewicz 7790fccb52SAndrzej Pietrasiewicz /* 7890fccb52SAndrzej Pietrasiewicz * controller driver data structures 7990fccb52SAndrzej Pietrasiewicz */ 8090fccb52SAndrzej Pietrasiewicz 8190fccb52SAndrzej Pietrasiewicz #define NUM_ENDPOINTS 6 8290fccb52SAndrzej Pietrasiewicz 8390fccb52SAndrzej Pietrasiewicz /* 8490fccb52SAndrzej Pietrasiewicz * hardware won't disable bus reset, or resume while the controller 8590fccb52SAndrzej Pietrasiewicz * is suspended ... watching suspend helps keep the logic symmetric. 8690fccb52SAndrzej Pietrasiewicz */ 8790fccb52SAndrzej Pietrasiewicz #define MINIMUS_INTERRUPTUS \ 8890fccb52SAndrzej Pietrasiewicz (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP) 8990fccb52SAndrzej Pietrasiewicz 9090fccb52SAndrzej Pietrasiewicz struct at91_ep { 9190fccb52SAndrzej Pietrasiewicz struct usb_ep ep; 9290fccb52SAndrzej Pietrasiewicz struct list_head queue; 9390fccb52SAndrzej Pietrasiewicz struct at91_udc *udc; 9490fccb52SAndrzej Pietrasiewicz void __iomem *creg; 9590fccb52SAndrzej Pietrasiewicz 9690fccb52SAndrzej Pietrasiewicz unsigned maxpacket:16; 9790fccb52SAndrzej Pietrasiewicz u8 int_mask; 9890fccb52SAndrzej Pietrasiewicz unsigned is_pingpong:1; 9990fccb52SAndrzej Pietrasiewicz 10090fccb52SAndrzej Pietrasiewicz unsigned stopped:1; 10190fccb52SAndrzej Pietrasiewicz unsigned is_in:1; 10290fccb52SAndrzej Pietrasiewicz unsigned is_iso:1; 10390fccb52SAndrzej Pietrasiewicz unsigned fifo_bank:1; 10490fccb52SAndrzej Pietrasiewicz }; 10590fccb52SAndrzej Pietrasiewicz 106f0bceab4SBoris Brezillon struct at91_udc_caps { 107f0bceab4SBoris Brezillon int (*init)(struct at91_udc *udc); 108f0bceab4SBoris Brezillon void (*pullup)(struct at91_udc *udc, int is_on); 109f0bceab4SBoris Brezillon }; 110f0bceab4SBoris Brezillon 111428163d7SAlexandre Belloni struct at91_udc_data { 112*4a555f2bSBalamanikandan Gunasundar struct gpio_desc *vbus_pin; /* high == host powering us */ 113428163d7SAlexandre Belloni u8 vbus_polled; /* Use polling, not interrupt */ 114*4a555f2bSBalamanikandan Gunasundar struct gpio_desc *pullup_pin; /* active == D+ pulled up */ 115428163d7SAlexandre Belloni }; 116428163d7SAlexandre Belloni 11790fccb52SAndrzej Pietrasiewicz /* 11890fccb52SAndrzej Pietrasiewicz * driver is non-SMP, and just blocks IRQs whenever it needs 11990fccb52SAndrzej Pietrasiewicz * access protection for chip registers or driver state 12090fccb52SAndrzej Pietrasiewicz */ 12190fccb52SAndrzej Pietrasiewicz struct at91_udc { 12290fccb52SAndrzej Pietrasiewicz struct usb_gadget gadget; 12390fccb52SAndrzej Pietrasiewicz struct at91_ep ep[NUM_ENDPOINTS]; 12490fccb52SAndrzej Pietrasiewicz struct usb_gadget_driver *driver; 125f0bceab4SBoris Brezillon const struct at91_udc_caps *caps; 12690fccb52SAndrzej Pietrasiewicz unsigned vbus:1; 12790fccb52SAndrzej Pietrasiewicz unsigned enabled:1; 12890fccb52SAndrzej Pietrasiewicz unsigned clocked:1; 12990fccb52SAndrzej Pietrasiewicz unsigned suspended:1; 13090fccb52SAndrzej Pietrasiewicz unsigned req_pending:1; 13190fccb52SAndrzej Pietrasiewicz unsigned wait_for_addr_ack:1; 13290fccb52SAndrzej Pietrasiewicz unsigned wait_for_config_ack:1; 13390fccb52SAndrzej Pietrasiewicz unsigned active_suspend:1; 13490fccb52SAndrzej Pietrasiewicz u8 addr; 13590fccb52SAndrzej Pietrasiewicz struct at91_udc_data board; 1369aa02165SBoris Brezillon struct clk *iclk, *fclk; 13790fccb52SAndrzej Pietrasiewicz struct platform_device *pdev; 13890fccb52SAndrzej Pietrasiewicz struct proc_dir_entry *pde; 13990fccb52SAndrzej Pietrasiewicz void __iomem *udp_baseaddr; 14090fccb52SAndrzej Pietrasiewicz int udp_irq; 14190fccb52SAndrzej Pietrasiewicz spinlock_t lock; 14290fccb52SAndrzej Pietrasiewicz struct timer_list vbus_timer; 14390fccb52SAndrzej Pietrasiewicz struct work_struct vbus_timer_work; 144f0bceab4SBoris Brezillon struct regmap *matrix; 14590fccb52SAndrzej Pietrasiewicz }; 14690fccb52SAndrzej Pietrasiewicz to_udc(struct usb_gadget * g)14790fccb52SAndrzej Pietrasiewiczstatic inline struct at91_udc *to_udc(struct usb_gadget *g) 14890fccb52SAndrzej Pietrasiewicz { 14990fccb52SAndrzej Pietrasiewicz return container_of(g, struct at91_udc, gadget); 15090fccb52SAndrzej Pietrasiewicz } 15190fccb52SAndrzej Pietrasiewicz 15290fccb52SAndrzej Pietrasiewicz struct at91_request { 15390fccb52SAndrzej Pietrasiewicz struct usb_request req; 15490fccb52SAndrzej Pietrasiewicz struct list_head queue; 15590fccb52SAndrzej Pietrasiewicz }; 15690fccb52SAndrzej Pietrasiewicz 15790fccb52SAndrzej Pietrasiewicz /*-------------------------------------------------------------------------*/ 15890fccb52SAndrzej Pietrasiewicz 15990fccb52SAndrzej Pietrasiewicz #ifdef VERBOSE_DEBUG 16090fccb52SAndrzej Pietrasiewicz # define VDBG DBG 16190fccb52SAndrzej Pietrasiewicz #else 16290fccb52SAndrzej Pietrasiewicz # define VDBG(stuff...) do{}while(0) 16390fccb52SAndrzej Pietrasiewicz #endif 16490fccb52SAndrzej Pietrasiewicz 16590fccb52SAndrzej Pietrasiewicz #ifdef PACKET_TRACE 16690fccb52SAndrzej Pietrasiewicz # define PACKET VDBG 16790fccb52SAndrzej Pietrasiewicz #else 16890fccb52SAndrzej Pietrasiewicz # define PACKET(stuff...) do{}while(0) 16990fccb52SAndrzej Pietrasiewicz #endif 17090fccb52SAndrzej Pietrasiewicz 17190fccb52SAndrzej Pietrasiewicz #define ERR(stuff...) pr_err("udc: " stuff) 172a4e6a852SJoe Perches #define WARNING(stuff...) pr_warn("udc: " stuff) 17390fccb52SAndrzej Pietrasiewicz #define INFO(stuff...) pr_info("udc: " stuff) 17490fccb52SAndrzej Pietrasiewicz #define DBG(stuff...) pr_debug("udc: " stuff) 17590fccb52SAndrzej Pietrasiewicz 17690fccb52SAndrzej Pietrasiewicz #endif 17790fccb52SAndrzej Pietrasiewicz 178