Skip to contentSkip to conversation

Migrate the PCIe-IDIO-24 and WS16C48 GPIO drivers to the regmap API

PATCH Superseded William Breathitt Gray 3 participants 6 messages Mar 5, 2023 – Mar 6, 2023

Subsystems (5)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v3 cover Migrate the PCIe-IDIO-24 and WS16C48 GPIO drivers to the regmap API

Changes in v3:
- Drop map from set_type_config() parameter list; regmap can be passed by irq_drv_data instead
- Adjust ws16c48_set_type_config() for parameter list
- Add mutex to prevent clobbering the COS_ENABLE register when masking IRQ and setting their type configuration
Changes in v2:
- Simplify PCIe-IDIO-24 register offset defines to remove superfluous arithmetic
- Check for NULL pointer after chip->irq_drv_data allocation
- Set gpio_regmap drvdata and use gpio_regmap_get_drvdata() to get the regmap in idio_24_reg_map_xlate()

The regmap API supports IO port accessors so we can take advantage of regmap abstractions rather than handling access to the device registers directly in the driver.

A patch to pass irq_drv_data as a parameter for struct regmap_irq_chip set_type_config() is included. This is needed by the idio_24_set_type_config() and ws16c48_set_type_config() callbacks in order to update the type configuration on their respective devices.

A patch to migrate the WS16C48 GPIO driver to the regmap API is included in this patchset due to its dependence on the struct regmap_irq_chip set_type_config() change.

William Breathitt Gray (3):
regmap: Pass irq_drv_data as a parameter for set_type_config()
gpio: pcie-idio-24: Migrate to the regmap API
gpio: ws16c48: Migrate to the regmap API

 drivers/base/regmap/regmap-irq.c |   8 +-
 drivers/gpio/Kconfig             |   6 +
 drivers/gpio/gpio-pcie-idio-24.c | 709 ++++++++++++-------------------
 drivers/gpio/gpio-ws16c48.c      | 566 +++++++++---------------
 include/linux/regmap.h           |   6 +-
 5 files changed, 496 insertions(+), 799 deletions(-)

base-commit: 4827aae061337251bb91801b316157a78b845ec7

Signature · 1 line
2.39.2
#1 lore raw

PATCH v3 1/3 regmap: Pass irq_drv_data as a parameter for set_type_config()

Allow the struct regmap_irq_chip set_type_config() callback to access irq_drv_data by passing it as a parameter.

---
Changes in v3:
- Drop map from set_type_config() parameter list; regmap can be passed by irq_drv_data instead
Changes in v2: none

 drivers/base/regmap/regmap-irq.c | 8 +++++---
 include/linux/regmap.h           | 6 ++++--
 2 files changed, 9 insertions(+), 5 deletions(-)
drivers/base/regmap/regmap-irq.c +5 -3
index a8f185430a07..9cfcb0b2db5e 100644
@@ -333,8 +333,8 @@ static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
 	}
 
 	if (d->chip->set_type_config) {
-		ret = d->chip->set_type_config(d->config_buf, type,
-					       irq_data, reg);
+		ret = d->chip->set_type_config(d->config_buf, type, irq_data,
+					       reg, d->chip->irq_drv_data);
 		if (ret)
 			return ret;
 	}
@@ -655,13 +655,15 @@ EXPORT_SYMBOL_GPL(regmap_irq_get_irq_reg_linear);
  * @type: The requested IRQ type.
  * @irq_data: The IRQ being configured.
  * @idx: Index of the irq's config registers within each array `buf[i]`
+ * @irq_drv_data: Driver specific IRQ data
  *
  * This is a &struct regmap_irq_chip->set_type_config callback suitable for
  * chips with one config register. Register values are updated according to
  * the &struct regmap_irq_type data associated with an IRQ.
  */
 int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
-				      const struct regmap_irq *irq_data, int idx)
+				      const struct regmap_irq *irq_data,
+				      int idx, void *irq_drv_data)
 {
 	const struct regmap_irq_type *t = &irq_data->type;
 
include/linux/regmap.h +4 -2
index a3bc695bcca0..80497dcc5c45 100644
@@ -1649,7 +1649,8 @@ struct regmap_irq_chip {
 	int (*set_type_virt)(unsigned int **buf, unsigned int type,
 			     unsigned long hwirq, int reg);
 	int (*set_type_config)(unsigned int **buf, unsigned int type,
-			       const struct regmap_irq *irq_data, int idx);
+			       const struct regmap_irq *irq_data, int idx,
+			       void *irq_drv_data);
 	unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data,
 				    unsigned int base, int index);
 	void *irq_drv_data;
