Re: [linux-yocto] [PATCH] gpio-pca953x: add "drive" property
On 2016-03-10 2:58 PM, Saul Wold wrote: From: Jussi Laako Galileo gen 2 has support for setting GPIO modes. Expose these properties through the GPIO sysfs interface. This approach is bit hacky, since it changes the interface semantics. The original patch was by Josef Ahmad and made on top of kernel 3.8. merged, and I just sent the SRCREV update. Bruce Signed-off-by: Ismo Puustinen Signed-off-by: Jussi Laako Signed-off-by: Saul Wold --- drivers/gpio/gpio-pca953x.c | 57 +++ drivers/gpio/gpiolib-sysfs.c | 78 +++ drivers/gpio/gpiolib.c| 18 ++ drivers/gpio/gpiolib.h| 4 +++ include/asm-generic/gpio.h| 5 +++ include/linux/gpio.h | 10 ++ include/linux/gpio/consumer.h | 11 ++ include/linux/gpio/driver.h | 2 ++ 8 files changed, 178 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index f23a4b4..f99706f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -39,6 +39,9 @@ #define PCA957X_MSK 6 #define PCA957X_INTS 7 +#define PCA953X_PUPD_EN35 +#define PCA953X_PUPD_SEL 36 + #define PCA_GPIO_MASK 0x00FF #define PCA_INT 0x0100 #define PCA953X_TYPE 0x1000 @@ -375,6 +378,43 @@ exit: mutex_unlock(&chip->i2c_lock); } +static int pca953x_gpio_set_drive(struct gpio_chip *gc, +unsigned off, unsigned mode) +{ + struct pca953x_chip *chip; + int ret = 0; + int val; + + chip = container_of(gc, struct pca953x_chip, gpio_chip); + + if (chip->chip_type != PCA953X_TYPE) + return -EINVAL; + + mutex_lock(&chip->i2c_lock); + + switch (mode) { + case GPIOF_DRIVE_PULLUP: + ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, 1, off); + break; + case GPIOF_DRIVE_PULLDOWN: + ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, 0, off); + break; + case GPIOF_DRIVE_STRONG: + case GPIOF_DRIVE_HIZ: + ret = pca953x_read_single(chip, PCA953X_PUPD_EN, &val, off) || + pca953x_write_single(chip, PCA953X_PUPD_EN, 0, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, val, off); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&chip->i2c_lock); + return ret; +} + static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) { struct gpio_chip *gc; @@ -393,6 +433,9 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->dev = &chip->client->dev; gc->owner = THIS_MODULE; gc->names = chip->names; + + if (chip->chip_type == PCA953X_TYPE) + gc->set_drive = pca953x_gpio_set_drive; } #ifdef CONFIG_GPIO_PCA953X_IRQ @@ -552,7 +595,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) } static int pca953x_irq_setup(struct pca953x_chip *chip, -int irq_base) +int irq_base) { struct i2c_client *client = chip->client; int ret, i, offset = 0; @@ -595,10 +638,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, } ret = gpiochip_irqchip_add(&chip->gpio_chip, - &pca953x_irq_chip, - irq_base, - handle_simple_irq, - IRQ_TYPE_NONE); + &pca953x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); @@ -615,7 +658,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, #else /* CONFIG_GPIO_PCA953X_IRQ */ static int pca953x_irq_setup(struct pca953x_chip *chip, -int irq_base) +int irq_base) { struct i2c_client *client = chip->client; @@ -636,7 +679,7 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) goto out; ret = pca953x_read_regs(chip, PCA953X_DIRECTION, - chip->reg_direction); + chip->reg_direction); if (ret) goto out; diff --git a/drivers/gpio/gpiolib
[linux-yocto] [PATCH] gpio-pca953x: add "drive" property
From: Jussi Laako Galileo gen 2 has support for setting GPIO modes. Expose these properties through the GPIO sysfs interface. This approach is bit hacky, since it changes the interface semantics. The original patch was by Josef Ahmad and made on top of kernel 3.8. Signed-off-by: Ismo Puustinen Signed-off-by: Jussi Laako Signed-off-by: Saul Wold --- drivers/gpio/gpio-pca953x.c | 57 +++ drivers/gpio/gpiolib-sysfs.c | 78 +++ drivers/gpio/gpiolib.c| 18 ++ drivers/gpio/gpiolib.h| 4 +++ include/asm-generic/gpio.h| 5 +++ include/linux/gpio.h | 10 ++ include/linux/gpio/consumer.h | 11 ++ include/linux/gpio/driver.h | 2 ++ 8 files changed, 178 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index f23a4b4..f99706f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -39,6 +39,9 @@ #define PCA957X_MSK6 #define PCA957X_INTS 7 +#define PCA953X_PUPD_EN35 +#define PCA953X_PUPD_SEL 36 + #define PCA_GPIO_MASK 0x00FF #define PCA_INT0x0100 #define PCA953X_TYPE 0x1000 @@ -375,6 +378,43 @@ exit: mutex_unlock(&chip->i2c_lock); } +static int pca953x_gpio_set_drive(struct gpio_chip *gc, +unsigned off, unsigned mode) +{ + struct pca953x_chip *chip; + int ret = 0; + int val; + + chip = container_of(gc, struct pca953x_chip, gpio_chip); + + if (chip->chip_type != PCA953X_TYPE) + return -EINVAL; + + mutex_lock(&chip->i2c_lock); + + switch (mode) { + case GPIOF_DRIVE_PULLUP: + ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, 1, off); + break; + case GPIOF_DRIVE_PULLDOWN: + ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, 0, off); + break; + case GPIOF_DRIVE_STRONG: + case GPIOF_DRIVE_HIZ: + ret = pca953x_read_single(chip, PCA953X_PUPD_EN, &val, off) || + pca953x_write_single(chip, PCA953X_PUPD_EN, 0, off) || + pca953x_write_single(chip, PCA953X_PUPD_SEL, val, off); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&chip->i2c_lock); + return ret; +} + static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) { struct gpio_chip *gc; @@ -393,6 +433,9 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->dev = &chip->client->dev; gc->owner = THIS_MODULE; gc->names = chip->names; + + if (chip->chip_type == PCA953X_TYPE) + gc->set_drive = pca953x_gpio_set_drive; } #ifdef CONFIG_GPIO_PCA953X_IRQ @@ -552,7 +595,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) } static int pca953x_irq_setup(struct pca953x_chip *chip, -int irq_base) +int irq_base) { struct i2c_client *client = chip->client; int ret, i, offset = 0; @@ -595,10 +638,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, } ret = gpiochip_irqchip_add(&chip->gpio_chip, - &pca953x_irq_chip, - irq_base, - handle_simple_irq, - IRQ_TYPE_NONE); + &pca953x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); @@ -615,7 +658,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, #else /* CONFIG_GPIO_PCA953X_IRQ */ static int pca953x_irq_setup(struct pca953x_chip *chip, -int irq_base) +int irq_base) { struct i2c_client *client = chip->client; @@ -636,7 +679,7 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) goto out; ret = pca953x_read_regs(chip, PCA953X_DIRECTION, - chip->reg_direction); + chip->reg_direction); if (ret) goto out; diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index b57ed8e..b60e477 100644 --- a/drivers/gpio/gpiolib-sysfs.c ++