From patchwork Mon Apr 1 13:54:29 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lubomir Popov X-Patchwork-Id: 232732 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 111DD2C010A for ; Tue, 2 Apr 2013 00:57:34 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CBD134A0B3; Mon, 1 Apr 2013 15:57:26 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BeRz7sUdxxPD; Mon, 1 Apr 2013 15:57:26 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 71E134A0B5; Mon, 1 Apr 2013 15:57:20 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E47434A0B5 for ; Mon, 1 Apr 2013 15:54:30 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VHe1nbp1Pr3v for ; Mon, 1 Apr 2013 15:54:28 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from extserv.mm-sol.com (ns.mm-sol.com [213.240.235.226]) by theia.denx.de (Postfix) with ESMTPS id 4CADD4A0B3 for ; Mon, 1 Apr 2013 15:54:26 +0200 (CEST) Received: from intsrv.int.mm-sol.com (unknown [172.18.0.2]) by extserv.mm-sol.com (Postfix) with ESMTP id 0CB2CC605; Mon, 1 Apr 2013 16:54:26 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by intsrv.int.mm-sol.com (Postfix) with ESMTP id ED736D22002; Mon, 1 Apr 2013 16:54:25 +0300 (EEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) Received: from intsrv.int.mm-sol.com ([127.0.0.1]) by localhost (mail.mm-sol.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cxOY0S-gexAx; Mon, 1 Apr 2013 16:54:17 +0300 (EEST) Received: from [172.20.2.19] (unknown [172.20.2.19]) by intsrv.int.mm-sol.com (Postfix) with ESMTPS id 8EA2AD22001; Mon, 1 Apr 2013 16:54:17 +0300 (EEST) Message-ID: <51599195.5030006@mm-sol.com> Date: Mon, 01 Apr 2013 16:54:29 +0300 From: Lubomir Popov Organization: MM Solutions AD User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4 MIME-Version: 1.0 To: u-boot@lists.denx.de X-Mailman-Approved-At: Mon, 01 Apr 2013 15:57:18 +0200 Cc: Tom Rini Subject: [U-Boot] [PATCH] OMAP5: Power: Added more functionality to twl6035 driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Signed-off-by: Lubomir Popov --- 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, * + * 02/2013 Modified by Lubomir Popov + * * See file CREDITS for list of people who contributed to this * project. * @@ -21,9 +23,12 @@ * MA 02111-1307 USA */ #include + +#ifdef CONFIG_TWL6035_POWER + #include -/* 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, * + * 02/2013 Modified by Lubomir Popov + * * See file CREDITS for list of people who contributed to this * project. * @@ -25,18 +27,87 @@ #include /* 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); +