Lines Matching +full:current +full:- +full:limit
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2010, Lars-Peter Clausen <[email protected]>
18 #include <linux/power/gpio-charger.h>
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()
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()
201 gpio_charger->current_limit_gpios = devm_gpiod_get_array_optional(dev, in init_charge_current_limit()
202 "charge-current-limit", GPIOD_OUT_LOW); in init_charge_current_limit()
203 if (IS_ERR(gpio_charger->current_limit_gpios)) { in init_charge_current_limit()
204 dev_err(dev, "error getting current-limit GPIOs\n"); in init_charge_current_limit()
205 return PTR_ERR(gpio_charger->current_limit_gpios); in init_charge_current_limit()
208 if (!gpio_charger->current_limit_gpios) in init_charge_current_limit()
211 len = device_property_read_u32_array(dev, "charge-current-limit-mapping", in init_charge_current_limit()
217 dev_err(dev, "invalid charge-current-limit-mapping length\n"); in init_charge_current_limit()
218 return -EINVAL; in init_charge_current_limit()
221 gpio_charger->current_limit_map = devm_kmalloc_array(dev, in init_charge_current_limit()
222 len / 2, sizeof(*gpio_charger->current_limit_map), GFP_KERNEL); in init_charge_current_limit()
223 if (!gpio_charger->current_limit_map) in init_charge_current_limit()
224 return -ENOMEM; in init_charge_current_limit()
226 gpio_charger->current_limit_map_size = len / 2; in init_charge_current_limit()
228 len = device_property_read_u32_array(dev, "charge-current-limit-mapping", in init_charge_current_limit()
229 (u32*) gpio_charger->current_limit_map, len); in init_charge_current_limit()
234 "charge-current-limit-default-microamp", in init_charge_current_limit()
236 for (i=0; i < gpio_charger->current_limit_map_size; i++) { in init_charge_current_limit()
237 if (gpio_charger->current_limit_map[i].limit_ua > cur_limit) { in init_charge_current_limit()
238 dev_err(dev, "charge-current-limit-mapping not sorted by current in descending order\n"); in init_charge_current_limit()
239 return -EINVAL; in init_charge_current_limit()
242 cur_limit = gpio_charger->current_limit_map[i].limit_ua; in init_charge_current_limit()
250 …dev_warn(dev, "charge-current-limit-default-microamp %u not listed in charge-current-limit-mapping… in init_charge_current_limit()
253 /* default to smallest current limitation for safety reasons */ in init_charge_current_limit()
254 len = gpio_charger->current_limit_map_size - 1; in init_charge_current_limit()
256 gpio_charger->current_limit_map[len].limit_ua); in init_charge_current_limit()
274 struct device *dev = &pdev->dev; in gpio_charger_probe()
275 const struct gpio_charger_platform_data *pdata = dev->platform_data; in gpio_charger_probe()
284 if (!pdata && !dev->of_node) { in gpio_charger_probe()
286 return -ENOENT; in gpio_charger_probe()
291 return -ENOMEM; in gpio_charger_probe()
292 gpio_charger->dev = dev; in gpio_charger_probe()
298 gpio_charger->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); in gpio_charger_probe()
299 if (IS_ERR(gpio_charger->gpiod)) { in gpio_charger_probe()
301 return dev_err_probe(dev, PTR_ERR(gpio_charger->gpiod), in gpio_charger_probe()
305 if (gpio_charger->gpiod) { in gpio_charger_probe()
310 charge_status = devm_gpiod_get_optional(dev, "charge-status", GPIOD_IN); in gpio_charger_probe()
314 gpio_charger->charge_status = charge_status; in gpio_charger_probe()
322 if (gpio_charger->current_limit_map) { in gpio_charger_probe()
328 charger_desc = &gpio_charger->charger_desc; in gpio_charger_probe()
329 charger_desc->properties = gpio_charger_properties; in gpio_charger_probe()
330 charger_desc->num_properties = num_props; in gpio_charger_probe()
331 charger_desc->get_property = gpio_charger_get_property; in gpio_charger_probe()
332 charger_desc->set_property = gpio_charger_set_property; in gpio_charger_probe()
333 charger_desc->property_is_writeable = in gpio_charger_probe()
336 psy_cfg.of_node = dev->of_node; in gpio_charger_probe()
340 charger_desc->name = pdata->name; in gpio_charger_probe()
341 charger_desc->type = pdata->type; in gpio_charger_probe()
342 psy_cfg.supplied_to = pdata->supplied_to; in gpio_charger_probe()
343 psy_cfg.num_supplicants = pdata->num_supplicants; in gpio_charger_probe()
345 charger_desc->name = dev->of_node->name; in gpio_charger_probe()
346 charger_desc->type = gpio_charger_get_type(dev); in gpio_charger_probe()
349 if (!charger_desc->name) in gpio_charger_probe()
350 charger_desc->name = pdev->name; in gpio_charger_probe()
352 gpio_charger->charger = devm_power_supply_register(dev, charger_desc, in gpio_charger_probe()
354 if (IS_ERR(gpio_charger->charger)) { in gpio_charger_probe()
355 ret = PTR_ERR(gpio_charger->charger); in gpio_charger_probe()
360 gpio_charger->irq = gpio_charger_get_irq(dev, gpio_charger->charger, in gpio_charger_probe()
361 gpio_charger->gpiod); in gpio_charger_probe()
363 charge_status_irq = gpio_charger_get_irq(dev, gpio_charger->charger, in gpio_charger_probe()
364 gpio_charger->charge_status); in gpio_charger_probe()
365 gpio_charger->charge_status_irq = charge_status_irq; in gpio_charger_probe()
380 gpio_charger->wakeup_enabled = in gpio_charger_suspend()
381 !enable_irq_wake(gpio_charger->irq); in gpio_charger_suspend()
390 if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled) in gpio_charger_resume()
391 disable_irq_wake(gpio_charger->irq); in gpio_charger_resume()
392 power_supply_changed(gpio_charger->charger); in gpio_charger_resume()
402 { .compatible = "gpio-charger" },
410 .name = "gpio-charger",
418 MODULE_AUTHOR("Lars-Peter Clausen <[email protected]>");
421 MODULE_ALIAS("platform:gpio-charger");