0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/err.h>
0011 #include <linux/slab.h>
0012 #include <linux/of.h>
0013 #include <linux/i2c.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/power_supply.h>
0017 #include <linux/mfd/max8925.h>
0018
0019
0020 #define MAX8925_OUT5VEN 0x54
0021 #define MAX8925_OUT3VEN 0x58
0022 #define MAX8925_CHG_CNTL1 0x7c
0023
0024
0025 #define MAX8925_CHG_STAT_VSYSLOW (1 << 0)
0026 #define MAX8925_CHG_STAT_MODE_MASK (3 << 2)
0027 #define MAX8925_CHG_STAT_EN_MASK (1 << 4)
0028 #define MAX8925_CHG_MBDET (1 << 1)
0029 #define MAX8925_CHG_AC_RANGE_MASK (3 << 6)
0030
0031
0032 #define MAX8925_ADC_RES_CNFG1 0x06
0033 #define MAX8925_ADC_AVG_CNFG1 0x07
0034 #define MAX8925_ADC_ACQ_CNFG1 0x08
0035 #define MAX8925_ADC_ACQ_CNFG2 0x09
0036
0037 #define MAX8925_ADC_AUX2 0x62
0038 #define MAX8925_ADC_VCHG 0x64
0039 #define MAX8925_ADC_VBBATT 0x66
0040 #define MAX8925_ADC_VMBATT 0x68
0041 #define MAX8925_ADC_ISNS 0x6a
0042 #define MAX8925_ADC_THM 0x6c
0043 #define MAX8925_ADC_TDIE 0x6e
0044 #define MAX8925_CMD_AUX2 0xc8
0045 #define MAX8925_CMD_VCHG 0xd0
0046 #define MAX8925_CMD_VBBATT 0xd8
0047 #define MAX8925_CMD_VMBATT 0xe0
0048 #define MAX8925_CMD_ISNS 0xe8
0049 #define MAX8925_CMD_THM 0xf0
0050 #define MAX8925_CMD_TDIE 0xf8
0051
0052 enum {
0053 MEASURE_AUX2,
0054 MEASURE_VCHG,
0055 MEASURE_VBBATT,
0056 MEASURE_VMBATT,
0057 MEASURE_ISNS,
0058 MEASURE_THM,
0059 MEASURE_TDIE,
0060 MEASURE_MAX,
0061 };
0062
0063 struct max8925_power_info {
0064 struct max8925_chip *chip;
0065 struct i2c_client *gpm;
0066 struct i2c_client *adc;
0067
0068 struct power_supply *ac;
0069 struct power_supply *usb;
0070 struct power_supply *battery;
0071 int irq_base;
0072 unsigned ac_online:1;
0073 unsigned usb_online:1;
0074 unsigned bat_online:1;
0075 unsigned chg_mode:2;
0076 unsigned batt_detect:1;
0077 unsigned topoff_threshold:2;
0078 unsigned fast_charge:3;
0079 unsigned no_temp_support:1;
0080 unsigned no_insert_detect:1;
0081
0082 int (*set_charger) (int);
0083 };
0084
0085 static int __set_charger(struct max8925_power_info *info, int enable)
0086 {
0087 struct max8925_chip *chip = info->chip;
0088 if (enable) {
0089
0090 if (info->set_charger)
0091 info->set_charger(1);
0092
0093 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
0094 } else {
0095
0096 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
0097 if (info->set_charger)
0098 info->set_charger(0);
0099 }
0100 dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
0101 : "Disable charger");
0102 return 0;
0103 }
0104
0105 static irqreturn_t max8925_charger_handler(int irq, void *data)
0106 {
0107 struct max8925_power_info *info = (struct max8925_power_info *)data;
0108 struct max8925_chip *chip = info->chip;
0109
0110 switch (irq - chip->irq_base) {
0111 case MAX8925_IRQ_VCHG_DC_R:
0112 info->ac_online = 1;
0113 __set_charger(info, 1);
0114 dev_dbg(chip->dev, "Adapter inserted\n");
0115 break;
0116 case MAX8925_IRQ_VCHG_DC_F:
0117 info->ac_online = 0;
0118 __set_charger(info, 0);
0119 dev_dbg(chip->dev, "Adapter removed\n");
0120 break;
0121 case MAX8925_IRQ_VCHG_THM_OK_F:
0122
0123 dev_dbg(chip->dev, "Battery temperature is out of range\n");
0124 fallthrough;
0125 case MAX8925_IRQ_VCHG_DC_OVP:
0126 dev_dbg(chip->dev, "Error detection\n");
0127 __set_charger(info, 0);
0128 break;
0129 case MAX8925_IRQ_VCHG_THM_OK_R:
0130
0131 dev_dbg(chip->dev, "Battery temperature is in range\n");
0132 break;
0133 case MAX8925_IRQ_VCHG_SYSLOW_R:
0134
0135 dev_info(chip->dev, "Sys power is too low\n");
0136 break;
0137 case MAX8925_IRQ_VCHG_SYSLOW_F:
0138 dev_dbg(chip->dev, "Sys power is above low threshold\n");
0139 break;
0140 case MAX8925_IRQ_VCHG_DONE:
0141 __set_charger(info, 0);
0142 dev_dbg(chip->dev, "Charging is done\n");
0143 break;
0144 case MAX8925_IRQ_VCHG_TOPOFF:
0145 dev_dbg(chip->dev, "Charging in top-off mode\n");
0146 break;
0147 case MAX8925_IRQ_VCHG_TMR_FAULT:
0148 __set_charger(info, 0);
0149 dev_dbg(chip->dev, "Safe timer is expired\n");
0150 break;
0151 case MAX8925_IRQ_VCHG_RST:
0152 __set_charger(info, 0);
0153 dev_dbg(chip->dev, "Charger is reset\n");
0154 break;
0155 }
0156 return IRQ_HANDLED;
0157 }
0158
0159 static int start_measure(struct max8925_power_info *info, int type)
0160 {
0161 unsigned char buf[2] = {0, 0};
0162 int meas_cmd;
0163 int meas_reg = 0, ret;
0164
0165 switch (type) {
0166 case MEASURE_VCHG:
0167 meas_cmd = MAX8925_CMD_VCHG;
0168 meas_reg = MAX8925_ADC_VCHG;
0169 break;
0170 case MEASURE_VBBATT:
0171 meas_cmd = MAX8925_CMD_VBBATT;
0172 meas_reg = MAX8925_ADC_VBBATT;
0173 break;
0174 case MEASURE_VMBATT:
0175 meas_cmd = MAX8925_CMD_VMBATT;
0176 meas_reg = MAX8925_ADC_VMBATT;
0177 break;
0178 case MEASURE_ISNS:
0179 meas_cmd = MAX8925_CMD_ISNS;
0180 meas_reg = MAX8925_ADC_ISNS;
0181 break;
0182 default:
0183 return -EINVAL;
0184 }
0185
0186 max8925_reg_write(info->adc, meas_cmd, 0);
0187 max8925_bulk_read(info->adc, meas_reg, 2, buf);
0188 ret = ((buf[0]<<8) | buf[1]) >> 4;
0189
0190 return ret;
0191 }
0192
0193 static int max8925_ac_get_prop(struct power_supply *psy,
0194 enum power_supply_property psp,
0195 union power_supply_propval *val)
0196 {
0197 struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent);
0198 int ret = 0;
0199
0200 switch (psp) {
0201 case POWER_SUPPLY_PROP_ONLINE:
0202 val->intval = info->ac_online;
0203 break;
0204 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0205 if (info->ac_online) {
0206 ret = start_measure(info, MEASURE_VCHG);
0207 if (ret >= 0) {
0208 val->intval = ret * 2000;
0209 goto out;
0210 }
0211 }
0212 ret = -ENODATA;
0213 break;
0214 default:
0215 ret = -ENODEV;
0216 break;
0217 }
0218 out:
0219 return ret;
0220 }
0221
0222 static enum power_supply_property max8925_ac_props[] = {
0223 POWER_SUPPLY_PROP_ONLINE,
0224 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0225 };
0226
0227 static int max8925_usb_get_prop(struct power_supply *psy,
0228 enum power_supply_property psp,
0229 union power_supply_propval *val)
0230 {
0231 struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent);
0232 int ret = 0;
0233
0234 switch (psp) {
0235 case POWER_SUPPLY_PROP_ONLINE:
0236 val->intval = info->usb_online;
0237 break;
0238 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0239 if (info->usb_online) {
0240 ret = start_measure(info, MEASURE_VCHG);
0241 if (ret >= 0) {
0242 val->intval = ret * 2000;
0243 goto out;
0244 }
0245 }
0246 ret = -ENODATA;
0247 break;
0248 default:
0249 ret = -ENODEV;
0250 break;
0251 }
0252 out:
0253 return ret;
0254 }
0255
0256 static enum power_supply_property max8925_usb_props[] = {
0257 POWER_SUPPLY_PROP_ONLINE,
0258 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0259 };
0260
0261 static int max8925_bat_get_prop(struct power_supply *psy,
0262 enum power_supply_property psp,
0263 union power_supply_propval *val)
0264 {
0265 struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent);
0266 int ret = 0;
0267
0268 switch (psp) {
0269 case POWER_SUPPLY_PROP_ONLINE:
0270 val->intval = info->bat_online;
0271 break;
0272 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0273 if (info->bat_online) {
0274 ret = start_measure(info, MEASURE_VMBATT);
0275 if (ret >= 0) {
0276 val->intval = ret * 2000;
0277 ret = 0;
0278 break;
0279 }
0280 }
0281 ret = -ENODATA;
0282 break;
0283 case POWER_SUPPLY_PROP_CURRENT_NOW:
0284 if (info->bat_online) {
0285 ret = start_measure(info, MEASURE_ISNS);
0286 if (ret >= 0) {
0287
0288 ret = ((ret * 6250) - 3125) ;
0289 val->intval = 0;
0290 if (ret > 0)
0291 val->intval = ret;
0292 ret = 0;
0293 break;
0294 }
0295 }
0296 ret = -ENODATA;
0297 break;
0298 case POWER_SUPPLY_PROP_CHARGE_TYPE:
0299 if (!info->bat_online) {
0300 ret = -ENODATA;
0301 break;
0302 }
0303 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
0304 ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2;
0305 switch (ret) {
0306 case 1:
0307 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
0308 break;
0309 case 0:
0310 case 2:
0311 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
0312 break;
0313 case 3:
0314 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
0315 break;
0316 }
0317 ret = 0;
0318 break;
0319 case POWER_SUPPLY_PROP_STATUS:
0320 if (!info->bat_online) {
0321 ret = -ENODATA;
0322 break;
0323 }
0324 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
0325 if (info->usb_online || info->ac_online) {
0326 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
0327 if (ret & MAX8925_CHG_STAT_EN_MASK)
0328 val->intval = POWER_SUPPLY_STATUS_CHARGING;
0329 } else
0330 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
0331 ret = 0;
0332 break;
0333 default:
0334 ret = -ENODEV;
0335 break;
0336 }
0337 return ret;
0338 }
0339
0340 static enum power_supply_property max8925_battery_props[] = {
0341 POWER_SUPPLY_PROP_ONLINE,
0342 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0343 POWER_SUPPLY_PROP_CURRENT_NOW,
0344 POWER_SUPPLY_PROP_CHARGE_TYPE,
0345 POWER_SUPPLY_PROP_STATUS,
0346 };
0347
0348 static const struct power_supply_desc ac_desc = {
0349 .name = "max8925-ac",
0350 .type = POWER_SUPPLY_TYPE_MAINS,
0351 .properties = max8925_ac_props,
0352 .num_properties = ARRAY_SIZE(max8925_ac_props),
0353 .get_property = max8925_ac_get_prop,
0354 };
0355
0356 static const struct power_supply_desc usb_desc = {
0357 .name = "max8925-usb",
0358 .type = POWER_SUPPLY_TYPE_USB,
0359 .properties = max8925_usb_props,
0360 .num_properties = ARRAY_SIZE(max8925_usb_props),
0361 .get_property = max8925_usb_get_prop,
0362 };
0363
0364 static const struct power_supply_desc battery_desc = {
0365 .name = "max8925-battery",
0366 .type = POWER_SUPPLY_TYPE_BATTERY,
0367 .properties = max8925_battery_props,
0368 .num_properties = ARRAY_SIZE(max8925_battery_props),
0369 .get_property = max8925_bat_get_prop,
0370 };
0371
0372 #define REQUEST_IRQ(_irq, _name) \
0373 do { \
0374 ret = request_threaded_irq(chip->irq_base + _irq, NULL, \
0375 max8925_charger_handler, \
0376 IRQF_ONESHOT, _name, info); \
0377 if (ret) \
0378 dev_err(chip->dev, "Failed to request IRQ #%d: %d\n", \
0379 _irq, ret); \
0380 } while (0)
0381
0382 static int max8925_init_charger(struct max8925_chip *chip,
0383 struct max8925_power_info *info)
0384 {
0385 int ret;
0386
0387 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
0388 if (!info->no_insert_detect) {
0389 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
0390 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
0391 }
0392 if (!info->no_temp_support) {
0393 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
0394 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
0395 }
0396 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
0397 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
0398 REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
0399 REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
0400 REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
0401 REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
0402
0403 info->usb_online = 0;
0404 info->bat_online = 0;
0405
0406
0407 if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
0408 info->ac_online = 1;
0409 else
0410 info->ac_online = 0;
0411
0412 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
0413 if (ret >= 0) {
0414
0415
0416
0417
0418
0419
0420 if (info->batt_detect)
0421 info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
0422 else
0423 info->bat_online = 1;
0424 if (ret & MAX8925_CHG_AC_RANGE_MASK)
0425 info->ac_online = 1;
0426 else
0427 info->ac_online = 0;
0428 }
0429
0430 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
0431
0432 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
0433 info->topoff_threshold << 5);
0434
0435 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);
0436
0437 return 0;
0438 }
0439
0440 static int max8925_deinit_charger(struct max8925_power_info *info)
0441 {
0442 struct max8925_chip *chip = info->chip;
0443 int irq;
0444
0445 irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP;
0446 for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++)
0447 free_irq(irq, info);
0448
0449 return 0;
0450 }
0451
0452 #ifdef CONFIG_OF
0453 static struct max8925_power_pdata *
0454 max8925_power_dt_init(struct platform_device *pdev)
0455 {
0456 struct device_node *nproot = pdev->dev.parent->of_node;
0457 struct device_node *np;
0458 int batt_detect;
0459 int topoff_threshold;
0460 int fast_charge;
0461 int no_temp_support;
0462 int no_insert_detect;
0463 struct max8925_power_pdata *pdata;
0464
0465 if (!nproot)
0466 return pdev->dev.platform_data;
0467
0468 np = of_get_child_by_name(nproot, "charger");
0469 if (!np) {
0470 dev_err(&pdev->dev, "failed to find charger node\n");
0471 return NULL;
0472 }
0473
0474 pdata = devm_kzalloc(&pdev->dev,
0475 sizeof(struct max8925_power_pdata),
0476 GFP_KERNEL);
0477 if (!pdata)
0478 goto ret;
0479
0480 of_property_read_u32(np, "topoff-threshold", &topoff_threshold);
0481 of_property_read_u32(np, "batt-detect", &batt_detect);
0482 of_property_read_u32(np, "fast-charge", &fast_charge);
0483 of_property_read_u32(np, "no-insert-detect", &no_insert_detect);
0484 of_property_read_u32(np, "no-temp-support", &no_temp_support);
0485
0486 pdata->batt_detect = batt_detect;
0487 pdata->fast_charge = fast_charge;
0488 pdata->topoff_threshold = topoff_threshold;
0489 pdata->no_insert_detect = no_insert_detect;
0490 pdata->no_temp_support = no_temp_support;
0491
0492 ret:
0493 of_node_put(np);
0494 return pdata;
0495 }
0496 #else
0497 static struct max8925_power_pdata *
0498 max8925_power_dt_init(struct platform_device *pdev)
0499 {
0500 return pdev->dev.platform_data;
0501 }
0502 #endif
0503
0504 static int max8925_power_probe(struct platform_device *pdev)
0505 {
0506 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
0507 struct power_supply_config psy_cfg = {};
0508 struct max8925_power_pdata *pdata = NULL;
0509 struct max8925_power_info *info;
0510 int ret;
0511
0512 pdata = max8925_power_dt_init(pdev);
0513 if (!pdata) {
0514 dev_err(&pdev->dev, "platform data isn't assigned to "
0515 "power supply\n");
0516 return -EINVAL;
0517 }
0518
0519 info = devm_kzalloc(&pdev->dev, sizeof(struct max8925_power_info),
0520 GFP_KERNEL);
0521 if (!info)
0522 return -ENOMEM;
0523 info->chip = chip;
0524 info->gpm = chip->i2c;
0525 info->adc = chip->adc;
0526 platform_set_drvdata(pdev, info);
0527
0528 psy_cfg.supplied_to = pdata->supplied_to;
0529 psy_cfg.num_supplicants = pdata->num_supplicants;
0530
0531 info->ac = power_supply_register(&pdev->dev, &ac_desc, &psy_cfg);
0532 if (IS_ERR(info->ac)) {
0533 ret = PTR_ERR(info->ac);
0534 goto out;
0535 }
0536 info->ac->dev.parent = &pdev->dev;
0537
0538 info->usb = power_supply_register(&pdev->dev, &usb_desc, &psy_cfg);
0539 if (IS_ERR(info->usb)) {
0540 ret = PTR_ERR(info->usb);
0541 goto out_unregister_ac;
0542 }
0543 info->usb->dev.parent = &pdev->dev;
0544
0545 info->battery = power_supply_register(&pdev->dev, &battery_desc, NULL);
0546 if (IS_ERR(info->battery)) {
0547 ret = PTR_ERR(info->battery);
0548 goto out_unregister_usb;
0549 }
0550 info->battery->dev.parent = &pdev->dev;
0551
0552 info->batt_detect = pdata->batt_detect;
0553 info->topoff_threshold = pdata->topoff_threshold;
0554 info->fast_charge = pdata->fast_charge;
0555 info->set_charger = pdata->set_charger;
0556 info->no_temp_support = pdata->no_temp_support;
0557 info->no_insert_detect = pdata->no_insert_detect;
0558
0559 max8925_init_charger(chip, info);
0560 return 0;
0561 out_unregister_usb:
0562 power_supply_unregister(info->usb);
0563 out_unregister_ac:
0564 power_supply_unregister(info->ac);
0565 out:
0566 return ret;
0567 }
0568
0569 static int max8925_power_remove(struct platform_device *pdev)
0570 {
0571 struct max8925_power_info *info = platform_get_drvdata(pdev);
0572
0573 if (info) {
0574 power_supply_unregister(info->ac);
0575 power_supply_unregister(info->usb);
0576 power_supply_unregister(info->battery);
0577 max8925_deinit_charger(info);
0578 }
0579 return 0;
0580 }
0581
0582 static struct platform_driver max8925_power_driver = {
0583 .probe = max8925_power_probe,
0584 .remove = max8925_power_remove,
0585 .driver = {
0586 .name = "max8925-power",
0587 },
0588 };
0589
0590 module_platform_driver(max8925_power_driver);
0591
0592 MODULE_LICENSE("GPL");
0593 MODULE_DESCRIPTION("Power supply driver for MAX8925");
0594 MODULE_ALIAS("platform:max8925-power");