0001
0002
0003
0004 #include <linux/module.h>
0005 #include <linux/platform_device.h>
0006 #include <linux/power_supply.h>
0007 #include <linux/usb/phy.h>
0008 #include <linux/regmap.h>
0009 #include <linux/notifier.h>
0010 #include <linux/of.h>
0011
0012
0013 #define SC2731_CHARGE_STATUS 0xedc
0014 #define SC2731_CHARGE_FULL BIT(4)
0015 #define SC2731_MODULE_EN1 0xc0c
0016 #define SC2731_CHARGE_EN BIT(5)
0017
0018
0019 #define SC2731_CHG_CFG0 0x0
0020 #define SC2731_CHG_CFG1 0x4
0021 #define SC2731_CHG_CFG2 0x8
0022 #define SC2731_CHG_CFG3 0xc
0023 #define SC2731_CHG_CFG4 0x10
0024 #define SC2731_CHG_CFG5 0x28
0025
0026
0027 #define SC2731_PRECHG_RNG_SHIFT 11
0028 #define SC2731_PRECHG_RNG_MASK GENMASK(12, 11)
0029
0030 #define SC2731_TERMINATION_VOL_MASK GENMASK(2, 1)
0031 #define SC2731_TERMINATION_VOL_SHIFT 1
0032 #define SC2731_TERMINATION_VOL_CAL_MASK GENMASK(8, 3)
0033 #define SC2731_TERMINATION_VOL_CAL_SHIFT 3
0034 #define SC2731_TERMINATION_CUR_MASK GENMASK(2, 0)
0035
0036 #define SC2731_CC_EN BIT(13)
0037 #define SC2731_CHARGER_PD BIT(0)
0038
0039
0040 #define SC2731_CUR_MASK GENMASK(5, 0)
0041
0042
0043 #define SC2731_CUR_LIMIT_SHIFT 8
0044 #define SC2731_CUR_LIMIT_MASK GENMASK(9, 8)
0045
0046
0047 #define SC2731_CURRENT_LIMIT_100 100
0048 #define SC2731_CURRENT_LIMIT_500 500
0049 #define SC2731_CURRENT_LIMIT_900 900
0050 #define SC2731_CURRENT_LIMIT_2000 2000
0051 #define SC2731_CURRENT_PRECHG 450
0052 #define SC2731_CURRENT_STEP 50
0053
0054 struct sc2731_charger_info {
0055 struct device *dev;
0056 struct regmap *regmap;
0057 struct usb_phy *usb_phy;
0058 struct notifier_block usb_notify;
0059 struct power_supply *psy_usb;
0060 struct work_struct work;
0061 struct mutex lock;
0062 bool charging;
0063 u32 base;
0064 u32 limit;
0065 };
0066
0067 static void sc2731_charger_stop_charge(struct sc2731_charger_info *info)
0068 {
0069 regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0070 SC2731_CC_EN, 0);
0071
0072 regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0073 SC2731_CHARGER_PD, SC2731_CHARGER_PD);
0074 }
0075
0076 static int sc2731_charger_start_charge(struct sc2731_charger_info *info)
0077 {
0078 int ret;
0079
0080
0081 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0082 SC2731_CC_EN, SC2731_CC_EN);
0083 if (ret)
0084 return ret;
0085
0086
0087 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0088 SC2731_CHARGER_PD, 0);
0089 }
0090
0091 static int sc2731_charger_set_current_limit(struct sc2731_charger_info *info,
0092 u32 limit)
0093 {
0094 u32 val;
0095
0096 if (limit <= SC2731_CURRENT_LIMIT_100)
0097 val = 0;
0098 else if (limit <= SC2731_CURRENT_LIMIT_500)
0099 val = 3;
0100 else if (limit <= SC2731_CURRENT_LIMIT_900)
0101 val = 2;
0102 else
0103 val = 1;
0104
0105 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG5,
0106 SC2731_CUR_LIMIT_MASK,
0107 val << SC2731_CUR_LIMIT_SHIFT);
0108 }
0109
0110 static int sc2731_charger_set_current(struct sc2731_charger_info *info, u32 cur)
0111 {
0112 u32 val;
0113 int ret;
0114
0115 if (cur > SC2731_CURRENT_LIMIT_2000)
0116 cur = SC2731_CURRENT_LIMIT_2000;
0117 else if (cur < SC2731_CURRENT_PRECHG)
0118 cur = SC2731_CURRENT_PRECHG;
0119
0120
0121 val = (cur - SC2731_CURRENT_PRECHG) / SC2731_CURRENT_STEP;
0122
0123
0124 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0125 SC2731_PRECHG_RNG_MASK,
0126 0x3 << SC2731_PRECHG_RNG_SHIFT);
0127 if (ret)
0128 return ret;
0129
0130 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG1,
0131 SC2731_CUR_MASK, val);
0132 }
0133
0134 static int sc2731_charger_get_status(struct sc2731_charger_info *info)
0135 {
0136 u32 val;
0137 int ret;
0138
0139 ret = regmap_read(info->regmap, SC2731_CHARGE_STATUS, &val);
0140 if (ret)
0141 return ret;
0142
0143 if (val & SC2731_CHARGE_FULL)
0144 return POWER_SUPPLY_STATUS_FULL;
0145
0146 return POWER_SUPPLY_STATUS_CHARGING;
0147 }
0148
0149 static int sc2731_charger_get_current(struct sc2731_charger_info *info,
0150 u32 *cur)
0151 {
0152 int ret;
0153 u32 val;
0154
0155 ret = regmap_read(info->regmap, info->base + SC2731_CHG_CFG1, &val);
0156 if (ret)
0157 return ret;
0158
0159 val &= SC2731_CUR_MASK;
0160 *cur = val * SC2731_CURRENT_STEP + SC2731_CURRENT_PRECHG;
0161
0162 return 0;
0163 }
0164
0165 static int sc2731_charger_get_current_limit(struct sc2731_charger_info *info,
0166 u32 *cur)
0167 {
0168 int ret;
0169 u32 val;
0170
0171 ret = regmap_read(info->regmap, info->base + SC2731_CHG_CFG5, &val);
0172 if (ret)
0173 return ret;
0174
0175 val = (val & SC2731_CUR_LIMIT_MASK) >> SC2731_CUR_LIMIT_SHIFT;
0176
0177 switch (val) {
0178 case 0:
0179 *cur = SC2731_CURRENT_LIMIT_100;
0180 break;
0181
0182 case 1:
0183 *cur = SC2731_CURRENT_LIMIT_2000;
0184 break;
0185
0186 case 2:
0187 *cur = SC2731_CURRENT_LIMIT_900;
0188 break;
0189
0190 case 3:
0191 *cur = SC2731_CURRENT_LIMIT_500;
0192 break;
0193
0194 default:
0195 return -EINVAL;
0196 }
0197
0198 return 0;
0199 }
0200
0201 static int
0202 sc2731_charger_usb_set_property(struct power_supply *psy,
0203 enum power_supply_property psp,
0204 const union power_supply_propval *val)
0205 {
0206 struct sc2731_charger_info *info = power_supply_get_drvdata(psy);
0207 int ret;
0208
0209 mutex_lock(&info->lock);
0210
0211 if (!info->charging) {
0212 mutex_unlock(&info->lock);
0213 return -ENODEV;
0214 }
0215
0216 switch (psp) {
0217 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0218 ret = sc2731_charger_set_current(info, val->intval / 1000);
0219 if (ret < 0)
0220 dev_err(info->dev, "set charge current failed\n");
0221 break;
0222
0223 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0224 ret = sc2731_charger_set_current_limit(info,
0225 val->intval / 1000);
0226 if (ret < 0)
0227 dev_err(info->dev, "set input current limit failed\n");
0228 break;
0229
0230 default:
0231 ret = -EINVAL;
0232 }
0233
0234 mutex_unlock(&info->lock);
0235 return ret;
0236 }
0237
0238 static int sc2731_charger_usb_get_property(struct power_supply *psy,
0239 enum power_supply_property psp,
0240 union power_supply_propval *val)
0241 {
0242 struct sc2731_charger_info *info = power_supply_get_drvdata(psy);
0243 int ret = 0;
0244 u32 cur;
0245
0246 mutex_lock(&info->lock);
0247
0248 switch (psp) {
0249 case POWER_SUPPLY_PROP_STATUS:
0250 if (info->charging)
0251 val->intval = sc2731_charger_get_status(info);
0252 else
0253 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
0254 break;
0255
0256 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0257 if (!info->charging) {
0258 val->intval = 0;
0259 } else {
0260 ret = sc2731_charger_get_current(info, &cur);
0261 if (ret)
0262 goto out;
0263
0264 val->intval = cur * 1000;
0265 }
0266 break;
0267
0268 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0269 if (!info->charging) {
0270 val->intval = 0;
0271 } else {
0272 ret = sc2731_charger_get_current_limit(info, &cur);
0273 if (ret)
0274 goto out;
0275
0276 val->intval = cur * 1000;
0277 }
0278 break;
0279
0280 default:
0281 ret = -EINVAL;
0282 }
0283
0284 out:
0285 mutex_unlock(&info->lock);
0286 return ret;
0287 }
0288
0289 static int sc2731_charger_property_is_writeable(struct power_supply *psy,
0290 enum power_supply_property psp)
0291 {
0292 int ret;
0293
0294 switch (psp) {
0295 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0296 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0297 ret = 1;
0298 break;
0299
0300 default:
0301 ret = 0;
0302 }
0303
0304 return ret;
0305 }
0306
0307 static enum power_supply_property sc2731_usb_props[] = {
0308 POWER_SUPPLY_PROP_STATUS,
0309 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
0310 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
0311 };
0312
0313 static const struct power_supply_desc sc2731_charger_desc = {
0314 .name = "sc2731_charger",
0315 .type = POWER_SUPPLY_TYPE_USB,
0316 .properties = sc2731_usb_props,
0317 .num_properties = ARRAY_SIZE(sc2731_usb_props),
0318 .get_property = sc2731_charger_usb_get_property,
0319 .set_property = sc2731_charger_usb_set_property,
0320 .property_is_writeable = sc2731_charger_property_is_writeable,
0321 };
0322
0323 static void sc2731_charger_work(struct work_struct *data)
0324 {
0325 struct sc2731_charger_info *info =
0326 container_of(data, struct sc2731_charger_info, work);
0327 int ret;
0328
0329 mutex_lock(&info->lock);
0330
0331 if (info->limit > 0 && !info->charging) {
0332
0333 ret = sc2731_charger_set_current_limit(info, info->limit);
0334 if (ret)
0335 goto out;
0336
0337 ret = sc2731_charger_set_current(info, info->limit);
0338 if (ret)
0339 goto out;
0340
0341 ret = sc2731_charger_start_charge(info);
0342 if (ret)
0343 goto out;
0344
0345 info->charging = true;
0346 } else if (!info->limit && info->charging) {
0347
0348 info->charging = false;
0349 sc2731_charger_stop_charge(info);
0350 }
0351
0352 out:
0353 mutex_unlock(&info->lock);
0354 }
0355
0356 static int sc2731_charger_usb_change(struct notifier_block *nb,
0357 unsigned long limit, void *data)
0358 {
0359 struct sc2731_charger_info *info =
0360 container_of(nb, struct sc2731_charger_info, usb_notify);
0361
0362 info->limit = limit;
0363
0364 schedule_work(&info->work);
0365
0366 return NOTIFY_OK;
0367 }
0368
0369 static int sc2731_charger_hw_init(struct sc2731_charger_info *info)
0370 {
0371 struct power_supply_battery_info *bat_info;
0372 u32 term_currrent, term_voltage, cur_val, vol_val;
0373 int ret;
0374
0375
0376 ret = regmap_update_bits(info->regmap, SC2731_MODULE_EN1,
0377 SC2731_CHARGE_EN, SC2731_CHARGE_EN);
0378 if (ret)
0379 return ret;
0380
0381 ret = power_supply_get_battery_info(info->psy_usb, &bat_info);
0382 if (ret) {
0383 dev_warn(info->dev, "no battery information is supplied\n");
0384
0385
0386
0387
0388
0389
0390 cur_val = 0x2;
0391 vol_val = 0x1;
0392 } else {
0393 term_currrent = bat_info->charge_term_current_ua / 1000;
0394
0395 if (term_currrent <= 90)
0396 cur_val = 0;
0397 else if (term_currrent >= 265)
0398 cur_val = 0x7;
0399 else
0400 cur_val = ((term_currrent - 90) / 25) + 1;
0401
0402 term_voltage = bat_info->constant_charge_voltage_max_uv / 1000;
0403
0404 if (term_voltage > 4500)
0405 term_voltage = 4500;
0406
0407 if (term_voltage > 4200)
0408 vol_val = (term_voltage - 4200) / 100;
0409 else
0410 vol_val = 0;
0411
0412 power_supply_put_battery_info(info->psy_usb, bat_info);
0413 }
0414
0415
0416 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG2,
0417 SC2731_TERMINATION_CUR_MASK, cur_val);
0418 if (ret)
0419 goto error;
0420
0421
0422 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
0423 SC2731_TERMINATION_VOL_MASK |
0424 SC2731_TERMINATION_VOL_CAL_MASK,
0425 (vol_val << SC2731_TERMINATION_VOL_SHIFT) |
0426 (0x6 << SC2731_TERMINATION_VOL_CAL_SHIFT));
0427 if (ret)
0428 goto error;
0429
0430 return 0;
0431
0432 error:
0433 regmap_update_bits(info->regmap, SC2731_MODULE_EN1, SC2731_CHARGE_EN, 0);
0434 return ret;
0435 }
0436
0437 static void sc2731_charger_detect_status(struct sc2731_charger_info *info)
0438 {
0439 unsigned int min, max;
0440
0441
0442
0443
0444
0445
0446 if (info->usb_phy->chg_state != USB_CHARGER_PRESENT)
0447 return;
0448
0449 usb_phy_get_charger_current(info->usb_phy, &min, &max);
0450 info->limit = min;
0451
0452 schedule_work(&info->work);
0453 }
0454
0455 static int sc2731_charger_probe(struct platform_device *pdev)
0456 {
0457 struct device_node *np = pdev->dev.of_node;
0458 struct sc2731_charger_info *info;
0459 struct power_supply_config charger_cfg = { };
0460 int ret;
0461
0462 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0463 if (!info)
0464 return -ENOMEM;
0465
0466 mutex_init(&info->lock);
0467 info->dev = &pdev->dev;
0468 INIT_WORK(&info->work, sc2731_charger_work);
0469
0470 info->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0471 if (!info->regmap) {
0472 dev_err(&pdev->dev, "failed to get charger regmap\n");
0473 return -ENODEV;
0474 }
0475
0476 ret = of_property_read_u32(np, "reg", &info->base);
0477 if (ret) {
0478 dev_err(&pdev->dev, "failed to get register address\n");
0479 return -ENODEV;
0480 }
0481
0482 charger_cfg.drv_data = info;
0483 charger_cfg.of_node = np;
0484 info->psy_usb = devm_power_supply_register(&pdev->dev,
0485 &sc2731_charger_desc,
0486 &charger_cfg);
0487 if (IS_ERR(info->psy_usb)) {
0488 dev_err(&pdev->dev, "failed to register power supply\n");
0489 return PTR_ERR(info->psy_usb);
0490 }
0491
0492 ret = sc2731_charger_hw_init(info);
0493 if (ret)
0494 return ret;
0495
0496 info->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "phys", 0);
0497 if (IS_ERR(info->usb_phy)) {
0498 dev_err(&pdev->dev, "failed to find USB phy\n");
0499 return PTR_ERR(info->usb_phy);
0500 }
0501
0502 info->usb_notify.notifier_call = sc2731_charger_usb_change;
0503 ret = usb_register_notifier(info->usb_phy, &info->usb_notify);
0504 if (ret) {
0505 dev_err(&pdev->dev, "failed to register notifier: %d\n", ret);
0506 return ret;
0507 }
0508
0509 sc2731_charger_detect_status(info);
0510
0511 return 0;
0512 }
0513
0514 static int sc2731_charger_remove(struct platform_device *pdev)
0515 {
0516 struct sc2731_charger_info *info = platform_get_drvdata(pdev);
0517
0518 usb_unregister_notifier(info->usb_phy, &info->usb_notify);
0519
0520 return 0;
0521 }
0522
0523 static const struct of_device_id sc2731_charger_of_match[] = {
0524 { .compatible = "sprd,sc2731-charger", },
0525 { }
0526 };
0527 MODULE_DEVICE_TABLE(of, sc2731_charger_of_match);
0528
0529 static struct platform_driver sc2731_charger_driver = {
0530 .driver = {
0531 .name = "sc2731-charger",
0532 .of_match_table = sc2731_charger_of_match,
0533 },
0534 .probe = sc2731_charger_probe,
0535 .remove = sc2731_charger_remove,
0536 };
0537
0538 module_platform_driver(sc2731_charger_driver);
0539
0540 MODULE_DESCRIPTION("Spreadtrum SC2731 Charger Driver");
0541 MODULE_LICENSE("GPL v2");