Commit 69752909 authored by Zahari Petkov's avatar Zahari Petkov Committed by Pavel

leds: pca963x: Fix open-drain initialization

Before commit bb29b9cc ("leds: pca963x: Add bindings to invert
polarity") Mode register 2 was initialized directly with either 0x01
or 0x05 for open-drain or totem pole (push-pull) configuration.

Afterwards, MODE2 initialization started using bitwise operations on
top of the default MODE2 register value (0x05). Using bitwise OR for
setting OUTDRV with 0x01 and 0x05 does not produce correct results.
When open-drain is used, instead of setting OUTDRV to 0, the driver
keeps it as 1:

Open-drain: 0x05 | 0x01 -> 0x05 (0b101 - incorrect)
Totem pole: 0x05 | 0x05 -> 0x05 (0b101 - correct but still wrong)

Now OUTDRV setting uses correct bitwise operations for initialization:

Open-drain: 0x05 & ~0x04 -> 0x01 (0b001 - correct)
Totem pole: 0x05 | 0x04 -> 0x05 (0b101 - correct)

Additional MODE2 register definitions are introduced now as well.

Fixes: bb29b9cc ("leds: pca963x: Add bindings to invert polarity")
Signed-off-by: default avatarZahari Petkov <zahari@balena.io>
Signed-off-by: default avatarPavel Machek <pavel@ucw.cz>
parent 9f4b952d
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#define PCA963X_LED_PWM 0x2 /* Controlled through PWM */ #define PCA963X_LED_PWM 0x2 /* Controlled through PWM */
#define PCA963X_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */ #define PCA963X_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
#define PCA963X_MODE2_OUTDRV 0x04 /* Open-drain or totem pole */
#define PCA963X_MODE2_INVRT 0x10 /* Normal or inverted direction */
#define PCA963X_MODE2_DMBLNK 0x20 /* Enable blinking */ #define PCA963X_MODE2_DMBLNK 0x20 /* Enable blinking */
#define PCA963X_MODE1 0x00 #define PCA963X_MODE1 0x00
...@@ -438,12 +440,12 @@ static int pca963x_probe(struct i2c_client *client, ...@@ -438,12 +440,12 @@ static int pca963x_probe(struct i2c_client *client,
PCA963X_MODE2); PCA963X_MODE2);
/* Configure output: open-drain or totem pole (push-pull) */ /* Configure output: open-drain or totem pole (push-pull) */
if (pdata->outdrv == PCA963X_OPEN_DRAIN) if (pdata->outdrv == PCA963X_OPEN_DRAIN)
mode2 |= 0x01; mode2 &= ~PCA963X_MODE2_OUTDRV;
else else
mode2 |= 0x05; mode2 |= PCA963X_MODE2_OUTDRV;
/* Configure direction: normal or inverted */ /* Configure direction: normal or inverted */
if (pdata->dir == PCA963X_INVERTED) if (pdata->dir == PCA963X_INVERTED)
mode2 |= 0x10; mode2 |= PCA963X_MODE2_INVRT;
i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2, i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
mode2); mode2);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment