[U-Boot] [PATCH] OMAP5: Power: Added more functionality to twl6035 driver

Signed-off-by: Lubomir Popov lpopov@mm-sol.com
---
This patch adds some new functions that were used for the SOM5_EVB bringup, but might be useful for other OMAP5 designs as well.
drivers/power/twl6035.c | 140 +++++++++++++++++++++++++++++++++++++++++++---- include/twl6035.h | 83 ++++++++++++++++++++++++++-- 2 files changed, 206 insertions(+), 17 deletions(-)
diff --git a/drivers/power/twl6035.c b/drivers/power/twl6035.c index d3de698..5fc517b 100644 --- a/drivers/power/twl6035.c +++ b/drivers/power/twl6035.c @@ -2,6 +2,8 @@ * (C) Copyright 2012 * Texas Instruments, <www.ti.com> * + * 02/2013 Modified by Lubomir Popov lpopov@mm-sol.com + * * See file CREDITS for list of people who contributed to this * project. * @@ -21,9 +23,12 @@ * MA 02111-1307 USA */ #include <config.h> + +#ifdef CONFIG_TWL6035_POWER + #include <twl6035.h>
-/* Functions to read and write from TWL6030 */ +/* Functions to read and write from TWL6035 */ int twl6035_i2c_write_u8(u8 chip_no, u8 val, u8 reg) { return i2c_write(chip_no, reg, 1, &val, 1); @@ -47,28 +52,141 @@ static inline int palmas_read_u8(u8 chip_no, u8 reg, u8 *val)
void twl6035_init_settings(void) { - return; +#ifdef CONFIG_TWL6035_SMPS7_FPWM + int err; + /* Set SMPS7 (1.8 V I/O supply) to forced PWM mode */ + u8 val = SMPS_MODE_SLP_FPWM | SMPS_MODE_ACT_FPWM; + if ((err = palmas_write_u8(TWL6035_CHIP_P1, SMPS7_CTRL, val))) + printf("twl6035: Could not force PWM for SMPS7: err = %d\n", err); +#endif +} + +/* On some hardware the SD card socket and LDO9_IN are powered by an + * external 3.3 V regulator. Therefore VDDS_SDCARD should be 3.3 V + * as well for 3 V cards. This requires that LDO9 is set to 'bypass' + * mode for such cases. + * + * NOTE: Switching LDOs between the 0.9 - 2.1 V and 2.15 - 3.3 V ranges + * cannot be done on the fly and requires restart (off - change + * voltage - on). This should be taken care of at a higher level. + */ +int twl6035_mmc1_set_ldo9(u8 vsel) +{ + u8 cval=0, vval=0; /* Off by default */ + int err; + + if (vsel) { + /* Turn on */ + if (vsel > LDO_VOLT_3V3) { + /* Put LDO9 in bypass */ + cval = LDO9_BYP_EN | RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + vval = LDO_VOLT_3V3; + } + else { + cval = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + vval = vsel & 0x3f; + } + } + if ((err = palmas_write_u8(TWL6035_CHIP_P1, LDO9_VOLTAGE, vval))) { + printf("twl6035: could not set LDO9 %s: err = %d\n", + vsel > LDO_VOLT_3V3 ? "bypass" : "voltage", err); + return err; + } + if ((err = palmas_write_u8(TWL6035_CHIP_P1, LDO9_CTRL, cval))) + printf("twl6035: could not turn on LDO9: err = %d\n", err); + return err; }
int twl6035_mmc1_poweron_ldo(void) { u8 val = 0;
- /* set LDO9 TWL6035 to 3V */ - val = 0x2b; /* (3 -.9)*28 +1 */ - - if (palmas_write_u8(0x48, LDO9_VOLTAGE, val)) { + /* Set TWL6035 LDO9 to 3.0 V */ + val = LDO_VOLT_3V0; + if (palmas_write_u8(TWL6035_CHIP_P1, LDO9_VOLTAGE, val)) { printf("twl6035: could not set LDO9 voltage.\n"); return 1; } - /* TURN ON LDO9 */ - val = LDO_ON | LDO_MODE_SLEEP | LDO_MODE_ACTIVE; - - if (palmas_write_u8(0x48, LDO9_CTRL, val)) { + val = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + if (palmas_write_u8(TWL6035_CHIP_P1, LDO9_CTRL, val)) { printf("twl6035: could not turn on LDO9.\n"); return 1; } - return 0; } + +int twl6035_usb_poweron_ldo(void) +{ + u8 val = 0; + int err; + + /* Enable external VCC_3v3_AUX supply on the sEVM (SYSEN2) */ + val = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + if ((err = palmas_write_u8(TWL6035_CHIP_P1, SYSEN2_CTRL, val))) { + printf("twl6035: could not set SYSEN2: err = %d\n", err); + return err; + } + + /* TURN ON LDO's needed */ + + /* Set LDOUSB to 3.3 V */ + val = LDO_VOLT_3V3; + if ((err = palmas_write_u8(TWL6035_CHIP_P1, LDOUSB_VOLTAGE, val))) { + printf("twl6035: could not set LDOUSB voltage: err = %d\n", err); + return err; + } + + /* Enable LDOUSB */ + val = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + if ((err = palmas_write_u8(TWL6035_CHIP_P1, LDOUSB_CTRL, val))) + printf("twl6035: could not turn on LDOUSB: err = %d\n", err); + return err; +} + +/* Turn audio codec power and 32 kHz clock on/off + */ +int twl6035_audio_power(u8 on) +{ + u8 cval=0, vval=0, c32k=0; + int err; + + if (on) { + vval = SMPS_VOLT_2V1; + cval = SMPS_MODE_SLP_AUTO | SMPS_MODE_ACT_AUTO; + c32k = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; + } + /* Set SMPS9 to 2.1 V (for TWL604x), or to 0 (off) */ + if ((err = palmas_write_u8(TWL6035_CHIP_P1, SMPS9_VOLTAGE, vval))) { + printf("twl6035: could not set SMPS9 voltage: err = %d\n", err); + return err; + } + /* Turn on or off SMPS9 */ + if ((err = palmas_write_u8(TWL6035_CHIP_P1, SMPS9_CTRL, cval))) { + printf("twl6035: could not turn SMPS9 %s: err = %d\n", + cval ? "on" : "off", err); + return err; + } + /* Output 32 kHz clock on or off */ + if ((err = palmas_write_u8(TWL6035_CHIP_P1, CLK32KGAUDIO_CTRL, c32k))) + printf("twl6035: could not turn CLK32KGAUDIO %s: err = %d\n", + c32k ? "on" : "off", err); + return err; +} + +/* Enable/disable back-up battery (or super cap) charging. + * Please use defines. + */ +int twl6035_enable_bb_charge(u8 bb_fields) +{ + u8 val = bb_fields & 0x0f; + int err; + + val |= (VRTC_EN_SLP | VRTC_EN_OFF | VRTC_PWEN); + if ((err = palmas_write_u8(TWL6035_CHIP_P1, BB_VRTC_CTRL, val))) + printf("twl6035: could not set BB_VRTC_CTRL to 0x%02x: err = %d\n", val, err); + return err; +} + +#endif /* CONFIG_TWL6035_POWER */ + diff --git a/include/twl6035.h b/include/twl6035.h index ce74348..50e0b47 100644 --- a/include/twl6035.h +++ b/include/twl6035.h @@ -2,6 +2,8 @@ * (C) Copyright 2012 * Texas Instruments, <www.ti.com> * + * 02/2013 Modified by Lubomir Popov lpopov@mm-sol.com + * * See file CREDITS for list of people who contributed to this * project. * @@ -25,18 +27,87 @@ #include <i2c.h>
/* I2C chip addresses */ -#define TWL6035_CHIP_ADDR 0x48 +#define TWL6035_CHIP_P1 0x48 /* Page 1 */ +#define TWL6035_CHIP_P2 0x49 /* Page 2 */ +#define TWL6035_CHIP_P3 0x4a /* Page 3 */ + +/* Page 1 registers (0x1XY translates to page 1, register address 0xXY): */
-/* 0x1XY translates to page 1, register address 0xXY */ +/* LDO9_CTRL */ #define LDO9_CTRL 0x60 #define LDO9_VOLTAGE 0x61
-/* Bit field definitions for LDOx_CTRL */ -#define LDO_ON (1 << 4) -#define LDO_MODE_SLEEP (1 << 2) -#define LDO_MODE_ACTIVE (1 << 0) +/* Control of 32 kHz audio clock */ +#define CLK32KGAUDIO_CTRL 0xd5 + +/* SYSEN2_CTRL for VCC_3v3_AUX supply on the sEVM */ +#define SYSEN2_CTRL 0xd9 + +/* LDOUSB_CTRL */ +#define LDOUSB_CTRL 0x64 +#define LDOUSB_VOLTAGE 0x65 + +/* Bit field definitions for LDOx_CTRL, SYSENx_CTRL + * and some other xxx_CTRL resources + */ +#define LDO9_BYP_EN (1 << 6) /* LDO9 only! */ +#define RSC_STAT_ON (1 << 4) /* RO bit! */ +#define RSC_MODE_SLEEP (1 << 2) +#define RSC_MODE_ACTIVE (1 << 0) + +/* Some LDO voltage values */ +#define LDO_VOLT_OFF 0 +#define LDO_VOLT_1V8 0x13 +#define LDO_VOLT_3V0 0x2b +#define LDO_VOLT_3V3 0x31 +/* Request bypass, LDO9 only */ +#define LDO9_BYPASS 0x3f + +/* SMPS7_CTRL */ +#define SMPS7_CTRL 0x30 + +/* SMPS9_CTRL */ +#define SMPS9_CTRL 0x38 +#define SMPS9_VOLTAGE 0x3b + +/* Bit field definitions for SMPSx_CTRL */ +#define SMPS_MODE_ACT_AUTO 1 +#define SMPS_MODE_ACT_ECO 2 +#define SMPS_MODE_ACT_FPWM 3 +#define SMPS_MODE_SLP_AUTO (1 << 2) +#define SMPS_MODE_SLP_ECO (2 << 2) +#define SMPS_MODE_SLP_FPWM (3 << 2) + +/* Some popular SMPS voltages, all with RANGE=1; note + * that RANGE cannot be changed on the fly + */ +#define SMPS_VOLT_OFF 0 +#define SMPS_VOLT_1V2 0x90 +#define SMPS_VOLT_1V8 0xae +#define SMPS_VOLT_2V1 0xbd +#define SMPS_VOLT_3V0 0xea +#define SMPS_VOLT_3V3 0xf9 + +/* Backup Battery & VRTC Control */ +#define BB_VRTC_CTRL 0xa8 +/* Bit definitions for BB_VRTC_CTRL */ +#define VRTC_EN_SLP (1 << 6) +#define VRTC_EN_OFF (1 << 5) +#define VRTC_PWEN (1 << 4) +#define BB_LOW_ICHRG (1 << 3) +#define BB_HIGH_ICHRG (0 << 3) +#define BB_VSEL_3V0 (0 << 1) +#define BB_VSEL_2V5 (1 << 1) +#define BB_VSEL_3V15 (2 << 1) +#define BB_VSEL_VBAT (3 << 1) +#define BB_CHRG_EN (1 << 0)
int twl6035_i2c_write_u8(u8 chip_no, u8 val, u8 reg); int twl6035_i2c_read_u8(u8 chip_no, u8 *val, u8 reg); void twl6035_init_settings(void); int twl6035_mmc1_poweron_ldo(void); +int twl6035_mmc1_set_ldo9(u8 vsel); +int twl6035_usb_poweron_ldo(void); +int twl6035_audio_power(u8 on); +int twl6035_enable_bb_charge(u8 bb_fields); +
participants (1)
-
Lubomir Popov