summaryrefslogtreecommitdiffstats
path: root/qemu/roms/u-boot/drivers/power/twl6030.c
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/drivers/power/twl6030.c
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/drivers/power/twl6030.c')
-rw-r--r--qemu/roms/u-boot/drivers/power/twl6030.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/drivers/power/twl6030.c b/qemu/roms/u-boot/drivers/power/twl6030.c
new file mode 100644
index 000000000..a1c6663a2
--- /dev/null
+++ b/qemu/roms/u-boot/drivers/power/twl6030.c
@@ -0,0 +1,235 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <config.h>
+#ifdef CONFIG_TWL6030_POWER
+
+#include <twl6030.h>
+
+static struct twl6030_data *twl;
+
+static struct twl6030_data twl6030_info = {
+ .chip_type = chip_TWL6030,
+ .adc_rbase = GPCH0_LSB,
+ .adc_ctrl = CTRL_P2,
+ .adc_enable = CTRL_P2_SP2,
+ .vbat_mult = TWL6030_VBAT_MULT,
+ .vbat_shift = TWL6030_VBAT_SHIFT,
+};
+
+static struct twl6030_data twl6032_info = {
+ .chip_type = chip_TWL6032,
+ .adc_rbase = TWL6032_GPCH0_LSB,
+ .adc_ctrl = TWL6032_CTRL_P1,
+ .adc_enable = CTRL_P1_SP1,
+ .vbat_mult = TWL6032_VBAT_MULT,
+ .vbat_shift = TWL6032_VBAT_SHIFT,
+};
+
+static int twl6030_gpadc_read_channel(u8 channel_no)
+{
+ u8 lsb = 0;
+ u8 msb = 0;
+ int ret = 0;
+
+ ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
+ twl->adc_rbase + channel_no * 2, &lsb);
+ if (ret)
+ return ret;
+
+ ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
+ twl->adc_rbase + 1 + channel_no * 2, &msb);
+ if (ret)
+ return ret;
+
+ return (msb << 8) | lsb;
+}
+
+static int twl6030_gpadc_sw2_trigger(void)
+{
+ u8 val;
+ int ret = 0;
+
+ ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
+ twl->adc_ctrl, twl->adc_enable);
+ if (ret)
+ return ret;
+
+ /* Waiting until the SW1 conversion ends*/
+ val = CTRL_P2_BUSY;
+
+ while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
+ ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
+ twl->adc_ctrl, &val);
+ if (ret)
+ return ret;
+ udelay(1000);
+ }
+
+ return 0;
+}
+
+void twl6030_stop_usb_charging(void)
+{
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0);
+
+ return;
+}
+
+void twl6030_start_usb_charging(void)
+{
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CONTROLLER_INT_MASK, MBAT_TEMP);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM);
+ /* Enable USB charging */
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
+ CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
+ return;
+}
+
+int twl6030_get_battery_current(void)
+{
+ int battery_current = 0;
+ u8 msb = 0;
+ u8 lsb = 0;
+
+ twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb);
+ twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb);
+ battery_current = ((msb << 8) | lsb);
+
+ /* convert 10 bit signed number to 16 bit signed number */
+ if (battery_current >= 0x2000)
+ battery_current = (battery_current - 0x4000);
+
+ battery_current = battery_current * 3000 / 4096;
+ printf("Battery Current: %d mA\n", battery_current);
+
+ return battery_current;
+}
+
+int twl6030_get_battery_voltage(void)
+{
+ int battery_volt = 0;
+ int ret = 0;
+ u8 vbatch;
+
+ if (twl->chip_type == chip_TWL6030) {
+ vbatch = TWL6030_GPADC_VBAT_CHNL;
+ } else {
+ ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
+ TWL6032_GPSELECT_ISB,
+ TWL6032_GPADC_VBAT_CHNL);
+ if (ret)
+ return ret;
+ vbatch = 0;
+ }
+
+ /* Start GPADC SW conversion */
+ ret = twl6030_gpadc_sw2_trigger();
+ if (ret) {
+ printf("Failed to convert battery voltage\n");
+ return ret;
+ }
+
+ /* measure Vbat voltage */
+ battery_volt = twl6030_gpadc_read_channel(vbatch);
+ if (battery_volt < 0) {
+ printf("Failed to read battery voltage\n");
+ return ret;
+ }
+ battery_volt = (battery_volt * twl->vbat_mult) >> twl->vbat_shift;
+ printf("Battery Voltage: %d mV\n", battery_volt);
+
+ return battery_volt;
+}
+
+void twl6030_init_battery_charging(void)
+{
+ u8 val = 0;
+ int battery_volt = 0;
+ int ret = 0;
+
+ ret = twl6030_i2c_read_u8(TWL6030_CHIP_USB, USB_PRODUCT_ID_LSB, &val);
+ if (ret) {
+ puts("twl6030_init_battery_charging(): could not determine chip!\n");
+ return;
+ }
+ if (val == 0x30) {
+ twl = &twl6030_info;
+ } else if (val == 0x32) {
+ twl = &twl6032_info;
+ } else {
+ puts("twl6030_init_battery_charging(): unsupported chip type\n");
+ return;
+ }
+
+ /* Enable VBAT measurement */
+ if (twl->chip_type == chip_TWL6030) {
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS);
+ twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
+ TWL6030_GPADC_CTRL,
+ GPADC_CTRL_SCALER_DIV4);
+ } else {
+ twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
+ TWL6032_GPADC_CTRL2,
+ GPADC_CTRL2_CH18_SCALER_EN);
+ }
+
+ /* Enable GPADC module */
+ ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS);
+ if (ret) {
+ printf("Failed to enable GPADC\n");
+ return;
+ }
+
+ battery_volt = twl6030_get_battery_voltage();
+ if (battery_volt < 0)
+ return;
+
+ if (battery_volt < 3000)
+ printf("Main battery voltage too low!\n");
+
+ /* Check for the presence of USB charger */
+ twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &val);
+
+ /* check for battery presence indirectly via Fuel gauge */
+ if ((val & VBUS_DET) && (battery_volt < 3300))
+ twl6030_start_usb_charging();
+
+ return;
+}
+
+void twl6030_power_mmc_init()
+{
+ /* set voltage to 3.0 and turnon for APP */
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_VOLTATE, 0x15);
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_STATE, 0x21);
+}
+
+void twl6030_usb_device_settings()
+{
+ u8 data = 0;
+
+ /* Select APP Group and set state to ON */
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, VUSB_CFG_STATE, 0x21);
+
+ twl6030_i2c_read_u8(TWL6030_CHIP_PM, MISC2, &data);
+ data |= 0x10;
+
+ /* Select the input supply for VBUS regulator */
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC2, data);
+}
+#endif