zephyr icon indicating copy to clipboard operation
zephyr copied to clipboard

[Driver] [GPIO] pca_series gpio expander driver

Open CkovMk opened this issue 5 months ago • 4 comments

Scope

I was trying to write a new driver for PCAL6524, a i2c gpio expander. Going thourgh existing drivers, there are numbers of driver for different PCA(L) series devices. They share similiar register layout and control logic. So I intends to unify these drivers for PCA(L)xxxx series i2c gpio expanders. If this driver gets merged, it should retire pca95xx , pca953x and pcal64xxa drivers.

Method

By referencing exsisting gpio_pca95xx and pcal64xxa driver, I have drafted these code to show my intended implementation. As shown in code, different capablilties can be defined:

  • basic functions this applies to all compatiable devices.
  • "latch" and drive strength this is what "L" in PCALxxxx means. allows to "latch" input until read and configure drive strength to one of 4 levels.
  • pull up/down pull enable and pull select
  • interrupt mask able to mask interrupt on certain pins. most PCAL devices has this, as well as PCA957x.
  • interrupt edge / clear seen on PCAL6524.
  • output config seen on PCAL6524. note that although many devices is able to configure push-pull or open-drain on a per-port basis, PCAL6524 suports configure on a per-pin basis.

We can describe a compatible device using a set of feature flags and ngpios property. Based on that, it's possible to create separate register maps and api maps to drive different devices.

Question

  1. Is it necessary to maintain cache for all config registers? In the original code, lots of registers are "cached" to speed-up the "read-modify-write" process. In my view, I/O expanders are not meant to be frequenty reconfigured. We also do not have tools like regmap in linux to automate the caching. Maintaining cache for devices with different port size can be complicated in coding. My intention is to only cache output values. update: The final implementation use Kconfig to control caching. I've tested the GPIO_PCA_SERIES_CACHE_ALL=n option on pcal6524 on mimx93_evk_a55 board. The GPIO_PCA_SERIES_CACHE_ALL=y option remains to be fully tested.

  2. Is there way to avoid creating multiple dt-bindings? I tried to avoid creating a lot of dt-bindings by put a "part_no" property under a single nxp,pca_series.yaml dt-binding.

Any suggestions are welcomed.

Thanks

CkovMk avatar Feb 22 '24 11:02 CkovMk