0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/module.h>
0015 #include <linux/slab.h>
0016 #include <linux/w1.h>
0017 #include <linux/regmap.h>
0018 #include <linux/power_supply.h>
0019
0020 #define W1_MAX1721X_FAMILY_ID 0x26
0021 #define DEF_DEV_NAME_MAX17211 "MAX17211"
0022 #define DEF_DEV_NAME_MAX17215 "MAX17215"
0023 #define DEF_DEV_NAME_UNKNOWN "UNKNOWN"
0024 #define DEF_MFG_NAME "MAXIM"
0025
0026 #define PSY_MAX_NAME_LEN 32
0027
0028
0029 #define MAX1721X_MAX_REG_NR 0x1EF
0030
0031
0032 #define MAX1721X_REG_NRSENSE 0x1CF
0033
0034 #define MAX1721X_REG_MFG_STR 0x1CC
0035 #define MAX1721X_REG_MFG_NUMB 3
0036 #define MAX1721X_REG_DEV_STR 0x1DB
0037 #define MAX1721X_REG_DEV_NUMB 5
0038
0039 #define MAX1721X_REG_SER_HEX 0x1D8
0040
0041
0042 #define MAX172XX_REG_STATUS 0x000
0043 #define MAX172XX_BAT_PRESENT (1<<4)
0044 #define MAX172XX_REG_DEVNAME 0x021
0045 #define MAX172XX_DEV_MASK 0x000F
0046 #define MAX172X1_DEV 0x0001
0047 #define MAX172X5_DEV 0x0005
0048 #define MAX172XX_REG_TEMP 0x008
0049 #define MAX172XX_REG_BATT 0x0DA
0050 #define MAX172XX_REG_CURRENT 0x00A
0051 #define MAX172XX_REG_AVGCURRENT 0x00B
0052 #define MAX172XX_REG_REPSOC 0x006
0053 #define MAX172XX_REG_DESIGNCAP 0x018
0054 #define MAX172XX_REG_REPCAP 0x005
0055 #define MAX172XX_REG_TTE 0x011
0056 #define MAX172XX_REG_TTF 0x020
0057
0058 struct max17211_device_info {
0059 char name[PSY_MAX_NAME_LEN];
0060 struct power_supply *bat;
0061 struct power_supply_desc bat_desc;
0062 struct device *w1_dev;
0063 struct regmap *regmap;
0064
0065 unsigned int rsense;
0066 char DeviceName[2 * MAX1721X_REG_DEV_NUMB + 1];
0067 char ManufacturerName[2 * MAX1721X_REG_MFG_NUMB + 1];
0068 char SerialNumber[13];
0069 };
0070
0071
0072
0073 static inline int max172xx_time_to_ps(unsigned int reg)
0074 {
0075 return reg * 5625 / 1000;
0076 }
0077
0078 static inline int max172xx_percent_to_ps(unsigned int reg)
0079 {
0080 return reg / 256;
0081 }
0082
0083 static inline int max172xx_voltage_to_ps(unsigned int reg)
0084 {
0085 return reg * 1250;
0086 }
0087
0088 static inline int max172xx_capacity_to_ps(unsigned int reg)
0089 {
0090 return reg * 500;
0091 }
0092
0093
0094
0095
0096
0097
0098 static inline int max172xx_temperature_to_ps(unsigned int reg)
0099 {
0100 int val = (int16_t)(reg);
0101
0102 return val * 10 / 256;
0103 }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 static inline int max172xx_current_to_voltage(unsigned int reg)
0114 {
0115 int val = (int16_t)(reg);
0116
0117 return val * 156252;
0118 }
0119
0120
0121 static inline struct max17211_device_info *
0122 to_device_info(struct power_supply *psy)
0123 {
0124 return power_supply_get_drvdata(psy);
0125 }
0126
0127 static int max1721x_battery_get_property(struct power_supply *psy,
0128 enum power_supply_property psp,
0129 union power_supply_propval *val)
0130 {
0131 struct max17211_device_info *info = to_device_info(psy);
0132 unsigned int reg = 0;
0133 int ret = 0;
0134
0135 switch (psp) {
0136 case POWER_SUPPLY_PROP_PRESENT:
0137
0138
0139
0140
0141
0142 val->intval =
0143 regmap_read(info->regmap, MAX172XX_REG_STATUS,
0144 ®) ? 0 : !(reg & MAX172XX_BAT_PRESENT);
0145 break;
0146 case POWER_SUPPLY_PROP_CAPACITY:
0147 ret = regmap_read(info->regmap, MAX172XX_REG_REPSOC, ®);
0148 val->intval = max172xx_percent_to_ps(reg);
0149 break;
0150 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0151 ret = regmap_read(info->regmap, MAX172XX_REG_BATT, ®);
0152 val->intval = max172xx_voltage_to_ps(reg);
0153 break;
0154 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
0155 ret = regmap_read(info->regmap, MAX172XX_REG_DESIGNCAP, ®);
0156 val->intval = max172xx_capacity_to_ps(reg);
0157 break;
0158 case POWER_SUPPLY_PROP_CHARGE_AVG:
0159 ret = regmap_read(info->regmap, MAX172XX_REG_REPCAP, ®);
0160 val->intval = max172xx_capacity_to_ps(reg);
0161 break;
0162 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
0163 ret = regmap_read(info->regmap, MAX172XX_REG_TTE, ®);
0164 val->intval = max172xx_time_to_ps(reg);
0165 break;
0166 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
0167 ret = regmap_read(info->regmap, MAX172XX_REG_TTF, ®);
0168 val->intval = max172xx_time_to_ps(reg);
0169 break;
0170 case POWER_SUPPLY_PROP_TEMP:
0171 ret = regmap_read(info->regmap, MAX172XX_REG_TEMP, ®);
0172 val->intval = max172xx_temperature_to_ps(reg);
0173 break;
0174
0175 case POWER_SUPPLY_PROP_CURRENT_NOW:
0176 ret = regmap_read(info->regmap, MAX172XX_REG_CURRENT, ®);
0177 val->intval =
0178 max172xx_current_to_voltage(reg) / (int)info->rsense;
0179 break;
0180 case POWER_SUPPLY_PROP_CURRENT_AVG:
0181 ret = regmap_read(info->regmap, MAX172XX_REG_AVGCURRENT, ®);
0182 val->intval =
0183 max172xx_current_to_voltage(reg) / (int)info->rsense;
0184 break;
0185
0186
0187
0188
0189 case POWER_SUPPLY_PROP_MODEL_NAME:
0190 ret = regmap_read(info->regmap, MAX1721X_REG_DEV_STR, ®);
0191 val->strval = info->DeviceName;
0192 break;
0193 case POWER_SUPPLY_PROP_MANUFACTURER:
0194 ret = regmap_read(info->regmap, MAX1721X_REG_MFG_STR, ®);
0195 val->strval = info->ManufacturerName;
0196 break;
0197 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
0198 ret = regmap_read(info->regmap, MAX1721X_REG_SER_HEX, ®);
0199 val->strval = info->SerialNumber;
0200 break;
0201 default:
0202 ret = -EINVAL;
0203 }
0204
0205 return ret;
0206 }
0207
0208 static enum power_supply_property max1721x_battery_props[] = {
0209
0210 POWER_SUPPLY_PROP_PRESENT,
0211 POWER_SUPPLY_PROP_CAPACITY,
0212 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0213 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
0214 POWER_SUPPLY_PROP_CHARGE_AVG,
0215 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
0216 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
0217 POWER_SUPPLY_PROP_TEMP,
0218 POWER_SUPPLY_PROP_CURRENT_NOW,
0219 POWER_SUPPLY_PROP_CURRENT_AVG,
0220
0221 POWER_SUPPLY_PROP_MODEL_NAME,
0222 POWER_SUPPLY_PROP_MANUFACTURER,
0223 POWER_SUPPLY_PROP_SERIAL_NUMBER,
0224 };
0225
0226 static int get_string(struct max17211_device_info *info,
0227 uint16_t reg, uint8_t nr, char *str)
0228 {
0229 unsigned int val;
0230
0231 if (!str || !(reg == MAX1721X_REG_MFG_STR ||
0232 reg == MAX1721X_REG_DEV_STR))
0233 return -EFAULT;
0234
0235 while (nr--) {
0236 if (regmap_read(info->regmap, reg++, &val))
0237 return -EFAULT;
0238 *str++ = val>>8 & 0x00FF;
0239 *str++ = val & 0x00FF;
0240 }
0241 return 0;
0242 }
0243
0244
0245 static int get_sn_string(struct max17211_device_info *info, char *str)
0246 {
0247 unsigned int val[3];
0248
0249 if (!str)
0250 return -EFAULT;
0251
0252 if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX, &val[0]))
0253 return -EFAULT;
0254 if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX + 1, &val[1]))
0255 return -EFAULT;
0256 if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX + 2, &val[2]))
0257 return -EFAULT;
0258
0259 snprintf(str, 13, "%04X%04X%04X", val[0], val[1], val[2]);
0260 return 0;
0261 }
0262
0263
0264
0265
0266 static const struct regmap_range max1721x_allow_range[] = {
0267 regmap_reg_range(0, 0xDF),
0268 regmap_reg_range(0x180, 0x1DF),
0269 regmap_reg_range(0x1E0, 0x1EF),
0270 };
0271
0272 static const struct regmap_range max1721x_deny_range[] = {
0273
0274 regmap_reg_range(0x24, 0x26),
0275 regmap_reg_range(0x30, 0x31),
0276 regmap_reg_range(0x33, 0x34),
0277 regmap_reg_range(0x37, 0x37),
0278 regmap_reg_range(0x3B, 0x3C),
0279 regmap_reg_range(0x40, 0x41),
0280 regmap_reg_range(0x43, 0x44),
0281 regmap_reg_range(0x47, 0x49),
0282 regmap_reg_range(0x4B, 0x4C),
0283 regmap_reg_range(0x4E, 0xAF),
0284 regmap_reg_range(0xB1, 0xB3),
0285 regmap_reg_range(0xB5, 0xB7),
0286 regmap_reg_range(0xBF, 0xD0),
0287 regmap_reg_range(0xDB, 0xDB),
0288
0289 regmap_reg_range(0xE0, 0x17F),
0290 };
0291
0292 static const struct regmap_access_table max1721x_regs = {
0293 .yes_ranges = max1721x_allow_range,
0294 .n_yes_ranges = ARRAY_SIZE(max1721x_allow_range),
0295 .no_ranges = max1721x_deny_range,
0296 .n_no_ranges = ARRAY_SIZE(max1721x_deny_range),
0297 };
0298
0299
0300
0301
0302
0303 static const struct regmap_range max1721x_volatile_allow[] = {
0304 regmap_reg_range(0, 0xDF),
0305 };
0306
0307 static const struct regmap_access_table max1721x_volatile_regs = {
0308 .yes_ranges = max1721x_volatile_allow,
0309 .n_yes_ranges = ARRAY_SIZE(max1721x_volatile_allow),
0310 };
0311
0312
0313
0314
0315 static const struct regmap_config max1721x_regmap_w1_config = {
0316 .reg_bits = 16,
0317 .val_bits = 16,
0318 .rd_table = &max1721x_regs,
0319 .volatile_table = &max1721x_volatile_regs,
0320 .max_register = MAX1721X_MAX_REG_NR,
0321 };
0322
0323 static int devm_w1_max1721x_add_device(struct w1_slave *sl)
0324 {
0325 struct power_supply_config psy_cfg = {};
0326 struct max17211_device_info *info;
0327
0328 info = devm_kzalloc(&sl->dev, sizeof(*info), GFP_KERNEL);
0329 if (!info)
0330 return -ENOMEM;
0331
0332 sl->family_data = (void *)info;
0333 info->w1_dev = &sl->dev;
0334
0335
0336
0337
0338
0339
0340
0341 snprintf(info->name, sizeof(info->name),
0342 "max1721x-%012X", (unsigned int)sl->reg_num.id);
0343 info->bat_desc.name = info->name;
0344
0345
0346
0347
0348
0349 info->bat_desc.no_thermal = true;
0350 info->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
0351 info->bat_desc.properties = max1721x_battery_props;
0352 info->bat_desc.num_properties = ARRAY_SIZE(max1721x_battery_props);
0353 info->bat_desc.get_property = max1721x_battery_get_property;
0354 psy_cfg.drv_data = info;
0355
0356
0357 info->regmap = devm_regmap_init_w1(info->w1_dev,
0358 &max1721x_regmap_w1_config);
0359 if (IS_ERR(info->regmap)) {
0360 int err = PTR_ERR(info->regmap);
0361
0362 dev_err(info->w1_dev, "Failed to allocate register map: %d\n",
0363 err);
0364 return err;
0365 }
0366
0367
0368 info->rsense = 0;
0369 if (regmap_read(info->regmap, MAX1721X_REG_NRSENSE, &info->rsense)) {
0370 dev_err(info->w1_dev, "Can't read RSense. Hardware error.\n");
0371 return -ENODEV;
0372 }
0373
0374 if (!info->rsense) {
0375 dev_warn(info->w1_dev, "RSense not calibrated, set 10 mOhms!\n");
0376 info->rsense = 1000;
0377 }
0378 dev_info(info->w1_dev, "RSense: %d mOhms.\n", info->rsense / 100);
0379
0380 if (get_string(info, MAX1721X_REG_MFG_STR,
0381 MAX1721X_REG_MFG_NUMB, info->ManufacturerName)) {
0382 dev_err(info->w1_dev, "Can't read manufacturer. Hardware error.\n");
0383 return -ENODEV;
0384 }
0385
0386 if (!info->ManufacturerName[0])
0387 strncpy(info->ManufacturerName, DEF_MFG_NAME,
0388 2 * MAX1721X_REG_MFG_NUMB);
0389
0390 if (get_string(info, MAX1721X_REG_DEV_STR,
0391 MAX1721X_REG_DEV_NUMB, info->DeviceName)) {
0392 dev_err(info->w1_dev, "Can't read device. Hardware error.\n");
0393 return -ENODEV;
0394 }
0395 if (!info->DeviceName[0]) {
0396 unsigned int dev_name;
0397
0398 if (regmap_read(info->regmap,
0399 MAX172XX_REG_DEVNAME, &dev_name)) {
0400 dev_err(info->w1_dev, "Can't read device name reg.\n");
0401 return -ENODEV;
0402 }
0403
0404 switch (dev_name & MAX172XX_DEV_MASK) {
0405 case MAX172X1_DEV:
0406 strncpy(info->DeviceName, DEF_DEV_NAME_MAX17211,
0407 2 * MAX1721X_REG_DEV_NUMB);
0408 break;
0409 case MAX172X5_DEV:
0410 strncpy(info->DeviceName, DEF_DEV_NAME_MAX17215,
0411 2 * MAX1721X_REG_DEV_NUMB);
0412 break;
0413 default:
0414 strncpy(info->DeviceName, DEF_DEV_NAME_UNKNOWN,
0415 2 * MAX1721X_REG_DEV_NUMB);
0416 }
0417 }
0418
0419 if (get_sn_string(info, info->SerialNumber)) {
0420 dev_err(info->w1_dev, "Can't read serial. Hardware error.\n");
0421 return -ENODEV;
0422 }
0423
0424 info->bat = devm_power_supply_register(&sl->dev, &info->bat_desc,
0425 &psy_cfg);
0426 if (IS_ERR(info->bat)) {
0427 dev_err(info->w1_dev, "failed to register battery\n");
0428 return PTR_ERR(info->bat);
0429 }
0430
0431 return 0;
0432 }
0433
0434 static const struct w1_family_ops w1_max1721x_fops = {
0435 .add_slave = devm_w1_max1721x_add_device,
0436 };
0437
0438 static struct w1_family w1_max1721x_family = {
0439 .fid = W1_MAX1721X_FAMILY_ID,
0440 .fops = &w1_max1721x_fops,
0441 };
0442
0443 module_w1_family(w1_max1721x_family);
0444
0445 MODULE_LICENSE("GPL");
0446 MODULE_AUTHOR("Alex A. Mihaylov <minimumlaw@rambler.ru>");
0447 MODULE_DESCRIPTION("Maxim MAX17211/MAX17215 Fuel Gauage IC driver");
0448 MODULE_ALIAS("w1-family-" __stringify(W1_MAX1721X_FAMILY_ID));