From b9270bf5069458988e55c007b17c944d6d522aba Mon Sep 17 00:00:00 2001 From: Rene Straub Date: Wed, 27 Jun 2018 08:36:37 +0200 Subject: [PATCH] hancock: pmic configuration - da9063 pmic driver refactoring - fixing register settings for pre v1.3 configuration --- board/nm/hancock/board.c | 103 ++++++++++++++++++++++++++++--------- board/nm/hancock/da9063.c | 104 +++++++++++++++++++++++++++++++------- board/nm/hancock/da9063.h | 24 +++++++-- 3 files changed, 186 insertions(+), 45 deletions(-) diff --git a/board/nm/hancock/board.c b/board/nm/hancock/board.c index af283e1fb4..e41d423c23 100644 --- a/board/nm/hancock/board.c +++ b/board/nm/hancock/board.c @@ -358,6 +358,57 @@ struct dpll_params dpll_ddr = { DDR3_CLOCK_FREQUENCY, OSC-1, 1, -1, -1, -1, -1 }; +static void init_pmic_spl(void) +{ + int rc; + int bus; + uint8_t val; + + /* PMIC basic configuration */ + da9063_init(CONFIG_PMIC_I2C_BUS); + + bus = da9063_claim_i2c_bus(); + + /* Workaround for pre v1.3 config (reports ID 0x3e) */ + rc = da9063_get_reg(PMIC_REG_CONFIG_ID, &val); + if (!rc && (val == 0x3E)) { + printf("Detected pre v1.3 PMIC config. Fixing registers\n"); + + /* Include +3V3_SENSORS (LDO3) in sequencing and enable manually */ + (void)da9063_set_reg(PMIC_REG_ID_4_3, 0x07 /* Slot 7 */); + (void)da9063_set_reg(PMIC_REG_LDO3_CONT, PMIC_LDOx_EN_MASK); + + /* + * Set AUTO Bit for sequencer controlled supplies, so that they get + * enabled when leaving power down state + */ + (void)da9063_set_reg(PMIC_REG_CONFIG_E, 0x3B); + (void)da9063_set_reg(PMIC_REG_CONFIG_G, 0x44); + + /* + * Clear sequencer target state bit (xxx_CONT::xxx_CONF bit), so that + * regulators are disabled when entering power down state. + */ + (void)da9063_set_reg(PMIC_REG_LDO3_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_LDO7_CONT, PMIC_LDOx_EN_MASK); + + (void)da9063_set_reg(PMIC_REG_BCORE1_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BCORE2_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BPERI_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BIO_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BMEM_CONT, PMIC_LDOx_EN_MASK); + } + + /* Enable +3V3_GNSS (LDO6) */ + (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); + mdelay(2); + + /* Enable +5V_CAN (LDO11 Switch) */ + (void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK); + mdelay(2); + + da9063_release_i2c_bus(bus); +} void am33xx_spl_board_init(void) { @@ -370,17 +421,8 @@ void am33xx_spl_board_init(void) /* Configure I2C busses */ init_i2c(); - /* PMIC basic configuration */ - da9063_init(CONFIG_PMIC_I2C_BUS); - - /* Enable +3V3_SENSOR (LDO3) - Not enabled in early PMIC configs */ - (void)da9063_set_reg(PMIC_REG_LDO3_CONT, PMIC_LDOx_EN_MASK); - - /* Enable +3V3_GNSS (LDO6) */ - (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); - - /* Enable +5V_CAN (LDO11 Switch) */ - (void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK); + /* Setup PMIC */ + init_pmic_spl(); init_leds(); set_status_led(1, 1); /* Orange */ /* TODO: -> Broken #2 use indicator led instead */ @@ -498,6 +540,10 @@ static void init_usb_hub(void) static void init_user_module(void) { + int bus; + + bus = da9063_claim_i2c_bus(); + /* TODO: Open Drain as UM can drive against mainboard */ /* TODO: Check whether reset shall be driven by mainboard at all */ /* REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_RST_PHY_N); */ @@ -521,6 +567,8 @@ static void init_user_module(void) gpio_direction_input(GPIO_RST_UM_N); /* Release reset (open drain) */ puts("ready\n"); + + da9063_release_i2c_bus(bus); } static void init_sim_mux(void) @@ -533,6 +581,8 @@ static void init_sim_mux(void) static void init_gsm(void) { + int bus; + /* * Perform power up sequence for TOBY-L2 modem. * @@ -544,8 +594,9 @@ static void init_gsm(void) * 2.3.1 Module power-on */ + bus = da9063_claim_i2c_bus(); + puts("GSM: "); - /* TODO: Update for uBlox TOBY-L2 */ /* TODO: Keep Power-On and use GSM Modem Reset Signal to restart */ @@ -560,15 +611,10 @@ static void init_gsm(void) mdelay(10); gpio_set_value(GPIO_RST_GSM, 0); /* Take modem out of reset */ - /* TODO: Check and update as required */ -#if 0 - mdelay(300); /* Wait for power to stabilizy, #3.4.2 */ - gpio_set_value(GPIO_PWR_GSM, 1); /* Generate power on event, #3.4.2 */ - mdelay(1200); - gpio_set_value(GPIO_PWR_GSM, 0); -#endif puts("ready\n"); + + da9063_release_i2c_bus(bus); } static void init_gnss(void) @@ -670,10 +716,21 @@ static void get_pmic_version(void) { uint8_t val = 0x00; uint8_t ver, rev; + int bus; + int rc; - (void)da9063_get_reg(PMIC_REG_CONFIG_ID, &val); - ver = (val >> 4) & 0xF; - rev = (val >> 0) & 0xF; + bus = da9063_claim_i2c_bus(); + + rc = da9063_get_reg(PMIC_REG_CONFIG_ID, &val); + if (!rc) { + ver = (val >> 4) & 0xF; + rev = (val >> 0) & 0xF; + } else { + ver = 0; + rev = 0; + } + + da9063_release_i2c_bus(bus); /* Quirk: * If reported version is 3.14, this is one of the 5 prototypes which have @@ -714,6 +771,7 @@ static bool get_button_state(void) { u8 state = 0x00; + /* TODO: Claim Bus */ (void)da9063_get_reg(PMIC_REG_STATUS_A, &state); return (state & 0x01) == 0x01; @@ -1015,4 +1073,3 @@ U_BOOT_CMD( ); #endif - diff --git a/board/nm/hancock/da9063.c b/board/nm/hancock/da9063.c index efa6eb1c4c..2deaeacf98 100644 --- a/board/nm/hancock/da9063.c +++ b/board/nm/hancock/da9063.c @@ -16,6 +16,33 @@ static int da9063_i2c_bus = 0; +static int bus_claimed = 0; + + +static int switch_i2c_bus(void) +{ + int old_bus; + + old_bus = i2c_get_bus_num(); + if (old_bus != da9063_i2c_bus) { + printf("i2c sw from %d\n", old_bus); + i2c_set_bus_num(da9063_i2c_bus); + } + + bus_claimed++; + + return old_bus; +} + +static void revert_i2c_bus(int bus) +{ + if (da9063_i2c_bus != bus) { + printf("i2c sw back to %d\n", bus); + i2c_set_bus_num(bus); + } + + bus_claimed--; +} void da9063_init(int i2c_bus) @@ -23,47 +50,67 @@ void da9063_init(int i2c_bus) da9063_i2c_bus = i2c_bus; } -int da9063_get_reg(int reg, u8* val) +int da9063_claim_i2c_bus(void) +{ + return switch_i2c_bus(); +} + +void da9063_release_i2c_bus(int bus) +{ + revert_i2c_bus(bus); +} + +int da9063_get_reg(uint32_t reg, u8* val) { int ret; - int old_bus; u8 temp; - /* TODO: Check whether switching is required */ - old_bus = i2c_get_bus_num(); - i2c_set_bus_num(da9063_i2c_bus); + /* Argument check */ + if ((reg >= 0x200) || (val==0)) { + return -1; + } + + /* State check. Has bus been claimed */ + if (bus_claimed == 0) { + return -2; + } - /* TODO: Use CONFIG_PMIC_I2C_ADDR+1 if reg > 0xFF */ *val = 0; if (reg < 0x100) { - ret = i2c_read(CONFIG_PMIC_I2C_ADDR, reg & 0xFF, 1, &temp, 1); + ret = i2c_read(CONFIG_PMIC_I2C_ADDR+0, reg & 0xFF, 1, &temp, 1); } else { ret = i2c_read(CONFIG_PMIC_I2C_ADDR+1, reg & 0xFF, 1, &temp, 1); } + if (ret == 0) *val = temp; - i2c_set_bus_num(old_bus); - return ret; } -int da9063_set_reg(int reg, u8 val) +int da9063_set_reg(uint32_t reg, u8 val) { int ret; - int old_bus; - /* TODO: Check whether switching is required */ - old_bus = i2c_get_bus_num(); - i2c_set_bus_num(da9063_i2c_bus); + /* Argument check */ + if ((reg >= 0x200) || (val==0)) { + return -1; + } + + /* State check. Has bus been claimed */ + if (bus_claimed == 0) { + return -2; + } + + if (reg < 0x100) { + ret = i2c_write(CONFIG_PMIC_I2C_ADDR+0, reg & 0xFF, 1, &val, 1); + } else { + ret = i2c_write(CONFIG_PMIC_I2C_ADDR+1, reg & 0xFF, 1, &val, 1); + } - /* TODO: Use CONFIG_PMIC_I2C_ADDR+1 if reg > 0xFF */ - ret = i2c_write(CONFIG_PMIC_I2C_ADDR, reg, 1, &val, 1); if (ret != 0) puts("da9063 write error\n"); - i2c_set_bus_num(old_bus); - return ret; } @@ -94,3 +141,24 @@ void da9063_set_gpio(unsigned bit, int state) } } +static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint8_t val = 0; + int bus; + int rc; + + bus = da9063_claim_i2c_bus(); + + rc = da9063_get_reg(0x2c, &val); + printf("%d: %02x\n", rc, val); + + da9063_release_i2c_bus(bus); + + return 0; +} + +U_BOOT_CMD( + pmic, 1, 1, do_pmic, + "pmic", + "" +); diff --git a/board/nm/hancock/da9063.h b/board/nm/hancock/da9063.h index 6f07fd9547..2ff56e5ea4 100644 --- a/board/nm/hancock/da9063.h +++ b/board/nm/hancock/da9063.h @@ -19,25 +19,41 @@ #define PMIC_REG_GPIO_MODE0_7 0x1D /* Control register for GPIOs 0..7 */ #define PMIC_REG_GPIO_MODE8_15 0x1E /* Control register for GPIOs 8..15 */ +#define PMIC_REG_BCORE1_CONT 0x21 /* Control register of BCORE1 */ +#define PMIC_REG_BCORE2_CONT 0x20 /* Control register of BCORE2 */ +#define PMIC_REG_BPERI_CONT 0x25 /* Control register of BPERI */ +#define PMIC_REG_BIO_CONT 0x24 /* Control register of BIO */ +#define PMIC_REG_BMEM_CONT 0x23 /* Control register of BMEM */ + #define PMIC_REG_LDO3_CONT 0x28 /* Control register of LDO3 */ #define PMIC_REG_LDO6_CONT 0x2B /* Control register of LDO6 */ #define PMIC_REG_LDO7_CONT 0x2C /* Control register of LDO7 */ #define PMIC_REG_LDO11_CONT 0x30 /* Control register of LDO11 */ + #define PMIC_LDOx_EN_MASK 0x01 +#define PMIC_LDOx_CONF_MASK 0x80 - -#define PMIC_REG_BBAT_CONT 0xC5 /* Control register for backup battery */ +#define PMIC_REG_ID_4_3 0x84 #define PMIC_REG_BUCK_ILIM_A 0x9A #define PMIC_REG_BUCK_ILIM_B 0x9B #define PMIC_REG_BUCK_ILIM_C 0x9C +#define PMIC_REG_BBAT_CONT 0xC5 /* Control register for backup battery */ + +#define PMIC_REG_CONFIG_E 0x10A +#define PMIC_REG_CONFIG_G 0x10C + #define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID */ extern void da9063_init(int i2c_bus); -extern int da9063_get_reg(int reg, u8* val); -extern int da9063_set_reg(int reg, u8 val); + +extern int da9063_claim_i2c_bus(void); +extern void da9063_release_i2c_bus(int bus); + +extern int da9063_get_reg(uint32_t reg, u8* val); +extern int da9063_set_reg(uint32_t reg, u8 val); extern void da9063_set_gpio(unsigned bit, int state);