Skip to content

Commit 15add06

Browse files
tpetazzoniLinus Walleij
authored andcommitted
gpio: pca953x: add ->set_config implementation
This commit adds a minimal implementation of the ->set_config() hook, with support for the PIN_CONFIG_BIAS_PULL_UP and PIN_CONFIG_BIAS_PULL_DOWN configurations. Signed-off-by: Thomas Petazzoni <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent d449991 commit 15add06

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

drivers/gpio/gpio-pca953x.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
178178
#define PCA957x_BANK_OUTPUT BIT(5)
179179

180180
#define PCAL9xxx_BANK_IN_LATCH BIT(8 + 2)
181+
#define PCAL9xxx_BANK_PULL_EN BIT(8 + 3)
182+
#define PCAL9xxx_BANK_PULL_SEL BIT(8 + 4)
181183
#define PCAL9xxx_BANK_IRQ_MASK BIT(8 + 5)
182184
#define PCAL9xxx_BANK_IRQ_STAT BIT(8 + 6)
183185

@@ -199,6 +201,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
199201
* - Extended set, above 0x40, often chip specific.
200202
* - PCAL6524/PCAL9555A with custom PCAL IRQ handling:
201203
* Input latch register 0x40 + 2 * bank_size RW
204+
* Pull-up/pull-down enable reg 0x40 + 3 * bank_size RW
205+
* Pull-up/pull-down select reg 0x40 + 4 * bank_size RW
202206
* Interrupt mask register 0x40 + 5 * bank_size RW
203207
* Interrupt status register 0x40 + 6 * bank_size R
204208
*
@@ -247,7 +251,8 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg)
247251
}
248252

249253
if (chip->driver_data & PCA_PCAL) {
250-
bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK |
254+
bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN |
255+
PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK |
251256
PCAL9xxx_BANK_IRQ_STAT;
252257
}
253258

@@ -268,7 +273,8 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
268273
}
269274

270275
if (chip->driver_data & PCA_PCAL)
271-
bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK;
276+
bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN |
277+
PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK;
272278

273279
return pca953x_check_register(chip, reg, bank);
274280
}
@@ -473,6 +479,61 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
473479
mutex_unlock(&chip->i2c_lock);
474480
}
475481

482+
static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip,
483+
unsigned int offset,
484+
unsigned long config)
485+
{
486+
u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset,
487+
true, false);
488+
u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset,
489+
true, false);
490+
u8 bit = BIT(offset % BANK_SZ);
491+
int ret;
492+
493+
/*
494+
* pull-up/pull-down configuration requires PCAL extended
495+
* registers
496+
*/
497+
if (!(chip->driver_data & PCA_PCAL))
498+
return -ENOTSUPP;
499+
500+
mutex_lock(&chip->i2c_lock);
501+
502+
/* Disable pull-up/pull-down */
503+
ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0);
504+
if (ret)
505+
goto exit;
506+
507+
/* Configure pull-up/pull-down */
508+
if (config == PIN_CONFIG_BIAS_PULL_UP)
509+
ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, bit);
510+
else if (config == PIN_CONFIG_BIAS_PULL_DOWN)
511+
ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, 0);
512+
if (ret)
513+
goto exit;
514+
515+
/* Enable pull-up/pull-down */
516+
ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit);
517+
518+
exit:
519+
mutex_unlock(&chip->i2c_lock);
520+
return ret;
521+
}
522+
523+
static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
524+
unsigned long config)
525+
{
526+
struct pca953x_chip *chip = gpiochip_get_data(gc);
527+
528+
switch (config) {
529+
case PIN_CONFIG_BIAS_PULL_UP:
530+
case PIN_CONFIG_BIAS_PULL_DOWN:
531+
return pca953x_gpio_set_pull_up_down(chip, offset, config);
532+
default:
533+
return -ENOTSUPP;
534+
}
535+
}
536+
476537
static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
477538
{
478539
struct gpio_chip *gc;
@@ -485,6 +546,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
485546
gc->set = pca953x_gpio_set_value;
486547
gc->get_direction = pca953x_gpio_get_direction;
487548
gc->set_multiple = pca953x_gpio_set_multiple;
549+
gc->set_config = pca953x_gpio_set_config;
488550
gc->can_sleep = true;
489551

490552
gc->base = chip->gpio_start;

0 commit comments

Comments
 (0)