1*c46a74ffSMary Strodl // SPDX-License-Identifier: GPL-2.0-only 2*c46a74ffSMary Strodl /* 3*c46a74ffSMary Strodl * FTDI MPSSE GPIO support 4*c46a74ffSMary Strodl * 5*c46a74ffSMary Strodl * Based on code by Anatolij Gustschin 6*c46a74ffSMary Strodl * 7*c46a74ffSMary Strodl * Copyright (C) 2024 Mary Strodl <mstrodl@csh.rit.edu> 8*c46a74ffSMary Strodl */ 9*c46a74ffSMary Strodl 10*c46a74ffSMary Strodl #include <linux/cleanup.h> 11*c46a74ffSMary Strodl #include <linux/gpio/driver.h> 12*c46a74ffSMary Strodl #include <linux/mutex.h> 13*c46a74ffSMary Strodl #include <linux/usb.h> 14*c46a74ffSMary Strodl 15*c46a74ffSMary Strodl struct mpsse_priv { 16*c46a74ffSMary Strodl struct gpio_chip gpio; 17*c46a74ffSMary Strodl struct usb_device *udev; /* USB device encompassing all MPSSEs */ 18*c46a74ffSMary Strodl struct usb_interface *intf; /* USB interface for this MPSSE */ 19*c46a74ffSMary Strodl u8 intf_id; /* USB interface number for this MPSSE */ 20*c46a74ffSMary Strodl struct work_struct irq_work; /* polling work thread */ 21*c46a74ffSMary Strodl struct mutex irq_mutex; /* lock over irq_data */ 22*c46a74ffSMary Strodl atomic_t irq_type[16]; /* pin -> edge detection type */ 23*c46a74ffSMary Strodl atomic_t irq_enabled; 24*c46a74ffSMary Strodl int id; 25*c46a74ffSMary Strodl 26*c46a74ffSMary Strodl u8 gpio_outputs[2]; /* Output states for GPIOs [L, H] */ 27*c46a74ffSMary Strodl u8 gpio_dir[2]; /* Directions for GPIOs [L, H] */ 28*c46a74ffSMary Strodl 29*c46a74ffSMary Strodl u8 *bulk_in_buf; /* Extra recv buffer to grab status bytes */ 30*c46a74ffSMary Strodl 31*c46a74ffSMary Strodl struct usb_endpoint_descriptor *bulk_in; 32*c46a74ffSMary Strodl struct usb_endpoint_descriptor *bulk_out; 33*c46a74ffSMary Strodl 34*c46a74ffSMary Strodl struct mutex io_mutex; /* sync I/O with disconnect */ 35*c46a74ffSMary Strodl }; 36*c46a74ffSMary Strodl 37*c46a74ffSMary Strodl struct bulk_desc { 38*c46a74ffSMary Strodl bool tx; /* direction of bulk transfer */ 39*c46a74ffSMary Strodl u8 *data; /* input (tx) or output (rx) */ 40*c46a74ffSMary Strodl int len; /* Length of `data` if tx, or length of */ 41*c46a74ffSMary Strodl /* Data to read if rx */ 42*c46a74ffSMary Strodl int len_actual; /* Length successfully transferred */ 43*c46a74ffSMary Strodl int timeout; 44*c46a74ffSMary Strodl }; 45*c46a74ffSMary Strodl 46*c46a74ffSMary Strodl static const struct usb_device_id gpio_mpsse_table[] = { 47*c46a74ffSMary Strodl { USB_DEVICE(0x0c52, 0xa064) }, /* SeaLevel Systems, Inc. */ 48*c46a74ffSMary Strodl { } /* Terminating entry */ 49*c46a74ffSMary Strodl }; 50*c46a74ffSMary Strodl 51*c46a74ffSMary Strodl MODULE_DEVICE_TABLE(usb, gpio_mpsse_table); 52*c46a74ffSMary Strodl 53*c46a74ffSMary Strodl static DEFINE_IDA(gpio_mpsse_ida); 54*c46a74ffSMary Strodl 55*c46a74ffSMary Strodl /* MPSSE commands */ 56*c46a74ffSMary Strodl #define SET_BITS_CMD 0x80 57*c46a74ffSMary Strodl #define GET_BITS_CMD 0x81 58*c46a74ffSMary Strodl 59*c46a74ffSMary Strodl #define SET_BITMODE_REQUEST 0x0B 60*c46a74ffSMary Strodl #define MODE_MPSSE (2 << 8) 61*c46a74ffSMary Strodl #define MODE_RESET 0 62*c46a74ffSMary Strodl 63*c46a74ffSMary Strodl /* Arbitrarily decided. This could probably be much less */ 64*c46a74ffSMary Strodl #define MPSSE_WRITE_TIMEOUT 5000 65*c46a74ffSMary Strodl #define MPSSE_READ_TIMEOUT 5000 66*c46a74ffSMary Strodl 67*c46a74ffSMary Strodl /* 1 millisecond, also pretty arbitrary */ 68*c46a74ffSMary Strodl #define MPSSE_POLL_INTERVAL 1000 69*c46a74ffSMary Strodl 70*c46a74ffSMary Strodl static int mpsse_bulk_xfer(struct usb_interface *intf, struct bulk_desc *desc) 71*c46a74ffSMary Strodl { 72*c46a74ffSMary Strodl struct mpsse_priv *priv = usb_get_intfdata(intf); 73*c46a74ffSMary Strodl struct usb_device *udev = priv->udev; 74*c46a74ffSMary Strodl unsigned int pipe; 75*c46a74ffSMary Strodl int ret; 76*c46a74ffSMary Strodl 77*c46a74ffSMary Strodl if (desc->tx) 78*c46a74ffSMary Strodl pipe = usb_sndbulkpipe(udev, priv->bulk_out->bEndpointAddress); 79*c46a74ffSMary Strodl else 80*c46a74ffSMary Strodl pipe = usb_rcvbulkpipe(udev, priv->bulk_in->bEndpointAddress); 81*c46a74ffSMary Strodl 82*c46a74ffSMary Strodl ret = usb_bulk_msg(udev, pipe, desc->data, desc->len, 83*c46a74ffSMary Strodl &desc->len_actual, desc->timeout); 84*c46a74ffSMary Strodl if (ret) 85*c46a74ffSMary Strodl dev_dbg(&udev->dev, "mpsse: bulk transfer failed: %d\n", ret); 86*c46a74ffSMary Strodl 87*c46a74ffSMary Strodl return ret; 88*c46a74ffSMary Strodl } 89*c46a74ffSMary Strodl 90*c46a74ffSMary Strodl static int mpsse_write(struct usb_interface *intf, 91*c46a74ffSMary Strodl u8 *buf, size_t len) 92*c46a74ffSMary Strodl { 93*c46a74ffSMary Strodl int ret; 94*c46a74ffSMary Strodl struct bulk_desc desc; 95*c46a74ffSMary Strodl 96*c46a74ffSMary Strodl desc.len_actual = 0; 97*c46a74ffSMary Strodl desc.tx = true; 98*c46a74ffSMary Strodl desc.data = buf; 99*c46a74ffSMary Strodl desc.len = len; 100*c46a74ffSMary Strodl desc.timeout = MPSSE_WRITE_TIMEOUT; 101*c46a74ffSMary Strodl 102*c46a74ffSMary Strodl ret = mpsse_bulk_xfer(intf, &desc); 103*c46a74ffSMary Strodl 104*c46a74ffSMary Strodl return ret; 105*c46a74ffSMary Strodl } 106*c46a74ffSMary Strodl 107*c46a74ffSMary Strodl static int mpsse_read(struct usb_interface *intf, u8 *buf, size_t len) 108*c46a74ffSMary Strodl { 109*c46a74ffSMary Strodl int ret; 110*c46a74ffSMary Strodl struct bulk_desc desc; 111*c46a74ffSMary Strodl struct mpsse_priv *priv = usb_get_intfdata(intf); 112*c46a74ffSMary Strodl 113*c46a74ffSMary Strodl desc.len_actual = 0; 114*c46a74ffSMary Strodl desc.tx = false; 115*c46a74ffSMary Strodl desc.data = priv->bulk_in_buf; 116*c46a74ffSMary Strodl /* Device sends 2 additional status bytes, read len + 2 */ 117*c46a74ffSMary Strodl desc.len = min_t(size_t, len + 2, usb_endpoint_maxp(priv->bulk_in)); 118*c46a74ffSMary Strodl desc.timeout = MPSSE_READ_TIMEOUT; 119*c46a74ffSMary Strodl 120*c46a74ffSMary Strodl ret = mpsse_bulk_xfer(intf, &desc); 121*c46a74ffSMary Strodl if (ret) 122*c46a74ffSMary Strodl return ret; 123*c46a74ffSMary Strodl 124*c46a74ffSMary Strodl /* Did we get enough data? */ 125*c46a74ffSMary Strodl if (desc.len_actual < desc.len) 126*c46a74ffSMary Strodl return -EIO; 127*c46a74ffSMary Strodl 128*c46a74ffSMary Strodl memcpy(buf, desc.data + 2, desc.len_actual - 2); 129*c46a74ffSMary Strodl 130*c46a74ffSMary Strodl return ret; 131*c46a74ffSMary Strodl } 132*c46a74ffSMary Strodl 133*c46a74ffSMary Strodl static int gpio_mpsse_set_bank(struct mpsse_priv *priv, u8 bank) 134*c46a74ffSMary Strodl { 135*c46a74ffSMary Strodl int ret; 136*c46a74ffSMary Strodl u8 tx_buf[3] = { 137*c46a74ffSMary Strodl SET_BITS_CMD | (bank << 1), 138*c46a74ffSMary Strodl priv->gpio_outputs[bank], 139*c46a74ffSMary Strodl priv->gpio_dir[bank], 140*c46a74ffSMary Strodl }; 141*c46a74ffSMary Strodl 142*c46a74ffSMary Strodl ret = mpsse_write(priv->intf, tx_buf, 3); 143*c46a74ffSMary Strodl 144*c46a74ffSMary Strodl return ret; 145*c46a74ffSMary Strodl } 146*c46a74ffSMary Strodl 147*c46a74ffSMary Strodl static int gpio_mpsse_get_bank(struct mpsse_priv *priv, u8 bank) 148*c46a74ffSMary Strodl { 149*c46a74ffSMary Strodl int ret; 150*c46a74ffSMary Strodl u8 buf = GET_BITS_CMD | (bank << 1); 151*c46a74ffSMary Strodl 152*c46a74ffSMary Strodl ret = mpsse_write(priv->intf, &buf, 1); 153*c46a74ffSMary Strodl if (ret) 154*c46a74ffSMary Strodl return ret; 155*c46a74ffSMary Strodl 156*c46a74ffSMary Strodl ret = mpsse_read(priv->intf, &buf, 1); 157*c46a74ffSMary Strodl if (ret) 158*c46a74ffSMary Strodl return ret; 159*c46a74ffSMary Strodl 160*c46a74ffSMary Strodl return buf; 161*c46a74ffSMary Strodl } 162*c46a74ffSMary Strodl 163*c46a74ffSMary Strodl static void gpio_mpsse_set_multiple(struct gpio_chip *chip, unsigned long *mask, 164*c46a74ffSMary Strodl unsigned long *bits) 165*c46a74ffSMary Strodl { 166*c46a74ffSMary Strodl unsigned long i, bank, bank_mask, bank_bits; 167*c46a74ffSMary Strodl int ret; 168*c46a74ffSMary Strodl struct mpsse_priv *priv = gpiochip_get_data(chip); 169*c46a74ffSMary Strodl 170*c46a74ffSMary Strodl guard(mutex)(&priv->io_mutex); 171*c46a74ffSMary Strodl for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { 172*c46a74ffSMary Strodl bank = i / 8; 173*c46a74ffSMary Strodl 174*c46a74ffSMary Strodl if (bank_mask) { 175*c46a74ffSMary Strodl bank_bits = bitmap_get_value8(bits, i); 176*c46a74ffSMary Strodl /* Zero out pins we want to change */ 177*c46a74ffSMary Strodl priv->gpio_outputs[bank] &= ~bank_mask; 178*c46a74ffSMary Strodl /* Set pins we care about */ 179*c46a74ffSMary Strodl priv->gpio_outputs[bank] |= bank_bits & bank_mask; 180*c46a74ffSMary Strodl 181*c46a74ffSMary Strodl ret = gpio_mpsse_set_bank(priv, bank); 182*c46a74ffSMary Strodl if (ret) 183*c46a74ffSMary Strodl dev_err(&priv->intf->dev, 184*c46a74ffSMary Strodl "Couldn't set values for bank %ld!", 185*c46a74ffSMary Strodl bank); 186*c46a74ffSMary Strodl } 187*c46a74ffSMary Strodl } 188*c46a74ffSMary Strodl } 189*c46a74ffSMary Strodl 190*c46a74ffSMary Strodl static int gpio_mpsse_get_multiple(struct gpio_chip *chip, unsigned long *mask, 191*c46a74ffSMary Strodl unsigned long *bits) 192*c46a74ffSMary Strodl { 193*c46a74ffSMary Strodl unsigned long i, bank, bank_mask; 194*c46a74ffSMary Strodl int ret; 195*c46a74ffSMary Strodl struct mpsse_priv *priv = gpiochip_get_data(chip); 196*c46a74ffSMary Strodl 197*c46a74ffSMary Strodl guard(mutex)(&priv->io_mutex); 198*c46a74ffSMary Strodl for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { 199*c46a74ffSMary Strodl bank = i / 8; 200*c46a74ffSMary Strodl 201*c46a74ffSMary Strodl if (bank_mask) { 202*c46a74ffSMary Strodl ret = gpio_mpsse_get_bank(priv, bank); 203*c46a74ffSMary Strodl if (ret < 0) 204*c46a74ffSMary Strodl return ret; 205*c46a74ffSMary Strodl 206*c46a74ffSMary Strodl bitmap_set_value8(bits, ret & bank_mask, i); 207*c46a74ffSMary Strodl } 208*c46a74ffSMary Strodl } 209*c46a74ffSMary Strodl 210*c46a74ffSMary Strodl return 0; 211*c46a74ffSMary Strodl } 212*c46a74ffSMary Strodl 213*c46a74ffSMary Strodl static int gpio_mpsse_gpio_get(struct gpio_chip *chip, unsigned int offset) 214*c46a74ffSMary Strodl { 215*c46a74ffSMary Strodl int err; 216*c46a74ffSMary Strodl unsigned long mask = 0, bits = 0; 217*c46a74ffSMary Strodl 218*c46a74ffSMary Strodl __set_bit(offset, &mask); 219*c46a74ffSMary Strodl err = gpio_mpsse_get_multiple(chip, &mask, &bits); 220*c46a74ffSMary Strodl if (err) 221*c46a74ffSMary Strodl return err; 222*c46a74ffSMary Strodl 223*c46a74ffSMary Strodl /* == is not guaranteed to give 1 if true */ 224*c46a74ffSMary Strodl if (bits) 225*c46a74ffSMary Strodl return 1; 226*c46a74ffSMary Strodl else 227*c46a74ffSMary Strodl return 0; 228*c46a74ffSMary Strodl } 229*c46a74ffSMary Strodl 230*c46a74ffSMary Strodl static void gpio_mpsse_gpio_set(struct gpio_chip *chip, unsigned int offset, 231*c46a74ffSMary Strodl int value) 232*c46a74ffSMary Strodl { 233*c46a74ffSMary Strodl unsigned long mask = 0, bits = 0; 234*c46a74ffSMary Strodl 235*c46a74ffSMary Strodl __set_bit(offset, &mask); 236*c46a74ffSMary Strodl if (value) 237*c46a74ffSMary Strodl __set_bit(offset, &bits); 238*c46a74ffSMary Strodl 239*c46a74ffSMary Strodl gpio_mpsse_set_multiple(chip, &mask, &bits); 240*c46a74ffSMary Strodl } 241*c46a74ffSMary Strodl 242*c46a74ffSMary Strodl static int gpio_mpsse_direction_output(struct gpio_chip *chip, 243*c46a74ffSMary Strodl unsigned int offset, int value) 244*c46a74ffSMary Strodl { 245*c46a74ffSMary Strodl struct mpsse_priv *priv = gpiochip_get_data(chip); 246*c46a74ffSMary Strodl int bank = (offset & 8) >> 3; 247*c46a74ffSMary Strodl int bank_offset = offset & 7; 248*c46a74ffSMary Strodl 249*c46a74ffSMary Strodl scoped_guard(mutex, &priv->io_mutex) 250*c46a74ffSMary Strodl priv->gpio_dir[bank] |= BIT(bank_offset); 251*c46a74ffSMary Strodl 252*c46a74ffSMary Strodl gpio_mpsse_gpio_set(chip, offset, value); 253*c46a74ffSMary Strodl 254*c46a74ffSMary Strodl return 0; 255*c46a74ffSMary Strodl } 256*c46a74ffSMary Strodl 257*c46a74ffSMary Strodl static int gpio_mpsse_direction_input(struct gpio_chip *chip, 258*c46a74ffSMary Strodl unsigned int offset) 259*c46a74ffSMary Strodl { 260*c46a74ffSMary Strodl struct mpsse_priv *priv = gpiochip_get_data(chip); 261*c46a74ffSMary Strodl int bank = (offset & 8) >> 3; 262*c46a74ffSMary Strodl int bank_offset = offset & 7; 263*c46a74ffSMary Strodl 264*c46a74ffSMary Strodl guard(mutex)(&priv->io_mutex); 265*c46a74ffSMary Strodl priv->gpio_dir[bank] &= ~BIT(bank_offset); 266*c46a74ffSMary Strodl gpio_mpsse_set_bank(priv, bank); 267*c46a74ffSMary Strodl 268*c46a74ffSMary Strodl return 0; 269*c46a74ffSMary Strodl } 270*c46a74ffSMary Strodl 271*c46a74ffSMary Strodl static int gpio_mpsse_get_direction(struct gpio_chip *chip, 272*c46a74ffSMary Strodl unsigned int offset) 273*c46a74ffSMary Strodl { 274*c46a74ffSMary Strodl int ret; 275*c46a74ffSMary Strodl int bank = (offset & 8) >> 3; 276*c46a74ffSMary Strodl int bank_offset = offset & 7; 277*c46a74ffSMary Strodl struct mpsse_priv *priv = gpiochip_get_data(chip); 278*c46a74ffSMary Strodl 279*c46a74ffSMary Strodl guard(mutex)(&priv->io_mutex); 280*c46a74ffSMary Strodl /* MPSSE directions are inverted */ 281*c46a74ffSMary Strodl if (priv->gpio_dir[bank] & BIT(bank_offset)) 282*c46a74ffSMary Strodl ret = GPIO_LINE_DIRECTION_OUT; 283*c46a74ffSMary Strodl else 284*c46a74ffSMary Strodl ret = GPIO_LINE_DIRECTION_IN; 285*c46a74ffSMary Strodl 286*c46a74ffSMary Strodl return ret; 287*c46a74ffSMary Strodl } 288*c46a74ffSMary Strodl 289*c46a74ffSMary Strodl static void gpio_mpsse_poll(struct work_struct *work) 290*c46a74ffSMary Strodl { 291*c46a74ffSMary Strodl unsigned long pin_mask, pin_states, flags; 292*c46a74ffSMary Strodl int irq_enabled, offset, err, value, fire_irq, 293*c46a74ffSMary Strodl irq, old_value[16], irq_type[16]; 294*c46a74ffSMary Strodl struct mpsse_priv *priv = container_of(work, struct mpsse_priv, 295*c46a74ffSMary Strodl irq_work); 296*c46a74ffSMary Strodl 297*c46a74ffSMary Strodl for (offset = 0; offset < priv->gpio.ngpio; ++offset) 298*c46a74ffSMary Strodl old_value[offset] = -1; 299*c46a74ffSMary Strodl 300*c46a74ffSMary Strodl while ((irq_enabled = atomic_read(&priv->irq_enabled))) { 301*c46a74ffSMary Strodl usleep_range(MPSSE_POLL_INTERVAL, MPSSE_POLL_INTERVAL + 1000); 302*c46a74ffSMary Strodl /* Cleanup will trigger at the end of the loop */ 303*c46a74ffSMary Strodl guard(mutex)(&priv->irq_mutex); 304*c46a74ffSMary Strodl 305*c46a74ffSMary Strodl pin_mask = 0; 306*c46a74ffSMary Strodl pin_states = 0; 307*c46a74ffSMary Strodl for (offset = 0; offset < priv->gpio.ngpio; ++offset) { 308*c46a74ffSMary Strodl irq_type[offset] = atomic_read(&priv->irq_type[offset]); 309*c46a74ffSMary Strodl if (irq_type[offset] != IRQ_TYPE_NONE && 310*c46a74ffSMary Strodl irq_enabled & BIT(offset)) 311*c46a74ffSMary Strodl pin_mask |= BIT(offset); 312*c46a74ffSMary Strodl else 313*c46a74ffSMary Strodl old_value[offset] = -1; 314*c46a74ffSMary Strodl } 315*c46a74ffSMary Strodl 316*c46a74ffSMary Strodl err = gpio_mpsse_get_multiple(&priv->gpio, &pin_mask, 317*c46a74ffSMary Strodl &pin_states); 318*c46a74ffSMary Strodl if (err) { 319*c46a74ffSMary Strodl dev_err_ratelimited(&priv->intf->dev, 320*c46a74ffSMary Strodl "Error polling!\n"); 321*c46a74ffSMary Strodl continue; 322*c46a74ffSMary Strodl } 323*c46a74ffSMary Strodl 324*c46a74ffSMary Strodl /* Check each value */ 325*c46a74ffSMary Strodl for (offset = 0; offset < priv->gpio.ngpio; ++offset) { 326*c46a74ffSMary Strodl if (old_value[offset] == -1) 327*c46a74ffSMary Strodl continue; 328*c46a74ffSMary Strodl 329*c46a74ffSMary Strodl fire_irq = 0; 330*c46a74ffSMary Strodl value = pin_states & BIT(offset); 331*c46a74ffSMary Strodl 332*c46a74ffSMary Strodl switch (irq_type[offset]) { 333*c46a74ffSMary Strodl case IRQ_TYPE_EDGE_RISING: 334*c46a74ffSMary Strodl fire_irq = value > old_value[offset]; 335*c46a74ffSMary Strodl break; 336*c46a74ffSMary Strodl case IRQ_TYPE_EDGE_FALLING: 337*c46a74ffSMary Strodl fire_irq = value < old_value[offset]; 338*c46a74ffSMary Strodl break; 339*c46a74ffSMary Strodl case IRQ_TYPE_EDGE_BOTH: 340*c46a74ffSMary Strodl fire_irq = value != old_value[offset]; 341*c46a74ffSMary Strodl break; 342*c46a74ffSMary Strodl } 343*c46a74ffSMary Strodl if (!fire_irq) 344*c46a74ffSMary Strodl continue; 345*c46a74ffSMary Strodl 346*c46a74ffSMary Strodl irq = irq_find_mapping(priv->gpio.irq.domain, 347*c46a74ffSMary Strodl offset); 348*c46a74ffSMary Strodl local_irq_save(flags); 349*c46a74ffSMary Strodl generic_handle_irq(irq); 350*c46a74ffSMary Strodl local_irq_disable(); 351*c46a74ffSMary Strodl local_irq_restore(flags); 352*c46a74ffSMary Strodl } 353*c46a74ffSMary Strodl 354*c46a74ffSMary Strodl /* Sync back values so we can refer to them next tick */ 355*c46a74ffSMary Strodl for (offset = 0; offset < priv->gpio.ngpio; ++offset) 356*c46a74ffSMary Strodl if (irq_type[offset] != IRQ_TYPE_NONE && 357*c46a74ffSMary Strodl irq_enabled & BIT(offset)) 358*c46a74ffSMary Strodl old_value[offset] = pin_states & BIT(offset); 359*c46a74ffSMary Strodl } 360*c46a74ffSMary Strodl } 361*c46a74ffSMary Strodl 362*c46a74ffSMary Strodl static int gpio_mpsse_set_irq_type(struct irq_data *irqd, unsigned int type) 363*c46a74ffSMary Strodl { 364*c46a74ffSMary Strodl int offset; 365*c46a74ffSMary Strodl struct mpsse_priv *priv = irq_data_get_irq_chip_data(irqd); 366*c46a74ffSMary Strodl 367*c46a74ffSMary Strodl offset = irqd->hwirq; 368*c46a74ffSMary Strodl atomic_set(&priv->irq_type[offset], type & IRQ_TYPE_EDGE_BOTH); 369*c46a74ffSMary Strodl 370*c46a74ffSMary Strodl return 0; 371*c46a74ffSMary Strodl } 372*c46a74ffSMary Strodl 373*c46a74ffSMary Strodl static void gpio_mpsse_irq_disable(struct irq_data *irqd) 374*c46a74ffSMary Strodl { 375*c46a74ffSMary Strodl struct mpsse_priv *priv = irq_data_get_irq_chip_data(irqd); 376*c46a74ffSMary Strodl 377*c46a74ffSMary Strodl atomic_and(~BIT(irqd->hwirq), &priv->irq_enabled); 378*c46a74ffSMary Strodl gpiochip_disable_irq(&priv->gpio, irqd->hwirq); 379*c46a74ffSMary Strodl } 380*c46a74ffSMary Strodl 381*c46a74ffSMary Strodl static void gpio_mpsse_irq_enable(struct irq_data *irqd) 382*c46a74ffSMary Strodl { 383*c46a74ffSMary Strodl struct mpsse_priv *priv = irq_data_get_irq_chip_data(irqd); 384*c46a74ffSMary Strodl 385*c46a74ffSMary Strodl gpiochip_enable_irq(&priv->gpio, irqd->hwirq); 386*c46a74ffSMary Strodl /* If no-one else was using the IRQ, enable it */ 387*c46a74ffSMary Strodl if (!atomic_fetch_or(BIT(irqd->hwirq), &priv->irq_enabled)) { 388*c46a74ffSMary Strodl INIT_WORK(&priv->irq_work, gpio_mpsse_poll); 389*c46a74ffSMary Strodl schedule_work(&priv->irq_work); 390*c46a74ffSMary Strodl } 391*c46a74ffSMary Strodl } 392*c46a74ffSMary Strodl 393*c46a74ffSMary Strodl static const struct irq_chip gpio_mpsse_irq_chip = { 394*c46a74ffSMary Strodl .name = "gpio-mpsse-irq", 395*c46a74ffSMary Strodl .irq_enable = gpio_mpsse_irq_enable, 396*c46a74ffSMary Strodl .irq_disable = gpio_mpsse_irq_disable, 397*c46a74ffSMary Strodl .irq_set_type = gpio_mpsse_set_irq_type, 398*c46a74ffSMary Strodl .flags = IRQCHIP_IMMUTABLE, 399*c46a74ffSMary Strodl GPIOCHIP_IRQ_RESOURCE_HELPERS, 400*c46a74ffSMary Strodl }; 401*c46a74ffSMary Strodl 402*c46a74ffSMary Strodl static void gpio_mpsse_ida_remove(void *data) 403*c46a74ffSMary Strodl { 404*c46a74ffSMary Strodl struct mpsse_priv *priv = data; 405*c46a74ffSMary Strodl 406*c46a74ffSMary Strodl ida_simple_remove(&gpio_mpsse_ida, priv->id); 407*c46a74ffSMary Strodl } 408*c46a74ffSMary Strodl 409*c46a74ffSMary Strodl static int gpio_mpsse_probe(struct usb_interface *interface, 410*c46a74ffSMary Strodl const struct usb_device_id *id) 411*c46a74ffSMary Strodl { 412*c46a74ffSMary Strodl struct mpsse_priv *priv; 413*c46a74ffSMary Strodl struct device *dev; 414*c46a74ffSMary Strodl int err; 415*c46a74ffSMary Strodl 416*c46a74ffSMary Strodl dev = &interface->dev; 417*c46a74ffSMary Strodl priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 418*c46a74ffSMary Strodl if (!priv) 419*c46a74ffSMary Strodl return -ENOMEM; 420*c46a74ffSMary Strodl 421*c46a74ffSMary Strodl priv->udev = usb_get_dev(interface_to_usbdev(interface)); 422*c46a74ffSMary Strodl priv->intf = interface; 423*c46a74ffSMary Strodl priv->intf_id = interface->cur_altsetting->desc.bInterfaceNumber; 424*c46a74ffSMary Strodl 425*c46a74ffSMary Strodl priv->id = ida_simple_get(&gpio_mpsse_ida, 0, 0, GFP_KERNEL); 426*c46a74ffSMary Strodl if (priv->id < 0) 427*c46a74ffSMary Strodl return priv->id; 428*c46a74ffSMary Strodl 429*c46a74ffSMary Strodl err = devm_add_action_or_reset(dev, gpio_mpsse_ida_remove, priv); 430*c46a74ffSMary Strodl if (err) 431*c46a74ffSMary Strodl return err; 432*c46a74ffSMary Strodl 433*c46a74ffSMary Strodl devm_mutex_init(dev, &priv->io_mutex); 434*c46a74ffSMary Strodl devm_mutex_init(dev, &priv->irq_mutex); 435*c46a74ffSMary Strodl 436*c46a74ffSMary Strodl priv->gpio.label = devm_kasprintf(dev, GFP_KERNEL, 437*c46a74ffSMary Strodl "gpio-mpsse.%d.%d", 438*c46a74ffSMary Strodl priv->id, priv->intf_id); 439*c46a74ffSMary Strodl if (!priv->gpio.label) 440*c46a74ffSMary Strodl return -ENOMEM; 441*c46a74ffSMary Strodl 442*c46a74ffSMary Strodl priv->gpio.owner = THIS_MODULE; 443*c46a74ffSMary Strodl priv->gpio.parent = interface->usb_dev; 444*c46a74ffSMary Strodl priv->gpio.get_direction = gpio_mpsse_get_direction; 445*c46a74ffSMary Strodl priv->gpio.direction_input = gpio_mpsse_direction_input; 446*c46a74ffSMary Strodl priv->gpio.direction_output = gpio_mpsse_direction_output; 447*c46a74ffSMary Strodl priv->gpio.get = gpio_mpsse_gpio_get; 448*c46a74ffSMary Strodl priv->gpio.set = gpio_mpsse_gpio_set; 449*c46a74ffSMary Strodl priv->gpio.get_multiple = gpio_mpsse_get_multiple; 450*c46a74ffSMary Strodl priv->gpio.set_multiple = gpio_mpsse_set_multiple; 451*c46a74ffSMary Strodl priv->gpio.base = -1; 452*c46a74ffSMary Strodl priv->gpio.ngpio = 16; 453*c46a74ffSMary Strodl priv->gpio.offset = priv->intf_id * priv->gpio.ngpio; 454*c46a74ffSMary Strodl priv->gpio.can_sleep = 1; 455*c46a74ffSMary Strodl 456*c46a74ffSMary Strodl err = usb_find_common_endpoints(interface->cur_altsetting, 457*c46a74ffSMary Strodl &priv->bulk_in, &priv->bulk_out, 458*c46a74ffSMary Strodl NULL, NULL); 459*c46a74ffSMary Strodl if (err) 460*c46a74ffSMary Strodl return err; 461*c46a74ffSMary Strodl 462*c46a74ffSMary Strodl priv->bulk_in_buf = devm_kmalloc(dev, usb_endpoint_maxp(priv->bulk_in), 463*c46a74ffSMary Strodl GFP_KERNEL); 464*c46a74ffSMary Strodl if (!priv->bulk_in_buf) 465*c46a74ffSMary Strodl return -ENOMEM; 466*c46a74ffSMary Strodl 467*c46a74ffSMary Strodl usb_set_intfdata(interface, priv); 468*c46a74ffSMary Strodl 469*c46a74ffSMary Strodl /* Reset mode, needed to correctly enter MPSSE mode */ 470*c46a74ffSMary Strodl err = usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 471*c46a74ffSMary Strodl SET_BITMODE_REQUEST, 472*c46a74ffSMary Strodl USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 473*c46a74ffSMary Strodl MODE_RESET, priv->intf_id + 1, NULL, 0, 474*c46a74ffSMary Strodl USB_CTRL_SET_TIMEOUT); 475*c46a74ffSMary Strodl if (err) 476*c46a74ffSMary Strodl return err; 477*c46a74ffSMary Strodl 478*c46a74ffSMary Strodl /* Enter MPSSE mode */ 479*c46a74ffSMary Strodl err = usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 480*c46a74ffSMary Strodl SET_BITMODE_REQUEST, 481*c46a74ffSMary Strodl USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 482*c46a74ffSMary Strodl MODE_MPSSE, priv->intf_id + 1, NULL, 0, 483*c46a74ffSMary Strodl USB_CTRL_SET_TIMEOUT); 484*c46a74ffSMary Strodl if (err) 485*c46a74ffSMary Strodl return err; 486*c46a74ffSMary Strodl 487*c46a74ffSMary Strodl gpio_irq_chip_set_chip(&priv->gpio.irq, &gpio_mpsse_irq_chip); 488*c46a74ffSMary Strodl 489*c46a74ffSMary Strodl priv->gpio.irq.parent_handler = NULL; 490*c46a74ffSMary Strodl priv->gpio.irq.num_parents = 0; 491*c46a74ffSMary Strodl priv->gpio.irq.parents = NULL; 492*c46a74ffSMary Strodl priv->gpio.irq.default_type = IRQ_TYPE_NONE; 493*c46a74ffSMary Strodl priv->gpio.irq.handler = handle_simple_irq; 494*c46a74ffSMary Strodl 495*c46a74ffSMary Strodl err = devm_gpiochip_add_data(dev, &priv->gpio, priv); 496*c46a74ffSMary Strodl if (err) 497*c46a74ffSMary Strodl return err; 498*c46a74ffSMary Strodl 499*c46a74ffSMary Strodl return 0; 500*c46a74ffSMary Strodl } 501*c46a74ffSMary Strodl 502*c46a74ffSMary Strodl static void gpio_mpsse_disconnect(struct usb_interface *intf) 503*c46a74ffSMary Strodl { 504*c46a74ffSMary Strodl struct mpsse_priv *priv = usb_get_intfdata(intf); 505*c46a74ffSMary Strodl 506*c46a74ffSMary Strodl priv->intf = NULL; 507*c46a74ffSMary Strodl usb_set_intfdata(intf, NULL); 508*c46a74ffSMary Strodl usb_put_dev(priv->udev); 509*c46a74ffSMary Strodl } 510*c46a74ffSMary Strodl 511*c46a74ffSMary Strodl static struct usb_driver gpio_mpsse_driver = { 512*c46a74ffSMary Strodl .name = "gpio-mpsse", 513*c46a74ffSMary Strodl .probe = gpio_mpsse_probe, 514*c46a74ffSMary Strodl .disconnect = gpio_mpsse_disconnect, 515*c46a74ffSMary Strodl .id_table = gpio_mpsse_table, 516*c46a74ffSMary Strodl }; 517*c46a74ffSMary Strodl 518*c46a74ffSMary Strodl module_usb_driver(gpio_mpsse_driver); 519*c46a74ffSMary Strodl 520*c46a74ffSMary Strodl MODULE_AUTHOR("Mary Strodl <mstrodl@csh.rit.edu>"); 521*c46a74ffSMary Strodl MODULE_DESCRIPTION("MPSSE GPIO driver"); 522*c46a74ffSMary Strodl MODULE_LICENSE("GPL"); 523