0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/interrupt.h>
0010 #include <linux/module.h>
0011 #include <linux/of.h>
0012 #include <linux/of_irq.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/power_supply.h>
0015 #include <linux/regmap.h>
0016 #include <linux/gpio/consumer.h>
0017
0018 static const char *act8945a_charger_model = "ACT8945A";
0019 static const char *act8945a_charger_manufacturer = "Active-semi";
0020
0021
0022
0023
0024
0025
0026 #define ACT8945A_APCH_CFG 0x71
0027 #define ACT8945A_APCH_STATUS 0x78
0028 #define ACT8945A_APCH_CTRL 0x79
0029 #define ACT8945A_APCH_STATE 0x7A
0030
0031
0032 #define APCH_CFG_OVPSET (0x3 << 0)
0033 #define APCH_CFG_OVPSET_6V6 (0x0 << 0)
0034 #define APCH_CFG_OVPSET_7V (0x1 << 0)
0035 #define APCH_CFG_OVPSET_7V5 (0x2 << 0)
0036 #define APCH_CFG_OVPSET_8V (0x3 << 0)
0037 #define APCH_CFG_PRETIMO (0x3 << 2)
0038 #define APCH_CFG_PRETIMO_40_MIN (0x0 << 2)
0039 #define APCH_CFG_PRETIMO_60_MIN (0x1 << 2)
0040 #define APCH_CFG_PRETIMO_80_MIN (0x2 << 2)
0041 #define APCH_CFG_PRETIMO_DISABLED (0x3 << 2)
0042 #define APCH_CFG_TOTTIMO (0x3 << 4)
0043 #define APCH_CFG_TOTTIMO_3_HOUR (0x0 << 4)
0044 #define APCH_CFG_TOTTIMO_4_HOUR (0x1 << 4)
0045 #define APCH_CFG_TOTTIMO_5_HOUR (0x2 << 4)
0046 #define APCH_CFG_TOTTIMO_DISABLED (0x3 << 4)
0047 #define APCH_CFG_SUSCHG (0x1 << 7)
0048
0049 #define APCH_STATUS_CHGDAT BIT(0)
0050 #define APCH_STATUS_INDAT BIT(1)
0051 #define APCH_STATUS_TEMPDAT BIT(2)
0052 #define APCH_STATUS_TIMRDAT BIT(3)
0053 #define APCH_STATUS_CHGSTAT BIT(4)
0054 #define APCH_STATUS_INSTAT BIT(5)
0055 #define APCH_STATUS_TEMPSTAT BIT(6)
0056 #define APCH_STATUS_TIMRSTAT BIT(7)
0057
0058 #define APCH_CTRL_CHGEOCOUT BIT(0)
0059 #define APCH_CTRL_INDIS BIT(1)
0060 #define APCH_CTRL_TEMPOUT BIT(2)
0061 #define APCH_CTRL_TIMRPRE BIT(3)
0062 #define APCH_CTRL_CHGEOCIN BIT(4)
0063 #define APCH_CTRL_INCON BIT(5)
0064 #define APCH_CTRL_TEMPIN BIT(6)
0065 #define APCH_CTRL_TIMRTOT BIT(7)
0066
0067 #define APCH_STATE_ACINSTAT (0x1 << 1)
0068 #define APCH_STATE_CSTATE (0x3 << 4)
0069 #define APCH_STATE_CSTATE_SHIFT 4
0070 #define APCH_STATE_CSTATE_DISABLED 0x00
0071 #define APCH_STATE_CSTATE_EOC 0x01
0072 #define APCH_STATE_CSTATE_FAST 0x02
0073 #define APCH_STATE_CSTATE_PRE 0x03
0074
0075 struct act8945a_charger {
0076 struct power_supply *psy;
0077 struct power_supply_desc desc;
0078 struct regmap *regmap;
0079 struct work_struct work;
0080
0081 bool init_done;
0082 struct gpio_desc *lbo_gpio;
0083 struct gpio_desc *chglev_gpio;
0084 };
0085
0086 static int act8945a_get_charger_state(struct regmap *regmap, int *val)
0087 {
0088 int ret;
0089 unsigned int status, state;
0090
0091 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
0092 if (ret < 0)
0093 return ret;
0094
0095 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
0096 if (ret < 0)
0097 return ret;
0098
0099 state &= APCH_STATE_CSTATE;
0100 state >>= APCH_STATE_CSTATE_SHIFT;
0101
0102 switch (state) {
0103 case APCH_STATE_CSTATE_PRE:
0104 case APCH_STATE_CSTATE_FAST:
0105 *val = POWER_SUPPLY_STATUS_CHARGING;
0106 break;
0107 case APCH_STATE_CSTATE_EOC:
0108 if (status & APCH_STATUS_CHGDAT)
0109 *val = POWER_SUPPLY_STATUS_FULL;
0110 else
0111 *val = POWER_SUPPLY_STATUS_CHARGING;
0112 break;
0113 case APCH_STATE_CSTATE_DISABLED:
0114 default:
0115 if (!(status & APCH_STATUS_INDAT))
0116 *val = POWER_SUPPLY_STATUS_DISCHARGING;
0117 else
0118 *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
0119 break;
0120 }
0121
0122 return 0;
0123 }
0124
0125 static int act8945a_get_charge_type(struct regmap *regmap, int *val)
0126 {
0127 int ret;
0128 unsigned int status, state;
0129
0130 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
0131 if (ret < 0)
0132 return ret;
0133
0134 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
0135 if (ret < 0)
0136 return ret;
0137
0138 state &= APCH_STATE_CSTATE;
0139 state >>= APCH_STATE_CSTATE_SHIFT;
0140
0141 switch (state) {
0142 case APCH_STATE_CSTATE_PRE:
0143 *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
0144 break;
0145 case APCH_STATE_CSTATE_FAST:
0146 *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
0147 break;
0148 case APCH_STATE_CSTATE_EOC:
0149 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
0150 break;
0151 case APCH_STATE_CSTATE_DISABLED:
0152 default:
0153 if (!(status & APCH_STATUS_INDAT))
0154 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
0155 else
0156 *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
0157 break;
0158 }
0159
0160 return 0;
0161 }
0162
0163 static int act8945a_get_battery_health(struct regmap *regmap, int *val)
0164 {
0165 int ret;
0166 unsigned int status, state, config;
0167
0168 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
0169 if (ret < 0)
0170 return ret;
0171
0172 ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
0173 if (ret < 0)
0174 return ret;
0175
0176 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
0177 if (ret < 0)
0178 return ret;
0179
0180 state &= APCH_STATE_CSTATE;
0181 state >>= APCH_STATE_CSTATE_SHIFT;
0182
0183 switch (state) {
0184 case APCH_STATE_CSTATE_DISABLED:
0185 if (config & APCH_CFG_SUSCHG) {
0186 *val = POWER_SUPPLY_HEALTH_UNKNOWN;
0187 } else if (status & APCH_STATUS_INDAT) {
0188 if (!(status & APCH_STATUS_TEMPDAT))
0189 *val = POWER_SUPPLY_HEALTH_OVERHEAT;
0190 else if (status & APCH_STATUS_TIMRDAT)
0191 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
0192 else
0193 *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
0194 } else {
0195 *val = POWER_SUPPLY_HEALTH_GOOD;
0196 }
0197 break;
0198 case APCH_STATE_CSTATE_PRE:
0199 case APCH_STATE_CSTATE_FAST:
0200 case APCH_STATE_CSTATE_EOC:
0201 default:
0202 *val = POWER_SUPPLY_HEALTH_GOOD;
0203 break;
0204 }
0205
0206 return 0;
0207 }
0208
0209 static int act8945a_get_capacity_level(struct act8945a_charger *charger,
0210 struct regmap *regmap, int *val)
0211 {
0212 int ret;
0213 unsigned int status, state, config;
0214 int lbo_level = gpiod_get_value(charger->lbo_gpio);
0215
0216 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
0217 if (ret < 0)
0218 return ret;
0219
0220 ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
0221 if (ret < 0)
0222 return ret;
0223
0224 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
0225 if (ret < 0)
0226 return ret;
0227
0228 state &= APCH_STATE_CSTATE;
0229 state >>= APCH_STATE_CSTATE_SHIFT;
0230
0231 switch (state) {
0232 case APCH_STATE_CSTATE_PRE:
0233 *val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
0234 break;
0235 case APCH_STATE_CSTATE_FAST:
0236 if (lbo_level)
0237 *val = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
0238 else
0239 *val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
0240 break;
0241 case APCH_STATE_CSTATE_EOC:
0242 if (status & APCH_STATUS_CHGDAT)
0243 *val = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
0244 else
0245 *val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
0246 break;
0247 case APCH_STATE_CSTATE_DISABLED:
0248 default:
0249 if (config & APCH_CFG_SUSCHG) {
0250 *val = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
0251 } else {
0252 *val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
0253 if (!(status & APCH_STATUS_INDAT)) {
0254 if (!lbo_level)
0255 *val = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
0256 }
0257 }
0258 break;
0259 }
0260
0261 return 0;
0262 }
0263
0264 #define MAX_CURRENT_USB_HIGH 450000
0265 #define MAX_CURRENT_USB_LOW 90000
0266 #define MAX_CURRENT_USB_PRE 45000
0267
0268
0269
0270
0271 #define MAX_CURRENT_AC_HIGH 886527
0272 #define MAX_CURRENT_AC_LOW 117305
0273 #define MAX_CURRENT_AC_HIGH_PRE 88653
0274 #define MAX_CURRENT_AC_LOW_PRE 11731
0275
0276 static int act8945a_get_current_max(struct act8945a_charger *charger,
0277 struct regmap *regmap, int *val)
0278 {
0279 int ret;
0280 unsigned int status, state;
0281 unsigned int acin_state;
0282 int chgin_level = gpiod_get_value(charger->chglev_gpio);
0283
0284 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
0285 if (ret < 0)
0286 return ret;
0287
0288 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
0289 if (ret < 0)
0290 return ret;
0291
0292 acin_state = (state & APCH_STATE_ACINSTAT) >> 1;
0293
0294 state &= APCH_STATE_CSTATE;
0295 state >>= APCH_STATE_CSTATE_SHIFT;
0296
0297 switch (state) {
0298 case APCH_STATE_CSTATE_PRE:
0299 if (acin_state) {
0300 if (chgin_level)
0301 *val = MAX_CURRENT_AC_HIGH_PRE;
0302 else
0303 *val = MAX_CURRENT_AC_LOW_PRE;
0304 } else {
0305 *val = MAX_CURRENT_USB_PRE;
0306 }
0307 break;
0308 case APCH_STATE_CSTATE_FAST:
0309 if (acin_state) {
0310 if (chgin_level)
0311 *val = MAX_CURRENT_AC_HIGH;
0312 else
0313 *val = MAX_CURRENT_AC_LOW;
0314 } else {
0315 if (chgin_level)
0316 *val = MAX_CURRENT_USB_HIGH;
0317 else
0318 *val = MAX_CURRENT_USB_LOW;
0319 }
0320 break;
0321 case APCH_STATE_CSTATE_EOC:
0322 case APCH_STATE_CSTATE_DISABLED:
0323 default:
0324 *val = 0;
0325 break;
0326 }
0327
0328 return 0;
0329 }
0330
0331 static enum power_supply_property act8945a_charger_props[] = {
0332 POWER_SUPPLY_PROP_STATUS,
0333 POWER_SUPPLY_PROP_CHARGE_TYPE,
0334 POWER_SUPPLY_PROP_TECHNOLOGY,
0335 POWER_SUPPLY_PROP_HEALTH,
0336 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
0337 POWER_SUPPLY_PROP_CURRENT_MAX,
0338 POWER_SUPPLY_PROP_MODEL_NAME,
0339 POWER_SUPPLY_PROP_MANUFACTURER
0340 };
0341
0342 static int act8945a_charger_get_property(struct power_supply *psy,
0343 enum power_supply_property prop,
0344 union power_supply_propval *val)
0345 {
0346 struct act8945a_charger *charger = power_supply_get_drvdata(psy);
0347 struct regmap *regmap = charger->regmap;
0348 int ret = 0;
0349
0350 switch (prop) {
0351 case POWER_SUPPLY_PROP_STATUS:
0352 ret = act8945a_get_charger_state(regmap, &val->intval);
0353 break;
0354 case POWER_SUPPLY_PROP_CHARGE_TYPE:
0355 ret = act8945a_get_charge_type(regmap, &val->intval);
0356 break;
0357 case POWER_SUPPLY_PROP_TECHNOLOGY:
0358 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
0359 break;
0360 case POWER_SUPPLY_PROP_HEALTH:
0361 ret = act8945a_get_battery_health(regmap, &val->intval);
0362 break;
0363 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
0364 ret = act8945a_get_capacity_level(charger,
0365 regmap, &val->intval);
0366 break;
0367 case POWER_SUPPLY_PROP_CURRENT_MAX:
0368 ret = act8945a_get_current_max(charger,
0369 regmap, &val->intval);
0370 break;
0371 case POWER_SUPPLY_PROP_MODEL_NAME:
0372 val->strval = act8945a_charger_model;
0373 break;
0374 case POWER_SUPPLY_PROP_MANUFACTURER:
0375 val->strval = act8945a_charger_manufacturer;
0376 break;
0377 default:
0378 return -EINVAL;
0379 }
0380
0381 return ret;
0382 }
0383
0384 static int act8945a_enable_interrupt(struct act8945a_charger *charger)
0385 {
0386 struct regmap *regmap = charger->regmap;
0387 unsigned char ctrl;
0388 int ret;
0389
0390 ctrl = APCH_CTRL_CHGEOCOUT | APCH_CTRL_CHGEOCIN |
0391 APCH_CTRL_INDIS | APCH_CTRL_INCON |
0392 APCH_CTRL_TEMPOUT | APCH_CTRL_TEMPIN |
0393 APCH_CTRL_TIMRPRE | APCH_CTRL_TIMRTOT;
0394 ret = regmap_write(regmap, ACT8945A_APCH_CTRL, ctrl);
0395 if (ret)
0396 return ret;
0397
0398 ctrl = APCH_STATUS_CHGSTAT | APCH_STATUS_INSTAT |
0399 APCH_STATUS_TEMPSTAT | APCH_STATUS_TIMRSTAT;
0400 ret = regmap_write(regmap, ACT8945A_APCH_STATUS, ctrl);
0401 if (ret)
0402 return ret;
0403
0404 return 0;
0405 }
0406
0407 static unsigned int act8945a_set_supply_type(struct act8945a_charger *charger,
0408 unsigned int *type)
0409 {
0410 unsigned int status, state;
0411 int ret;
0412
0413 ret = regmap_read(charger->regmap, ACT8945A_APCH_STATUS, &status);
0414 if (ret < 0)
0415 return ret;
0416
0417 ret = regmap_read(charger->regmap, ACT8945A_APCH_STATE, &state);
0418 if (ret < 0)
0419 return ret;
0420
0421 if (status & APCH_STATUS_INDAT) {
0422 if (state & APCH_STATE_ACINSTAT)
0423 *type = POWER_SUPPLY_TYPE_MAINS;
0424 else
0425 *type = POWER_SUPPLY_TYPE_USB;
0426 } else {
0427 *type = POWER_SUPPLY_TYPE_BATTERY;
0428 }
0429
0430 return 0;
0431 }
0432
0433 static void act8945a_work(struct work_struct *work)
0434 {
0435 struct act8945a_charger *charger =
0436 container_of(work, struct act8945a_charger, work);
0437
0438 act8945a_set_supply_type(charger, &charger->desc.type);
0439
0440 power_supply_changed(charger->psy);
0441 }
0442
0443 static irqreturn_t act8945a_status_changed(int irq, void *dev_id)
0444 {
0445 struct act8945a_charger *charger = dev_id;
0446
0447 if (charger->init_done)
0448 schedule_work(&charger->work);
0449
0450 return IRQ_HANDLED;
0451 }
0452
0453 #define DEFAULT_TOTAL_TIME_OUT 3
0454 #define DEFAULT_PRE_TIME_OUT 40
0455 #define DEFAULT_INPUT_OVP_THRESHOLD 6600
0456
0457 static int act8945a_charger_config(struct device *dev,
0458 struct act8945a_charger *charger)
0459 {
0460 struct device_node *np = dev->of_node;
0461 struct regmap *regmap = charger->regmap;
0462
0463 u32 total_time_out;
0464 u32 pre_time_out;
0465 u32 input_voltage_threshold;
0466 int err, ret;
0467
0468 unsigned int tmp;
0469 unsigned int value = 0;
0470
0471 if (!np) {
0472 dev_err(dev, "no charger of node\n");
0473 return -EINVAL;
0474 }
0475
0476 ret = regmap_read(regmap, ACT8945A_APCH_CFG, &tmp);
0477 if (ret)
0478 return ret;
0479
0480 if (tmp & APCH_CFG_SUSCHG) {
0481 value |= APCH_CFG_SUSCHG;
0482 dev_info(dev, "have been suspended\n");
0483 }
0484
0485 charger->lbo_gpio = devm_gpiod_get_optional(dev, "active-semi,lbo",
0486 GPIOD_IN);
0487 if (IS_ERR(charger->lbo_gpio)) {
0488 err = PTR_ERR(charger->lbo_gpio);
0489 dev_err(dev, "unable to claim gpio \"lbo\": %d\n", err);
0490 return err;
0491 }
0492
0493 ret = devm_request_irq(dev, gpiod_to_irq(charger->lbo_gpio),
0494 act8945a_status_changed,
0495 (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING),
0496 "act8945a_lbo_detect", charger);
0497 if (ret)
0498 dev_info(dev, "failed to request gpio \"lbo\" IRQ\n");
0499
0500 charger->chglev_gpio = devm_gpiod_get_optional(dev,
0501 "active-semi,chglev",
0502 GPIOD_IN);
0503 if (IS_ERR(charger->chglev_gpio)) {
0504 err = PTR_ERR(charger->chglev_gpio);
0505 dev_err(dev, "unable to claim gpio \"chglev\": %d\n", err);
0506 return err;
0507 }
0508
0509 if (of_property_read_u32(np,
0510 "active-semi,input-voltage-threshold-microvolt",
0511 &input_voltage_threshold))
0512 input_voltage_threshold = DEFAULT_INPUT_OVP_THRESHOLD;
0513
0514 if (of_property_read_u32(np,
0515 "active-semi,precondition-timeout",
0516 &pre_time_out))
0517 pre_time_out = DEFAULT_PRE_TIME_OUT;
0518
0519 if (of_property_read_u32(np, "active-semi,total-timeout",
0520 &total_time_out))
0521 total_time_out = DEFAULT_TOTAL_TIME_OUT;
0522
0523 switch (input_voltage_threshold) {
0524 case 8000:
0525 value |= APCH_CFG_OVPSET_8V;
0526 break;
0527 case 7500:
0528 value |= APCH_CFG_OVPSET_7V5;
0529 break;
0530 case 7000:
0531 value |= APCH_CFG_OVPSET_7V;
0532 break;
0533 case 6600:
0534 default:
0535 value |= APCH_CFG_OVPSET_6V6;
0536 break;
0537 }
0538
0539 switch (pre_time_out) {
0540 case 60:
0541 value |= APCH_CFG_PRETIMO_60_MIN;
0542 break;
0543 case 80:
0544 value |= APCH_CFG_PRETIMO_80_MIN;
0545 break;
0546 case 0:
0547 value |= APCH_CFG_PRETIMO_DISABLED;
0548 break;
0549 case 40:
0550 default:
0551 value |= APCH_CFG_PRETIMO_40_MIN;
0552 break;
0553 }
0554
0555 switch (total_time_out) {
0556 case 4:
0557 value |= APCH_CFG_TOTTIMO_4_HOUR;
0558 break;
0559 case 5:
0560 value |= APCH_CFG_TOTTIMO_5_HOUR;
0561 break;
0562 case 0:
0563 value |= APCH_CFG_TOTTIMO_DISABLED;
0564 break;
0565 case 3:
0566 default:
0567 value |= APCH_CFG_TOTTIMO_3_HOUR;
0568 break;
0569 }
0570
0571 return regmap_write(regmap, ACT8945A_APCH_CFG, value);
0572 }
0573
0574 static int act8945a_charger_probe(struct platform_device *pdev)
0575 {
0576 struct act8945a_charger *charger;
0577 struct power_supply_config psy_cfg = {};
0578 int irq, ret;
0579
0580 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
0581 if (!charger)
0582 return -ENOMEM;
0583
0584 charger->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0585 if (!charger->regmap) {
0586 dev_err(&pdev->dev, "Parent did not provide regmap\n");
0587 return -EINVAL;
0588 }
0589
0590 ret = act8945a_charger_config(&pdev->dev, charger);
0591 if (ret)
0592 return ret;
0593
0594 irq = of_irq_get(pdev->dev.of_node, 0);
0595 if (irq <= 0) {
0596 dev_err(&pdev->dev, "failed to find IRQ number\n");
0597 return irq ?: -ENXIO;
0598 }
0599
0600 ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
0601 IRQF_TRIGGER_FALLING, "act8945a_interrupt",
0602 charger);
0603 if (ret) {
0604 dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
0605 return ret;
0606 }
0607
0608 charger->desc.name = "act8945a-charger";
0609 charger->desc.get_property = act8945a_charger_get_property;
0610 charger->desc.properties = act8945a_charger_props;
0611 charger->desc.num_properties = ARRAY_SIZE(act8945a_charger_props);
0612
0613 ret = act8945a_set_supply_type(charger, &charger->desc.type);
0614 if (ret)
0615 return -EINVAL;
0616
0617 psy_cfg.of_node = pdev->dev.of_node;
0618 psy_cfg.drv_data = charger;
0619
0620 charger->psy = devm_power_supply_register(&pdev->dev,
0621 &charger->desc,
0622 &psy_cfg);
0623 if (IS_ERR(charger->psy)) {
0624 dev_err(&pdev->dev, "failed to register power supply\n");
0625 return PTR_ERR(charger->psy);
0626 }
0627
0628 platform_set_drvdata(pdev, charger);
0629
0630 INIT_WORK(&charger->work, act8945a_work);
0631
0632 ret = act8945a_enable_interrupt(charger);
0633 if (ret)
0634 return -EIO;
0635
0636 charger->init_done = true;
0637
0638 return 0;
0639 }
0640
0641 static int act8945a_charger_remove(struct platform_device *pdev)
0642 {
0643 struct act8945a_charger *charger = platform_get_drvdata(pdev);
0644
0645 charger->init_done = false;
0646 cancel_work_sync(&charger->work);
0647
0648 return 0;
0649 }
0650
0651 static struct platform_driver act8945a_charger_driver = {
0652 .driver = {
0653 .name = "act8945a-charger",
0654 },
0655 .probe = act8945a_charger_probe,
0656 .remove = act8945a_charger_remove,
0657 };
0658 module_platform_driver(act8945a_charger_driver);
0659
0660 MODULE_DESCRIPTION("Active-semi ACT8945A ActivePath charger driver");
0661 MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
0662 MODULE_LICENSE("GPL");