1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2010 4 * Texas Instruments, <www.ti.com> 5 */ 6 #include <config.h> 7 8 #include <twl6030.h> 9 10 static struct twl6030_data *twl; 11 12 static struct twl6030_data twl6030_info = { 13 .chip_type = chip_TWL6030, 14 .adc_rbase = GPCH0_LSB, 15 .adc_ctrl = CTRL_P2, 16 .adc_enable = CTRL_P2_SP2, 17 .vbat_mult = TWL6030_VBAT_MULT, 18 .vbat_shift = TWL6030_VBAT_SHIFT, 19 }; 20 21 static struct twl6030_data twl6032_info = { 22 .chip_type = chip_TWL6032, 23 .adc_rbase = TWL6032_GPCH0_LSB, 24 .adc_ctrl = TWL6032_CTRL_P1, 25 .adc_enable = CTRL_P1_SP1, 26 .vbat_mult = TWL6032_VBAT_MULT, 27 .vbat_shift = TWL6032_VBAT_SHIFT, 28 }; 29 30 31 static int twl6030_gpadc_read_channel(u8 channel_no) 32 { 33 u8 lsb = 0; 34 u8 msb = 0; 35 int ret = 0; 36 37 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, 38 twl->adc_rbase + channel_no * 2, &lsb); 39 if (ret) 40 return ret; 41 42 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, 43 twl->adc_rbase + 1 + channel_no * 2, &msb); 44 if (ret) 45 return ret; 46 47 return (msb << 8) | lsb; 48 } 49 50 static int twl6030_gpadc_sw2_trigger(void) 51 { 52 u8 val; 53 int ret = 0; 54 55 ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, 56 twl->adc_ctrl, twl->adc_enable); 57 if (ret) 58 return ret; 59 60 /* Waiting until the SW1 conversion ends*/ 61 val = CTRL_P2_BUSY; 62 63 while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) { 64 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, 65 twl->adc_ctrl, &val); 66 if (ret) 67 return ret; 68 udelay(1000); 69 } 70 71 return 0; 72 } 73 74 void twl6030_power_off(void) 75 { 76 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_PHOENIX_DEV_ON, 77 TWL6030_PHOENIX_APP_DEVOFF | TWL6030_PHOENIX_CON_DEVOFF | 78 TWL6030_PHOENIX_MOD_DEVOFF); 79 } 80 81 void twl6030_stop_usb_charging(void) 82 { 83 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0); 84 85 return; 86 } 87 88 void twl6030_start_usb_charging(void) 89 { 90 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 91 CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500); 92 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 93 CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE); 94 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 95 CONTROLLER_INT_MASK, MBAT_TEMP); 96 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 97 CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG); 98 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 99 CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0); 100 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 101 CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400); 102 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM); 103 /* Enable USB charging */ 104 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 105 CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER); 106 return; 107 } 108 109 int twl6030_get_battery_current(void) 110 { 111 int battery_current = 0; 112 u8 msb = 0; 113 u8 lsb = 0; 114 115 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb); 116 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb); 117 battery_current = ((msb << 8) | lsb); 118 119 /* convert 10 bit signed number to 16 bit signed number */ 120 if (battery_current >= 0x2000) 121 battery_current = (battery_current - 0x4000); 122 123 battery_current = battery_current * 3000 / 4096; 124 printf("Battery Current: %d mA\n", battery_current); 125 126 return battery_current; 127 } 128 129 int twl6030_get_battery_voltage(void) 130 { 131 int battery_volt = 0; 132 int ret = 0; 133 u8 vbatch; 134 135 if (twl->chip_type == chip_TWL6030) { 136 vbatch = TWL6030_GPADC_VBAT_CHNL; 137 } else { 138 ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, 139 TWL6032_GPSELECT_ISB, 140 TWL6032_GPADC_VBAT_CHNL); 141 if (ret) 142 return ret; 143 vbatch = 0; 144 } 145 146 /* Start GPADC SW conversion */ 147 ret = twl6030_gpadc_sw2_trigger(); 148 if (ret) { 149 printf("Failed to convert battery voltage\n"); 150 return ret; 151 } 152 153 /* measure Vbat voltage */ 154 battery_volt = twl6030_gpadc_read_channel(vbatch); 155 if (battery_volt < 0) { 156 printf("Failed to read battery voltage\n"); 157 return ret; 158 } 159 battery_volt = (battery_volt * twl->vbat_mult) >> twl->vbat_shift; 160 printf("Battery Voltage: %d mV\n", battery_volt); 161 162 return battery_volt; 163 } 164 165 void twl6030_init_battery_charging(void) 166 { 167 u8 val = 0; 168 int battery_volt = 0; 169 int ret = 0; 170 171 ret = twl6030_i2c_read_u8(TWL6030_CHIP_USB, USB_PRODUCT_ID_LSB, &val); 172 if (ret) { 173 puts("twl6030_init_battery_charging(): could not determine chip!\n"); 174 return; 175 } 176 if (val == 0x30) { 177 twl = &twl6030_info; 178 } else if (val == 0x32) { 179 twl = &twl6032_info; 180 } else { 181 puts("twl6030_init_battery_charging(): unsupported chip type\n"); 182 return; 183 } 184 185 /* Enable VBAT measurement */ 186 if (twl->chip_type == chip_TWL6030) { 187 twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS); 188 twl6030_i2c_write_u8(TWL6030_CHIP_ADC, 189 TWL6030_GPADC_CTRL, 190 GPADC_CTRL_SCALER_DIV4); 191 } else { 192 twl6030_i2c_write_u8(TWL6030_CHIP_ADC, 193 TWL6032_GPADC_CTRL2, 194 GPADC_CTRL2_CH18_SCALER_EN); 195 } 196 197 /* Enable GPADC module */ 198 ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS); 199 if (ret) { 200 printf("Failed to enable GPADC\n"); 201 return; 202 } 203 204 battery_volt = twl6030_get_battery_voltage(); 205 if (battery_volt < 0) 206 return; 207 208 if (battery_volt < 3000) 209 printf("Main battery voltage too low!\n"); 210 211 /* Check for the presence of USB charger */ 212 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &val); 213 214 /* check for battery presence indirectly via Fuel gauge */ 215 if ((val & VBUS_DET) && (battery_volt < 3300)) 216 twl6030_start_usb_charging(); 217 218 return; 219 } 220 221 void twl6030_power_mmc_init(int dev_index) 222 { 223 u8 value = 0; 224 225 if (dev_index == 0) { 226 /* 3.0V voltage output for VMMC */ 227 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VMMC_CFG_VOLTAGE, 228 TWL6030_CFG_VOLTAGE_30); 229 230 /* Enable P1 output for VMMC */ 231 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VMMC_CFG_STATE, 232 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON); 233 } else if (dev_index == 1) { 234 twl6030_i2c_read_u8(TWL6030_CHIP_PM, TWL6030_PH_STS_BOOT, 235 &value); 236 /* BOOT2 indicates 1.8V/2.8V VAUX1 for eMMC */ 237 if (value & TWL6030_PH_STS_BOOT2) { 238 /* 1.8V voltage output for VAUX1 */ 239 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_VOLTAGE, 240 TWL6030_CFG_VOLTAGE_18); 241 } else { 242 /* 2.8V voltage output for VAUX1 */ 243 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_VOLTAGE, 244 TWL6030_CFG_VOLTAGE_28); 245 } 246 247 /* Enable P1 output for VAUX */ 248 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_STATE, 249 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON); 250 } 251 } 252 253 void twl6030_usb_device_settings() 254 { 255 u8 value = 0; 256 257 /* 3.3V voltage output for VUSB */ 258 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VUSB_CFG_VOLTAGE, 259 TWL6030_CFG_VOLTAGE_33); 260 261 /* Enable P1 output for VUSB */ 262 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VUSB_CFG_STATE, 263 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON); 264 265 /* Select the input supply for VUSB regulator */ 266 twl6030_i2c_read_u8(TWL6030_CHIP_PM, TWL6030_MISC2, &value); 267 value |= TWL6030_MISC2_VUSB_IN_VSYS; 268 value &= ~TWL6030_MISC2_VUSB_IN_PMID; 269 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_MISC2, value); 270 } 271