leds: leds-pm8xxx: Add CABC support for backlight control

Content adaptive backlight control (CABC) support is needed to
control backlight by external PWM.  It can be enabled by setting
"cabc_en = true" in the platform data wled_cfg structure.

CRs-fixed: 379347
Change-Id: If30defd3a3ca61283233c97ab26f255a3a62ad7c
Signed-off-by: Amy Maloche <amaloche@codeaurora.org>
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 04041e4..255920e 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -80,6 +80,17 @@
 
 #define WLED_SYNC_VAL			0x07
 #define WLED_SYNC_RESET_VAL		0x00
+#define WLED_SYNC_MASK			0xF8
+
+#define ONE_WLED_STRING			1
+#define TWO_WLED_STRINGS		2
+#define THREE_WLED_STRINGS		3
+
+#define WLED_CABC_ONE_STRING		0x01
+#define WLED_CABC_TWO_STRING		0x03
+#define WLED_CABC_THREE_STRING		0x07
+
+#define WLED_CABC_SHIFT			3
 
 #define SSBI_REG_ADDR_RGB_CNTL1		0x12D
 #define SSBI_REG_ADDR_RGB_CNTL2		0x12E
@@ -290,17 +301,23 @@
 			return rc;
 		}
 	}
-
+	rc = pm8xxx_readb(led->dev->parent, WLED_SYNC_REG, &val);
+	if (rc) {
+		dev_err(led->dev->parent,
+			"can't read wled sync register rc=%d\n", rc);
+		return rc;
+	}
 	/* sync */
-	val = WLED_SYNC_VAL;
+	val &= WLED_SYNC_MASK;
+	val |= WLED_SYNC_VAL;
 	rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
 	if (rc) {
 		dev_err(led->dev->parent,
 			"can't read wled sync register rc=%d\n", rc);
 		return rc;
 	}
-
-	val = WLED_SYNC_RESET_VAL;
+	val &= WLED_SYNC_MASK;
+	val |= WLED_SYNC_RESET_VAL;
 	rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
 	if (rc) {
 		dev_err(led->dev->parent,
@@ -656,6 +673,36 @@
 		}
 	}
 
+	if (led->wled_cfg->cabc_en) {
+		rc = pm8xxx_readb(led->dev->parent, WLED_SYNC_REG, &val);
+		if (rc) {
+			dev_err(led->dev->parent,
+				"can't read cabc register rc=%d\n", rc);
+			return rc;
+		}
+
+		switch (num_wled_strings) {
+		case ONE_WLED_STRING:
+			val |= (WLED_CABC_ONE_STRING << WLED_CABC_SHIFT);
+			break;
+		case TWO_WLED_STRINGS:
+			val |= (WLED_CABC_TWO_STRING << WLED_CABC_SHIFT);
+			break;
+		case THREE_WLED_STRINGS:
+			val |= (WLED_CABC_THREE_STRING << WLED_CABC_SHIFT);
+			break;
+		default:
+			break;
+		}
+
+		rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
+		if (rc) {
+			dev_err(led->dev->parent,
+				"can't write to enable cabc rc=%d\n", rc);
+			return rc;
+		}
+	}
+
 	/* program digital module generator, cs out and enable the module */
 	rc = pm8xxx_readb(led->dev->parent, WLED_MOD_CTRL_REG, &val);
 	if (rc) {