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 struct max3421_hcd *next; 1292d53139fSDavid Mosberger 1302d53139fSDavid Mosberger enum max3421_rh_state rh_state; 1312d53139fSDavid Mosberger /* lower 16 bits contain port status, upper 16 bits the change mask: */ 1322d53139fSDavid Mosberger u32 port_status; 1332d53139fSDavid Mosberger 1342d53139fSDavid Mosberger unsigned active:1; 1352d53139fSDavid Mosberger 1362d53139fSDavid Mosberger struct list_head ep_list; /* list of EP's with work */ 1372d53139fSDavid Mosberger 1382d53139fSDavid Mosberger /* 1392d53139fSDavid Mosberger * The following are owned by spi_thread (may be accessed by 1402d53139fSDavid Mosberger * SPI-thread without acquiring the HCD lock: 1412d53139fSDavid Mosberger */ 1422d53139fSDavid Mosberger u8 rev; /* chip revision */ 1432d53139fSDavid Mosberger u16 frame_number; 1442d53139fSDavid Mosberger /* 14505dfa5c9SDavid Mosberger-Tang * kmalloc'd buffers guaranteed to be in separate (DMA) 14605dfa5c9SDavid Mosberger-Tang * cache-lines: 14705dfa5c9SDavid Mosberger-Tang */ 14805dfa5c9SDavid Mosberger-Tang struct max3421_dma_buf *tx; 14905dfa5c9SDavid Mosberger-Tang struct max3421_dma_buf *rx; 15005dfa5c9SDavid Mosberger-Tang /* 1512d53139fSDavid Mosberger * URB we're currently processing. Must not be reset to NULL 1522d53139fSDavid Mosberger * unless MAX3421E chip is idle: 1532d53139fSDavid Mosberger */ 1542d53139fSDavid Mosberger struct urb *curr_urb; 1552d53139fSDavid Mosberger enum scheduling_pass sched_pass; 1562d53139fSDavid Mosberger struct usb_device *loaded_dev; /* dev that's loaded into the chip */ 1572d53139fSDavid Mosberger int loaded_epnum; /* epnum whose toggles are loaded */ 1582d53139fSDavid Mosberger int urb_done; /* > 0 -> no errors, < 0: errno */ 1592d53139fSDavid Mosberger size_t curr_len; 1602d53139fSDavid Mosberger u8 hien; 1612d53139fSDavid Mosberger u8 mode; 1622d53139fSDavid Mosberger u8 iopins[2]; 1632eb5dbddSDavid Mosberger-Tang unsigned long todo; 1642d53139fSDavid Mosberger #ifdef DEBUG 1652d53139fSDavid Mosberger unsigned long err_stat[16]; 1662d53139fSDavid Mosberger #endif 1672d53139fSDavid Mosberger }; 1682d53139fSDavid Mosberger 1692d53139fSDavid Mosberger struct max3421_ep { 1702d53139fSDavid Mosberger struct usb_host_endpoint *ep; 1712d53139fSDavid Mosberger struct list_head ep_list; 1722d53139fSDavid Mosberger u32 naks; 1732d53139fSDavid Mosberger u16 last_active; /* frame # this ep was last active */ 1742d53139fSDavid Mosberger enum pkt_state pkt_state; 1752d53139fSDavid Mosberger u8 retries; 1762d53139fSDavid Mosberger u8 retransmit; /* packet needs retransmission */ 1772d53139fSDavid Mosberger }; 1782d53139fSDavid Mosberger 1792d53139fSDavid Mosberger static struct max3421_hcd *max3421_hcd_list; 1802d53139fSDavid Mosberger 1812d53139fSDavid Mosberger #define MAX3421_FIFO_SIZE 64 1822d53139fSDavid Mosberger 1832d53139fSDavid Mosberger #define MAX3421_SPI_DIR_RD 0 /* read register from MAX3421 */ 1842d53139fSDavid Mosberger #define MAX3421_SPI_DIR_WR 1 /* write register to MAX3421 */ 1852d53139fSDavid Mosberger 1862d53139fSDavid Mosberger /* SPI commands: */ 1872d53139fSDavid Mosberger #define MAX3421_SPI_DIR_SHIFT 1 1882d53139fSDavid Mosberger #define MAX3421_SPI_REG_SHIFT 3 1892d53139fSDavid Mosberger 1902d53139fSDavid Mosberger #define MAX3421_REG_RCVFIFO 1 1912d53139fSDavid Mosberger #define MAX3421_REG_SNDFIFO 2 1922d53139fSDavid Mosberger #define MAX3421_REG_SUDFIFO 4 1932d53139fSDavid Mosberger #define MAX3421_REG_RCVBC 6 1942d53139fSDavid Mosberger #define MAX3421_REG_SNDBC 7 1952d53139fSDavid Mosberger #define MAX3421_REG_USBIRQ 13 1962d53139fSDavid Mosberger #define MAX3421_REG_USBIEN 14 1972d53139fSDavid Mosberger #define MAX3421_REG_USBCTL 15 1982d53139fSDavid Mosberger #define MAX3421_REG_CPUCTL 16 1992d53139fSDavid Mosberger #define MAX3421_REG_PINCTL 17 2002d53139fSDavid Mosberger #define MAX3421_REG_REVISION 18 2012d53139fSDavid Mosberger #define MAX3421_REG_IOPINS1 20 2022d53139fSDavid Mosberger #define MAX3421_REG_IOPINS2 21 2032d53139fSDavid Mosberger #define MAX3421_REG_GPINIRQ 22 2042d53139fSDavid Mosberger #define MAX3421_REG_GPINIEN 23 2052d53139fSDavid Mosberger #define MAX3421_REG_GPINPOL 24 2062d53139fSDavid Mosberger #define MAX3421_REG_HIRQ 25 2072d53139fSDavid Mosberger #define MAX3421_REG_HIEN 26 2082d53139fSDavid Mosberger #define MAX3421_REG_MODE 27 2092d53139fSDavid Mosberger #define MAX3421_REG_PERADDR 28 2102d53139fSDavid Mosberger #define MAX3421_REG_HCTL 29 2112d53139fSDavid Mosberger #define MAX3421_REG_HXFR 30 2122d53139fSDavid Mosberger #define MAX3421_REG_HRSL 31 2132d53139fSDavid Mosberger 2142d53139fSDavid Mosberger enum { 2152d53139fSDavid Mosberger MAX3421_USBIRQ_OSCOKIRQ_BIT = 0, 2162d53139fSDavid Mosberger MAX3421_USBIRQ_NOVBUSIRQ_BIT = 5, 2172d53139fSDavid Mosberger MAX3421_USBIRQ_VBUSIRQ_BIT 2182d53139fSDavid Mosberger }; 2192d53139fSDavid Mosberger 2202d53139fSDavid Mosberger enum { 2212d53139fSDavid Mosberger MAX3421_CPUCTL_IE_BIT = 0, 2222d53139fSDavid Mosberger MAX3421_CPUCTL_PULSEWID0_BIT = 6, 2232d53139fSDavid Mosberger MAX3421_CPUCTL_PULSEWID1_BIT 2242d53139fSDavid Mosberger }; 2252d53139fSDavid Mosberger 2262d53139fSDavid Mosberger enum { 2272d53139fSDavid Mosberger MAX3421_USBCTL_PWRDOWN_BIT = 4, 2282d53139fSDavid Mosberger MAX3421_USBCTL_CHIPRES_BIT 2292d53139fSDavid Mosberger }; 2302d53139fSDavid Mosberger 2312d53139fSDavid Mosberger enum { 2322d53139fSDavid Mosberger MAX3421_PINCTL_GPXA_BIT = 0, 2332d53139fSDavid Mosberger MAX3421_PINCTL_GPXB_BIT, 2342d53139fSDavid Mosberger MAX3421_PINCTL_POSINT_BIT, 2352d53139fSDavid Mosberger MAX3421_PINCTL_INTLEVEL_BIT, 2362d53139fSDavid Mosberger MAX3421_PINCTL_FDUPSPI_BIT, 2372d53139fSDavid Mosberger MAX3421_PINCTL_EP0INAK_BIT, 2382d53139fSDavid Mosberger MAX3421_PINCTL_EP2INAK_BIT, 2392d53139fSDavid Mosberger MAX3421_PINCTL_EP3INAK_BIT, 2402d53139fSDavid Mosberger }; 2412d53139fSDavid Mosberger 2422d53139fSDavid Mosberger enum { 2432d53139fSDavid Mosberger MAX3421_HI_BUSEVENT_BIT = 0, /* bus-reset/-resume */ 2442d53139fSDavid Mosberger MAX3421_HI_RWU_BIT, /* remote wakeup */ 2452d53139fSDavid Mosberger MAX3421_HI_RCVDAV_BIT, /* receive FIFO data available */ 2462d53139fSDavid Mosberger MAX3421_HI_SNDBAV_BIT, /* send buffer available */ 2472d53139fSDavid Mosberger MAX3421_HI_SUSDN_BIT, /* suspend operation done */ 2482d53139fSDavid Mosberger MAX3421_HI_CONDET_BIT, /* peripheral connect/disconnect */ 2492d53139fSDavid Mosberger MAX3421_HI_FRAME_BIT, /* frame generator */ 2502d53139fSDavid Mosberger MAX3421_HI_HXFRDN_BIT, /* host transfer done */ 2512d53139fSDavid Mosberger }; 2522d53139fSDavid Mosberger 2532d53139fSDavid Mosberger enum { 2542d53139fSDavid Mosberger MAX3421_HCTL_BUSRST_BIT = 0, 2552d53139fSDavid Mosberger MAX3421_HCTL_FRMRST_BIT, 2562d53139fSDavid Mosberger MAX3421_HCTL_SAMPLEBUS_BIT, 2572d53139fSDavid Mosberger MAX3421_HCTL_SIGRSM_BIT, 2582d53139fSDavid Mosberger MAX3421_HCTL_RCVTOG0_BIT, 2592d53139fSDavid Mosberger MAX3421_HCTL_RCVTOG1_BIT, 2602d53139fSDavid Mosberger MAX3421_HCTL_SNDTOG0_BIT, 2612d53139fSDavid Mosberger MAX3421_HCTL_SNDTOG1_BIT 2622d53139fSDavid Mosberger }; 2632d53139fSDavid Mosberger 2642d53139fSDavid Mosberger enum { 2652d53139fSDavid Mosberger MAX3421_MODE_HOST_BIT = 0, 2662d53139fSDavid Mosberger MAX3421_MODE_LOWSPEED_BIT, 2672d53139fSDavid Mosberger MAX3421_MODE_HUBPRE_BIT, 2682d53139fSDavid Mosberger MAX3421_MODE_SOFKAENAB_BIT, 2692d53139fSDavid Mosberger MAX3421_MODE_SEPIRQ_BIT, 2702d53139fSDavid Mosberger MAX3421_MODE_DELAYISO_BIT, 2712d53139fSDavid Mosberger MAX3421_MODE_DMPULLDN_BIT, 2722d53139fSDavid Mosberger MAX3421_MODE_DPPULLDN_BIT 2732d53139fSDavid Mosberger }; 2742d53139fSDavid Mosberger 2752d53139fSDavid Mosberger enum { 2762d53139fSDavid Mosberger MAX3421_HRSL_OK = 0, 2772d53139fSDavid Mosberger MAX3421_HRSL_BUSY, 2782d53139fSDavid Mosberger MAX3421_HRSL_BADREQ, 2792d53139fSDavid Mosberger MAX3421_HRSL_UNDEF, 2802d53139fSDavid Mosberger MAX3421_HRSL_NAK, 2812d53139fSDavid Mosberger MAX3421_HRSL_STALL, 2822d53139fSDavid Mosberger MAX3421_HRSL_TOGERR, 2832d53139fSDavid Mosberger MAX3421_HRSL_WRONGPID, 2842d53139fSDavid Mosberger MAX3421_HRSL_BADBC, 2852d53139fSDavid Mosberger MAX3421_HRSL_PIDERR, 2862d53139fSDavid Mosberger MAX3421_HRSL_PKTERR, 2872d53139fSDavid Mosberger MAX3421_HRSL_CRCERR, 2882d53139fSDavid Mosberger MAX3421_HRSL_KERR, 2892d53139fSDavid Mosberger MAX3421_HRSL_JERR, 2902d53139fSDavid Mosberger MAX3421_HRSL_TIMEOUT, 2912d53139fSDavid Mosberger MAX3421_HRSL_BABBLE, 2922d53139fSDavid Mosberger MAX3421_HRSL_RESULT_MASK = 0xf, 2932d53139fSDavid Mosberger MAX3421_HRSL_RCVTOGRD_BIT = 4, 2942d53139fSDavid Mosberger MAX3421_HRSL_SNDTOGRD_BIT, 2952d53139fSDavid Mosberger MAX3421_HRSL_KSTATUS_BIT, 2962d53139fSDavid Mosberger MAX3421_HRSL_JSTATUS_BIT 2972d53139fSDavid Mosberger }; 2982d53139fSDavid Mosberger 2992d53139fSDavid Mosberger /* Return same error-codes as ohci.h:cc_to_error: */ 3002d53139fSDavid Mosberger static const int hrsl_to_error[] = { 3012d53139fSDavid Mosberger [MAX3421_HRSL_OK] = 0, 3022d53139fSDavid Mosberger [MAX3421_HRSL_BUSY] = -EINVAL, 3032d53139fSDavid Mosberger [MAX3421_HRSL_BADREQ] = -EINVAL, 3042d53139fSDavid Mosberger [MAX3421_HRSL_UNDEF] = -EINVAL, 3052d53139fSDavid Mosberger [MAX3421_HRSL_NAK] = -EAGAIN, 3062d53139fSDavid Mosberger [MAX3421_HRSL_STALL] = -EPIPE, 3072d53139fSDavid Mosberger [MAX3421_HRSL_TOGERR] = -EILSEQ, 3082d53139fSDavid Mosberger [MAX3421_HRSL_WRONGPID] = -EPROTO, 3092d53139fSDavid Mosberger [MAX3421_HRSL_BADBC] = -EREMOTEIO, 3102d53139fSDavid Mosberger [MAX3421_HRSL_PIDERR] = -EPROTO, 3112d53139fSDavid Mosberger [MAX3421_HRSL_PKTERR] = -EPROTO, 3122d53139fSDavid Mosberger [MAX3421_HRSL_CRCERR] = -EILSEQ, 3132d53139fSDavid Mosberger [MAX3421_HRSL_KERR] = -EIO, 3142d53139fSDavid Mosberger [MAX3421_HRSL_JERR] = -EIO, 3152d53139fSDavid Mosberger [MAX3421_HRSL_TIMEOUT] = -ETIME, 3162d53139fSDavid Mosberger [MAX3421_HRSL_BABBLE] = -EOVERFLOW 3172d53139fSDavid Mosberger }; 3182d53139fSDavid Mosberger 3192d53139fSDavid Mosberger /* 320ffeb1e9eSAlexander A. Klimov * See https://www.beyondlogic.org/usbnutshell/usb4.shtml#Control for a 3212d53139fSDavid Mosberger * reasonable overview of how control transfers use the the IN/OUT 3222d53139fSDavid Mosberger * tokens. 3232d53139fSDavid Mosberger */ 3242d53139fSDavid Mosberger #define MAX3421_HXFR_BULK_IN(ep) (0x00 | (ep)) /* bulk or interrupt */ 3252d53139fSDavid Mosberger #define MAX3421_HXFR_SETUP 0x10 3262d53139fSDavid Mosberger #define MAX3421_HXFR_BULK_OUT(ep) (0x20 | (ep)) /* bulk or interrupt */ 3272d53139fSDavid Mosberger #define MAX3421_HXFR_ISO_IN(ep) (0x40 | (ep)) 3282d53139fSDavid Mosberger #define MAX3421_HXFR_ISO_OUT(ep) (0x60 | (ep)) 3292d53139fSDavid Mosberger #define MAX3421_HXFR_HS_IN 0x80 /* handshake in */ 3302d53139fSDavid Mosberger #define MAX3421_HXFR_HS_OUT 0xa0 /* handshake out */ 3312d53139fSDavid Mosberger 3322d53139fSDavid Mosberger #define field(val, bit) ((val) << (bit)) 3332d53139fSDavid Mosberger 3342d53139fSDavid Mosberger static inline s16 3352d53139fSDavid Mosberger frame_diff(u16 left, u16 right) 3362d53139fSDavid Mosberger { 3372d53139fSDavid Mosberger return ((unsigned) (left - right)) % (USB_MAX_FRAME_NUMBER + 1); 3382d53139fSDavid Mosberger } 3392d53139fSDavid Mosberger 3402d53139fSDavid Mosberger static inline struct max3421_hcd * 3412d53139fSDavid Mosberger hcd_to_max3421(struct usb_hcd *hcd) 3422d53139fSDavid Mosberger { 3432d53139fSDavid Mosberger return (struct max3421_hcd *) hcd->hcd_priv; 3442d53139fSDavid Mosberger } 3452d53139fSDavid Mosberger 3462d53139fSDavid Mosberger static inline struct usb_hcd * 3472d53139fSDavid Mosberger max3421_to_hcd(struct max3421_hcd *max3421_hcd) 3482d53139fSDavid Mosberger { 3492d53139fSDavid Mosberger return container_of((void *) max3421_hcd, struct usb_hcd, hcd_priv); 3502d53139fSDavid Mosberger } 3512d53139fSDavid Mosberger 3522d53139fSDavid Mosberger static u8 3532d53139fSDavid Mosberger spi_rd8(struct usb_hcd *hcd, unsigned int reg) 3542d53139fSDavid Mosberger { 35505dfa5c9SDavid Mosberger-Tang struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 3562d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 3572d53139fSDavid Mosberger struct spi_transfer transfer; 3582d53139fSDavid Mosberger struct spi_message msg; 3592d53139fSDavid Mosberger 3602d53139fSDavid Mosberger memset(&transfer, 0, sizeof(transfer)); 3612d53139fSDavid Mosberger 3622d53139fSDavid Mosberger spi_message_init(&msg); 3632d53139fSDavid Mosberger 36405dfa5c9SDavid Mosberger-Tang max3421_hcd->tx->data[0] = 36505dfa5c9SDavid Mosberger-Tang (field(reg, MAX3421_SPI_REG_SHIFT) | 3662d53139fSDavid Mosberger field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); 3672d53139fSDavid Mosberger 36805dfa5c9SDavid Mosberger-Tang transfer.tx_buf = max3421_hcd->tx->data; 36905dfa5c9SDavid Mosberger-Tang transfer.rx_buf = max3421_hcd->rx->data; 3702d53139fSDavid Mosberger transfer.len = 2; 3712d53139fSDavid Mosberger 3722d53139fSDavid Mosberger spi_message_add_tail(&transfer, &msg); 3732d53139fSDavid Mosberger spi_sync(spi, &msg); 3742d53139fSDavid Mosberger 37505dfa5c9SDavid Mosberger-Tang return max3421_hcd->rx->data[1]; 3762d53139fSDavid Mosberger } 3772d53139fSDavid Mosberger 3782d53139fSDavid Mosberger static void 3792d53139fSDavid Mosberger spi_wr8(struct usb_hcd *hcd, unsigned int reg, u8 val) 3802d53139fSDavid Mosberger { 3812d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 38205dfa5c9SDavid Mosberger-Tang struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 3832d53139fSDavid Mosberger struct spi_transfer transfer; 3842d53139fSDavid Mosberger struct spi_message msg; 3852d53139fSDavid Mosberger 3862d53139fSDavid Mosberger memset(&transfer, 0, sizeof(transfer)); 3872d53139fSDavid Mosberger 3882d53139fSDavid Mosberger spi_message_init(&msg); 3892d53139fSDavid Mosberger 39005dfa5c9SDavid Mosberger-Tang max3421_hcd->tx->data[0] = 39105dfa5c9SDavid Mosberger-Tang (field(reg, MAX3421_SPI_REG_SHIFT) | 3922d53139fSDavid Mosberger field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); 39305dfa5c9SDavid Mosberger-Tang max3421_hcd->tx->data[1] = val; 3942d53139fSDavid Mosberger 39505dfa5c9SDavid Mosberger-Tang transfer.tx_buf = max3421_hcd->tx->data; 3962d53139fSDavid Mosberger transfer.len = 2; 3972d53139fSDavid Mosberger 3982d53139fSDavid Mosberger spi_message_add_tail(&transfer, &msg); 3992d53139fSDavid Mosberger spi_sync(spi, &msg); 4002d53139fSDavid Mosberger } 4012d53139fSDavid Mosberger 4022d53139fSDavid Mosberger static void 4032d53139fSDavid Mosberger spi_rd_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) 4042d53139fSDavid Mosberger { 4052d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 40605dfa5c9SDavid Mosberger-Tang struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 4072d53139fSDavid Mosberger struct spi_transfer transfer[2]; 4082d53139fSDavid Mosberger struct spi_message msg; 4092d53139fSDavid Mosberger 4102d53139fSDavid Mosberger memset(transfer, 0, sizeof(transfer)); 4112d53139fSDavid Mosberger 4122d53139fSDavid Mosberger spi_message_init(&msg); 4132d53139fSDavid Mosberger 41405dfa5c9SDavid Mosberger-Tang max3421_hcd->tx->data[0] = 41505dfa5c9SDavid Mosberger-Tang (field(reg, MAX3421_SPI_REG_SHIFT) | 4162d53139fSDavid Mosberger field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); 41705dfa5c9SDavid Mosberger-Tang transfer[0].tx_buf = max3421_hcd->tx->data; 4182d53139fSDavid Mosberger transfer[0].len = 1; 4192d53139fSDavid Mosberger 4202d53139fSDavid Mosberger transfer[1].rx_buf = buf; 4212d53139fSDavid Mosberger transfer[1].len = len; 4222d53139fSDavid Mosberger 4232d53139fSDavid Mosberger spi_message_add_tail(&transfer[0], &msg); 4242d53139fSDavid Mosberger spi_message_add_tail(&transfer[1], &msg); 4252d53139fSDavid Mosberger spi_sync(spi, &msg); 4262d53139fSDavid Mosberger } 4272d53139fSDavid Mosberger 4282d53139fSDavid Mosberger static void 4292d53139fSDavid Mosberger spi_wr_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) 4302d53139fSDavid Mosberger { 4312d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 43205dfa5c9SDavid Mosberger-Tang struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 4332d53139fSDavid Mosberger struct spi_transfer transfer[2]; 4342d53139fSDavid Mosberger struct spi_message msg; 4352d53139fSDavid Mosberger 4362d53139fSDavid Mosberger memset(transfer, 0, sizeof(transfer)); 4372d53139fSDavid Mosberger 4382d53139fSDavid Mosberger spi_message_init(&msg); 4392d53139fSDavid Mosberger 44005dfa5c9SDavid Mosberger-Tang max3421_hcd->tx->data[0] = 44105dfa5c9SDavid Mosberger-Tang (field(reg, MAX3421_SPI_REG_SHIFT) | 4422d53139fSDavid Mosberger field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); 4432d53139fSDavid Mosberger 44405dfa5c9SDavid Mosberger-Tang transfer[0].tx_buf = max3421_hcd->tx->data; 4452d53139fSDavid Mosberger transfer[0].len = 1; 4462d53139fSDavid Mosberger 4472d53139fSDavid Mosberger transfer[1].tx_buf = buf; 4482d53139fSDavid Mosberger transfer[1].len = len; 4492d53139fSDavid Mosberger 4502d53139fSDavid Mosberger spi_message_add_tail(&transfer[0], &msg); 4512d53139fSDavid Mosberger spi_message_add_tail(&transfer[1], &msg); 4522d53139fSDavid Mosberger spi_sync(spi, &msg); 4532d53139fSDavid Mosberger } 4542d53139fSDavid Mosberger 4552d53139fSDavid Mosberger /* 4562d53139fSDavid Mosberger * Figure out the correct setting for the LOWSPEED and HUBPRE mode 4572d53139fSDavid Mosberger * bits. The HUBPRE bit needs to be set when MAX3421E operates at 4582d53139fSDavid Mosberger * full speed, but it's talking to a low-speed device (i.e., through a 4592d53139fSDavid Mosberger * hub). Setting that bit ensures that every low-speed packet is 4602d53139fSDavid Mosberger * preceded by a full-speed PRE PID. Possible configurations: 4612d53139fSDavid Mosberger * 4622d53139fSDavid Mosberger * Hub speed: Device speed: => LOWSPEED bit: HUBPRE bit: 4632d53139fSDavid Mosberger * FULL FULL => 0 0 4642d53139fSDavid Mosberger * FULL LOW => 1 1 4652d53139fSDavid Mosberger * LOW LOW => 1 0 4662d53139fSDavid Mosberger * LOW FULL => 1 0 4672d53139fSDavid Mosberger */ 4682d53139fSDavid Mosberger static void 4692d53139fSDavid Mosberger max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev) 4702d53139fSDavid Mosberger { 4712d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 4722d53139fSDavid Mosberger u8 mode_lowspeed, mode_hubpre, mode = max3421_hcd->mode; 4732d53139fSDavid Mosberger 4742d53139fSDavid Mosberger mode_lowspeed = BIT(MAX3421_MODE_LOWSPEED_BIT); 4752d53139fSDavid Mosberger mode_hubpre = BIT(MAX3421_MODE_HUBPRE_BIT); 4762d53139fSDavid Mosberger if (max3421_hcd->port_status & USB_PORT_STAT_LOW_SPEED) { 4772d53139fSDavid Mosberger mode |= mode_lowspeed; 4782d53139fSDavid Mosberger mode &= ~mode_hubpre; 4792d53139fSDavid Mosberger } else if (dev->speed == USB_SPEED_LOW) { 4802d53139fSDavid Mosberger mode |= mode_lowspeed | mode_hubpre; 4812d53139fSDavid Mosberger } else { 4822d53139fSDavid Mosberger mode &= ~(mode_lowspeed | mode_hubpre); 4832d53139fSDavid Mosberger } 4842d53139fSDavid Mosberger if (mode != max3421_hcd->mode) { 4852d53139fSDavid Mosberger max3421_hcd->mode = mode; 4862d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); 4872d53139fSDavid Mosberger } 4882d53139fSDavid Mosberger 4892d53139fSDavid Mosberger } 4902d53139fSDavid Mosberger 4912d53139fSDavid Mosberger /* 4922d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 4932d53139fSDavid Mosberger */ 4942d53139fSDavid Mosberger static void 4952d53139fSDavid Mosberger max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, 4962d53139fSDavid Mosberger int force_toggles) 4972d53139fSDavid Mosberger { 4982d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 4992d53139fSDavid Mosberger int old_epnum, same_ep, rcvtog, sndtog; 5002d53139fSDavid Mosberger struct usb_device *old_dev; 5012d53139fSDavid Mosberger u8 hctl; 5022d53139fSDavid Mosberger 5032d53139fSDavid Mosberger old_dev = max3421_hcd->loaded_dev; 5042d53139fSDavid Mosberger old_epnum = max3421_hcd->loaded_epnum; 5052d53139fSDavid Mosberger 5062d53139fSDavid Mosberger same_ep = (dev == old_dev && epnum == old_epnum); 5072d53139fSDavid Mosberger if (same_ep && !force_toggles) 5082d53139fSDavid Mosberger return; 5092d53139fSDavid Mosberger 5102d53139fSDavid Mosberger if (old_dev && !same_ep) { 5112d53139fSDavid Mosberger /* save the old end-points toggles: */ 5122d53139fSDavid Mosberger u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); 5132d53139fSDavid Mosberger 5142d53139fSDavid Mosberger rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; 5152d53139fSDavid Mosberger sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; 5162d53139fSDavid Mosberger 5172d53139fSDavid Mosberger /* no locking: HCD (i.e., we) own toggles, don't we? */ 5182d53139fSDavid Mosberger usb_settoggle(old_dev, old_epnum, 0, rcvtog); 5192d53139fSDavid Mosberger usb_settoggle(old_dev, old_epnum, 1, sndtog); 5202d53139fSDavid Mosberger } 5212d53139fSDavid Mosberger /* setup new endpoint's toggle bits: */ 5222d53139fSDavid Mosberger rcvtog = usb_gettoggle(dev, epnum, 0); 5232d53139fSDavid Mosberger sndtog = usb_gettoggle(dev, epnum, 1); 5242d53139fSDavid Mosberger hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | 5252d53139fSDavid Mosberger BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); 5262d53139fSDavid Mosberger 5272d53139fSDavid Mosberger max3421_hcd->loaded_epnum = epnum; 5282d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, hctl); 5292d53139fSDavid Mosberger 5302d53139fSDavid Mosberger /* 5312d53139fSDavid Mosberger * Note: devnum for one and the same device can change during 5322d53139fSDavid Mosberger * address-assignment so it's best to just always load the 5332d53139fSDavid Mosberger * address whenever the end-point changed/was forced. 5342d53139fSDavid Mosberger */ 5352d53139fSDavid Mosberger max3421_hcd->loaded_dev = dev; 5362d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum); 5372d53139fSDavid Mosberger } 5382d53139fSDavid Mosberger 5392d53139fSDavid Mosberger static int 5402d53139fSDavid Mosberger max3421_ctrl_setup(struct usb_hcd *hcd, struct urb *urb) 5412d53139fSDavid Mosberger { 5422d53139fSDavid Mosberger spi_wr_buf(hcd, MAX3421_REG_SUDFIFO, urb->setup_packet, 8); 5432d53139fSDavid Mosberger return MAX3421_HXFR_SETUP; 5442d53139fSDavid Mosberger } 5452d53139fSDavid Mosberger 5462d53139fSDavid Mosberger static int 5472d53139fSDavid Mosberger max3421_transfer_in(struct usb_hcd *hcd, struct urb *urb) 5482d53139fSDavid Mosberger { 5492d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 5502d53139fSDavid Mosberger int epnum = usb_pipeendpoint(urb->pipe); 5512d53139fSDavid Mosberger 5522d53139fSDavid Mosberger max3421_hcd->curr_len = 0; 5532d53139fSDavid Mosberger max3421_hcd->hien |= BIT(MAX3421_HI_RCVDAV_BIT); 5542d53139fSDavid Mosberger return MAX3421_HXFR_BULK_IN(epnum); 5552d53139fSDavid Mosberger } 5562d53139fSDavid Mosberger 5572d53139fSDavid Mosberger static int 5582d53139fSDavid Mosberger max3421_transfer_out(struct usb_hcd *hcd, struct urb *urb, int fast_retransmit) 5592d53139fSDavid Mosberger { 5602d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 5612d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 5622d53139fSDavid Mosberger int epnum = usb_pipeendpoint(urb->pipe); 5632d53139fSDavid Mosberger u32 max_packet; 5642d53139fSDavid Mosberger void *src; 5652d53139fSDavid Mosberger 5662d53139fSDavid Mosberger src = urb->transfer_buffer + urb->actual_length; 5672d53139fSDavid Mosberger 5682d53139fSDavid Mosberger if (fast_retransmit) { 5692d53139fSDavid Mosberger if (max3421_hcd->rev == 0x12) { 5702d53139fSDavid Mosberger /* work around rev 0x12 bug: */ 5712d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDBC, 0); 5722d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDFIFO, ((u8 *) src)[0]); 5732d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len); 5742d53139fSDavid Mosberger } 5752d53139fSDavid Mosberger return MAX3421_HXFR_BULK_OUT(epnum); 5762d53139fSDavid Mosberger } 5772d53139fSDavid Mosberger 5782d53139fSDavid Mosberger max_packet = usb_maxpacket(urb->dev, urb->pipe, 1); 5792d53139fSDavid Mosberger 5802d53139fSDavid Mosberger if (max_packet > MAX3421_FIFO_SIZE) { 5812d53139fSDavid Mosberger /* 5822d53139fSDavid Mosberger * We do not support isochronous transfers at this 5832d53139fSDavid Mosberger * time. 5842d53139fSDavid Mosberger */ 5852d53139fSDavid Mosberger dev_err(&spi->dev, 5862d53139fSDavid Mosberger "%s: packet-size of %u too big (limit is %u bytes)", 5872d53139fSDavid Mosberger __func__, max_packet, MAX3421_FIFO_SIZE); 5882d53139fSDavid Mosberger max3421_hcd->urb_done = -EMSGSIZE; 5892d53139fSDavid Mosberger return -EMSGSIZE; 5902d53139fSDavid Mosberger } 5912d53139fSDavid Mosberger max3421_hcd->curr_len = min((urb->transfer_buffer_length - 5922d53139fSDavid Mosberger urb->actual_length), max_packet); 5932d53139fSDavid Mosberger 5942d53139fSDavid Mosberger spi_wr_buf(hcd, MAX3421_REG_SNDFIFO, src, max3421_hcd->curr_len); 5952d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len); 5962d53139fSDavid Mosberger return MAX3421_HXFR_BULK_OUT(epnum); 5972d53139fSDavid Mosberger } 5982d53139fSDavid Mosberger 5992d53139fSDavid Mosberger /* 6002d53139fSDavid Mosberger * Issue the next host-transfer command. 6012d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 6022d53139fSDavid Mosberger */ 6032d53139fSDavid Mosberger static void 6042d53139fSDavid Mosberger max3421_next_transfer(struct usb_hcd *hcd, int fast_retransmit) 6052d53139fSDavid Mosberger { 6062d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 6072d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 608f9da25c7SDavid Mosberger-Tang struct max3421_ep *max3421_ep; 6092d53139fSDavid Mosberger int cmd = -EINVAL; 6102d53139fSDavid Mosberger 6112d53139fSDavid Mosberger if (!urb) 6122d53139fSDavid Mosberger return; /* nothing to do */ 6132d53139fSDavid Mosberger 614f9da25c7SDavid Mosberger-Tang max3421_ep = urb->ep->hcpriv; 615f9da25c7SDavid Mosberger-Tang 6162d53139fSDavid Mosberger switch (max3421_ep->pkt_state) { 6172d53139fSDavid Mosberger case PKT_STATE_SETUP: 6182d53139fSDavid Mosberger cmd = max3421_ctrl_setup(hcd, urb); 6192d53139fSDavid Mosberger break; 6202d53139fSDavid Mosberger 6212d53139fSDavid Mosberger case PKT_STATE_TRANSFER: 6222d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 6232d53139fSDavid Mosberger cmd = max3421_transfer_in(hcd, urb); 6242d53139fSDavid Mosberger else 6252d53139fSDavid Mosberger cmd = max3421_transfer_out(hcd, urb, fast_retransmit); 6262d53139fSDavid Mosberger break; 6272d53139fSDavid Mosberger 6282d53139fSDavid Mosberger case PKT_STATE_TERMINATE: 6292d53139fSDavid Mosberger /* 6302d53139fSDavid Mosberger * IN transfers are terminated with HS_OUT token, 6312d53139fSDavid Mosberger * OUT transfers with HS_IN: 6322d53139fSDavid Mosberger */ 6332d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 6342d53139fSDavid Mosberger cmd = MAX3421_HXFR_HS_OUT; 6352d53139fSDavid Mosberger else 6362d53139fSDavid Mosberger cmd = MAX3421_HXFR_HS_IN; 6372d53139fSDavid Mosberger break; 6382d53139fSDavid Mosberger } 6392d53139fSDavid Mosberger 6402d53139fSDavid Mosberger if (cmd < 0) 6412d53139fSDavid Mosberger return; 6422d53139fSDavid Mosberger 6432d53139fSDavid Mosberger /* issue the command and wait for host-xfer-done interrupt: */ 6442d53139fSDavid Mosberger 6452d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HXFR, cmd); 6462d53139fSDavid Mosberger max3421_hcd->hien |= BIT(MAX3421_HI_HXFRDN_BIT); 6472d53139fSDavid Mosberger } 6482d53139fSDavid Mosberger 6492d53139fSDavid Mosberger /* 6502d53139fSDavid Mosberger * Find the next URB to process and start its execution. 6512d53139fSDavid Mosberger * 6522d53139fSDavid Mosberger * At this time, we do not anticipate ever connecting a USB hub to the 6532d53139fSDavid Mosberger * MAX3421 chip, so at most USB device can be connected and we can use 6542d53139fSDavid Mosberger * a simplistic scheduler: at the start of a frame, schedule all 6552d53139fSDavid Mosberger * periodic transfers. Once that is done, use the remainder of the 6562d53139fSDavid Mosberger * frame to process non-periodic (bulk & control) transfers. 6572d53139fSDavid Mosberger * 6582d53139fSDavid Mosberger * Preconditions: 6592d53139fSDavid Mosberger * o Caller must NOT hold HCD spinlock. 6602d53139fSDavid Mosberger * o max3421_hcd->curr_urb MUST BE NULL. 6612d53139fSDavid Mosberger * o MAX3421E chip must be idle. 6622d53139fSDavid Mosberger */ 6632d53139fSDavid Mosberger static int 6642d53139fSDavid Mosberger max3421_select_and_start_urb(struct usb_hcd *hcd) 6652d53139fSDavid Mosberger { 6662d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 6672d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 6682d53139fSDavid Mosberger struct urb *urb, *curr_urb = NULL; 6692d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 6702d53139fSDavid Mosberger int epnum, force_toggles = 0; 6712d53139fSDavid Mosberger struct usb_host_endpoint *ep; 6722d53139fSDavid Mosberger struct list_head *pos; 6732d53139fSDavid Mosberger unsigned long flags; 6742d53139fSDavid Mosberger 6752d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 6762d53139fSDavid Mosberger 6772d53139fSDavid Mosberger for (; 6782d53139fSDavid Mosberger max3421_hcd->sched_pass < SCHED_PASS_DONE; 6792d53139fSDavid Mosberger ++max3421_hcd->sched_pass) 6802d53139fSDavid Mosberger list_for_each(pos, &max3421_hcd->ep_list) { 6812d53139fSDavid Mosberger urb = NULL; 6822d53139fSDavid Mosberger max3421_ep = container_of(pos, struct max3421_ep, 6832d53139fSDavid Mosberger ep_list); 6842d53139fSDavid Mosberger ep = max3421_ep->ep; 6852d53139fSDavid Mosberger 6862d53139fSDavid Mosberger switch (usb_endpoint_type(&ep->desc)) { 6872d53139fSDavid Mosberger case USB_ENDPOINT_XFER_ISOC: 6882d53139fSDavid Mosberger case USB_ENDPOINT_XFER_INT: 6892d53139fSDavid Mosberger if (max3421_hcd->sched_pass != 6902d53139fSDavid Mosberger SCHED_PASS_PERIODIC) 6912d53139fSDavid Mosberger continue; 6922d53139fSDavid Mosberger break; 6932d53139fSDavid Mosberger 6942d53139fSDavid Mosberger case USB_ENDPOINT_XFER_CONTROL: 6952d53139fSDavid Mosberger case USB_ENDPOINT_XFER_BULK: 6962d53139fSDavid Mosberger if (max3421_hcd->sched_pass != 6972d53139fSDavid Mosberger SCHED_PASS_NON_PERIODIC) 6982d53139fSDavid Mosberger continue; 6992d53139fSDavid Mosberger break; 7002d53139fSDavid Mosberger } 7012d53139fSDavid Mosberger 7022d53139fSDavid Mosberger if (list_empty(&ep->urb_list)) 7032d53139fSDavid Mosberger continue; /* nothing to do */ 7042d53139fSDavid Mosberger urb = list_first_entry(&ep->urb_list, struct urb, 7052d53139fSDavid Mosberger urb_list); 7062d53139fSDavid Mosberger if (urb->unlinked) { 7072d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", 7082d53139fSDavid Mosberger __func__, urb, urb->unlinked); 7092d53139fSDavid Mosberger max3421_hcd->curr_urb = urb; 7102d53139fSDavid Mosberger max3421_hcd->urb_done = 1; 7112d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, 7122d53139fSDavid Mosberger flags); 7132d53139fSDavid Mosberger return 1; 7142d53139fSDavid Mosberger } 7152d53139fSDavid Mosberger 7162d53139fSDavid Mosberger switch (usb_endpoint_type(&ep->desc)) { 7172d53139fSDavid Mosberger case USB_ENDPOINT_XFER_CONTROL: 7182d53139fSDavid Mosberger /* 7192d53139fSDavid Mosberger * Allow one control transaction per 7202d53139fSDavid Mosberger * frame per endpoint: 7212d53139fSDavid Mosberger */ 7222d53139fSDavid Mosberger if (frame_diff(max3421_ep->last_active, 7232d53139fSDavid Mosberger max3421_hcd->frame_number) == 0) 7242d53139fSDavid Mosberger continue; 7252d53139fSDavid Mosberger break; 7262d53139fSDavid Mosberger 7272d53139fSDavid Mosberger case USB_ENDPOINT_XFER_BULK: 7282d53139fSDavid Mosberger if (max3421_ep->retransmit 7292d53139fSDavid Mosberger && (frame_diff(max3421_ep->last_active, 7302d53139fSDavid Mosberger max3421_hcd->frame_number) 7312d53139fSDavid Mosberger == 0)) 7322d53139fSDavid Mosberger /* 7332d53139fSDavid Mosberger * We already tried this EP 7342d53139fSDavid Mosberger * during this frame and got a 7352d53139fSDavid Mosberger * NAK or error; wait for next frame 7362d53139fSDavid Mosberger */ 7372d53139fSDavid Mosberger continue; 7382d53139fSDavid Mosberger break; 7392d53139fSDavid Mosberger 7402d53139fSDavid Mosberger case USB_ENDPOINT_XFER_ISOC: 7412d53139fSDavid Mosberger case USB_ENDPOINT_XFER_INT: 7422d53139fSDavid Mosberger if (frame_diff(max3421_hcd->frame_number, 7432d53139fSDavid Mosberger max3421_ep->last_active) 7442d53139fSDavid Mosberger < urb->interval) 7452d53139fSDavid Mosberger /* 7462d53139fSDavid Mosberger * We already processed this 7472d53139fSDavid Mosberger * end-point in the current 7482d53139fSDavid Mosberger * frame 7492d53139fSDavid Mosberger */ 7502d53139fSDavid Mosberger continue; 7512d53139fSDavid Mosberger break; 7522d53139fSDavid Mosberger } 7532d53139fSDavid Mosberger 7542d53139fSDavid Mosberger /* move current ep to tail: */ 7552d53139fSDavid Mosberger list_move_tail(pos, &max3421_hcd->ep_list); 7562d53139fSDavid Mosberger curr_urb = urb; 7572d53139fSDavid Mosberger goto done; 7582d53139fSDavid Mosberger } 7592d53139fSDavid Mosberger done: 7602d53139fSDavid Mosberger if (!curr_urb) { 7612d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 7622d53139fSDavid Mosberger return 0; 7632d53139fSDavid Mosberger } 7642d53139fSDavid Mosberger 7652d53139fSDavid Mosberger urb = max3421_hcd->curr_urb = curr_urb; 7662d53139fSDavid Mosberger epnum = usb_endpoint_num(&urb->ep->desc); 7672d53139fSDavid Mosberger if (max3421_ep->retransmit) 7682d53139fSDavid Mosberger /* restart (part of) a USB transaction: */ 7692d53139fSDavid Mosberger max3421_ep->retransmit = 0; 7702d53139fSDavid Mosberger else { 7712d53139fSDavid Mosberger /* start USB transaction: */ 7722d53139fSDavid Mosberger if (usb_endpoint_xfer_control(&ep->desc)) { 7732d53139fSDavid Mosberger /* 7742d53139fSDavid Mosberger * See USB 2.0 spec section 8.6.1 7752d53139fSDavid Mosberger * Initialization via SETUP Token: 7762d53139fSDavid Mosberger */ 7772d53139fSDavid Mosberger usb_settoggle(urb->dev, epnum, 0, 1); 7782d53139fSDavid Mosberger usb_settoggle(urb->dev, epnum, 1, 1); 7792d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_SETUP; 7802d53139fSDavid Mosberger force_toggles = 1; 7812d53139fSDavid Mosberger } else 7822d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TRANSFER; 7832d53139fSDavid Mosberger } 7842d53139fSDavid Mosberger 7852d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 7862d53139fSDavid Mosberger 7872d53139fSDavid Mosberger max3421_ep->last_active = max3421_hcd->frame_number; 7882d53139fSDavid Mosberger max3421_set_address(hcd, urb->dev, epnum, force_toggles); 7892d53139fSDavid Mosberger max3421_set_speed(hcd, urb->dev); 7902d53139fSDavid Mosberger max3421_next_transfer(hcd, 0); 7912d53139fSDavid Mosberger return 1; 7922d53139fSDavid Mosberger } 7932d53139fSDavid Mosberger 7942d53139fSDavid Mosberger /* 7952d53139fSDavid Mosberger * Check all endpoints for URBs that got unlinked. 7962d53139fSDavid Mosberger * 7972d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 7982d53139fSDavid Mosberger */ 7992d53139fSDavid Mosberger static int 8002d53139fSDavid Mosberger max3421_check_unlink(struct usb_hcd *hcd) 8012d53139fSDavid Mosberger { 8022d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 8032d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8042d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 8052d53139fSDavid Mosberger struct usb_host_endpoint *ep; 806553c2360SGeliang Tang struct urb *urb, *next; 8072d53139fSDavid Mosberger unsigned long flags; 8082d53139fSDavid Mosberger int retval = 0; 8092d53139fSDavid Mosberger 8102d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 811553c2360SGeliang Tang list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) { 8122d53139fSDavid Mosberger ep = max3421_ep->ep; 813553c2360SGeliang Tang list_for_each_entry_safe(urb, next, &ep->urb_list, urb_list) { 8142d53139fSDavid Mosberger if (urb->unlinked) { 8152d53139fSDavid Mosberger retval = 1; 8162d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", 8172d53139fSDavid Mosberger __func__, urb, urb->unlinked); 8182d53139fSDavid Mosberger usb_hcd_unlink_urb_from_ep(hcd, urb); 8192d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, 8202d53139fSDavid Mosberger flags); 8212d53139fSDavid Mosberger usb_hcd_giveback_urb(hcd, urb, 0); 8222d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 8232d53139fSDavid Mosberger } 8242d53139fSDavid Mosberger } 8252d53139fSDavid Mosberger } 8262d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 8272d53139fSDavid Mosberger return retval; 8282d53139fSDavid Mosberger } 8292d53139fSDavid Mosberger 8302d53139fSDavid Mosberger /* 8312d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 8322d53139fSDavid Mosberger */ 8332d53139fSDavid Mosberger static void 8342d53139fSDavid Mosberger max3421_slow_retransmit(struct usb_hcd *hcd) 8352d53139fSDavid Mosberger { 8362d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8372d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8382d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 8392d53139fSDavid Mosberger 8402d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 8412d53139fSDavid Mosberger max3421_ep->retransmit = 1; 8422d53139fSDavid Mosberger max3421_hcd->curr_urb = NULL; 8432d53139fSDavid Mosberger } 8442d53139fSDavid Mosberger 8452d53139fSDavid Mosberger /* 8462d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 8472d53139fSDavid Mosberger */ 8482d53139fSDavid Mosberger static void 8492d53139fSDavid Mosberger max3421_recv_data_available(struct usb_hcd *hcd) 8502d53139fSDavid Mosberger { 8512d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8522d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8532d53139fSDavid Mosberger size_t remaining, transfer_size; 8542d53139fSDavid Mosberger u8 rcvbc; 8552d53139fSDavid Mosberger 8562d53139fSDavid Mosberger rcvbc = spi_rd8(hcd, MAX3421_REG_RCVBC); 8572d53139fSDavid Mosberger 8582d53139fSDavid Mosberger if (rcvbc > MAX3421_FIFO_SIZE) 8592d53139fSDavid Mosberger rcvbc = MAX3421_FIFO_SIZE; 8602d53139fSDavid Mosberger if (urb->actual_length >= urb->transfer_buffer_length) 8612d53139fSDavid Mosberger remaining = 0; 8622d53139fSDavid Mosberger else 8632d53139fSDavid Mosberger remaining = urb->transfer_buffer_length - urb->actual_length; 8642d53139fSDavid Mosberger transfer_size = rcvbc; 8652d53139fSDavid Mosberger if (transfer_size > remaining) 8662d53139fSDavid Mosberger transfer_size = remaining; 8672d53139fSDavid Mosberger if (transfer_size > 0) { 8682d53139fSDavid Mosberger void *dst = urb->transfer_buffer + urb->actual_length; 8692d53139fSDavid Mosberger 8702d53139fSDavid Mosberger spi_rd_buf(hcd, MAX3421_REG_RCVFIFO, dst, transfer_size); 8712d53139fSDavid Mosberger urb->actual_length += transfer_size; 8722d53139fSDavid Mosberger max3421_hcd->curr_len = transfer_size; 8732d53139fSDavid Mosberger } 8742d53139fSDavid Mosberger 8752d53139fSDavid Mosberger /* ack the RCVDAV irq now that the FIFO has been read: */ 8762d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIRQ, BIT(MAX3421_HI_RCVDAV_BIT)); 8772d53139fSDavid Mosberger } 8782d53139fSDavid Mosberger 8792d53139fSDavid Mosberger static void 8802d53139fSDavid Mosberger max3421_handle_error(struct usb_hcd *hcd, u8 hrsl) 8812d53139fSDavid Mosberger { 8822d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 8832d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 8842d53139fSDavid Mosberger u8 result_code = hrsl & MAX3421_HRSL_RESULT_MASK; 8852d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 8862d53139fSDavid Mosberger struct max3421_ep *max3421_ep = urb->ep->hcpriv; 8872d53139fSDavid Mosberger int switch_sndfifo; 8882d53139fSDavid Mosberger 8892d53139fSDavid Mosberger /* 8902d53139fSDavid Mosberger * If an OUT command results in any response other than OK 8912d53139fSDavid Mosberger * (i.e., error or NAK), we have to perform a dummy-write to 8922d53139fSDavid Mosberger * SNDBC so the FIFO gets switched back to us. Otherwise, we 8932d53139fSDavid Mosberger * get out of sync with the SNDFIFO double buffer. 8942d53139fSDavid Mosberger */ 8952d53139fSDavid Mosberger switch_sndfifo = (max3421_ep->pkt_state == PKT_STATE_TRANSFER && 8962d53139fSDavid Mosberger usb_urb_dir_out(urb)); 8972d53139fSDavid Mosberger 8982d53139fSDavid Mosberger switch (result_code) { 8992d53139fSDavid Mosberger case MAX3421_HRSL_OK: 9002d53139fSDavid Mosberger return; /* this shouldn't happen */ 9012d53139fSDavid Mosberger 9022d53139fSDavid Mosberger case MAX3421_HRSL_WRONGPID: /* received wrong PID */ 9032d53139fSDavid Mosberger case MAX3421_HRSL_BUSY: /* SIE busy */ 9042d53139fSDavid Mosberger case MAX3421_HRSL_BADREQ: /* bad val in HXFR */ 9052d53139fSDavid Mosberger case MAX3421_HRSL_UNDEF: /* reserved */ 9062d53139fSDavid Mosberger case MAX3421_HRSL_KERR: /* K-state instead of response */ 9072d53139fSDavid Mosberger case MAX3421_HRSL_JERR: /* J-state instead of response */ 9082d53139fSDavid Mosberger /* 9092d53139fSDavid Mosberger * packet experienced an error that we cannot recover 9102d53139fSDavid Mosberger * from; report error 9112d53139fSDavid Mosberger */ 9122d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9132d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9142d53139fSDavid Mosberger __func__, hrsl); 9152d53139fSDavid Mosberger break; 9162d53139fSDavid Mosberger 9172d53139fSDavid Mosberger case MAX3421_HRSL_TOGERR: 9182d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 9192d53139fSDavid Mosberger ; /* don't do anything (device will switch toggle) */ 9202d53139fSDavid Mosberger else { 9212d53139fSDavid Mosberger /* flip the send toggle bit: */ 9222d53139fSDavid Mosberger int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; 9232d53139fSDavid Mosberger 9242d53139fSDavid Mosberger sndtog ^= 1; 9252d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, 9262d53139fSDavid Mosberger BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); 9272d53139fSDavid Mosberger } 9280d9b6d49SGustavo A. R. Silva fallthrough; 9292d53139fSDavid Mosberger case MAX3421_HRSL_BADBC: /* bad byte count */ 9302d53139fSDavid Mosberger case MAX3421_HRSL_PIDERR: /* received PID is corrupted */ 9312d53139fSDavid Mosberger case MAX3421_HRSL_PKTERR: /* packet error (stuff, EOP) */ 9322d53139fSDavid Mosberger case MAX3421_HRSL_CRCERR: /* CRC error */ 9332d53139fSDavid Mosberger case MAX3421_HRSL_BABBLE: /* device talked too long */ 9342d53139fSDavid Mosberger case MAX3421_HRSL_TIMEOUT: 9352d53139fSDavid Mosberger if (max3421_ep->retries++ < USB_MAX_RETRIES) 9362d53139fSDavid Mosberger /* retry the packet again in the next frame */ 9372d53139fSDavid Mosberger max3421_slow_retransmit(hcd); 9382d53139fSDavid Mosberger else { 9392d53139fSDavid Mosberger /* Based on ohci.h cc_to_err[]: */ 9402d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9412d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9422d53139fSDavid Mosberger __func__, hrsl); 9432d53139fSDavid Mosberger } 9442d53139fSDavid Mosberger break; 9452d53139fSDavid Mosberger 9462d53139fSDavid Mosberger case MAX3421_HRSL_STALL: 9472d53139fSDavid Mosberger dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", 9482d53139fSDavid Mosberger __func__, hrsl); 9492d53139fSDavid Mosberger max3421_hcd->urb_done = hrsl_to_error[result_code]; 9502d53139fSDavid Mosberger break; 9512d53139fSDavid Mosberger 9522d53139fSDavid Mosberger case MAX3421_HRSL_NAK: 9532d53139fSDavid Mosberger /* 9542d53139fSDavid Mosberger * Device wasn't ready for data or has no data 9552d53139fSDavid Mosberger * available: retry the packet again. 9562d53139fSDavid Mosberger */ 9572d53139fSDavid Mosberger if (max3421_ep->naks++ < NAK_MAX_FAST_RETRANSMITS) { 9582d53139fSDavid Mosberger max3421_next_transfer(hcd, 1); 9592d53139fSDavid Mosberger switch_sndfifo = 0; 9602d53139fSDavid Mosberger } else 9612d53139fSDavid Mosberger max3421_slow_retransmit(hcd); 9622d53139fSDavid Mosberger break; 9632d53139fSDavid Mosberger } 9642d53139fSDavid Mosberger if (switch_sndfifo) 9652d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_SNDBC, 0); 9662d53139fSDavid Mosberger } 9672d53139fSDavid Mosberger 9682d53139fSDavid Mosberger /* 9692d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 9702d53139fSDavid Mosberger */ 9712d53139fSDavid Mosberger static int 9722d53139fSDavid Mosberger max3421_transfer_in_done(struct usb_hcd *hcd, struct urb *urb) 9732d53139fSDavid Mosberger { 9742d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 9752d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 9762d53139fSDavid Mosberger u32 max_packet; 9772d53139fSDavid Mosberger 9782d53139fSDavid Mosberger if (urb->actual_length >= urb->transfer_buffer_length) 9792d53139fSDavid Mosberger return 1; /* read is complete, so we're done */ 9802d53139fSDavid Mosberger 9812d53139fSDavid Mosberger /* 9822d53139fSDavid Mosberger * USB 2.0 Section 5.3.2 Pipes: packets must be full size 9832d53139fSDavid Mosberger * except for last one. 9842d53139fSDavid Mosberger */ 9852d53139fSDavid Mosberger max_packet = usb_maxpacket(urb->dev, urb->pipe, 0); 9862d53139fSDavid Mosberger if (max_packet > MAX3421_FIFO_SIZE) { 9872d53139fSDavid Mosberger /* 9882d53139fSDavid Mosberger * We do not support isochronous transfers at this 9892d53139fSDavid Mosberger * time... 9902d53139fSDavid Mosberger */ 9912d53139fSDavid Mosberger dev_err(&spi->dev, 9922d53139fSDavid Mosberger "%s: packet-size of %u too big (limit is %u bytes)", 9932d53139fSDavid Mosberger __func__, max_packet, MAX3421_FIFO_SIZE); 9942d53139fSDavid Mosberger return -EINVAL; 9952d53139fSDavid Mosberger } 9962d53139fSDavid Mosberger 9972d53139fSDavid Mosberger if (max3421_hcd->curr_len < max_packet) { 9982d53139fSDavid Mosberger if (urb->transfer_flags & URB_SHORT_NOT_OK) { 9992d53139fSDavid Mosberger /* 10002d53139fSDavid Mosberger * remaining > 0 and received an 10012d53139fSDavid Mosberger * unexpected partial packet -> 10022d53139fSDavid Mosberger * error 10032d53139fSDavid Mosberger */ 10042d53139fSDavid Mosberger return -EREMOTEIO; 10052d53139fSDavid Mosberger } else 10062d53139fSDavid Mosberger /* short read, but it's OK */ 10072d53139fSDavid Mosberger return 1; 10082d53139fSDavid Mosberger } 10092d53139fSDavid Mosberger return 0; /* not done */ 10102d53139fSDavid Mosberger } 10112d53139fSDavid Mosberger 10122d53139fSDavid Mosberger /* 10132d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 10142d53139fSDavid Mosberger */ 10152d53139fSDavid Mosberger static int 10162d53139fSDavid Mosberger max3421_transfer_out_done(struct usb_hcd *hcd, struct urb *urb) 10172d53139fSDavid Mosberger { 10182d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 10192d53139fSDavid Mosberger 10202d53139fSDavid Mosberger urb->actual_length += max3421_hcd->curr_len; 10212d53139fSDavid Mosberger if (urb->actual_length < urb->transfer_buffer_length) 10222d53139fSDavid Mosberger return 0; 10232d53139fSDavid Mosberger if (urb->transfer_flags & URB_ZERO_PACKET) { 10242d53139fSDavid Mosberger /* 10252d53139fSDavid Mosberger * Some hardware needs a zero-size packet at the end 10262d53139fSDavid Mosberger * of a bulk-out transfer if the last transfer was a 10272d53139fSDavid Mosberger * full-sized packet (i.e., such hardware use < 10282d53139fSDavid Mosberger * max_packet as an indicator that the end of the 10292d53139fSDavid Mosberger * packet has been reached). 10302d53139fSDavid Mosberger */ 10312d53139fSDavid Mosberger u32 max_packet = usb_maxpacket(urb->dev, urb->pipe, 1); 10322d53139fSDavid Mosberger 10332d53139fSDavid Mosberger if (max3421_hcd->curr_len == max_packet) 10342d53139fSDavid Mosberger return 0; 10352d53139fSDavid Mosberger } 10362d53139fSDavid Mosberger return 1; 10372d53139fSDavid Mosberger } 10382d53139fSDavid Mosberger 10392d53139fSDavid Mosberger /* 10402d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 10412d53139fSDavid Mosberger */ 10422d53139fSDavid Mosberger static void 10432d53139fSDavid Mosberger max3421_host_transfer_done(struct usb_hcd *hcd) 10442d53139fSDavid Mosberger { 10452d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 10462d53139fSDavid Mosberger struct urb *urb = max3421_hcd->curr_urb; 10472d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 10482d53139fSDavid Mosberger u8 result_code, hrsl; 10492d53139fSDavid Mosberger int urb_done = 0; 10502d53139fSDavid Mosberger 10512d53139fSDavid Mosberger max3421_hcd->hien &= ~(BIT(MAX3421_HI_HXFRDN_BIT) | 10522d53139fSDavid Mosberger BIT(MAX3421_HI_RCVDAV_BIT)); 10532d53139fSDavid Mosberger 10542d53139fSDavid Mosberger hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); 10552d53139fSDavid Mosberger result_code = hrsl & MAX3421_HRSL_RESULT_MASK; 10562d53139fSDavid Mosberger 10572d53139fSDavid Mosberger #ifdef DEBUG 10582d53139fSDavid Mosberger ++max3421_hcd->err_stat[result_code]; 10592d53139fSDavid Mosberger #endif 10602d53139fSDavid Mosberger 10612d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 10622d53139fSDavid Mosberger 10632d53139fSDavid Mosberger if (unlikely(result_code != MAX3421_HRSL_OK)) { 10642d53139fSDavid Mosberger max3421_handle_error(hcd, hrsl); 10652d53139fSDavid Mosberger return; 10662d53139fSDavid Mosberger } 10672d53139fSDavid Mosberger 10682d53139fSDavid Mosberger max3421_ep->naks = 0; 10692d53139fSDavid Mosberger max3421_ep->retries = 0; 10702d53139fSDavid Mosberger switch (max3421_ep->pkt_state) { 10712d53139fSDavid Mosberger 10722d53139fSDavid Mosberger case PKT_STATE_SETUP: 10732d53139fSDavid Mosberger if (urb->transfer_buffer_length > 0) 10742d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TRANSFER; 10752d53139fSDavid Mosberger else 10762d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TERMINATE; 10772d53139fSDavid Mosberger break; 10782d53139fSDavid Mosberger 10792d53139fSDavid Mosberger case PKT_STATE_TRANSFER: 10802d53139fSDavid Mosberger if (usb_urb_dir_in(urb)) 10812d53139fSDavid Mosberger urb_done = max3421_transfer_in_done(hcd, urb); 10822d53139fSDavid Mosberger else 10832d53139fSDavid Mosberger urb_done = max3421_transfer_out_done(hcd, urb); 10842d53139fSDavid Mosberger if (urb_done > 0 && usb_pipetype(urb->pipe) == PIPE_CONTROL) { 10852d53139fSDavid Mosberger /* 10862d53139fSDavid Mosberger * We aren't really done - we still need to 10872d53139fSDavid Mosberger * terminate the control transfer: 10882d53139fSDavid Mosberger */ 10892d53139fSDavid Mosberger max3421_hcd->urb_done = urb_done = 0; 10902d53139fSDavid Mosberger max3421_ep->pkt_state = PKT_STATE_TERMINATE; 10912d53139fSDavid Mosberger } 10922d53139fSDavid Mosberger break; 10932d53139fSDavid Mosberger 10942d53139fSDavid Mosberger case PKT_STATE_TERMINATE: 10952d53139fSDavid Mosberger urb_done = 1; 10962d53139fSDavid Mosberger break; 10972d53139fSDavid Mosberger } 10982d53139fSDavid Mosberger 10992d53139fSDavid Mosberger if (urb_done) 11002d53139fSDavid Mosberger max3421_hcd->urb_done = urb_done; 11012d53139fSDavid Mosberger else 11022d53139fSDavid Mosberger max3421_next_transfer(hcd, 0); 11032d53139fSDavid Mosberger } 11042d53139fSDavid Mosberger 11052d53139fSDavid Mosberger /* 11062d53139fSDavid Mosberger * Caller must NOT hold HCD spinlock. 11072d53139fSDavid Mosberger */ 11082d53139fSDavid Mosberger static void 11092d53139fSDavid Mosberger max3421_detect_conn(struct usb_hcd *hcd) 11102d53139fSDavid Mosberger { 11112d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11122d53139fSDavid Mosberger unsigned int jk, have_conn = 0; 11132d53139fSDavid Mosberger u32 old_port_status, chg; 11142d53139fSDavid Mosberger unsigned long flags; 11152d53139fSDavid Mosberger u8 hrsl, mode; 11162d53139fSDavid Mosberger 11172d53139fSDavid Mosberger hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); 11182d53139fSDavid Mosberger 11192d53139fSDavid Mosberger jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) | 11202d53139fSDavid Mosberger (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1)); 11212d53139fSDavid Mosberger 11222d53139fSDavid Mosberger mode = max3421_hcd->mode; 11232d53139fSDavid Mosberger 11242d53139fSDavid Mosberger switch (jk) { 11252d53139fSDavid Mosberger case 0x0: /* SE0: disconnect */ 11262d53139fSDavid Mosberger /* 11272d53139fSDavid Mosberger * Turn off SOFKAENAB bit to avoid getting interrupt 11282d53139fSDavid Mosberger * every milli-second: 11292d53139fSDavid Mosberger */ 11302d53139fSDavid Mosberger mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT); 11312d53139fSDavid Mosberger break; 11322d53139fSDavid Mosberger 11332d53139fSDavid Mosberger case 0x1: /* J=0,K=1: low-speed (in full-speed or vice versa) */ 11342d53139fSDavid Mosberger case 0x2: /* J=1,K=0: full-speed (in full-speed or vice versa) */ 11352d53139fSDavid Mosberger if (jk == 0x2) 11362d53139fSDavid Mosberger /* need to switch to the other speed: */ 11372d53139fSDavid Mosberger mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT); 11382d53139fSDavid Mosberger /* turn on SOFKAENAB bit: */ 11392d53139fSDavid Mosberger mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT); 11402d53139fSDavid Mosberger have_conn = 1; 11412d53139fSDavid Mosberger break; 11422d53139fSDavid Mosberger 11432d53139fSDavid Mosberger case 0x3: /* illegal */ 11442d53139fSDavid Mosberger break; 11452d53139fSDavid Mosberger } 11462d53139fSDavid Mosberger 11472d53139fSDavid Mosberger max3421_hcd->mode = mode; 11482d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); 11492d53139fSDavid Mosberger 11502d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 11512d53139fSDavid Mosberger old_port_status = max3421_hcd->port_status; 11522d53139fSDavid Mosberger if (have_conn) 11532d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_CONNECTION; 11542d53139fSDavid Mosberger else 11552d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION; 11562d53139fSDavid Mosberger if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT)) 11572d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_LOW_SPEED; 11582d53139fSDavid Mosberger else 11592d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED; 11602d53139fSDavid Mosberger chg = (old_port_status ^ max3421_hcd->port_status); 11612d53139fSDavid Mosberger max3421_hcd->port_status |= chg << 16; 11622d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 11632d53139fSDavid Mosberger } 11642d53139fSDavid Mosberger 11652d53139fSDavid Mosberger static irqreturn_t 11662d53139fSDavid Mosberger max3421_irq_handler(int irq, void *dev_id) 11672d53139fSDavid Mosberger { 11682d53139fSDavid Mosberger struct usb_hcd *hcd = dev_id; 11692d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 11702d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11712d53139fSDavid Mosberger 1172*37aadc68SPeter Zijlstra if (max3421_hcd->spi_thread) 11732d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 11742eb5dbddSDavid Mosberger-Tang if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo)) 11752d53139fSDavid Mosberger disable_irq_nosync(spi->irq); 11762d53139fSDavid Mosberger return IRQ_HANDLED; 11772d53139fSDavid Mosberger } 11782d53139fSDavid Mosberger 11792d53139fSDavid Mosberger #ifdef DEBUG 11802d53139fSDavid Mosberger 11812d53139fSDavid Mosberger static void 11822d53139fSDavid Mosberger dump_eps(struct usb_hcd *hcd) 11832d53139fSDavid Mosberger { 11842d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 11852d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 11862d53139fSDavid Mosberger struct usb_host_endpoint *ep; 11872d53139fSDavid Mosberger char ubuf[512], *dp, *end; 11882d53139fSDavid Mosberger unsigned long flags; 11892d53139fSDavid Mosberger struct urb *urb; 11902d53139fSDavid Mosberger int epnum, ret; 11912d53139fSDavid Mosberger 11922d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 1193553c2360SGeliang Tang list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) { 11942d53139fSDavid Mosberger ep = max3421_ep->ep; 11952d53139fSDavid Mosberger 11962d53139fSDavid Mosberger dp = ubuf; 11972d53139fSDavid Mosberger end = dp + sizeof(ubuf); 11982d53139fSDavid Mosberger *dp = '\0'; 1199553c2360SGeliang Tang list_for_each_entry(urb, &ep->urb_list, urb_list) { 12002d53139fSDavid Mosberger ret = snprintf(dp, end - dp, " %p(%d.%s %d/%d)", urb, 12012d53139fSDavid Mosberger usb_pipetype(urb->pipe), 12022d53139fSDavid Mosberger usb_urb_dir_in(urb) ? "IN" : "OUT", 12032d53139fSDavid Mosberger urb->actual_length, 12042d53139fSDavid Mosberger urb->transfer_buffer_length); 12052d53139fSDavid Mosberger if (ret < 0 || ret >= end - dp) 12062d53139fSDavid Mosberger break; /* error or buffer full */ 12072d53139fSDavid Mosberger dp += ret; 12082d53139fSDavid Mosberger } 12092d53139fSDavid Mosberger 12102d53139fSDavid Mosberger epnum = usb_endpoint_num(&ep->desc); 12112d53139fSDavid Mosberger pr_info("EP%0u %u lst %04u rtr %u nak %6u rxmt %u: %s\n", 12122d53139fSDavid Mosberger epnum, max3421_ep->pkt_state, max3421_ep->last_active, 12132d53139fSDavid Mosberger max3421_ep->retries, max3421_ep->naks, 12142d53139fSDavid Mosberger max3421_ep->retransmit, ubuf); 12152d53139fSDavid Mosberger } 12162d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 12172d53139fSDavid Mosberger } 12182d53139fSDavid Mosberger 12192d53139fSDavid Mosberger #endif /* DEBUG */ 12202d53139fSDavid Mosberger 12212d53139fSDavid Mosberger /* Return zero if no work was performed, 1 otherwise. */ 12222d53139fSDavid Mosberger static int 12232d53139fSDavid Mosberger max3421_handle_irqs(struct usb_hcd *hcd) 12242d53139fSDavid Mosberger { 12252d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 12262d53139fSDavid Mosberger u32 chg, old_port_status; 12272d53139fSDavid Mosberger unsigned long flags; 12282d53139fSDavid Mosberger u8 hirq; 12292d53139fSDavid Mosberger 12302d53139fSDavid Mosberger /* 12312d53139fSDavid Mosberger * Read and ack pending interrupts (CPU must never 12322d53139fSDavid Mosberger * clear SNDBAV directly and RCVDAV must be cleared by 12332d53139fSDavid Mosberger * max3421_recv_data_available()!): 12342d53139fSDavid Mosberger */ 12352d53139fSDavid Mosberger hirq = spi_rd8(hcd, MAX3421_REG_HIRQ); 12362d53139fSDavid Mosberger hirq &= max3421_hcd->hien; 12372d53139fSDavid Mosberger if (!hirq) 12382d53139fSDavid Mosberger return 0; 12392d53139fSDavid Mosberger 12402d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIRQ, 12412d53139fSDavid Mosberger hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) | 12422d53139fSDavid Mosberger BIT(MAX3421_HI_RCVDAV_BIT))); 12432d53139fSDavid Mosberger 12442d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_FRAME_BIT)) { 12452d53139fSDavid Mosberger max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1) 12462d53139fSDavid Mosberger & USB_MAX_FRAME_NUMBER); 12472d53139fSDavid Mosberger max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; 12482d53139fSDavid Mosberger } 12492d53139fSDavid Mosberger 12502d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_RCVDAV_BIT)) 12512d53139fSDavid Mosberger max3421_recv_data_available(hcd); 12522d53139fSDavid Mosberger 12532d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_HXFRDN_BIT)) 12542d53139fSDavid Mosberger max3421_host_transfer_done(hcd); 12552d53139fSDavid Mosberger 12562d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_CONDET_BIT)) 12572d53139fSDavid Mosberger max3421_detect_conn(hcd); 12582d53139fSDavid Mosberger 12592d53139fSDavid Mosberger /* 12602d53139fSDavid Mosberger * Now process interrupts that may affect HCD state 12612d53139fSDavid Mosberger * other than the end-points: 12622d53139fSDavid Mosberger */ 12632d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 12642d53139fSDavid Mosberger 12652d53139fSDavid Mosberger old_port_status = max3421_hcd->port_status; 12662d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) { 12672d53139fSDavid Mosberger if (max3421_hcd->port_status & USB_PORT_STAT_RESET) { 12682d53139fSDavid Mosberger /* BUSEVENT due to completion of Bus Reset */ 12692d53139fSDavid Mosberger max3421_hcd->port_status &= ~USB_PORT_STAT_RESET; 12702d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_ENABLE; 12712d53139fSDavid Mosberger } else { 12722d53139fSDavid Mosberger /* BUSEVENT due to completion of Bus Resume */ 12732d53139fSDavid Mosberger pr_info("%s: BUSEVENT Bus Resume Done\n", __func__); 12742d53139fSDavid Mosberger } 12752d53139fSDavid Mosberger } 12762d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_RWU_BIT)) 12772d53139fSDavid Mosberger pr_info("%s: RWU\n", __func__); 12782d53139fSDavid Mosberger if (hirq & BIT(MAX3421_HI_SUSDN_BIT)) 12792d53139fSDavid Mosberger pr_info("%s: SUSDN\n", __func__); 12802d53139fSDavid Mosberger 12812d53139fSDavid Mosberger chg = (old_port_status ^ max3421_hcd->port_status); 12822d53139fSDavid Mosberger max3421_hcd->port_status |= chg << 16; 12832d53139fSDavid Mosberger 12842d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 12852d53139fSDavid Mosberger 12862d53139fSDavid Mosberger #ifdef DEBUG 12872d53139fSDavid Mosberger { 12882d53139fSDavid Mosberger static unsigned long last_time; 12892d53139fSDavid Mosberger char sbuf[16 * 16], *dp, *end; 12902d53139fSDavid Mosberger int i; 12912d53139fSDavid Mosberger 1292788bfe88SAsaf Vertz if (time_after(jiffies, last_time + 5*HZ)) { 12932d53139fSDavid Mosberger dp = sbuf; 12942d53139fSDavid Mosberger end = sbuf + sizeof(sbuf); 12952d53139fSDavid Mosberger *dp = '\0'; 12962d53139fSDavid Mosberger for (i = 0; i < 16; ++i) { 12972d53139fSDavid Mosberger int ret = snprintf(dp, end - dp, " %lu", 12982d53139fSDavid Mosberger max3421_hcd->err_stat[i]); 12992d53139fSDavid Mosberger if (ret < 0 || ret >= end - dp) 13002d53139fSDavid Mosberger break; /* error or buffer full */ 13012d53139fSDavid Mosberger dp += ret; 13022d53139fSDavid Mosberger } 13032d53139fSDavid Mosberger pr_info("%s: hrsl_stats %s\n", __func__, sbuf); 13042d53139fSDavid Mosberger memset(max3421_hcd->err_stat, 0, 13052d53139fSDavid Mosberger sizeof(max3421_hcd->err_stat)); 13062d53139fSDavid Mosberger last_time = jiffies; 13072d53139fSDavid Mosberger 13082d53139fSDavid Mosberger dump_eps(hcd); 13092d53139fSDavid Mosberger } 13102d53139fSDavid Mosberger } 13112d53139fSDavid Mosberger #endif 13122d53139fSDavid Mosberger return 1; 13132d53139fSDavid Mosberger } 13142d53139fSDavid Mosberger 13152d53139fSDavid Mosberger static int 13162d53139fSDavid Mosberger max3421_reset_hcd(struct usb_hcd *hcd) 13172d53139fSDavid Mosberger { 13182d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 13192d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 13202d53139fSDavid Mosberger int timeout; 13212d53139fSDavid Mosberger 13222d53139fSDavid Mosberger /* perform a chip reset and wait for OSCIRQ signal to appear: */ 13232d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_USBCTL, BIT(MAX3421_USBCTL_CHIPRES_BIT)); 13242d53139fSDavid Mosberger /* clear reset: */ 13252d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_USBCTL, 0); 13262d53139fSDavid Mosberger timeout = 1000; 13272d53139fSDavid Mosberger while (1) { 13282d53139fSDavid Mosberger if (spi_rd8(hcd, MAX3421_REG_USBIRQ) 13292d53139fSDavid Mosberger & BIT(MAX3421_USBIRQ_OSCOKIRQ_BIT)) 13302d53139fSDavid Mosberger break; 13312d53139fSDavid Mosberger if (--timeout < 0) { 13322d53139fSDavid Mosberger dev_err(&spi->dev, 13332d53139fSDavid Mosberger "timed out waiting for oscillator OK signal"); 13342d53139fSDavid Mosberger return 1; 13352d53139fSDavid Mosberger } 13362d53139fSDavid Mosberger cond_resched(); 13372d53139fSDavid Mosberger } 13382d53139fSDavid Mosberger 13392d53139fSDavid Mosberger /* 13402d53139fSDavid Mosberger * Turn on host mode, automatic generation of SOF packets, and 13412d53139fSDavid Mosberger * enable pull-down registers on DM/DP: 13422d53139fSDavid Mosberger */ 13432d53139fSDavid Mosberger max3421_hcd->mode = (BIT(MAX3421_MODE_HOST_BIT) | 13442d53139fSDavid Mosberger BIT(MAX3421_MODE_SOFKAENAB_BIT) | 13452d53139fSDavid Mosberger BIT(MAX3421_MODE_DMPULLDN_BIT) | 13462d53139fSDavid Mosberger BIT(MAX3421_MODE_DPPULLDN_BIT)); 13472d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); 13482d53139fSDavid Mosberger 13492d53139fSDavid Mosberger /* reset frame-number: */ 13502d53139fSDavid Mosberger max3421_hcd->frame_number = USB_MAX_FRAME_NUMBER; 13512d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_FRMRST_BIT)); 13522d53139fSDavid Mosberger 13532d53139fSDavid Mosberger /* sample the state of the D+ and D- lines */ 13542d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_SAMPLEBUS_BIT)); 13552d53139fSDavid Mosberger max3421_detect_conn(hcd); 13562d53139fSDavid Mosberger 13572d53139fSDavid Mosberger /* enable frame, connection-detected, and bus-event interrupts: */ 13582d53139fSDavid Mosberger max3421_hcd->hien = (BIT(MAX3421_HI_FRAME_BIT) | 13592d53139fSDavid Mosberger BIT(MAX3421_HI_CONDET_BIT) | 13602d53139fSDavid Mosberger BIT(MAX3421_HI_BUSEVENT_BIT)); 13612d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); 13622d53139fSDavid Mosberger 13632d53139fSDavid Mosberger /* enable interrupts: */ 13642d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_CPUCTL, BIT(MAX3421_CPUCTL_IE_BIT)); 13652d53139fSDavid Mosberger return 1; 13662d53139fSDavid Mosberger } 13672d53139fSDavid Mosberger 13682d53139fSDavid Mosberger static int 13692d53139fSDavid Mosberger max3421_urb_done(struct usb_hcd *hcd) 13702d53139fSDavid Mosberger { 13712d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 13722d53139fSDavid Mosberger unsigned long flags; 13732d53139fSDavid Mosberger struct urb *urb; 13742d53139fSDavid Mosberger int status; 13752d53139fSDavid Mosberger 13762d53139fSDavid Mosberger status = max3421_hcd->urb_done; 13772d53139fSDavid Mosberger max3421_hcd->urb_done = 0; 13782d53139fSDavid Mosberger if (status > 0) 13792d53139fSDavid Mosberger status = 0; 13802d53139fSDavid Mosberger urb = max3421_hcd->curr_urb; 13812d53139fSDavid Mosberger if (urb) { 13822d53139fSDavid Mosberger max3421_hcd->curr_urb = NULL; 13832d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 13842d53139fSDavid Mosberger usb_hcd_unlink_urb_from_ep(hcd, urb); 13852d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 13862d53139fSDavid Mosberger 13872d53139fSDavid Mosberger /* must be called without the HCD spinlock: */ 13882d53139fSDavid Mosberger usb_hcd_giveback_urb(hcd, urb, status); 13892d53139fSDavid Mosberger } 13902d53139fSDavid Mosberger return 1; 13912d53139fSDavid Mosberger } 13922d53139fSDavid Mosberger 13932d53139fSDavid Mosberger static int 13942d53139fSDavid Mosberger max3421_spi_thread(void *dev_id) 13952d53139fSDavid Mosberger { 13962d53139fSDavid Mosberger struct usb_hcd *hcd = dev_id; 13972d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 13982d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 13992d53139fSDavid Mosberger int i, i_worked = 1; 14002d53139fSDavid Mosberger 14012d53139fSDavid Mosberger /* set full-duplex SPI mode, low-active interrupt pin: */ 14022d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_PINCTL, 14032d53139fSDavid Mosberger (BIT(MAX3421_PINCTL_FDUPSPI_BIT) | /* full-duplex */ 14042d53139fSDavid Mosberger BIT(MAX3421_PINCTL_INTLEVEL_BIT))); /* low-active irq */ 14052d53139fSDavid Mosberger 14062d53139fSDavid Mosberger while (!kthread_should_stop()) { 14072d53139fSDavid Mosberger max3421_hcd->rev = spi_rd8(hcd, MAX3421_REG_REVISION); 14082d53139fSDavid Mosberger if (max3421_hcd->rev == 0x12 || max3421_hcd->rev == 0x13) 14092d53139fSDavid Mosberger break; 14102d53139fSDavid Mosberger dev_err(&spi->dev, "bad rev 0x%02x", max3421_hcd->rev); 14112d53139fSDavid Mosberger msleep(10000); 14122d53139fSDavid Mosberger } 14132d53139fSDavid Mosberger dev_info(&spi->dev, "rev 0x%x, SPI clk %dHz, bpw %u, irq %d\n", 14142d53139fSDavid Mosberger max3421_hcd->rev, spi->max_speed_hz, spi->bits_per_word, 14152d53139fSDavid Mosberger spi->irq); 14162d53139fSDavid Mosberger 14172d53139fSDavid Mosberger while (!kthread_should_stop()) { 14182d53139fSDavid Mosberger if (!i_worked) { 14192d53139fSDavid Mosberger /* 14202d53139fSDavid Mosberger * We'll be waiting for wakeups from the hard 14212d53139fSDavid Mosberger * interrupt handler, so now is a good time to 14222d53139fSDavid Mosberger * sync our hien with the chip: 14232d53139fSDavid Mosberger */ 14242d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); 14252d53139fSDavid Mosberger 14262d53139fSDavid Mosberger set_current_state(TASK_INTERRUPTIBLE); 14272eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(ENABLE_IRQ, &max3421_hcd->todo)) 14282d53139fSDavid Mosberger enable_irq(spi->irq); 14292d53139fSDavid Mosberger schedule(); 14302d53139fSDavid Mosberger __set_current_state(TASK_RUNNING); 14312d53139fSDavid Mosberger } 14322d53139fSDavid Mosberger 14332d53139fSDavid Mosberger i_worked = 0; 14342d53139fSDavid Mosberger 14352d53139fSDavid Mosberger if (max3421_hcd->urb_done) 14362d53139fSDavid Mosberger i_worked |= max3421_urb_done(hcd); 14372d53139fSDavid Mosberger else if (max3421_handle_irqs(hcd)) 14382d53139fSDavid Mosberger i_worked = 1; 14392d53139fSDavid Mosberger else if (!max3421_hcd->curr_urb) 14402d53139fSDavid Mosberger i_worked |= max3421_select_and_start_urb(hcd); 14412d53139fSDavid Mosberger 14422eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(RESET_HCD, &max3421_hcd->todo)) 14432d53139fSDavid Mosberger /* reset the HCD: */ 14442d53139fSDavid Mosberger i_worked |= max3421_reset_hcd(hcd); 14452eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(RESET_PORT, &max3421_hcd->todo)) { 14462d53139fSDavid Mosberger /* perform a USB bus reset: */ 14472d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_HCTL, 14482d53139fSDavid Mosberger BIT(MAX3421_HCTL_BUSRST_BIT)); 14492d53139fSDavid Mosberger i_worked = 1; 14502d53139fSDavid Mosberger } 14512eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(CHECK_UNLINK, &max3421_hcd->todo)) 14522d53139fSDavid Mosberger i_worked |= max3421_check_unlink(hcd); 14532eb5dbddSDavid Mosberger-Tang if (test_and_clear_bit(IOPIN_UPDATE, &max3421_hcd->todo)) { 14542d53139fSDavid Mosberger /* 14552d53139fSDavid Mosberger * IOPINS1/IOPINS2 do not auto-increment, so we can't 14562d53139fSDavid Mosberger * use spi_wr_buf(). 14572d53139fSDavid Mosberger */ 14582d53139fSDavid Mosberger for (i = 0; i < ARRAY_SIZE(max3421_hcd->iopins); ++i) { 14592d53139fSDavid Mosberger u8 val = spi_rd8(hcd, MAX3421_REG_IOPINS1); 14602d53139fSDavid Mosberger 14612d53139fSDavid Mosberger val = ((val & 0xf0) | 14622d53139fSDavid Mosberger (max3421_hcd->iopins[i] & 0x0f)); 14632d53139fSDavid Mosberger spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val); 14642d53139fSDavid Mosberger max3421_hcd->iopins[i] = val; 14652d53139fSDavid Mosberger } 14662d53139fSDavid Mosberger i_worked = 1; 14672d53139fSDavid Mosberger } 14682d53139fSDavid Mosberger } 14692d53139fSDavid Mosberger set_current_state(TASK_RUNNING); 14702d53139fSDavid Mosberger dev_info(&spi->dev, "SPI thread exiting"); 14712d53139fSDavid Mosberger return 0; 14722d53139fSDavid Mosberger } 14732d53139fSDavid Mosberger 14742d53139fSDavid Mosberger static int 14752d53139fSDavid Mosberger max3421_reset_port(struct usb_hcd *hcd) 14762d53139fSDavid Mosberger { 14772d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 14782d53139fSDavid Mosberger 14792d53139fSDavid Mosberger max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | 14802d53139fSDavid Mosberger USB_PORT_STAT_LOW_SPEED); 1481a2b63cb5SDavid Mosberger-Tang max3421_hcd->port_status |= USB_PORT_STAT_RESET; 14822eb5dbddSDavid Mosberger-Tang set_bit(RESET_PORT, &max3421_hcd->todo); 14832d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 14842d53139fSDavid Mosberger return 0; 14852d53139fSDavid Mosberger } 14862d53139fSDavid Mosberger 14872d53139fSDavid Mosberger static int 14882d53139fSDavid Mosberger max3421_reset(struct usb_hcd *hcd) 14892d53139fSDavid Mosberger { 14902d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 14912d53139fSDavid Mosberger 14922d53139fSDavid Mosberger hcd->self.sg_tablesize = 0; 14932d53139fSDavid Mosberger hcd->speed = HCD_USB2; 14942d53139fSDavid Mosberger hcd->self.root_hub->speed = USB_SPEED_FULL; 14952eb5dbddSDavid Mosberger-Tang set_bit(RESET_HCD, &max3421_hcd->todo); 14962d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 14972d53139fSDavid Mosberger return 0; 14982d53139fSDavid Mosberger } 14992d53139fSDavid Mosberger 15002d53139fSDavid Mosberger static int 15012d53139fSDavid Mosberger max3421_start(struct usb_hcd *hcd) 15022d53139fSDavid Mosberger { 15032d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15042d53139fSDavid Mosberger 15052d53139fSDavid Mosberger spin_lock_init(&max3421_hcd->lock); 15062d53139fSDavid Mosberger max3421_hcd->rh_state = MAX3421_RH_RUNNING; 15072d53139fSDavid Mosberger 15082d53139fSDavid Mosberger INIT_LIST_HEAD(&max3421_hcd->ep_list); 15092d53139fSDavid Mosberger 15102d53139fSDavid Mosberger hcd->power_budget = POWER_BUDGET; 15112d53139fSDavid Mosberger hcd->state = HC_STATE_RUNNING; 15122d53139fSDavid Mosberger hcd->uses_new_polling = 1; 15132d53139fSDavid Mosberger return 0; 15142d53139fSDavid Mosberger } 15152d53139fSDavid Mosberger 15162d53139fSDavid Mosberger static void 15172d53139fSDavid Mosberger max3421_stop(struct usb_hcd *hcd) 15182d53139fSDavid Mosberger { 15192d53139fSDavid Mosberger } 15202d53139fSDavid Mosberger 15212d53139fSDavid Mosberger static int 15222d53139fSDavid Mosberger max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) 15232d53139fSDavid Mosberger { 15242d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 15252d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15262d53139fSDavid Mosberger struct max3421_ep *max3421_ep; 15272d53139fSDavid Mosberger unsigned long flags; 15282d53139fSDavid Mosberger int retval; 15292d53139fSDavid Mosberger 15302d53139fSDavid Mosberger switch (usb_pipetype(urb->pipe)) { 15312d53139fSDavid Mosberger case PIPE_INTERRUPT: 15322d53139fSDavid Mosberger case PIPE_ISOCHRONOUS: 15332d53139fSDavid Mosberger if (urb->interval < 0) { 15342d53139fSDavid Mosberger dev_err(&spi->dev, 15352d53139fSDavid Mosberger "%s: interval=%d for intr-/iso-pipe; expected > 0\n", 15362d53139fSDavid Mosberger __func__, urb->interval); 15372d53139fSDavid Mosberger return -EINVAL; 15382d53139fSDavid Mosberger } 153993c747edSGustavo A. R. Silva break; 15402d53139fSDavid Mosberger default: 15412d53139fSDavid Mosberger break; 15422d53139fSDavid Mosberger } 15432d53139fSDavid Mosberger 15442d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 15452d53139fSDavid Mosberger 15462d53139fSDavid Mosberger max3421_ep = urb->ep->hcpriv; 15472d53139fSDavid Mosberger if (!max3421_ep) { 15482d53139fSDavid Mosberger /* gets freed in max3421_endpoint_disable: */ 15496c0f3695SAlexey Khoroshilov max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC); 155000c5aa17SDavid Mosberger-Tang if (!max3421_ep) { 155100c5aa17SDavid Mosberger-Tang retval = -ENOMEM; 155200c5aa17SDavid Mosberger-Tang goto out; 155300c5aa17SDavid Mosberger-Tang } 15542d53139fSDavid Mosberger max3421_ep->ep = urb->ep; 15552d53139fSDavid Mosberger max3421_ep->last_active = max3421_hcd->frame_number; 15562d53139fSDavid Mosberger urb->ep->hcpriv = max3421_ep; 15572d53139fSDavid Mosberger 15582d53139fSDavid Mosberger list_add_tail(&max3421_ep->ep_list, &max3421_hcd->ep_list); 15592d53139fSDavid Mosberger } 15602d53139fSDavid Mosberger 15612d53139fSDavid Mosberger retval = usb_hcd_link_urb_to_ep(hcd, urb); 15622d53139fSDavid Mosberger if (retval == 0) { 15632d53139fSDavid Mosberger /* Since we added to the queue, restart scheduling: */ 15642d53139fSDavid Mosberger max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; 15652d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 15662d53139fSDavid Mosberger } 15672d53139fSDavid Mosberger 156800c5aa17SDavid Mosberger-Tang out: 15692d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 15702d53139fSDavid Mosberger return retval; 15712d53139fSDavid Mosberger } 15722d53139fSDavid Mosberger 15732d53139fSDavid Mosberger static int 15742d53139fSDavid Mosberger max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 15752d53139fSDavid Mosberger { 15762d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15772d53139fSDavid Mosberger unsigned long flags; 15782d53139fSDavid Mosberger int retval; 15792d53139fSDavid Mosberger 15802d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 15812d53139fSDavid Mosberger 15822d53139fSDavid Mosberger /* 15832d53139fSDavid Mosberger * This will set urb->unlinked which in turn causes the entry 15842d53139fSDavid Mosberger * to be dropped at the next opportunity. 15852d53139fSDavid Mosberger */ 15862d53139fSDavid Mosberger retval = usb_hcd_check_unlink_urb(hcd, urb, status); 15872d53139fSDavid Mosberger if (retval == 0) { 15882eb5dbddSDavid Mosberger-Tang set_bit(CHECK_UNLINK, &max3421_hcd->todo); 15892d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 15902d53139fSDavid Mosberger } 15912d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 15922d53139fSDavid Mosberger return retval; 15932d53139fSDavid Mosberger } 15942d53139fSDavid Mosberger 15952d53139fSDavid Mosberger static void 15962d53139fSDavid Mosberger max3421_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) 15972d53139fSDavid Mosberger { 15982d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 15992d53139fSDavid Mosberger unsigned long flags; 16002d53139fSDavid Mosberger 16012d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 16022d53139fSDavid Mosberger 16032d53139fSDavid Mosberger if (ep->hcpriv) { 16042d53139fSDavid Mosberger struct max3421_ep *max3421_ep = ep->hcpriv; 16052d53139fSDavid Mosberger 16062d53139fSDavid Mosberger /* remove myself from the ep_list: */ 16072d53139fSDavid Mosberger if (!list_empty(&max3421_ep->ep_list)) 16082d53139fSDavid Mosberger list_del(&max3421_ep->ep_list); 16092d53139fSDavid Mosberger kfree(max3421_ep); 16102d53139fSDavid Mosberger ep->hcpriv = NULL; 16112d53139fSDavid Mosberger } 16122d53139fSDavid Mosberger 16132d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 16142d53139fSDavid Mosberger } 16152d53139fSDavid Mosberger 16162d53139fSDavid Mosberger static int 16172d53139fSDavid Mosberger max3421_get_frame_number(struct usb_hcd *hcd) 16182d53139fSDavid Mosberger { 16192d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16202d53139fSDavid Mosberger return max3421_hcd->frame_number; 16212d53139fSDavid Mosberger } 16222d53139fSDavid Mosberger 16232d53139fSDavid Mosberger /* 16242d53139fSDavid Mosberger * Should return a non-zero value when any port is undergoing a resume 16252d53139fSDavid Mosberger * transition while the root hub is suspended. 16262d53139fSDavid Mosberger */ 16272d53139fSDavid Mosberger static int 16282d53139fSDavid Mosberger max3421_hub_status_data(struct usb_hcd *hcd, char *buf) 16292d53139fSDavid Mosberger { 16302d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16312d53139fSDavid Mosberger unsigned long flags; 16322d53139fSDavid Mosberger int retval = 0; 16332d53139fSDavid Mosberger 16342d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 16352d53139fSDavid Mosberger if (!HCD_HW_ACCESSIBLE(hcd)) 16362d53139fSDavid Mosberger goto done; 16372d53139fSDavid Mosberger 16382d53139fSDavid Mosberger *buf = 0; 16392d53139fSDavid Mosberger if ((max3421_hcd->port_status & PORT_C_MASK) != 0) { 16402d53139fSDavid Mosberger *buf = (1 << 1); /* a hub over-current condition exists */ 16412d53139fSDavid Mosberger dev_dbg(hcd->self.controller, 16422d53139fSDavid Mosberger "port status 0x%08x has changes\n", 16432d53139fSDavid Mosberger max3421_hcd->port_status); 16442d53139fSDavid Mosberger retval = 1; 16452d53139fSDavid Mosberger if (max3421_hcd->rh_state == MAX3421_RH_SUSPENDED) 16462d53139fSDavid Mosberger usb_hcd_resume_root_hub(hcd); 16472d53139fSDavid Mosberger } 16482d53139fSDavid Mosberger done: 16492d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 16502d53139fSDavid Mosberger return retval; 16512d53139fSDavid Mosberger } 16522d53139fSDavid Mosberger 16532d53139fSDavid Mosberger static inline void 16542d53139fSDavid Mosberger hub_descriptor(struct usb_hub_descriptor *desc) 16552d53139fSDavid Mosberger { 16562d53139fSDavid Mosberger memset(desc, 0, sizeof(*desc)); 16572d53139fSDavid Mosberger /* 16582d53139fSDavid Mosberger * See Table 11-13: Hub Descriptor in USB 2.0 spec. 16592d53139fSDavid Mosberger */ 1660e3d02e0eSSergei Shtylyov desc->bDescriptorType = USB_DT_HUB; /* hub descriptor */ 16612d53139fSDavid Mosberger desc->bDescLength = 9; 16622e48c466SSergei Shtylyov desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | 16632e48c466SSergei Shtylyov HUB_CHAR_COMMON_OCPM); 16642d53139fSDavid Mosberger desc->bNbrPorts = 1; 16652d53139fSDavid Mosberger } 16662d53139fSDavid Mosberger 16672d53139fSDavid Mosberger /* 16682d53139fSDavid Mosberger * Set the MAX3421E general-purpose output with number PIN_NUMBER to 16692d53139fSDavid Mosberger * VALUE (0 or 1). PIN_NUMBER may be in the range from 1-8. For 16702d53139fSDavid Mosberger * any other value, this function acts as a no-op. 16712d53139fSDavid Mosberger */ 16722d53139fSDavid Mosberger static void 16732d53139fSDavid Mosberger max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) 16742d53139fSDavid Mosberger { 16752d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16762d53139fSDavid Mosberger u8 mask, idx; 16772d53139fSDavid Mosberger 16782d53139fSDavid Mosberger --pin_number; 1679721fdc83SJules Maselbas if (pin_number >= MAX3421_GPOUT_COUNT) 16802d53139fSDavid Mosberger return; 16812d53139fSDavid Mosberger 168259b71f77SJaewon Kim mask = 1u << (pin_number % 4); 16832d53139fSDavid Mosberger idx = pin_number / 4; 16842d53139fSDavid Mosberger 16852d53139fSDavid Mosberger if (value) 16862d53139fSDavid Mosberger max3421_hcd->iopins[idx] |= mask; 16872d53139fSDavid Mosberger else 16882d53139fSDavid Mosberger max3421_hcd->iopins[idx] &= ~mask; 16892eb5dbddSDavid Mosberger-Tang set_bit(IOPIN_UPDATE, &max3421_hcd->todo); 16902d53139fSDavid Mosberger wake_up_process(max3421_hcd->spi_thread); 16912d53139fSDavid Mosberger } 16922d53139fSDavid Mosberger 16932d53139fSDavid Mosberger static int 16942d53139fSDavid Mosberger max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index, 16952d53139fSDavid Mosberger char *buf, u16 length) 16962d53139fSDavid Mosberger { 16972d53139fSDavid Mosberger struct spi_device *spi = to_spi_device(hcd->self.controller); 16982d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); 16992d53139fSDavid Mosberger struct max3421_hcd_platform_data *pdata; 17002d53139fSDavid Mosberger unsigned long flags; 17012d53139fSDavid Mosberger int retval = 0; 17022d53139fSDavid Mosberger 17032d53139fSDavid Mosberger pdata = spi->dev.platform_data; 1704892f6ebcSJules Maselbas 1705892f6ebcSJules Maselbas spin_lock_irqsave(&max3421_hcd->lock, flags); 17062d53139fSDavid Mosberger 17072d53139fSDavid Mosberger switch (type_req) { 17082d53139fSDavid Mosberger case ClearHubFeature: 17092d53139fSDavid Mosberger break; 17102d53139fSDavid Mosberger case ClearPortFeature: 17112d53139fSDavid Mosberger switch (value) { 17122d53139fSDavid Mosberger case USB_PORT_FEAT_SUSPEND: 17132d53139fSDavid Mosberger break; 17142d53139fSDavid Mosberger case USB_PORT_FEAT_POWER: 17152d53139fSDavid Mosberger dev_dbg(hcd->self.controller, "power-off\n"); 17164055e5e5SDavid Mosberger-Tang max3421_gpout_set_value(hcd, pdata->vbus_gpout, 17174055e5e5SDavid Mosberger-Tang !pdata->vbus_active_level); 17180d9b6d49SGustavo A. R. Silva fallthrough; 17192d53139fSDavid Mosberger default: 17202d53139fSDavid Mosberger max3421_hcd->port_status &= ~(1 << value); 17212d53139fSDavid Mosberger } 17222d53139fSDavid Mosberger break; 17232d53139fSDavid Mosberger case GetHubDescriptor: 17242d53139fSDavid Mosberger hub_descriptor((struct usb_hub_descriptor *) buf); 17252d53139fSDavid Mosberger break; 17262d53139fSDavid Mosberger 17272d53139fSDavid Mosberger case DeviceRequest | USB_REQ_GET_DESCRIPTOR: 17282d53139fSDavid Mosberger case GetPortErrorCount: 17292d53139fSDavid Mosberger case SetHubDepth: 17302d53139fSDavid Mosberger /* USB3 only */ 17312d53139fSDavid Mosberger goto error; 17322d53139fSDavid Mosberger 17332d53139fSDavid Mosberger case GetHubStatus: 17342d53139fSDavid Mosberger *(__le32 *) buf = cpu_to_le32(0); 17352d53139fSDavid Mosberger break; 17362d53139fSDavid Mosberger 17372d53139fSDavid Mosberger case GetPortStatus: 17382d53139fSDavid Mosberger if (index != 1) { 17392d53139fSDavid Mosberger retval = -EPIPE; 17402d53139fSDavid Mosberger goto error; 17412d53139fSDavid Mosberger } 17422d53139fSDavid Mosberger ((__le16 *) buf)[0] = cpu_to_le16(max3421_hcd->port_status); 17432d53139fSDavid Mosberger ((__le16 *) buf)[1] = 17442d53139fSDavid Mosberger cpu_to_le16(max3421_hcd->port_status >> 16); 17452d53139fSDavid Mosberger break; 17462d53139fSDavid Mosberger 17472d53139fSDavid Mosberger case SetHubFeature: 17482d53139fSDavid Mosberger retval = -EPIPE; 17492d53139fSDavid Mosberger break; 17502d53139fSDavid Mosberger 17512d53139fSDavid Mosberger case SetPortFeature: 17522d53139fSDavid Mosberger switch (value) { 17532d53139fSDavid Mosberger case USB_PORT_FEAT_LINK_STATE: 17542d53139fSDavid Mosberger case USB_PORT_FEAT_U1_TIMEOUT: 17552d53139fSDavid Mosberger case USB_PORT_FEAT_U2_TIMEOUT: 17562d53139fSDavid Mosberger case USB_PORT_FEAT_BH_PORT_RESET: 17572d53139fSDavid Mosberger goto error; 17582d53139fSDavid Mosberger case USB_PORT_FEAT_SUSPEND: 17592d53139fSDavid Mosberger if (max3421_hcd->active) 17602d53139fSDavid Mosberger max3421_hcd->port_status |= 17612d53139fSDavid Mosberger USB_PORT_STAT_SUSPEND; 17622d53139fSDavid Mosberger break; 17632d53139fSDavid Mosberger case USB_PORT_FEAT_POWER: 17642d53139fSDavid Mosberger dev_dbg(hcd->self.controller, "power-on\n"); 17652d53139fSDavid Mosberger max3421_hcd->port_status |= USB_PORT_STAT_POWER; 17664055e5e5SDavid Mosberger-Tang max3421_gpout_set_value(hcd, pdata->vbus_gpout, 17674055e5e5SDavid Mosberger-Tang pdata->vbus_active_level); 17682d53139fSDavid Mosberger break; 17692d53139fSDavid Mosberger case USB_PORT_FEAT_RESET: 17702d53139fSDavid Mosberger max3421_reset_port(hcd); 17710d9b6d49SGustavo A. R. Silva fallthrough; 17722d53139fSDavid Mosberger default: 17732d53139fSDavid Mosberger if ((max3421_hcd->port_status & USB_PORT_STAT_POWER) 17742d53139fSDavid Mosberger != 0) 17752d53139fSDavid Mosberger max3421_hcd->port_status |= (1 << value); 17762d53139fSDavid Mosberger } 17772d53139fSDavid Mosberger break; 17782d53139fSDavid Mosberger 17792d53139fSDavid Mosberger default: 17802d53139fSDavid Mosberger dev_dbg(hcd->self.controller, 17812d53139fSDavid Mosberger "hub control req%04x v%04x i%04x l%d\n", 17822d53139fSDavid Mosberger type_req, value, index, length); 17832d53139fSDavid Mosberger error: /* "protocol stall" on error */ 17842d53139fSDavid Mosberger retval = -EPIPE; 17852d53139fSDavid Mosberger } 17862d53139fSDavid Mosberger 17872d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 17882d53139fSDavid Mosberger return retval; 17892d53139fSDavid Mosberger } 17902d53139fSDavid Mosberger 17912d53139fSDavid Mosberger static int 17922d53139fSDavid Mosberger max3421_bus_suspend(struct usb_hcd *hcd) 17932d53139fSDavid Mosberger { 17942d53139fSDavid Mosberger return -1; 17952d53139fSDavid Mosberger } 17962d53139fSDavid Mosberger 17972d53139fSDavid Mosberger static int 17982d53139fSDavid Mosberger max3421_bus_resume(struct usb_hcd *hcd) 17992d53139fSDavid Mosberger { 18002d53139fSDavid Mosberger return -1; 18012d53139fSDavid Mosberger } 18022d53139fSDavid Mosberger 1803887e2e0cSJulia Lawall static const struct hc_driver max3421_hcd_desc = { 18042d53139fSDavid Mosberger .description = "max3421", 18052d53139fSDavid Mosberger .product_desc = DRIVER_DESC, 18062d53139fSDavid Mosberger .hcd_priv_size = sizeof(struct max3421_hcd), 18072d53139fSDavid Mosberger .flags = HCD_USB11, 18082d53139fSDavid Mosberger .reset = max3421_reset, 18092d53139fSDavid Mosberger .start = max3421_start, 18102d53139fSDavid Mosberger .stop = max3421_stop, 18112d53139fSDavid Mosberger .get_frame_number = max3421_get_frame_number, 18122d53139fSDavid Mosberger .urb_enqueue = max3421_urb_enqueue, 18132d53139fSDavid Mosberger .urb_dequeue = max3421_urb_dequeue, 18142d53139fSDavid Mosberger .endpoint_disable = max3421_endpoint_disable, 18152d53139fSDavid Mosberger .hub_status_data = max3421_hub_status_data, 18162d53139fSDavid Mosberger .hub_control = max3421_hub_control, 18172d53139fSDavid Mosberger .bus_suspend = max3421_bus_suspend, 18182d53139fSDavid Mosberger .bus_resume = max3421_bus_resume, 18192d53139fSDavid Mosberger }; 18202d53139fSDavid Mosberger 18212d53139fSDavid Mosberger static int 1822721fdc83SJules Maselbas max3421_of_vbus_en_pin(struct device *dev, struct max3421_hcd_platform_data *pdata) 1823721fdc83SJules Maselbas { 1824721fdc83SJules Maselbas int retval; 1825721fdc83SJules Maselbas uint32_t value[2]; 1826721fdc83SJules Maselbas 1827721fdc83SJules Maselbas if (!pdata) 1828721fdc83SJules Maselbas return -EINVAL; 1829721fdc83SJules Maselbas 1830721fdc83SJules Maselbas retval = of_property_read_u32_array(dev->of_node, "maxim,vbus-en-pin", value, 2); 1831721fdc83SJules Maselbas if (retval) { 1832721fdc83SJules Maselbas dev_err(dev, "device tree node property 'maxim,vbus-en-pin' is missing\n"); 1833721fdc83SJules Maselbas return retval; 1834721fdc83SJules Maselbas } 1835721fdc83SJules Maselbas dev_info(dev, "property 'maxim,vbus-en-pin' value is <%d %d>\n", value[0], value[1]); 1836721fdc83SJules Maselbas 1837721fdc83SJules Maselbas pdata->vbus_gpout = value[0]; 1838721fdc83SJules Maselbas pdata->vbus_active_level = value[1]; 1839721fdc83SJules Maselbas 1840721fdc83SJules Maselbas return 0; 1841721fdc83SJules Maselbas } 1842721fdc83SJules Maselbas 1843721fdc83SJules Maselbas static int 18442d53139fSDavid Mosberger max3421_probe(struct spi_device *spi) 18452d53139fSDavid Mosberger { 1846721fdc83SJules Maselbas struct device *dev = &spi->dev; 18472d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd; 184805dfa5c9SDavid Mosberger-Tang struct usb_hcd *hcd = NULL; 1849721fdc83SJules Maselbas struct max3421_hcd_platform_data *pdata = NULL; 18505a569343SYang Yingliang int retval; 18512d53139fSDavid Mosberger 18522d53139fSDavid Mosberger if (spi_setup(spi) < 0) { 18532d53139fSDavid Mosberger dev_err(&spi->dev, "Unable to setup SPI bus"); 18542d53139fSDavid Mosberger return -EFAULT; 18552d53139fSDavid Mosberger } 18562d53139fSDavid Mosberger 1857721fdc83SJules Maselbas if (!spi->irq) { 1858721fdc83SJules Maselbas dev_err(dev, "Failed to get SPI IRQ"); 1859721fdc83SJules Maselbas return -EFAULT; 1860721fdc83SJules Maselbas } 1861721fdc83SJules Maselbas 1862721fdc83SJules Maselbas if (IS_ENABLED(CONFIG_OF) && dev->of_node) { 1863721fdc83SJules Maselbas pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); 1864721fdc83SJules Maselbas if (!pdata) { 1865721fdc83SJules Maselbas retval = -ENOMEM; 1866721fdc83SJules Maselbas goto error; 1867721fdc83SJules Maselbas } 1868721fdc83SJules Maselbas retval = max3421_of_vbus_en_pin(dev, pdata); 1869721fdc83SJules Maselbas if (retval) 1870721fdc83SJules Maselbas goto error; 1871721fdc83SJules Maselbas 1872721fdc83SJules Maselbas spi->dev.platform_data = pdata; 1873721fdc83SJules Maselbas } 1874721fdc83SJules Maselbas 1875721fdc83SJules Maselbas pdata = spi->dev.platform_data; 1876721fdc83SJules Maselbas if (!pdata) { 1877721fdc83SJules Maselbas dev_err(&spi->dev, "driver configuration data is not provided\n"); 1878721fdc83SJules Maselbas retval = -EFAULT; 1879721fdc83SJules Maselbas goto error; 1880721fdc83SJules Maselbas } 1881721fdc83SJules Maselbas if (pdata->vbus_active_level > 1) { 1882721fdc83SJules Maselbas dev_err(&spi->dev, "vbus active level value %d is out of range (0/1)\n", pdata->vbus_active_level); 1883721fdc83SJules Maselbas retval = -EINVAL; 1884721fdc83SJules Maselbas goto error; 1885721fdc83SJules Maselbas } 1886721fdc83SJules Maselbas if (pdata->vbus_gpout < 1 || pdata->vbus_gpout > MAX3421_GPOUT_COUNT) { 1887721fdc83SJules Maselbas dev_err(&spi->dev, "vbus gpout value %d is out of range (1..8)\n", pdata->vbus_gpout); 1888721fdc83SJules Maselbas retval = -EINVAL; 1889721fdc83SJules Maselbas goto error; 1890721fdc83SJules Maselbas } 1891721fdc83SJules Maselbas 18925a569343SYang Yingliang retval = -ENOMEM; 18932d53139fSDavid Mosberger hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev, 18942d53139fSDavid Mosberger dev_name(&spi->dev)); 18952d53139fSDavid Mosberger if (!hcd) { 18962d53139fSDavid Mosberger dev_err(&spi->dev, "failed to create HCD structure\n"); 189705dfa5c9SDavid Mosberger-Tang goto error; 18982d53139fSDavid Mosberger } 18992d53139fSDavid Mosberger set_bit(HCD_FLAG_POLL_RH, &hcd->flags); 19002d53139fSDavid Mosberger max3421_hcd = hcd_to_max3421(hcd); 19012d53139fSDavid Mosberger max3421_hcd->next = max3421_hcd_list; 19022d53139fSDavid Mosberger max3421_hcd_list = max3421_hcd; 19032d53139fSDavid Mosberger INIT_LIST_HEAD(&max3421_hcd->ep_list); 19042d53139fSDavid Mosberger 190505dfa5c9SDavid Mosberger-Tang max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); 190613dcf780SWolfram Sang if (!max3421_hcd->tx) 190705dfa5c9SDavid Mosberger-Tang goto error; 190805dfa5c9SDavid Mosberger-Tang max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); 190913dcf780SWolfram Sang if (!max3421_hcd->rx) 191005dfa5c9SDavid Mosberger-Tang goto error; 191105dfa5c9SDavid Mosberger-Tang 19122d53139fSDavid Mosberger max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, 19132d53139fSDavid Mosberger "max3421_spi_thread"); 19142d53139fSDavid Mosberger if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) { 19152d53139fSDavid Mosberger dev_err(&spi->dev, 19162d53139fSDavid Mosberger "failed to create SPI thread (out of memory)\n"); 191705dfa5c9SDavid Mosberger-Tang goto error; 19182d53139fSDavid Mosberger } 19192d53139fSDavid Mosberger 19202d53139fSDavid Mosberger retval = usb_add_hcd(hcd, 0, 0); 19212d53139fSDavid Mosberger if (retval) { 19222d53139fSDavid Mosberger dev_err(&spi->dev, "failed to add HCD\n"); 192305dfa5c9SDavid Mosberger-Tang goto error; 19242d53139fSDavid Mosberger } 19252d53139fSDavid Mosberger 19262d53139fSDavid Mosberger retval = request_irq(spi->irq, max3421_irq_handler, 19272d53139fSDavid Mosberger IRQF_TRIGGER_LOW, "max3421", hcd); 19282d53139fSDavid Mosberger if (retval < 0) { 19292d53139fSDavid Mosberger dev_err(&spi->dev, "failed to request irq %d\n", spi->irq); 193005dfa5c9SDavid Mosberger-Tang goto error; 19312d53139fSDavid Mosberger } 19322d53139fSDavid Mosberger return 0; 193305dfa5c9SDavid Mosberger-Tang 193405dfa5c9SDavid Mosberger-Tang error: 1935721fdc83SJules Maselbas if (IS_ENABLED(CONFIG_OF) && dev->of_node && pdata) { 1936721fdc83SJules Maselbas devm_kfree(&spi->dev, pdata); 1937721fdc83SJules Maselbas spi->dev.platform_data = NULL; 1938721fdc83SJules Maselbas } 1939721fdc83SJules Maselbas 194005dfa5c9SDavid Mosberger-Tang if (hcd) { 194105dfa5c9SDavid Mosberger-Tang kfree(max3421_hcd->tx); 194205dfa5c9SDavid Mosberger-Tang kfree(max3421_hcd->rx); 194305dfa5c9SDavid Mosberger-Tang if (max3421_hcd->spi_thread) 194405dfa5c9SDavid Mosberger-Tang kthread_stop(max3421_hcd->spi_thread); 194505dfa5c9SDavid Mosberger-Tang usb_put_hcd(hcd); 194605dfa5c9SDavid Mosberger-Tang } 194705dfa5c9SDavid Mosberger-Tang return retval; 19482d53139fSDavid Mosberger } 19492d53139fSDavid Mosberger 19502d53139fSDavid Mosberger static int 19512d53139fSDavid Mosberger max3421_remove(struct spi_device *spi) 19522d53139fSDavid Mosberger { 19532d53139fSDavid Mosberger struct max3421_hcd *max3421_hcd = NULL, **prev; 19542d53139fSDavid Mosberger struct usb_hcd *hcd = NULL; 19552d53139fSDavid Mosberger unsigned long flags; 19562d53139fSDavid Mosberger 19572d53139fSDavid Mosberger for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { 19582d53139fSDavid Mosberger max3421_hcd = *prev; 19592d53139fSDavid Mosberger hcd = max3421_to_hcd(max3421_hcd); 19602d53139fSDavid Mosberger if (hcd->self.controller == &spi->dev) 19612d53139fSDavid Mosberger break; 19622d53139fSDavid Mosberger } 19632d53139fSDavid Mosberger if (!max3421_hcd) { 19642d53139fSDavid Mosberger dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", 19652d53139fSDavid Mosberger spi); 19662d53139fSDavid Mosberger return -ENODEV; 19672d53139fSDavid Mosberger } 19682d53139fSDavid Mosberger 19692d53139fSDavid Mosberger usb_remove_hcd(hcd); 19702d53139fSDavid Mosberger 19712d53139fSDavid Mosberger spin_lock_irqsave(&max3421_hcd->lock, flags); 19722d53139fSDavid Mosberger 19732d53139fSDavid Mosberger kthread_stop(max3421_hcd->spi_thread); 19742d53139fSDavid Mosberger *prev = max3421_hcd->next; 19752d53139fSDavid Mosberger 19762d53139fSDavid Mosberger spin_unlock_irqrestore(&max3421_hcd->lock, flags); 19772d53139fSDavid Mosberger 19782d53139fSDavid Mosberger free_irq(spi->irq, hcd); 19792d53139fSDavid Mosberger 19802d53139fSDavid Mosberger usb_put_hcd(hcd); 19812d53139fSDavid Mosberger return 0; 19822d53139fSDavid Mosberger } 19832d53139fSDavid Mosberger 1984721fdc83SJules Maselbas static const struct of_device_id max3421_of_match_table[] = { 1985721fdc83SJules Maselbas { .compatible = "maxim,max3421", }, 1986721fdc83SJules Maselbas {}, 1987721fdc83SJules Maselbas }; 1988721fdc83SJules Maselbas MODULE_DEVICE_TABLE(of, max3421_of_match_table); 1989721fdc83SJules Maselbas 19902d53139fSDavid Mosberger static struct spi_driver max3421_driver = { 19912d53139fSDavid Mosberger .probe = max3421_probe, 19922d53139fSDavid Mosberger .remove = max3421_remove, 19932d53139fSDavid Mosberger .driver = { 19942d53139fSDavid Mosberger .name = "max3421-hcd", 1995721fdc83SJules Maselbas .of_match_table = of_match_ptr(max3421_of_match_table), 19962d53139fSDavid Mosberger }, 19972d53139fSDavid Mosberger }; 19982d53139fSDavid Mosberger 19997df45d5fSSachin Kamat module_spi_driver(max3421_driver); 20002d53139fSDavid Mosberger 20012d53139fSDavid Mosberger MODULE_DESCRIPTION(DRIVER_DESC); 20022d53139fSDavid Mosberger MODULE_AUTHOR("David Mosberger <davidm@egauge.net>"); 20032d53139fSDavid Mosberger MODULE_LICENSE("GPL"); 2004