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