@@ -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+
476537static 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