1 /* 2 * (C) Copyright 2010 3 * Texas Instruments, <www.ti.com> 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 #include <config.h> 24 #ifdef CONFIG_TWL6030_POWER 25 26 #include <twl6030.h> 27 28 /* Functions to read and write from TWL6030 */ 29 static inline int twl6030_i2c_write_u8(u8 chip_no, u8 val, u8 reg) 30 { 31 return i2c_write(chip_no, reg, 1, &val, 1); 32 } 33 34 static inline int twl6030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg) 35 { 36 return i2c_read(chip_no, reg, 1, val, 1); 37 } 38 39 static int twl6030_gpadc_read_channel(u8 channel_no) 40 { 41 u8 lsb = 0; 42 u8 msb = 0; 43 int ret = 0; 44 45 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &lsb, 46 GPCH0_LSB + channel_no * 2); 47 if (ret) 48 return ret; 49 50 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &msb, 51 GPCH0_MSB + channel_no * 2); 52 if (ret) 53 return ret; 54 55 return (msb << 8) | lsb; 56 } 57 58 static int twl6030_gpadc_sw2_trigger(void) 59 { 60 u8 val; 61 int ret = 0; 62 63 ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2_SP2, CTRL_P2); 64 if (ret) 65 return ret; 66 67 /* Waiting until the SW1 conversion ends*/ 68 val = CTRL_P2_BUSY; 69 70 while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) { 71 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &val, CTRL_P2); 72 if (ret) 73 return ret; 74 udelay(1000); 75 } 76 77 return 0; 78 } 79 80 void twl6030_stop_usb_charging(void) 81 { 82 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 0, CONTROLLER_CTRL1); 83 84 return; 85 } 86 87 void twl6030_start_usb_charging(void) 88 { 89 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VICHRG_1500, 90 CHARGERUSB_VICHRG); 91 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CIN_LIMIT_NONE, 92 CHARGERUSB_CINLIMIT); 93 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MBAT_TEMP, 94 CONTROLLER_INT_MASK); 95 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MASK_MCHARGERUSB_THMREG, 96 CHARGERUSB_INT_MASK); 97 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VOREG_4P0, 98 CHARGERUSB_VOREG); 99 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_400, 100 CHARGERUSB_CTRL2); 101 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TERM, CHARGERUSB_CTRL1); 102 /* Enable USB charging */ 103 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1_EN_CHARGER, 104 CONTROLLER_CTRL1); 105 return; 106 } 107 108 int twl6030_get_battery_current(void) 109 { 110 int battery_current = 0; 111 u8 msb = 0; 112 u8 lsb = 0; 113 114 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &msb, FG_REG_11); 115 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &lsb, FG_REG_10); 116 battery_current = ((msb << 8) | lsb); 117 118 /* convert 10 bit signed number to 16 bit signed number */ 119 if (battery_current >= 0x2000) 120 battery_current = (battery_current - 0x4000); 121 122 battery_current = battery_current * 3000 / 4096; 123 printf("Battery Current: %d mA\n", battery_current); 124 125 return battery_current; 126 } 127 128 int twl6030_get_battery_voltage(void) 129 { 130 int battery_volt = 0; 131 int ret = 0; 132 133 /* Start GPADC SW conversion */ 134 ret = twl6030_gpadc_sw2_trigger(); 135 if (ret) { 136 printf("Failed to convert battery voltage\n"); 137 return ret; 138 } 139 140 /* measure Vbat voltage */ 141 battery_volt = twl6030_gpadc_read_channel(7); 142 if (battery_volt < 0) { 143 printf("Failed to read battery voltage\n"); 144 return ret; 145 } 146 battery_volt = (battery_volt * 25 * 1000) >> (10 + 2); 147 printf("Battery Voltage: %d mV\n", battery_volt); 148 149 return battery_volt; 150 } 151 152 void twl6030_init_battery_charging(void) 153 { 154 u8 stat1 = 0; 155 int battery_volt = 0; 156 int ret = 0; 157 158 /* Enable VBAT measurement */ 159 twl6030_i2c_write_u8(TWL6030_CHIP_PM, VBAT_MEAS, MISC1); 160 161 /* Enable GPADC module */ 162 ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, FGS | GPADCS, TOGGLE1); 163 if (ret) { 164 printf("Failed to enable GPADC\n"); 165 return; 166 } 167 168 battery_volt = twl6030_get_battery_voltage(); 169 if (battery_volt < 0) 170 return; 171 172 if (battery_volt < 3000) 173 printf("Main battery voltage too low!\n"); 174 175 /* Check for the presence of USB charger */ 176 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &stat1, CONTROLLER_STAT1); 177 178 /* check for battery presence indirectly via Fuel gauge */ 179 if ((stat1 & VBUS_DET) && (battery_volt < 3300)) 180 twl6030_start_usb_charging(); 181 182 return; 183 } 184 185 void twl6030_usb_device_settings() 186 { 187 u8 data = 0; 188 189 /* Select APP Group and set state to ON */ 190 twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VUSB_CFG_STATE); 191 192 twl6030_i2c_read_u8(TWL6030_CHIP_PM, &data, MISC2); 193 data |= 0x10; 194 195 /* Select the input supply for VBUS regulator */ 196 twl6030_i2c_write_u8(TWL6030_CHIP_PM, data, MISC2); 197 } 198 #endif 199