aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2016-09-01 05:29:59 -0400
committerSebastian Reichel <sre@kernel.org>2016-09-01 07:55:55 -0400
commit528e3504123d0281c613b83ca46aaf2dd7c3f45e (patch)
tree94e66d32f7f8d23707789dce98d6981ec9e65599
parent369eba0986d503302784f55f1020129bf802ae72 (diff)
power: supply: act8945a_charger: Add max current property
Add the power supply's current max property, POWER_SUPPLY_PROP_CURRENT_MAX. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
-rw-r--r--drivers/power/supply/act8945a_charger.c89
1 files changed, 80 insertions, 9 deletions
diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
index 2f875997d97a..d1eb2e359532 100644
--- a/drivers/power/supply/act8945a_charger.c
+++ b/drivers/power/supply/act8945a_charger.c
@@ -13,7 +13,6 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_gpio.h>
17#include <linux/of_irq.h> 16#include <linux/of_irq.h>
18#include <linux/platform_device.h> 17#include <linux/platform_device.h>
19#include <linux/power_supply.h> 18#include <linux/power_supply.h>
@@ -85,6 +84,7 @@ struct act8945a_charger {
85 84
86 bool init_done; 85 bool init_done;
87 struct gpio_desc *lbo_gpio; 86 struct gpio_desc *lbo_gpio;
87 struct gpio_desc *chglev_gpio;
88}; 88};
89 89
90static int act8945a_get_charger_state(struct regmap *regmap, int *val) 90static int act8945a_get_charger_state(struct regmap *regmap, int *val)
@@ -265,12 +265,80 @@ static int act8945a_get_capacity_level(struct act8945a_charger *charger,
265 return 0; 265 return 0;
266} 266}
267 267
268#define MAX_CURRENT_USB_HIGH 450000
269#define MAX_CURRENT_USB_LOW 90000
270#define MAX_CURRENT_USB_PRE 45000
271/*
272 * Riset(K) = 2336 * (1V/Ichg(mA)) - 0.205
273 * Riset = 2.43K
274 */
275#define MAX_CURRENT_AC_HIGH 886527
276#define MAX_CURRENT_AC_LOW 117305
277#define MAX_CURRENT_AC_HIGH_PRE 88653
278#define MAX_CURRENT_AC_LOW_PRE 11731
279
280static int act8945a_get_current_max(struct act8945a_charger *charger,
281 struct regmap *regmap, int *val)
282{
283 int ret;
284 unsigned int status, state;
285 unsigned int acin_state;
286 int chgin_level = gpiod_get_value(charger->chglev_gpio);
287
288 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
289 if (ret < 0)
290 return ret;
291
292 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
293 if (ret < 0)
294 return ret;
295
296 acin_state = (state & APCH_STATE_ACINSTAT) >> 1;
297
298 state &= APCH_STATE_CSTATE;
299 state >>= APCH_STATE_CSTATE_SHIFT;
300
301 switch (state) {
302 case APCH_STATE_CSTATE_PRE:
303 if (acin_state) {
304 if (chgin_level)
305 *val = MAX_CURRENT_AC_HIGH_PRE;
306 else
307 *val = MAX_CURRENT_AC_LOW_PRE;
308 } else {
309 *val = MAX_CURRENT_USB_PRE;
310 }
311 break;
312 case APCH_STATE_CSTATE_FAST:
313 if (acin_state) {
314 if (chgin_level)
315 *val = MAX_CURRENT_AC_HIGH;
316 else
317 *val = MAX_CURRENT_AC_LOW;
318 } else {
319 if (chgin_level)
320 *val = MAX_CURRENT_USB_HIGH;
321 else
322 *val = MAX_CURRENT_USB_LOW;
323 }
324 break;
325 case APCH_STATE_CSTATE_EOC:
326 case APCH_STATE_CSTATE_DISABLED:
327 default:
328 *val = 0;
329 break;
330 }
331
332 return 0;
333}
334
268static enum power_supply_property act8945a_charger_props[] = { 335static enum power_supply_property act8945a_charger_props[] = {
269 POWER_SUPPLY_PROP_STATUS, 336 POWER_SUPPLY_PROP_STATUS,
270 POWER_SUPPLY_PROP_CHARGE_TYPE, 337 POWER_SUPPLY_PROP_CHARGE_TYPE,
271 POWER_SUPPLY_PROP_TECHNOLOGY, 338 POWER_SUPPLY_PROP_TECHNOLOGY,
272 POWER_SUPPLY_PROP_HEALTH, 339 POWER_SUPPLY_PROP_HEALTH,
273 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 340 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
341 POWER_SUPPLY_PROP_CURRENT_MAX,
274 POWER_SUPPLY_PROP_MODEL_NAME, 342 POWER_SUPPLY_PROP_MODEL_NAME,
275 POWER_SUPPLY_PROP_MANUFACTURER 343 POWER_SUPPLY_PROP_MANUFACTURER
276}; 344};
@@ -300,6 +368,10 @@ static int act8945a_charger_get_property(struct power_supply *psy,
300 ret = act8945a_get_capacity_level(charger, 368 ret = act8945a_get_capacity_level(charger,
301 regmap, &val->intval); 369 regmap, &val->intval);
302 break; 370 break;
371 case POWER_SUPPLY_PROP_CURRENT_MAX:
372 ret = act8945a_get_current_max(charger,
373 regmap, &val->intval);
374 break;
303 case POWER_SUPPLY_PROP_MODEL_NAME: 375 case POWER_SUPPLY_PROP_MODEL_NAME:
304 val->strval = act8945a_charger_model; 376 val->strval = act8945a_charger_model;
305 break; 377 break;
@@ -390,13 +462,11 @@ static int act8945a_charger_config(struct device *dev,
390 struct act8945a_charger *charger) 462 struct act8945a_charger *charger)
391{ 463{
392 struct device_node *np = dev->of_node; 464 struct device_node *np = dev->of_node;
393 enum of_gpio_flags flags;
394 struct regmap *regmap = charger->regmap; 465 struct regmap *regmap = charger->regmap;
395 466
396 u32 total_time_out; 467 u32 total_time_out;
397 u32 pre_time_out; 468 u32 pre_time_out;
398 u32 input_voltage_threshold; 469 u32 input_voltage_threshold;
399 int chglev_pin;
400 int err, ret; 470 int err, ret;
401 471
402 unsigned int tmp; 472 unsigned int tmp;
@@ -431,12 +501,13 @@ static int act8945a_charger_config(struct device *dev,
431 if (ret) 501 if (ret)
432 dev_info(dev, "failed to request gpio \"lbo\" IRQ\n"); 502 dev_info(dev, "failed to request gpio \"lbo\" IRQ\n");
433 503
434 chglev_pin = of_get_named_gpio_flags(np, 504 charger->chglev_gpio = devm_gpiod_get_optional(dev,
435 "active-semi,chglev-gpios", 0, &flags); 505 "active-semi,chglev",
436 506 GPIOD_IN);
437 if (gpio_is_valid(chglev_pin)) { 507 if (IS_ERR(charger->chglev_gpio)) {
438 gpio_set_value(chglev_pin, 508 err = PTR_ERR(charger->chglev_gpio);
439 ((flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1)); 509 dev_err(dev, "unable to claim gpio \"chglev\": %d\n", err);
510 return err;
440 } 511 }
441 512
442 if (of_property_read_u32(np, 513 if (of_property_read_u32(np,