xref: /openbmc/linux/drivers/usb/host/max3421-hcd.c (revision 13dcf780)
12d53139fSDavid Mosberger /*
22d53139fSDavid Mosberger  * MAX3421 Host Controller driver for USB.
32d53139fSDavid Mosberger  *
42d53139fSDavid Mosberger  * Author: David Mosberger-Tang <davidm@egauge.net>
52d53139fSDavid Mosberger  *
62d53139fSDavid Mosberger  * (C) Copyright 2014 David Mosberger-Tang <davidm@egauge.net>
72d53139fSDavid Mosberger  *
82d53139fSDavid Mosberger  * MAX3421 is a chip implementing a USB 2.0 Full-/Low-Speed host
92d53139fSDavid Mosberger  * controller on a SPI bus.
102d53139fSDavid Mosberger  *
112d53139fSDavid Mosberger  * Based on:
122d53139fSDavid Mosberger  *	o MAX3421E datasheet
132d53139fSDavid Mosberger  *		http://datasheets.maximintegrated.com/en/ds/MAX3421E.pdf
142d53139fSDavid Mosberger  *	o MAX3421E Programming Guide
152d53139fSDavid Mosberger  *		http://www.hdl.co.jp/ftpdata/utl-001/AN3785.pdf
162d53139fSDavid Mosberger  *	o gadget/dummy_hcd.c
172d53139fSDavid Mosberger  *		For USB HCD implementation.
182d53139fSDavid Mosberger  *	o Arduino MAX3421 driver
192d53139fSDavid Mosberger  *	     https://github.com/felis/USB_Host_Shield_2.0/blob/master/Usb.cpp
202d53139fSDavid Mosberger  *
212d53139fSDavid Mosberger  * This file is licenced under the GPL v2.
222d53139fSDavid Mosberger  *
232d53139fSDavid Mosberger  * Important note on worst-case (full-speed) packet size constraints
242d53139fSDavid Mosberger  * (See USB 2.0 Section 5.6.3 and following):
252d53139fSDavid Mosberger  *
262d53139fSDavid Mosberger  *	- control:	  64 bytes
272d53139fSDavid Mosberger  *	- isochronous:	1023 bytes
282d53139fSDavid Mosberger  *	- interrupt:	  64 bytes
292d53139fSDavid Mosberger  *	- bulk:		  64 bytes
302d53139fSDavid Mosberger  *
312d53139fSDavid Mosberger  * Since the MAX3421 FIFO size is 64 bytes, we do not have to work about
322d53139fSDavid Mosberger  * multi-FIFO writes/reads for a single USB packet *except* for isochronous
332d53139fSDavid Mosberger  * transfers.  We don't support isochronous transfers at this time, so we
342d53139fSDavid Mosberger  * just assume that a USB packet always fits into a single FIFO buffer.
352d53139fSDavid Mosberger  *
362d53139fSDavid Mosberger  * NOTE: The June 2006 version of "MAX3421E Programming Guide"
372d53139fSDavid Mosberger  * (AN3785) has conflicting info for the RCVDAVIRQ bit:
382d53139fSDavid Mosberger  *
392d53139fSDavid Mosberger  *	The description of RCVDAVIRQ says "The CPU *must* clear
402d53139fSDavid Mosberger  *	this IRQ bit (by writing a 1 to it) before reading the
412d53139fSDavid Mosberger  *	RCVFIFO data.
422d53139fSDavid Mosberger  *
432d53139fSDavid Mosberger  * However, the earlier section on "Programming BULK-IN
442d53139fSDavid Mosberger  * Transfers" says * that:
452d53139fSDavid Mosberger  *
462d53139fSDavid Mosberger  *	After the CPU retrieves the data, it clears the
472d53139fSDavid Mosberger  *	RCVDAVIRQ bit.
482d53139fSDavid Mosberger  *
492d53139fSDavid Mosberger  * The December 2006 version has been corrected and it consistently
502d53139fSDavid Mosberger  * states the second behavior is the correct one.
512d53139fSDavid Mosberger  *
522d53139fSDavid Mosberger  * Synchronous SPI transactions sleep so we can't perform any such
532d53139fSDavid Mosberger  * transactions while holding a spin-lock (and/or while interrupts are
542d53139fSDavid Mosberger  * masked).  To achieve this, all SPI transactions are issued from a
552d53139fSDavid Mosberger  * single thread (max3421_spi_thread).
562d53139fSDavid Mosberger  */
572d53139fSDavid Mosberger 
58788bfe88SAsaf Vertz #include <linux/jiffies.h>
592d53139fSDavid Mosberger #include <linux/module.h>
602d53139fSDavid Mosberger #include <linux/spi/spi.h>
612d53139fSDavid Mosberger #include <linux/usb.h>
622d53139fSDavid Mosberger #include <linux/usb/hcd.h>
632d53139fSDavid Mosberger 
642d53139fSDavid Mosberger #include <linux/platform_data/max3421-hcd.h>
652d53139fSDavid Mosberger 
662d53139fSDavid Mosberger #define DRIVER_DESC	"MAX3421 USB Host-Controller Driver"
672d53139fSDavid Mosberger #define DRIVER_VERSION	"1.0"
682d53139fSDavid Mosberger 
692d53139fSDavid Mosberger /* 11-bit counter that wraps around (USB 2.0 Section 8.3.3): */
702d53139fSDavid Mosberger #define USB_MAX_FRAME_NUMBER	0x7ff
712d53139fSDavid Mosberger #define USB_MAX_RETRIES		3 /* # of retries before error is reported */
722d53139fSDavid Mosberger 
732d53139fSDavid Mosberger /*
742d53139fSDavid Mosberger  * Max. # of times we're willing to retransmit a request immediately in
752d53139fSDavid Mosberger  * resposne to a NAK.  Afterwards, we fall back on trying once a frame.
762d53139fSDavid Mosberger  */
772d53139fSDavid Mosberger #define NAK_MAX_FAST_RETRANSMITS	2
782d53139fSDavid Mosberger 
792d53139fSDavid Mosberger #define POWER_BUDGET	500	/* in mA; use 8 for low-power port testing */
802d53139fSDavid Mosberger 
812d53139fSDavid Mosberger /* Port-change mask: */
822d53139fSDavid Mosberger #define PORT_C_MASK	((USB_PORT_STAT_C_CONNECTION |	\
832d53139fSDavid Mosberger 			  USB_PORT_STAT_C_ENABLE |	\
842d53139fSDavid Mosberger 			  USB_PORT_STAT_C_SUSPEND |	\
852d53139fSDavid Mosberger 			  USB_PORT_STAT_C_OVERCURRENT | \
862d53139fSDavid Mosberger 			  USB_PORT_STAT_C_RESET) << 16)
872d53139fSDavid Mosberger 
882d53139fSDavid Mosberger enum max3421_rh_state {
892d53139fSDavid Mosberger 	MAX3421_RH_RESET,
902d53139fSDavid Mosberger 	MAX3421_RH_SUSPENDED,
912d53139fSDavid Mosberger 	MAX3421_RH_RUNNING
922d53139fSDavid Mosberger };
932d53139fSDavid Mosberger 
942d53139fSDavid Mosberger enum pkt_state {
952d53139fSDavid Mosberger 	PKT_STATE_SETUP,	/* waiting to send setup packet to ctrl pipe */
962d53139fSDavid Mosberger 	PKT_STATE_TRANSFER,	/* waiting to xfer transfer_buffer */
972d53139fSDavid Mosberger 	PKT_STATE_TERMINATE	/* waiting to terminate control transfer */
982d53139fSDavid Mosberger };
992d53139fSDavid Mosberger 
1002d53139fSDavid Mosberger enum scheduling_pass {
1012d53139fSDavid Mosberger 	SCHED_PASS_PERIODIC,
1022d53139fSDavid Mosberger 	SCHED_PASS_NON_PERIODIC,
1032d53139fSDavid Mosberger 	SCHED_PASS_DONE
1042d53139fSDavid Mosberger };
1052d53139fSDavid Mosberger 
1062eb5dbddSDavid Mosberger-Tang /* Bit numbers for max3421_hcd->todo: */
1072eb5dbddSDavid Mosberger-Tang enum {
1082eb5dbddSDavid Mosberger-Tang 	ENABLE_IRQ = 0,
1092eb5dbddSDavid Mosberger-Tang 	RESET_HCD,
1102eb5dbddSDavid Mosberger-Tang 	RESET_PORT,
1112eb5dbddSDavid Mosberger-Tang 	CHECK_UNLINK,
1122eb5dbddSDavid Mosberger-Tang 	IOPIN_UPDATE
1132eb5dbddSDavid Mosberger-Tang };
1142eb5dbddSDavid Mosberger-Tang 
11505dfa5c9SDavid Mosberger-Tang struct max3421_dma_buf {
11605dfa5c9SDavid Mosberger-Tang 	u8 data[2];
11705dfa5c9SDavid Mosberger-Tang };
11805dfa5c9SDavid Mosberger-Tang 
1192d53139fSDavid Mosberger struct max3421_hcd {
1202d53139fSDavid Mosberger 	spinlock_t lock;
1212d53139fSDavid Mosberger 
1222d53139fSDavid Mosberger 	struct task_struct *spi_thread;
1232d53139fSDavid Mosberger 
1242d53139fSDavid Mosberger 	struct max3421_hcd *next;
1252d53139fSDavid Mosberger 
1262d53139fSDavid Mosberger 	enum max3421_rh_state rh_state;
1272d53139fSDavid Mosberger 	/* lower 16 bits contain port status, upper 16 bits the change mask: */
1282d53139fSDavid Mosberger 	u32 port_status;
1292d53139fSDavid Mosberger 
1302d53139fSDavid Mosberger 	unsigned active:1;
1312d53139fSDavid Mosberger 
1322d53139fSDavid Mosberger 	struct list_head ep_list;	/* list of EP's with work */
1332d53139fSDavid Mosberger 
1342d53139fSDavid Mosberger 	/*
1352d53139fSDavid Mosberger 	 * The following are owned by spi_thread (may be accessed by
1362d53139fSDavid Mosberger 	 * SPI-thread without acquiring the HCD lock:
1372d53139fSDavid Mosberger 	 */
1382d53139fSDavid Mosberger 	u8 rev;				/* chip revision */
1392d53139fSDavid Mosberger 	u16 frame_number;
1402d53139fSDavid Mosberger 	/*
14105dfa5c9SDavid Mosberger-Tang 	 * kmalloc'd buffers guaranteed to be in separate (DMA)
14205dfa5c9SDavid Mosberger-Tang 	 * cache-lines:
14305dfa5c9SDavid Mosberger-Tang 	 */
14405dfa5c9SDavid Mosberger-Tang 	struct max3421_dma_buf *tx;
14505dfa5c9SDavid Mosberger-Tang 	struct max3421_dma_buf *rx;
14605dfa5c9SDavid Mosberger-Tang 	/*
1472d53139fSDavid Mosberger 	 * URB we're currently processing.  Must not be reset to NULL
1482d53139fSDavid Mosberger 	 * unless MAX3421E chip is idle:
1492d53139fSDavid Mosberger 	 */
1502d53139fSDavid Mosberger 	struct urb *curr_urb;
1512d53139fSDavid Mosberger 	enum scheduling_pass sched_pass;
1522d53139fSDavid Mosberger 	struct usb_device *loaded_dev;	/* dev that's loaded into the chip */
1532d53139fSDavid Mosberger 	int loaded_epnum;		/* epnum whose toggles are loaded */
1542d53139fSDavid Mosberger 	int urb_done;			/* > 0 -> no errors, < 0: errno */
1552d53139fSDavid Mosberger 	size_t curr_len;
1562d53139fSDavid Mosberger 	u8 hien;
1572d53139fSDavid Mosberger 	u8 mode;
1582d53139fSDavid Mosberger 	u8 iopins[2];
1592eb5dbddSDavid Mosberger-Tang 	unsigned long todo;
1602d53139fSDavid Mosberger #ifdef DEBUG
1612d53139fSDavid Mosberger 	unsigned long err_stat[16];
1622d53139fSDavid Mosberger #endif
1632d53139fSDavid Mosberger };
1642d53139fSDavid Mosberger 
1652d53139fSDavid Mosberger struct max3421_ep {
1662d53139fSDavid Mosberger 	struct usb_host_endpoint *ep;
1672d53139fSDavid Mosberger 	struct list_head ep_list;
1682d53139fSDavid Mosberger 	u32 naks;
1692d53139fSDavid Mosberger 	u16 last_active;		/* frame # this ep was last active */
1702d53139fSDavid Mosberger 	enum pkt_state pkt_state;
1712d53139fSDavid Mosberger 	u8 retries;
1722d53139fSDavid Mosberger 	u8 retransmit;			/* packet needs retransmission */
1732d53139fSDavid Mosberger };
1742d53139fSDavid Mosberger 
1752d53139fSDavid Mosberger static struct max3421_hcd *max3421_hcd_list;
1762d53139fSDavid Mosberger 
1772d53139fSDavid Mosberger #define MAX3421_FIFO_SIZE	64
1782d53139fSDavid Mosberger 
1792d53139fSDavid Mosberger #define MAX3421_SPI_DIR_RD	0	/* read register from MAX3421 */
1802d53139fSDavid Mosberger #define MAX3421_SPI_DIR_WR	1	/* write register to MAX3421 */
1812d53139fSDavid Mosberger 
1822d53139fSDavid Mosberger /* SPI commands: */
1832d53139fSDavid Mosberger #define MAX3421_SPI_DIR_SHIFT	1
1842d53139fSDavid Mosberger #define MAX3421_SPI_REG_SHIFT	3
1852d53139fSDavid Mosberger 
1862d53139fSDavid Mosberger #define MAX3421_REG_RCVFIFO	1
1872d53139fSDavid Mosberger #define MAX3421_REG_SNDFIFO	2
1882d53139fSDavid Mosberger #define MAX3421_REG_SUDFIFO	4
1892d53139fSDavid Mosberger #define MAX3421_REG_RCVBC	6
1902d53139fSDavid Mosberger #define MAX3421_REG_SNDBC	7
1912d53139fSDavid Mosberger #define MAX3421_REG_USBIRQ	13
1922d53139fSDavid Mosberger #define MAX3421_REG_USBIEN	14
1932d53139fSDavid Mosberger #define MAX3421_REG_USBCTL	15
1942d53139fSDavid Mosberger #define MAX3421_REG_CPUCTL	16
1952d53139fSDavid Mosberger #define MAX3421_REG_PINCTL	17
1962d53139fSDavid Mosberger #define MAX3421_REG_REVISION	18
1972d53139fSDavid Mosberger #define MAX3421_REG_IOPINS1	20
1982d53139fSDavid Mosberger #define MAX3421_REG_IOPINS2	21
1992d53139fSDavid Mosberger #define MAX3421_REG_GPINIRQ	22
2002d53139fSDavid Mosberger #define MAX3421_REG_GPINIEN	23
2012d53139fSDavid Mosberger #define MAX3421_REG_GPINPOL	24
2022d53139fSDavid Mosberger #define MAX3421_REG_HIRQ	25
2032d53139fSDavid Mosberger #define MAX3421_REG_HIEN	26
2042d53139fSDavid Mosberger #define MAX3421_REG_MODE	27
2052d53139fSDavid Mosberger #define MAX3421_REG_PERADDR	28
2062d53139fSDavid Mosberger #define MAX3421_REG_HCTL	29
2072d53139fSDavid Mosberger #define MAX3421_REG_HXFR	30
2082d53139fSDavid Mosberger #define MAX3421_REG_HRSL	31
2092d53139fSDavid Mosberger 
2102d53139fSDavid Mosberger enum {
2112d53139fSDavid Mosberger 	MAX3421_USBIRQ_OSCOKIRQ_BIT = 0,
2122d53139fSDavid Mosberger 	MAX3421_USBIRQ_NOVBUSIRQ_BIT = 5,
2132d53139fSDavid Mosberger 	MAX3421_USBIRQ_VBUSIRQ_BIT
2142d53139fSDavid Mosberger };
2152d53139fSDavid Mosberger 
2162d53139fSDavid Mosberger enum {
2172d53139fSDavid Mosberger 	MAX3421_CPUCTL_IE_BIT = 0,
2182d53139fSDavid Mosberger 	MAX3421_CPUCTL_PULSEWID0_BIT = 6,
2192d53139fSDavid Mosberger 	MAX3421_CPUCTL_PULSEWID1_BIT
2202d53139fSDavid Mosberger };
2212d53139fSDavid Mosberger 
2222d53139fSDavid Mosberger enum {
2232d53139fSDavid Mosberger 	MAX3421_USBCTL_PWRDOWN_BIT = 4,
2242d53139fSDavid Mosberger 	MAX3421_USBCTL_CHIPRES_BIT
2252d53139fSDavid Mosberger };
2262d53139fSDavid Mosberger 
2272d53139fSDavid Mosberger enum {
2282d53139fSDavid Mosberger 	MAX3421_PINCTL_GPXA_BIT	= 0,
2292d53139fSDavid Mosberger 	MAX3421_PINCTL_GPXB_BIT,
2302d53139fSDavid Mosberger 	MAX3421_PINCTL_POSINT_BIT,
2312d53139fSDavid Mosberger 	MAX3421_PINCTL_INTLEVEL_BIT,
2322d53139fSDavid Mosberger 	MAX3421_PINCTL_FDUPSPI_BIT,
2332d53139fSDavid Mosberger 	MAX3421_PINCTL_EP0INAK_BIT,
2342d53139fSDavid Mosberger 	MAX3421_PINCTL_EP2INAK_BIT,
2352d53139fSDavid Mosberger 	MAX3421_PINCTL_EP3INAK_BIT,
2362d53139fSDavid Mosberger };
2372d53139fSDavid Mosberger 
2382d53139fSDavid Mosberger enum {
2392d53139fSDavid Mosberger 	MAX3421_HI_BUSEVENT_BIT = 0,	/* bus-reset/-resume */
2402d53139fSDavid Mosberger 	MAX3421_HI_RWU_BIT,		/* remote wakeup */
2412d53139fSDavid Mosberger 	MAX3421_HI_RCVDAV_BIT,		/* receive FIFO data available */
2422d53139fSDavid Mosberger 	MAX3421_HI_SNDBAV_BIT,		/* send buffer available */
2432d53139fSDavid Mosberger 	MAX3421_HI_SUSDN_BIT,		/* suspend operation done */
2442d53139fSDavid Mosberger 	MAX3421_HI_CONDET_BIT,		/* peripheral connect/disconnect */
2452d53139fSDavid Mosberger 	MAX3421_HI_FRAME_BIT,		/* frame generator */
2462d53139fSDavid Mosberger 	MAX3421_HI_HXFRDN_BIT,		/* host transfer done */
2472d53139fSDavid Mosberger };
2482d53139fSDavid Mosberger 
2492d53139fSDavid Mosberger enum {
2502d53139fSDavid Mosberger 	MAX3421_HCTL_BUSRST_BIT = 0,
2512d53139fSDavid Mosberger 	MAX3421_HCTL_FRMRST_BIT,
2522d53139fSDavid Mosberger 	MAX3421_HCTL_SAMPLEBUS_BIT,
2532d53139fSDavid Mosberger 	MAX3421_HCTL_SIGRSM_BIT,
2542d53139fSDavid Mosberger 	MAX3421_HCTL_RCVTOG0_BIT,
2552d53139fSDavid Mosberger 	MAX3421_HCTL_RCVTOG1_BIT,
2562d53139fSDavid Mosberger 	MAX3421_HCTL_SNDTOG0_BIT,
2572d53139fSDavid Mosberger 	MAX3421_HCTL_SNDTOG1_BIT
2582d53139fSDavid Mosberger };
2592d53139fSDavid Mosberger 
2602d53139fSDavid Mosberger enum {
2612d53139fSDavid Mosberger 	MAX3421_MODE_HOST_BIT = 0,
2622d53139fSDavid Mosberger 	MAX3421_MODE_LOWSPEED_BIT,
2632d53139fSDavid Mosberger 	MAX3421_MODE_HUBPRE_BIT,
2642d53139fSDavid Mosberger 	MAX3421_MODE_SOFKAENAB_BIT,
2652d53139fSDavid Mosberger 	MAX3421_MODE_SEPIRQ_BIT,
2662d53139fSDavid Mosberger 	MAX3421_MODE_DELAYISO_BIT,
2672d53139fSDavid Mosberger 	MAX3421_MODE_DMPULLDN_BIT,
2682d53139fSDavid Mosberger 	MAX3421_MODE_DPPULLDN_BIT
2692d53139fSDavid Mosberger };
2702d53139fSDavid Mosberger 
2712d53139fSDavid Mosberger enum {
2722d53139fSDavid Mosberger 	MAX3421_HRSL_OK = 0,
2732d53139fSDavid Mosberger 	MAX3421_HRSL_BUSY,
2742d53139fSDavid Mosberger 	MAX3421_HRSL_BADREQ,
2752d53139fSDavid Mosberger 	MAX3421_HRSL_UNDEF,
2762d53139fSDavid Mosberger 	MAX3421_HRSL_NAK,
2772d53139fSDavid Mosberger 	MAX3421_HRSL_STALL,
2782d53139fSDavid Mosberger 	MAX3421_HRSL_TOGERR,
2792d53139fSDavid Mosberger 	MAX3421_HRSL_WRONGPID,
2802d53139fSDavid Mosberger 	MAX3421_HRSL_BADBC,
2812d53139fSDavid Mosberger 	MAX3421_HRSL_PIDERR,
2822d53139fSDavid Mosberger 	MAX3421_HRSL_PKTERR,
2832d53139fSDavid Mosberger 	MAX3421_HRSL_CRCERR,
2842d53139fSDavid Mosberger 	MAX3421_HRSL_KERR,
2852d53139fSDavid Mosberger 	MAX3421_HRSL_JERR,
2862d53139fSDavid Mosberger 	MAX3421_HRSL_TIMEOUT,
2872d53139fSDavid Mosberger 	MAX3421_HRSL_BABBLE,
2882d53139fSDavid Mosberger 	MAX3421_HRSL_RESULT_MASK = 0xf,
2892d53139fSDavid Mosberger 	MAX3421_HRSL_RCVTOGRD_BIT = 4,
2902d53139fSDavid Mosberger 	MAX3421_HRSL_SNDTOGRD_BIT,
2912d53139fSDavid Mosberger 	MAX3421_HRSL_KSTATUS_BIT,
2922d53139fSDavid Mosberger 	MAX3421_HRSL_JSTATUS_BIT
2932d53139fSDavid Mosberger };
2942d53139fSDavid Mosberger 
2952d53139fSDavid Mosberger /* Return same error-codes as ohci.h:cc_to_error: */
2962d53139fSDavid Mosberger static const int hrsl_to_error[] = {
2972d53139fSDavid Mosberger 	[MAX3421_HRSL_OK] =		0,
2982d53139fSDavid Mosberger 	[MAX3421_HRSL_BUSY] =		-EINVAL,
2992d53139fSDavid Mosberger 	[MAX3421_HRSL_BADREQ] =		-EINVAL,
3002d53139fSDavid Mosberger 	[MAX3421_HRSL_UNDEF] =		-EINVAL,
3012d53139fSDavid Mosberger 	[MAX3421_HRSL_NAK] =		-EAGAIN,
3022d53139fSDavid Mosberger 	[MAX3421_HRSL_STALL] =		-EPIPE,
3032d53139fSDavid Mosberger 	[MAX3421_HRSL_TOGERR] =		-EILSEQ,
3042d53139fSDavid Mosberger 	[MAX3421_HRSL_WRONGPID] =	-EPROTO,
3052d53139fSDavid Mosberger 	[MAX3421_HRSL_BADBC] =		-EREMOTEIO,
3062d53139fSDavid Mosberger 	[MAX3421_HRSL_PIDERR] =		-EPROTO,
3072d53139fSDavid Mosberger 	[MAX3421_HRSL_PKTERR] =		-EPROTO,
3082d53139fSDavid Mosberger 	[MAX3421_HRSL_CRCERR] =		-EILSEQ,
3092d53139fSDavid Mosberger 	[MAX3421_HRSL_KERR] =		-EIO,
3102d53139fSDavid Mosberger 	[MAX3421_HRSL_JERR] =		-EIO,
3112d53139fSDavid Mosberger 	[MAX3421_HRSL_TIMEOUT] =	-ETIME,
3122d53139fSDavid Mosberger 	[MAX3421_HRSL_BABBLE] =		-EOVERFLOW
3132d53139fSDavid Mosberger };
3142d53139fSDavid Mosberger 
3152d53139fSDavid Mosberger /*
3162d53139fSDavid Mosberger  * See http://www.beyondlogic.org/usbnutshell/usb4.shtml#Control for a
3172d53139fSDavid Mosberger  * reasonable overview of how control transfers use the the IN/OUT
3182d53139fSDavid Mosberger  * tokens.
3192d53139fSDavid Mosberger  */
3202d53139fSDavid Mosberger #define MAX3421_HXFR_BULK_IN(ep)	(0x00 | (ep))	/* bulk or interrupt */
3212d53139fSDavid Mosberger #define MAX3421_HXFR_SETUP		 0x10
3222d53139fSDavid Mosberger #define MAX3421_HXFR_BULK_OUT(ep)	(0x20 | (ep))	/* bulk or interrupt */
3232d53139fSDavid Mosberger #define MAX3421_HXFR_ISO_IN(ep)		(0x40 | (ep))
3242d53139fSDavid Mosberger #define MAX3421_HXFR_ISO_OUT(ep)	(0x60 | (ep))
3252d53139fSDavid Mosberger #define MAX3421_HXFR_HS_IN		 0x80		/* handshake in */
3262d53139fSDavid Mosberger #define MAX3421_HXFR_HS_OUT		 0xa0		/* handshake out */
3272d53139fSDavid Mosberger 
3282d53139fSDavid Mosberger #define field(val, bit)	((val) << (bit))
3292d53139fSDavid Mosberger 
3302d53139fSDavid Mosberger static inline s16
3312d53139fSDavid Mosberger frame_diff(u16 left, u16 right)
3322d53139fSDavid Mosberger {
3332d53139fSDavid Mosberger 	return ((unsigned) (left - right)) % (USB_MAX_FRAME_NUMBER + 1);
3342d53139fSDavid Mosberger }
3352d53139fSDavid Mosberger 
3362d53139fSDavid Mosberger static inline struct max3421_hcd *
3372d53139fSDavid Mosberger hcd_to_max3421(struct usb_hcd *hcd)
3382d53139fSDavid Mosberger {
3392d53139fSDavid Mosberger 	return (struct max3421_hcd *) hcd->hcd_priv;
3402d53139fSDavid Mosberger }
3412d53139fSDavid Mosberger 
3422d53139fSDavid Mosberger static inline struct usb_hcd *
3432d53139fSDavid Mosberger max3421_to_hcd(struct max3421_hcd *max3421_hcd)
3442d53139fSDavid Mosberger {
3452d53139fSDavid Mosberger 	return container_of((void *) max3421_hcd, struct usb_hcd, hcd_priv);
3462d53139fSDavid Mosberger }
3472d53139fSDavid Mosberger 
3482d53139fSDavid Mosberger static u8
3492d53139fSDavid Mosberger spi_rd8(struct usb_hcd *hcd, unsigned int reg)
3502d53139fSDavid Mosberger {
35105dfa5c9SDavid Mosberger-Tang 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
3522d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
3532d53139fSDavid Mosberger 	struct spi_transfer transfer;
3542d53139fSDavid Mosberger 	struct spi_message msg;
3552d53139fSDavid Mosberger 
3562d53139fSDavid Mosberger 	memset(&transfer, 0, sizeof(transfer));
3572d53139fSDavid Mosberger 
3582d53139fSDavid Mosberger 	spi_message_init(&msg);
3592d53139fSDavid Mosberger 
36005dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx->data[0] =
36105dfa5c9SDavid Mosberger-Tang 		(field(reg, MAX3421_SPI_REG_SHIFT) |
3622d53139fSDavid Mosberger 		 field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT));
3632d53139fSDavid Mosberger 
36405dfa5c9SDavid Mosberger-Tang 	transfer.tx_buf = max3421_hcd->tx->data;
36505dfa5c9SDavid Mosberger-Tang 	transfer.rx_buf = max3421_hcd->rx->data;
3662d53139fSDavid Mosberger 	transfer.len = 2;
3672d53139fSDavid Mosberger 
3682d53139fSDavid Mosberger 	spi_message_add_tail(&transfer, &msg);
3692d53139fSDavid Mosberger 	spi_sync(spi, &msg);
3702d53139fSDavid Mosberger 
37105dfa5c9SDavid Mosberger-Tang 	return max3421_hcd->rx->data[1];
3722d53139fSDavid Mosberger }
3732d53139fSDavid Mosberger 
3742d53139fSDavid Mosberger static void
3752d53139fSDavid Mosberger spi_wr8(struct usb_hcd *hcd, unsigned int reg, u8 val)
3762d53139fSDavid Mosberger {
3772d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
37805dfa5c9SDavid Mosberger-Tang 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
3792d53139fSDavid Mosberger 	struct spi_transfer transfer;
3802d53139fSDavid Mosberger 	struct spi_message msg;
3812d53139fSDavid Mosberger 
3822d53139fSDavid Mosberger 	memset(&transfer, 0, sizeof(transfer));
3832d53139fSDavid Mosberger 
3842d53139fSDavid Mosberger 	spi_message_init(&msg);
3852d53139fSDavid Mosberger 
38605dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx->data[0] =
38705dfa5c9SDavid Mosberger-Tang 		(field(reg, MAX3421_SPI_REG_SHIFT) |
3882d53139fSDavid Mosberger 		 field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT));
38905dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx->data[1] = val;
3902d53139fSDavid Mosberger 
39105dfa5c9SDavid Mosberger-Tang 	transfer.tx_buf = max3421_hcd->tx->data;
3922d53139fSDavid Mosberger 	transfer.len = 2;
3932d53139fSDavid Mosberger 
3942d53139fSDavid Mosberger 	spi_message_add_tail(&transfer, &msg);
3952d53139fSDavid Mosberger 	spi_sync(spi, &msg);
3962d53139fSDavid Mosberger }
3972d53139fSDavid Mosberger 
3982d53139fSDavid Mosberger static void
3992d53139fSDavid Mosberger spi_rd_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len)
4002d53139fSDavid Mosberger {
4012d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
40205dfa5c9SDavid Mosberger-Tang 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
4032d53139fSDavid Mosberger 	struct spi_transfer transfer[2];
4042d53139fSDavid Mosberger 	struct spi_message msg;
4052d53139fSDavid Mosberger 
4062d53139fSDavid Mosberger 	memset(transfer, 0, sizeof(transfer));
4072d53139fSDavid Mosberger 
4082d53139fSDavid Mosberger 	spi_message_init(&msg);
4092d53139fSDavid Mosberger 
41005dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx->data[0] =
41105dfa5c9SDavid Mosberger-Tang 		(field(reg, MAX3421_SPI_REG_SHIFT) |
4122d53139fSDavid Mosberger 		 field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT));
41305dfa5c9SDavid Mosberger-Tang 	transfer[0].tx_buf = max3421_hcd->tx->data;
4142d53139fSDavid Mosberger 	transfer[0].len = 1;
4152d53139fSDavid Mosberger 
4162d53139fSDavid Mosberger 	transfer[1].rx_buf = buf;
4172d53139fSDavid Mosberger 	transfer[1].len = len;
4182d53139fSDavid Mosberger 
4192d53139fSDavid Mosberger 	spi_message_add_tail(&transfer[0], &msg);
4202d53139fSDavid Mosberger 	spi_message_add_tail(&transfer[1], &msg);
4212d53139fSDavid Mosberger 	spi_sync(spi, &msg);
4222d53139fSDavid Mosberger }
4232d53139fSDavid Mosberger 
4242d53139fSDavid Mosberger static void
4252d53139fSDavid Mosberger spi_wr_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len)
4262d53139fSDavid Mosberger {
4272d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
42805dfa5c9SDavid Mosberger-Tang 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
4292d53139fSDavid Mosberger 	struct spi_transfer transfer[2];
4302d53139fSDavid Mosberger 	struct spi_message msg;
4312d53139fSDavid Mosberger 
4322d53139fSDavid Mosberger 	memset(transfer, 0, sizeof(transfer));
4332d53139fSDavid Mosberger 
4342d53139fSDavid Mosberger 	spi_message_init(&msg);
4352d53139fSDavid Mosberger 
43605dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx->data[0] =
43705dfa5c9SDavid Mosberger-Tang 		(field(reg, MAX3421_SPI_REG_SHIFT) |
4382d53139fSDavid Mosberger 		 field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT));
4392d53139fSDavid Mosberger 
44005dfa5c9SDavid Mosberger-Tang 	transfer[0].tx_buf = max3421_hcd->tx->data;
4412d53139fSDavid Mosberger 	transfer[0].len = 1;
4422d53139fSDavid Mosberger 
4432d53139fSDavid Mosberger 	transfer[1].tx_buf = buf;
4442d53139fSDavid Mosberger 	transfer[1].len = len;
4452d53139fSDavid Mosberger 
4462d53139fSDavid Mosberger 	spi_message_add_tail(&transfer[0], &msg);
4472d53139fSDavid Mosberger 	spi_message_add_tail(&transfer[1], &msg);
4482d53139fSDavid Mosberger 	spi_sync(spi, &msg);
4492d53139fSDavid Mosberger }
4502d53139fSDavid Mosberger 
4512d53139fSDavid Mosberger /*
4522d53139fSDavid Mosberger  * Figure out the correct setting for the LOWSPEED and HUBPRE mode
4532d53139fSDavid Mosberger  * bits.  The HUBPRE bit needs to be set when MAX3421E operates at
4542d53139fSDavid Mosberger  * full speed, but it's talking to a low-speed device (i.e., through a
4552d53139fSDavid Mosberger  * hub).  Setting that bit ensures that every low-speed packet is
4562d53139fSDavid Mosberger  * preceded by a full-speed PRE PID.  Possible configurations:
4572d53139fSDavid Mosberger  *
4582d53139fSDavid Mosberger  * Hub speed:	Device speed:	=>	LOWSPEED bit:	HUBPRE bit:
4592d53139fSDavid Mosberger  *	FULL	FULL		=>	0		0
4602d53139fSDavid Mosberger  *	FULL	LOW		=>	1		1
4612d53139fSDavid Mosberger  *	LOW	LOW		=>	1		0
4622d53139fSDavid Mosberger  *	LOW	FULL		=>	1		0
4632d53139fSDavid Mosberger  */
4642d53139fSDavid Mosberger static void
4652d53139fSDavid Mosberger max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev)
4662d53139fSDavid Mosberger {
4672d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
4682d53139fSDavid Mosberger 	u8 mode_lowspeed, mode_hubpre, mode = max3421_hcd->mode;
4692d53139fSDavid Mosberger 
4702d53139fSDavid Mosberger 	mode_lowspeed = BIT(MAX3421_MODE_LOWSPEED_BIT);
4712d53139fSDavid Mosberger 	mode_hubpre   = BIT(MAX3421_MODE_HUBPRE_BIT);
4722d53139fSDavid Mosberger 	if (max3421_hcd->port_status & USB_PORT_STAT_LOW_SPEED) {
4732d53139fSDavid Mosberger 		mode |=  mode_lowspeed;
4742d53139fSDavid Mosberger 		mode &= ~mode_hubpre;
4752d53139fSDavid Mosberger 	} else if (dev->speed == USB_SPEED_LOW) {
4762d53139fSDavid Mosberger 		mode |= mode_lowspeed | mode_hubpre;
4772d53139fSDavid Mosberger 	} else {
4782d53139fSDavid Mosberger 		mode &= ~(mode_lowspeed | mode_hubpre);
4792d53139fSDavid Mosberger 	}
4802d53139fSDavid Mosberger 	if (mode != max3421_hcd->mode) {
4812d53139fSDavid Mosberger 		max3421_hcd->mode = mode;
4822d53139fSDavid Mosberger 		spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode);
4832d53139fSDavid Mosberger 	}
4842d53139fSDavid Mosberger 
4852d53139fSDavid Mosberger }
4862d53139fSDavid Mosberger 
4872d53139fSDavid Mosberger /*
4882d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
4892d53139fSDavid Mosberger  */
4902d53139fSDavid Mosberger static void
4912d53139fSDavid Mosberger max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum,
4922d53139fSDavid Mosberger 		    int force_toggles)
4932d53139fSDavid Mosberger {
4942d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
4952d53139fSDavid Mosberger 	int old_epnum, same_ep, rcvtog, sndtog;
4962d53139fSDavid Mosberger 	struct usb_device *old_dev;
4972d53139fSDavid Mosberger 	u8 hctl;
4982d53139fSDavid Mosberger 
4992d53139fSDavid Mosberger 	old_dev = max3421_hcd->loaded_dev;
5002d53139fSDavid Mosberger 	old_epnum = max3421_hcd->loaded_epnum;
5012d53139fSDavid Mosberger 
5022d53139fSDavid Mosberger 	same_ep = (dev == old_dev && epnum == old_epnum);
5032d53139fSDavid Mosberger 	if (same_ep && !force_toggles)
5042d53139fSDavid Mosberger 		return;
5052d53139fSDavid Mosberger 
5062d53139fSDavid Mosberger 	if (old_dev && !same_ep) {
5072d53139fSDavid Mosberger 		/* save the old end-points toggles: */
5082d53139fSDavid Mosberger 		u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);
5092d53139fSDavid Mosberger 
5102d53139fSDavid Mosberger 		rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1;
5112d53139fSDavid Mosberger 		sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1;
5122d53139fSDavid Mosberger 
5132d53139fSDavid Mosberger 		/* no locking: HCD (i.e., we) own toggles, don't we? */
5142d53139fSDavid Mosberger 		usb_settoggle(old_dev, old_epnum, 0, rcvtog);
5152d53139fSDavid Mosberger 		usb_settoggle(old_dev, old_epnum, 1, sndtog);
5162d53139fSDavid Mosberger 	}
5172d53139fSDavid Mosberger 	/* setup new endpoint's toggle bits: */
5182d53139fSDavid Mosberger 	rcvtog = usb_gettoggle(dev, epnum, 0);
5192d53139fSDavid Mosberger 	sndtog = usb_gettoggle(dev, epnum, 1);
5202d53139fSDavid Mosberger 	hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) |
5212d53139fSDavid Mosberger 		BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT));
5222d53139fSDavid Mosberger 
5232d53139fSDavid Mosberger 	max3421_hcd->loaded_epnum = epnum;
5242d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HCTL, hctl);
5252d53139fSDavid Mosberger 
5262d53139fSDavid Mosberger 	/*
5272d53139fSDavid Mosberger 	 * Note: devnum for one and the same device can change during
5282d53139fSDavid Mosberger 	 * address-assignment so it's best to just always load the
5292d53139fSDavid Mosberger 	 * address whenever the end-point changed/was forced.
5302d53139fSDavid Mosberger 	 */
5312d53139fSDavid Mosberger 	max3421_hcd->loaded_dev = dev;
5322d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum);
5332d53139fSDavid Mosberger }
5342d53139fSDavid Mosberger 
5352d53139fSDavid Mosberger static int
5362d53139fSDavid Mosberger max3421_ctrl_setup(struct usb_hcd *hcd, struct urb *urb)
5372d53139fSDavid Mosberger {
5382d53139fSDavid Mosberger 	spi_wr_buf(hcd, MAX3421_REG_SUDFIFO, urb->setup_packet, 8);
5392d53139fSDavid Mosberger 	return MAX3421_HXFR_SETUP;
5402d53139fSDavid Mosberger }
5412d53139fSDavid Mosberger 
5422d53139fSDavid Mosberger static int
5432d53139fSDavid Mosberger max3421_transfer_in(struct usb_hcd *hcd, struct urb *urb)
5442d53139fSDavid Mosberger {
5452d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
5462d53139fSDavid Mosberger 	int epnum = usb_pipeendpoint(urb->pipe);
5472d53139fSDavid Mosberger 
5482d53139fSDavid Mosberger 	max3421_hcd->curr_len = 0;
5492d53139fSDavid Mosberger 	max3421_hcd->hien |= BIT(MAX3421_HI_RCVDAV_BIT);
5502d53139fSDavid Mosberger 	return MAX3421_HXFR_BULK_IN(epnum);
5512d53139fSDavid Mosberger }
5522d53139fSDavid Mosberger 
5532d53139fSDavid Mosberger static int
5542d53139fSDavid Mosberger max3421_transfer_out(struct usb_hcd *hcd, struct urb *urb, int fast_retransmit)
5552d53139fSDavid Mosberger {
5562d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
5572d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
5582d53139fSDavid Mosberger 	int epnum = usb_pipeendpoint(urb->pipe);
5592d53139fSDavid Mosberger 	u32 max_packet;
5602d53139fSDavid Mosberger 	void *src;
5612d53139fSDavid Mosberger 
5622d53139fSDavid Mosberger 	src = urb->transfer_buffer + urb->actual_length;
5632d53139fSDavid Mosberger 
5642d53139fSDavid Mosberger 	if (fast_retransmit) {
5652d53139fSDavid Mosberger 		if (max3421_hcd->rev == 0x12) {
5662d53139fSDavid Mosberger 			/* work around rev 0x12 bug: */
5672d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_SNDBC, 0);
5682d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_SNDFIFO, ((u8 *) src)[0]);
5692d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len);
5702d53139fSDavid Mosberger 		}
5712d53139fSDavid Mosberger 		return MAX3421_HXFR_BULK_OUT(epnum);
5722d53139fSDavid Mosberger 	}
5732d53139fSDavid Mosberger 
5742d53139fSDavid Mosberger 	max_packet = usb_maxpacket(urb->dev, urb->pipe, 1);
5752d53139fSDavid Mosberger 
5762d53139fSDavid Mosberger 	if (max_packet > MAX3421_FIFO_SIZE) {
5772d53139fSDavid Mosberger 		/*
5782d53139fSDavid Mosberger 		 * We do not support isochronous transfers at this
5792d53139fSDavid Mosberger 		 * time.
5802d53139fSDavid Mosberger 		 */
5812d53139fSDavid Mosberger 		dev_err(&spi->dev,
5822d53139fSDavid Mosberger 			"%s: packet-size of %u too big (limit is %u bytes)",
5832d53139fSDavid Mosberger 			__func__, max_packet, MAX3421_FIFO_SIZE);
5842d53139fSDavid Mosberger 		max3421_hcd->urb_done = -EMSGSIZE;
5852d53139fSDavid Mosberger 		return -EMSGSIZE;
5862d53139fSDavid Mosberger 	}
5872d53139fSDavid Mosberger 	max3421_hcd->curr_len = min((urb->transfer_buffer_length -
5882d53139fSDavid Mosberger 				     urb->actual_length), max_packet);
5892d53139fSDavid Mosberger 
5902d53139fSDavid Mosberger 	spi_wr_buf(hcd, MAX3421_REG_SNDFIFO, src, max3421_hcd->curr_len);
5912d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len);
5922d53139fSDavid Mosberger 	return MAX3421_HXFR_BULK_OUT(epnum);
5932d53139fSDavid Mosberger }
5942d53139fSDavid Mosberger 
5952d53139fSDavid Mosberger /*
5962d53139fSDavid Mosberger  * Issue the next host-transfer command.
5972d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
5982d53139fSDavid Mosberger  */
5992d53139fSDavid Mosberger static void
6002d53139fSDavid Mosberger max3421_next_transfer(struct usb_hcd *hcd, int fast_retransmit)
6012d53139fSDavid Mosberger {
6022d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
6032d53139fSDavid Mosberger 	struct urb *urb = max3421_hcd->curr_urb;
604f9da25c7SDavid Mosberger-Tang 	struct max3421_ep *max3421_ep;
6052d53139fSDavid Mosberger 	int cmd = -EINVAL;
6062d53139fSDavid Mosberger 
6072d53139fSDavid Mosberger 	if (!urb)
6082d53139fSDavid Mosberger 		return;	/* nothing to do */
6092d53139fSDavid Mosberger 
610f9da25c7SDavid Mosberger-Tang 	max3421_ep = urb->ep->hcpriv;
611f9da25c7SDavid Mosberger-Tang 
6122d53139fSDavid Mosberger 	switch (max3421_ep->pkt_state) {
6132d53139fSDavid Mosberger 	case PKT_STATE_SETUP:
6142d53139fSDavid Mosberger 		cmd = max3421_ctrl_setup(hcd, urb);
6152d53139fSDavid Mosberger 		break;
6162d53139fSDavid Mosberger 
6172d53139fSDavid Mosberger 	case PKT_STATE_TRANSFER:
6182d53139fSDavid Mosberger 		if (usb_urb_dir_in(urb))
6192d53139fSDavid Mosberger 			cmd = max3421_transfer_in(hcd, urb);
6202d53139fSDavid Mosberger 		else
6212d53139fSDavid Mosberger 			cmd = max3421_transfer_out(hcd, urb, fast_retransmit);
6222d53139fSDavid Mosberger 		break;
6232d53139fSDavid Mosberger 
6242d53139fSDavid Mosberger 	case PKT_STATE_TERMINATE:
6252d53139fSDavid Mosberger 		/*
6262d53139fSDavid Mosberger 		 * IN transfers are terminated with HS_OUT token,
6272d53139fSDavid Mosberger 		 * OUT transfers with HS_IN:
6282d53139fSDavid Mosberger 		 */
6292d53139fSDavid Mosberger 		if (usb_urb_dir_in(urb))
6302d53139fSDavid Mosberger 			cmd = MAX3421_HXFR_HS_OUT;
6312d53139fSDavid Mosberger 		else
6322d53139fSDavid Mosberger 			cmd = MAX3421_HXFR_HS_IN;
6332d53139fSDavid Mosberger 		break;
6342d53139fSDavid Mosberger 	}
6352d53139fSDavid Mosberger 
6362d53139fSDavid Mosberger 	if (cmd < 0)
6372d53139fSDavid Mosberger 		return;
6382d53139fSDavid Mosberger 
6392d53139fSDavid Mosberger 	/* issue the command and wait for host-xfer-done interrupt: */
6402d53139fSDavid Mosberger 
6412d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HXFR, cmd);
6422d53139fSDavid Mosberger 	max3421_hcd->hien |= BIT(MAX3421_HI_HXFRDN_BIT);
6432d53139fSDavid Mosberger }
6442d53139fSDavid Mosberger 
6452d53139fSDavid Mosberger /*
6462d53139fSDavid Mosberger  * Find the next URB to process and start its execution.
6472d53139fSDavid Mosberger  *
6482d53139fSDavid Mosberger  * At this time, we do not anticipate ever connecting a USB hub to the
6492d53139fSDavid Mosberger  * MAX3421 chip, so at most USB device can be connected and we can use
6502d53139fSDavid Mosberger  * a simplistic scheduler: at the start of a frame, schedule all
6512d53139fSDavid Mosberger  * periodic transfers.  Once that is done, use the remainder of the
6522d53139fSDavid Mosberger  * frame to process non-periodic (bulk & control) transfers.
6532d53139fSDavid Mosberger  *
6542d53139fSDavid Mosberger  * Preconditions:
6552d53139fSDavid Mosberger  * o Caller must NOT hold HCD spinlock.
6562d53139fSDavid Mosberger  * o max3421_hcd->curr_urb MUST BE NULL.
6572d53139fSDavid Mosberger  * o MAX3421E chip must be idle.
6582d53139fSDavid Mosberger  */
6592d53139fSDavid Mosberger static int
6602d53139fSDavid Mosberger max3421_select_and_start_urb(struct usb_hcd *hcd)
6612d53139fSDavid Mosberger {
6622d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
6632d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
6642d53139fSDavid Mosberger 	struct urb *urb, *curr_urb = NULL;
6652d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
6662d53139fSDavid Mosberger 	int epnum, force_toggles = 0;
6672d53139fSDavid Mosberger 	struct usb_host_endpoint *ep;
6682d53139fSDavid Mosberger 	struct list_head *pos;
6692d53139fSDavid Mosberger 	unsigned long flags;
6702d53139fSDavid Mosberger 
6712d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
6722d53139fSDavid Mosberger 
6732d53139fSDavid Mosberger 	for (;
6742d53139fSDavid Mosberger 	     max3421_hcd->sched_pass < SCHED_PASS_DONE;
6752d53139fSDavid Mosberger 	     ++max3421_hcd->sched_pass)
6762d53139fSDavid Mosberger 		list_for_each(pos, &max3421_hcd->ep_list) {
6772d53139fSDavid Mosberger 			urb = NULL;
6782d53139fSDavid Mosberger 			max3421_ep = container_of(pos, struct max3421_ep,
6792d53139fSDavid Mosberger 						  ep_list);
6802d53139fSDavid Mosberger 			ep = max3421_ep->ep;
6812d53139fSDavid Mosberger 
6822d53139fSDavid Mosberger 			switch (usb_endpoint_type(&ep->desc)) {
6832d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_ISOC:
6842d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_INT:
6852d53139fSDavid Mosberger 				if (max3421_hcd->sched_pass !=
6862d53139fSDavid Mosberger 				    SCHED_PASS_PERIODIC)
6872d53139fSDavid Mosberger 					continue;
6882d53139fSDavid Mosberger 				break;
6892d53139fSDavid Mosberger 
6902d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_CONTROL:
6912d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_BULK:
6922d53139fSDavid Mosberger 				if (max3421_hcd->sched_pass !=
6932d53139fSDavid Mosberger 				    SCHED_PASS_NON_PERIODIC)
6942d53139fSDavid Mosberger 					continue;
6952d53139fSDavid Mosberger 				break;
6962d53139fSDavid Mosberger 			}
6972d53139fSDavid Mosberger 
6982d53139fSDavid Mosberger 			if (list_empty(&ep->urb_list))
6992d53139fSDavid Mosberger 				continue;	/* nothing to do */
7002d53139fSDavid Mosberger 			urb = list_first_entry(&ep->urb_list, struct urb,
7012d53139fSDavid Mosberger 					       urb_list);
7022d53139fSDavid Mosberger 			if (urb->unlinked) {
7032d53139fSDavid Mosberger 				dev_dbg(&spi->dev, "%s: URB %p unlinked=%d",
7042d53139fSDavid Mosberger 					__func__, urb, urb->unlinked);
7052d53139fSDavid Mosberger 				max3421_hcd->curr_urb = urb;
7062d53139fSDavid Mosberger 				max3421_hcd->urb_done = 1;
7072d53139fSDavid Mosberger 				spin_unlock_irqrestore(&max3421_hcd->lock,
7082d53139fSDavid Mosberger 						       flags);
7092d53139fSDavid Mosberger 				return 1;
7102d53139fSDavid Mosberger 			}
7112d53139fSDavid Mosberger 
7122d53139fSDavid Mosberger 			switch (usb_endpoint_type(&ep->desc)) {
7132d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_CONTROL:
7142d53139fSDavid Mosberger 				/*
7152d53139fSDavid Mosberger 				 * Allow one control transaction per
7162d53139fSDavid Mosberger 				 * frame per endpoint:
7172d53139fSDavid Mosberger 				 */
7182d53139fSDavid Mosberger 				if (frame_diff(max3421_ep->last_active,
7192d53139fSDavid Mosberger 					       max3421_hcd->frame_number) == 0)
7202d53139fSDavid Mosberger 					continue;
7212d53139fSDavid Mosberger 				break;
7222d53139fSDavid Mosberger 
7232d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_BULK:
7242d53139fSDavid Mosberger 				if (max3421_ep->retransmit
7252d53139fSDavid Mosberger 				    && (frame_diff(max3421_ep->last_active,
7262d53139fSDavid Mosberger 						   max3421_hcd->frame_number)
7272d53139fSDavid Mosberger 					== 0))
7282d53139fSDavid Mosberger 					/*
7292d53139fSDavid Mosberger 					 * We already tried this EP
7302d53139fSDavid Mosberger 					 * during this frame and got a
7312d53139fSDavid Mosberger 					 * NAK or error; wait for next frame
7322d53139fSDavid Mosberger 					 */
7332d53139fSDavid Mosberger 					continue;
7342d53139fSDavid Mosberger 				break;
7352d53139fSDavid Mosberger 
7362d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_ISOC:
7372d53139fSDavid Mosberger 			case USB_ENDPOINT_XFER_INT:
7382d53139fSDavid Mosberger 				if (frame_diff(max3421_hcd->frame_number,
7392d53139fSDavid Mosberger 					       max3421_ep->last_active)
7402d53139fSDavid Mosberger 				    < urb->interval)
7412d53139fSDavid Mosberger 					/*
7422d53139fSDavid Mosberger 					 * We already processed this
7432d53139fSDavid Mosberger 					 * end-point in the current
7442d53139fSDavid Mosberger 					 * frame
7452d53139fSDavid Mosberger 					 */
7462d53139fSDavid Mosberger 					continue;
7472d53139fSDavid Mosberger 				break;
7482d53139fSDavid Mosberger 			}
7492d53139fSDavid Mosberger 
7502d53139fSDavid Mosberger 			/* move current ep to tail: */
7512d53139fSDavid Mosberger 			list_move_tail(pos, &max3421_hcd->ep_list);
7522d53139fSDavid Mosberger 			curr_urb = urb;
7532d53139fSDavid Mosberger 			goto done;
7542d53139fSDavid Mosberger 		}
7552d53139fSDavid Mosberger done:
7562d53139fSDavid Mosberger 	if (!curr_urb) {
7572d53139fSDavid Mosberger 		spin_unlock_irqrestore(&max3421_hcd->lock, flags);
7582d53139fSDavid Mosberger 		return 0;
7592d53139fSDavid Mosberger 	}
7602d53139fSDavid Mosberger 
7612d53139fSDavid Mosberger 	urb = max3421_hcd->curr_urb = curr_urb;
7622d53139fSDavid Mosberger 	epnum = usb_endpoint_num(&urb->ep->desc);
7632d53139fSDavid Mosberger 	if (max3421_ep->retransmit)
7642d53139fSDavid Mosberger 		/* restart (part of) a USB transaction: */
7652d53139fSDavid Mosberger 		max3421_ep->retransmit = 0;
7662d53139fSDavid Mosberger 	else {
7672d53139fSDavid Mosberger 		/* start USB transaction: */
7682d53139fSDavid Mosberger 		if (usb_endpoint_xfer_control(&ep->desc)) {
7692d53139fSDavid Mosberger 			/*
7702d53139fSDavid Mosberger 			 * See USB 2.0 spec section 8.6.1
7712d53139fSDavid Mosberger 			 * Initialization via SETUP Token:
7722d53139fSDavid Mosberger 			 */
7732d53139fSDavid Mosberger 			usb_settoggle(urb->dev, epnum, 0, 1);
7742d53139fSDavid Mosberger 			usb_settoggle(urb->dev, epnum, 1, 1);
7752d53139fSDavid Mosberger 			max3421_ep->pkt_state = PKT_STATE_SETUP;
7762d53139fSDavid Mosberger 			force_toggles = 1;
7772d53139fSDavid Mosberger 		} else
7782d53139fSDavid Mosberger 			max3421_ep->pkt_state = PKT_STATE_TRANSFER;
7792d53139fSDavid Mosberger 	}
7802d53139fSDavid Mosberger 
7812d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
7822d53139fSDavid Mosberger 
7832d53139fSDavid Mosberger 	max3421_ep->last_active = max3421_hcd->frame_number;
7842d53139fSDavid Mosberger 	max3421_set_address(hcd, urb->dev, epnum, force_toggles);
7852d53139fSDavid Mosberger 	max3421_set_speed(hcd, urb->dev);
7862d53139fSDavid Mosberger 	max3421_next_transfer(hcd, 0);
7872d53139fSDavid Mosberger 	return 1;
7882d53139fSDavid Mosberger }
7892d53139fSDavid Mosberger 
7902d53139fSDavid Mosberger /*
7912d53139fSDavid Mosberger  * Check all endpoints for URBs that got unlinked.
7922d53139fSDavid Mosberger  *
7932d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
7942d53139fSDavid Mosberger  */
7952d53139fSDavid Mosberger static int
7962d53139fSDavid Mosberger max3421_check_unlink(struct usb_hcd *hcd)
7972d53139fSDavid Mosberger {
7982d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
7992d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
8002d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
8012d53139fSDavid Mosberger 	struct usb_host_endpoint *ep;
802553c2360SGeliang Tang 	struct urb *urb, *next;
8032d53139fSDavid Mosberger 	unsigned long flags;
8042d53139fSDavid Mosberger 	int retval = 0;
8052d53139fSDavid Mosberger 
8062d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
807553c2360SGeliang Tang 	list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) {
8082d53139fSDavid Mosberger 		ep = max3421_ep->ep;
809553c2360SGeliang Tang 		list_for_each_entry_safe(urb, next, &ep->urb_list, urb_list) {
8102d53139fSDavid Mosberger 			if (urb->unlinked) {
8112d53139fSDavid Mosberger 				retval = 1;
8122d53139fSDavid Mosberger 				dev_dbg(&spi->dev, "%s: URB %p unlinked=%d",
8132d53139fSDavid Mosberger 					__func__, urb, urb->unlinked);
8142d53139fSDavid Mosberger 				usb_hcd_unlink_urb_from_ep(hcd, urb);
8152d53139fSDavid Mosberger 				spin_unlock_irqrestore(&max3421_hcd->lock,
8162d53139fSDavid Mosberger 						       flags);
8172d53139fSDavid Mosberger 				usb_hcd_giveback_urb(hcd, urb, 0);
8182d53139fSDavid Mosberger 				spin_lock_irqsave(&max3421_hcd->lock, flags);
8192d53139fSDavid Mosberger 			}
8202d53139fSDavid Mosberger 		}
8212d53139fSDavid Mosberger 	}
8222d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
8232d53139fSDavid Mosberger 	return retval;
8242d53139fSDavid Mosberger }
8252d53139fSDavid Mosberger 
8262d53139fSDavid Mosberger /*
8272d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
8282d53139fSDavid Mosberger  */
8292d53139fSDavid Mosberger static void
8302d53139fSDavid Mosberger max3421_slow_retransmit(struct usb_hcd *hcd)
8312d53139fSDavid Mosberger {
8322d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
8332d53139fSDavid Mosberger 	struct urb *urb = max3421_hcd->curr_urb;
8342d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
8352d53139fSDavid Mosberger 
8362d53139fSDavid Mosberger 	max3421_ep = urb->ep->hcpriv;
8372d53139fSDavid Mosberger 	max3421_ep->retransmit = 1;
8382d53139fSDavid Mosberger 	max3421_hcd->curr_urb = NULL;
8392d53139fSDavid Mosberger }
8402d53139fSDavid Mosberger 
8412d53139fSDavid Mosberger /*
8422d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
8432d53139fSDavid Mosberger  */
8442d53139fSDavid Mosberger static void
8452d53139fSDavid Mosberger max3421_recv_data_available(struct usb_hcd *hcd)
8462d53139fSDavid Mosberger {
8472d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
8482d53139fSDavid Mosberger 	struct urb *urb = max3421_hcd->curr_urb;
8492d53139fSDavid Mosberger 	size_t remaining, transfer_size;
8502d53139fSDavid Mosberger 	u8 rcvbc;
8512d53139fSDavid Mosberger 
8522d53139fSDavid Mosberger 	rcvbc = spi_rd8(hcd, MAX3421_REG_RCVBC);
8532d53139fSDavid Mosberger 
8542d53139fSDavid Mosberger 	if (rcvbc > MAX3421_FIFO_SIZE)
8552d53139fSDavid Mosberger 		rcvbc = MAX3421_FIFO_SIZE;
8562d53139fSDavid Mosberger 	if (urb->actual_length >= urb->transfer_buffer_length)
8572d53139fSDavid Mosberger 		remaining = 0;
8582d53139fSDavid Mosberger 	else
8592d53139fSDavid Mosberger 		remaining = urb->transfer_buffer_length - urb->actual_length;
8602d53139fSDavid Mosberger 	transfer_size = rcvbc;
8612d53139fSDavid Mosberger 	if (transfer_size > remaining)
8622d53139fSDavid Mosberger 		transfer_size = remaining;
8632d53139fSDavid Mosberger 	if (transfer_size > 0) {
8642d53139fSDavid Mosberger 		void *dst = urb->transfer_buffer + urb->actual_length;
8652d53139fSDavid Mosberger 
8662d53139fSDavid Mosberger 		spi_rd_buf(hcd, MAX3421_REG_RCVFIFO, dst, transfer_size);
8672d53139fSDavid Mosberger 		urb->actual_length += transfer_size;
8682d53139fSDavid Mosberger 		max3421_hcd->curr_len = transfer_size;
8692d53139fSDavid Mosberger 	}
8702d53139fSDavid Mosberger 
8712d53139fSDavid Mosberger 	/* ack the RCVDAV irq now that the FIFO has been read: */
8722d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HIRQ, BIT(MAX3421_HI_RCVDAV_BIT));
8732d53139fSDavid Mosberger }
8742d53139fSDavid Mosberger 
8752d53139fSDavid Mosberger static void
8762d53139fSDavid Mosberger max3421_handle_error(struct usb_hcd *hcd, u8 hrsl)
8772d53139fSDavid Mosberger {
8782d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
8792d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
8802d53139fSDavid Mosberger 	u8 result_code = hrsl & MAX3421_HRSL_RESULT_MASK;
8812d53139fSDavid Mosberger 	struct urb *urb = max3421_hcd->curr_urb;
8822d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep = urb->ep->hcpriv;
8832d53139fSDavid Mosberger 	int switch_sndfifo;
8842d53139fSDavid Mosberger 
8852d53139fSDavid Mosberger 	/*
8862d53139fSDavid Mosberger 	 * If an OUT command results in any response other than OK
8872d53139fSDavid Mosberger 	 * (i.e., error or NAK), we have to perform a dummy-write to
8882d53139fSDavid Mosberger 	 * SNDBC so the FIFO gets switched back to us.  Otherwise, we
8892d53139fSDavid Mosberger 	 * get out of sync with the SNDFIFO double buffer.
8902d53139fSDavid Mosberger 	 */
8912d53139fSDavid Mosberger 	switch_sndfifo = (max3421_ep->pkt_state == PKT_STATE_TRANSFER &&
8922d53139fSDavid Mosberger 			  usb_urb_dir_out(urb));
8932d53139fSDavid Mosberger 
8942d53139fSDavid Mosberger 	switch (result_code) {
8952d53139fSDavid Mosberger 	case MAX3421_HRSL_OK:
8962d53139fSDavid Mosberger 		return;			/* this shouldn't happen */
8972d53139fSDavid Mosberger 
8982d53139fSDavid Mosberger 	case MAX3421_HRSL_WRONGPID:	/* received wrong PID */
8992d53139fSDavid Mosberger 	case MAX3421_HRSL_BUSY:		/* SIE busy */
9002d53139fSDavid Mosberger 	case MAX3421_HRSL_BADREQ:	/* bad val in HXFR */
9012d53139fSDavid Mosberger 	case MAX3421_HRSL_UNDEF:	/* reserved */
9022d53139fSDavid Mosberger 	case MAX3421_HRSL_KERR:		/* K-state instead of response */
9032d53139fSDavid Mosberger 	case MAX3421_HRSL_JERR:		/* J-state instead of response */
9042d53139fSDavid Mosberger 		/*
9052d53139fSDavid Mosberger 		 * packet experienced an error that we cannot recover
9062d53139fSDavid Mosberger 		 * from; report error
9072d53139fSDavid Mosberger 		 */
9082d53139fSDavid Mosberger 		max3421_hcd->urb_done = hrsl_to_error[result_code];
9092d53139fSDavid Mosberger 		dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x",
9102d53139fSDavid Mosberger 			__func__, hrsl);
9112d53139fSDavid Mosberger 		break;
9122d53139fSDavid Mosberger 
9132d53139fSDavid Mosberger 	case MAX3421_HRSL_TOGERR:
9142d53139fSDavid Mosberger 		if (usb_urb_dir_in(urb))
9152d53139fSDavid Mosberger 			; /* don't do anything (device will switch toggle) */
9162d53139fSDavid Mosberger 		else {
9172d53139fSDavid Mosberger 			/* flip the send toggle bit: */
9182d53139fSDavid Mosberger 			int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1;
9192d53139fSDavid Mosberger 
9202d53139fSDavid Mosberger 			sndtog ^= 1;
9212d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_HCTL,
9222d53139fSDavid Mosberger 				BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT));
9232d53139fSDavid Mosberger 		}
9242d53139fSDavid Mosberger 		/* FALL THROUGH */
9252d53139fSDavid Mosberger 	case MAX3421_HRSL_BADBC:	/* bad byte count */
9262d53139fSDavid Mosberger 	case MAX3421_HRSL_PIDERR:	/* received PID is corrupted */
9272d53139fSDavid Mosberger 	case MAX3421_HRSL_PKTERR:	/* packet error (stuff, EOP) */
9282d53139fSDavid Mosberger 	case MAX3421_HRSL_CRCERR:	/* CRC error */
9292d53139fSDavid Mosberger 	case MAX3421_HRSL_BABBLE:	/* device talked too long */
9302d53139fSDavid Mosberger 	case MAX3421_HRSL_TIMEOUT:
9312d53139fSDavid Mosberger 		if (max3421_ep->retries++ < USB_MAX_RETRIES)
9322d53139fSDavid Mosberger 			/* retry the packet again in the next frame */
9332d53139fSDavid Mosberger 			max3421_slow_retransmit(hcd);
9342d53139fSDavid Mosberger 		else {
9352d53139fSDavid Mosberger 			/* Based on ohci.h cc_to_err[]: */
9362d53139fSDavid Mosberger 			max3421_hcd->urb_done = hrsl_to_error[result_code];
9372d53139fSDavid Mosberger 			dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x",
9382d53139fSDavid Mosberger 				__func__, hrsl);
9392d53139fSDavid Mosberger 		}
9402d53139fSDavid Mosberger 		break;
9412d53139fSDavid Mosberger 
9422d53139fSDavid Mosberger 	case MAX3421_HRSL_STALL:
9432d53139fSDavid Mosberger 		dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x",
9442d53139fSDavid Mosberger 			__func__, hrsl);
9452d53139fSDavid Mosberger 		max3421_hcd->urb_done = hrsl_to_error[result_code];
9462d53139fSDavid Mosberger 		break;
9472d53139fSDavid Mosberger 
9482d53139fSDavid Mosberger 	case MAX3421_HRSL_NAK:
9492d53139fSDavid Mosberger 		/*
9502d53139fSDavid Mosberger 		 * Device wasn't ready for data or has no data
9512d53139fSDavid Mosberger 		 * available: retry the packet again.
9522d53139fSDavid Mosberger 		 */
9532d53139fSDavid Mosberger 		if (max3421_ep->naks++ < NAK_MAX_FAST_RETRANSMITS) {
9542d53139fSDavid Mosberger 			max3421_next_transfer(hcd, 1);
9552d53139fSDavid Mosberger 			switch_sndfifo = 0;
9562d53139fSDavid Mosberger 		} else
9572d53139fSDavid Mosberger 			max3421_slow_retransmit(hcd);
9582d53139fSDavid Mosberger 		break;
9592d53139fSDavid Mosberger 	}
9602d53139fSDavid Mosberger 	if (switch_sndfifo)
9612d53139fSDavid Mosberger 		spi_wr8(hcd, MAX3421_REG_SNDBC, 0);
9622d53139fSDavid Mosberger }
9632d53139fSDavid Mosberger 
9642d53139fSDavid Mosberger /*
9652d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
9662d53139fSDavid Mosberger  */
9672d53139fSDavid Mosberger static int
9682d53139fSDavid Mosberger max3421_transfer_in_done(struct usb_hcd *hcd, struct urb *urb)
9692d53139fSDavid Mosberger {
9702d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
9712d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
9722d53139fSDavid Mosberger 	u32 max_packet;
9732d53139fSDavid Mosberger 
9742d53139fSDavid Mosberger 	if (urb->actual_length >= urb->transfer_buffer_length)
9752d53139fSDavid Mosberger 		return 1;	/* read is complete, so we're done */
9762d53139fSDavid Mosberger 
9772d53139fSDavid Mosberger 	/*
9782d53139fSDavid Mosberger 	 * USB 2.0 Section 5.3.2 Pipes: packets must be full size
9792d53139fSDavid Mosberger 	 * except for last one.
9802d53139fSDavid Mosberger 	 */
9812d53139fSDavid Mosberger 	max_packet = usb_maxpacket(urb->dev, urb->pipe, 0);
9822d53139fSDavid Mosberger 	if (max_packet > MAX3421_FIFO_SIZE) {
9832d53139fSDavid Mosberger 		/*
9842d53139fSDavid Mosberger 		 * We do not support isochronous transfers at this
9852d53139fSDavid Mosberger 		 * time...
9862d53139fSDavid Mosberger 		 */
9872d53139fSDavid Mosberger 		dev_err(&spi->dev,
9882d53139fSDavid Mosberger 			"%s: packet-size of %u too big (limit is %u bytes)",
9892d53139fSDavid Mosberger 			__func__, max_packet, MAX3421_FIFO_SIZE);
9902d53139fSDavid Mosberger 		return -EINVAL;
9912d53139fSDavid Mosberger 	}
9922d53139fSDavid Mosberger 
9932d53139fSDavid Mosberger 	if (max3421_hcd->curr_len < max_packet) {
9942d53139fSDavid Mosberger 		if (urb->transfer_flags & URB_SHORT_NOT_OK) {
9952d53139fSDavid Mosberger 			/*
9962d53139fSDavid Mosberger 			 * remaining > 0 and received an
9972d53139fSDavid Mosberger 			 * unexpected partial packet ->
9982d53139fSDavid Mosberger 			 * error
9992d53139fSDavid Mosberger 			 */
10002d53139fSDavid Mosberger 			return -EREMOTEIO;
10012d53139fSDavid Mosberger 		} else
10022d53139fSDavid Mosberger 			/* short read, but it's OK */
10032d53139fSDavid Mosberger 			return 1;
10042d53139fSDavid Mosberger 	}
10052d53139fSDavid Mosberger 	return 0;	/* not done */
10062d53139fSDavid Mosberger }
10072d53139fSDavid Mosberger 
10082d53139fSDavid Mosberger /*
10092d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
10102d53139fSDavid Mosberger  */
10112d53139fSDavid Mosberger static int
10122d53139fSDavid Mosberger max3421_transfer_out_done(struct usb_hcd *hcd, struct urb *urb)
10132d53139fSDavid Mosberger {
10142d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
10152d53139fSDavid Mosberger 
10162d53139fSDavid Mosberger 	urb->actual_length += max3421_hcd->curr_len;
10172d53139fSDavid Mosberger 	if (urb->actual_length < urb->transfer_buffer_length)
10182d53139fSDavid Mosberger 		return 0;
10192d53139fSDavid Mosberger 	if (urb->transfer_flags & URB_ZERO_PACKET) {
10202d53139fSDavid Mosberger 		/*
10212d53139fSDavid Mosberger 		 * Some hardware needs a zero-size packet at the end
10222d53139fSDavid Mosberger 		 * of a bulk-out transfer if the last transfer was a
10232d53139fSDavid Mosberger 		 * full-sized packet (i.e., such hardware use <
10242d53139fSDavid Mosberger 		 * max_packet as an indicator that the end of the
10252d53139fSDavid Mosberger 		 * packet has been reached).
10262d53139fSDavid Mosberger 		 */
10272d53139fSDavid Mosberger 		u32 max_packet = usb_maxpacket(urb->dev, urb->pipe, 1);
10282d53139fSDavid Mosberger 
10292d53139fSDavid Mosberger 		if (max3421_hcd->curr_len == max_packet)
10302d53139fSDavid Mosberger 			return 0;
10312d53139fSDavid Mosberger 	}
10322d53139fSDavid Mosberger 	return 1;
10332d53139fSDavid Mosberger }
10342d53139fSDavid Mosberger 
10352d53139fSDavid Mosberger /*
10362d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
10372d53139fSDavid Mosberger  */
10382d53139fSDavid Mosberger static void
10392d53139fSDavid Mosberger max3421_host_transfer_done(struct usb_hcd *hcd)
10402d53139fSDavid Mosberger {
10412d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
10422d53139fSDavid Mosberger 	struct urb *urb = max3421_hcd->curr_urb;
10432d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
10442d53139fSDavid Mosberger 	u8 result_code, hrsl;
10452d53139fSDavid Mosberger 	int urb_done = 0;
10462d53139fSDavid Mosberger 
10472d53139fSDavid Mosberger 	max3421_hcd->hien &= ~(BIT(MAX3421_HI_HXFRDN_BIT) |
10482d53139fSDavid Mosberger 			       BIT(MAX3421_HI_RCVDAV_BIT));
10492d53139fSDavid Mosberger 
10502d53139fSDavid Mosberger 	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);
10512d53139fSDavid Mosberger 	result_code = hrsl & MAX3421_HRSL_RESULT_MASK;
10522d53139fSDavid Mosberger 
10532d53139fSDavid Mosberger #ifdef DEBUG
10542d53139fSDavid Mosberger 	++max3421_hcd->err_stat[result_code];
10552d53139fSDavid Mosberger #endif
10562d53139fSDavid Mosberger 
10572d53139fSDavid Mosberger 	max3421_ep = urb->ep->hcpriv;
10582d53139fSDavid Mosberger 
10592d53139fSDavid Mosberger 	if (unlikely(result_code != MAX3421_HRSL_OK)) {
10602d53139fSDavid Mosberger 		max3421_handle_error(hcd, hrsl);
10612d53139fSDavid Mosberger 		return;
10622d53139fSDavid Mosberger 	}
10632d53139fSDavid Mosberger 
10642d53139fSDavid Mosberger 	max3421_ep->naks = 0;
10652d53139fSDavid Mosberger 	max3421_ep->retries = 0;
10662d53139fSDavid Mosberger 	switch (max3421_ep->pkt_state) {
10672d53139fSDavid Mosberger 
10682d53139fSDavid Mosberger 	case PKT_STATE_SETUP:
10692d53139fSDavid Mosberger 		if (urb->transfer_buffer_length > 0)
10702d53139fSDavid Mosberger 			max3421_ep->pkt_state = PKT_STATE_TRANSFER;
10712d53139fSDavid Mosberger 		else
10722d53139fSDavid Mosberger 			max3421_ep->pkt_state = PKT_STATE_TERMINATE;
10732d53139fSDavid Mosberger 		break;
10742d53139fSDavid Mosberger 
10752d53139fSDavid Mosberger 	case PKT_STATE_TRANSFER:
10762d53139fSDavid Mosberger 		if (usb_urb_dir_in(urb))
10772d53139fSDavid Mosberger 			urb_done = max3421_transfer_in_done(hcd, urb);
10782d53139fSDavid Mosberger 		else
10792d53139fSDavid Mosberger 			urb_done = max3421_transfer_out_done(hcd, urb);
10802d53139fSDavid Mosberger 		if (urb_done > 0 && usb_pipetype(urb->pipe) == PIPE_CONTROL) {
10812d53139fSDavid Mosberger 			/*
10822d53139fSDavid Mosberger 			 * We aren't really done - we still need to
10832d53139fSDavid Mosberger 			 * terminate the control transfer:
10842d53139fSDavid Mosberger 			 */
10852d53139fSDavid Mosberger 			max3421_hcd->urb_done = urb_done = 0;
10862d53139fSDavid Mosberger 			max3421_ep->pkt_state = PKT_STATE_TERMINATE;
10872d53139fSDavid Mosberger 		}
10882d53139fSDavid Mosberger 		break;
10892d53139fSDavid Mosberger 
10902d53139fSDavid Mosberger 	case PKT_STATE_TERMINATE:
10912d53139fSDavid Mosberger 		urb_done = 1;
10922d53139fSDavid Mosberger 		break;
10932d53139fSDavid Mosberger 	}
10942d53139fSDavid Mosberger 
10952d53139fSDavid Mosberger 	if (urb_done)
10962d53139fSDavid Mosberger 		max3421_hcd->urb_done = urb_done;
10972d53139fSDavid Mosberger 	else
10982d53139fSDavid Mosberger 		max3421_next_transfer(hcd, 0);
10992d53139fSDavid Mosberger }
11002d53139fSDavid Mosberger 
11012d53139fSDavid Mosberger /*
11022d53139fSDavid Mosberger  * Caller must NOT hold HCD spinlock.
11032d53139fSDavid Mosberger  */
11042d53139fSDavid Mosberger static void
11052d53139fSDavid Mosberger max3421_detect_conn(struct usb_hcd *hcd)
11062d53139fSDavid Mosberger {
11072d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
11082d53139fSDavid Mosberger 	unsigned int jk, have_conn = 0;
11092d53139fSDavid Mosberger 	u32 old_port_status, chg;
11102d53139fSDavid Mosberger 	unsigned long flags;
11112d53139fSDavid Mosberger 	u8 hrsl, mode;
11122d53139fSDavid Mosberger 
11132d53139fSDavid Mosberger 	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);
11142d53139fSDavid Mosberger 
11152d53139fSDavid Mosberger 	jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) |
11162d53139fSDavid Mosberger 	      (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1));
11172d53139fSDavid Mosberger 
11182d53139fSDavid Mosberger 	mode = max3421_hcd->mode;
11192d53139fSDavid Mosberger 
11202d53139fSDavid Mosberger 	switch (jk) {
11212d53139fSDavid Mosberger 	case 0x0: /* SE0: disconnect */
11222d53139fSDavid Mosberger 		/*
11232d53139fSDavid Mosberger 		 * Turn off SOFKAENAB bit to avoid getting interrupt
11242d53139fSDavid Mosberger 		 * every milli-second:
11252d53139fSDavid Mosberger 		 */
11262d53139fSDavid Mosberger 		mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT);
11272d53139fSDavid Mosberger 		break;
11282d53139fSDavid Mosberger 
11292d53139fSDavid Mosberger 	case 0x1: /* J=0,K=1: low-speed (in full-speed or vice versa) */
11302d53139fSDavid Mosberger 	case 0x2: /* J=1,K=0: full-speed (in full-speed or vice versa) */
11312d53139fSDavid Mosberger 		if (jk == 0x2)
11322d53139fSDavid Mosberger 			/* need to switch to the other speed: */
11332d53139fSDavid Mosberger 			mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT);
11342d53139fSDavid Mosberger 		/* turn on SOFKAENAB bit: */
11352d53139fSDavid Mosberger 		mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT);
11362d53139fSDavid Mosberger 		have_conn = 1;
11372d53139fSDavid Mosberger 		break;
11382d53139fSDavid Mosberger 
11392d53139fSDavid Mosberger 	case 0x3: /* illegal */
11402d53139fSDavid Mosberger 		break;
11412d53139fSDavid Mosberger 	}
11422d53139fSDavid Mosberger 
11432d53139fSDavid Mosberger 	max3421_hcd->mode = mode;
11442d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode);
11452d53139fSDavid Mosberger 
11462d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
11472d53139fSDavid Mosberger 	old_port_status = max3421_hcd->port_status;
11482d53139fSDavid Mosberger 	if (have_conn)
11492d53139fSDavid Mosberger 		max3421_hcd->port_status |=  USB_PORT_STAT_CONNECTION;
11502d53139fSDavid Mosberger 	else
11512d53139fSDavid Mosberger 		max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION;
11522d53139fSDavid Mosberger 	if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT))
11532d53139fSDavid Mosberger 		max3421_hcd->port_status |=  USB_PORT_STAT_LOW_SPEED;
11542d53139fSDavid Mosberger 	else
11552d53139fSDavid Mosberger 		max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED;
11562d53139fSDavid Mosberger 	chg = (old_port_status ^ max3421_hcd->port_status);
11572d53139fSDavid Mosberger 	max3421_hcd->port_status |= chg << 16;
11582d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
11592d53139fSDavid Mosberger }
11602d53139fSDavid Mosberger 
11612d53139fSDavid Mosberger static irqreturn_t
11622d53139fSDavid Mosberger max3421_irq_handler(int irq, void *dev_id)
11632d53139fSDavid Mosberger {
11642d53139fSDavid Mosberger 	struct usb_hcd *hcd = dev_id;
11652d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
11662d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
11672d53139fSDavid Mosberger 
11682d53139fSDavid Mosberger 	if (max3421_hcd->spi_thread &&
11692d53139fSDavid Mosberger 	    max3421_hcd->spi_thread->state != TASK_RUNNING)
11702d53139fSDavid Mosberger 		wake_up_process(max3421_hcd->spi_thread);
11712eb5dbddSDavid Mosberger-Tang 	if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo))
11722d53139fSDavid Mosberger 		disable_irq_nosync(spi->irq);
11732d53139fSDavid Mosberger 	return IRQ_HANDLED;
11742d53139fSDavid Mosberger }
11752d53139fSDavid Mosberger 
11762d53139fSDavid Mosberger #ifdef DEBUG
11772d53139fSDavid Mosberger 
11782d53139fSDavid Mosberger static void
11792d53139fSDavid Mosberger dump_eps(struct usb_hcd *hcd)
11802d53139fSDavid Mosberger {
11812d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
11822d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
11832d53139fSDavid Mosberger 	struct usb_host_endpoint *ep;
11842d53139fSDavid Mosberger 	char ubuf[512], *dp, *end;
11852d53139fSDavid Mosberger 	unsigned long flags;
11862d53139fSDavid Mosberger 	struct urb *urb;
11872d53139fSDavid Mosberger 	int epnum, ret;
11882d53139fSDavid Mosberger 
11892d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
1190553c2360SGeliang Tang 	list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) {
11912d53139fSDavid Mosberger 		ep = max3421_ep->ep;
11922d53139fSDavid Mosberger 
11932d53139fSDavid Mosberger 		dp = ubuf;
11942d53139fSDavid Mosberger 		end = dp + sizeof(ubuf);
11952d53139fSDavid Mosberger 		*dp = '\0';
1196553c2360SGeliang Tang 		list_for_each_entry(urb, &ep->urb_list, urb_list) {
11972d53139fSDavid Mosberger 			ret = snprintf(dp, end - dp, " %p(%d.%s %d/%d)", urb,
11982d53139fSDavid Mosberger 				       usb_pipetype(urb->pipe),
11992d53139fSDavid Mosberger 				       usb_urb_dir_in(urb) ? "IN" : "OUT",
12002d53139fSDavid Mosberger 				       urb->actual_length,
12012d53139fSDavid Mosberger 				       urb->transfer_buffer_length);
12022d53139fSDavid Mosberger 			if (ret < 0 || ret >= end - dp)
12032d53139fSDavid Mosberger 				break;	/* error or buffer full */
12042d53139fSDavid Mosberger 			dp += ret;
12052d53139fSDavid Mosberger 		}
12062d53139fSDavid Mosberger 
12072d53139fSDavid Mosberger 		epnum = usb_endpoint_num(&ep->desc);
12082d53139fSDavid Mosberger 		pr_info("EP%0u %u lst %04u rtr %u nak %6u rxmt %u: %s\n",
12092d53139fSDavid Mosberger 			epnum, max3421_ep->pkt_state, max3421_ep->last_active,
12102d53139fSDavid Mosberger 			max3421_ep->retries, max3421_ep->naks,
12112d53139fSDavid Mosberger 			max3421_ep->retransmit, ubuf);
12122d53139fSDavid Mosberger 	}
12132d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
12142d53139fSDavid Mosberger }
12152d53139fSDavid Mosberger 
12162d53139fSDavid Mosberger #endif /* DEBUG */
12172d53139fSDavid Mosberger 
12182d53139fSDavid Mosberger /* Return zero if no work was performed, 1 otherwise.  */
12192d53139fSDavid Mosberger static int
12202d53139fSDavid Mosberger max3421_handle_irqs(struct usb_hcd *hcd)
12212d53139fSDavid Mosberger {
12222d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
12232d53139fSDavid Mosberger 	u32 chg, old_port_status;
12242d53139fSDavid Mosberger 	unsigned long flags;
12252d53139fSDavid Mosberger 	u8 hirq;
12262d53139fSDavid Mosberger 
12272d53139fSDavid Mosberger 	/*
12282d53139fSDavid Mosberger 	 * Read and ack pending interrupts (CPU must never
12292d53139fSDavid Mosberger 	 * clear SNDBAV directly and RCVDAV must be cleared by
12302d53139fSDavid Mosberger 	 * max3421_recv_data_available()!):
12312d53139fSDavid Mosberger 	 */
12322d53139fSDavid Mosberger 	hirq = spi_rd8(hcd, MAX3421_REG_HIRQ);
12332d53139fSDavid Mosberger 	hirq &= max3421_hcd->hien;
12342d53139fSDavid Mosberger 	if (!hirq)
12352d53139fSDavid Mosberger 		return 0;
12362d53139fSDavid Mosberger 
12372d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HIRQ,
12382d53139fSDavid Mosberger 		hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) |
12392d53139fSDavid Mosberger 			 BIT(MAX3421_HI_RCVDAV_BIT)));
12402d53139fSDavid Mosberger 
12412d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_FRAME_BIT)) {
12422d53139fSDavid Mosberger 		max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1)
12432d53139fSDavid Mosberger 					     & USB_MAX_FRAME_NUMBER);
12442d53139fSDavid Mosberger 		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC;
12452d53139fSDavid Mosberger 	}
12462d53139fSDavid Mosberger 
12472d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_RCVDAV_BIT))
12482d53139fSDavid Mosberger 		max3421_recv_data_available(hcd);
12492d53139fSDavid Mosberger 
12502d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_HXFRDN_BIT))
12512d53139fSDavid Mosberger 		max3421_host_transfer_done(hcd);
12522d53139fSDavid Mosberger 
12532d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_CONDET_BIT))
12542d53139fSDavid Mosberger 		max3421_detect_conn(hcd);
12552d53139fSDavid Mosberger 
12562d53139fSDavid Mosberger 	/*
12572d53139fSDavid Mosberger 	 * Now process interrupts that may affect HCD state
12582d53139fSDavid Mosberger 	 * other than the end-points:
12592d53139fSDavid Mosberger 	 */
12602d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
12612d53139fSDavid Mosberger 
12622d53139fSDavid Mosberger 	old_port_status = max3421_hcd->port_status;
12632d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) {
12642d53139fSDavid Mosberger 		if (max3421_hcd->port_status & USB_PORT_STAT_RESET) {
12652d53139fSDavid Mosberger 			/* BUSEVENT due to completion of Bus Reset */
12662d53139fSDavid Mosberger 			max3421_hcd->port_status &= ~USB_PORT_STAT_RESET;
12672d53139fSDavid Mosberger 			max3421_hcd->port_status |=  USB_PORT_STAT_ENABLE;
12682d53139fSDavid Mosberger 		} else {
12692d53139fSDavid Mosberger 			/* BUSEVENT due to completion of Bus Resume */
12702d53139fSDavid Mosberger 			pr_info("%s: BUSEVENT Bus Resume Done\n", __func__);
12712d53139fSDavid Mosberger 		}
12722d53139fSDavid Mosberger 	}
12732d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_RWU_BIT))
12742d53139fSDavid Mosberger 		pr_info("%s: RWU\n", __func__);
12752d53139fSDavid Mosberger 	if (hirq & BIT(MAX3421_HI_SUSDN_BIT))
12762d53139fSDavid Mosberger 		pr_info("%s: SUSDN\n", __func__);
12772d53139fSDavid Mosberger 
12782d53139fSDavid Mosberger 	chg = (old_port_status ^ max3421_hcd->port_status);
12792d53139fSDavid Mosberger 	max3421_hcd->port_status |= chg << 16;
12802d53139fSDavid Mosberger 
12812d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
12822d53139fSDavid Mosberger 
12832d53139fSDavid Mosberger #ifdef DEBUG
12842d53139fSDavid Mosberger 	{
12852d53139fSDavid Mosberger 		static unsigned long last_time;
12862d53139fSDavid Mosberger 		char sbuf[16 * 16], *dp, *end;
12872d53139fSDavid Mosberger 		int i;
12882d53139fSDavid Mosberger 
1289788bfe88SAsaf Vertz 		if (time_after(jiffies, last_time + 5*HZ)) {
12902d53139fSDavid Mosberger 			dp = sbuf;
12912d53139fSDavid Mosberger 			end = sbuf + sizeof(sbuf);
12922d53139fSDavid Mosberger 			*dp = '\0';
12932d53139fSDavid Mosberger 			for (i = 0; i < 16; ++i) {
12942d53139fSDavid Mosberger 				int ret = snprintf(dp, end - dp, " %lu",
12952d53139fSDavid Mosberger 						   max3421_hcd->err_stat[i]);
12962d53139fSDavid Mosberger 				if (ret < 0 || ret >= end - dp)
12972d53139fSDavid Mosberger 					break;	/* error or buffer full */
12982d53139fSDavid Mosberger 				dp += ret;
12992d53139fSDavid Mosberger 			}
13002d53139fSDavid Mosberger 			pr_info("%s: hrsl_stats %s\n", __func__, sbuf);
13012d53139fSDavid Mosberger 			memset(max3421_hcd->err_stat, 0,
13022d53139fSDavid Mosberger 			       sizeof(max3421_hcd->err_stat));
13032d53139fSDavid Mosberger 			last_time = jiffies;
13042d53139fSDavid Mosberger 
13052d53139fSDavid Mosberger 			dump_eps(hcd);
13062d53139fSDavid Mosberger 		}
13072d53139fSDavid Mosberger 	}
13082d53139fSDavid Mosberger #endif
13092d53139fSDavid Mosberger 	return 1;
13102d53139fSDavid Mosberger }
13112d53139fSDavid Mosberger 
13122d53139fSDavid Mosberger static int
13132d53139fSDavid Mosberger max3421_reset_hcd(struct usb_hcd *hcd)
13142d53139fSDavid Mosberger {
13152d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
13162d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
13172d53139fSDavid Mosberger 	int timeout;
13182d53139fSDavid Mosberger 
13192d53139fSDavid Mosberger 	/* perform a chip reset and wait for OSCIRQ signal to appear: */
13202d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_USBCTL, BIT(MAX3421_USBCTL_CHIPRES_BIT));
13212d53139fSDavid Mosberger 	/* clear reset: */
13222d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_USBCTL, 0);
13232d53139fSDavid Mosberger 	timeout = 1000;
13242d53139fSDavid Mosberger 	while (1) {
13252d53139fSDavid Mosberger 		if (spi_rd8(hcd, MAX3421_REG_USBIRQ)
13262d53139fSDavid Mosberger 		    & BIT(MAX3421_USBIRQ_OSCOKIRQ_BIT))
13272d53139fSDavid Mosberger 			break;
13282d53139fSDavid Mosberger 		if (--timeout < 0) {
13292d53139fSDavid Mosberger 			dev_err(&spi->dev,
13302d53139fSDavid Mosberger 				"timed out waiting for oscillator OK signal");
13312d53139fSDavid Mosberger 			return 1;
13322d53139fSDavid Mosberger 		}
13332d53139fSDavid Mosberger 		cond_resched();
13342d53139fSDavid Mosberger 	}
13352d53139fSDavid Mosberger 
13362d53139fSDavid Mosberger 	/*
13372d53139fSDavid Mosberger 	 * Turn on host mode, automatic generation of SOF packets, and
13382d53139fSDavid Mosberger 	 * enable pull-down registers on DM/DP:
13392d53139fSDavid Mosberger 	 */
13402d53139fSDavid Mosberger 	max3421_hcd->mode = (BIT(MAX3421_MODE_HOST_BIT) |
13412d53139fSDavid Mosberger 			     BIT(MAX3421_MODE_SOFKAENAB_BIT) |
13422d53139fSDavid Mosberger 			     BIT(MAX3421_MODE_DMPULLDN_BIT) |
13432d53139fSDavid Mosberger 			     BIT(MAX3421_MODE_DPPULLDN_BIT));
13442d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode);
13452d53139fSDavid Mosberger 
13462d53139fSDavid Mosberger 	/* reset frame-number: */
13472d53139fSDavid Mosberger 	max3421_hcd->frame_number = USB_MAX_FRAME_NUMBER;
13482d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_FRMRST_BIT));
13492d53139fSDavid Mosberger 
13502d53139fSDavid Mosberger 	/* sample the state of the D+ and D- lines */
13512d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_SAMPLEBUS_BIT));
13522d53139fSDavid Mosberger 	max3421_detect_conn(hcd);
13532d53139fSDavid Mosberger 
13542d53139fSDavid Mosberger 	/* enable frame, connection-detected, and bus-event interrupts: */
13552d53139fSDavid Mosberger 	max3421_hcd->hien = (BIT(MAX3421_HI_FRAME_BIT) |
13562d53139fSDavid Mosberger 			     BIT(MAX3421_HI_CONDET_BIT) |
13572d53139fSDavid Mosberger 			     BIT(MAX3421_HI_BUSEVENT_BIT));
13582d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien);
13592d53139fSDavid Mosberger 
13602d53139fSDavid Mosberger 	/* enable interrupts: */
13612d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_CPUCTL, BIT(MAX3421_CPUCTL_IE_BIT));
13622d53139fSDavid Mosberger 	return 1;
13632d53139fSDavid Mosberger }
13642d53139fSDavid Mosberger 
13652d53139fSDavid Mosberger static int
13662d53139fSDavid Mosberger max3421_urb_done(struct usb_hcd *hcd)
13672d53139fSDavid Mosberger {
13682d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
13692d53139fSDavid Mosberger 	unsigned long flags;
13702d53139fSDavid Mosberger 	struct urb *urb;
13712d53139fSDavid Mosberger 	int status;
13722d53139fSDavid Mosberger 
13732d53139fSDavid Mosberger 	status = max3421_hcd->urb_done;
13742d53139fSDavid Mosberger 	max3421_hcd->urb_done = 0;
13752d53139fSDavid Mosberger 	if (status > 0)
13762d53139fSDavid Mosberger 		status = 0;
13772d53139fSDavid Mosberger 	urb = max3421_hcd->curr_urb;
13782d53139fSDavid Mosberger 	if (urb) {
13792d53139fSDavid Mosberger 		max3421_hcd->curr_urb = NULL;
13802d53139fSDavid Mosberger 		spin_lock_irqsave(&max3421_hcd->lock, flags);
13812d53139fSDavid Mosberger 		usb_hcd_unlink_urb_from_ep(hcd, urb);
13822d53139fSDavid Mosberger 		spin_unlock_irqrestore(&max3421_hcd->lock, flags);
13832d53139fSDavid Mosberger 
13842d53139fSDavid Mosberger 		/* must be called without the HCD spinlock: */
13852d53139fSDavid Mosberger 		usb_hcd_giveback_urb(hcd, urb, status);
13862d53139fSDavid Mosberger 	}
13872d53139fSDavid Mosberger 	return 1;
13882d53139fSDavid Mosberger }
13892d53139fSDavid Mosberger 
13902d53139fSDavid Mosberger static int
13912d53139fSDavid Mosberger max3421_spi_thread(void *dev_id)
13922d53139fSDavid Mosberger {
13932d53139fSDavid Mosberger 	struct usb_hcd *hcd = dev_id;
13942d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
13952d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
13962d53139fSDavid Mosberger 	int i, i_worked = 1;
13972d53139fSDavid Mosberger 
13982d53139fSDavid Mosberger 	/* set full-duplex SPI mode, low-active interrupt pin: */
13992d53139fSDavid Mosberger 	spi_wr8(hcd, MAX3421_REG_PINCTL,
14002d53139fSDavid Mosberger 		(BIT(MAX3421_PINCTL_FDUPSPI_BIT) |	/* full-duplex */
14012d53139fSDavid Mosberger 		 BIT(MAX3421_PINCTL_INTLEVEL_BIT)));	/* low-active irq */
14022d53139fSDavid Mosberger 
14032d53139fSDavid Mosberger 	while (!kthread_should_stop()) {
14042d53139fSDavid Mosberger 		max3421_hcd->rev = spi_rd8(hcd, MAX3421_REG_REVISION);
14052d53139fSDavid Mosberger 		if (max3421_hcd->rev == 0x12 || max3421_hcd->rev == 0x13)
14062d53139fSDavid Mosberger 			break;
14072d53139fSDavid Mosberger 		dev_err(&spi->dev, "bad rev 0x%02x", max3421_hcd->rev);
14082d53139fSDavid Mosberger 		msleep(10000);
14092d53139fSDavid Mosberger 	}
14102d53139fSDavid Mosberger 	dev_info(&spi->dev, "rev 0x%x, SPI clk %dHz, bpw %u, irq %d\n",
14112d53139fSDavid Mosberger 		 max3421_hcd->rev, spi->max_speed_hz, spi->bits_per_word,
14122d53139fSDavid Mosberger 		 spi->irq);
14132d53139fSDavid Mosberger 
14142d53139fSDavid Mosberger 	while (!kthread_should_stop()) {
14152d53139fSDavid Mosberger 		if (!i_worked) {
14162d53139fSDavid Mosberger 			/*
14172d53139fSDavid Mosberger 			 * We'll be waiting for wakeups from the hard
14182d53139fSDavid Mosberger 			 * interrupt handler, so now is a good time to
14192d53139fSDavid Mosberger 			 * sync our hien with the chip:
14202d53139fSDavid Mosberger 			 */
14212d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien);
14222d53139fSDavid Mosberger 
14232d53139fSDavid Mosberger 			set_current_state(TASK_INTERRUPTIBLE);
14242eb5dbddSDavid Mosberger-Tang 			if (test_and_clear_bit(ENABLE_IRQ, &max3421_hcd->todo))
14252d53139fSDavid Mosberger 				enable_irq(spi->irq);
14262d53139fSDavid Mosberger 			schedule();
14272d53139fSDavid Mosberger 			__set_current_state(TASK_RUNNING);
14282d53139fSDavid Mosberger 		}
14292d53139fSDavid Mosberger 
14302d53139fSDavid Mosberger 		i_worked = 0;
14312d53139fSDavid Mosberger 
14322d53139fSDavid Mosberger 		if (max3421_hcd->urb_done)
14332d53139fSDavid Mosberger 			i_worked |= max3421_urb_done(hcd);
14342d53139fSDavid Mosberger 		else if (max3421_handle_irqs(hcd))
14352d53139fSDavid Mosberger 			i_worked = 1;
14362d53139fSDavid Mosberger 		else if (!max3421_hcd->curr_urb)
14372d53139fSDavid Mosberger 			i_worked |= max3421_select_and_start_urb(hcd);
14382d53139fSDavid Mosberger 
14392eb5dbddSDavid Mosberger-Tang 		if (test_and_clear_bit(RESET_HCD, &max3421_hcd->todo))
14402d53139fSDavid Mosberger 			/* reset the HCD: */
14412d53139fSDavid Mosberger 			i_worked |= max3421_reset_hcd(hcd);
14422eb5dbddSDavid Mosberger-Tang 		if (test_and_clear_bit(RESET_PORT, &max3421_hcd->todo)) {
14432d53139fSDavid Mosberger 			/* perform a USB bus reset: */
14442d53139fSDavid Mosberger 			spi_wr8(hcd, MAX3421_REG_HCTL,
14452d53139fSDavid Mosberger 				BIT(MAX3421_HCTL_BUSRST_BIT));
14462d53139fSDavid Mosberger 			i_worked = 1;
14472d53139fSDavid Mosberger 		}
14482eb5dbddSDavid Mosberger-Tang 		if (test_and_clear_bit(CHECK_UNLINK, &max3421_hcd->todo))
14492d53139fSDavid Mosberger 			i_worked |= max3421_check_unlink(hcd);
14502eb5dbddSDavid Mosberger-Tang 		if (test_and_clear_bit(IOPIN_UPDATE, &max3421_hcd->todo)) {
14512d53139fSDavid Mosberger 			/*
14522d53139fSDavid Mosberger 			 * IOPINS1/IOPINS2 do not auto-increment, so we can't
14532d53139fSDavid Mosberger 			 * use spi_wr_buf().
14542d53139fSDavid Mosberger 			 */
14552d53139fSDavid Mosberger 			for (i = 0; i < ARRAY_SIZE(max3421_hcd->iopins); ++i) {
14562d53139fSDavid Mosberger 				u8 val = spi_rd8(hcd, MAX3421_REG_IOPINS1);
14572d53139fSDavid Mosberger 
14582d53139fSDavid Mosberger 				val = ((val & 0xf0) |
14592d53139fSDavid Mosberger 				       (max3421_hcd->iopins[i] & 0x0f));
14602d53139fSDavid Mosberger 				spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val);
14612d53139fSDavid Mosberger 				max3421_hcd->iopins[i] = val;
14622d53139fSDavid Mosberger 			}
14632d53139fSDavid Mosberger 			i_worked = 1;
14642d53139fSDavid Mosberger 		}
14652d53139fSDavid Mosberger 	}
14662d53139fSDavid Mosberger 	set_current_state(TASK_RUNNING);
14672d53139fSDavid Mosberger 	dev_info(&spi->dev, "SPI thread exiting");
14682d53139fSDavid Mosberger 	return 0;
14692d53139fSDavid Mosberger }
14702d53139fSDavid Mosberger 
14712d53139fSDavid Mosberger static int
14722d53139fSDavid Mosberger max3421_reset_port(struct usb_hcd *hcd)
14732d53139fSDavid Mosberger {
14742d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
14752d53139fSDavid Mosberger 
14762d53139fSDavid Mosberger 	max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE |
14772d53139fSDavid Mosberger 				      USB_PORT_STAT_LOW_SPEED);
1478a2b63cb5SDavid Mosberger-Tang 	max3421_hcd->port_status |= USB_PORT_STAT_RESET;
14792eb5dbddSDavid Mosberger-Tang 	set_bit(RESET_PORT, &max3421_hcd->todo);
14802d53139fSDavid Mosberger 	wake_up_process(max3421_hcd->spi_thread);
14812d53139fSDavid Mosberger 	return 0;
14822d53139fSDavid Mosberger }
14832d53139fSDavid Mosberger 
14842d53139fSDavid Mosberger static int
14852d53139fSDavid Mosberger max3421_reset(struct usb_hcd *hcd)
14862d53139fSDavid Mosberger {
14872d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
14882d53139fSDavid Mosberger 
14892d53139fSDavid Mosberger 	hcd->self.sg_tablesize = 0;
14902d53139fSDavid Mosberger 	hcd->speed = HCD_USB2;
14912d53139fSDavid Mosberger 	hcd->self.root_hub->speed = USB_SPEED_FULL;
14922eb5dbddSDavid Mosberger-Tang 	set_bit(RESET_HCD, &max3421_hcd->todo);
14932d53139fSDavid Mosberger 	wake_up_process(max3421_hcd->spi_thread);
14942d53139fSDavid Mosberger 	return 0;
14952d53139fSDavid Mosberger }
14962d53139fSDavid Mosberger 
14972d53139fSDavid Mosberger static int
14982d53139fSDavid Mosberger max3421_start(struct usb_hcd *hcd)
14992d53139fSDavid Mosberger {
15002d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
15012d53139fSDavid Mosberger 
15022d53139fSDavid Mosberger 	spin_lock_init(&max3421_hcd->lock);
15032d53139fSDavid Mosberger 	max3421_hcd->rh_state = MAX3421_RH_RUNNING;
15042d53139fSDavid Mosberger 
15052d53139fSDavid Mosberger 	INIT_LIST_HEAD(&max3421_hcd->ep_list);
15062d53139fSDavid Mosberger 
15072d53139fSDavid Mosberger 	hcd->power_budget = POWER_BUDGET;
15082d53139fSDavid Mosberger 	hcd->state = HC_STATE_RUNNING;
15092d53139fSDavid Mosberger 	hcd->uses_new_polling = 1;
15102d53139fSDavid Mosberger 	return 0;
15112d53139fSDavid Mosberger }
15122d53139fSDavid Mosberger 
15132d53139fSDavid Mosberger static void
15142d53139fSDavid Mosberger max3421_stop(struct usb_hcd *hcd)
15152d53139fSDavid Mosberger {
15162d53139fSDavid Mosberger }
15172d53139fSDavid Mosberger 
15182d53139fSDavid Mosberger static int
15192d53139fSDavid Mosberger max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
15202d53139fSDavid Mosberger {
15212d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
15222d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
15232d53139fSDavid Mosberger 	struct max3421_ep *max3421_ep;
15242d53139fSDavid Mosberger 	unsigned long flags;
15252d53139fSDavid Mosberger 	int retval;
15262d53139fSDavid Mosberger 
15272d53139fSDavid Mosberger 	switch (usb_pipetype(urb->pipe)) {
15282d53139fSDavid Mosberger 	case PIPE_INTERRUPT:
15292d53139fSDavid Mosberger 	case PIPE_ISOCHRONOUS:
15302d53139fSDavid Mosberger 		if (urb->interval < 0) {
15312d53139fSDavid Mosberger 			dev_err(&spi->dev,
15322d53139fSDavid Mosberger 			  "%s: interval=%d for intr-/iso-pipe; expected > 0\n",
15332d53139fSDavid Mosberger 				__func__, urb->interval);
15342d53139fSDavid Mosberger 			return -EINVAL;
15352d53139fSDavid Mosberger 		}
15362d53139fSDavid Mosberger 	default:
15372d53139fSDavid Mosberger 		break;
15382d53139fSDavid Mosberger 	}
15392d53139fSDavid Mosberger 
15402d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
15412d53139fSDavid Mosberger 
15422d53139fSDavid Mosberger 	max3421_ep = urb->ep->hcpriv;
15432d53139fSDavid Mosberger 	if (!max3421_ep) {
15442d53139fSDavid Mosberger 		/* gets freed in max3421_endpoint_disable: */
15456c0f3695SAlexey Khoroshilov 		max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC);
154600c5aa17SDavid Mosberger-Tang 		if (!max3421_ep) {
154700c5aa17SDavid Mosberger-Tang 			retval = -ENOMEM;
154800c5aa17SDavid Mosberger-Tang 			goto out;
154900c5aa17SDavid Mosberger-Tang 		}
15502d53139fSDavid Mosberger 		max3421_ep->ep = urb->ep;
15512d53139fSDavid Mosberger 		max3421_ep->last_active = max3421_hcd->frame_number;
15522d53139fSDavid Mosberger 		urb->ep->hcpriv = max3421_ep;
15532d53139fSDavid Mosberger 
15542d53139fSDavid Mosberger 		list_add_tail(&max3421_ep->ep_list, &max3421_hcd->ep_list);
15552d53139fSDavid Mosberger 	}
15562d53139fSDavid Mosberger 
15572d53139fSDavid Mosberger 	retval = usb_hcd_link_urb_to_ep(hcd, urb);
15582d53139fSDavid Mosberger 	if (retval == 0) {
15592d53139fSDavid Mosberger 		/* Since we added to the queue, restart scheduling: */
15602d53139fSDavid Mosberger 		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC;
15612d53139fSDavid Mosberger 		wake_up_process(max3421_hcd->spi_thread);
15622d53139fSDavid Mosberger 	}
15632d53139fSDavid Mosberger 
156400c5aa17SDavid Mosberger-Tang out:
15652d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
15662d53139fSDavid Mosberger 	return retval;
15672d53139fSDavid Mosberger }
15682d53139fSDavid Mosberger 
15692d53139fSDavid Mosberger static int
15702d53139fSDavid Mosberger max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
15712d53139fSDavid Mosberger {
15722d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
15732d53139fSDavid Mosberger 	unsigned long flags;
15742d53139fSDavid Mosberger 	int retval;
15752d53139fSDavid Mosberger 
15762d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
15772d53139fSDavid Mosberger 
15782d53139fSDavid Mosberger 	/*
15792d53139fSDavid Mosberger 	 * This will set urb->unlinked which in turn causes the entry
15802d53139fSDavid Mosberger 	 * to be dropped at the next opportunity.
15812d53139fSDavid Mosberger 	 */
15822d53139fSDavid Mosberger 	retval = usb_hcd_check_unlink_urb(hcd, urb, status);
15832d53139fSDavid Mosberger 	if (retval == 0) {
15842eb5dbddSDavid Mosberger-Tang 		set_bit(CHECK_UNLINK, &max3421_hcd->todo);
15852d53139fSDavid Mosberger 		wake_up_process(max3421_hcd->spi_thread);
15862d53139fSDavid Mosberger 	}
15872d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
15882d53139fSDavid Mosberger 	return retval;
15892d53139fSDavid Mosberger }
15902d53139fSDavid Mosberger 
15912d53139fSDavid Mosberger static void
15922d53139fSDavid Mosberger max3421_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
15932d53139fSDavid Mosberger {
15942d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
15952d53139fSDavid Mosberger 	unsigned long flags;
15962d53139fSDavid Mosberger 
15972d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
15982d53139fSDavid Mosberger 
15992d53139fSDavid Mosberger 	if (ep->hcpriv) {
16002d53139fSDavid Mosberger 		struct max3421_ep *max3421_ep = ep->hcpriv;
16012d53139fSDavid Mosberger 
16022d53139fSDavid Mosberger 		/* remove myself from the ep_list: */
16032d53139fSDavid Mosberger 		if (!list_empty(&max3421_ep->ep_list))
16042d53139fSDavid Mosberger 			list_del(&max3421_ep->ep_list);
16052d53139fSDavid Mosberger 		kfree(max3421_ep);
16062d53139fSDavid Mosberger 		ep->hcpriv = NULL;
16072d53139fSDavid Mosberger 	}
16082d53139fSDavid Mosberger 
16092d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
16102d53139fSDavid Mosberger }
16112d53139fSDavid Mosberger 
16122d53139fSDavid Mosberger static int
16132d53139fSDavid Mosberger max3421_get_frame_number(struct usb_hcd *hcd)
16142d53139fSDavid Mosberger {
16152d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
16162d53139fSDavid Mosberger 	return max3421_hcd->frame_number;
16172d53139fSDavid Mosberger }
16182d53139fSDavid Mosberger 
16192d53139fSDavid Mosberger /*
16202d53139fSDavid Mosberger  * Should return a non-zero value when any port is undergoing a resume
16212d53139fSDavid Mosberger  * transition while the root hub is suspended.
16222d53139fSDavid Mosberger  */
16232d53139fSDavid Mosberger static int
16242d53139fSDavid Mosberger max3421_hub_status_data(struct usb_hcd *hcd, char *buf)
16252d53139fSDavid Mosberger {
16262d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
16272d53139fSDavid Mosberger 	unsigned long flags;
16282d53139fSDavid Mosberger 	int retval = 0;
16292d53139fSDavid Mosberger 
16302d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
16312d53139fSDavid Mosberger 	if (!HCD_HW_ACCESSIBLE(hcd))
16322d53139fSDavid Mosberger 		goto done;
16332d53139fSDavid Mosberger 
16342d53139fSDavid Mosberger 	*buf = 0;
16352d53139fSDavid Mosberger 	if ((max3421_hcd->port_status & PORT_C_MASK) != 0) {
16362d53139fSDavid Mosberger 		*buf = (1 << 1); /* a hub over-current condition exists */
16372d53139fSDavid Mosberger 		dev_dbg(hcd->self.controller,
16382d53139fSDavid Mosberger 			"port status 0x%08x has changes\n",
16392d53139fSDavid Mosberger 			max3421_hcd->port_status);
16402d53139fSDavid Mosberger 		retval = 1;
16412d53139fSDavid Mosberger 		if (max3421_hcd->rh_state == MAX3421_RH_SUSPENDED)
16422d53139fSDavid Mosberger 			usb_hcd_resume_root_hub(hcd);
16432d53139fSDavid Mosberger 	}
16442d53139fSDavid Mosberger done:
16452d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
16462d53139fSDavid Mosberger 	return retval;
16472d53139fSDavid Mosberger }
16482d53139fSDavid Mosberger 
16492d53139fSDavid Mosberger static inline void
16502d53139fSDavid Mosberger hub_descriptor(struct usb_hub_descriptor *desc)
16512d53139fSDavid Mosberger {
16522d53139fSDavid Mosberger 	memset(desc, 0, sizeof(*desc));
16532d53139fSDavid Mosberger 	/*
16542d53139fSDavid Mosberger 	 * See Table 11-13: Hub Descriptor in USB 2.0 spec.
16552d53139fSDavid Mosberger 	 */
1656e3d02e0eSSergei Shtylyov 	desc->bDescriptorType = USB_DT_HUB; /* hub descriptor */
16572d53139fSDavid Mosberger 	desc->bDescLength = 9;
16582e48c466SSergei Shtylyov 	desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM |
16592e48c466SSergei Shtylyov 						HUB_CHAR_COMMON_OCPM);
16602d53139fSDavid Mosberger 	desc->bNbrPorts = 1;
16612d53139fSDavid Mosberger }
16622d53139fSDavid Mosberger 
16632d53139fSDavid Mosberger /*
16642d53139fSDavid Mosberger  * Set the MAX3421E general-purpose output with number PIN_NUMBER to
16652d53139fSDavid Mosberger  * VALUE (0 or 1).  PIN_NUMBER may be in the range from 1-8.  For
16662d53139fSDavid Mosberger  * any other value, this function acts as a no-op.
16672d53139fSDavid Mosberger  */
16682d53139fSDavid Mosberger static void
16692d53139fSDavid Mosberger max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value)
16702d53139fSDavid Mosberger {
16712d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
16722d53139fSDavid Mosberger 	u8 mask, idx;
16732d53139fSDavid Mosberger 
16742d53139fSDavid Mosberger 	--pin_number;
16752d53139fSDavid Mosberger 	if (pin_number > 7)
16762d53139fSDavid Mosberger 		return;
16772d53139fSDavid Mosberger 
167859b71f77SJaewon Kim 	mask = 1u << (pin_number % 4);
16792d53139fSDavid Mosberger 	idx = pin_number / 4;
16802d53139fSDavid Mosberger 
16812d53139fSDavid Mosberger 	if (value)
16822d53139fSDavid Mosberger 		max3421_hcd->iopins[idx] |=  mask;
16832d53139fSDavid Mosberger 	else
16842d53139fSDavid Mosberger 		max3421_hcd->iopins[idx] &= ~mask;
16852eb5dbddSDavid Mosberger-Tang 	set_bit(IOPIN_UPDATE, &max3421_hcd->todo);
16862d53139fSDavid Mosberger 	wake_up_process(max3421_hcd->spi_thread);
16872d53139fSDavid Mosberger }
16882d53139fSDavid Mosberger 
16892d53139fSDavid Mosberger static int
16902d53139fSDavid Mosberger max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
16912d53139fSDavid Mosberger 		    char *buf, u16 length)
16922d53139fSDavid Mosberger {
16932d53139fSDavid Mosberger 	struct spi_device *spi = to_spi_device(hcd->self.controller);
16942d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
16952d53139fSDavid Mosberger 	struct max3421_hcd_platform_data *pdata;
16962d53139fSDavid Mosberger 	unsigned long flags;
16972d53139fSDavid Mosberger 	int retval = 0;
16982d53139fSDavid Mosberger 
16992d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
17002d53139fSDavid Mosberger 
17012d53139fSDavid Mosberger 	pdata = spi->dev.platform_data;
17022d53139fSDavid Mosberger 
17032d53139fSDavid Mosberger 	switch (type_req) {
17042d53139fSDavid Mosberger 	case ClearHubFeature:
17052d53139fSDavid Mosberger 		break;
17062d53139fSDavid Mosberger 	case ClearPortFeature:
17072d53139fSDavid Mosberger 		switch (value) {
17082d53139fSDavid Mosberger 		case USB_PORT_FEAT_SUSPEND:
17092d53139fSDavid Mosberger 			break;
17102d53139fSDavid Mosberger 		case USB_PORT_FEAT_POWER:
17112d53139fSDavid Mosberger 			dev_dbg(hcd->self.controller, "power-off\n");
17124055e5e5SDavid Mosberger-Tang 			max3421_gpout_set_value(hcd, pdata->vbus_gpout,
17134055e5e5SDavid Mosberger-Tang 						!pdata->vbus_active_level);
17142d53139fSDavid Mosberger 			/* FALLS THROUGH */
17152d53139fSDavid Mosberger 		default:
17162d53139fSDavid Mosberger 			max3421_hcd->port_status &= ~(1 << value);
17172d53139fSDavid Mosberger 		}
17182d53139fSDavid Mosberger 		break;
17192d53139fSDavid Mosberger 	case GetHubDescriptor:
17202d53139fSDavid Mosberger 		hub_descriptor((struct usb_hub_descriptor *) buf);
17212d53139fSDavid Mosberger 		break;
17222d53139fSDavid Mosberger 
17232d53139fSDavid Mosberger 	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
17242d53139fSDavid Mosberger 	case GetPortErrorCount:
17252d53139fSDavid Mosberger 	case SetHubDepth:
17262d53139fSDavid Mosberger 		/* USB3 only */
17272d53139fSDavid Mosberger 		goto error;
17282d53139fSDavid Mosberger 
17292d53139fSDavid Mosberger 	case GetHubStatus:
17302d53139fSDavid Mosberger 		*(__le32 *) buf = cpu_to_le32(0);
17312d53139fSDavid Mosberger 		break;
17322d53139fSDavid Mosberger 
17332d53139fSDavid Mosberger 	case GetPortStatus:
17342d53139fSDavid Mosberger 		if (index != 1) {
17352d53139fSDavid Mosberger 			retval = -EPIPE;
17362d53139fSDavid Mosberger 			goto error;
17372d53139fSDavid Mosberger 		}
17382d53139fSDavid Mosberger 		((__le16 *) buf)[0] = cpu_to_le16(max3421_hcd->port_status);
17392d53139fSDavid Mosberger 		((__le16 *) buf)[1] =
17402d53139fSDavid Mosberger 			cpu_to_le16(max3421_hcd->port_status >> 16);
17412d53139fSDavid Mosberger 		break;
17422d53139fSDavid Mosberger 
17432d53139fSDavid Mosberger 	case SetHubFeature:
17442d53139fSDavid Mosberger 		retval = -EPIPE;
17452d53139fSDavid Mosberger 		break;
17462d53139fSDavid Mosberger 
17472d53139fSDavid Mosberger 	case SetPortFeature:
17482d53139fSDavid Mosberger 		switch (value) {
17492d53139fSDavid Mosberger 		case USB_PORT_FEAT_LINK_STATE:
17502d53139fSDavid Mosberger 		case USB_PORT_FEAT_U1_TIMEOUT:
17512d53139fSDavid Mosberger 		case USB_PORT_FEAT_U2_TIMEOUT:
17522d53139fSDavid Mosberger 		case USB_PORT_FEAT_BH_PORT_RESET:
17532d53139fSDavid Mosberger 			goto error;
17542d53139fSDavid Mosberger 		case USB_PORT_FEAT_SUSPEND:
17552d53139fSDavid Mosberger 			if (max3421_hcd->active)
17562d53139fSDavid Mosberger 				max3421_hcd->port_status |=
17572d53139fSDavid Mosberger 					USB_PORT_STAT_SUSPEND;
17582d53139fSDavid Mosberger 			break;
17592d53139fSDavid Mosberger 		case USB_PORT_FEAT_POWER:
17602d53139fSDavid Mosberger 			dev_dbg(hcd->self.controller, "power-on\n");
17612d53139fSDavid Mosberger 			max3421_hcd->port_status |= USB_PORT_STAT_POWER;
17624055e5e5SDavid Mosberger-Tang 			max3421_gpout_set_value(hcd, pdata->vbus_gpout,
17634055e5e5SDavid Mosberger-Tang 						pdata->vbus_active_level);
17642d53139fSDavid Mosberger 			break;
17652d53139fSDavid Mosberger 		case USB_PORT_FEAT_RESET:
17662d53139fSDavid Mosberger 			max3421_reset_port(hcd);
17672d53139fSDavid Mosberger 			/* FALLS THROUGH */
17682d53139fSDavid Mosberger 		default:
17692d53139fSDavid Mosberger 			if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
17702d53139fSDavid Mosberger 			    != 0)
17712d53139fSDavid Mosberger 				max3421_hcd->port_status |= (1 << value);
17722d53139fSDavid Mosberger 		}
17732d53139fSDavid Mosberger 		break;
17742d53139fSDavid Mosberger 
17752d53139fSDavid Mosberger 	default:
17762d53139fSDavid Mosberger 		dev_dbg(hcd->self.controller,
17772d53139fSDavid Mosberger 			"hub control req%04x v%04x i%04x l%d\n",
17782d53139fSDavid Mosberger 			type_req, value, index, length);
17792d53139fSDavid Mosberger error:		/* "protocol stall" on error */
17802d53139fSDavid Mosberger 		retval = -EPIPE;
17812d53139fSDavid Mosberger 	}
17822d53139fSDavid Mosberger 
17832d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
17842d53139fSDavid Mosberger 	return retval;
17852d53139fSDavid Mosberger }
17862d53139fSDavid Mosberger 
17872d53139fSDavid Mosberger static int
17882d53139fSDavid Mosberger max3421_bus_suspend(struct usb_hcd *hcd)
17892d53139fSDavid Mosberger {
17902d53139fSDavid Mosberger 	return -1;
17912d53139fSDavid Mosberger }
17922d53139fSDavid Mosberger 
17932d53139fSDavid Mosberger static int
17942d53139fSDavid Mosberger max3421_bus_resume(struct usb_hcd *hcd)
17952d53139fSDavid Mosberger {
17962d53139fSDavid Mosberger 	return -1;
17972d53139fSDavid Mosberger }
17982d53139fSDavid Mosberger 
17992d53139fSDavid Mosberger /*
18002d53139fSDavid Mosberger  * The SPI driver already takes care of DMA-mapping/unmapping, so no
18012d53139fSDavid Mosberger  * reason to do it twice.
18022d53139fSDavid Mosberger  */
18032d53139fSDavid Mosberger static int
18042d53139fSDavid Mosberger max3421_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
18052d53139fSDavid Mosberger {
18062d53139fSDavid Mosberger 	return 0;
18072d53139fSDavid Mosberger }
18082d53139fSDavid Mosberger 
18092d53139fSDavid Mosberger static void
18102d53139fSDavid Mosberger max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
18112d53139fSDavid Mosberger {
18122d53139fSDavid Mosberger }
18132d53139fSDavid Mosberger 
18142d53139fSDavid Mosberger static struct hc_driver max3421_hcd_desc = {
18152d53139fSDavid Mosberger 	.description =		"max3421",
18162d53139fSDavid Mosberger 	.product_desc =		DRIVER_DESC,
18172d53139fSDavid Mosberger 	.hcd_priv_size =	sizeof(struct max3421_hcd),
18182d53139fSDavid Mosberger 	.flags =		HCD_USB11,
18192d53139fSDavid Mosberger 	.reset =		max3421_reset,
18202d53139fSDavid Mosberger 	.start =		max3421_start,
18212d53139fSDavid Mosberger 	.stop =			max3421_stop,
18222d53139fSDavid Mosberger 	.get_frame_number =	max3421_get_frame_number,
18232d53139fSDavid Mosberger 	.urb_enqueue =		max3421_urb_enqueue,
18242d53139fSDavid Mosberger 	.urb_dequeue =		max3421_urb_dequeue,
18252d53139fSDavid Mosberger 	.map_urb_for_dma =	max3421_map_urb_for_dma,
18262d53139fSDavid Mosberger 	.unmap_urb_for_dma =	max3421_unmap_urb_for_dma,
18272d53139fSDavid Mosberger 	.endpoint_disable =	max3421_endpoint_disable,
18282d53139fSDavid Mosberger 	.hub_status_data =	max3421_hub_status_data,
18292d53139fSDavid Mosberger 	.hub_control =		max3421_hub_control,
18302d53139fSDavid Mosberger 	.bus_suspend =		max3421_bus_suspend,
18312d53139fSDavid Mosberger 	.bus_resume =		max3421_bus_resume,
18322d53139fSDavid Mosberger };
18332d53139fSDavid Mosberger 
18342d53139fSDavid Mosberger static int
18352d53139fSDavid Mosberger max3421_probe(struct spi_device *spi)
18362d53139fSDavid Mosberger {
18372d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd;
183805dfa5c9SDavid Mosberger-Tang 	struct usb_hcd *hcd = NULL;
183905dfa5c9SDavid Mosberger-Tang 	int retval = -ENOMEM;
18402d53139fSDavid Mosberger 
18412d53139fSDavid Mosberger 	if (spi_setup(spi) < 0) {
18422d53139fSDavid Mosberger 		dev_err(&spi->dev, "Unable to setup SPI bus");
18432d53139fSDavid Mosberger 		return -EFAULT;
18442d53139fSDavid Mosberger 	}
18452d53139fSDavid Mosberger 
18462d53139fSDavid Mosberger 	hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev,
18472d53139fSDavid Mosberger 			     dev_name(&spi->dev));
18482d53139fSDavid Mosberger 	if (!hcd) {
18492d53139fSDavid Mosberger 		dev_err(&spi->dev, "failed to create HCD structure\n");
185005dfa5c9SDavid Mosberger-Tang 		goto error;
18512d53139fSDavid Mosberger 	}
18522d53139fSDavid Mosberger 	set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
18532d53139fSDavid Mosberger 	max3421_hcd = hcd_to_max3421(hcd);
18542d53139fSDavid Mosberger 	max3421_hcd->next = max3421_hcd_list;
18552d53139fSDavid Mosberger 	max3421_hcd_list = max3421_hcd;
18562d53139fSDavid Mosberger 	INIT_LIST_HEAD(&max3421_hcd->ep_list);
18572d53139fSDavid Mosberger 
185805dfa5c9SDavid Mosberger-Tang 	max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL);
185913dcf780SWolfram Sang 	if (!max3421_hcd->tx)
186005dfa5c9SDavid Mosberger-Tang 		goto error;
186105dfa5c9SDavid Mosberger-Tang 	max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL);
186213dcf780SWolfram Sang 	if (!max3421_hcd->rx)
186305dfa5c9SDavid Mosberger-Tang 		goto error;
186405dfa5c9SDavid Mosberger-Tang 
18652d53139fSDavid Mosberger 	max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd,
18662d53139fSDavid Mosberger 					      "max3421_spi_thread");
18672d53139fSDavid Mosberger 	if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) {
18682d53139fSDavid Mosberger 		dev_err(&spi->dev,
18692d53139fSDavid Mosberger 			"failed to create SPI thread (out of memory)\n");
187005dfa5c9SDavid Mosberger-Tang 		goto error;
18712d53139fSDavid Mosberger 	}
18722d53139fSDavid Mosberger 
18732d53139fSDavid Mosberger 	retval = usb_add_hcd(hcd, 0, 0);
18742d53139fSDavid Mosberger 	if (retval) {
18752d53139fSDavid Mosberger 		dev_err(&spi->dev, "failed to add HCD\n");
187605dfa5c9SDavid Mosberger-Tang 		goto error;
18772d53139fSDavid Mosberger 	}
18782d53139fSDavid Mosberger 
18792d53139fSDavid Mosberger 	retval = request_irq(spi->irq, max3421_irq_handler,
18802d53139fSDavid Mosberger 			     IRQF_TRIGGER_LOW, "max3421", hcd);
18812d53139fSDavid Mosberger 	if (retval < 0) {
18822d53139fSDavid Mosberger 		dev_err(&spi->dev, "failed to request irq %d\n", spi->irq);
188305dfa5c9SDavid Mosberger-Tang 		goto error;
18842d53139fSDavid Mosberger 	}
18852d53139fSDavid Mosberger 	return 0;
188605dfa5c9SDavid Mosberger-Tang 
188705dfa5c9SDavid Mosberger-Tang error:
188805dfa5c9SDavid Mosberger-Tang 	if (hcd) {
188905dfa5c9SDavid Mosberger-Tang 		kfree(max3421_hcd->tx);
189005dfa5c9SDavid Mosberger-Tang 		kfree(max3421_hcd->rx);
189105dfa5c9SDavid Mosberger-Tang 		if (max3421_hcd->spi_thread)
189205dfa5c9SDavid Mosberger-Tang 			kthread_stop(max3421_hcd->spi_thread);
189305dfa5c9SDavid Mosberger-Tang 		usb_put_hcd(hcd);
189405dfa5c9SDavid Mosberger-Tang 	}
189505dfa5c9SDavid Mosberger-Tang 	return retval;
18962d53139fSDavid Mosberger }
18972d53139fSDavid Mosberger 
18982d53139fSDavid Mosberger static int
18992d53139fSDavid Mosberger max3421_remove(struct spi_device *spi)
19002d53139fSDavid Mosberger {
19012d53139fSDavid Mosberger 	struct max3421_hcd *max3421_hcd = NULL, **prev;
19022d53139fSDavid Mosberger 	struct usb_hcd *hcd = NULL;
19032d53139fSDavid Mosberger 	unsigned long flags;
19042d53139fSDavid Mosberger 
19052d53139fSDavid Mosberger 	for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) {
19062d53139fSDavid Mosberger 		max3421_hcd = *prev;
19072d53139fSDavid Mosberger 		hcd = max3421_to_hcd(max3421_hcd);
19082d53139fSDavid Mosberger 		if (hcd->self.controller == &spi->dev)
19092d53139fSDavid Mosberger 			break;
19102d53139fSDavid Mosberger 	}
19112d53139fSDavid Mosberger 	if (!max3421_hcd) {
19122d53139fSDavid Mosberger 		dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n",
19132d53139fSDavid Mosberger 			spi);
19142d53139fSDavid Mosberger 		return -ENODEV;
19152d53139fSDavid Mosberger 	}
19162d53139fSDavid Mosberger 
19172d53139fSDavid Mosberger 	usb_remove_hcd(hcd);
19182d53139fSDavid Mosberger 
19192d53139fSDavid Mosberger 	spin_lock_irqsave(&max3421_hcd->lock, flags);
19202d53139fSDavid Mosberger 
19212d53139fSDavid Mosberger 	kthread_stop(max3421_hcd->spi_thread);
19222d53139fSDavid Mosberger 	*prev = max3421_hcd->next;
19232d53139fSDavid Mosberger 
19242d53139fSDavid Mosberger 	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
19252d53139fSDavid Mosberger 
19262d53139fSDavid Mosberger 	free_irq(spi->irq, hcd);
19272d53139fSDavid Mosberger 
19282d53139fSDavid Mosberger 	usb_put_hcd(hcd);
19292d53139fSDavid Mosberger 	return 0;
19302d53139fSDavid Mosberger }
19312d53139fSDavid Mosberger 
19322d53139fSDavid Mosberger static struct spi_driver max3421_driver = {
19332d53139fSDavid Mosberger 	.probe		= max3421_probe,
19342d53139fSDavid Mosberger 	.remove		= max3421_remove,
19352d53139fSDavid Mosberger 	.driver		= {
19362d53139fSDavid Mosberger 		.name	= "max3421-hcd",
19372d53139fSDavid Mosberger 	},
19382d53139fSDavid Mosberger };
19392d53139fSDavid Mosberger 
19407df45d5fSSachin Kamat module_spi_driver(max3421_driver);
19412d53139fSDavid Mosberger 
19422d53139fSDavid Mosberger MODULE_DESCRIPTION(DRIVER_DESC);
19432d53139fSDavid Mosberger MODULE_AUTHOR("David Mosberger <davidm@egauge.net>");
19442d53139fSDavid Mosberger MODULE_LICENSE("GPL");
1945