@@ -1658,7 +1659,8 @@ struct regmap_irq_chip {
 unsigned int regmap_irq_get_irq_reg_linear(struct regmap_irq_chip_data *data,
 					   unsigned int base, int index);
 int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
-				      const struct regmap_irq *irq_data, int idx);
+				      const struct regmap_irq *irq_data,
+				      int idx, void *irq_drv_data);
 
 int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 			int irq_base, const struct regmap_irq_chip *chip,
Signature · 1 line
2.39.2
#2 lore raw

PATCH v3 2/3 gpio: pcie-idio-24: Migrate to the regmap API

In reply to William Breathitt Gray

The regmap API supports IO port accessors so we can take advantage of regmap abstractions rather than handling access to the device registers directly in the driver.

For the PCIe-IDIO-24 series of devices, the following BARs are available:

    BAR[0]: memory mapped PEX8311
    BAR[1]: I/O mapped PEX8311
    BAR[2]: I/O mapped card registers

There are 24 FET Output lines, 24 Isolated Input lines, and 8 TTL/CMOS lines (which may be configured for either output or input). The GPIO lines are exposed by the following card registers:

    Base +0x0-0x2 (Read/Write): FET Outputs
    Base +0xB (Read/Write): TTL/CMOS
    Base +0x4-0x6 (Read): Isolated Inputs
    Base +0x7 (Read): TTL/CMOS

In order for the device to support interrupts, the PLX PEX8311 internal PCI wire interrupt and local interrupt input must first be enabled.

The following card registers for Change-Of-State may be used:

    Base +0x8-0xA (Read): COS Status Inputs
    Base +0x8-0xA (Write): COS Clear Inputs
    Base +0xB (Read): COS Status TTL/CMOS
    Base +0xB (Write): COS Clear TTL/CMOS
    Base +0xE (Read/Write): COS Enable

The COS Enable register is used to enable/disable interrupts and configure the interrupt levels; each bit maps to a group of eight inputs as described below:

Bit 0: IRQ EN Rising Edge IN0-7
Bit 1: IRQ EN Rising Edge IN8-15
Bit 2: IRQ EN Rising Edge IN16-23
Bit 3: IRQ EN Rising Edge TTL0-7
Bit 4: IRQ EN Falling Edge IN0-7
Bit 5: IRQ EN Falling Edge IN8-15
Bit 6: IRQ EN Falling Edge IN16-23
Bit 7: IRQ EN Falling Edge TTL0-7

An interrupt is asserted when a change-of-state matching the interrupt level configuration respective for a particular group of eight inputs with enabled COS is detected.

The COS Status registers may be read to determine which inputs have changed; if interrupts were enabled, an IRQ will be generated for the set bits in these registers. Writing the value read from the COS Status register back to the respective COS Clear register will clear just those interrupts.

Cc Arnaud de Turckheim <[email protected]>
Cc John Hentges <[email protected]>
Cc Jay Dolan <[email protected]>

---
Changes in v3:
- Adjust ws16c48_set_type_config() for parameter list
- Add mutex to prevent clobbering the COS_ENABLE register when masking IRQ and setting their type configuration
Changes in v2:
- Simplify PCIe-IDIO-24 register offset defines to remove superfluous arithmetic
- Check for NULL pointer after chip->irq_drv_data allocation
- Set gpio_regmap drvdata and use gpio_regmap_get_drvdata() to get the regmap in idio_24_reg_map_xlate()

 drivers/gpio/Kconfig             |   3 +
 drivers/gpio/gpio-pcie-idio-24.c | 709 ++++++++++++-------------------
 2 files changed, 285 insertions(+), 427 deletions(-)
drivers/gpio/Kconfig +3 -0
index 406e8bda487f..06c7a96e6033 100644
@@ -1578,7 +1578,10 @@ config GPIO_PCI_IDIO_16
 
 config GPIO_PCIE_IDIO_24
 	tristate "ACCES PCIe-IDIO-24 GPIO support"
