From 7fc504b993cee79e38c0f018bf3c38940873bebd Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Wed, 1 Apr 2020 13:49:37 -0400 Subject: gpio: xgene-sb: set valid IRQ type in to_irq() xgene-sb is setup to be a hierarchical IRQ chip with the GIC as the parent chip. xgene_gpio_sb_to_irq() currently sets the default IRQ type to IRQ_TYPE_NONE, which the GIC loudly complains about with a WARN_ON(). Let's set the initial default to a sane value (IRQ_TYPE_EDGE_RISING) that was determined by decoding the ACPI tables on affected hardware: Device (_SB.GPSB) { Name (_HID, "APMC0D15") // _HID: Hardware ID Name (_CID, "APMC0D15") // _CID: Compatible ID Name (_UID, "GPIOSB") // _UID: Unique ID ... Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { ... Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, ) { 0x00000048, } ... } } This can be overridden later as needed with irq_set_irq_type(). Signed-off-by: Brian Masney Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-xgene-sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-xgene-sb.c b/drivers/gpio/gpio-xgene-sb.c index 25d86441666e..b45bfa9baa26 100644 --- a/drivers/gpio/gpio-xgene-sb.c +++ b/drivers/gpio/gpio-xgene-sb.c @@ -122,7 +122,7 @@ static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio) fwspec.fwnode = gc->parent->fwnode; fwspec.param_count = 2; fwspec.param[0] = GPIO_TO_HWIRQ(priv, gpio); - fwspec.param[1] = IRQ_TYPE_NONE; + fwspec.param[1] = IRQ_TYPE_EDGE_RISING; return irq_create_fwspec_mapping(&fwspec); } -- cgit v1.2.3 From 85a94ff8fb14511c88b8d21f82937197d76b82a2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 2 Apr 2020 22:21:45 +0300 Subject: gpio: Extend TODO to cover code duplication avoidance It appears at least two drivers has a lot of duplication code in GPIO subsystem. To avoid adding more and get rid of existing duplication extend TODO. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/TODO | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO index 3a44e6ae52bd..b989c9352da2 100644 --- a/drivers/gpio/TODO +++ b/drivers/gpio/TODO @@ -99,6 +99,10 @@ similar and probe a proper driver in the gpiolib subsystem. In some cases it makes sense to create a GPIO chip from the local driver for a few GPIOs. Those should stay where they are. +At the same time it makes sense to get rid of code duplication in existing or +new coming drivers. For example, gpio-ml-ioh should be incorporated into +gpio-pch. In similar way gpio-intel-mid into gpio-pxa. + Generic MMIO GPIO -- cgit v1.2.3 From 616844408de7f21546c3c2a71ea7f8d364f45e0d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 8 Apr 2020 19:41:10 -0600 Subject: gpio: pl061: Support building as module Enable building the PL061 GPIO driver as a module. This does change the initcall level when built-in. This shouldn't be a problem as any user should support deferred probe by now. A scan of DT based platforms at least didn't reveal any users that would be a problem. Cc: Linus Walleij Cc: Bartosz Golaszewski Cc: linux-gpio@vger.kernel.org Signed-off-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 2 +- drivers/gpio/gpio-pl061.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1b96169d84f7..8ef2179fb999 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -422,7 +422,7 @@ config GPIO_OMAP Say yes here to enable GPIO support for TI OMAP SoCs. config GPIO_PL061 - bool "PrimeCell PL061 GPIO support" + tristate "PrimeCell PL061 GPIO support" depends on ARM_AMBA select IRQ_DOMAIN select GPIOLIB_IRQCHIP diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index e241fb884c12..f1b53dd1df1a 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -408,6 +409,7 @@ static const struct amba_id pl061_ids[] = { }, { 0, 0 }, }; +MODULE_DEVICE_TABLE(amba, pl061_ids); static struct amba_driver pl061_gpio_driver = { .drv = { @@ -419,9 +421,6 @@ static struct amba_driver pl061_gpio_driver = { .id_table = pl061_ids, .probe = pl061_probe, }; +module_amba_driver(pl061_gpio_driver); -static int __init pl061_gpio_init(void) -{ - return amba_driver_register(&pl061_gpio_driver); -} -device_initcall(pl061_gpio_init); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From ea06a482a47c41f5d04565dffbc21156bcfdd3e8 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 11 Apr 2020 20:33:51 -0500 Subject: gpiolib: of: improve gpiolib-of support of pull up/down on expanders When using GPIO expanders attached to I2C ports, their set_config function needs to be passed a config setting which contains options to enable pull up or pull down bias feature. In order to set this config properly, the gpio parser needs to handle GPIO_PULL_UP and GPIO_PULL_DOWN. This patch enables the flags corresponding to GPIO_PULL_UP and GPIO_PULL_DOWN. Signed-off-by: Adam Ford Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-of.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index ccc449df3792..2c5dd1349f16 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -344,6 +344,12 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, if (transitory) lflags |= GPIO_TRANSITORY; + if (flags & OF_GPIO_PULL_UP) + lflags |= GPIO_PULL_UP; + + if (flags & OF_GPIO_PULL_DOWN) + lflags |= GPIO_PULL_DOWN; + ret = gpiod_configure_flags(desc, propname, lflags, dflags); if (ret < 0) { gpiod_put(desc); @@ -585,6 +591,10 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, *lflags |= GPIO_ACTIVE_LOW; if (xlate_flags & OF_GPIO_TRANSITORY) *lflags |= GPIO_TRANSITORY; + if (xlate_flags & OF_GPIO_PULL_UP) + *lflags |= GPIO_PULL_UP; + if (xlate_flags & OF_GPIO_PULL_DOWN) + *lflags |= GPIO_PULL_DOWN; if (of_property_read_bool(np, "input")) *dflags |= GPIOD_IN; -- cgit v1.2.3 From 96d7c7b3e6545612c1d37944621fdd611afd6adf Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Tue, 14 Apr 2020 11:28:42 -0400 Subject: gpio: gpio-pca953x, Add get_multiple function Implement a get_multiple function for gpio-pca953x. If a driver leaves get_multiple unimplemented then gpio_chip_get_multiple() in gpiolib.c takes care of it by calling chip->get() as needed. For i2c chips this is very inefficient. For example if you do an 8-bit read then instead of a single i2c transaction there are 8 transactions reading the same byte! Signed-off-by: Paul Thomas Acked-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5638b4e5355f..6317510b0dc3 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids); #define MAX_BANK 5 #define BANK_SZ 8 +#define BANK_SFT 3 /* ilog2(BANK_SZ) */ #define MAX_LINE (MAX_BANK * BANK_SZ) #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ) @@ -466,6 +467,41 @@ static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) return GPIO_LINE_DIRECTION_OUT; } +static int pca953x_gpio_get_multiple(struct gpio_chip *gc, + unsigned long *mask, unsigned long *bits) +{ + struct pca953x_chip *chip = gpiochip_get_data(gc); + unsigned int reg_val; + int offset, value, i, ret = 0; + u8 inreg; + + /* Force offset outside the range of i so that + * at least the first relevant register is read + */ + offset = gc->ngpio; + for_each_set_bit(i, mask, gc->ngpio) { + /* whenever i goes into a new bank update inreg + * and read the register + */ + if ((offset >> BANK_SFT) != (i >> BANK_SFT)) { + offset = i; + inreg = pca953x_recalc_addr(chip, chip->regs->input, + offset, true, false); + mutex_lock(&chip->i2c_lock); + ret = regmap_read(chip->regmap, inreg, ®_val); + mutex_unlock(&chip->i2c_lock); + if (ret < 0) + return ret; + } + /* reg_val is relative to the last read byte, + * so only shift the relative bits + */ + value = (reg_val >> (i % 8)) & 0x01; + __assign_bit(i, bits, value); + } + return ret; +} + static void pca953x_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { @@ -551,6 +587,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->get = pca953x_gpio_get_value; gc->set = pca953x_gpio_set_value; gc->get_direction = pca953x_gpio_get_direction; + gc->get_multiple = pca953x_gpio_get_multiple; gc->set_multiple = pca953x_gpio_set_multiple; gc->set_config = pca953x_gpio_set_config; gc->can_sleep = true; -- cgit v1.2.3 From aa58a21ae37894d456a2f91a37e9fd71ad4aa27e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 7 Apr 2020 17:42:45 +0200 Subject: gpio: pca953x: disable regmap locking This driver uses its own locking but regmap silently uses a mutex for all operations too. Add the option to disable locking to the regmap config struct. Signed-off-by: Bartosz Golaszewski Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Acked-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6317510b0dc3..60ae18e4b5f5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -307,6 +307,7 @@ static const struct regmap_config pca953x_i2c_regmap = { .writeable_reg = pca953x_writeable_register, .volatile_reg = pca953x_volatile_register, + .disable_locking = true, .cache_type = REGCACHE_RBTREE, /* REVISIT: should be 0x7f but some 24 bit chips use REG_ADDR_AI */ .max_register = 0xff, -- cgit v1.2.3 From 9784c9963feccd8dede924dbc0f8b1c64506e646 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 23 Apr 2020 13:34:16 -0700 Subject: gpiolib: devprop: Warn if gpio-line-names is too long Some DT authors (including myself) have messed up the length of gpio-line-names and made it longer than it should be. Add a warning here so that developers can figure out that they've messed up their DT and should fix it. Cc: Alexandru M Stan Signed-off-by: Stephen Boyd Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-devprop.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-devprop.c b/drivers/gpio/gpiolib-devprop.c index 53781b253986..26741032fa9e 100644 --- a/drivers/gpio/gpiolib-devprop.c +++ b/drivers/gpio/gpiolib-devprop.c @@ -37,8 +37,11 @@ void devprop_gpiochip_set_names(struct gpio_chip *chip, if (count < 0) return; - if (count > gdev->ngpio) + if (count > gdev->ngpio) { + dev_warn(&gdev->dev, "gpio-line-names is length %d but should be at most length %d", + count, gdev->ngpio); count = gdev->ngpio; + } names = kcalloc(count, sizeof(*names), GFP_KERNEL); if (!names) -- cgit v1.2.3 From 6f793485fc03fe832e1abcf0682efd7b4419ae2d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 20 Apr 2020 20:27:50 +0300 Subject: gpio: pca953x: Rewrite ->get_multiple() function The commit 96d7c7b3e654 ("gpio: gpio-pca953x, Add get_multiple function") basically did everything wrong from style and code reuse perspective, i.e. - it didn't utilize existing PCA953x internal helpers - it didn't utilize bitmap API - it misses the point that ilog2(), besides that BANK_SFT is useless, can be used in macros - it has indentation issues. Rewrite the function completely. Cc: Paul Thomas Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 60ae18e4b5f5..41be681ae77c 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -115,7 +115,6 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids); #define MAX_BANK 5 #define BANK_SZ 8 -#define BANK_SFT 3 /* ilog2(BANK_SZ) */ #define MAX_LINE (MAX_BANK * BANK_SZ) #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ) @@ -469,38 +468,20 @@ static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) } static int pca953x_gpio_get_multiple(struct gpio_chip *gc, - unsigned long *mask, unsigned long *bits) + unsigned long *mask, unsigned long *bits) { struct pca953x_chip *chip = gpiochip_get_data(gc); - unsigned int reg_val; - int offset, value, i, ret = 0; - u8 inreg; + DECLARE_BITMAP(reg_val, MAX_LINE); + int ret; - /* Force offset outside the range of i so that - * at least the first relevant register is read - */ - offset = gc->ngpio; - for_each_set_bit(i, mask, gc->ngpio) { - /* whenever i goes into a new bank update inreg - * and read the register - */ - if ((offset >> BANK_SFT) != (i >> BANK_SFT)) { - offset = i; - inreg = pca953x_recalc_addr(chip, chip->regs->input, - offset, true, false); - mutex_lock(&chip->i2c_lock); - ret = regmap_read(chip->regmap, inreg, ®_val); - mutex_unlock(&chip->i2c_lock); - if (ret < 0) - return ret; - } - /* reg_val is relative to the last read byte, - * so only shift the relative bits - */ - value = (reg_val >> (i % 8)) & 0x01; - __assign_bit(i, bits, value); - } - return ret; + mutex_lock(&chip->i2c_lock); + ret = pca953x_read_regs(chip, chip->regs->input, reg_val); + mutex_unlock(&chip->i2c_lock); + if (ret) + return ret; + + bitmap_replace(bits, bits, reg_val, mask, gc->ngpio); + return 0; } static void pca953x_gpio_set_multiple(struct gpio_chip *gc, -- cgit v1.2.3 From bcf41dc480b179bfb669a232080a2e26dc7294b4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 20 Apr 2020 20:27:51 +0300 Subject: gpio: pca953x: fix handling of automatic address incrementing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of the chips supported by the pca953x driver need the most significant bit in the address word set to automatically increment the address pointer on subsequent reads and writes (example: PCA9505). With this bit unset the same register is read multiple times on a multi-byte read sequence. Other chips must not have this bit set and autoincrement always (example: PCA9555). Up to now this AI bit was interpreted to be part of the address, which resulted in inconsistent regmap caching when a register was written with AI set and then read without it. This happened for the PCA9505 in pca953x_gpio_set_multiple() where pca953x_read_regs() bulk read from the cache for registers 0x8-0xc and then wrote to registers 0x88-0x8c. (Side note: reading 5 values from offset 0x8 yiels OP0 5 times because AI must be set to get OP0-OP4, which is another bug that is resolved here as a by-product.) The same problem happens when calls to gpio_set_value() and gpio_set_array_value() were mixed. With this patch the AI bit is always set for chips that support it. This works as there are no code locations that make use of the behaviour with AI unset (for the chips that support it). Note that the call to pca953x_setup_gpio() had to be done a bit earlier to make the NBANK macro work. The history of this bug is a bit complicated. Commit b32cecb46bdc ("gpio: pca953x: Extract the register address mangling to single function") changed which chips and functions are affected. Commit 3b00691cc46a ("gpio: pca953x: hack to fix 24 bit gpio expanders") used some duct tape to make the driver at least appear to work. Commit 49427232764d ("gpio: pca953x: Perform basic regmap conversion") introduced the caching. Commit b4818afeacbd ("gpio: pca953x: Add set_multiple to allow multiple bits to be set in one write.") introduced the .set_multiple() callback which didn't work for chips that need the AI bit which was fixed later for some chips in 8958262af3fb ("gpio: pca953x: Repair multi-byte IO address increment on PCA9575"). So I'm sorry, I don't know which commit I should pick for a Fixes: line. Tested-by: Marcel Gudert Signed-off-by: Uwe Kleine-König Tested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 41be681ae77c..590b07236637 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -308,8 +308,22 @@ static const struct regmap_config pca953x_i2c_regmap = { .disable_locking = true, .cache_type = REGCACHE_RBTREE, - /* REVISIT: should be 0x7f but some 24 bit chips use REG_ADDR_AI */ - .max_register = 0xff, + .max_register = 0x7f, +}; + +static const struct regmap_config pca953x_ai_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .read_flag_mask = REG_ADDR_AI, + .write_flag_mask = REG_ADDR_AI, + + .readable_reg = pca953x_readable_register, + .writeable_reg = pca953x_writeable_register, + .volatile_reg = pca953x_volatile_register, + + .cache_type = REGCACHE_RBTREE, + .max_register = 0x7f, }; static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, @@ -320,18 +334,6 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1; u8 regaddr = pinctrl | addr | (off / BANK_SZ); - /* Single byte read doesn't need AI bit set. */ - if (!addrinc) - return regaddr; - - /* Chips with 24 and more GPIOs always support Auto Increment */ - if (write && NBANK(chip) > 2) - regaddr |= REG_ADDR_AI; - - /* PCA9575 needs address-increment on multi-byte writes */ - if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) - regaddr |= REG_ADDR_AI; - return regaddr; } @@ -882,6 +884,7 @@ static int pca953x_probe(struct i2c_client *client, int ret; u32 invert = 0; struct regulator *reg; + const struct regmap_config *regmap_config; chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) @@ -944,7 +947,17 @@ static int pca953x_probe(struct i2c_client *client, i2c_set_clientdata(client, chip); - chip->regmap = devm_regmap_init_i2c(client, &pca953x_i2c_regmap); + pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK); + + if (NBANK(chip) > 2 || PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { + dev_info(&client->dev, "using AI\n"); + regmap_config = &pca953x_ai_i2c_regmap; + } else { + dev_info(&client->dev, "using no AI\n"); + regmap_config = &pca953x_i2c_regmap; + } + + chip->regmap = devm_regmap_init_i2c(client, regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); goto err_exit; @@ -975,7 +988,6 @@ static int pca953x_probe(struct i2c_client *client, /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ - pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK); if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) { chip->regs = &pca953x_regs; -- cgit v1.2.3 From 6fdeb6cbe1ef3bccd2c5e2b3427a06e9cda1efc2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 20 Apr 2020 20:27:52 +0300 Subject: gpio: pca953x: drop unused parameters of pca953x_recalc_addr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the previous patch the two last parameters of pca953x_recalc_addr() are unused and so can be dropped. Tested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Signed-off-by: Uwe Kleine-König Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 590b07236637..06d6af60e6b7 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -326,8 +326,7 @@ static const struct regmap_config pca953x_ai_i2c_regmap = { .max_register = 0x7f, }; -static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, - bool write, bool addrinc) +static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off) { int bank_shift = pca953x_bank_shift(chip); int addr = (reg & PCAL_GPIO_MASK) << bank_shift; @@ -339,7 +338,7 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { - u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true); + u8 regaddr = pca953x_recalc_addr(chip, reg, 0); u8 value[MAX_BANK]; int i, ret; @@ -357,7 +356,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { - u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true); + u8 regaddr = pca953x_recalc_addr(chip, reg, 0); u8 value[MAX_BANK]; int i, ret; @@ -376,8 +375,7 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long * static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off, - true, false); + u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); u8 bit = BIT(off % BANK_SZ); int ret; @@ -391,10 +389,8 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off, - true, false); - u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off, - true, false); + u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); + u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off); u8 bit = BIT(off % BANK_SZ); int ret; @@ -414,8 +410,7 @@ exit: static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off, - true, false); + u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off); u8 bit = BIT(off % BANK_SZ); u32 reg_val; int ret; @@ -439,8 +434,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off, - true, false); + u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off); u8 bit = BIT(off % BANK_SZ); mutex_lock(&chip->i2c_lock); @@ -451,8 +445,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off, - true, false); + u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); u8 bit = BIT(off % BANK_SZ); u32 reg_val; int ret; @@ -509,10 +502,8 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, unsigned int offset, unsigned long config) { - u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset, - true, false); - u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset, - true, false); + u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset); + u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset); u8 bit = BIT(offset % BANK_SZ); int ret; -- cgit v1.2.3 From fef2d3bb2db61d904e4016a181dd107d608fd055 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 5 May 2020 10:45:01 +0200 Subject: gpio: tegra186: export MODULE_DEVICE_TABLE Export MODULE_DEVICE_TABLE since the driver can be built as a module. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-tegra186.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 79b553dc39a3..178e9128ded0 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -894,6 +894,7 @@ static const struct of_device_id tegra186_gpio_of_match[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, tegra186_gpio_of_match); static struct platform_driver tegra186_gpio_driver = { .driver = { -- cgit v1.2.3 From 17f96ee2b9be9b65517fe167cfb13b86b33f3a1d Mon Sep 17 00:00:00 2001 From: Petteri Jokinen Date: Sat, 2 May 2020 20:22:39 +0300 Subject: gpio-f7188x: Add GPIO support for F81865 Add GPIO support for Fintek F81865 chip. Datasheet: http://www.hardwaresecrets.com/datasheets/F81865_V028P.pdf Signed-off-by: Petteri Jokinen Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-f7188x.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-f7188x.c b/drivers/gpio/gpio-f7188x.c index cadd02993539..18a3147f5a42 100644 --- a/drivers/gpio/gpio-f7188x.c +++ b/drivers/gpio/gpio-f7188x.c @@ -36,9 +36,19 @@ #define SIO_F71889A_ID 0x1005 /* F71889A chipset ID */ #define SIO_F81866_ID 0x1010 /* F81866 chipset ID */ #define SIO_F81804_ID 0x1502 /* F81804 chipset ID, same for f81966 */ - - -enum chips { f71869, f71869a, f71882fg, f71889a, f71889f, f81866, f81804 }; +#define SIO_F81865_ID 0x0704 /* F81865 chipset ID */ + + +enum chips { + f71869, + f71869a, + f71882fg, + f71889a, + f71889f, + f81866, + f81804, + f81865, +}; static const char * const f7188x_names[] = { "f71869", @@ -48,6 +58,7 @@ static const char * const f7188x_names[] = { "f71889f", "f81866", "f81804", + "f81865", }; struct f7188x_sio { @@ -233,6 +244,15 @@ static struct f7188x_gpio_bank f81804_gpio_bank[] = { F7188X_GPIO_BANK(90, 8, 0x98), }; +static struct f7188x_gpio_bank f81865_gpio_bank[] = { + F7188X_GPIO_BANK(0, 8, 0xF0), + F7188X_GPIO_BANK(10, 8, 0xE0), + F7188X_GPIO_BANK(20, 8, 0xD0), + F7188X_GPIO_BANK(30, 8, 0xC0), + F7188X_GPIO_BANK(40, 8, 0xB0), + F7188X_GPIO_BANK(50, 8, 0xA0), + F7188X_GPIO_BANK(60, 5, 0x90), +}; static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) { @@ -425,6 +445,10 @@ static int f7188x_gpio_probe(struct platform_device *pdev) data->nr_bank = ARRAY_SIZE(f81804_gpio_bank); data->bank = f81804_gpio_bank; break; + case f81865: + data->nr_bank = ARRAY_SIZE(f81865_gpio_bank); + data->bank = f81865_gpio_bank; + break; default: return -ENODEV; } @@ -490,6 +514,9 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio) case SIO_F81804_ID: sio->type = f81804; break; + case SIO_F81865_ID: + sio->type = f81865; + break; default: pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid); goto err; -- cgit v1.2.3