1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2013 Samsung Electronics 4 * Piotr Wilczek <p.wilczek@samsung.com> 5 */ 6 7 #include <common.h> 8 #include <power/pmic.h> 9 #include <power/max77693_fg.h> 10 #include <i2c.h> 11 #include <power/power_chrg.h> 12 #include <power/battery.h> 13 #include <power/fg_battery_cell_params.h> 14 #include <errno.h> 15 16 static int max77693_get_vcell(u32 *vcell) 17 { 18 u16 value; 19 u8 ret; 20 21 ret = i2c_read(MAX77693_FUEL_I2C_ADDR, MAX77693_VCELL, 1, 22 (u8 *)&value, 2); 23 if (ret) 24 return ret; 25 26 *vcell = (u32)(value >> 3); 27 *vcell = *vcell * 625; 28 29 return 0; 30 } 31 32 static int max77693_get_soc(u32 *soc) 33 { 34 u16 value; 35 u8 ret; 36 37 ret = i2c_read(MAX77693_FUEL_I2C_ADDR, MAX77693_VFSOC, 1, 38 (u8 *)&value, 2); 39 if (ret) 40 return ret; 41 42 *soc = (u32)(value >> 8); 43 44 return 0; 45 } 46 47 static int power_update_battery(struct pmic *p, struct pmic *bat) 48 { 49 struct power_battery *pb = bat->pbat; 50 int ret; 51 52 if (pmic_probe(p)) { 53 puts("Can't find max77693 fuel gauge\n"); 54 return -ENODEV; 55 } 56 57 ret = max77693_get_soc(&pb->bat->state_of_chrg); 58 if (ret) 59 return ret; 60 61 max77693_get_vcell(&pb->bat->voltage_uV); 62 63 return 0; 64 } 65 66 static int power_check_battery(struct pmic *p, struct pmic *bat) 67 { 68 struct power_battery *pb = bat->pbat; 69 unsigned int val; 70 int ret = 0; 71 72 if (pmic_probe(p)) { 73 puts("Can't find max77693 fuel gauge\n"); 74 return -ENODEV; 75 } 76 77 ret = pmic_reg_read(p, MAX77693_STATUS, &val); 78 if (ret) 79 return ret; 80 debug("fg status: 0x%x\n", val); 81 82 ret = pmic_reg_read(p, MAX77693_VERSION, &pb->bat->version); 83 if (ret) 84 return ret; 85 86 ret = power_update_battery(p, bat); 87 if (ret) 88 return ret; 89 debug("fg ver: 0x%x\n", pb->bat->version); 90 printf("BAT: state_of_charge(SOC):%d%%\n", 91 pb->bat->state_of_chrg); 92 93 printf(" voltage: %d.%6.6d [V] (expected to be %d [mAh])\n", 94 pb->bat->voltage_uV / 1000000, 95 pb->bat->voltage_uV % 1000000, 96 pb->bat->capacity); 97 98 if (pb->bat->voltage_uV > 3850000) 99 pb->bat->state = EXT_SOURCE; 100 else if (pb->bat->voltage_uV < 3600000 || pb->bat->state_of_chrg < 5) 101 pb->bat->state = CHARGE; 102 else 103 pb->bat->state = NORMAL; 104 105 return 0; 106 } 107 108 static struct power_fg power_fg_ops = { 109 .fg_battery_check = power_check_battery, 110 .fg_battery_update = power_update_battery, 111 }; 112 113 int power_fg_init(unsigned char bus) 114 { 115 static const char name[] = "MAX77693_FG"; 116 struct pmic *p = pmic_alloc(); 117 118 if (!p) { 119 printf("%s: POWER allocation error!\n", __func__); 120 return -ENOMEM; 121 } 122 123 debug("Board Fuel Gauge init\n"); 124 125 p->name = name; 126 p->interface = PMIC_I2C; 127 p->number_of_regs = FG_NUM_OF_REGS; 128 p->hw.i2c.addr = MAX77693_FUEL_I2C_ADDR; 129 p->hw.i2c.tx_num = 2; 130 p->sensor_byte_order = PMIC_SENSOR_BYTE_ORDER_BIG; 131 p->bus = bus; 132 133 p->fg = &power_fg_ops; 134 135 return 0; 136 } 137