1 /* 2 * Copyright (C) 2012 Samsung Electronics 3 * Lukasz Majewski <l.majewski@samsung.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 24 #include <common.h> 25 #include <power/pmic.h> 26 #include <power/max17042_fg.h> 27 #include <i2c.h> 28 #include <power/max8997_pmic.h> 29 #include <power/power_chrg.h> 30 #include <power/battery.h> 31 #include <power/fg_battery_cell_params.h> 32 #include <errno.h> 33 34 static int fg_write_regs(struct pmic *p, u8 addr, u16 *data, int num) 35 { 36 int ret = 0; 37 int i; 38 39 for (i = 0; i < num; i++, addr++) 40 ret |= pmic_reg_write(p, addr, *(data + i)); 41 42 return ret; 43 } 44 45 static int fg_read_regs(struct pmic *p, u8 addr, u16 *data, int num) 46 { 47 int ret = 0; 48 int i; 49 50 for (i = 0; i < num; i++, addr++) 51 ret |= pmic_reg_read(p, addr, (u32 *) (data + i)); 52 53 return ret; 54 } 55 56 static int fg_write_and_verify(struct pmic *p, u8 addr, u16 data) 57 { 58 unsigned int val = data; 59 int ret = 0; 60 61 ret |= pmic_reg_write(p, addr, val); 62 ret |= pmic_reg_read(p, addr, &val); 63 64 if (ret) 65 return ret; 66 67 if (((u16) val) == data) 68 return 0; 69 70 return -1; 71 } 72 73 static void por_fuelgauge_init(struct pmic *p) 74 { 75 u16 r_data0[16], r_data1[16], r_data2[16]; 76 u32 rewrite_count = 5, i = 0; 77 unsigned int val; 78 int ret = 0; 79 80 /* Delay 500 ms */ 81 mdelay(500); 82 /* Initilize Configuration */ 83 pmic_reg_write(p, MAX17042_CONFIG, 0x2310); 84 85 rewrite_model: 86 /* Unlock Model Access */ 87 pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_UNLOCK1); 88 pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_UNLOCK2); 89 90 /* Write/Read/Verify the Custom Model */ 91 ret |= fg_write_regs(p, MAX17042_MODEL1, cell_character0, 92 ARRAY_SIZE(cell_character0)); 93 ret |= fg_write_regs(p, MAX17042_MODEL2, cell_character1, 94 ARRAY_SIZE(cell_character1)); 95 ret |= fg_write_regs(p, MAX17042_MODEL3, cell_character2, 96 ARRAY_SIZE(cell_character2)); 97 98 if (ret) { 99 printf("%s: Cell parameters write failed!\n", __func__); 100 return; 101 } 102 103 ret |= fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0)); 104 ret |= fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1)); 105 ret |= fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2)); 106 107 if (ret) 108 printf("%s: Cell parameters read failed!\n", __func__); 109 110 for (i = 0; i < 16; i++) { 111 if ((cell_character0[i] != r_data0[i]) 112 || (cell_character1[i] != r_data1[i]) 113 || (cell_character2[i] != r_data2[i])) 114 goto rewrite_model; 115 } 116 117 /* Lock model access */ 118 pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_LOCK1); 119 pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_LOCK2); 120 121 /* Verify the model access is locked */ 122 ret |= fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0)); 123 ret |= fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1)); 124 ret |= fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2)); 125 126 if (ret) { 127 printf("%s: Cell parameters read failed!\n", __func__); 128 return; 129 } 130 131 for (i = 0; i < ARRAY_SIZE(r_data0); i++) { 132 /* Check if model locked */ 133 if (r_data0[i] || r_data1[i] || r_data2[i]) { 134 /* Rewrite model data - prevent from endless loop */ 135 if (rewrite_count--) { 136 puts("FG - Lock model access failed!\n"); 137 goto rewrite_model; 138 } 139 } 140 } 141 142 /* Write Custom Parameters */ 143 fg_write_and_verify(p, MAX17042_RCOMP0, RCOMP0); 144 fg_write_and_verify(p, MAX17042_TEMPCO, TempCo); 145 146 /* Delay at least 350mS */ 147 mdelay(350); 148 149 /* Initialization Complete */ 150 pmic_reg_read(p, MAX17042_STATUS, &val); 151 /* Write and Verify Status with POR bit Cleared */ 152 fg_write_and_verify(p, MAX17042_STATUS, val & ~MAX17042_POR); 153 154 /* Delay at least 350 ms */ 155 mdelay(350); 156 } 157 158 static int power_update_battery(struct pmic *p, struct pmic *bat) 159 { 160 struct power_battery *pb = bat->pbat; 161 unsigned int val; 162 int ret = 0; 163 164 if (pmic_probe(p)) { 165 puts("Can't find max17042 fuel gauge\n"); 166 return -1; 167 } 168 169 ret |= pmic_reg_read(p, MAX17042_VFSOC, &val); 170 pb->bat->state_of_chrg = (val >> 8); 171 172 pmic_reg_read(p, MAX17042_VCELL, &val); 173 debug("vfsoc: 0x%x\n", val); 174 pb->bat->voltage_uV = ((val & 0xFFUL) >> 3) + ((val & 0xFF00) >> 3); 175 pb->bat->voltage_uV = (pb->bat->voltage_uV * 625); 176 177 pmic_reg_read(p, 0x05, &val); 178 pb->bat->capacity = val >> 2; 179 180 return ret; 181 } 182 183 static int power_check_battery(struct pmic *p, struct pmic *bat) 184 { 185 struct power_battery *pb = bat->pbat; 186 unsigned int val; 187 int ret = 0; 188 189 if (pmic_probe(p)) { 190 puts("Can't find max17042 fuel gauge\n"); 191 return -1; 192 } 193 194 ret |= pmic_reg_read(p, MAX17042_STATUS, &val); 195 debug("fg status: 0x%x\n", val); 196 197 if (val == MAX17042_POR) 198 por_fuelgauge_init(p); 199 200 ret |= pmic_reg_read(p, MAX17042_VERSION, &val); 201 pb->bat->version = val; 202 203 power_update_battery(p, bat); 204 debug("fg ver: 0x%x\n", pb->bat->version); 205 printf("BAT: state_of_charge(SOC):%d%%\n", 206 pb->bat->state_of_chrg); 207 208 printf(" voltage: %d.%6.6d [V] (expected to be %d [mAh])\n", 209 pb->bat->voltage_uV / 1000000, 210 pb->bat->voltage_uV % 1000000, 211 pb->bat->capacity); 212 213 if (pb->bat->voltage_uV > 3850000) 214 pb->bat->state = EXT_SOURCE; 215 else if (pb->bat->voltage_uV < 3600000 || pb->bat->state_of_chrg < 5) 216 pb->bat->state = CHARGE; 217 else 218 pb->bat->state = NORMAL; 219 220 return ret; 221 } 222 223 static struct power_fg power_fg_ops = { 224 .fg_battery_check = power_check_battery, 225 .fg_battery_update = power_update_battery, 226 }; 227 228 int power_fg_init(unsigned char bus) 229 { 230 static const char name[] = "MAX17042_FG"; 231 struct pmic *p = pmic_alloc(); 232 233 if (!p) { 234 printf("%s: POWER allocation error!\n", __func__); 235 return -ENOMEM; 236 } 237 238 debug("Board Fuel Gauge init\n"); 239 240 p->name = name; 241 p->interface = PMIC_I2C; 242 p->number_of_regs = FG_NUM_OF_REGS; 243 p->hw.i2c.addr = MAX17042_I2C_ADDR; 244 p->hw.i2c.tx_num = 2; 245 p->sensor_byte_order = PMIC_SENSOR_BYTE_ORDER_BIG; 246 p->bus = bus; 247 248 p->fg = &power_fg_ops; 249 return 0; 250 } 251