diff options
-rw-r--r-- | board/lg/sniper/Makefile | 2 | ||||
-rw-r--r-- | board/lg/sniper/lp8720.c | 109 | ||||
-rw-r--r-- | board/lg/sniper/lp8720.h | 93 | ||||
-rw-r--r-- | board/lg/sniper/sniper.c | 49 | ||||
-rw-r--r-- | board/lg/sniper/sniper.h | 2 |
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 |