Re: [PATCH v2 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO adapter
On Tue, Sep 30, 2014 at 01:08:29PM +0200, Johan Hovold wrote: > On Thu, Sep 25, 2014 at 11:21:58AM +0530, Muthu Mani wrote: > > +static int cy_gpio_direction_input(struct gpio_chip *chip, > > + unsigned offset) > > +{ > > + return 0; > > +} > > + > > +static int cy_gpio_direction_output(struct gpio_chip *chip, > > + unsigned offset, int value) > > +{ > > + return 0; > > +} > > This is not a correct implementation of these. You're are supposed to > return what direction the gpio is configured for. You should also add a > call back to set the direction. That was backwards; these are supposed to set the direction, and then you should also implement the get_direction callback. Johan -- 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
Re: [PATCH v2 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO adapter
On Thu, Sep 25, 2014 at 11:21:58AM +0530, Muthu Mani wrote: > Adds support for USB-GPIO interface of Cypress Semiconductor > CYUSBS234 USB-Serial Bridge controller. > > The GPIO get/set can be done through vendor command on control endpoint. > > Details about the device can be found at: > http://www.cypress.com/?rID=84126 > > Signed-off-by: Muthu Mani > Signed-off-by: Rajaram Regupathy > --- > drivers/gpio/Kconfig | 13 +++ > drivers/gpio/Makefile | 1 + > drivers/gpio/gpio-cyusbs23x.c | 182 > ++ > 3 files changed, 196 insertions(+) > create mode 100644 drivers/gpio/gpio-cyusbs23x.c > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 9de1515..932e07c 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -886,6 +886,19 @@ config GPIO_BCM_KONA > > comment "USB GPIO expanders:" > > +config GPIO_CYUSBS23X > + tristate "CYUSBS23x GPIO support" > + depends on MFD_CYUSBS23X && USB > + help > + Say yes here to access the GPIO signals of Cypress > + Semiconductor CYUSBS23x USB Serial Bridge Controller. > + > + This driver enables the GPIO interface of CYUSBS23x USB Serial > + Bridge controller. > + > + This driver can also be built as a module. If so, the module will be > + called gpio-cyusbs23x. > + > 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 5d024e3..3ad89f1 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_BT8XX)+= gpio-bt8xx.o > obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o > obj-$(CONFIG_GPIO_CS5535)+= gpio-cs5535.o > obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o > +obj-$(CONFIG_GPIO_CYUSBS23X) += gpio-cyusbs23x.o > obj-$(CONFIG_GPIO_DA9052)+= gpio-da9052.o > obj-$(CONFIG_GPIO_DA9055)+= gpio-da9055.o > obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o > diff --git a/drivers/gpio/gpio-cyusbs23x.c b/drivers/gpio/gpio-cyusbs23x.c > new file mode 100644 > index 000..ad83b00 > --- /dev/null > +++ b/drivers/gpio/gpio-cyusbs23x.c > @@ -0,0 +1,182 @@ > +/* > + * GPIO subdriver for Cypress CYUSBS234 USB-Serial Bridge controller. > + * Details about the device can be found at: > + *http://www.cypress.com/?rID=84126 > + * All GPIOs are exposed for get operation and only unused GPIOs can be set. > + * > + * Copyright (c) 2014 Cypress Semiconductor Corporation. > + * > + * Author: > + * Muthu Mani > + * > + * Additional contributors include: > + * Rajaram Regupathy > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published > by > + * the Free Software Foundation. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > + > +#define CY_GPIO_GET_LEN (2) No parentheses. > + > +struct cyusbs_gpio { > + struct gpio_chip gpio; > + struct cyusbs23x *cyusbs; > +}; > + > +static int cy_gpio_get(struct gpio_chip *chip, > + unsigned offset) > +{ > + int ret; > + char *buf; > + u16 wIndex, wValue; > + struct cyusbs_gpio *gpio = > + container_of(chip, struct cyusbs_gpio, gpio); Add helper macro? > + struct cyusbs23x *cyusbs = gpio->cyusbs; > + > + dev_dbg(&cyusbs->usb_intf->dev, "%s: %d\n", __func__, > + offset); Drop this. > + wValue = offset; > + wIndex = 0; > + buf = kmalloc(CY_GPIO_GET_LEN, GFP_KERNEL); Error handling missing. > + > + mutex_lock(&cyusbs->lock); Locking not needed. > + ret = usb_control_msg(cyusbs->usb_dev, > + usb_rcvctrlpipe(cyusbs->usb_dev, 0), > + CY_GPIO_GET_VALUE_CMD, > + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, > + wValue, wIndex, buf, CY_GPIO_GET_LEN, 2000); timeout define. > + mutex_unlock(&cyusbs->lock); > + > + dev_dbg(&cyusbs->usb_intf->dev, "%s: %d %02x %02x\n", __func__, > + ret, buf[0], buf[1]); Use the gpio_chip device rather than usb-interface device in gpio callbacks for debug and error messages. > + > + if (ret == CY_GPIO_GET_LEN) { > + if (buf[0] == 0) > + ret = buf[1]; > + else > + ret = -EINVAL; > + } else { > + ret = -EREMOTEIO; > + } Just use -EIO for both error cases. > + > + kfree(buf); > + return ret; > +} > + > +static void cy_gpio_set(struct gpio_chip *chip, > + unsigned offset, int value) > +{ > + int ret; > + u16 wIndex, wValue; > + struct cyusbs_gpio *gpio = > + container_of(chip, struct cyusbs_gpio, gpio);
[PATCH v2 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO adapter
Adds support for USB-GPIO interface of Cypress Semiconductor CYUSBS234 USB-Serial Bridge controller. The GPIO get/set can be done through vendor command on control endpoint. Details about the device can be found at: http://www.cypress.com/?rID=84126 Signed-off-by: Muthu Mani Signed-off-by: Rajaram Regupathy --- drivers/gpio/Kconfig | 13 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-cyusbs23x.c | 182 ++ 3 files changed, 196 insertions(+) create mode 100644 drivers/gpio/gpio-cyusbs23x.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9de1515..932e07c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -886,6 +886,19 @@ config GPIO_BCM_KONA comment "USB GPIO expanders:" +config GPIO_CYUSBS23X + tristate "CYUSBS23x GPIO support" + depends on MFD_CYUSBS23X && USB + help + Say yes here to access the GPIO signals of Cypress + Semiconductor CYUSBS23x USB Serial Bridge Controller. + + This driver enables the GPIO interface of CYUSBS23x USB Serial + Bridge controller. + + This driver can also be built as a module. If so, the module will be + called gpio-cyusbs23x. + 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 5d024e3..3ad89f1 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o +obj-$(CONFIG_GPIO_CYUSBS23X) += gpio-cyusbs23x.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o diff --git a/drivers/gpio/gpio-cyusbs23x.c b/drivers/gpio/gpio-cyusbs23x.c new file mode 100644 index 000..ad83b00 --- /dev/null +++ b/drivers/gpio/gpio-cyusbs23x.c @@ -0,0 +1,182 @@ +/* + * GPIO subdriver for Cypress CYUSBS234 USB-Serial Bridge controller. + * Details about the device can be found at: + *http://www.cypress.com/?rID=84126 + * All GPIOs are exposed for get operation and only unused GPIOs can be set. + * + * Copyright (c) 2014 Cypress Semiconductor Corporation. + * + * Author: + * Muthu Mani + * + * Additional contributors include: + * Rajaram Regupathy + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define CY_GPIO_GET_LEN(2) + +struct cyusbs_gpio { + struct gpio_chip gpio; + struct cyusbs23x *cyusbs; +}; + +static int cy_gpio_get(struct gpio_chip *chip, + unsigned offset) +{ + int ret; + char *buf; + u16 wIndex, wValue; + struct cyusbs_gpio *gpio = + container_of(chip, struct cyusbs_gpio, gpio); + struct cyusbs23x *cyusbs = gpio->cyusbs; + + dev_dbg(&cyusbs->usb_intf->dev, "%s: %d\n", __func__, + offset); + wValue = offset; + wIndex = 0; + buf = kmalloc(CY_GPIO_GET_LEN, GFP_KERNEL); + + mutex_lock(&cyusbs->lock); + ret = usb_control_msg(cyusbs->usb_dev, + usb_rcvctrlpipe(cyusbs->usb_dev, 0), + CY_GPIO_GET_VALUE_CMD, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + wValue, wIndex, buf, CY_GPIO_GET_LEN, 2000); + mutex_unlock(&cyusbs->lock); + + dev_dbg(&cyusbs->usb_intf->dev, "%s: %d %02x %02x\n", __func__, + ret, buf[0], buf[1]); + + if (ret == CY_GPIO_GET_LEN) { + if (buf[0] == 0) + ret = buf[1]; + else + ret = -EINVAL; + } else { + ret = -EREMOTEIO; + } + + kfree(buf); + return ret; +} + +static void cy_gpio_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + int ret; + u16 wIndex, wValue; + struct cyusbs_gpio *gpio = + container_of(chip, struct cyusbs_gpio, gpio); + struct cyusbs23x *cyusbs = gpio->cyusbs; + + dev_dbg(&cyusbs->usb_intf->dev, "%s: %d\n", __func__, + offset); + wValue = offset; + wIndex = value; + + mutex_lock(&cyusbs->lock); + ret = usb_control_msg(cyusbs->usb_dev, + usb_sndctrlpipe(cyusbs->usb_dev, 0), + CY_GPIO_SET_VALUE_CMD, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + wValue, wIndex, NULL, 0, 20