Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2018 Spreadtrum Communications Inc.
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 /* PMIC global registers definition */
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 /* SC2731 switch charger registers definition */
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 /* SC2731_CHG_CFG0 register definition */
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 /* SC2731_CHG_CFG1 register definition */
0040 #define SC2731_CUR_MASK         GENMASK(5, 0)
0041 
0042 /* SC2731_CHG_CFG5 register definition */
0043 #define SC2731_CUR_LIMIT_SHIFT      8
0044 #define SC2731_CUR_LIMIT_MASK       GENMASK(9, 8)
0045 
0046 /* Default current definition (unit is mA) */
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     /* Enable charger constant current mode */
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     /* Start charging */
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     /* Calculate the step value, each step is 50 mA */
0121     val = (cur - SC2731_CURRENT_PRECHG) / SC2731_CURRENT_STEP;
0122 
0123     /* Set pre-charge current as 450 mA */
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         /* set current limitation and start to charge */
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         /* Stop charging */
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     /* Enable charger module */
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          * If no battery information is supplied, we should set
0387          * default charge termination current to 120 mA, and default
0388          * charge termination voltage to 4.35V.
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     /* Set charge termination current */
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     /* Set charge termination voltage */
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      * If the USB charger status has been USB_CHARGER_PRESENT before
0443      * registering the notifier, we should start to charge with getting
0444      * the charge current.
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");