Lines Matching +full:charge +full:- +full:current +full:- +full:limit +full:- +full:mapping
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
18 #include <linux/power/gpio-charger.h>
58 struct gpio_mapping mapping; in set_charge_current_limit() local
59 int ndescs = gpio_charger->current_limit_gpios->ndescs; in set_charge_current_limit()
60 struct gpio_desc **gpios = gpio_charger->current_limit_gpios->desc; in set_charge_current_limit()
63 if (!gpio_charger->current_limit_map_size) in set_charge_current_limit()
64 return -EINVAL; in set_charge_current_limit()
66 for (i = 0; i < gpio_charger->current_limit_map_size; i++) { in set_charge_current_limit()
67 if (gpio_charger->current_limit_map[i].limit_ua <= val) in set_charge_current_limit()
72 * If a valid charge current limit isn't found, default to smallest in set_charge_current_limit()
73 * current limitation for safety reasons. in set_charge_current_limit()
75 if (i >= gpio_charger->current_limit_map_size) in set_charge_current_limit()
76 i = gpio_charger->current_limit_map_size - 1; in set_charge_current_limit()
78 mapping = gpio_charger->current_limit_map[i]; in set_charge_current_limit()
81 bool val = (mapping.gpiodata >> i) & 1; in set_charge_current_limit()
82 gpiod_set_value_cansleep(gpios[ndescs-i-1], val); in set_charge_current_limit()
85 gpio_charger->charge_current_limit = mapping.limit_ua; in set_charge_current_limit()
87 dev_dbg(gpio_charger->dev, "set charge current limit to %d (requested: %d)\n", in set_charge_current_limit()
88 gpio_charger->charge_current_limit, val); in set_charge_current_limit()
100 val->intval = gpiod_get_value_cansleep(gpio_charger->gpiod); in gpio_charger_get_property()
103 if (gpiod_get_value_cansleep(gpio_charger->charge_status)) in gpio_charger_get_property()
104 val->intval = POWER_SUPPLY_STATUS_CHARGING; in gpio_charger_get_property()
106 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in gpio_charger_get_property()
109 val->intval = gpio_charger->charge_current_limit; in gpio_charger_get_property()
112 return -EINVAL; in gpio_charger_get_property()
125 return set_charge_current_limit(gpio_charger, val->intval); in gpio_charger_set_property()
127 return -EINVAL; in gpio_charger_set_property()
150 if (!device_property_read_string(dev, "charger-type", &chargetype)) { in gpio_charger_get_type()
159 if (!strcmp("usb-sdp", chargetype)) in gpio_charger_get_type()
161 if (!strcmp("usb-dcp", chargetype)) in gpio_charger_get_type()
163 if (!strcmp("usb-cdp", chargetype)) in gpio_charger_get_type()
165 if (!strcmp("usb-aca", chargetype)) in gpio_charger_get_type()
199 gpio_charger->current_limit_gpios = devm_gpiod_get_array_optional(dev, in init_charge_current_limit()
200 "charge-current-limit", GPIOD_OUT_LOW); in init_charge_current_limit()
201 if (IS_ERR(gpio_charger->current_limit_gpios)) { in init_charge_current_limit()
202 dev_err(dev, "error getting current-limit GPIOs\n"); in init_charge_current_limit()
203 return PTR_ERR(gpio_charger->current_limit_gpios); in init_charge_current_limit()
206 if (!gpio_charger->current_limit_gpios) in init_charge_current_limit()
209 len = device_property_read_u32_array(dev, "charge-current-limit-mapping", in init_charge_current_limit()
215 dev_err(dev, "invalid charge-current-limit-mapping length\n"); in init_charge_current_limit()
216 return -EINVAL; in init_charge_current_limit()
219 gpio_charger->current_limit_map = devm_kmalloc_array(dev, in init_charge_current_limit()
220 len / 2, sizeof(*gpio_charger->current_limit_map), GFP_KERNEL); in init_charge_current_limit()
221 if (!gpio_charger->current_limit_map) in init_charge_current_limit()
222 return -ENOMEM; in init_charge_current_limit()
224 gpio_charger->current_limit_map_size = len / 2; in init_charge_current_limit()
226 len = device_property_read_u32_array(dev, "charge-current-limit-mapping", in init_charge_current_limit()
227 (u32*) gpio_charger->current_limit_map, len); in init_charge_current_limit()
231 for (i=0; i < gpio_charger->current_limit_map_size; i++) { in init_charge_current_limit()
232 if (gpio_charger->current_limit_map[i].limit_ua > cur_limit) { in init_charge_current_limit()
233 dev_err(dev, "charge-current-limit-mapping not sorted by current in descending order\n"); in init_charge_current_limit()
234 return -EINVAL; in init_charge_current_limit()
237 cur_limit = gpio_charger->current_limit_map[i].limit_ua; in init_charge_current_limit()
240 /* default to smallest current limitation for safety reasons */ in init_charge_current_limit()
241 len = gpio_charger->current_limit_map_size - 1; in init_charge_current_limit()
243 gpio_charger->current_limit_map[len].limit_ua); in init_charge_current_limit()
261 struct device *dev = &pdev->dev; in gpio_charger_probe()
262 const struct gpio_charger_platform_data *pdata = dev->platform_data; in gpio_charger_probe()
271 if (!pdata && !dev->of_node) { in gpio_charger_probe()
273 return -ENOENT; in gpio_charger_probe()
278 return -ENOMEM; in gpio_charger_probe()
279 gpio_charger->dev = dev; in gpio_charger_probe()
285 gpio_charger->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); in gpio_charger_probe()
286 if (IS_ERR(gpio_charger->gpiod)) { in gpio_charger_probe()
288 return dev_err_probe(dev, PTR_ERR(gpio_charger->gpiod), in gpio_charger_probe()
292 if (gpio_charger->gpiod) { in gpio_charger_probe()
297 charge_status = devm_gpiod_get_optional(dev, "charge-status", GPIOD_IN); in gpio_charger_probe()
301 gpio_charger->charge_status = charge_status; in gpio_charger_probe()
309 if (gpio_charger->current_limit_map) { in gpio_charger_probe()
315 charger_desc = &gpio_charger->charger_desc; in gpio_charger_probe()
316 charger_desc->properties = gpio_charger_properties; in gpio_charger_probe()
317 charger_desc->num_properties = num_props; in gpio_charger_probe()
318 charger_desc->get_property = gpio_charger_get_property; in gpio_charger_probe()
319 charger_desc->set_property = gpio_charger_set_property; in gpio_charger_probe()
320 charger_desc->property_is_writeable = in gpio_charger_probe()
323 psy_cfg.of_node = dev->of_node; in gpio_charger_probe()
327 charger_desc->name = pdata->name; in gpio_charger_probe()
328 charger_desc->type = pdata->type; in gpio_charger_probe()
329 psy_cfg.supplied_to = pdata->supplied_to; in gpio_charger_probe()
330 psy_cfg.num_supplicants = pdata->num_supplicants; in gpio_charger_probe()
332 charger_desc->name = dev->of_node->name; in gpio_charger_probe()
333 charger_desc->type = gpio_charger_get_type(dev); in gpio_charger_probe()
336 if (!charger_desc->name) in gpio_charger_probe()
337 charger_desc->name = pdev->name; in gpio_charger_probe()
339 gpio_charger->charger = devm_power_supply_register(dev, charger_desc, in gpio_charger_probe()
341 if (IS_ERR(gpio_charger->charger)) { in gpio_charger_probe()
342 ret = PTR_ERR(gpio_charger->charger); in gpio_charger_probe()
347 gpio_charger->irq = gpio_charger_get_irq(dev, gpio_charger->charger, in gpio_charger_probe()
348 gpio_charger->gpiod); in gpio_charger_probe()
350 charge_status_irq = gpio_charger_get_irq(dev, gpio_charger->charger, in gpio_charger_probe()
351 gpio_charger->charge_status); in gpio_charger_probe()
352 gpio_charger->charge_status_irq = charge_status_irq; in gpio_charger_probe()
367 gpio_charger->wakeup_enabled = in gpio_charger_suspend()
368 !enable_irq_wake(gpio_charger->irq); in gpio_charger_suspend()
377 if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled) in gpio_charger_resume()
378 disable_irq_wake(gpio_charger->irq); in gpio_charger_resume()
379 power_supply_changed(gpio_charger->charger); in gpio_charger_resume()
389 { .compatible = "gpio-charger" },
397 .name = "gpio-charger",
405 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
408 MODULE_ALIAS("platform:gpio-charger");