+	select REGMAP_IRQ
+	select REGMAP_MMIO
 	select GPIOLIB_IRQCHIP
+	select GPIO_REGMAP
 	help
 	  Enables GPIO support for the ACCES PCIe-IDIO-24 family (PCIe-IDIO-24,
 	  PCIe-IDI-24, PCIe-IDO-24, PCIe-IDIO-12). An interrupt is generated
drivers/gpio/gpio-pcie-idio-24.c +282 -427

783 lines not on this page · raw message

Signature · 1 line
2.39.2
#3 lore raw

Re: [PATCH v3 2/3] gpio: pcie-idio-24: Migrate to the regmap API

I love your patch! Perhaps something to improve:

Hi William,

I love your patch! Perhaps something to improve:

[auto build test WARNING on 4827aae061337251bb91801b316157a78b845ec7]

url:    https://github.com/intel-lab-lkp/linux/commits/William-Breathitt-Gray/regmap-Pass-irq_drv_data-as-a-parameter-for-set_type_config/20230306-010313
base:   4827aae061337251bb91801b316157a78b845ec7
patch link:    https://lore.kernel.org/r/278e328cd1689a4e331e7515050c12c29f2a4785.1678034378.git.william.gray%40linaro.org
patch subject: [PATCH v3 2/3] gpio: pcie-idio-24: Migrate to the regmap API
config: i386-randconfig-a013 (https://download.01.org/0day-ci/archive/20230306/[email protected]/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/e60d5c32ff098c33b1e171190079ed3f40180008
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review William-Breathitt-Gray/regmap-Pass-irq_drv_data-as-a-parameter-for-set_type_config/20230306-010313 git checkout e60d5c32ff098c33b1e171190079ed3f40180008
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpio/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> drivers/gpio/gpio-pcie-idio-24.c:365:2: warning: variable 'idio24gpio' is uninitialized when used here [-Wuninitialized]
           idio24gpio->map = devm_regmap_init_mmio(dev, idio_24_regs,
           ^~~~~~~~~~
   drivers/gpio/gpio-pcie-idio-24.c:333:33: note: initialize the variable 'idio24gpio' to silence this warning
           struct idio_24_gpio *idio24gpio;
                                          ^
                                           = NULL

1 warning generated.

vim +/idio24gpio +365 drivers/gpio/gpio-pcie-idio-24.c

329
330 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
331 {
332 struct device *const dev = &pdev->dev;
333 struct idio_24_gpio *idio24gpio;
334 int err;
335 const size_t pci_plx_bar_index = 1;
336 const size_t pci_bar_index = 2;
337 const char *const name = pci_name(pdev);
338 struct gpio_regmap_config gpio_config = {};
339 void __iomem *pex8311_intcsr;
340 void __iomem *idio_24_regs;
341 struct regmap *pex8311_intcsr_map;
342 struct regmap_irq_chip *chip;
343 struct regmap_irq_chip_data *chip_data;
344
345 err = pcim_enable_device(pdev);
346 if (err) {
347 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
348 return err;
349 }
350
351 err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
352 if (err) {
353 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
354 return err;
355 }
356
357 pex8311_intcsr = pcim_iomap_table(pdev)[pci_plx_bar_index] + PLX_PEX8311_PCI_LCS_INTCSR;
358 idio_24_regs = pcim_iomap_table(pdev)[pci_bar_index];
359
360 pex8311_intcsr_map = devm_regmap_init_mmio(dev, pex8311_intcsr,
361 &pex8311_intcsr_regmap_config);
362 if (IS_ERR(pex8311_intcsr_map))
363 return dev_err_probe(dev, PTR_ERR(pex8311_intcsr_map),
364 "Unable to initialize PEX8311 register map\n");

 > 365		idio24gpio->map = devm_regmap_init_mmio(dev, idio_24_regs,

366 &idio_24_regmap_config);
367 if (IS_ERR(idio24gpio->map))
368 return dev_err_probe(dev, PTR_ERR(idio24gpio->map),
369 "Unable to initialize register map\n");
370
371 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
372 if (!idio24gpio)
373 return -ENOMEM;
374
375 mutex_init(&idio24gpio->lock);
376
377 /* Initialize all IRQ type configuration to IRQ_TYPE_EDGE_BOTH */
378 idio24gpio->irq_type = GENMASK(7, 0);
379
380 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
381 if (!chip)
382 return -ENOMEM;
383
384 chip->name = name;
385 chip->status_base = IDIO_24_COS_STATUS_BASE;
386 chip->mask_base = IDIO_24_COS_ENABLE;
387 chip->ack_base = IDIO_24_COS_STATUS_BASE;
388 chip->num_regs = 4;
389 chip->irqs = idio_24_regmap_irqs;
390 chip->num_irqs = ARRAY_SIZE(idio_24_regmap_irqs);
391 chip->handle_mask_sync = idio_24_handle_mask_sync;
392 chip->set_type_config = idio_24_set_type_config;
393 chip->irq_drv_data = idio24gpio;
394
395 /* Software board reset */
396 err = regmap_write(idio24gpio->map, IDIO_24_SOFT_RESET, 0);
397 if (err)
398 return err;
399 /*
400 * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
401 * input
402 */
403 err = regmap_update_bits(pex8311_intcsr_map, 0x0, IDIO_24_ENABLE_IRQ,
404 IDIO_24_ENABLE_IRQ);
405 if (err)
406 return err;
407
408 err = devm_regmap_add_irq_chip(dev, idio24gpio->map, pdev->irq, 0, 0,
409 chip, &chip_data);
410 if (err)
411 return dev_err_probe(dev, err, "IRQ registration failed\n");
412
413 gpio_config.parent = dev;
414 gpio_config.regmap = idio24gpio->map;
415 gpio_config.ngpio = IDIO_24_NGPIO;
416 gpio_config.names = idio_24_names;
417 gpio_config.reg_dat_base = GPIO_REGMAP_ADDR(IDIO_24_OUT_BASE);
418 gpio_config.reg_set_base = GPIO_REGMAP_ADDR(IDIO_24_OUT_BASE);
419 gpio_config.reg_dir_out_base = GPIO_REGMAP_ADDR(IDIO_24_CONTROL_REG);
420 gpio_config.ngpio_per_reg = IDIO_24_NGPIO_PER_REG;
421 gpio_config.irq_domain = regmap_irq_get_domain(chip_data);
422 gpio_config.reg_mask_xlate = idio_24_reg_mask_xlate;
423 gpio_config.drvdata = idio24gpio->map;
424
425 return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config));
426 }
427

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
#4 lore raw

