brcm2708: update to latest patches from RPi foundation
[openwrt/staging/chunkeey.git] / target / linux / brcm2708 / patches-4.19 / 950-0786-leds-pca963x-Fix-open-drain-initialization.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0786-leds-pca963x-Fix-open-drain-initialization.patch b/target/linux/brcm2708/patches-4.19/950-0786-leds-pca963x-Fix-open-drain-initialization.patch
new file mode 100644 (file)
index 0000000..e63d4c6
--- /dev/null
@@ -0,0 +1,61 @@
+From 1738aaf187e0c8e97fbdd9661960b835f45e8985 Mon Sep 17 00:00:00 2001
+From: Zahari Petkov <zahari@balena.io>
+Date: Mon, 18 Nov 2019 23:02:55 +0200
+Subject: [PATCH] leds: pca963x: Fix open-drain initialization
+
+commit 697529091ac7a0a90ca349b914bb30641c13c753 upstream.
+
+Before commit bb29b9cccd95 ("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: bb29b9cccd95 ("leds: pca963x: Add bindings to invert polarity")
+Signed-off-by: Zahari Petkov <zahari@balena.io>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+---
+ drivers/leds/leds-pca963x.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/leds/leds-pca963x.c
++++ b/drivers/leds/leds-pca963x.c
+@@ -43,6 +43,8 @@
+ #define PCA963X_LED_PWM               0x2     /* Controlled through PWM */
+ #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_MODE1         0x00
+@@ -462,12 +464,12 @@ static int pca963x_probe(struct i2c_clie
+                                                   PCA963X_MODE2);
+               /* Configure output: open-drain or totem pole (push-pull) */
+               if (pdata->outdrv == PCA963X_OPEN_DRAIN)
+-                      mode2 |= 0x01;
++                      mode2 &= ~PCA963X_MODE2_OUTDRV;
+               else
+-                      mode2 |= 0x05;
++                      mode2 |= PCA963X_MODE2_OUTDRV;
+               /* Configure direction: normal or inverted */
+               if (pdata->dir == PCA963X_INVERTED)
+-                      mode2 |= 0x10;
++                      mode2 |= PCA963X_MODE2_INVRT;
+               i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
+                                         mode2);
+       }