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 */ 29516799f6SSteve Sakoman static inline int twl6030_i2c_write_u8(u8 chip_no, u8 val, u8 reg) 30516799f6SSteve Sakoman { 31516799f6SSteve Sakoman return i2c_write(chip_no, reg, 1, &val, 1); 32516799f6SSteve Sakoman } 33516799f6SSteve Sakoman 34516799f6SSteve Sakoman static inline int twl6030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg) 35516799f6SSteve Sakoman { 36516799f6SSteve Sakoman return i2c_read(chip_no, reg, 1, val, 1); 37516799f6SSteve Sakoman } 38516799f6SSteve Sakoman 39*3e664f6dSBalaji T K static int twl6030_gpadc_read_channel(u8 channel_no) 40*3e664f6dSBalaji T K { 41*3e664f6dSBalaji T K u8 lsb = 0; 42*3e664f6dSBalaji T K u8 msb = 0; 43*3e664f6dSBalaji T K int ret = 0; 44*3e664f6dSBalaji T K 45*3e664f6dSBalaji T K ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &lsb, 46*3e664f6dSBalaji T K GPCH0_LSB + channel_no * 2); 47*3e664f6dSBalaji T K if (ret) 48*3e664f6dSBalaji T K return ret; 49*3e664f6dSBalaji T K 50*3e664f6dSBalaji T K ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &msb, 51*3e664f6dSBalaji T K GPCH0_MSB + channel_no * 2); 52*3e664f6dSBalaji T K if (ret) 53*3e664f6dSBalaji T K return ret; 54*3e664f6dSBalaji T K 55*3e664f6dSBalaji T K return (msb << 8) | lsb; 56*3e664f6dSBalaji T K } 57*3e664f6dSBalaji T K 58*3e664f6dSBalaji T K static int twl6030_gpadc_sw2_trigger(void) 59*3e664f6dSBalaji T K { 60*3e664f6dSBalaji T K u8 val; 61*3e664f6dSBalaji T K int ret = 0; 62*3e664f6dSBalaji T K 63*3e664f6dSBalaji T K ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2_SP2, CTRL_P2); 64*3e664f6dSBalaji T K if (ret) 65*3e664f6dSBalaji T K return ret; 66*3e664f6dSBalaji T K 67*3e664f6dSBalaji T K /* Waiting until the SW1 conversion ends*/ 68*3e664f6dSBalaji T K val = CTRL_P2_BUSY; 69*3e664f6dSBalaji T K 70*3e664f6dSBalaji T K while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) { 71*3e664f6dSBalaji T K ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &val, CTRL_P2); 72*3e664f6dSBalaji T K if (ret) 73*3e664f6dSBalaji T K return ret; 74*3e664f6dSBalaji T K udelay(1000); 75*3e664f6dSBalaji T K } 76*3e664f6dSBalaji T K 77*3e664f6dSBalaji T K return 0; 78*3e664f6dSBalaji T K } 79*3e664f6dSBalaji T K 80*3e664f6dSBalaji T K void twl6030_stop_usb_charging(void) 81*3e664f6dSBalaji T K { 82*3e664f6dSBalaji T K twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 0, CONTROLLER_CTRL1); 83*3e664f6dSBalaji T K 84*3e664f6dSBalaji T K return; 85*3e664f6dSBalaji T K } 86*3e664f6dSBalaji T K 87516799f6SSteve Sakoman void twl6030_start_usb_charging(void) 88516799f6SSteve Sakoman { 89516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VICHRG_1500, 90516799f6SSteve Sakoman CHARGERUSB_VICHRG); 91516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CIN_LIMIT_NONE, 92516799f6SSteve Sakoman CHARGERUSB_CINLIMIT); 93516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MBAT_TEMP, 94516799f6SSteve Sakoman CONTROLLER_INT_MASK); 95516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MASK_MCHARGERUSB_THMREG, 96516799f6SSteve Sakoman CHARGERUSB_INT_MASK); 97516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VOREG_4P0, 98516799f6SSteve Sakoman CHARGERUSB_VOREG); 99*3e664f6dSBalaji T K twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_400, 100516799f6SSteve Sakoman CHARGERUSB_CTRL2); 101*3e664f6dSBalaji T K twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TERM, CHARGERUSB_CTRL1); 102516799f6SSteve Sakoman /* Enable USB charging */ 103516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1_EN_CHARGER, 104516799f6SSteve Sakoman CONTROLLER_CTRL1); 105516799f6SSteve Sakoman return; 106516799f6SSteve Sakoman } 107516799f6SSteve Sakoman 108*3e664f6dSBalaji T K int twl6030_get_battery_current(void) 109*3e664f6dSBalaji T K { 110*3e664f6dSBalaji T K int battery_current = 0; 111*3e664f6dSBalaji T K u8 msb = 0; 112*3e664f6dSBalaji T K u8 lsb = 0; 113*3e664f6dSBalaji T K 114*3e664f6dSBalaji T K twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &msb, FG_REG_11); 115*3e664f6dSBalaji T K twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &lsb, FG_REG_10); 116*3e664f6dSBalaji T K battery_current = ((msb << 8) | lsb); 117*3e664f6dSBalaji T K 118*3e664f6dSBalaji T K /* convert 10 bit signed number to 16 bit signed number */ 119*3e664f6dSBalaji T K if (battery_current >= 0x2000) 120*3e664f6dSBalaji T K battery_current = (battery_current - 0x4000); 121*3e664f6dSBalaji T K 122*3e664f6dSBalaji T K battery_current = battery_current * 3000 / 4096; 123*3e664f6dSBalaji T K printf("Battery Current: %d mA\n", battery_current); 124*3e664f6dSBalaji T K 125*3e664f6dSBalaji T K return battery_current; 126*3e664f6dSBalaji T K } 127*3e664f6dSBalaji T K 128*3e664f6dSBalaji T K int twl6030_get_battery_voltage(void) 129*3e664f6dSBalaji T K { 130*3e664f6dSBalaji T K int battery_volt = 0; 131*3e664f6dSBalaji T K int ret = 0; 132*3e664f6dSBalaji T K 133*3e664f6dSBalaji T K /* Start GPADC SW conversion */ 134*3e664f6dSBalaji T K ret = twl6030_gpadc_sw2_trigger(); 135*3e664f6dSBalaji T K if (ret) { 136*3e664f6dSBalaji T K printf("Failed to convert battery voltage\n"); 137*3e664f6dSBalaji T K return ret; 138*3e664f6dSBalaji T K } 139*3e664f6dSBalaji T K 140*3e664f6dSBalaji T K /* measure Vbat voltage */ 141*3e664f6dSBalaji T K battery_volt = twl6030_gpadc_read_channel(7); 142*3e664f6dSBalaji T K if (battery_volt < 0) { 143*3e664f6dSBalaji T K printf("Failed to read battery voltage\n"); 144*3e664f6dSBalaji T K return ret; 145*3e664f6dSBalaji T K } 146*3e664f6dSBalaji T K battery_volt = (battery_volt * 25 * 1000) >> (10 + 2); 147*3e664f6dSBalaji T K printf("Battery Voltage: %d mV\n", battery_volt); 148*3e664f6dSBalaji T K 149*3e664f6dSBalaji T K return battery_volt; 150*3e664f6dSBalaji T K } 151*3e664f6dSBalaji T K 152516799f6SSteve Sakoman void twl6030_init_battery_charging(void) 153516799f6SSteve Sakoman { 154*3e664f6dSBalaji T K u8 stat1 = 0; 155*3e664f6dSBalaji T K int battery_volt = 0; 156*3e664f6dSBalaji T K int ret = 0; 157*3e664f6dSBalaji T K 158*3e664f6dSBalaji T K /* Enable VBAT measurement */ 159*3e664f6dSBalaji T K twl6030_i2c_write_u8(TWL6030_CHIP_PM, VBAT_MEAS, MISC1); 160*3e664f6dSBalaji T K 161*3e664f6dSBalaji T K /* Enable GPADC module */ 162*3e664f6dSBalaji T K ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, FGS | GPADCS, TOGGLE1); 163*3e664f6dSBalaji T K if (ret) { 164*3e664f6dSBalaji T K printf("Failed to enable GPADC\n"); 165*3e664f6dSBalaji T K return; 166*3e664f6dSBalaji T K } 167*3e664f6dSBalaji T K 168*3e664f6dSBalaji T K battery_volt = twl6030_get_battery_voltage(); 169*3e664f6dSBalaji T K if (battery_volt < 0) 170*3e664f6dSBalaji T K return; 171*3e664f6dSBalaji T K 172*3e664f6dSBalaji T K if (battery_volt < 3000) 173*3e664f6dSBalaji T K printf("Main battery voltage too low!\n"); 174*3e664f6dSBalaji T K 175*3e664f6dSBalaji T K /* Check for the presence of USB charger */ 176*3e664f6dSBalaji T K twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &stat1, CONTROLLER_STAT1); 177*3e664f6dSBalaji T K 178*3e664f6dSBalaji T K /* check for battery presence indirectly via Fuel gauge */ 179*3e664f6dSBalaji T K if ((stat1 & VBUS_DET) && (battery_volt < 3300)) 180516799f6SSteve Sakoman twl6030_start_usb_charging(); 181*3e664f6dSBalaji T K 182516799f6SSteve Sakoman return; 183516799f6SSteve Sakoman } 184516799f6SSteve Sakoman 185516799f6SSteve Sakoman void twl6030_usb_device_settings() 186516799f6SSteve Sakoman { 187516799f6SSteve Sakoman u8 data = 0; 188516799f6SSteve Sakoman 189516799f6SSteve Sakoman /* Select APP Group and set state to ON */ 190516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VUSB_CFG_STATE); 191516799f6SSteve Sakoman 192516799f6SSteve Sakoman twl6030_i2c_read_u8(TWL6030_CHIP_PM, &data, MISC2); 193516799f6SSteve Sakoman data |= 0x10; 194516799f6SSteve Sakoman 195516799f6SSteve Sakoman /* Select the input supply for VBUS regulator */ 196516799f6SSteve Sakoman twl6030_i2c_write_u8(TWL6030_CHIP_PM, data, MISC2); 197516799f6SSteve Sakoman } 198516799f6SSteve Sakoman #endif 199