Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for LP8727 Micro/Mini USB IC with integrated charger
0004  *
0005  *          Copyright (C) 2011 Texas Instruments
0006  *          Copyright (C) 2011 National Semiconductor
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/slab.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/i2c.h>
0013 #include <linux/power_supply.h>
0014 #include <linux/platform_data/lp8727.h>
0015 #include <linux/of.h>
0016 
0017 #define LP8788_NUM_INTREGS  2
0018 #define DEFAULT_DEBOUNCE_MSEC   270
0019 
0020 /* Registers */
0021 #define LP8727_CTRL1        0x1
0022 #define LP8727_CTRL2        0x2
0023 #define LP8727_SWCTRL       0x3
0024 #define LP8727_INT1     0x4
0025 #define LP8727_INT2     0x5
0026 #define LP8727_STATUS1      0x6
0027 #define LP8727_STATUS2      0x7
0028 #define LP8727_CHGCTRL2     0x9
0029 
0030 /* CTRL1 register */
0031 #define LP8727_CP_EN        BIT(0)
0032 #define LP8727_ADC_EN       BIT(1)
0033 #define LP8727_ID200_EN     BIT(4)
0034 
0035 /* CTRL2 register */
0036 #define LP8727_CHGDET_EN    BIT(1)
0037 #define LP8727_INT_EN       BIT(6)
0038 
0039 /* SWCTRL register */
0040 #define LP8727_SW_DM1_DM    (0x0 << 0)
0041 #define LP8727_SW_DM1_HiZ   (0x7 << 0)
0042 #define LP8727_SW_DP2_DP    (0x0 << 3)
0043 #define LP8727_SW_DP2_HiZ   (0x7 << 3)
0044 
0045 /* INT1 register */
0046 #define LP8727_IDNO     (0xF << 0)
0047 #define LP8727_VBUS     BIT(4)
0048 
0049 /* STATUS1 register */
0050 #define LP8727_CHGSTAT      (3 << 4)
0051 #define LP8727_CHPORT       BIT(6)
0052 #define LP8727_DCPORT       BIT(7)
0053 #define LP8727_STAT_EOC     0x30
0054 
0055 /* STATUS2 register */
0056 #define LP8727_TEMP_STAT    (3 << 5)
0057 #define LP8727_TEMP_SHIFT   5
0058 
0059 /* CHGCTRL2 register */
0060 #define LP8727_ICHG_SHIFT   4
0061 
0062 enum lp8727_dev_id {
0063     LP8727_ID_NONE,
0064     LP8727_ID_TA,
0065     LP8727_ID_DEDICATED_CHG,
0066     LP8727_ID_USB_CHG,
0067     LP8727_ID_USB_DS,
0068     LP8727_ID_MAX,
0069 };
0070 
0071 enum lp8727_die_temp {
0072     LP8788_TEMP_75C,
0073     LP8788_TEMP_95C,
0074     LP8788_TEMP_115C,
0075     LP8788_TEMP_135C,
0076 };
0077 
0078 struct lp8727_psy {
0079     struct power_supply *ac;
0080     struct power_supply *usb;
0081     struct power_supply *batt;
0082 };
0083 
0084 struct lp8727_chg {
0085     struct device *dev;
0086     struct i2c_client *client;
0087     struct mutex xfer_lock;
0088     struct lp8727_psy *psy;
0089     struct lp8727_platform_data *pdata;
0090 
0091     /* Charger Data */
0092     enum lp8727_dev_id devid;
0093     struct lp8727_chg_param *chg_param;
0094 
0095     /* Interrupt Handling */
0096     int irq;
0097     struct delayed_work work;
0098     unsigned long debounce_jiffies;
0099 };
0100 
0101 static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
0102 {
0103     s32 ret;
0104 
0105     mutex_lock(&pchg->xfer_lock);
0106     ret = i2c_smbus_read_i2c_block_data(pchg->client, reg, len, data);
0107     mutex_unlock(&pchg->xfer_lock);
0108 
0109     return (ret != len) ? -EIO : 0;
0110 }
0111 
0112 static inline int lp8727_read_byte(struct lp8727_chg *pchg, u8 reg, u8 *data)
0113 {
0114     return lp8727_read_bytes(pchg, reg, data, 1);
0115 }
0116 
0117 static int lp8727_write_byte(struct lp8727_chg *pchg, u8 reg, u8 data)
0118 {
0119     int ret;
0120 
0121     mutex_lock(&pchg->xfer_lock);
0122     ret = i2c_smbus_write_byte_data(pchg->client, reg, data);
0123     mutex_unlock(&pchg->xfer_lock);
0124 
0125     return ret;
0126 }
0127 
0128 static bool lp8727_is_charger_attached(const char *name, int id)
0129 {
0130     if (!strcmp(name, "ac"))
0131         return id == LP8727_ID_TA || id == LP8727_ID_DEDICATED_CHG;
0132     else if (!strcmp(name, "usb"))
0133         return id == LP8727_ID_USB_CHG;
0134 
0135     return id >= LP8727_ID_TA && id <= LP8727_ID_USB_CHG;
0136 }
0137 
0138 static int lp8727_init_device(struct lp8727_chg *pchg)
0139 {
0140     u8 val;
0141     int ret;
0142     u8 intstat[LP8788_NUM_INTREGS];
0143 
0144     /* clear interrupts */
0145     ret = lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS);
0146     if (ret)
0147         return ret;
0148 
0149     val = LP8727_ID200_EN | LP8727_ADC_EN | LP8727_CP_EN;
0150     ret = lp8727_write_byte(pchg, LP8727_CTRL1, val);
0151     if (ret)
0152         return ret;
0153 
0154     val = LP8727_INT_EN | LP8727_CHGDET_EN;
0155     return lp8727_write_byte(pchg, LP8727_CTRL2, val);
0156 }
0157 
0158 static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg)
0159 {
0160     u8 val;
0161 
0162     lp8727_read_byte(pchg, LP8727_STATUS1, &val);
0163     return val & LP8727_DCPORT;
0164 }
0165 
0166 static int lp8727_is_usb_charger(struct lp8727_chg *pchg)
0167 {
0168     u8 val;
0169 
0170     lp8727_read_byte(pchg, LP8727_STATUS1, &val);
0171     return val & LP8727_CHPORT;
0172 }
0173 
0174 static inline void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
0175 {
0176     lp8727_write_byte(pchg, LP8727_SWCTRL, sw);
0177 }
0178 
0179 static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
0180 {
0181     struct lp8727_platform_data *pdata = pchg->pdata;
0182     u8 devid = LP8727_ID_NONE;
0183     u8 swctrl = LP8727_SW_DM1_HiZ | LP8727_SW_DP2_HiZ;
0184 
0185     switch (id) {
0186     case 0x5:
0187         devid = LP8727_ID_TA;
0188         pchg->chg_param = pdata ? pdata->ac : NULL;
0189         break;
0190     case 0xB:
0191         if (lp8727_is_dedicated_charger(pchg)) {
0192             pchg->chg_param = pdata ? pdata->ac : NULL;
0193             devid = LP8727_ID_DEDICATED_CHG;
0194         } else if (lp8727_is_usb_charger(pchg)) {
0195             pchg->chg_param = pdata ? pdata->usb : NULL;
0196             devid = LP8727_ID_USB_CHG;
0197             swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP;
0198         } else if (vbusin) {
0199             devid = LP8727_ID_USB_DS;
0200             swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP;
0201         }
0202         break;
0203     default:
0204         devid = LP8727_ID_NONE;
0205         pchg->chg_param = NULL;
0206         break;
0207     }
0208 
0209     pchg->devid = devid;
0210     lp8727_ctrl_switch(pchg, swctrl);
0211 }
0212 
0213 static void lp8727_enable_chgdet(struct lp8727_chg *pchg)
0214 {
0215     u8 val;
0216 
0217     lp8727_read_byte(pchg, LP8727_CTRL2, &val);
0218     val |= LP8727_CHGDET_EN;
0219     lp8727_write_byte(pchg, LP8727_CTRL2, val);
0220 }
0221 
0222 static void lp8727_delayed_func(struct work_struct *_work)
0223 {
0224     struct lp8727_chg *pchg = container_of(_work, struct lp8727_chg,
0225                         work.work);
0226     u8 intstat[LP8788_NUM_INTREGS];
0227     u8 idno;
0228     u8 vbus;
0229 
0230     if (lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS)) {
0231         dev_err(pchg->dev, "can not read INT registers\n");
0232         return;
0233     }
0234 
0235     idno = intstat[0] & LP8727_IDNO;
0236     vbus = intstat[0] & LP8727_VBUS;
0237 
0238     lp8727_id_detection(pchg, idno, vbus);
0239     lp8727_enable_chgdet(pchg);
0240 
0241     power_supply_changed(pchg->psy->ac);
0242     power_supply_changed(pchg->psy->usb);
0243     power_supply_changed(pchg->psy->batt);
0244 }
0245 
0246 static irqreturn_t lp8727_isr_func(int irq, void *ptr)
0247 {
0248     struct lp8727_chg *pchg = ptr;
0249 
0250     schedule_delayed_work(&pchg->work, pchg->debounce_jiffies);
0251     return IRQ_HANDLED;
0252 }
0253 
0254 static int lp8727_setup_irq(struct lp8727_chg *pchg)
0255 {
0256     int ret;
0257     int irq = pchg->client->irq;
0258     unsigned delay_msec = pchg->pdata ? pchg->pdata->debounce_msec :
0259                         DEFAULT_DEBOUNCE_MSEC;
0260 
0261     INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func);
0262 
0263     if (irq <= 0) {
0264         dev_warn(pchg->dev, "invalid irq number: %d\n", irq);
0265         return 0;
0266     }
0267 
0268     ret = request_threaded_irq(irq, NULL, lp8727_isr_func,
0269                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0270                 "lp8727_irq", pchg);
0271 
0272     if (ret)
0273         return ret;
0274 
0275     pchg->irq = irq;
0276     pchg->debounce_jiffies = msecs_to_jiffies(delay_msec);
0277 
0278     return 0;
0279 }
0280 
0281 static void lp8727_release_irq(struct lp8727_chg *pchg)
0282 {
0283     cancel_delayed_work_sync(&pchg->work);
0284 
0285     if (pchg->irq)
0286         free_irq(pchg->irq, pchg);
0287 }
0288 
0289 static enum power_supply_property lp8727_charger_prop[] = {
0290     POWER_SUPPLY_PROP_ONLINE,
0291 };
0292 
0293 static enum power_supply_property lp8727_battery_prop[] = {
0294     POWER_SUPPLY_PROP_STATUS,
0295     POWER_SUPPLY_PROP_HEALTH,
0296     POWER_SUPPLY_PROP_PRESENT,
0297     POWER_SUPPLY_PROP_VOLTAGE_NOW,
0298     POWER_SUPPLY_PROP_CAPACITY,
0299     POWER_SUPPLY_PROP_TEMP,
0300 };
0301 
0302 static char *battery_supplied_to[] = {
0303     "main_batt",
0304 };
0305 
0306 static int lp8727_charger_get_property(struct power_supply *psy,
0307                        enum power_supply_property psp,
0308                        union power_supply_propval *val)
0309 {
0310     struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent);
0311 
0312     if (psp != POWER_SUPPLY_PROP_ONLINE)
0313         return -EINVAL;
0314 
0315     val->intval = lp8727_is_charger_attached(psy->desc->name, pchg->devid);
0316 
0317     return 0;
0318 }
0319 
0320 static bool lp8727_is_high_temperature(enum lp8727_die_temp temp)
0321 {
0322     switch (temp) {
0323     case LP8788_TEMP_95C:
0324     case LP8788_TEMP_115C:
0325     case LP8788_TEMP_135C:
0326         return true;
0327     default:
0328         return false;
0329     }
0330 }
0331 
0332 static int lp8727_battery_get_property(struct power_supply *psy,
0333                        enum power_supply_property psp,
0334                        union power_supply_propval *val)
0335 {
0336     struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent);
0337     struct lp8727_platform_data *pdata = pchg->pdata;
0338     enum lp8727_die_temp temp;
0339     u8 read;
0340 
0341     switch (psp) {
0342     case POWER_SUPPLY_PROP_STATUS:
0343         if (!lp8727_is_charger_attached(psy->desc->name, pchg->devid)) {
0344             val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
0345             return 0;
0346         }
0347 
0348         lp8727_read_byte(pchg, LP8727_STATUS1, &read);
0349 
0350         val->intval = (read & LP8727_CHGSTAT) == LP8727_STAT_EOC ?
0351                 POWER_SUPPLY_STATUS_FULL :
0352                 POWER_SUPPLY_STATUS_CHARGING;
0353         break;
0354     case POWER_SUPPLY_PROP_HEALTH:
0355         lp8727_read_byte(pchg, LP8727_STATUS2, &read);
0356         temp = (read & LP8727_TEMP_STAT) >> LP8727_TEMP_SHIFT;
0357 
0358         val->intval = lp8727_is_high_temperature(temp) ?
0359             POWER_SUPPLY_HEALTH_OVERHEAT :
0360             POWER_SUPPLY_HEALTH_GOOD;
0361         break;
0362     case POWER_SUPPLY_PROP_PRESENT:
0363         if (!pdata)
0364             return -EINVAL;
0365 
0366         if (pdata->get_batt_present)
0367             val->intval = pdata->get_batt_present();
0368         break;
0369     case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0370         if (!pdata)
0371             return -EINVAL;
0372 
0373         if (pdata->get_batt_level)
0374             val->intval = pdata->get_batt_level();
0375         break;
0376     case POWER_SUPPLY_PROP_CAPACITY:
0377         if (!pdata)
0378             return -EINVAL;
0379 
0380         if (pdata->get_batt_capacity)
0381             val->intval = pdata->get_batt_capacity();
0382         break;
0383     case POWER_SUPPLY_PROP_TEMP:
0384         if (!pdata)
0385             return -EINVAL;
0386 
0387         if (pdata->get_batt_temp)
0388             val->intval = pdata->get_batt_temp();
0389         break;
0390     default:
0391         break;
0392     }
0393 
0394     return 0;
0395 }
0396 
0397 static void lp8727_charger_changed(struct power_supply *psy)
0398 {
0399     struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent);
0400     u8 eoc_level;
0401     u8 ichg;
0402     u8 val;
0403 
0404     /* skip if no charger exists */
0405     if (!lp8727_is_charger_attached(psy->desc->name, pchg->devid))
0406         return;
0407 
0408     /* update charging parameters */
0409     if (pchg->chg_param) {
0410         eoc_level = pchg->chg_param->eoc_level;
0411         ichg = pchg->chg_param->ichg;
0412         val = (ichg << LP8727_ICHG_SHIFT) | eoc_level;
0413         lp8727_write_byte(pchg, LP8727_CHGCTRL2, val);
0414     }
0415 }
0416 
0417 static const struct power_supply_desc lp8727_ac_desc = {
0418     .name           = "ac",
0419     .type           = POWER_SUPPLY_TYPE_MAINS,
0420     .properties     = lp8727_charger_prop,
0421     .num_properties     = ARRAY_SIZE(lp8727_charger_prop),
0422     .get_property       = lp8727_charger_get_property,
0423 };
0424 
0425 static const struct power_supply_desc lp8727_usb_desc = {
0426     .name           = "usb",
0427     .type           = POWER_SUPPLY_TYPE_USB,
0428     .properties     = lp8727_charger_prop,
0429     .num_properties     = ARRAY_SIZE(lp8727_charger_prop),
0430     .get_property       = lp8727_charger_get_property,
0431 };
0432 
0433 static const struct power_supply_desc lp8727_batt_desc = {
0434     .name           = "main_batt",
0435     .type           = POWER_SUPPLY_TYPE_BATTERY,
0436     .properties     = lp8727_battery_prop,
0437     .num_properties     = ARRAY_SIZE(lp8727_battery_prop),
0438     .get_property       = lp8727_battery_get_property,
0439     .external_power_changed = lp8727_charger_changed,
0440 };
0441 
0442 static int lp8727_register_psy(struct lp8727_chg *pchg)
0443 {
0444     struct power_supply_config psy_cfg = {}; /* Only for ac and usb */
0445     struct lp8727_psy *psy;
0446 
0447     psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL);
0448     if (!psy)
0449         return -ENOMEM;
0450 
0451     pchg->psy = psy;
0452 
0453     psy_cfg.supplied_to = battery_supplied_to;
0454     psy_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to);
0455 
0456     psy->ac = power_supply_register(pchg->dev, &lp8727_ac_desc, &psy_cfg);
0457     if (IS_ERR(psy->ac))
0458         goto err_psy_ac;
0459 
0460     psy->usb = power_supply_register(pchg->dev, &lp8727_usb_desc,
0461                      &psy_cfg);
0462     if (IS_ERR(psy->usb))
0463         goto err_psy_usb;
0464 
0465     psy->batt = power_supply_register(pchg->dev, &lp8727_batt_desc, NULL);
0466     if (IS_ERR(psy->batt))
0467         goto err_psy_batt;
0468 
0469     return 0;
0470 
0471 err_psy_batt:
0472     power_supply_unregister(psy->usb);
0473 err_psy_usb:
0474     power_supply_unregister(psy->ac);
0475 err_psy_ac:
0476     return -EPERM;
0477 }
0478 
0479 static void lp8727_unregister_psy(struct lp8727_chg *pchg)
0480 {
0481     struct lp8727_psy *psy = pchg->psy;
0482 
0483     if (!psy)
0484         return;
0485 
0486     power_supply_unregister(psy->ac);
0487     power_supply_unregister(psy->usb);
0488     power_supply_unregister(psy->batt);
0489 }
0490 
0491 #ifdef CONFIG_OF
0492 static struct lp8727_chg_param
0493 *lp8727_parse_charge_pdata(struct device *dev, struct device_node *np)
0494 {
0495     struct lp8727_chg_param *param;
0496 
0497     param = devm_kzalloc(dev, sizeof(*param), GFP_KERNEL);
0498     if (!param)
0499         goto out;
0500 
0501     of_property_read_u8(np, "eoc-level", (u8 *)&param->eoc_level);
0502     of_property_read_u8(np, "charging-current", (u8 *)&param->ichg);
0503 out:
0504     return param;
0505 }
0506 
0507 static struct lp8727_platform_data *lp8727_parse_dt(struct device *dev)
0508 {
0509     struct device_node *np = dev->of_node;
0510     struct device_node *child;
0511     struct lp8727_platform_data *pdata;
0512     const char *type;
0513 
0514     pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
0515     if (!pdata)
0516         return ERR_PTR(-ENOMEM);
0517 
0518     of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec);
0519 
0520     /* If charging parameter is not defined, just skip parsing the dt */
0521     if (of_get_child_count(np) == 0)
0522         return pdata;
0523 
0524     for_each_child_of_node(np, child) {
0525         of_property_read_string(child, "charger-type", &type);
0526 
0527         if (!strcmp(type, "ac"))
0528             pdata->ac = lp8727_parse_charge_pdata(dev, child);
0529 
0530         if (!strcmp(type, "usb"))
0531             pdata->usb = lp8727_parse_charge_pdata(dev, child);
0532     }
0533 
0534     return pdata;
0535 }
0536 #else
0537 static struct lp8727_platform_data *lp8727_parse_dt(struct device *dev)
0538 {
0539     return NULL;
0540 }
0541 #endif
0542 
0543 static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
0544 {
0545     struct lp8727_chg *pchg;
0546     struct lp8727_platform_data *pdata;
0547     int ret;
0548 
0549     if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
0550         return -EIO;
0551 
0552     if (cl->dev.of_node) {
0553         pdata = lp8727_parse_dt(&cl->dev);
0554         if (IS_ERR(pdata))
0555             return PTR_ERR(pdata);
0556     } else {
0557         pdata = dev_get_platdata(&cl->dev);
0558     }
0559 
0560     pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL);
0561     if (!pchg)
0562         return -ENOMEM;
0563 
0564     pchg->client = cl;
0565     pchg->dev = &cl->dev;
0566     pchg->pdata = pdata;
0567     i2c_set_clientdata(cl, pchg);
0568 
0569     mutex_init(&pchg->xfer_lock);
0570 
0571     ret = lp8727_init_device(pchg);
0572     if (ret) {
0573         dev_err(pchg->dev, "i2c communication err: %d", ret);
0574         return ret;
0575     }
0576 
0577     ret = lp8727_register_psy(pchg);
0578     if (ret) {
0579         dev_err(pchg->dev, "power supplies register err: %d", ret);
0580         return ret;
0581     }
0582 
0583     ret = lp8727_setup_irq(pchg);
0584     if (ret) {
0585         dev_err(pchg->dev, "irq handler err: %d", ret);
0586         lp8727_unregister_psy(pchg);
0587         return ret;
0588     }
0589 
0590     return 0;
0591 }
0592 
0593 static int lp8727_remove(struct i2c_client *cl)
0594 {
0595     struct lp8727_chg *pchg = i2c_get_clientdata(cl);
0596 
0597     lp8727_release_irq(pchg);
0598     lp8727_unregister_psy(pchg);
0599     return 0;
0600 }
0601 
0602 static const struct of_device_id lp8727_dt_ids[] = {
0603     { .compatible = "ti,lp8727", },
0604     { }
0605 };
0606 MODULE_DEVICE_TABLE(of, lp8727_dt_ids);
0607 
0608 static const struct i2c_device_id lp8727_ids[] = {
0609     {"lp8727", 0},
0610     { }
0611 };
0612 MODULE_DEVICE_TABLE(i2c, lp8727_ids);
0613 
0614 static struct i2c_driver lp8727_driver = {
0615     .driver = {
0616            .name = "lp8727",
0617            .of_match_table = of_match_ptr(lp8727_dt_ids),
0618            },
0619     .probe = lp8727_probe,
0620     .remove = lp8727_remove,
0621     .id_table = lp8727_ids,
0622 };
0623 module_i2c_driver(lp8727_driver);
0624 
0625 MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver");
0626 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>");
0627 MODULE_LICENSE("GPL");