drivers: led: bcm6858: Set a default brightness when probing LEDs

When probing the LEDs, a default brightness is set based on settings
from the U-Boot device tree, i.e. the 'default-brightness' property
of the LED nodes. If that property is not present, the default
maximum brightness is set.
This should make sure the LED controller's registers affecting the
brightness are correctly initialized and should give a consistent
behaviour.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
diff --git a/drivers/led/led_bcm6858.c b/drivers/led/led_bcm6858.c
index fbf46a1..3ca6c5b 100644
--- a/drivers/led/led_bcm6858.c
+++ b/drivers/led/led_bcm6858.c
@@ -18,6 +18,7 @@
 
 #define LEDS_MAX		32
 #define LEDS_WAIT		100
+#define LEDS_MAX_BRIGHTNESS	7
 
 /* LED Mode register */
 #define LED_MODE_REG		0x0
@@ -38,6 +39,8 @@
 #define LED_HW_LED_EN_REG		0x08
 /* LED Flash control register0 */
 #define LED_FLASH_RATE_CONTROL_REG0	0x10
+/* LED Brightness control register0 */
+#define LED_BRIGHTNESS_CONTROL_REG0	0x20
 /* Soft LED input register */
 #define LED_SW_LED_IP_REG		0xb8
 /* Parallel LED Output Polarity Register */
@@ -96,6 +99,27 @@
 }
 #endif
 
+static int led_set_brightness(struct udevice *dev, unsigned int brightness)
+{
+	struct bcm6858_led_priv *priv = dev_get_priv(dev);
+	u32 offset, shift, mask, value;
+
+	offset = (priv->pin / 8) * 4;
+	shift  = (priv->pin % 8) * 4;
+	mask   = 0xf << shift;
+
+	/* 8 levels of brightness achieved through PWM */
+	value = (brightness > LEDS_MAX_BRIGHTNESS ?
+			LEDS_MAX_BRIGHTNESS : brightness) << shift;
+
+	debug("%s: %s brightness set to %u\n", __func__, dev->name, value >> shift);
+
+	clrbits_32(priv->regs + LED_BRIGHTNESS_CONTROL_REG0 + offset, mask);
+	setbits_32(priv->regs + LED_BRIGHTNESS_CONTROL_REG0 + offset, value);
+
+	return 0;
+}
+
 static enum led_state_t bcm6858_led_get_state(struct udevice *dev)
 {
 	struct bcm6858_led_priv *priv = dev_get_priv(dev);
@@ -113,6 +137,8 @@
 {
 	struct bcm6858_led_priv *priv = dev_get_priv(dev);
 
+	debug("%s: Set led %s to %d\n", __func__, dev->name, state);
+
 	switch (state) {
 	case LEDST_OFF:
 		clrbits_32(priv->regs + LED_SW_LED_IP_REG, (1 << priv->pin));
@@ -180,7 +206,7 @@
 	} else {
 		struct bcm6858_led_priv *priv = dev_get_priv(dev);
 		void __iomem *regs;
-		unsigned int pin;
+		unsigned int pin, brightness;
 
 		regs = dev_remap_addr(dev_get_parent(dev));
 		if (!regs)
@@ -201,6 +227,10 @@
 			clrbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin);
 		else
 			setbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin);
+
+		brightness = dev_read_u32_default(dev, "default-brightness",
+						  LEDS_MAX_BRIGHTNESS);
+		led_set_brightness(dev, brightness);
 	}
 
 	return 0;