1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2023, Linaro Limited 5 */ 6 #include <linux/delay.h> 7 #include <linux/i2c.h> 8 #include <linux/power_supply.h> 9 #include <linux/regmap.h> 10 11 #define REG_BATID 0x00 /* This one is very unclear */ 12 #define BATID_101 0x0101 /* 107kOhm */ 13 #define BATID_102 0x0102 /* 10kOhm */ 14 #define REG_TEMPERATURE 0x06 15 #define REG_VOLTAGE 0x08 16 #define REG_FLAGS 0x0a 17 #define MM8013_FLAG_OTC BIT(15) 18 #define MM8013_FLAG_OTD BIT(14) 19 #define MM8013_FLAG_BATHI BIT(13) 20 #define MM8013_FLAG_BATLOW BIT(12) 21 #define MM8013_FLAG_CHG_INH BIT(11) 22 #define MM8013_FLAG_FC BIT(9) 23 #define MM8013_FLAG_CHG BIT(8) 24 #define MM8013_FLAG_OCC BIT(6) 25 #define MM8013_FLAG_ODC BIT(5) 26 #define MM8013_FLAG_OT BIT(4) 27 #define MM8013_FLAG_UT BIT(3) 28 #define MM8013_FLAG_DSG BIT(0) 29 #define REG_FULL_CHARGE_CAPACITY 0x0e 30 #define REG_NOMINAL_CHARGE_CAPACITY 0x0c 31 #define REG_AVERAGE_CURRENT 0x14 32 #define REG_AVERAGE_TIME_TO_EMPTY 0x16 33 #define REG_AVERAGE_TIME_TO_FULL 0x18 34 #define REG_MAX_LOAD_CURRENT 0x1e 35 #define REG_CYCLE_COUNT 0x2a 36 #define REG_STATE_OF_CHARGE 0x2c 37 #define REG_DESIGN_CAPACITY 0x3c 38 /* TODO: 0x62-0x68 seem to contain 'MM8013C' in a length-prefixed, non-terminated string */ 39 40 #define DECIKELVIN_TO_DECIDEGC(t) (t - 2731) 41 42 struct mm8013_chip { 43 struct i2c_client *client; 44 struct regmap *regmap; 45 }; 46 47 static int mm8013_checkdevice(struct mm8013_chip *chip) 48 { 49 int battery_id, ret; 50 u32 val; 51 52 ret = regmap_write(chip->regmap, REG_BATID, 0x0008); 53 if (ret < 0) 54 return ret; 55 56 ret = regmap_read(chip->regmap, REG_BATID, &val); 57 if (ret < 0) 58 return ret; 59 60 if (val == BATID_102) 61 battery_id = 2; 62 else if (val == BATID_101) 63 battery_id = 1; 64 else 65 return -EINVAL; 66 67 dev_dbg(&chip->client->dev, "battery_id: %d\n", battery_id); 68 69 return 0; 70 } 71 72 static enum power_supply_property mm8013_battery_props[] = { 73 POWER_SUPPLY_PROP_CAPACITY, 74 POWER_SUPPLY_PROP_CHARGE_FULL, 75 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 76 POWER_SUPPLY_PROP_CHARGE_NOW, 77 POWER_SUPPLY_PROP_CURRENT_MAX, 78 POWER_SUPPLY_PROP_CURRENT_NOW, 79 POWER_SUPPLY_PROP_CYCLE_COUNT, 80 POWER_SUPPLY_PROP_HEALTH, 81 POWER_SUPPLY_PROP_PRESENT, 82 POWER_SUPPLY_PROP_STATUS, 83 POWER_SUPPLY_PROP_TEMP, 84 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 85 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 86 POWER_SUPPLY_PROP_VOLTAGE_NOW, 87 }; 88 89 static int mm8013_get_property(struct power_supply *psy, 90 enum power_supply_property psp, 91 union power_supply_propval *val) 92 { 93 struct mm8013_chip *chip = psy->drv_data; 94 int ret = 0; 95 u32 regval; 96 97 switch (psp) { 98 case POWER_SUPPLY_PROP_CAPACITY: 99 ret = regmap_read(chip->regmap, REG_STATE_OF_CHARGE, ®val); 100 if (ret < 0) 101 return ret; 102 103 val->intval = regval; 104 break; 105 case POWER_SUPPLY_PROP_CHARGE_FULL: 106 ret = regmap_read(chip->regmap, REG_FULL_CHARGE_CAPACITY, ®val); 107 if (ret < 0) 108 return ret; 109 110 val->intval = 1000 * regval; 111 break; 112 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 113 ret = regmap_read(chip->regmap, REG_DESIGN_CAPACITY, ®val); 114 if (ret < 0) 115 return ret; 116 117 val->intval = 1000 * regval; 118 break; 119 case POWER_SUPPLY_PROP_CHARGE_NOW: 120 ret = regmap_read(chip->regmap, REG_NOMINAL_CHARGE_CAPACITY, ®val); 121 if (ret < 0) 122 return ret; 123 124 val->intval = 1000 * regval; 125 break; 126 case POWER_SUPPLY_PROP_CURRENT_MAX: 127 ret = regmap_read(chip->regmap, REG_MAX_LOAD_CURRENT, ®val); 128 if (ret < 0) 129 return ret; 130 131 val->intval = -1000 * (s16)regval; 132 break; 133 case POWER_SUPPLY_PROP_CURRENT_NOW: 134 ret = regmap_read(chip->regmap, REG_AVERAGE_CURRENT, ®val); 135 if (ret < 0) 136 return ret; 137 138 val->intval = -1000 * (s16)regval; 139 break; 140 case POWER_SUPPLY_PROP_CYCLE_COUNT: 141 ret = regmap_read(chip->regmap, REG_CYCLE_COUNT, ®val); 142 if (ret < 0) 143 return ret; 144 145 val->intval = regval; 146 break; 147 case POWER_SUPPLY_PROP_HEALTH: 148 ret = regmap_read(chip->regmap, REG_FLAGS, ®val); 149 if (ret < 0) 150 return ret; 151 152 if (regval & MM8013_FLAG_UT) 153 val->intval = POWER_SUPPLY_HEALTH_COLD; 154 else if (regval & (MM8013_FLAG_ODC | MM8013_FLAG_OCC)) 155 val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 156 else if (regval & (MM8013_FLAG_BATLOW)) 157 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 158 else if (regval & MM8013_FLAG_BATHI) 159 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 160 else if (regval & (MM8013_FLAG_OT | MM8013_FLAG_OTD | MM8013_FLAG_OTC)) 161 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 162 else 163 val->intval = POWER_SUPPLY_HEALTH_GOOD; 164 break; 165 case POWER_SUPPLY_PROP_PRESENT: 166 ret = regmap_read(chip->regmap, REG_TEMPERATURE, ®val); 167 if (ret < 0) 168 return ret; 169 170 val->intval = ((s16)regval > 0); 171 break; 172 case POWER_SUPPLY_PROP_STATUS: 173 ret = regmap_read(chip->regmap, REG_FLAGS, ®val); 174 if (ret < 0) 175 return ret; 176 177 if (regval & MM8013_FLAG_DSG) 178 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 179 else if (regval & MM8013_FLAG_CHG_INH) 180 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 181 else if (regval & MM8013_FLAG_CHG) 182 val->intval = POWER_SUPPLY_STATUS_CHARGING; 183 else if (regval & MM8013_FLAG_FC) 184 val->intval = POWER_SUPPLY_STATUS_FULL; 185 else 186 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 187 break; 188 case POWER_SUPPLY_PROP_TEMP: 189 ret = regmap_read(chip->regmap, REG_TEMPERATURE, ®val); 190 if (ret < 0) 191 return ret; 192 193 val->intval = DECIKELVIN_TO_DECIDEGC(regval); 194 break; 195 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 196 ret = regmap_read(chip->regmap, REG_AVERAGE_TIME_TO_EMPTY, ®val); 197 if (ret < 0) 198 return ret; 199 200 /* The estimation is not yet ready */ 201 if (regval == U16_MAX) 202 return -ENODATA; 203 204 val->intval = regval; 205 break; 206 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 207 ret = regmap_read(chip->regmap, REG_AVERAGE_TIME_TO_FULL, ®val); 208 if (ret < 0) 209 return ret; 210 211 /* The estimation is not yet ready */ 212 if (regval == U16_MAX) 213 return -ENODATA; 214 215 val->intval = regval; 216 break; 217 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 218 ret = regmap_read(chip->regmap, REG_VOLTAGE, ®val); 219 if (ret < 0) 220 return ret; 221 222 val->intval = 1000 * regval; 223 break; 224 default: 225 return -EINVAL; 226 } 227 228 return 0; 229 } 230 231 static const struct power_supply_desc mm8013_desc = { 232 .name = "mm8013", 233 .type = POWER_SUPPLY_TYPE_BATTERY, 234 .properties = mm8013_battery_props, 235 .num_properties = ARRAY_SIZE(mm8013_battery_props), 236 .get_property = mm8013_get_property, 237 }; 238 239 static const struct regmap_config mm8013_regmap_config = { 240 .reg_bits = 8, 241 .val_bits = 16, 242 .max_register = 0x68, 243 .use_single_read = true, 244 .use_single_write = true, 245 .val_format_endian = REGMAP_ENDIAN_LITTLE, 246 }; 247 248 static int mm8013_probe(struct i2c_client *client) 249 { 250 struct power_supply_config psy_cfg = {}; 251 struct device *dev = &client->dev; 252 struct power_supply *psy; 253 struct mm8013_chip *chip; 254 int ret = 0; 255 256 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) 257 return dev_err_probe(dev, -EIO, 258 "I2C_FUNC_SMBUS_WORD_DATA not supported\n"); 259 260 chip = devm_kzalloc(dev, sizeof(struct mm8013_chip), GFP_KERNEL); 261 if (!chip) 262 return -ENOMEM; 263 264 chip->client = client; 265 266 chip->regmap = devm_regmap_init_i2c(client, &mm8013_regmap_config); 267 if (IS_ERR(chip->regmap)) { 268 ret = PTR_ERR(chip->regmap); 269 return dev_err_probe(dev, ret, "Couldn't initialize regmap\n"); 270 } 271 272 ret = mm8013_checkdevice(chip); 273 if (ret) 274 return dev_err_probe(dev, ret, "MM8013 not found\n"); 275 276 psy_cfg.drv_data = chip; 277 psy_cfg.of_node = dev->of_node; 278 279 psy = devm_power_supply_register(dev, &mm8013_desc, &psy_cfg); 280 if (IS_ERR(psy)) 281 return PTR_ERR(psy); 282 283 return 0; 284 } 285 286 static const struct i2c_device_id mm8013_id_table[] = { 287 { "mm8013", 0 }, 288 {} 289 }; 290 MODULE_DEVICE_TABLE(i2c, mm8013_id_table); 291 292 static const struct of_device_id mm8013_match_table[] = { 293 { .compatible = "mitsumi,mm8013" }, 294 {} 295 }; 296 297 static struct i2c_driver mm8013_i2c_driver = { 298 .probe = mm8013_probe, 299 .id_table = mm8013_id_table, 300 .driver = { 301 .name = "mm8013", 302 .of_match_table = mm8013_match_table, 303 }, 304 }; 305 module_i2c_driver(mm8013_i2c_driver); 306 307 MODULE_DESCRIPTION("MM8013 fuel gauge driver"); 308 MODULE_LICENSE("GPL"); 309