0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/slab.h>
0011 #include <linux/init.h>
0012 #include <linux/types.h>
0013 #include <linux/device.h>
0014 #include <linux/workqueue.h>
0015 #include <linux/module.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/power_supply.h>
0018 #include <linux/mfd/da903x.h>
0019
0020 #include <linux/debugfs.h>
0021 #include <linux/seq_file.h>
0022 #include <linux/notifier.h>
0023
0024 #define DA9030_FAULT_LOG 0x0a
0025 #define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
0026 #define DA9030_FAULT_LOG_VBAT_OVER (1 << 4)
0027
0028 #define DA9030_CHARGE_CONTROL 0x28
0029 #define DA9030_CHRG_CHARGER_ENABLE (1 << 7)
0030
0031 #define DA9030_ADC_MAN_CONTROL 0x30
0032 #define DA9030_ADC_TBATREF_ENABLE (1 << 5)
0033 #define DA9030_ADC_LDO_INT_ENABLE (1 << 4)
0034
0035 #define DA9030_ADC_AUTO_CONTROL 0x31
0036 #define DA9030_ADC_TBAT_ENABLE (1 << 5)
0037 #define DA9030_ADC_VBAT_IN_TXON (1 << 4)
0038 #define DA9030_ADC_VCH_ENABLE (1 << 3)
0039 #define DA9030_ADC_ICH_ENABLE (1 << 2)
0040 #define DA9030_ADC_VBAT_ENABLE (1 << 1)
0041 #define DA9030_ADC_AUTO_SLEEP_ENABLE (1 << 0)
0042
0043 #define DA9030_VBATMON 0x32
0044 #define DA9030_VBATMONTXON 0x33
0045 #define DA9030_TBATHIGHP 0x34
0046 #define DA9030_TBATHIGHN 0x35
0047 #define DA9030_TBATLOW 0x36
0048
0049 #define DA9030_VBAT_RES 0x41
0050 #define DA9030_VBATMIN_RES 0x42
0051 #define DA9030_VBATMINTXON_RES 0x43
0052 #define DA9030_ICHMAX_RES 0x44
0053 #define DA9030_ICHMIN_RES 0x45
0054 #define DA9030_ICHAVERAGE_RES 0x46
0055 #define DA9030_VCHMAX_RES 0x47
0056 #define DA9030_VCHMIN_RES 0x48
0057 #define DA9030_TBAT_RES 0x49
0058
0059 struct da9030_adc_res {
0060 uint8_t vbat_res;
0061 uint8_t vbatmin_res;
0062 uint8_t vbatmintxon;
0063 uint8_t ichmax_res;
0064 uint8_t ichmin_res;
0065 uint8_t ichaverage_res;
0066 uint8_t vchmax_res;
0067 uint8_t vchmin_res;
0068 uint8_t tbat_res;
0069 uint8_t adc_in4_res;
0070 uint8_t adc_in5_res;
0071 };
0072
0073 struct da9030_battery_thresholds {
0074 int tbat_low;
0075 int tbat_high;
0076 int tbat_restart;
0077
0078 int vbat_low;
0079 int vbat_crit;
0080 int vbat_charge_start;
0081 int vbat_charge_stop;
0082 int vbat_charge_restart;
0083
0084 int vcharge_min;
0085 int vcharge_max;
0086 };
0087
0088 struct da9030_charger {
0089 struct power_supply *psy;
0090 struct power_supply_desc psy_desc;
0091
0092 struct device *master;
0093
0094 struct da9030_adc_res adc;
0095 struct delayed_work work;
0096 unsigned int interval;
0097
0098 struct power_supply_info *battery_info;
0099
0100 struct da9030_battery_thresholds thresholds;
0101
0102 unsigned int charge_milliamp;
0103 unsigned int charge_millivolt;
0104
0105
0106 bool chdet;
0107 uint8_t fault;
0108 int mA;
0109 int mV;
0110 bool is_on;
0111
0112 struct notifier_block nb;
0113
0114
0115 void (*battery_low)(void);
0116 void (*battery_critical)(void);
0117
0118 struct dentry *debug_file;
0119 };
0120
0121 static inline int da9030_reg_to_mV(int reg)
0122 {
0123 return ((reg * 2650) >> 8) + 2650;
0124 }
0125
0126 static inline int da9030_millivolt_to_reg(int mV)
0127 {
0128 return ((mV - 2650) << 8) / 2650;
0129 }
0130
0131 static inline int da9030_reg_to_mA(int reg)
0132 {
0133 return ((reg * 24000) >> 8) / 15;
0134 }
0135
0136 #ifdef CONFIG_DEBUG_FS
0137 static int bat_debug_show(struct seq_file *s, void *data)
0138 {
0139 struct da9030_charger *charger = s->private;
0140
0141 seq_printf(s, "charger is %s\n", charger->is_on ? "on" : "off");
0142 if (charger->chdet) {
0143 seq_printf(s, "iset = %dmA, vset = %dmV\n",
0144 charger->mA, charger->mV);
0145 }
0146
0147 seq_printf(s, "vbat_res = %d (%dmV)\n",
0148 charger->adc.vbat_res,
0149 da9030_reg_to_mV(charger->adc.vbat_res));
0150 seq_printf(s, "vbatmin_res = %d (%dmV)\n",
0151 charger->adc.vbatmin_res,
0152 da9030_reg_to_mV(charger->adc.vbatmin_res));
0153 seq_printf(s, "vbatmintxon = %d (%dmV)\n",
0154 charger->adc.vbatmintxon,
0155 da9030_reg_to_mV(charger->adc.vbatmintxon));
0156 seq_printf(s, "ichmax_res = %d (%dmA)\n",
0157 charger->adc.ichmax_res,
0158 da9030_reg_to_mV(charger->adc.ichmax_res));
0159 seq_printf(s, "ichmin_res = %d (%dmA)\n",
0160 charger->adc.ichmin_res,
0161 da9030_reg_to_mA(charger->adc.ichmin_res));
0162 seq_printf(s, "ichaverage_res = %d (%dmA)\n",
0163 charger->adc.ichaverage_res,
0164 da9030_reg_to_mA(charger->adc.ichaverage_res));
0165 seq_printf(s, "vchmax_res = %d (%dmV)\n",
0166 charger->adc.vchmax_res,
0167 da9030_reg_to_mA(charger->adc.vchmax_res));
0168 seq_printf(s, "vchmin_res = %d (%dmV)\n",
0169 charger->adc.vchmin_res,
0170 da9030_reg_to_mV(charger->adc.vchmin_res));
0171
0172 return 0;
0173 }
0174
0175 DEFINE_SHOW_ATTRIBUTE(bat_debug);
0176
0177 static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
0178 {
0179 charger->debug_file = debugfs_create_file("charger", 0666, NULL,
0180 charger, &bat_debug_fops);
0181 return charger->debug_file;
0182 }
0183
0184 static void da9030_bat_remove_debugfs(struct da9030_charger *charger)
0185 {
0186 debugfs_remove(charger->debug_file);
0187 }
0188 #else
0189 static inline struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
0190 {
0191 return NULL;
0192 }
0193 static inline void da9030_bat_remove_debugfs(struct da9030_charger *charger)
0194 {
0195 }
0196 #endif
0197
0198 static inline void da9030_read_adc(struct da9030_charger *charger,
0199 struct da9030_adc_res *adc)
0200 {
0201 da903x_reads(charger->master, DA9030_VBAT_RES,
0202 sizeof(*adc), (uint8_t *)adc);
0203 }
0204
0205 static void da9030_charger_update_state(struct da9030_charger *charger)
0206 {
0207 uint8_t val;
0208
0209 da903x_read(charger->master, DA9030_CHARGE_CONTROL, &val);
0210 charger->is_on = (val & DA9030_CHRG_CHARGER_ENABLE) ? 1 : 0;
0211 charger->mA = ((val >> 3) & 0xf) * 100;
0212 charger->mV = (val & 0x7) * 50 + 4000;
0213
0214 da9030_read_adc(charger, &charger->adc);
0215 da903x_read(charger->master, DA9030_FAULT_LOG, &charger->fault);
0216 charger->chdet = da903x_query_status(charger->master,
0217 DA9030_STATUS_CHDET);
0218 }
0219
0220 static void da9030_set_charge(struct da9030_charger *charger, int on)
0221 {
0222 uint8_t val;
0223
0224 if (on) {
0225 val = DA9030_CHRG_CHARGER_ENABLE;
0226 val |= (charger->charge_milliamp / 100) << 3;
0227 val |= (charger->charge_millivolt - 4000) / 50;
0228 charger->is_on = 1;
0229 } else {
0230 val = 0;
0231 charger->is_on = 0;
0232 }
0233
0234 da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);
0235
0236 power_supply_changed(charger->psy);
0237 }
0238
0239 static void da9030_charger_check_state(struct da9030_charger *charger)
0240 {
0241 da9030_charger_update_state(charger);
0242
0243
0244 if (!charger->is_on) {
0245 if ((charger->chdet) &&
0246 (charger->adc.vbat_res <
0247 charger->thresholds.vbat_charge_start)) {
0248 da9030_set_charge(charger, 1);
0249 }
0250 } else {
0251
0252 if (!charger->chdet) {
0253 da9030_set_charge(charger, 0);
0254 return;
0255 }
0256
0257 if (charger->adc.vbat_res >=
0258 charger->thresholds.vbat_charge_stop) {
0259 da9030_set_charge(charger, 0);
0260 da903x_write(charger->master, DA9030_VBATMON,
0261 charger->thresholds.vbat_charge_restart);
0262 } else if (charger->adc.vbat_res >
0263 charger->thresholds.vbat_low) {
0264
0265
0266
0267 da903x_write(charger->master, DA9030_VBATMON,
0268 charger->thresholds.vbat_low);
0269 }
0270 if (charger->adc.vchmax_res > charger->thresholds.vcharge_max ||
0271 charger->adc.vchmin_res < charger->thresholds.vcharge_min ||
0272
0273 charger->adc.tbat_res < charger->thresholds.tbat_high ||
0274 charger->adc.tbat_res > charger->thresholds.tbat_low) {
0275
0276 da9030_set_charge(charger, 0);
0277 }
0278 }
0279 }
0280
0281 static void da9030_charging_monitor(struct work_struct *work)
0282 {
0283 struct da9030_charger *charger;
0284
0285 charger = container_of(work, struct da9030_charger, work.work);
0286
0287 da9030_charger_check_state(charger);
0288
0289
0290 schedule_delayed_work(&charger->work, charger->interval);
0291 }
0292
0293 static enum power_supply_property da9030_battery_props[] = {
0294 POWER_SUPPLY_PROP_MODEL_NAME,
0295 POWER_SUPPLY_PROP_STATUS,
0296 POWER_SUPPLY_PROP_HEALTH,
0297 POWER_SUPPLY_PROP_TECHNOLOGY,
0298 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
0299 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
0300 POWER_SUPPLY_PROP_VOLTAGE_NOW,
0301 POWER_SUPPLY_PROP_CURRENT_AVG,
0302 };
0303
0304 static void da9030_battery_check_status(struct da9030_charger *charger,
0305 union power_supply_propval *val)
0306 {
0307 if (charger->chdet) {
0308 if (charger->is_on)
0309 val->intval = POWER_SUPPLY_STATUS_CHARGING;
0310 else
0311 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
0312 } else {
0313 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
0314 }
0315 }
0316
0317 static void da9030_battery_check_health(struct da9030_charger *charger,
0318 union power_supply_propval *val)
0319 {
0320 if (charger->fault & DA9030_FAULT_LOG_OVER_TEMP)
0321 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
0322 else if (charger->fault & DA9030_FAULT_LOG_VBAT_OVER)
0323 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
0324 else
0325 val->intval = POWER_SUPPLY_HEALTH_GOOD;
0326 }
0327
0328 static int da9030_battery_get_property(struct power_supply *psy,
0329 enum power_supply_property psp,
0330 union power_supply_propval *val)
0331 {
0332 struct da9030_charger *charger = power_supply_get_drvdata(psy);
0333
0334 switch (psp) {
0335 case POWER_SUPPLY_PROP_STATUS:
0336 da9030_battery_check_status(charger, val);
0337 break;
0338 case POWER_SUPPLY_PROP_HEALTH:
0339 da9030_battery_check_health(charger, val);
0340 break;
0341 case POWER_SUPPLY_PROP_TECHNOLOGY:
0342 val->intval = charger->battery_info->technology;
0343 break;
0344 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
0345 val->intval = charger->battery_info->voltage_max_design;
0346 break;
0347 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
0348 val->intval = charger->battery_info->voltage_min_design;
0349 break;
0350 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0351 val->intval = da9030_reg_to_mV(charger->adc.vbat_res) * 1000;
0352 break;
0353 case POWER_SUPPLY_PROP_CURRENT_AVG:
0354 val->intval =
0355 da9030_reg_to_mA(charger->adc.ichaverage_res) * 1000;
0356 break;
0357 case POWER_SUPPLY_PROP_MODEL_NAME:
0358 val->strval = charger->battery_info->name;
0359 break;
0360 default:
0361 break;
0362 }
0363
0364 return 0;
0365 }
0366
0367 static void da9030_battery_vbat_event(struct da9030_charger *charger)
0368 {
0369 da9030_read_adc(charger, &charger->adc);
0370
0371 if (charger->is_on)
0372 return;
0373
0374 if (charger->adc.vbat_res < charger->thresholds.vbat_low) {
0375
0376 da903x_write(charger->master, DA9030_VBATMON,
0377 charger->thresholds.vbat_crit);
0378 if (charger->battery_low)
0379 charger->battery_low();
0380 } else if (charger->adc.vbat_res <
0381 charger->thresholds.vbat_crit) {
0382
0383 if (charger->battery_critical)
0384 charger->battery_critical();
0385 }
0386 }
0387
0388 static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
0389 void *data)
0390 {
0391 struct da9030_charger *charger =
0392 container_of(nb, struct da9030_charger, nb);
0393
0394 switch (event) {
0395 case DA9030_EVENT_CHDET:
0396 cancel_delayed_work_sync(&charger->work);
0397 schedule_work(&charger->work.work);
0398 break;
0399 case DA9030_EVENT_VBATMON:
0400 da9030_battery_vbat_event(charger);
0401 break;
0402 case DA9030_EVENT_CHIOVER:
0403 case DA9030_EVENT_TBAT:
0404 da9030_set_charge(charger, 0);
0405 break;
0406 }
0407
0408 return 0;
0409 }
0410
0411 static void da9030_battery_convert_thresholds(struct da9030_charger *charger,
0412 struct da9030_battery_info *pdata)
0413 {
0414 charger->thresholds.tbat_low = pdata->tbat_low;
0415 charger->thresholds.tbat_high = pdata->tbat_high;
0416 charger->thresholds.tbat_restart = pdata->tbat_restart;
0417
0418 charger->thresholds.vbat_low =
0419 da9030_millivolt_to_reg(pdata->vbat_low);
0420 charger->thresholds.vbat_crit =
0421 da9030_millivolt_to_reg(pdata->vbat_crit);
0422 charger->thresholds.vbat_charge_start =
0423 da9030_millivolt_to_reg(pdata->vbat_charge_start);
0424 charger->thresholds.vbat_charge_stop =
0425 da9030_millivolt_to_reg(pdata->vbat_charge_stop);
0426 charger->thresholds.vbat_charge_restart =
0427 da9030_millivolt_to_reg(pdata->vbat_charge_restart);
0428
0429 charger->thresholds.vcharge_min =
0430 da9030_millivolt_to_reg(pdata->vcharge_min);
0431 charger->thresholds.vcharge_max =
0432 da9030_millivolt_to_reg(pdata->vcharge_max);
0433 }
0434
0435 static void da9030_battery_setup_psy(struct da9030_charger *charger)
0436 {
0437 struct power_supply_desc *psy_desc = &charger->psy_desc;
0438 struct power_supply_info *info = charger->battery_info;
0439
0440 psy_desc->name = info->name;
0441 psy_desc->use_for_apm = info->use_for_apm;
0442 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
0443 psy_desc->get_property = da9030_battery_get_property;
0444
0445 psy_desc->properties = da9030_battery_props;
0446 psy_desc->num_properties = ARRAY_SIZE(da9030_battery_props);
0447 };
0448
0449 static int da9030_battery_charger_init(struct da9030_charger *charger)
0450 {
0451 char v[5];
0452 int ret;
0453
0454 v[0] = v[1] = charger->thresholds.vbat_low;
0455 v[2] = charger->thresholds.tbat_high;
0456 v[3] = charger->thresholds.tbat_restart;
0457 v[4] = charger->thresholds.tbat_low;
0458
0459 ret = da903x_writes(charger->master, DA9030_VBATMON, 5, v);
0460 if (ret)
0461 return ret;
0462
0463
0464
0465
0466
0467 ret = da903x_write(charger->master, DA9030_ADC_MAN_CONTROL,
0468 DA9030_ADC_LDO_INT_ENABLE |
0469 DA9030_ADC_TBATREF_ENABLE);
0470 if (ret)
0471 return ret;
0472
0473
0474 return da903x_write(charger->master, DA9030_ADC_AUTO_CONTROL,
0475 DA9030_ADC_TBAT_ENABLE | DA9030_ADC_VBAT_IN_TXON |
0476 DA9030_ADC_VCH_ENABLE | DA9030_ADC_ICH_ENABLE |
0477 DA9030_ADC_VBAT_ENABLE |
0478 DA9030_ADC_AUTO_SLEEP_ENABLE);
0479 }
0480
0481 static int da9030_battery_probe(struct platform_device *pdev)
0482 {
0483 struct da9030_charger *charger;
0484 struct power_supply_config psy_cfg = {};
0485 struct da9030_battery_info *pdata = pdev->dev.platform_data;
0486 int ret;
0487
0488 if (pdata == NULL)
0489 return -EINVAL;
0490
0491 if (pdata->charge_milliamp >= 1500 ||
0492 pdata->charge_millivolt < 4000 ||
0493 pdata->charge_millivolt > 4350)
0494 return -EINVAL;
0495
0496 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
0497 if (charger == NULL)
0498 return -ENOMEM;
0499
0500 charger->master = pdev->dev.parent;
0501
0502
0503
0504 charger->interval = msecs_to_jiffies(
0505 (pdata->batmon_interval ? : 10) * 1000);
0506
0507 charger->charge_milliamp = pdata->charge_milliamp;
0508 charger->charge_millivolt = pdata->charge_millivolt;
0509 charger->battery_info = pdata->battery_info;
0510 charger->battery_low = pdata->battery_low;
0511 charger->battery_critical = pdata->battery_critical;
0512
0513 da9030_battery_convert_thresholds(charger, pdata);
0514
0515 ret = da9030_battery_charger_init(charger);
0516 if (ret)
0517 goto err_charger_init;
0518
0519 INIT_DELAYED_WORK(&charger->work, da9030_charging_monitor);
0520 schedule_delayed_work(&charger->work, charger->interval);
0521
0522 charger->nb.notifier_call = da9030_battery_event;
0523 ret = da903x_register_notifier(charger->master, &charger->nb,
0524 DA9030_EVENT_CHDET |
0525 DA9030_EVENT_VBATMON |
0526 DA9030_EVENT_CHIOVER |
0527 DA9030_EVENT_TBAT);
0528 if (ret)
0529 goto err_notifier;
0530
0531 da9030_battery_setup_psy(charger);
0532 psy_cfg.drv_data = charger;
0533 charger->psy = power_supply_register(&pdev->dev, &charger->psy_desc,
0534 &psy_cfg);
0535 if (IS_ERR(charger->psy)) {
0536 ret = PTR_ERR(charger->psy);
0537 goto err_ps_register;
0538 }
0539
0540 charger->debug_file = da9030_bat_create_debugfs(charger);
0541 platform_set_drvdata(pdev, charger);
0542 return 0;
0543
0544 err_ps_register:
0545 da903x_unregister_notifier(charger->master, &charger->nb,
0546 DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
0547 DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
0548 err_notifier:
0549 cancel_delayed_work(&charger->work);
0550
0551 err_charger_init:
0552 return ret;
0553 }
0554
0555 static int da9030_battery_remove(struct platform_device *dev)
0556 {
0557 struct da9030_charger *charger = platform_get_drvdata(dev);
0558
0559 da9030_bat_remove_debugfs(charger);
0560
0561 da903x_unregister_notifier(charger->master, &charger->nb,
0562 DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
0563 DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
0564 cancel_delayed_work_sync(&charger->work);
0565 da9030_set_charge(charger, 0);
0566 power_supply_unregister(charger->psy);
0567
0568 return 0;
0569 }
0570
0571 static struct platform_driver da903x_battery_driver = {
0572 .driver = {
0573 .name = "da903x-battery",
0574 },
0575 .probe = da9030_battery_probe,
0576 .remove = da9030_battery_remove,
0577 };
0578
0579 module_platform_driver(da903x_battery_driver);
0580
0581 MODULE_DESCRIPTION("DA9030 battery charger driver");
0582 MODULE_AUTHOR("Mike Rapoport, CompuLab");
0583 MODULE_LICENSE("GPL");