gpio_charger
val->intval = gpiod_get_value_cansleep(gpio_charger->gpiod);
if (gpiod_get_value_cansleep(gpio_charger->charge_status))
val->intval = gpio_charger->charge_current_limit;
struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);
return set_charge_current_limit(gpio_charger, val->intval);
struct gpio_charger *gpio_charger)
gpio_charger->current_limit_gpios = devm_gpiod_get_array_optional(dev,
if (IS_ERR(gpio_charger->current_limit_gpios)) {
return PTR_ERR(gpio_charger->current_limit_gpios);
if (!gpio_charger->current_limit_gpios)
gpio_charger->current_limit_map = devm_kmalloc_array(dev,
len / 2, sizeof(*gpio_charger->current_limit_map), GFP_KERNEL);
if (!gpio_charger->current_limit_map)
gpio_charger->current_limit_map_size = len / 2;
(u32 *) gpio_charger->current_limit_map, len);
for (i = 0; i < gpio_charger->current_limit_map_size; i++) {
if (gpio_charger->current_limit_map[i].limit_ua > cur_limit) {
cur_limit = gpio_charger->current_limit_map[i].limit_ua;
set_charge_current_limit(gpio_charger, cur_limit);
len = gpio_charger->current_limit_map_size - 1;
set_charge_current_limit(gpio_charger,
gpio_charger->current_limit_map[len].limit_ua);
struct gpio_charger *gpio_charger;
gpio_charger = devm_kzalloc(dev, sizeof(*gpio_charger), GFP_KERNEL);
if (!gpio_charger)
gpio_charger->dev = dev;
gpio_charger->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN);
if (IS_ERR(gpio_charger->gpiod)) {
return dev_err_probe(dev, PTR_ERR(gpio_charger->gpiod),
if (gpio_charger->gpiod) {
gpio_charger->charge_status = charge_status;
ret = init_charge_current_limit(dev, gpio_charger);
if (gpio_charger->current_limit_map) {
charger_desc = &gpio_charger->charger_desc;
psy_cfg.drv_data = gpio_charger;
gpio_charger->charger = devm_power_supply_register(dev, charger_desc,
if (IS_ERR(gpio_charger->charger)) {
ret = PTR_ERR(gpio_charger->charger);
gpio_charger->irq = gpio_charger_get_irq(dev, gpio_charger->charger,
gpio_charger->gpiod);
charge_status_irq = gpio_charger_get_irq(dev, gpio_charger->charger,
gpio_charger->charge_status);
gpio_charger->charge_status_irq = charge_status_irq;
platform_set_drvdata(pdev, gpio_charger);
struct gpio_charger *gpio_charger = dev_get_drvdata(dev);
gpio_charger->wakeup_enabled =
!enable_irq_wake(gpio_charger->irq);
struct gpio_charger *gpio_charger = dev_get_drvdata(dev);
if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled)
disable_irq_wake(gpio_charger->irq);
power_supply_changed(gpio_charger->charger);
static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
static int set_charge_current_limit(struct gpio_charger *gpio_charger, int val)
int ndescs = gpio_charger->current_limit_gpios->ndescs;
struct gpio_desc **gpios = gpio_charger->current_limit_gpios->desc;
if (!gpio_charger->current_limit_map_size)
for (i = 0; i < gpio_charger->current_limit_map_size; i++) {
if (gpio_charger->current_limit_map[i].limit_ua <= val)
if (i >= gpio_charger->current_limit_map_size)
i = gpio_charger->current_limit_map_size - 1;
mapping = gpio_charger->current_limit_map[i];
gpio_charger->charge_current_limit = mapping.limit_ua;
dev_dbg(gpio_charger->dev, "set charge current limit to %d (requested: %d)\n",
gpio_charger->charge_current_limit, val);
struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);