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 list_head *pos, *upos, *next_upos; 8012d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 8022d53139fSDavid Mosberger struct usb_host_endpoint *ep; 8032d53139fSDavid Mosberger struct urb *urb; 8042d53139fSDavid Mosberger unsigned long flags; 8052d53139fSDavid Mosberger int retval = 0; 8062d53139fSDavid Mosberger 8072d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 8082d53139fSDavid Mosberger list_for_each(pos, &max3421_hcd->ep_list) { 8092d53139fSDavid Mosberger max3421_ep = container_of(pos, struct max3421_ep, ep_list); 8102d53139fSDavid Mosberger ep = max3421_ep->ep; 8112d53139fSDavid Mosberger list_for_each_safe(upos, next_upos, &ep->urb_list) { 8122d53139fSDavid Mosberger urb = container_of(upos, struct urb, urb_list); 8132d53139fSDavid Mosberger if (urb->unlinked) { 8142d53139fSDavid Mosberger retval = 1; 8152d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", 8162d53139fSDavid Mosberger __func__, urb, urb->unlinked); 8172d53139fSDavid Mosberger usb_hcd_unlink_urb_from_ep(hcd, urb); 8182d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, 8192d53139fSDavid Mosberger flags); 8202d53139fSDavid Mosberger usb_hcd_giveback_urb(hcd, urb, 0); 8212d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 8222d53139fSDavid Mosberger } 8232d53139fSDavid Mosberger } 8242d53139fSDavid Mosberger } 8252d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 8262d53139fSDavid Mosberger return retval; 8272d53139fSDavid Mosberger } 8282d53139fSDavid Mosberger 8292d53139fSDavid Mosberger /* 8302d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 8312d53139fSDavid Mosberger */ 8322d53139fSDavid Mosberger static void 8332d53139fSDavid Mosberger max3421_slow_retransmit(struct usb_hcd *hcd) 8342d53139fSDavid Mosberger { 8352d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8362d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8372d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 8382d53139fSDavid Mosberger 8392d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 8402d53139fSDavid Mosberger max3421_ep->retransmit = 1; 8412d53139fSDavid Mosberger max3421_hcd->curr_urb = NULL; 8422d53139fSDavid Mosberger } 8432d53139fSDavid Mosberger 8442d53139fSDavid Mosberger /* 8452d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 8462d53139fSDavid Mosberger */ 8472d53139fSDavid Mosberger static void 8482d53139fSDavid Mosberger max3421_recv_data_available(struct usb_hcd *hcd) 8492d53139fSDavid Mosberger { 8502d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8512d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8522d53139fSDavid Mosberger size_t remaining, transfer_size; 8532d53139fSDavid Mosberger u8 rcvbc; 8542d53139fSDavid Mosberger 8552d53139fSDavid Mosberger rcvbc = spi_rd8(hcd, MAX3421_REG_RCVBC); 8562d53139fSDavid Mosberger 8572d53139fSDavid Mosberger if (rcvbc > MAX3421_FIFO_SIZE) 8582d53139fSDavid Mosberger rcvbc = MAX3421_FIFO_SIZE; 8592d53139fSDavid Mosberger if (urb->actual_length >= urb->transfer_buffer_length) 8602d53139fSDavid Mosberger remaining = 0; 8612d53139fSDavid Mosberger else 8622d53139fSDavid Mosberger remaining = urb->transfer_buffer_length - urb->actual_length; 8632d53139fSDavid Mosberger transfer_size = rcvbc; 8642d53139fSDavid Mosberger if (transfer_size > remaining) 8652d53139fSDavid Mosberger transfer_size = remaining; 8662d53139fSDavid Mosberger if (transfer_size > 0) { 8672d53139fSDavid Mosberger void *dst = urb->transfer_buffer + urb->actual_length; 8682d53139fSDavid Mosberger 8692d53139fSDavid Mosberger spi_rd_buf(hcd, MAX3421_REG_RCVFIFO, dst, transfer_size); 8702d53139fSDavid Mosberger urb->actual_length += transfer_size; 8712d53139fSDavid Mosberger max3421_hcd->curr_len = transfer_size; 8722d53139fSDavid Mosberger } 8732d53139fSDavid Mosberger 8742d53139fSDavid Mosberger /* ack the RCVDAV irq now that the FIFO has been read: */ 8752d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIRQ, BIT(MAX3421_HI_RCVDAV_BIT)); 8762d53139fSDavid Mosberger } 8772d53139fSDavid Mosberger 8782d53139fSDavid Mosberger static void 8792d53139fSDavid Mosberger max3421_handle_error(struct usb_hcd *hcd, u8 hrsl) 8802d53139fSDavid Mosberger { 8812d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 8822d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8832d53139fSDavid Mosberger u8 result_code = hrsl & MAX3421_HRSL_RESULT_MASK; 8842d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8852d53139fSDavid Mosberger struct max3421_ep *max3421_ep = urb->ep->hcpriv; 8862d53139fSDavid Mosberger int switch_sndfifo; 8872d53139fSDavid Mosberger 8882d53139fSDavid Mosberger /* 8892d53139fSDavid Mosberger * If an OUT command results in any response other than OK 8902d53139fSDavid Mosberger * (i.e., error or NAK), we have to perform a dummy-write to 8912d53139fSDavid Mosberger * SNDBC so the FIFO gets switched back to us. Otherwise, we 8922d53139fSDavid Mosberger * get out of sync with the SNDFIFO double buffer. 8932d53139fSDavid Mosberger */ 8942d53139fSDavid Mosberger switch_sndfifo = (max3421_ep->pkt_state == PKT_STATE_TRANSFER && 8952d53139fSDavid Mosberger usb_urb_dir_out(urb)); 8962d53139fSDavid Mosberger 8972d53139fSDavid Mosberger switch (result_code) { 8982d53139fSDavid Mosberger case MAX3421_HRSL_OK: 8992d53139fSDavid Mosberger return; /* this shouldn't happen */ 9002d53139fSDavid Mosberger 9012d53139fSDavid Mosberger case MAX3421_HRSL_WRONGPID: /* received wrong PID */ 9022d53139fSDavid Mosberger case MAX3421_HRSL_BUSY: /* SIE busy */ 9032d53139fSDavid Mosberger case MAX3421_HRSL_BADREQ: /* bad val in HXFR */ 9042d53139fSDavid Mosberger case MAX3421_HRSL_UNDEF: /* reserved */ 9052d53139fSDavid Mosberger case MAX3421_HRSL_KERR: /* K-state instead of response */ 9062d53139fSDavid Mosberger case MAX3421_HRSL_JERR: /* J-state instead of response */ 9072d53139fSDavid Mosberger /* 9082d53139fSDavid Mosberger * packet experienced an error that we cannot recover 9092d53139fSDavid Mosberger * from; report error 9102d53139fSDavid Mosberger */ 9112d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9122d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9132d53139fSDavid Mosberger __func__, hrsl); 9142d53139fSDavid Mosberger break; 9152d53139fSDavid Mosberger 9162d53139fSDavid Mosberger case MAX3421_HRSL_TOGERR: 9172d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 9182d53139fSDavid Mosberger ; /* don't do anything (device will switch toggle) */ 9192d53139fSDavid Mosberger else { 9202d53139fSDavid Mosberger /* flip the send toggle bit: */ 9212d53139fSDavid Mosberger int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; 9222d53139fSDavid Mosberger 9232d53139fSDavid Mosberger sndtog ^= 1; 9242d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, 9252d53139fSDavid Mosberger BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); 9262d53139fSDavid Mosberger } 9272d53139fSDavid Mosberger /* FALL THROUGH */ 9282d53139fSDavid Mosberger case MAX3421_HRSL_BADBC: /* bad byte count */ 9292d53139fSDavid Mosberger case MAX3421_HRSL_PIDERR: /* received PID is corrupted */ 9302d53139fSDavid Mosberger case MAX3421_HRSL_PKTERR: /* packet error (stuff, EOP) */ 9312d53139fSDavid Mosberger case MAX3421_HRSL_CRCERR: /* CRC error */ 9322d53139fSDavid Mosberger case MAX3421_HRSL_BABBLE: /* device talked too long */ 9332d53139fSDavid Mosberger case MAX3421_HRSL_TIMEOUT: 9342d53139fSDavid Mosberger if (max3421_ep->retries++ < USB_MAX_RETRIES) 9352d53139fSDavid Mosberger /* retry the packet again in the next frame */ 9362d53139fSDavid Mosberger max3421_slow_retransmit(hcd); 9372d53139fSDavid Mosberger else { 9382d53139fSDavid Mosberger /* Based on ohci.h cc_to_err[]: */ 9392d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9402d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9412d53139fSDavid Mosberger __func__, hrsl); 9422d53139fSDavid Mosberger } 9432d53139fSDavid Mosberger break; 9442d53139fSDavid Mosberger 9452d53139fSDavid Mosberger case MAX3421_HRSL_STALL: 9462d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9472d53139fSDavid Mosberger __func__, hrsl); 9482d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9492d53139fSDavid Mosberger break; 9502d53139fSDavid Mosberger 9512d53139fSDavid Mosberger case MAX3421_HRSL_NAK: 9522d53139fSDavid Mosberger /* 9532d53139fSDavid Mosberger * Device wasn't ready for data or has no data 9542d53139fSDavid Mosberger * available: retry the packet again. 9552d53139fSDavid Mosberger */ 9562d53139fSDavid Mosberger if (max3421_ep->naks++ < NAK_MAX_FAST_RETRANSMITS) { 9572d53139fSDavid Mosberger max3421_next_transfer(hcd, 1); 9582d53139fSDavid Mosberger switch_sndfifo = 0; 9592d53139fSDavid Mosberger } else 9602d53139fSDavid Mosberger max3421_slow_retransmit(hcd); 9612d53139fSDavid Mosberger break; 9622d53139fSDavid Mosberger } 9632d53139fSDavid Mosberger if (switch_sndfifo) 9642d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDBC, 0); 9652d53139fSDavid Mosberger } 9662d53139fSDavid Mosberger 9672d53139fSDavid Mosberger /* 9682d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 9692d53139fSDavid Mosberger */ 9702d53139fSDavid Mosberger static int 9712d53139fSDavid Mosberger max3421_transfer_in_done(struct usb_hcd *hcd, struct urb *urb) 9722d53139fSDavid Mosberger { 9732d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 9742d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 9752d53139fSDavid Mosberger u32 max_packet; 9762d53139fSDavid Mosberger 9772d53139fSDavid Mosberger if (urb->actual_length >= urb->transfer_buffer_length) 9782d53139fSDavid Mosberger return 1; /* read is complete, so we're done */ 9792d53139fSDavid Mosberger 9802d53139fSDavid Mosberger /* 9812d53139fSDavid Mosberger * USB 2.0 Section 5.3.2 Pipes: packets must be full size 9822d53139fSDavid Mosberger * except for last one. 9832d53139fSDavid Mosberger */ 9842d53139fSDavid Mosberger max_packet = usb_maxpacket(urb->dev, urb->pipe, 0); 9852d53139fSDavid Mosberger if (max_packet > MAX3421_FIFO_SIZE) { 9862d53139fSDavid Mosberger /* 9872d53139fSDavid Mosberger * We do not support isochronous transfers at this 9882d53139fSDavid Mosberger * time... 9892d53139fSDavid Mosberger */ 9902d53139fSDavid Mosberger dev_err(&spi->dev, 9912d53139fSDavid Mosberger "%s: packet-size of %u too big (limit is %u bytes)", 9922d53139fSDavid Mosberger __func__, max_packet, MAX3421_FIFO_SIZE); 9932d53139fSDavid Mosberger return -EINVAL; 9942d53139fSDavid Mosberger } 9952d53139fSDavid Mosberger 9962d53139fSDavid Mosberger if (max3421_hcd->curr_len < max_packet) { 9972d53139fSDavid Mosberger if (urb->transfer_flags & URB_SHORT_NOT_OK) { 9982d53139fSDavid Mosberger /* 9992d53139fSDavid Mosberger * remaining > 0 and received an 10002d53139fSDavid Mosberger * unexpected partial packet -> 10012d53139fSDavid Mosberger * error 10022d53139fSDavid Mosberger */ 10032d53139fSDavid Mosberger return -EREMOTEIO; 10042d53139fSDavid Mosberger } else 10052d53139fSDavid Mosberger /* short read, but it's OK */ 10062d53139fSDavid Mosberger return 1; 10072d53139fSDavid Mosberger } 10082d53139fSDavid Mosberger return 0; /* not done */ 10092d53139fSDavid Mosberger } 10102d53139fSDavid Mosberger 10112d53139fSDavid Mosberger /* 10122d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 10132d53139fSDavid Mosberger */ 10142d53139fSDavid Mosberger static int 10152d53139fSDavid Mosberger max3421_transfer_out_done(struct usb_hcd *hcd, struct urb *urb) 10162d53139fSDavid Mosberger { 10172d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 10182d53139fSDavid Mosberger 10192d53139fSDavid Mosberger urb->actual_length += max3421_hcd->curr_len; 10202d53139fSDavid Mosberger if (urb->actual_length < urb->transfer_buffer_length) 10212d53139fSDavid Mosberger return 0; 10222d53139fSDavid Mosberger if (urb->transfer_flags & URB_ZERO_PACKET) { 10232d53139fSDavid Mosberger /* 10242d53139fSDavid Mosberger * Some hardware needs a zero-size packet at the end 10252d53139fSDavid Mosberger * of a bulk-out transfer if the last transfer was a 10262d53139fSDavid Mosberger * full-sized packet (i.e., such hardware use < 10272d53139fSDavid Mosberger * max_packet as an indicator that the end of the 10282d53139fSDavid Mosberger * packet has been reached). 10292d53139fSDavid Mosberger */ 10302d53139fSDavid Mosberger u32 max_packet = usb_maxpacket(urb->dev, urb->pipe, 1); 10312d53139fSDavid Mosberger 10322d53139fSDavid Mosberger if (max3421_hcd->curr_len == max_packet) 10332d53139fSDavid Mosberger return 0; 10342d53139fSDavid Mosberger } 10352d53139fSDavid Mosberger return 1; 10362d53139fSDavid Mosberger } 10372d53139fSDavid Mosberger 10382d53139fSDavid Mosberger /* 10392d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 10402d53139fSDavid Mosberger */ 10412d53139fSDavid Mosberger static void 10422d53139fSDavid Mosberger max3421_host_transfer_done(struct usb_hcd *hcd) 10432d53139fSDavid Mosberger { 10442d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 10452d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 10462d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 10472d53139fSDavid Mosberger u8 result_code, hrsl; 10482d53139fSDavid Mosberger int urb_done = 0; 10492d53139fSDavid Mosberger 10502d53139fSDavid Mosberger max3421_hcd->hien &= ~(BIT(MAX3421_HI_HXFRDN_BIT) | 10512d53139fSDavid Mosberger BIT(MAX3421_HI_RCVDAV_BIT)); 10522d53139fSDavid Mosberger 10532d53139fSDavid Mosberger hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); 10542d53139fSDavid Mosberger result_code = hrsl & MAX3421_HRSL_RESULT_MASK; 10552d53139fSDavid Mosberger 10562d53139fSDavid Mosberger #ifdef DEBUG 10572d53139fSDavid Mosberger ++max3421_hcd->err_stat[result_code]; 10582d53139fSDavid Mosberger #endif 10592d53139fSDavid Mosberger 10602d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 10612d53139fSDavid Mosberger 10622d53139fSDavid Mosberger if (unlikely(result_code != MAX3421_HRSL_OK)) { 10632d53139fSDavid Mosberger max3421_handle_error(hcd, hrsl); 10642d53139fSDavid Mosberger return; 10652d53139fSDavid Mosberger } 10662d53139fSDavid Mosberger 10672d53139fSDavid Mosberger max3421_ep->naks = 0; 10682d53139fSDavid Mosberger max3421_ep->retries = 0; 10692d53139fSDavid Mosberger switch (max3421_ep->pkt_state) { 10702d53139fSDavid Mosberger 10712d53139fSDavid Mosberger case PKT_STATE_SETUP: 10722d53139fSDavid Mosberger if (urb->transfer_buffer_length > 0) 10732d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TRANSFER; 10742d53139fSDavid Mosberger else 10752d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TERMINATE; 10762d53139fSDavid Mosberger break; 10772d53139fSDavid Mosberger 10782d53139fSDavid Mosberger case PKT_STATE_TRANSFER: 10792d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 10802d53139fSDavid Mosberger urb_done = max3421_transfer_in_done(hcd, urb); 10812d53139fSDavid Mosberger else 10822d53139fSDavid Mosberger urb_done = max3421_transfer_out_done(hcd, urb); 10832d53139fSDavid Mosberger if (urb_done > 0 && usb_pipetype(urb->pipe) == PIPE_CONTROL) { 10842d53139fSDavid Mosberger /* 10852d53139fSDavid Mosberger * We aren't really done - we still need to 10862d53139fSDavid Mosberger * terminate the control transfer: 10872d53139fSDavid Mosberger */ 10882d53139fSDavid Mosberger max3421_hcd->urb_done = urb_done = 0; 10892d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TERMINATE; 10902d53139fSDavid Mosberger } 10912d53139fSDavid Mosberger break; 10922d53139fSDavid Mosberger 10932d53139fSDavid Mosberger case PKT_STATE_TERMINATE: 10942d53139fSDavid Mosberger urb_done = 1; 10952d53139fSDavid Mosberger break; 10962d53139fSDavid Mosberger } 10972d53139fSDavid Mosberger 10982d53139fSDavid Mosberger if (urb_done) 10992d53139fSDavid Mosberger max3421_hcd->urb_done = urb_done; 11002d53139fSDavid Mosberger else 11012d53139fSDavid Mosberger max3421_next_transfer(hcd, 0); 11022d53139fSDavid Mosberger } 11032d53139fSDavid Mosberger 11042d53139fSDavid Mosberger /* 11052d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 11062d53139fSDavid Mosberger */ 11072d53139fSDavid Mosberger static void 11082d53139fSDavid Mosberger max3421_detect_conn(struct usb_hcd *hcd) 11092d53139fSDavid Mosberger { 11102d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11112d53139fSDavid Mosberger unsigned int jk, have_conn = 0; 11122d53139fSDavid Mosberger u32 old_port_status, chg; 11132d53139fSDavid Mosberger unsigned long flags; 11142d53139fSDavid Mosberger u8 hrsl, mode; 11152d53139fSDavid Mosberger 11162d53139fSDavid Mosberger hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); 11172d53139fSDavid Mosberger 11182d53139fSDavid Mosberger jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) | 11192d53139fSDavid Mosberger (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1)); 11202d53139fSDavid Mosberger 11212d53139fSDavid Mosberger mode = max3421_hcd->mode; 11222d53139fSDavid Mosberger 11232d53139fSDavid Mosberger switch (jk) { 11242d53139fSDavid Mosberger case 0x0: /* SE0: disconnect */ 11252d53139fSDavid Mosberger /* 11262d53139fSDavid Mosberger * Turn off SOFKAENAB bit to avoid getting interrupt 11272d53139fSDavid Mosberger * every milli-second: 11282d53139fSDavid Mosberger */ 11292d53139fSDavid Mosberger mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT); 11302d53139fSDavid Mosberger break; 11312d53139fSDavid Mosberger 11322d53139fSDavid Mosberger case 0x1: /* J=0,K=1: low-speed (in full-speed or vice versa) */ 11332d53139fSDavid Mosberger case 0x2: /* J=1,K=0: full-speed (in full-speed or vice versa) */ 11342d53139fSDavid Mosberger if (jk == 0x2) 11352d53139fSDavid Mosberger /* need to switch to the other speed: */ 11362d53139fSDavid Mosberger mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT); 11372d53139fSDavid Mosberger /* turn on SOFKAENAB bit: */ 11382d53139fSDavid Mosberger mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT); 11392d53139fSDavid Mosberger have_conn = 1; 11402d53139fSDavid Mosberger break; 11412d53139fSDavid Mosberger 11422d53139fSDavid Mosberger case 0x3: /* illegal */ 11432d53139fSDavid Mosberger break; 11442d53139fSDavid Mosberger } 11452d53139fSDavid Mosberger 11462d53139fSDavid Mosberger max3421_hcd->mode = mode; 11472d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); 11482d53139fSDavid Mosberger 11492d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 11502d53139fSDavid Mosberger old_port_status = max3421_hcd->port_status; 11512d53139fSDavid Mosberger if (have_conn) 11522d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_CONNECTION; 11532d53139fSDavid Mosberger else 11542d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION; 11552d53139fSDavid Mosberger if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT)) 11562d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_LOW_SPEED; 11572d53139fSDavid Mosberger else 11582d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED; 11592d53139fSDavid Mosberger chg = (old_port_status ^ max3421_hcd->port_status); 11602d53139fSDavid Mosberger max3421_hcd->port_status |= chg << 16; 11612d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 11622d53139fSDavid Mosberger } 11632d53139fSDavid Mosberger 11642d53139fSDavid Mosberger static irqreturn_t 11652d53139fSDavid Mosberger max3421_irq_handler(int irq, void *dev_id) 11662d53139fSDavid Mosberger { 11672d53139fSDavid Mosberger struct usb_hcd *hcd = dev_id; 11682d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 11692d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11702d53139fSDavid Mosberger 11712d53139fSDavid Mosberger if (max3421_hcd->spi_thread && 11722d53139fSDavid Mosberger max3421_hcd->spi_thread->state != TASK_RUNNING) 11732d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 11742eb5dbddSDavid Mosberger-Tang if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo)) 11752d53139fSDavid Mosberger disable_irq_nosync(spi->irq); 11762d53139fSDavid Mosberger return IRQ_HANDLED; 11772d53139fSDavid Mosberger } 11782d53139fSDavid Mosberger 11792d53139fSDavid Mosberger #ifdef DEBUG 11802d53139fSDavid Mosberger 11812d53139fSDavid Mosberger static void 11822d53139fSDavid Mosberger dump_eps(struct usb_hcd *hcd) 11832d53139fSDavid Mosberger { 11842d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11852d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 11862d53139fSDavid Mosberger struct usb_host_endpoint *ep; 11872d53139fSDavid Mosberger struct list_head *pos, *upos; 11882d53139fSDavid Mosberger char ubuf[512], *dp, *end; 11892d53139fSDavid Mosberger unsigned long flags; 11902d53139fSDavid Mosberger struct urb *urb; 11912d53139fSDavid Mosberger int epnum, ret; 11922d53139fSDavid Mosberger 11932d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 11942d53139fSDavid Mosberger list_for_each(pos, &max3421_hcd->ep_list) { 11952d53139fSDavid Mosberger max3421_ep = container_of(pos, struct max3421_ep, ep_list); 11962d53139fSDavid Mosberger ep = max3421_ep->ep; 11972d53139fSDavid Mosberger 11982d53139fSDavid Mosberger dp = ubuf; 11992d53139fSDavid Mosberger end = dp + sizeof(ubuf); 12002d53139fSDavid Mosberger *dp = '\0'; 12012d53139fSDavid Mosberger list_for_each(upos, &ep->urb_list) { 12022d53139fSDavid Mosberger urb = container_of(upos, struct urb, urb_list); 12032d53139fSDavid Mosberger ret = snprintf(dp, end - dp, " %p(%d.%s %d/%d)", urb, 12042d53139fSDavid Mosberger usb_pipetype(urb->pipe), 12052d53139fSDavid Mosberger usb_urb_dir_in(urb) ? "IN" : "OUT", 12062d53139fSDavid Mosberger urb->actual_length, 12072d53139fSDavid Mosberger urb->transfer_buffer_length); 12082d53139fSDavid Mosberger if (ret < 0 || ret >= end - dp) 12092d53139fSDavid Mosberger break; /* error or buffer full */ 12102d53139fSDavid Mosberger dp += ret; 12112d53139fSDavid Mosberger } 12122d53139fSDavid Mosberger 12132d53139fSDavid Mosberger epnum = usb_endpoint_num(&ep->desc); 12142d53139fSDavid Mosberger pr_info("EP%0u %u lst %04u rtr %u nak %6u rxmt %u: %s\n", 12152d53139fSDavid Mosberger epnum, max3421_ep->pkt_state, max3421_ep->last_active, 12162d53139fSDavid Mosberger max3421_ep->retries, max3421_ep->naks, 12172d53139fSDavid Mosberger max3421_ep->retransmit, ubuf); 12182d53139fSDavid Mosberger } 12192d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 12202d53139fSDavid Mosberger } 12212d53139fSDavid Mosberger 12222d53139fSDavid Mosberger #endif /* DEBUG */ 12232d53139fSDavid Mosberger 12242d53139fSDavid Mosberger /* Return zero if no work was performed, 1 otherwise. */ 12252d53139fSDavid Mosberger static int 12262d53139fSDavid Mosberger max3421_handle_irqs(struct usb_hcd *hcd) 12272d53139fSDavid Mosberger { 12282d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 12292d53139fSDavid Mosberger u32 chg, old_port_status; 12302d53139fSDavid Mosberger unsigned long flags; 12312d53139fSDavid Mosberger u8 hirq; 12322d53139fSDavid Mosberger 12332d53139fSDavid Mosberger /* 12342d53139fSDavid Mosberger * Read and ack pending interrupts (CPU must never 12352d53139fSDavid Mosberger * clear SNDBAV directly and RCVDAV must be cleared by 12362d53139fSDavid Mosberger * max3421_recv_data_available()!): 12372d53139fSDavid Mosberger */ 12382d53139fSDavid Mosberger hirq = spi_rd8(hcd, MAX3421_REG_HIRQ); 12392d53139fSDavid Mosberger hirq &= max3421_hcd->hien; 12402d53139fSDavid Mosberger if (!hirq) 12412d53139fSDavid Mosberger return 0; 12422d53139fSDavid Mosberger 12432d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIRQ, 12442d53139fSDavid Mosberger hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) | 12452d53139fSDavid Mosberger BIT(MAX3421_HI_RCVDAV_BIT))); 12462d53139fSDavid Mosberger 12472d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_FRAME_BIT)) { 12482d53139fSDavid Mosberger max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1) 12492d53139fSDavid Mosberger & USB_MAX_FRAME_NUMBER); 12502d53139fSDavid Mosberger max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; 12512d53139fSDavid Mosberger } 12522d53139fSDavid Mosberger 12532d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_RCVDAV_BIT)) 12542d53139fSDavid Mosberger max3421_recv_data_available(hcd); 12552d53139fSDavid Mosberger 12562d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_HXFRDN_BIT)) 12572d53139fSDavid Mosberger max3421_host_transfer_done(hcd); 12582d53139fSDavid Mosberger 12592d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_CONDET_BIT)) 12602d53139fSDavid Mosberger max3421_detect_conn(hcd); 12612d53139fSDavid Mosberger 12622d53139fSDavid Mosberger /* 12632d53139fSDavid Mosberger * Now process interrupts that may affect HCD state 12642d53139fSDavid Mosberger * other than the end-points: 12652d53139fSDavid Mosberger */ 12662d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 12672d53139fSDavid Mosberger 12682d53139fSDavid Mosberger old_port_status = max3421_hcd->port_status; 12692d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) { 12702d53139fSDavid Mosberger if (max3421_hcd->port_status & USB_PORT_STAT_RESET) { 12712d53139fSDavid Mosberger /* BUSEVENT due to completion of Bus Reset */ 12722d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_RESET; 12732d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_ENABLE; 12742d53139fSDavid Mosberger } else { 12752d53139fSDavid Mosberger /* BUSEVENT due to completion of Bus Resume */ 12762d53139fSDavid Mosberger pr_info("%s: BUSEVENT Bus Resume Done\n", __func__); 12772d53139fSDavid Mosberger } 12782d53139fSDavid Mosberger } 12792d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_RWU_BIT)) 12802d53139fSDavid Mosberger pr_info("%s: RWU\n", __func__); 12812d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_SUSDN_BIT)) 12822d53139fSDavid Mosberger pr_info("%s: SUSDN\n", __func__); 12832d53139fSDavid Mosberger 12842d53139fSDavid Mosberger chg = (old_port_status ^ max3421_hcd->port_status); 12852d53139fSDavid Mosberger max3421_hcd->port_status |= chg << 16; 12862d53139fSDavid Mosberger 12872d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 12882d53139fSDavid Mosberger 12892d53139fSDavid Mosberger #ifdef DEBUG 12902d53139fSDavid Mosberger { 12912d53139fSDavid Mosberger static unsigned long last_time; 12922d53139fSDavid Mosberger char sbuf[16 * 16], *dp, *end; 12932d53139fSDavid Mosberger int i; 12942d53139fSDavid Mosberger 1295788bfe88SAsaf Vertz if (time_after(jiffies, last_time + 5*HZ)) { 12962d53139fSDavid Mosberger dp = sbuf; 12972d53139fSDavid Mosberger end = sbuf + sizeof(sbuf); 12982d53139fSDavid Mosberger *dp = '\0'; 12992d53139fSDavid Mosberger for (i = 0; i < 16; ++i) { 13002d53139fSDavid Mosberger int ret = snprintf(dp, end - dp, " %lu", 13012d53139fSDavid Mosberger max3421_hcd->err_stat[i]); 13022d53139fSDavid Mosberger if (ret < 0 || ret >= end - dp) 13032d53139fSDavid Mosberger break; /* error or buffer full */ 13042d53139fSDavid Mosberger dp += ret; 13052d53139fSDavid Mosberger } 13062d53139fSDavid Mosberger pr_info("%s: hrsl_stats %s\n", __func__, sbuf); 13072d53139fSDavid Mosberger memset(max3421_hcd->err_stat, 0, 13082d53139fSDavid Mosberger sizeof(max3421_hcd->err_stat)); 13092d53139fSDavid Mosberger last_time = jiffies; 13102d53139fSDavid Mosberger 13112d53139fSDavid Mosberger dump_eps(hcd); 13122d53139fSDavid Mosberger } 13132d53139fSDavid Mosberger } 13142d53139fSDavid Mosberger #endif 13152d53139fSDavid Mosberger return 1; 13162d53139fSDavid Mosberger } 13172d53139fSDavid Mosberger 13182d53139fSDavid Mosberger static int 13192d53139fSDavid Mosberger max3421_reset_hcd(struct usb_hcd *hcd) 13202d53139fSDavid Mosberger { 13212d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 13222d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 13232d53139fSDavid Mosberger int timeout; 13242d53139fSDavid Mosberger 13252d53139fSDavid Mosberger /* perform a chip reset and wait for OSCIRQ signal to appear: */ 13262d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_USBCTL, BIT(MAX3421_USBCTL_CHIPRES_BIT)); 13272d53139fSDavid Mosberger /* clear reset: */ 13282d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_USBCTL, 0); 13292d53139fSDavid Mosberger timeout = 1000; 13302d53139fSDavid Mosberger while (1) { 13312d53139fSDavid Mosberger if (spi_rd8(hcd, MAX3421_REG_USBIRQ) 13322d53139fSDavid Mosberger & BIT(MAX3421_USBIRQ_OSCOKIRQ_BIT)) 13332d53139fSDavid Mosberger break; 13342d53139fSDavid Mosberger if (--timeout < 0) { 13352d53139fSDavid Mosberger dev_err(&spi->dev, 13362d53139fSDavid Mosberger "timed out waiting for oscillator OK signal"); 13372d53139fSDavid Mosberger return 1; 13382d53139fSDavid Mosberger } 13392d53139fSDavid Mosberger cond_resched(); 13402d53139fSDavid Mosberger } 13412d53139fSDavid Mosberger 13422d53139fSDavid Mosberger /* 13432d53139fSDavid Mosberger * Turn on host mode, automatic generation of SOF packets, and 13442d53139fSDavid Mosberger * enable pull-down registers on DM/DP: 13452d53139fSDavid Mosberger */ 13462d53139fSDavid Mosberger max3421_hcd->mode = (BIT(MAX3421_MODE_HOST_BIT) | 13472d53139fSDavid Mosberger BIT(MAX3421_MODE_SOFKAENAB_BIT) | 13482d53139fSDavid Mosberger BIT(MAX3421_MODE_DMPULLDN_BIT) | 13492d53139fSDavid Mosberger BIT(MAX3421_MODE_DPPULLDN_BIT)); 13502d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); 13512d53139fSDavid Mosberger 13522d53139fSDavid Mosberger /* reset frame-number: */ 13532d53139fSDavid Mosberger max3421_hcd->frame_number = USB_MAX_FRAME_NUMBER; 13542d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_FRMRST_BIT)); 13552d53139fSDavid Mosberger 13562d53139fSDavid Mosberger /* sample the state of the D+ and D- lines */ 13572d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_SAMPLEBUS_BIT)); 13582d53139fSDavid Mosberger max3421_detect_conn(hcd); 13592d53139fSDavid Mosberger 13602d53139fSDavid Mosberger /* enable frame, connection-detected, and bus-event interrupts: */ 13612d53139fSDavid Mosberger max3421_hcd->hien = (BIT(MAX3421_HI_FRAME_BIT) | 13622d53139fSDavid Mosberger BIT(MAX3421_HI_CONDET_BIT) | 13632d53139fSDavid Mosberger BIT(MAX3421_HI_BUSEVENT_BIT)); 13642d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); 13652d53139fSDavid Mosberger 13662d53139fSDavid Mosberger /* enable interrupts: */ 13672d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_CPUCTL, BIT(MAX3421_CPUCTL_IE_BIT)); 13682d53139fSDavid Mosberger return 1; 13692d53139fSDavid Mosberger } 13702d53139fSDavid Mosberger 13712d53139fSDavid Mosberger static int 13722d53139fSDavid Mosberger max3421_urb_done(struct usb_hcd *hcd) 13732d53139fSDavid Mosberger { 13742d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 13752d53139fSDavid Mosberger unsigned long flags; 13762d53139fSDavid Mosberger struct urb *urb; 13772d53139fSDavid Mosberger int status; 13782d53139fSDavid Mosberger 13792d53139fSDavid Mosberger status = max3421_hcd->urb_done; 13802d53139fSDavid Mosberger max3421_hcd->urb_done = 0; 13812d53139fSDavid Mosberger if (status > 0) 13822d53139fSDavid Mosberger status = 0; 13832d53139fSDavid Mosberger urb = max3421_hcd->curr_urb; 13842d53139fSDavid Mosberger if (urb) { 13852d53139fSDavid Mosberger max3421_hcd->curr_urb = NULL; 13862d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 13872d53139fSDavid Mosberger usb_hcd_unlink_urb_from_ep(hcd, urb); 13882d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 13892d53139fSDavid Mosberger 13902d53139fSDavid Mosberger /* must be called without the HCD spinlock: */ 13912d53139fSDavid Mosberger usb_hcd_giveback_urb(hcd, urb, status); 13922d53139fSDavid Mosberger } 13932d53139fSDavid Mosberger return 1; 13942d53139fSDavid Mosberger } 13952d53139fSDavid Mosberger 13962d53139fSDavid Mosberger static int 13972d53139fSDavid Mosberger max3421_spi_thread(void *dev_id) 13982d53139fSDavid Mosberger { 13992d53139fSDavid Mosberger struct usb_hcd *hcd = dev_id; 14002d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 14012d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 14022d53139fSDavid Mosberger int i, i_worked = 1; 14032d53139fSDavid Mosberger 14042d53139fSDavid Mosberger /* set full-duplex SPI mode, low-active interrupt pin: */ 14052d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_PINCTL, 14062d53139fSDavid Mosberger (BIT(MAX3421_PINCTL_FDUPSPI_BIT) | /* full-duplex */ 14072d53139fSDavid Mosberger BIT(MAX3421_PINCTL_INTLEVEL_BIT))); /* low-active irq */ 14082d53139fSDavid Mosberger 14092d53139fSDavid Mosberger while (!kthread_should_stop()) { 14102d53139fSDavid Mosberger max3421_hcd->rev = spi_rd8(hcd, MAX3421_REG_REVISION); 14112d53139fSDavid Mosberger if (max3421_hcd->rev == 0x12 || max3421_hcd->rev == 0x13) 14122d53139fSDavid Mosberger break; 14132d53139fSDavid Mosberger dev_err(&spi->dev, "bad rev 0x%02x", max3421_hcd->rev); 14142d53139fSDavid Mosberger msleep(10000); 14152d53139fSDavid Mosberger } 14162d53139fSDavid Mosberger dev_info(&spi->dev, "rev 0x%x, SPI clk %dHz, bpw %u, irq %d\n", 14172d53139fSDavid Mosberger max3421_hcd->rev, spi->max_speed_hz, spi->bits_per_word, 14182d53139fSDavid Mosberger spi->irq); 14192d53139fSDavid Mosberger 14202d53139fSDavid Mosberger while (!kthread_should_stop()) { 14212d53139fSDavid Mosberger if (!i_worked) { 14222d53139fSDavid Mosberger /* 14232d53139fSDavid Mosberger * We'll be waiting for wakeups from the hard 14242d53139fSDavid Mosberger * interrupt handler, so now is a good time to 14252d53139fSDavid Mosberger * sync our hien with the chip: 14262d53139fSDavid Mosberger */ 14272d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); 14282d53139fSDavid Mosberger 14292d53139fSDavid Mosberger set_current_state(TASK_INTERRUPTIBLE); 14302eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(ENABLE_IRQ, &max3421_hcd->todo)) 14312d53139fSDavid Mosberger enable_irq(spi->irq); 14322d53139fSDavid Mosberger schedule(); 14332d53139fSDavid Mosberger __set_current_state(TASK_RUNNING); 14342d53139fSDavid Mosberger } 14352d53139fSDavid Mosberger 14362d53139fSDavid Mosberger i_worked = 0; 14372d53139fSDavid Mosberger 14382d53139fSDavid Mosberger if (max3421_hcd->urb_done) 14392d53139fSDavid Mosberger i_worked |= max3421_urb_done(hcd); 14402d53139fSDavid Mosberger else if (max3421_handle_irqs(hcd)) 14412d53139fSDavid Mosberger i_worked = 1; 14422d53139fSDavid Mosberger else if (!max3421_hcd->curr_urb) 14432d53139fSDavid Mosberger i_worked |= max3421_select_and_start_urb(hcd); 14442d53139fSDavid Mosberger 14452eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(RESET_HCD, &max3421_hcd->todo)) 14462d53139fSDavid Mosberger /* reset the HCD: */ 14472d53139fSDavid Mosberger i_worked |= max3421_reset_hcd(hcd); 14482eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(RESET_PORT, &max3421_hcd->todo)) { 14492d53139fSDavid Mosberger /* perform a USB bus reset: */ 14502d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, 14512d53139fSDavid Mosberger BIT(MAX3421_HCTL_BUSRST_BIT)); 14522d53139fSDavid Mosberger i_worked = 1; 14532d53139fSDavid Mosberger } 14542eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(CHECK_UNLINK, &max3421_hcd->todo)) 14552d53139fSDavid Mosberger i_worked |= max3421_check_unlink(hcd); 14562eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(IOPIN_UPDATE, &max3421_hcd->todo)) { 14572d53139fSDavid Mosberger /* 14582d53139fSDavid Mosberger * IOPINS1/IOPINS2 do not auto-increment, so we can't 14592d53139fSDavid Mosberger * use spi_wr_buf(). 14602d53139fSDavid Mosberger */ 14612d53139fSDavid Mosberger for (i = 0; i < ARRAY_SIZE(max3421_hcd->iopins); ++i) { 14622d53139fSDavid Mosberger u8 val = spi_rd8(hcd, MAX3421_REG_IOPINS1); 14632d53139fSDavid Mosberger 14642d53139fSDavid Mosberger val = ((val & 0xf0) | 14652d53139fSDavid Mosberger (max3421_hcd->iopins[i] & 0x0f)); 14662d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val); 14672d53139fSDavid Mosberger max3421_hcd->iopins[i] = val; 14682d53139fSDavid Mosberger } 14692d53139fSDavid Mosberger i_worked = 1; 14702d53139fSDavid Mosberger } 14712d53139fSDavid Mosberger } 14722d53139fSDavid Mosberger set_current_state(TASK_RUNNING); 14732d53139fSDavid Mosberger dev_info(&spi->dev, "SPI thread exiting"); 14742d53139fSDavid Mosberger return 0; 14752d53139fSDavid Mosberger } 14762d53139fSDavid Mosberger 14772d53139fSDavid Mosberger static int 14782d53139fSDavid Mosberger max3421_reset_port(struct usb_hcd *hcd) 14792d53139fSDavid Mosberger { 14802d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 14812d53139fSDavid Mosberger 14822d53139fSDavid Mosberger max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | 14832d53139fSDavid Mosberger USB_PORT_STAT_LOW_SPEED); 1484a2b63cb5SDavid Mosberger-Tang max3421_hcd->port_status |= USB_PORT_STAT_RESET; 14852eb5dbddSDavid Mosberger-Tang set_bit(RESET_PORT, &max3421_hcd->todo); 14862d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 14872d53139fSDavid Mosberger return 0; 14882d53139fSDavid Mosberger } 14892d53139fSDavid Mosberger 14902d53139fSDavid Mosberger static int 14912d53139fSDavid Mosberger max3421_reset(struct usb_hcd *hcd) 14922d53139fSDavid Mosberger { 14932d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 14942d53139fSDavid Mosberger 14952d53139fSDavid Mosberger hcd->self.sg_tablesize = 0; 14962d53139fSDavid Mosberger hcd->speed = HCD_USB2; 14972d53139fSDavid Mosberger hcd->self.root_hub->speed = USB_SPEED_FULL; 14982eb5dbddSDavid Mosberger-Tang set_bit(RESET_HCD, &max3421_hcd->todo); 14992d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 15002d53139fSDavid Mosberger return 0; 15012d53139fSDavid Mosberger } 15022d53139fSDavid Mosberger 15032d53139fSDavid Mosberger static int 15042d53139fSDavid Mosberger max3421_start(struct usb_hcd *hcd) 15052d53139fSDavid Mosberger { 15062d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15072d53139fSDavid Mosberger 15082d53139fSDavid Mosberger spin_lock_init(&max3421_hcd->lock); 15092d53139fSDavid Mosberger max3421_hcd->rh_state = MAX3421_RH_RUNNING; 15102d53139fSDavid Mosberger 15112d53139fSDavid Mosberger INIT_LIST_HEAD(&max3421_hcd->ep_list); 15122d53139fSDavid Mosberger 15132d53139fSDavid Mosberger hcd->power_budget = POWER_BUDGET; 15142d53139fSDavid Mosberger hcd->state = HC_STATE_RUNNING; 15152d53139fSDavid Mosberger hcd->uses_new_polling = 1; 15162d53139fSDavid Mosberger return 0; 15172d53139fSDavid Mosberger } 15182d53139fSDavid Mosberger 15192d53139fSDavid Mosberger static void 15202d53139fSDavid Mosberger max3421_stop(struct usb_hcd *hcd) 15212d53139fSDavid Mosberger { 15222d53139fSDavid Mosberger } 15232d53139fSDavid Mosberger 15242d53139fSDavid Mosberger static int 15252d53139fSDavid Mosberger max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) 15262d53139fSDavid Mosberger { 15272d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 15282d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15292d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 15302d53139fSDavid Mosberger unsigned long flags; 15312d53139fSDavid Mosberger int retval; 15322d53139fSDavid Mosberger 15332d53139fSDavid Mosberger switch (usb_pipetype(urb->pipe)) { 15342d53139fSDavid Mosberger case PIPE_INTERRUPT: 15352d53139fSDavid Mosberger case PIPE_ISOCHRONOUS: 15362d53139fSDavid Mosberger if (urb->interval < 0) { 15372d53139fSDavid Mosberger dev_err(&spi->dev, 15382d53139fSDavid Mosberger "%s: interval=%d for intr-/iso-pipe; expected > 0\n", 15392d53139fSDavid Mosberger __func__, urb->interval); 15402d53139fSDavid Mosberger return -EINVAL; 15412d53139fSDavid Mosberger } 15422d53139fSDavid Mosberger default: 15432d53139fSDavid Mosberger break; 15442d53139fSDavid Mosberger } 15452d53139fSDavid Mosberger 15462d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 15472d53139fSDavid Mosberger 15482d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 15492d53139fSDavid Mosberger if (!max3421_ep) { 15502d53139fSDavid Mosberger /* gets freed in max3421_endpoint_disable: */ 15516c0f3695SAlexey Khoroshilov max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC); 155200c5aa17SDavid Mosberger-Tang if (!max3421_ep) { 155300c5aa17SDavid Mosberger-Tang retval = -ENOMEM; 155400c5aa17SDavid Mosberger-Tang goto out; 155500c5aa17SDavid Mosberger-Tang } 15562d53139fSDavid Mosberger max3421_ep->ep = urb->ep; 15572d53139fSDavid Mosberger max3421_ep->last_active = max3421_hcd->frame_number; 15582d53139fSDavid Mosberger urb->ep->hcpriv = max3421_ep; 15592d53139fSDavid Mosberger 15602d53139fSDavid Mosberger list_add_tail(&max3421_ep->ep_list, &max3421_hcd->ep_list); 15612d53139fSDavid Mosberger } 15622d53139fSDavid Mosberger 15632d53139fSDavid Mosberger retval = usb_hcd_link_urb_to_ep(hcd, urb); 15642d53139fSDavid Mosberger if (retval == 0) { 15652d53139fSDavid Mosberger /* Since we added to the queue, restart scheduling: */ 15662d53139fSDavid Mosberger max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; 15672d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 15682d53139fSDavid Mosberger } 15692d53139fSDavid Mosberger 157000c5aa17SDavid Mosberger-Tang out: 15712d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 15722d53139fSDavid Mosberger return retval; 15732d53139fSDavid Mosberger } 15742d53139fSDavid Mosberger 15752d53139fSDavid Mosberger static int 15762d53139fSDavid Mosberger max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 15772d53139fSDavid Mosberger { 15782d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15792d53139fSDavid Mosberger unsigned long flags; 15802d53139fSDavid Mosberger int retval; 15812d53139fSDavid Mosberger 15822d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 15832d53139fSDavid Mosberger 15842d53139fSDavid Mosberger /* 15852d53139fSDavid Mosberger * This will set urb->unlinked which in turn causes the entry 15862d53139fSDavid Mosberger * to be dropped at the next opportunity. 15872d53139fSDavid Mosberger */ 15882d53139fSDavid Mosberger retval = usb_hcd_check_unlink_urb(hcd, urb, status); 15892d53139fSDavid Mosberger if (retval == 0) { 15902eb5dbddSDavid Mosberger-Tang set_bit(CHECK_UNLINK, &max3421_hcd->todo); 15912d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 15922d53139fSDavid Mosberger } 15932d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 15942d53139fSDavid Mosberger return retval; 15952d53139fSDavid Mosberger } 15962d53139fSDavid Mosberger 15972d53139fSDavid Mosberger static void 15982d53139fSDavid Mosberger max3421_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) 15992d53139fSDavid Mosberger { 16002d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16012d53139fSDavid Mosberger unsigned long flags; 16022d53139fSDavid Mosberger 16032d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 16042d53139fSDavid Mosberger 16052d53139fSDavid Mosberger if (ep->hcpriv) { 16062d53139fSDavid Mosberger struct max3421_ep *max3421_ep = ep->hcpriv; 16072d53139fSDavid Mosberger 16082d53139fSDavid Mosberger /* remove myself from the ep_list: */ 16092d53139fSDavid Mosberger if (!list_empty(&max3421_ep->ep_list)) 16102d53139fSDavid Mosberger list_del(&max3421_ep->ep_list); 16112d53139fSDavid Mosberger kfree(max3421_ep); 16122d53139fSDavid Mosberger ep->hcpriv = NULL; 16132d53139fSDavid Mosberger } 16142d53139fSDavid Mosberger 16152d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 16162d53139fSDavid Mosberger } 16172d53139fSDavid Mosberger 16182d53139fSDavid Mosberger static int 16192d53139fSDavid Mosberger max3421_get_frame_number(struct usb_hcd *hcd) 16202d53139fSDavid Mosberger { 16212d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16222d53139fSDavid Mosberger return max3421_hcd->frame_number; 16232d53139fSDavid Mosberger } 16242d53139fSDavid Mosberger 16252d53139fSDavid Mosberger /* 16262d53139fSDavid Mosberger * Should return a non-zero value when any port is undergoing a resume 16272d53139fSDavid Mosberger * transition while the root hub is suspended. 16282d53139fSDavid Mosberger */ 16292d53139fSDavid Mosberger static int 16302d53139fSDavid Mosberger max3421_hub_status_data(struct usb_hcd *hcd, char *buf) 16312d53139fSDavid Mosberger { 16322d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16332d53139fSDavid Mosberger unsigned long flags; 16342d53139fSDavid Mosberger int retval = 0; 16352d53139fSDavid Mosberger 16362d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 16372d53139fSDavid Mosberger if (!HCD_HW_ACCESSIBLE(hcd)) 16382d53139fSDavid Mosberger goto done; 16392d53139fSDavid Mosberger 16402d53139fSDavid Mosberger *buf = 0; 16412d53139fSDavid Mosberger if ((max3421_hcd->port_status & PORT_C_MASK) != 0) { 16422d53139fSDavid Mosberger *buf = (1 << 1); /* a hub over-current condition exists */ 16432d53139fSDavid Mosberger dev_dbg(hcd->self.controller, 16442d53139fSDavid Mosberger "port status 0x%08x has changes\n", 16452d53139fSDavid Mosberger max3421_hcd->port_status); 16462d53139fSDavid Mosberger retval = 1; 16472d53139fSDavid Mosberger if (max3421_hcd->rh_state == MAX3421_RH_SUSPENDED) 16482d53139fSDavid Mosberger usb_hcd_resume_root_hub(hcd); 16492d53139fSDavid Mosberger } 16502d53139fSDavid Mosberger done: 16512d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 16522d53139fSDavid Mosberger return retval; 16532d53139fSDavid Mosberger } 16542d53139fSDavid Mosberger 16552d53139fSDavid Mosberger static inline void 16562d53139fSDavid Mosberger hub_descriptor(struct usb_hub_descriptor *desc) 16572d53139fSDavid Mosberger { 16582d53139fSDavid Mosberger memset(desc, 0, sizeof(*desc)); 16592d53139fSDavid Mosberger /* 16602d53139fSDavid Mosberger * See Table 11-13: Hub Descriptor in USB 2.0 spec. 16612d53139fSDavid Mosberger */ 1662e3d02e0eSSergei Shtylyov desc->bDescriptorType = USB_DT_HUB; /* hub descriptor */ 16632d53139fSDavid Mosberger desc->bDescLength = 9; 16642e48c466SSergei Shtylyov desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | 16652e48c466SSergei Shtylyov HUB_CHAR_COMMON_OCPM); 16662d53139fSDavid Mosberger desc->bNbrPorts = 1; 16672d53139fSDavid Mosberger } 16682d53139fSDavid Mosberger 16692d53139fSDavid Mosberger /* 16702d53139fSDavid Mosberger * Set the MAX3421E general-purpose output with number PIN_NUMBER to 16712d53139fSDavid Mosberger * VALUE (0 or 1). PIN_NUMBER may be in the range from 1-8. For 16722d53139fSDavid Mosberger * any other value, this function acts as a no-op. 16732d53139fSDavid Mosberger */ 16742d53139fSDavid Mosberger static void 16752d53139fSDavid Mosberger max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) 16762d53139fSDavid Mosberger { 16772d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16782d53139fSDavid Mosberger u8 mask, idx; 16792d53139fSDavid Mosberger 16802d53139fSDavid Mosberger --pin_number; 16812d53139fSDavid Mosberger if (pin_number > 7) 16822d53139fSDavid Mosberger return; 16832d53139fSDavid Mosberger 16842d53139fSDavid Mosberger mask = 1u << pin_number; 16852d53139fSDavid Mosberger idx = pin_number / 4; 16862d53139fSDavid Mosberger 16872d53139fSDavid Mosberger if (value) 16882d53139fSDavid Mosberger max3421_hcd->iopins[idx] |= mask; 16892d53139fSDavid Mosberger else 16902d53139fSDavid Mosberger max3421_hcd->iopins[idx] &= ~mask; 16912eb5dbddSDavid Mosberger-Tang set_bit(IOPIN_UPDATE, &max3421_hcd->todo); 16922d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 16932d53139fSDavid Mosberger } 16942d53139fSDavid Mosberger 16952d53139fSDavid Mosberger static int 16962d53139fSDavid Mosberger max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index, 16972d53139fSDavid Mosberger char *buf, u16 length) 16982d53139fSDavid Mosberger { 16992d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 17002d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 17012d53139fSDavid Mosberger struct max3421_hcd_platform_data *pdata; 17022d53139fSDavid Mosberger unsigned long flags; 17032d53139fSDavid Mosberger int retval = 0; 17042d53139fSDavid Mosberger 17052d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 17062d53139fSDavid Mosberger 17072d53139fSDavid Mosberger pdata = spi->dev.platform_data; 17082d53139fSDavid Mosberger 17092d53139fSDavid Mosberger switch (type_req) { 17102d53139fSDavid Mosberger case ClearHubFeature: 17112d53139fSDavid Mosberger break; 17122d53139fSDavid Mosberger case ClearPortFeature: 17132d53139fSDavid Mosberger switch (value) { 17142d53139fSDavid Mosberger case USB_PORT_FEAT_SUSPEND: 17152d53139fSDavid Mosberger break; 17162d53139fSDavid Mosberger case USB_PORT_FEAT_POWER: 17172d53139fSDavid Mosberger dev_dbg(hcd->self.controller, "power-off\n"); 17184055e5e5SDavid Mosberger-Tang max3421_gpout_set_value(hcd, pdata->vbus_gpout, 17194055e5e5SDavid Mosberger-Tang !pdata->vbus_active_level); 17202d53139fSDavid Mosberger /* FALLS THROUGH */ 17212d53139fSDavid Mosberger default: 17222d53139fSDavid Mosberger max3421_hcd->port_status &= ~(1 << value); 17232d53139fSDavid Mosberger } 17242d53139fSDavid Mosberger break; 17252d53139fSDavid Mosberger case GetHubDescriptor: 17262d53139fSDavid Mosberger hub_descriptor((struct usb_hub_descriptor *) buf); 17272d53139fSDavid Mosberger break; 17282d53139fSDavid Mosberger 17292d53139fSDavid Mosberger case DeviceRequest | USB_REQ_GET_DESCRIPTOR: 17302d53139fSDavid Mosberger case GetPortErrorCount: 17312d53139fSDavid Mosberger case SetHubDepth: 17322d53139fSDavid Mosberger /* USB3 only */ 17332d53139fSDavid Mosberger goto error; 17342d53139fSDavid Mosberger 17352d53139fSDavid Mosberger case GetHubStatus: 17362d53139fSDavid Mosberger *(__le32 *) buf = cpu_to_le32(0); 17372d53139fSDavid Mosberger break; 17382d53139fSDavid Mosberger 17392d53139fSDavid Mosberger case GetPortStatus: 17402d53139fSDavid Mosberger if (index != 1) { 17412d53139fSDavid Mosberger retval = -EPIPE; 17422d53139fSDavid Mosberger goto error; 17432d53139fSDavid Mosberger } 17442d53139fSDavid Mosberger ((__le16 *) buf)[0] = cpu_to_le16(max3421_hcd->port_status); 17452d53139fSDavid Mosberger ((__le16 *) buf)[1] = 17462d53139fSDavid Mosberger cpu_to_le16(max3421_hcd->port_status >> 16); 17472d53139fSDavid Mosberger break; 17482d53139fSDavid Mosberger 17492d53139fSDavid Mosberger case SetHubFeature: 17502d53139fSDavid Mosberger retval = -EPIPE; 17512d53139fSDavid Mosberger break; 17522d53139fSDavid Mosberger 17532d53139fSDavid Mosberger case SetPortFeature: 17542d53139fSDavid Mosberger switch (value) { 17552d53139fSDavid Mosberger case USB_PORT_FEAT_LINK_STATE: 17562d53139fSDavid Mosberger case USB_PORT_FEAT_U1_TIMEOUT: 17572d53139fSDavid Mosberger case USB_PORT_FEAT_U2_TIMEOUT: 17582d53139fSDavid Mosberger case USB_PORT_FEAT_BH_PORT_RESET: 17592d53139fSDavid Mosberger goto error; 17602d53139fSDavid Mosberger case USB_PORT_FEAT_SUSPEND: 17612d53139fSDavid Mosberger if (max3421_hcd->active) 17622d53139fSDavid Mosberger max3421_hcd->port_status |= 17632d53139fSDavid Mosberger USB_PORT_STAT_SUSPEND; 17642d53139fSDavid Mosberger break; 17652d53139fSDavid Mosberger case USB_PORT_FEAT_POWER: 17662d53139fSDavid Mosberger dev_dbg(hcd->self.controller, "power-on\n"); 17672d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_POWER; 17684055e5e5SDavid Mosberger-Tang max3421_gpout_set_value(hcd, pdata->vbus_gpout, 17694055e5e5SDavid Mosberger-Tang pdata->vbus_active_level); 17702d53139fSDavid Mosberger break; 17712d53139fSDavid Mosberger case USB_PORT_FEAT_RESET: 17722d53139fSDavid Mosberger max3421_reset_port(hcd); 17732d53139fSDavid Mosberger /* FALLS THROUGH */ 17742d53139fSDavid Mosberger default: 17752d53139fSDavid Mosberger if ((max3421_hcd->port_status & USB_PORT_STAT_POWER) 17762d53139fSDavid Mosberger != 0) 17772d53139fSDavid Mosberger max3421_hcd->port_status |= (1 << value); 17782d53139fSDavid Mosberger } 17792d53139fSDavid Mosberger break; 17802d53139fSDavid Mosberger 17812d53139fSDavid Mosberger default: 17822d53139fSDavid Mosberger dev_dbg(hcd->self.controller, 17832d53139fSDavid Mosberger "hub control req%04x v%04x i%04x l%d\n", 17842d53139fSDavid Mosberger type_req, value, index, length); 17852d53139fSDavid Mosberger error: /* "protocol stall" on error */ 17862d53139fSDavid Mosberger retval = -EPIPE; 17872d53139fSDavid Mosberger } 17882d53139fSDavid Mosberger 17892d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 17902d53139fSDavid Mosberger return retval; 17912d53139fSDavid Mosberger } 17922d53139fSDavid Mosberger 17932d53139fSDavid Mosberger static int 17942d53139fSDavid Mosberger max3421_bus_suspend(struct usb_hcd *hcd) 17952d53139fSDavid Mosberger { 17962d53139fSDavid Mosberger return -1; 17972d53139fSDavid Mosberger } 17982d53139fSDavid Mosberger 17992d53139fSDavid Mosberger static int 18002d53139fSDavid Mosberger max3421_bus_resume(struct usb_hcd *hcd) 18012d53139fSDavid Mosberger { 18022d53139fSDavid Mosberger return -1; 18032d53139fSDavid Mosberger } 18042d53139fSDavid Mosberger 18052d53139fSDavid Mosberger /* 18062d53139fSDavid Mosberger * The SPI driver already takes care of DMA-mapping/unmapping, so no 18072d53139fSDavid Mosberger * reason to do it twice. 18082d53139fSDavid Mosberger */ 18092d53139fSDavid Mosberger static int 18102d53139fSDavid Mosberger max3421_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) 18112d53139fSDavid Mosberger { 18122d53139fSDavid Mosberger return 0; 18132d53139fSDavid Mosberger } 18142d53139fSDavid Mosberger 18152d53139fSDavid Mosberger static void 18162d53139fSDavid Mosberger max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) 18172d53139fSDavid Mosberger { 18182d53139fSDavid Mosberger } 18192d53139fSDavid Mosberger 18202d53139fSDavid Mosberger static struct hc_driver max3421_hcd_desc = { 18212d53139fSDavid Mosberger .description = "max3421", 18222d53139fSDavid Mosberger .product_desc = DRIVER_DESC, 18232d53139fSDavid Mosberger .hcd_priv_size = sizeof(struct max3421_hcd), 18242d53139fSDavid Mosberger .flags = HCD_USB11, 18252d53139fSDavid Mosberger .reset = max3421_reset, 18262d53139fSDavid Mosberger .start = max3421_start, 18272d53139fSDavid Mosberger .stop = max3421_stop, 18282d53139fSDavid Mosberger .get_frame_number = max3421_get_frame_number, 18292d53139fSDavid Mosberger .urb_enqueue = max3421_urb_enqueue, 18302d53139fSDavid Mosberger .urb_dequeue = max3421_urb_dequeue, 18312d53139fSDavid Mosberger .map_urb_for_dma = max3421_map_urb_for_dma, 18322d53139fSDavid Mosberger .unmap_urb_for_dma = max3421_unmap_urb_for_dma, 18332d53139fSDavid Mosberger .endpoint_disable = max3421_endpoint_disable, 18342d53139fSDavid Mosberger .hub_status_data = max3421_hub_status_data, 18352d53139fSDavid Mosberger .hub_control = max3421_hub_control, 18362d53139fSDavid Mosberger .bus_suspend = max3421_bus_suspend, 18372d53139fSDavid Mosberger .bus_resume = max3421_bus_resume, 18382d53139fSDavid Mosberger }; 18392d53139fSDavid Mosberger 18402d53139fSDavid Mosberger static int 18412d53139fSDavid Mosberger max3421_probe(struct spi_device *spi) 18422d53139fSDavid Mosberger { 18432d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd; 184405dfa5c9SDavid Mosberger-Tang struct usb_hcd *hcd = NULL; 184505dfa5c9SDavid Mosberger-Tang int retval = -ENOMEM; 18462d53139fSDavid Mosberger 18472d53139fSDavid Mosberger if (spi_setup(spi) < 0) { 18482d53139fSDavid Mosberger dev_err(&spi->dev, "Unable to setup SPI bus"); 18492d53139fSDavid Mosberger return -EFAULT; 18502d53139fSDavid Mosberger } 18512d53139fSDavid Mosberger 18522d53139fSDavid Mosberger hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev, 18532d53139fSDavid Mosberger dev_name(&spi->dev)); 18542d53139fSDavid Mosberger if (!hcd) { 18552d53139fSDavid Mosberger dev_err(&spi->dev, "failed to create HCD structure\n"); 185605dfa5c9SDavid Mosberger-Tang goto error; 18572d53139fSDavid Mosberger } 18582d53139fSDavid Mosberger set_bit(HCD_FLAG_POLL_RH, &hcd->flags); 18592d53139fSDavid Mosberger max3421_hcd = hcd_to_max3421(hcd); 18602d53139fSDavid Mosberger max3421_hcd->next = max3421_hcd_list; 18612d53139fSDavid Mosberger max3421_hcd_list = max3421_hcd; 18622d53139fSDavid Mosberger INIT_LIST_HEAD(&max3421_hcd->ep_list); 18632d53139fSDavid Mosberger 186405dfa5c9SDavid Mosberger-Tang max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); 186505dfa5c9SDavid Mosberger-Tang if (!max3421_hcd->tx) { 186605dfa5c9SDavid Mosberger-Tang dev_err(&spi->dev, "failed to kmalloc tx buffer\n"); 186705dfa5c9SDavid Mosberger-Tang goto error; 186805dfa5c9SDavid Mosberger-Tang } 186905dfa5c9SDavid Mosberger-Tang max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); 187005dfa5c9SDavid Mosberger-Tang if (!max3421_hcd->rx) { 187105dfa5c9SDavid Mosberger-Tang dev_err(&spi->dev, "failed to kmalloc rx buffer\n"); 187205dfa5c9SDavid Mosberger-Tang goto error; 187305dfa5c9SDavid Mosberger-Tang } 187405dfa5c9SDavid Mosberger-Tang 18752d53139fSDavid Mosberger max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, 18762d53139fSDavid Mosberger "max3421_spi_thread"); 18772d53139fSDavid Mosberger if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) { 18782d53139fSDavid Mosberger dev_err(&spi->dev, 18792d53139fSDavid Mosberger "failed to create SPI thread (out of memory)\n"); 188005dfa5c9SDavid Mosberger-Tang goto error; 18812d53139fSDavid Mosberger } 18822d53139fSDavid Mosberger 18832d53139fSDavid Mosberger retval = usb_add_hcd(hcd, 0, 0); 18842d53139fSDavid Mosberger if (retval) { 18852d53139fSDavid Mosberger dev_err(&spi->dev, "failed to add HCD\n"); 188605dfa5c9SDavid Mosberger-Tang goto error; 18872d53139fSDavid Mosberger } 18882d53139fSDavid Mosberger 18892d53139fSDavid Mosberger retval = request_irq(spi->irq, max3421_irq_handler, 18902d53139fSDavid Mosberger IRQF_TRIGGER_LOW, "max3421", hcd); 18912d53139fSDavid Mosberger if (retval < 0) { 18922d53139fSDavid Mosberger dev_err(&spi->dev, "failed to request irq %d\n", spi->irq); 189305dfa5c9SDavid Mosberger-Tang goto error; 18942d53139fSDavid Mosberger } 18952d53139fSDavid Mosberger return 0; 189605dfa5c9SDavid Mosberger-Tang 189705dfa5c9SDavid Mosberger-Tang error: 189805dfa5c9SDavid Mosberger-Tang if (hcd) { 189905dfa5c9SDavid Mosberger-Tang kfree(max3421_hcd->tx); 190005dfa5c9SDavid Mosberger-Tang kfree(max3421_hcd->rx); 190105dfa5c9SDavid Mosberger-Tang if (max3421_hcd->spi_thread) 190205dfa5c9SDavid Mosberger-Tang kthread_stop(max3421_hcd->spi_thread); 190305dfa5c9SDavid Mosberger-Tang usb_put_hcd(hcd); 190405dfa5c9SDavid Mosberger-Tang } 190505dfa5c9SDavid Mosberger-Tang return retval; 19062d53139fSDavid Mosberger } 19072d53139fSDavid Mosberger 19082d53139fSDavid Mosberger static int 19092d53139fSDavid Mosberger max3421_remove(struct spi_device *spi) 19102d53139fSDavid Mosberger { 19112d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = NULL, **prev; 19122d53139fSDavid Mosberger struct usb_hcd *hcd = NULL; 19132d53139fSDavid Mosberger unsigned long flags; 19142d53139fSDavid Mosberger 19152d53139fSDavid Mosberger for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { 19162d53139fSDavid Mosberger max3421_hcd = *prev; 19172d53139fSDavid Mosberger hcd = max3421_to_hcd(max3421_hcd); 19182d53139fSDavid Mosberger if (hcd->self.controller == &spi->dev) 19192d53139fSDavid Mosberger break; 19202d53139fSDavid Mosberger } 19212d53139fSDavid Mosberger if (!max3421_hcd) { 19222d53139fSDavid Mosberger dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", 19232d53139fSDavid Mosberger spi); 19242d53139fSDavid Mosberger return -ENODEV; 19252d53139fSDavid Mosberger } 19262d53139fSDavid Mosberger 19272d53139fSDavid Mosberger usb_remove_hcd(hcd); 19282d53139fSDavid Mosberger 19292d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 19302d53139fSDavid Mosberger 19312d53139fSDavid Mosberger kthread_stop(max3421_hcd->spi_thread); 19322d53139fSDavid Mosberger *prev = max3421_hcd->next; 19332d53139fSDavid Mosberger 19342d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 19352d53139fSDavid Mosberger 19362d53139fSDavid Mosberger free_irq(spi->irq, hcd); 19372d53139fSDavid Mosberger 19382d53139fSDavid Mosberger usb_put_hcd(hcd); 19392d53139fSDavid Mosberger return 0; 19402d53139fSDavid Mosberger } 19412d53139fSDavid Mosberger 19422d53139fSDavid Mosberger static struct spi_driver max3421_driver = { 19432d53139fSDavid Mosberger .probe = max3421_probe, 19442d53139fSDavid Mosberger .remove = max3421_remove, 19452d53139fSDavid Mosberger .driver = { 19462d53139fSDavid Mosberger .name = "max3421-hcd", 19472d53139fSDavid Mosberger .owner = THIS_MODULE, 19482d53139fSDavid Mosberger }, 19492d53139fSDavid Mosberger }; 19502d53139fSDavid Mosberger 19517df45d5fSSachin Kamat module_spi_driver(max3421_driver); 19522d53139fSDavid Mosberger 19532d53139fSDavid Mosberger MODULE_DESCRIPTION(DRIVER_DESC); 19542d53139fSDavid Mosberger MODULE_AUTHOR("David Mosberger <davidm@egauge.net>"); 19552d53139fSDavid Mosberger MODULE_LICENSE("GPL"); 1956