RE: [PATCH 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO adapter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: Johan Hovold [mailto:jhovold@xxxxxxxxx] On Behalf Of Johan Hovold
> Sent: Monday, September 22, 2014 5:14 PM
> To: Muthu Mani
> Cc: Samuel Ortiz; Lee Jones; Wolfram Sang; linux-i2c@xxxxxxxxxxxxxxx; Linus
> Walleij; Alexandre Courbot; linux-gpio@xxxxxxxxxxxxxxx;
> gregkh@xxxxxxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx; Rajaram Regupathy
> Subject: Re: [PATCH 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO
> adapter
> 
> On Mon, Sep 22, 2014 at 03:04:18PM +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 <muth@xxxxxxxxxxx>
> > Signed-off-by: Rajaram Regupathy <rera@xxxxxxxxxxx>
> > ---
> >  drivers/gpio/Kconfig          |  13 +++
> >  drivers/gpio/Makefile         |   1 +
> >  drivers/gpio/gpio-cyusbs23x.c | 190
> > ++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 204 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
> > 0000000..8aa3ab6
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-cyusbs23x.c
> > @@ -0,0 +1,190 @@
> > +/*
> > + * Cypress USB-Serial Bridge Controller GPIO driver
> > + *
> > + * Copyright (c) 2014 Cypress Semiconductor Corporation.
> > + *
> > + * Author:
> > + *   Muthu Mani <muth@xxxxxxxxxxx>
> > + *
> > + * Additional contributors include:
> > + *   Rajaram Regupathy <rera@xxxxxxxxxxx>
> > + *
> > + * 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 <linux/kernel.h>
> > +#include <linux/errno.h>
> > +#include <linux/module.h>
> > +#include <linux/slab.h>
> > +#include <linux/types.h>
> > +#include <linux/mutex.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include <linux/usb.h>
> > +#include <linux/gpio.h>
> > +
> > +#include <linux/mfd/cyusbs23x.h>
> > +
> > +#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[CY_GPIO_GET_LEN];
> 
> Buffers used for USB (DMA) transfers cannot be allocated on the stack.
> Use kmalloc and friends.

Ok, will update it.

> 
> > +     __u16 wIndex, wValue;
> 
> u16 throughout.

Ok.

> 
> > +     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;
> > +
> > +     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;
> > +     }
> > +
> > +     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, 2000);
> > +     mutex_unlock(&cyusbs->lock);
> > +
> > +     if (ret < 0)
> > +             dev_err(&cyusbs->usb_intf->dev, "error setting
> > +gpio:%d\n", ret); }
> > +
> > +static int cy_gpio_direction_input(struct gpio_chip *chip,
> > +                                     unsigned offset) {
> > +     return 0;
> 
> Aren't the GPIOs output-only?

No.

> 
> > +}
> > +
> > +static int cy_gpio_direction_output(struct gpio_chip *chip,
> > +                                     unsigned offset, int value) {
> > +     return 0;
> > +}
> > +
> > +static int cyusbs23x_gpio_probe(struct platform_device *pdev) {
> > +     struct cyusbs23x *cyusbs;
> > +     struct cyusbs_gpio *cy_gpio;
> > +     int ret = 0;
> > +
> > +     dev_dbg(&pdev->dev, "%s\n", __func__);
> > +
> > +     cyusbs = dev_get_drvdata(pdev->dev.parent);
> > +
> > +     cy_gpio = devm_kzalloc(&pdev->dev, sizeof(*cy_gpio), GFP_KERNEL);
> > +     if (cy_gpio == NULL)
> > +             return -ENOMEM;
> > +
> > +     cy_gpio->cyusbs = cyusbs;
> > +     /* registering gpio */
> > +     cy_gpio->gpio.label = "cyusbs23x gpio";
> > +     cy_gpio->gpio.dev = &pdev->dev;
> > +     cy_gpio->gpio.owner = THIS_MODULE;
> > +     cy_gpio->gpio.base = -1;
> > +     cy_gpio->gpio.ngpio = 12; /* total GPIOs */
> 
> I think you need to read out the gpio config from the device eeprom and
> implement a request() callback where you verify that a requested gpio is
> actually available (mode dependent, and there are never more than 10 gpios
> availble).

In this initial driver, all GPIOs are made available to user space.
Additional functionalities will be added in the next version of the driver.

> 
> > +     cy_gpio->gpio.can_sleep = true;
> > +     cy_gpio->gpio.set = cy_gpio_set;
> > +     cy_gpio->gpio.get = cy_gpio_get;
> > +     cy_gpio->gpio.direction_input = cy_gpio_direction_input;
> > +     cy_gpio->gpio.direction_output = cy_gpio_direction_output;
> > +     ret = gpiochip_add(&cy_gpio->gpio);
> > +     if (ret < 0) {
> > +             dev_err(cy_gpio->gpio.dev, "could not add gpio");
> > +             goto error;
> > +     }
> > +
> > +     platform_set_drvdata(pdev, cy_gpio);
> > +
> > +     dev_dbg(&pdev->dev, "added GPIO\n");
> > +     return ret;
> > +
> > +error:
> > +     dev_dbg(&pdev->dev, "error occured %d\n", ret);
> > +     return ret;
> > +}
> > +
> > +static int cyusbs23x_gpio_remove(struct platform_device *pdev) {
> > +     struct cyusbs_gpio *cy_gpio = platform_get_drvdata(pdev);
> > +
> > +     dev_dbg(&pdev->dev, "%s\n", __func__);
> > +
> > +     gpiochip_remove(&cy_gpio->gpio);
> > +
> > +     return 0;
> > +}
> > +
> > +static struct platform_driver cyusbs23x_gpio_driver = {
> > +     .driver.name    = "cyusbs23x-gpio",
> > +     .driver.owner   = THIS_MODULE,
> > +     .probe          = cyusbs23x_gpio_probe,
> > +     .remove         = cyusbs23x_gpio_remove,
> > +};
> > +
> > +static int __init cyusbs23x_gpio_init(void) {
> > +     return platform_driver_register(&cyusbs23x_gpio_driver);
> > +}
> > +subsys_initcall(cyusbs23x_gpio_init);
> > +
> > +static void __exit cyusbs23x_gpio_exit(void) {
> > +     platform_driver_unregister(&cyusbs23x_gpio_driver);
> > +}
> > +module_exit(cyusbs23x_gpio_exit);
> 
> module_platform_driver

Ok.

> 
> > +
> > +MODULE_AUTHOR("Rajaram Regupathy <rera@xxxxxxxxxxx>");
> > +MODULE_AUTHOR("Muthu Mani <muth@xxxxxxxxxxx>");
> > +MODULE_DESCRIPTION("gpio-cyusbs23x driver v0.1");
> > +MODULE_LICENSE("GPL");
> 
> Description and license comments from i2c patch apply here as well.

Ok, will update it.

> 
> > +MODULE_ALIAS("platform:cyusbs23x-gpio");
> > +
> 
> Stray new line.

Ok, will remove it.
I will send the v2 patch soon.

> 
> Johan
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux