1516799f6SSteve Sakoman /* 2516799f6SSteve Sakoman * (C) Copyright 2010 3516799f6SSteve Sakoman * Texas Instruments, <www.ti.com> 4516799f6SSteve Sakoman * 5516799f6SSteve Sakoman * See file CREDITS for list of people who contributed to this 6516799f6SSteve Sakoman * project. 7516799f6SSteve Sakoman * 8516799f6SSteve Sakoman * This program is free software; you can redistribute it and/or 9516799f6SSteve Sakoman * modify it under the terms of the GNU General Public License as 10516799f6SSteve Sakoman * published by the Free Software Foundation; either version 2 of 11516799f6SSteve Sakoman * the License, or (at your option) any later version. 12516799f6SSteve Sakoman * 13516799f6SSteve Sakoman * This program is distributed in the hope that it will be useful, 14516799f6SSteve Sakoman * but WITHOUT ANY WARRANTY; without even the implied warranty of 15516799f6SSteve Sakoman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16516799f6SSteve Sakoman * GNU General Public License for more details. 17516799f6SSteve Sakoman * 18516799f6SSteve Sakoman * You should have received a copy of the GNU General Public License 19516799f6SSteve Sakoman * along with this program; if not, write to the Free Software 20516799f6SSteve Sakoman * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21516799f6SSteve Sakoman * MA 02111-1307 USA 22516799f6SSteve Sakoman */ 23516799f6SSteve Sakoman #include <config.h> 24516799f6SSteve Sakoman #ifdef CONFIG_TWL6030_POWER 25516799f6SSteve Sakoman 26516799f6SSteve Sakoman #include <twl6030.h> 27516799f6SSteve Sakoman 28516799f6SSteve Sakoman /* Functions to read and write from TWL6030 */ 29*345ef204SNishanth Menon static inline int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val) 30516799f6SSteve Sakoman { 31516799f6SSteve Sakoman return i2c_write(chip_no, reg, 1, &val, 1); 32516799f6SSteve Sakoman } 33516799f6SSteve Sakoman 34*345ef204SNishanth Menon static inline int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val) 35516799f6SSteve Sakoman { 36516799f6SSteve Sakoman return i2c_read(chip_no, reg, 1, val, 1); 37516799f6SSteve Sakoman } 38516799f6SSteve Sakoman 393e664f6dSBalaji T K static int twl6030_gpadc_read_channel(u8 channel_no) 403e664f6dSBalaji T K { 413e664f6dSBalaji T K u8 lsb = 0; 423e664f6dSBalaji T K u8 msb = 0; 433e664f6dSBalaji T K int ret = 0; 443e664f6dSBalaji T K 45*345ef204SNishanth Menon ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, 46*345ef204SNishanth Menon GPCH0_LSB + channel_no * 2, &lsb); 473e664f6dSBalaji T K if (ret) 483e664f6dSBalaji T K return ret; 493e664f6dSBalaji T K 50*345ef204SNishanth Menon ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, 51*345ef204SNishanth Menon GPCH0_MSB + channel_no * 2, &msb); 523e664f6dSBalaji T K if (ret) 533e664f6dSBalaji T K return ret; 543e664f6dSBalaji T K 553e664f6dSBalaji T K return (msb << 8) | lsb; 563e664f6dSBalaji T K } 573e664f6dSBalaji T K 583e664f6dSBalaji T K static int twl6030_gpadc_sw2_trigger(void) 593e664f6dSBalaji T K { 603e664f6dSBalaji T K u8 val; 613e664f6dSBalaji T K int ret = 0; 623e664f6dSBalaji T K 63*345ef204SNishanth Menon ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2, CTRL_P2_SP2); 643e664f6dSBalaji T K if (ret) 653e664f6dSBalaji T K return ret; 663e664f6dSBalaji T K 673e664f6dSBalaji T K /* Waiting until the SW1 conversion ends*/ 683e664f6dSBalaji T K val = CTRL_P2_BUSY; 693e664f6dSBalaji T K 703e664f6dSBalaji T K while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) { 71*345ef204SNishanth Menon ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, CTRL_P2, &val); 723e664f6dSBalaji T K if (ret) 733e664f6dSBalaji T K return ret; 743e664f6dSBalaji T K udelay(1000); 753e664f6dSBalaji T K } 763e664f6dSBalaji T K 773e664f6dSBalaji T K return 0; 783e664f6dSBalaji T K } 793e664f6dSBalaji T K 803e664f6dSBalaji T K void twl6030_stop_usb_charging(void) 813e664f6dSBalaji T K { 82*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0); 833e664f6dSBalaji T K 843e664f6dSBalaji T K return; 853e664f6dSBalaji T K } 863e664f6dSBalaji T K 87516799f6SSteve Sakoman void twl6030_start_usb_charging(void) 88516799f6SSteve Sakoman { 89*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 90*345ef204SNishanth Menon CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500); 91*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 92*345ef204SNishanth Menon CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE); 93*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 94*345ef204SNishanth Menon CONTROLLER_INT_MASK, MBAT_TEMP); 95*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 96*345ef204SNishanth Menon CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG); 97*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 98*345ef204SNishanth Menon CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0); 99*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 100*345ef204SNishanth Menon CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400); 101*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM); 102516799f6SSteve Sakoman /* Enable USB charging */ 103*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 104*345ef204SNishanth Menon CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER); 105516799f6SSteve Sakoman return; 106516799f6SSteve Sakoman } 107516799f6SSteve Sakoman 1083e664f6dSBalaji T K int twl6030_get_battery_current(void) 1093e664f6dSBalaji T K { 1103e664f6dSBalaji T K int battery_current = 0; 1113e664f6dSBalaji T K u8 msb = 0; 1123e664f6dSBalaji T K u8 lsb = 0; 1133e664f6dSBalaji T K 114*345ef204SNishanth Menon twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb); 115*345ef204SNishanth Menon twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb); 1163e664f6dSBalaji T K battery_current = ((msb << 8) | lsb); 1173e664f6dSBalaji T K 1183e664f6dSBalaji T K /* convert 10 bit signed number to 16 bit signed number */ 1193e664f6dSBalaji T K if (battery_current >= 0x2000) 1203e664f6dSBalaji T K battery_current = (battery_current - 0x4000); 1213e664f6dSBalaji T K 1223e664f6dSBalaji T K battery_current = battery_current * 3000 / 4096; 1233e664f6dSBalaji T K printf("Battery Current: %d mA\n", battery_current); 1243e664f6dSBalaji T K 1253e664f6dSBalaji T K return battery_current; 1263e664f6dSBalaji T K } 1273e664f6dSBalaji T K 1283e664f6dSBalaji T K int twl6030_get_battery_voltage(void) 1293e664f6dSBalaji T K { 1303e664f6dSBalaji T K int battery_volt = 0; 1313e664f6dSBalaji T K int ret = 0; 1323e664f6dSBalaji T K 1333e664f6dSBalaji T K /* Start GPADC SW conversion */ 1343e664f6dSBalaji T K ret = twl6030_gpadc_sw2_trigger(); 1353e664f6dSBalaji T K if (ret) { 1363e664f6dSBalaji T K printf("Failed to convert battery voltage\n"); 1373e664f6dSBalaji T K return ret; 1383e664f6dSBalaji T K } 1393e664f6dSBalaji T K 1403e664f6dSBalaji T K /* measure Vbat voltage */ 1413e664f6dSBalaji T K battery_volt = twl6030_gpadc_read_channel(7); 1423e664f6dSBalaji T K if (battery_volt < 0) { 1433e664f6dSBalaji T K printf("Failed to read battery voltage\n"); 1443e664f6dSBalaji T K return ret; 1453e664f6dSBalaji T K } 1463e664f6dSBalaji T K battery_volt = (battery_volt * 25 * 1000) >> (10 + 2); 1473e664f6dSBalaji T K printf("Battery Voltage: %d mV\n", battery_volt); 1483e664f6dSBalaji T K 1493e664f6dSBalaji T K return battery_volt; 1503e664f6dSBalaji T K } 1513e664f6dSBalaji T K 152516799f6SSteve Sakoman void twl6030_init_battery_charging(void) 153516799f6SSteve Sakoman { 1543e664f6dSBalaji T K u8 stat1 = 0; 1553e664f6dSBalaji T K int battery_volt = 0; 1563e664f6dSBalaji T K int ret = 0; 1573e664f6dSBalaji T K 1583e664f6dSBalaji T K /* Enable VBAT measurement */ 159*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS); 1603e664f6dSBalaji T K 1613e664f6dSBalaji T K /* Enable GPADC module */ 162*345ef204SNishanth Menon ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS); 1633e664f6dSBalaji T K if (ret) { 1643e664f6dSBalaji T K printf("Failed to enable GPADC\n"); 1653e664f6dSBalaji T K return; 1663e664f6dSBalaji T K } 1673e664f6dSBalaji T K 1683e664f6dSBalaji T K battery_volt = twl6030_get_battery_voltage(); 1693e664f6dSBalaji T K if (battery_volt < 0) 1703e664f6dSBalaji T K return; 1713e664f6dSBalaji T K 1723e664f6dSBalaji T K if (battery_volt < 3000) 1733e664f6dSBalaji T K printf("Main battery voltage too low!\n"); 1743e664f6dSBalaji T K 1753e664f6dSBalaji T K /* Check for the presence of USB charger */ 176*345ef204SNishanth Menon twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &stat1); 1773e664f6dSBalaji T K 1783e664f6dSBalaji T K /* check for battery presence indirectly via Fuel gauge */ 1793e664f6dSBalaji T K if ((stat1 & VBUS_DET) && (battery_volt < 3300)) 180516799f6SSteve Sakoman twl6030_start_usb_charging(); 1813e664f6dSBalaji T K 182516799f6SSteve Sakoman return; 183516799f6SSteve Sakoman } 184516799f6SSteve Sakoman 18514fa2dd0SBalaji T K void twl6030_power_mmc_init() 18614fa2dd0SBalaji T K { 18714fa2dd0SBalaji T K /* set voltage to 3.0 and turnon for APP */ 188*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_VOLTATE, 0x15); 189*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_STATE, 0x21); 19014fa2dd0SBalaji T K } 19114fa2dd0SBalaji T K 192516799f6SSteve Sakoman void twl6030_usb_device_settings() 193516799f6SSteve Sakoman { 194516799f6SSteve Sakoman u8 data = 0; 195516799f6SSteve Sakoman 196516799f6SSteve Sakoman /* Select APP Group and set state to ON */ 197*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_PM, VUSB_CFG_STATE, 0x21); 198516799f6SSteve Sakoman 199*345ef204SNishanth Menon twl6030_i2c_read_u8(TWL6030_CHIP_PM, MISC2, &data); 200516799f6SSteve Sakoman data |= 0x10; 201516799f6SSteve Sakoman 202516799f6SSteve Sakoman /* Select the input supply for VBUS regulator */ 203*345ef204SNishanth Menon twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC2, data); 204516799f6SSteve Sakoman } 205516799f6SSteve Sakoman #endif 206