aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/lg/sniper/Makefile2
-rw-r--r--board/lg/sniper/lp8720.c109
-rw-r--r--board/lg/sniper/lp8720.h93
-rw-r--r--board/lg/sniper/sniper.c49
-rw-r--r--board/lg/sniper/sniper.h2
5 files changed, 253 insertions, 2 deletions
diff --git a/board/lg/sniper/Makefile b/board/lg/sniper/Makefile
index f32a481d0e2..bdd5f2273eb 100644
--- a/board/lg/sniper/Makefile
+++ b/board/lg/sniper/Makefile
@@ -6,4 +6,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y := sniper.o
+obj-y := sniper.o lp8720.o
diff --git a/board/lg/sniper/lp8720.c b/board/lg/sniper/lp8720.c
new file mode 100644
index 00000000000..3c33fc59c90
--- /dev/null
+++ b/board/lg/sniper/lp8720.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+#include "lp8720.h"
+
+static struct lp8720_info lp8720_info;
+
+static int lp8720_write(u8 reg, u8 val)
+{
+ return i2c_write(lp8720_info.chip_idsel, reg, 1, &val, 1);
+}
+
+static int lp8720_read(u8 reg, u8 *val)
+{
+ return i2c_read(lp8720_info.chip_idsel, reg, 1, val, 1);
+}
+
+int lp8720_init(int enable_gpio, int chip_idsel)
+{
+ int ret;
+
+ if (enable_gpio) {
+/*
+ if (!gpio_is_valid(enable_gpio))
+ return -1;
+*/
+
+ ret = gpio_request(enable_gpio, "lp8720_en");
+ if (ret)
+ return ret;
+
+ ret = gpio_direction_output(enable_gpio, 0);
+ if (ret)
+ return ret;
+ }
+
+ lp8720_info.enable_gpio = enable_gpio;
+ lp8720_info.chip_idsel = chip_idsel;
+
+ return 0;
+}
+
+int lp8720_enable(void)
+{
+ int ret;
+
+ if (lp8720_info.enable_gpio) {
+ ret = gpio_set_value(lp8720_info.enable_gpio, 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int lp8720_is_enabled(void)
+{
+ if (lp8720_info.enable_gpio)
+ return gpio_get_value(lp8720_info.enable_gpio);
+
+ /* Assume LP8720 enabled when there is no enable GPIO */
+ return 1;
+}
+
+int lp8720_ldo_enable(u8 ldo_enable)
+{
+ u8 val;
+ int ret;
+
+ ret = lp8720_read(LP8720_ENABLE_BITS, &val);
+ if (ret)
+ return ret;
+
+ val |= ldo_enable;
+
+ ret = lp8720_write(LP8720_ENABLE_BITS, val);
+ if (ret)
+ return ret;
+
+ /* Enable the IC */
+ if (!lp8720_is_enabled())
+ lp8720_enable();
+
+ return 0;
+}
+
+int lp8720_ldo_voltage(u8 ldo_reg, u8 voltage, u8 delay)
+{
+ u8 val;
+ int ret;
+
+ /* Register V field */
+ val = voltage & 0x1F;
+
+ /* Register T field */
+ val |= (delay & 0x07) << 5;
+
+ ret = lp8720_write(ldo_reg, val);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/board/lg/sniper/lp8720.h b/board/lg/sniper/lp8720.h
new file mode 100644
index 00000000000..033f2c46055
--- /dev/null
+++ b/board/lg/sniper/lp8720.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef LP8720_H
+#define LP8720_H
+
+#include <common.h>
+
+/*
+ * Chip ID selection
+ */
+
+#define LP8720_CHIP_IDSEL_VBATT 0x7F
+#define LP8720_CHIP_IDSEL_HI_Z 0x7C
+#define LP8720_CHIP_IDSEL_GND 0x7D
+
+/*
+ * Registers
+ */
+
+#define LP8720_GENERAL_SETTINGS 0x00
+#define LP8720_LDO1_SETTINGS 0x01
+#define LP8720_LDO2_SETTINGS 0x02
+#define LP8720_LDO3_SETTINGS 0x03
+#define LP8720_LDO4_SETTINGS 0x04
+#define LP8720_LDO5_SETTINGS 0x05
+#define LP8720_BUCK_SETTINGS1 0x06
+#define LP8720_BUCK_SETTINGS2 0x07
+#define LP8720_ENABLE_BITS 0x08
+#define LP8720_PULLDOWN_BITS 0x09
+#define LP8720_STATUS_BITS 0x0A
+#define LP8720_INTERRUPT_BITS 0x0B
+#define LP8720_INTERRUPT_MASK 0x0C
+
+/*
+ * Values
+ */
+
+/* LP8720_GENERAL_SETTINGS */
+#define LP8720_25_US_TIME_STEP (1 << 0)
+#define LP8720_50_US_TIME_STEP (0 << 0)
+
+/* LP8720_LDO*_SETTINGS */
+#define LP8720_LDO1235_V_12 0x00
+#define LP8720_LDO1235_V_18 0x0C
+#define LP8720_LDO1235_V_30 0x1D
+#define LP8720_LDO1235_V_33 0x1F
+
+#define LP8720_LDO4_V_12 0x00
+#define LP8720_LDO4_V_14 0x09
+#define LP8720_LDO4_V_18 0x11
+#define LP8720_LDO4_V_28 0x1E
+
+#define LP8720_DELAY_0 0
+#define LP8720_DELAY_1_TS 1
+#define LP8720_DELAY_2_TS 2
+#define LP8720_DELAY_3_TS 3
+#define LP8720_DELAY_4_TS 4
+#define LP8720_DELAY_5_TS 5
+#define LP8720_DELAY_6_TS 6
+#define LP8720_DELAY_NO_START 7
+
+/* LP8720_ENABLE_BITS */
+#define LP8720_LDO1_EN (1 << 0)
+#define LP8720_LDO2_EN (1 << 1)
+#define LP8720_LDO3_EN (1 << 2)
+#define LP8720_LDO4_EN (1 << 3)
+#define LP8720_LDO5_EN (1 << 4)
+#define LP8720_BUCK_EN (1 << 5)
+
+/*
+ * Driver info
+ */
+
+struct lp8720_info {
+ int enable_gpio;
+ int chip_idsel;
+};
+
+/*
+ * Declarations
+ */
+
+int lp8720_init(int enable_gpio, int chip_idsel);
+int lp8720_enable(void);
+int lp8720_is_enabled(void);
+int lp8720_ldo_enable(u8 ldo_enable);
+int lp8720_ldo_voltage(u8 ldo_reg, u8 voltage, u8 delay);
+
+#endif
diff --git a/board/lg/sniper/sniper.c b/board/lg/sniper/sniper.c
index 7524000b8bb..72953788d9b 100644
--- a/board/lg/sniper/sniper.c
+++ b/board/lg/sniper/sniper.c
@@ -19,6 +19,7 @@
#include <asm/io.h>
#include <ns16550.h>
#include <twl4030.h>
+#include "lp8720.h"
#include "sniper.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -251,11 +252,57 @@ int fb_set_reboot_flag(void)
#ifndef CONFIG_SPL_BUILD
int board_mmc_init(bd_t *bis)
{
- return omap_mmc_init(1, 0, 0, -1, -1);
+ int ret;
+
+ ret = omap_mmc_init(0, 0, 0, SNIPER_GPIO_MICROSD_DET_N, -1);
+ if (ret)
+ return ret;
+
+ ret = omap_mmc_init(1, 0, 0, -1, -1);
+ if (ret)
+ return ret;
+
+ return 0;
}
#endif
void board_mmc_power_init(void)
{
+ /*
+ * In order to boot from MMC1 (microsd card), the LP8720 LDO1 (3.0V_MMC)
+ * regulator has to be enabled. The LP8720 is accessed through I2C3.
+ *
+ * Enabling TWL4030 VAUX2 (3.0V_MOTION) and TWL4030 VDAC
+ * (1.8V_MOTION_VIO) is required to power the sensors that are slaves
+ * on I2C3. When not powered, these sensors cause I2C3 SCK to stay low.
+ */
+
+ i2c_set_bus_num(0);
+
+ /* TWL4030 VAUX2 (3.0V_MOTION) to 2.8V */
+ twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
+ TWL4030_PM_RECEIVER_VAUX2_VSEL_28,
+ TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
+ TWL4030_PM_RECEIVER_DEV_GRP_P1);
+
+ /* TWL4030 VDAC (1.8V_MOTION_VIO) to 1.8V */
+ twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VDAC_DEDICATED,
+ TWL4030_PM_RECEIVER_VDAC_VSEL_18,
+ TWL4030_PM_RECEIVER_VDAC_DEV_GRP,
+ TWL4030_PM_RECEIVER_DEV_GRP_P1);
+
+ mdelay(100); /* ramp-up delay from Linux code */
+
+ i2c_set_bus_num(2);
+
+ lp8720_init(SNIPER_GPIO_CAM_SUBPM_EN, LP8720_CHIP_IDSEL_GND);
+
+ /* LP8720 LDO1 (3.0V_MMC) to 3.0V */
+ lp8720_ldo_voltage(LP8720_LDO1_SETTINGS, LP8720_LDO1235_V_30,
+ LP8720_DELAY_0);
+ lp8720_ldo_enable(LP8720_LDO1_EN);
+
+ i2c_set_bus_num(0);
+
twl4030_power_mmc_init(1);
}
diff --git a/board/lg/sniper/sniper.h b/board/lg/sniper/sniper.h
index e07a0016654..7146bb5e584 100644
--- a/board/lg/sniper/sniper.h
+++ b/board/lg/sniper/sniper.h
@@ -11,6 +11,8 @@
#include <asm/arch/mux.h>
+#define SNIPER_GPIO_MICROSD_DET_N 10
+#define SNIPER_GPIO_CAM_SUBPM_EN 37
#define SNIPER_GPIO_LCD_CP_EN 62
#define SNIPER_GPIO_KEY_LED_RESET 128