Re: [PATCH 2/2] gpio: gpio-ftdi-cbus: add driver for FTDI CBUS GPIOs

2015-07-15 Thread Linus Walleij
On Sun, Jun 21, 2015 at 12:12 AM, Stefan Agner ste...@agner.ch wrote:

 This driver allows to use the CBUS pins, e.g. CBUS 0-3 on FT232R
 type of devices. Note that the pins need to be configured first
 by using I/O mode signal option in the EEPROM. This is _not_ the
 factory default configuration of any of the four pins.

 See also FTDI's Application Note AN_232R-01.

 Signed-off-by: Stefan Agner ste...@agner.ch

I see no big problems with this driver but I guess the serial portions
are the controversial parts.

 +++ b/drivers/gpio/gpio-ftdi-cbus.c
 @@ -0,0 +1,167 @@
 +/*
 + * gpiolib support for FTDI SIO chips supporting CBUS GPIO's (FT232R class)
 + *
 + * Copyright 2015 Stefan Agner
 + *
 + * Author: Stefan Agner ste...@agner.ch
 + *
 + *  This program is free software; you can redistribute  it and/or modify it
 + *  under  the terms of  the GNU General  Public License as published by the
 + *  Free Software Foundation;  either version 2 of the  License, or (at your
 + *  option) any later version.
 + *
 + * Note: To use the GPIOs on CBUS the signal option need to be set to
 + * I/O mode in EEPROM!
 + */
 +
 +#include linux/kernel.h
 +#include linux/slab.h
 +#include linux/module.h
 +#include linux/gpio.h

#include linux/gpio/driver.h

should be enough.

 +static int ftdi_cbus_gpio_direction_input(struct gpio_chip *chip,
 + unsigned offset)
 +{
 +   struct ftdi_cbus_gpio *fcg = to_ftdi_cbus_gpio(chip);
 +
 +   fcg-cbus_mask = ~((1  offset)  4);

I usually replace:

(1  offset)

with

#include linux/bitops.h

BIT(offset)

so it's clear what is happening.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] gpio: gpio-ftdi-cbus: add driver for FTDI CBUS GPIOs

2015-06-20 Thread Stefan Agner
This driver allows to use the CBUS pins, e.g. CBUS 0-3 on FT232R
type of devices. Note that the pins need to be configured first
by using I/O mode signal option in the EEPROM. This is _not_ the
factory default configuration of any of the four pins.

See also FTDI's Application Note AN_232R-01.

Signed-off-by: Stefan Agner ste...@agner.ch
---
 drivers/gpio/Kconfig  |  10 +++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-ftdi-cbus.c | 167 ++
 drivers/usb/serial/ftdi_sio.c |  16 
 4 files changed, 194 insertions(+)
 create mode 100644 drivers/gpio/gpio-ftdi-cbus.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index caefe80..450ba9f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -975,6 +975,16 @@ endmenu
 menu USB GPIO expanders
depends on USB
 
+config GPIO_FTDI_CBUS
+   tristate FTDI FT232R CBUS bitmode GPIO support
+   depends on USB_SERIAL_FTDI_SIO
+   help
+ Say yes to use up to four CBUS pins on FT232R type of devices
+ Note that the pins need to be configured in EEPROM using to
+  I/O mode signal option first. The factory configuration
+ does not ship with this signal option set for any of the four
+ supported CBUS pins.
+
 config GPIO_VIPERBOARD
tristate Viperboard GPIO a  b support
depends on MFD_VIPERBOARD  USB
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f71bb97..a5d661b4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_DWAPB)  += gpio-dwapb.o
 obj-$(CONFIG_GPIO_EM)  += gpio-em.o
 obj-$(CONFIG_GPIO_EP93XX)  += gpio-ep93xx.o
 obj-$(CONFIG_GPIO_F7188X)  += gpio-f7188x.o
+obj-$(CONFIG_GPIO_FTDI_CBUS)   += gpio-ftdi-cbus.o
 obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
 obj-$(CONFIG_GPIO_GRGPIO)  += gpio-grgpio.o
 obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
diff --git a/drivers/gpio/gpio-ftdi-cbus.c b/drivers/gpio/gpio-ftdi-cbus.c
new file mode 100644
index 000..3a4dc46
--- /dev/null
+++ b/drivers/gpio/gpio-ftdi-cbus.c
@@ -0,0 +1,167 @@
+/*
+ * gpiolib support for FTDI SIO chips supporting CBUS GPIO's (FT232R class)
+ *
+ * Copyright 2015 Stefan Agner
+ *
+ * Author: Stefan Agner ste...@agner.ch
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Note: To use the GPIOs on CBUS the signal option need to be set to
+ * I/O mode in EEPROM!
+ */
+
+#include linux/kernel.h
+#include linux/slab.h
+#include linux/module.h
+#include linux/gpio.h
+#include linux/platform_device.h
+#include linux/seq_file.h
+#include linux/regmap.h
+
+#include linux/usb/ftdi_sio.h
+
+struct ftdi_cbus_gpio {
+   struct usb_serial_port *port;
+   struct gpio_chip gpio_chip;
+   u8 cbus_mask;
+};
+
+static inline struct ftdi_cbus_gpio *to_ftdi_cbus_gpio(struct gpio_chip *chip)
+{
+   return container_of(chip, struct ftdi_cbus_gpio, gpio_chip);
+}
+
+static int ftdi_cbus_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+   struct ftdi_cbus_gpio *fcg = to_ftdi_cbus_gpio(chip);
+
+   fcg-cbus_mask = ~((1  offset)  4);
+
+   return ftdi_sio_set_bitmode(fcg-port, fcg-cbus_mask, BITMODE_CBUS);
+}
+
+static int ftdi_cbus_gpio_direction_output(struct gpio_chip *chip,
+  unsigned offset, int value)
+{
+   struct ftdi_cbus_gpio *fcg = to_ftdi_cbus_gpio(chip);
+
+   fcg-cbus_mask |= ((1  offset)  4);
+   if (value)
+   fcg-cbus_mask |= (1  offset);
+   else
+   fcg-cbus_mask = ~(1  offset);
+
+   return ftdi_sio_set_bitmode(fcg-port, fcg-cbus_mask, BITMODE_CBUS);
+}
+
+static void ftdi_cbus_gpio_set(struct gpio_chip *chip, unsigned offset,
+  int value)
+{
+   struct ftdi_cbus_gpio *fcg = to_ftdi_cbus_gpio(chip);
+   int ret;
+
+   if (value)
+   fcg-cbus_mask |= (1  offset);
+   else
+   fcg-cbus_mask = ~(1  offset);
+
+   ret = ftdi_sio_set_bitmode(fcg-port, fcg-cbus_mask, 0x20);
+   if (ret  0)
+   dev_warn(chip-dev, error setting pin value, %d\n, ret);
+}
+
+static int ftdi_cbus_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+   struct ftdi_cbus_gpio *fcg = to_ftdi_cbus_gpio(chip);
+   u8 val;
+   int ret;
+
+   ret = ftdi_sio_read_pins(fcg-port, val);
+
+   if (ret  0) {
+   dev_warn(chip-dev, error getting pin value, %d\n, ret);
+   return 0;
+   }
+
+   if (val  (1  offset))
+   return 1;
+   else
+   return 0;
+}
+
+static struct gpio_chip ftdi_cbus_gpio_chip = {
+   .label  = ftdi-cbus-gpio,
+