Re: [PATCH v3 2/3] gpio: pcie-idio-24: Migrate to the regmap API

In reply to William Breathitt Gray

Hi William,

url:    https://github.com/intel-lab-lkp/linux/commits/William-Breathitt-Gray/regmap-Pass-irq_drv_data-as-a-parameter-for-set_type_config/20230306-010313
base:   4827aae061337251bb91801b316157a78b845ec7
patch link:    https://lore.kernel.org/r/278e328cd1689a4e331e7515050c12c29f2a4785.1678034378.git.william.gray%40linaro.org
patch subject: [PATCH v3 2/3] gpio: pcie-idio-24: Migrate to the regmap API
config: loongarch-randconfig-m041-20230305 (https://download.01.org/0day-ci/archive/20230306/[email protected]/config)
compiler: loongarch64-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable

| Reported-by: kernel test robot <[email protected]>
| Reported-by: Dan Carpenter <[email protected]>
| Link: https://lore.kernel.org/r/[email protected]/

smatch warnings:
drivers/gpio/gpio-pcie-idio-24.c:365 idio_24_probe() error: potentially dereferencing uninitialized 'idio24gpio'.

vim +/idio24gpio +365 drivers/gpio/gpio-pcie-idio-24.c

58556204662812 William Breathitt Gray 2018-01-09  330  static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
58556204662812 William Breathitt Gray 2018-01-09  331  {
58556204662812 William Breathitt Gray 2018-01-09  332  	struct device *const dev = &pdev->dev;
58556204662812 William Breathitt Gray 2018-01-09  333  	struct idio_24_gpio *idio24gpio;
58556204662812 William Breathitt Gray 2018-01-09  334  	int err;
10a2f11d3c9e48 Arnaud de Turckheim    2020-11-04  335  	const size_t pci_plx_bar_index = 1;
58556204662812 William Breathitt Gray 2018-01-09  336  	const size_t pci_bar_index = 2;
58556204662812 William Breathitt Gray 2018-01-09  337  	const char *const name = pci_name(pdev);
e60d5c32ff098c William Breathitt Gray 2023-03-05  338  	struct gpio_regmap_config gpio_config = {};
e60d5c32ff098c William Breathitt Gray 2023-03-05  339  	void __iomem *pex8311_intcsr;
e60d5c32ff098c William Breathitt Gray 2023-03-05  340  	void __iomem *idio_24_regs;
e60d5c32ff098c William Breathitt Gray 2023-03-05  341  	struct regmap *pex8311_intcsr_map;
e60d5c32ff098c William Breathitt Gray 2023-03-05  342  	struct regmap_irq_chip *chip;
e60d5c32ff098c William Breathitt Gray 2023-03-05  343  	struct regmap_irq_chip_data *chip_data;
58556204662812 William Breathitt Gray 2018-01-09  344  
58556204662812 William Breathitt Gray 2018-01-09  345  	err = pcim_enable_device(pdev);
58556204662812 William Breathitt Gray 2018-01-09  346  	if (err) {
58556204662812 William Breathitt Gray 2018-01-09  347  		dev_err(dev, "Failed to enable PCI device (%d)\n", err);
58556204662812 William Breathitt Gray 2018-01-09  348  		return err;
58556204662812 William Breathitt Gray 2018-01-09  349  	}
58556204662812 William Breathitt Gray 2018-01-09  350  
10a2f11d3c9e48 Arnaud de Turckheim    2020-11-04  351  	err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
58556204662812 William Breathitt Gray 2018-01-09  352  	if (err) {
58556204662812 William Breathitt Gray 2018-01-09  353  		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
58556204662812 William Breathitt Gray 2018-01-09  354  		return err;
58556204662812 William Breathitt Gray 2018-01-09  355  	}
58556204662812 William Breathitt Gray 2018-01-09  356  
e60d5c32ff098c William Breathitt Gray 2023-03-05  357  	pex8311_intcsr = pcim_iomap_table(pdev)[pci_plx_bar_index] + PLX_PEX8311_PCI_LCS_INTCSR;
e60d5c32ff098c William Breathitt Gray 2023-03-05  358  	idio_24_regs = pcim_iomap_table(pdev)[pci_bar_index];
e60d5c32ff098c William Breathitt Gray 2023-03-05  359  
e60d5c32ff098c William Breathitt Gray 2023-03-05  360  	pex8311_intcsr_map = devm_regmap_init_mmio(dev, pex8311_intcsr,
e60d5c32ff098c William Breathitt Gray 2023-03-05  361  						   &pex8311_intcsr_regmap_config);
e60d5c32ff098c William Breathitt Gray 2023-03-05  362  	if (IS_ERR(pex8311_intcsr_map))
e60d5c32ff098c William Breathitt Gray 2023-03-05  363  		return dev_err_probe(dev, PTR_ERR(pex8311_intcsr_map),
e60d5c32ff098c William Breathitt Gray 2023-03-05  364  				     "Unable to initialize PEX8311 register map\n");

e60d5c32ff098c William Breathitt Gray 2023-03-05 @365 idio24gpio->map = devm_regmap_init_mmio(dev, idio_24_regs,
e60d5c32ff098c William Breathitt Gray 2023-03-05 366 &idio_24_regmap_config);

Heh. This needs to be after the idio24gpio = devm_kzalloc().

e60d5c32ff098c William Breathitt Gray 2023-03-05  367  	if (IS_ERR(idio24gpio->map))
e60d5c32ff098c William Breathitt Gray 2023-03-05  368  		return dev_err_probe(dev, PTR_ERR(idio24gpio->map),
e60d5c32ff098c William Breathitt Gray 2023-03-05  369  				     "Unable to initialize register map\n");
e60d5c32ff098c William Breathitt Gray 2023-03-05  370  
e60d5c32ff098c William Breathitt Gray 2023-03-05  371  	idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
e60d5c32ff098c William Breathitt Gray 2023-03-05  372  	if (!idio24gpio)
e60d5c32ff098c William Breathitt Gray 2023-03-05  373  		return -ENOMEM;
e60d5c32ff098c William Breathitt Gray 2023-03-05  374  
e60d5c32ff098c William Breathitt Gray 2023-03-05  375  	mutex_init(&idio24gpio->lock);
e60d5c32ff098c William Breathitt Gray 2023-03-05  376  
e60d5c32ff098c William Breathitt Gray 2023-03-05  377  	/* Initialize all IRQ type configuration to IRQ_TYPE_EDGE_BOTH */
e60d5c32ff098c William Breathitt Gray 2023-03-05  378  	idio24gpio->irq_type = GENMASK(7, 0);
e60d5c32ff098c William Breathitt Gray 2023-03-05  379  
e60d5c32ff098c William Breathitt Gray 2023-03-05  380  	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
e60d5c32ff098c William Breathitt Gray 2023-03-05  381  	if (!chip)
e60d5c32ff098c William Breathitt Gray 2023-03-05  382  		return -ENOMEM;
e60d5c32ff098c William Breathitt Gray 2023-03-05  383  
e60d5c32ff098c William Breathitt Gray 2023-03-05  384  	chip->name = name;
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
#5 lore raw

PATCH v3 3/3 gpio: ws16c48: Migrate to the regmap API

In reply to William Breathitt Gray

The regmap API supports IO port accessors so we can take advantage of regmap abstractions rather than handling access to the device registers directly in the driver.

The WinSystems WS16C48 provides the following registers:

    Offset 0x0-0x5: Port 0-5 I/O
    Offset 0x6: Int_Pending
    Offset 0x7: Page/Lock
    Offset 0x8-0xA (Page 1): Pol_0-Pol_2
    Offset 0x8-0xA (Page 2): Enab_0-Enab_2
    Offset 0x8-0xA (Page 3): Int_ID0-Int_ID2

Port 0-5 I/O provides access to 48 lines of digital I/O across six registers, each bit position corresponding to the respective line. Writing a 1 to a respective bit position causes that output pin to sink current, while writing a 0 to the same bit position causes that output pin to go to a high-impedance state and allows it to be used an input. Reads on a port report the inverted state (0 = high, 1 = low) of an I/O pin when used in input mode. Interrupts are supported on Port 0-2.

Int_Pending is a read-only register that reports the combined state of the INT_ID0 through INT_ID2 registers; an interrupt pending is indicated when any of the low three bits are set.

The Page/Lock register provides the following bits:

    Bit 0-5: Port 0-5 I/O Lock
    Bit 6-7: Page 0-3 Selection

For Bits 0-5, writing a 1 to a respective bit position locks the output state of the corresponding I/O port. Writing the page number to Bits 6-7 selects that respective register page for use.

Pol_0-Pol_2 are accessible when Page 1 is selected. Writing a 1 to a respective bit position selects the rising edge detection interrupts for that input line, while writing a 0 to the same bit position selects the falling edge detection interrupts.

Enab_0-Enab_2 are accessible when Page 2 is selected. Writing a 1 to a respective bit position enables interrupts for that input line, while writing a 0 to that same bit position clears and disables interrupts for that input line.

Int_ID0-Int_ID2 are accessible when Page 3 is selected. A respective bit when read as a 1 indicates that an edge of the polarity set in the corresponding polarity register was detected for the corresponding input line. Writing any value to this register clears all pending interrupts for the register.

---
 drivers/gpio/Kconfig        |   3 +
 drivers/gpio/gpio-ws16c48.c | 566 +++++++++++++-----------------------
 2 files changed, 202 insertions(+), 367 deletions(-)
drivers/gpio/Kconfig +3 -0
index 06c7a96e6033..e29b8a5ca2b2 100644
@@ -986,7 +986,10 @@ config GPIO_WINBOND
 config GPIO_WS16C48
 	tristate "WinSystems WS16C48 GPIO support"
 	select ISA_BUS_API
+	select REGMAP_IRQ
+	select REGMAP_MMIO
 	select GPIOLIB_IRQCHIP
+	select GPIO_REGMAP
 	help
 	  Enables GPIO support for the WinSystems WS16C48. The base port
 	  addresses for the devices may be configured via the base module
drivers/gpio/gpio-ws16c48.c +199 -367

669 lines not on this page · raw message

Signature · 1 line
2.39.2