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