summaryrefslogtreecommitdiff
path: root/driver/led
diff options
context:
space:
mode:
authorBenjamin Gordon <bmgordon@chromium.org>2018-01-23 09:20:51 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-01-25 19:23:37 -0800
commitd258f8a78828fd925f95e91e4de8d1505fa3ea82 (patch)
tree5e6c70a690ddaff5df3db29459dd2fb883c4bde9 /driver/led
parentb46496c2d5d1ab56fdeb5a3626ffa0bcb60c26e6 (diff)
downloadchrome-ec-d258f8a78828fd925f95e91e4de8d1505fa3ea82.tar.gz
driver/led: Add LM3630A driver
This chip controls the keyboard backlight. The backlight level is set through PWM, but the chip needs to be enabled and configured before PWM settings are recognized. This will be initially used for grunt and zoombini. BUG=b:69379749 BRANCH=none TEST=In EC console for grunt: kblight 100; kblight 0 Change-Id: I5576d709687d8f61b5757485baa239ffd6b41a74 Signed-off-by: Benjamin Gordon <bmgordon@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/879082 Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'driver/led')
-rw-r--r--driver/led/lm3630a.c69
-rw-r--r--driver/led/lm3630a.h68
2 files changed, 137 insertions, 0 deletions
diff --git a/driver/led/lm3630a.c b/driver/led/lm3630a.c
new file mode 100644
index 0000000000..932afcf644
--- /dev/null
+++ b/driver/led/lm3630a.c
@@ -0,0 +1,69 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * TI LM3630A LED driver.
+ */
+
+#include "i2c.h"
+#include "lm3630a.h"
+
+/* 8-bit I2C address */
+#define LM3630A_I2C_ADDR (0x36 << 1)
+
+static inline int lm3630a_write(uint8_t reg, uint8_t val)
+{
+ return i2c_write8(I2C_PORT_KBLIGHT, LM3630A_I2C_ADDR, reg, val);
+}
+
+static inline int lm3630a_read(uint8_t reg, int *val)
+{
+ return i2c_read8(I2C_PORT_KBLIGHT, LM3630A_I2C_ADDR, reg, val);
+}
+
+int lm3630a_poweron(void)
+{
+ int ret = 0;
+
+ /* Sample PWM every 8 periods. */
+ ret |= lm3630a_write(LM3630A_REG_FILTER_STRENGTH, 0x3);
+
+ /* Enable feedback and PWM for banks A & B. */
+ ret |= lm3630a_write(LM3630A_REG_CONFIG,
+ LM3630A_CFG_BIT_FB_EN_A |
+ LM3630A_CFG_BIT_FB_EN_B |
+ LM3630A_CFG_BIT_PWM_EN_A |
+ LM3630A_CFG_BIT_PWM_EN_B);
+
+ /* 24V, 800mA overcurrent protection, 500kHz boost frequency. */
+ ret |= lm3630a_write(LM3630A_REG_BOOST_CONTROL,
+ LM3630A_BOOST_OVP_24V |
+ LM3630A_BOOST_OCP_800MA |
+ LM3630A_FMODE_500KHZ);
+
+ /* Limit current to 24.5mA */
+ ret |= lm3630a_write(LM3630A_REG_A_CURRENT, 0x1a);
+ ret |= lm3630a_write(LM3630A_REG_B_CURRENT, 0x1a);
+
+ /* Enable both banks, put in linear mode, and connect LED2 to bank A. */
+ ret |= lm3630a_write(LM3630A_REG_CONTROL,
+ LM3630A_CTRL_BIT_LINEAR_A |
+ LM3630A_CTRL_BIT_LINEAR_B |
+ LM3630A_CTRL_BIT_LED_EN_A |
+ LM3630A_CTRL_BIT_LED_EN_B |
+ LM3630A_CTRL_BIT_LED2_ON_A);
+
+ /*
+ * Set full brightness so that PWM will control. This needs to happen
+ * after setting the control register, because enabling the banks
+ * resets the value to 0.
+ */
+ ret |= lm3630a_write(LM3630A_REG_A_BRIGHTNESS, 0xff);
+
+ return ret;
+}
+
+int lm3630a_poweroff(void)
+{
+ return lm3630a_write(LM3630A_REG_CONTROL, LM3630A_CTRL_BIT_SLEEP_CMD);
+}
diff --git a/driver/led/lm3630a.h b/driver/led/lm3630a.h
new file mode 100644
index 0000000000..38fc52e111
--- /dev/null
+++ b/driver/led/lm3630a.h
@@ -0,0 +1,68 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * TI LM3630A LED driver.
+ */
+
+#ifndef __CROS_EC_LM3630A_H
+#define __CROS_EC_LM3630A_H
+
+#define LM3630A_REG_CONTROL 0x00
+#define LM3630A_REG_CONFIG 0x01
+#define LM3630A_REG_BOOST_CONTROL 0x02
+#define LM3630A_REG_A_BRIGHTNESS 0x03
+#define LM3630A_REG_B_BRIGHTNESS 0x04
+#define LM3630A_REG_A_CURRENT 0x05
+#define LM3630A_REG_B_CURRENT 0x06
+#define LM3630A_REG_ONOFF_RAMP 0x07
+#define LM3630A_REG_RUN_RAMP 0x08
+#define LM3630A_REG_INT_STATUS 0x09
+#define LM3630A_REG_INT_ENABLE 0x0a
+#define LM3630A_REG_FAULT_STATUS 0x0b
+#define LM3630A_REG_SW_RESET 0x0f
+#define LM3630A_REG_PWM_OUT_LOW 0x12
+#define LM3630A_REG_PWM_OUT_HIGH 0x13
+#define LM3630A_REG_REVISION 0x1f
+#define LM3630A_REG_FILTER_STRENGTH 0x50
+
+/* Control register bits */
+#define LM3630A_CTRL_BIT_SLEEP_CMD (1 << 7)
+#define LM3630A_CTRL_BIT_SLEEP_STAT (1 << 6)
+#define LM3630A_CTRL_BIT_LINEAR_A (1 << 4)
+#define LM3630A_CTRL_BIT_LINEAR_B (1 << 3)
+#define LM3630A_CTRL_BIT_LED_EN_A (1 << 2)
+#define LM3630A_CTRL_BIT_LED_EN_B (1 << 1)
+#define LM3630A_CTRL_BIT_LED2_ON_A (1 << 0)
+
+/* Config register bits */
+#define LM3630A_CFG_BIT_FB_EN_B (1 << 4)
+#define LM3630A_CFG_BIT_FB_EN_A (1 << 3)
+#define LM3630A_CFG_BIT_PWM_LOW (1 << 2)
+#define LM3630A_CFG_BIT_PWM_EN_B (1 << 1)
+#define LM3630A_CFG_BIT_PWM_EN_A (1 << 0)
+
+/* Boost control register bits */
+#define LM3630A_BOOST_OVP_16V (0 << 5)
+#define LM3630A_BOOST_OVP_24V (1 << 5)
+#define LM3630A_BOOST_OVP_32V (2 << 5)
+#define LM3630A_BOOST_OVP_40V (3 << 5)
+#define LM3630A_BOOST_OCP_600MA (0 << 3)
+#define LM3630A_BOOST_OCP_800MA (1 << 3)
+#define LM3630A_BOOST_OCP_1000MA (2 << 3)
+#define LM3630A_BOOST_OCP_1200MA (3 << 3)
+#define LM3630A_BOOST_SLOW_START (1 << 2)
+#define LM3630A_SHIFT_500KHZ (0 << 1) /* FMODE=0 */
+#define LM3630A_SHIFT_560KHZ (1 << 1) /* FMODE=0 */
+#define LM3630A_SHIFT_1000KHZ (0 << 1) /* FMODE=1 */
+#define LM3630A_SHIFT_1120KHZ (1 << 1) /* FMODE=1 */
+#define LM3630A_FMODE_500KHZ (0 << 0)
+#define LM3630A_FMODE_1000KHZ (1 << 0)
+
+/* Power on and initialize LM3630A. */
+int lm3630a_poweron(void);
+
+/* Power off LM3630A. */
+int lm3630a_poweroff(void);
+
+#endif /* __CROS_EC_LM3630A_H */