Hi Andy,
Am 26.04.2018 um 12:06 schrieb Andy Shevchenko andy.shevchenko@gmail.com:
On Wed, Apr 25, 2018 at 9:05 PM, H. Nikolaus Schaller hns@goldelico.com wrote:
Am 11.04.2018 um 07:00 schrieb H. Nikolaus Schaller hns@goldelico.com:
Am 10.04.2018 um 20:06 schrieb Andy Shevchenko andy.shevchenko@gmail.com: On Tue, Apr 10, 2018 at 7:07 PM, H. Nikolaus Schaller hns@goldelico.com wrote:
PCAL chips ("L" seems to stand for "latched") have additional registers starting at address 0x40 to control the latches, interrupt mask, pull-up and pull down etc.
The constants are so far defined in a way that they fit for the pcal9555a when shifted by the number of banks, i.e. multiplied by 2.
Now the pcal6524 has 3 banks which means the relative offset must be multiplied by 4 which gives a wrong result if not done carefully, since the base offset is already included in the offset.
For the basic registers shared with all pca93xx/tca64xx chips there is no such offset.
Therefore, we add code to adjust the register number for exended registers to the 24 bit accessor functions.
And we add additional register offset constants (not yet used by the driver code) which are specific to the pcal6524.
First of all, as I said, please split this to two patches. Don't mix the things.
Ok. Queued for v4.
I actually think it would be even more patches:
- move to hex from dec
- add new definitions for PCAL953x
- append new code for registers (see below)
- add definitions for PCAL6524
It is already done in my local git, just waiting for the address thing...
/* adjust register address for pcal6524 */
if (reg >= PCAL953X_OUT_STRENGTH)
reg -= PCAL953X_OUT_STRENGTH >> 1;
Give me some days to think about it.
So, what about something like:
--- 8< --- 8< --- #define PCAL953X_GPIO_MASK GENMASK(5,0) // this makes sense even for your initial solution
int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); int addr = (reg & PCAL953X_GPIO_MASK) << bank_shift; int pinctrl = (reg & ~PCAL953X_GPIO_MASK) << 1;
Ok! Intersting idea.
Basically decomposes register bank number (pinctrl) and register offset (addr) and shifts them differently.
return i2c_smbus_write_i2c_block_data(chip->client, pinctrl | addr | REG_ADDR_AI, NBANK(chip), val);
// similar for read.
Looks good. I'll test asap.
BR and thanks, Nikolaus
--- 8< --- 8< ---
Keep in mind your solution has a bug for registers starting from 0x30.
-- With Best Regards, Andy Shevchenko