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_BEHAVIOUR, 75 POWER_SUPPLY_PROP_CHARGE_FULL, 76 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 77 POWER_SUPPLY_PROP_CHARGE_NOW, 78 POWER_SUPPLY_PROP_CURRENT_MAX, 79 POWER_SUPPLY_PROP_CURRENT_NOW, 80 POWER_SUPPLY_PROP_CYCLE_COUNT, 81 POWER_SUPPLY_PROP_HEALTH, 82 POWER_SUPPLY_PROP_PRESENT, 83 POWER_SUPPLY_PROP_STATUS, 84 POWER_SUPPLY_PROP_TEMP, 85 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 86 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 87 POWER_SUPPLY_PROP_VOLTAGE_NOW, 88 }; 89 90 static int mm8013_get_property(struct power_supply *psy, 91 enum power_supply_property psp, 92 union power_supply_propval *val) 93 { 94 struct mm8013_chip *chip = psy->drv_data; 95 int ret = 0; 96 u32 regval; 97 98 switch (psp) { 99 case POWER_SUPPLY_PROP_CAPACITY: 100 ret = regmap_read(chip->regmap, REG_STATE_OF_CHARGE, ®val); 101 if (ret < 0) 102 return ret; 103 104 val->intval = regval; 105 break; 106 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 107 ret = regmap_read(chip->regmap, REG_FLAGS, ®val); 108 if (ret < 0) 109 return ret; 110 111 if (regval & MM8013_FLAG_CHG_INH) 112 val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; 113 else 114 val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; 115 break; 116 case POWER_SUPPLY_PROP_CHARGE_FULL: 117 ret = regmap_read(chip->regmap, REG_FULL_CHARGE_CAPACITY, ®val); 118 if (ret < 0) 119 return ret; 120 121 val->intval = 1000 * regval; 122 break; 123 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 124 ret = regmap_read(chip->regmap, REG_DESIGN_CAPACITY, ®val); 125 if (ret < 0) 126 return ret; 127 128 val->intval = 1000 * regval; 129 break; 130 case POWER_SUPPLY_PROP_CHARGE_NOW: 131 ret = regmap_read(chip->regmap, REG_NOMINAL_CHARGE_CAPACITY, ®val); 132 if (ret < 0) 133 return ret; 134 135 val->intval = 1000 * regval; 136 break; 137 case POWER_SUPPLY_PROP_CURRENT_MAX: 138 ret = regmap_read(chip->regmap, REG_MAX_LOAD_CURRENT, ®val); 139 if (ret < 0) 140 return ret; 141 142 val->intval = -1000 * (s16)regval; 143 break; 144 case POWER_SUPPLY_PROP_CURRENT_NOW: 145 ret = regmap_read(chip->regmap, REG_AVERAGE_CURRENT, ®val); 146 if (ret < 0) 147 return ret; 148 149 val->intval = -1000 * (s16)regval; 150 break; 151 case POWER_SUPPLY_PROP_CYCLE_COUNT: 152 ret = regmap_read(chip->regmap, REG_CYCLE_COUNT, ®val); 153 if (ret < 0) 154 return ret; 155 156 val->intval = regval; 157 break; 158 case POWER_SUPPLY_PROP_HEALTH: 159 ret = regmap_read(chip->regmap, REG_FLAGS, ®val); 160 if (ret < 0) 161 return ret; 162 163 if (regval & MM8013_FLAG_UT) 164 val->intval = POWER_SUPPLY_HEALTH_COLD; 165 else if (regval & (MM8013_FLAG_ODC | MM8013_FLAG_OCC)) 166 val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 167 else if (regval & (MM8013_FLAG_BATLOW)) 168 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 169 else if (regval & MM8013_FLAG_BATHI) 170 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 171 else if (regval & (MM8013_FLAG_OT | MM8013_FLAG_OTD | MM8013_FLAG_OTC)) 172 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 173 else 174 val->intval = POWER_SUPPLY_HEALTH_GOOD; 175 break; 176 case POWER_SUPPLY_PROP_PRESENT: 177 ret = regmap_read(chip->regmap, REG_TEMPERATURE, ®val); 178 if (ret < 0) 179 return ret; 180 181 val->intval = ((s16)regval > 0); 182 break; 183 case POWER_SUPPLY_PROP_STATUS: 184 ret = regmap_read(chip->regmap, REG_FLAGS, ®val); 185 if (ret < 0) 186 return ret; 187 188 if (regval & MM8013_FLAG_DSG) 189 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 190 else if (regval & MM8013_FLAG_CHG) 191 val->intval = POWER_SUPPLY_STATUS_CHARGING; 192 else if (regval & MM8013_FLAG_FC) 193 val->intval = POWER_SUPPLY_STATUS_FULL; 194 else 195 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 196 break; 197 case POWER_SUPPLY_PROP_TEMP: 198 ret = regmap_read(chip->regmap, REG_TEMPERATURE, ®val); 199 if (ret < 0) 200 return ret; 201 202 val->intval = DECIKELVIN_TO_DECIDEGC(regval); 203 break; 204 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 205 ret = regmap_read(chip->regmap, REG_AVERAGE_TIME_TO_EMPTY, ®val); 206 if (ret < 0) 207 return ret; 208 209 /* The estimation is not yet ready */ 210 if (regval == U16_MAX) 211 return -ENODATA; 212 213 val->intval = regval; 214 break; 215 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 216 ret = regmap_read(chip->regmap, REG_AVERAGE_TIME_TO_FULL, ®val); 217 if (ret < 0) 218 return ret; 219 220 /* The estimation is not yet ready */ 221 if (regval == U16_MAX) 222 return -ENODATA; 223 224 val->intval = regval; 225 break; 226 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 227 ret = regmap_read(chip->regmap, REG_VOLTAGE, ®val); 228 if (ret < 0) 229 return ret; 230 231 val->intval = 1000 * regval; 232 break; 233 default: 234 return -EINVAL; 235 } 236 237 return 0; 238 } 239 240 static const struct power_supply_desc mm8013_desc = { 241 .name = "mm8013", 242 .type = POWER_SUPPLY_TYPE_BATTERY, 243 .properties = mm8013_battery_props, 244 .num_properties = ARRAY_SIZE(mm8013_battery_props), 245 .get_property = mm8013_get_property, 246 }; 247 248 static const struct regmap_config mm8013_regmap_config = { 249 .reg_bits = 8, 250 .val_bits = 16, 251 .max_register = 0x68, 252 .use_single_read = true, 253 .use_single_write = true, 254 .val_format_endian = REGMAP_ENDIAN_LITTLE, 255 }; 256 257 static int mm8013_probe(struct i2c_client *client) 258 { 259 struct power_supply_config psy_cfg = {}; 260 struct device *dev = &client->dev; 261 struct power_supply *psy; 262 struct mm8013_chip *chip; 263 int ret = 0; 264 265 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) 266 return dev_err_probe(dev, -EIO, 267 "I2C_FUNC_SMBUS_WORD_DATA not supported\n"); 268 269 chip = devm_kzalloc(dev, sizeof(struct mm8013_chip), GFP_KERNEL); 270 if (!chip) 271 return -ENOMEM; 272 273 chip->client = client; 274 275 chip->regmap = devm_regmap_init_i2c(client, &mm8013_regmap_config); 276 if (IS_ERR(chip->regmap)) { 277 ret = PTR_ERR(chip->regmap); 278 return dev_err_probe(dev, ret, "Couldn't initialize regmap\n"); 279 } 280 281 ret = mm8013_checkdevice(chip); 282 if (ret) 283 return dev_err_probe(dev, ret, "MM8013 not found\n"); 284 285 psy_cfg.drv_data = chip; 286 psy_cfg.of_node = dev->of_node; 287 288 psy = devm_power_supply_register(dev, &mm8013_desc, &psy_cfg); 289 if (IS_ERR(psy)) 290 return PTR_ERR(psy); 291 292 return 0; 293 } 294 295 static const struct i2c_device_id mm8013_id_table[] = { 296 { "mm8013", 0 }, 297 {} 298 }; 299 MODULE_DEVICE_TABLE(i2c, mm8013_id_table); 300 301 static const struct of_device_id mm8013_match_table[] = { 302 { .compatible = "mitsumi,mm8013" }, 303 {} 304 }; 305 306 static struct i2c_driver mm8013_i2c_driver = { 307 .probe = mm8013_probe, 308 .id_table = mm8013_id_table, 309 .driver = { 310 .name = "mm8013", 311 .of_match_table = mm8013_match_table, 312 }, 313 }; 314 module_i2c_driver(mm8013_i2c_driver); 315 316 MODULE_DESCRIPTION("MM8013 fuel gauge driver"); 317 MODULE_LICENSE("GPL"); 318