Lines Matching +full:gpio +full:- +full:charger
2 * Battery charger driver for TI BQ24735
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include <linux/devm-helpers.h>
28 #include <linux/gpio/consumer.h>
32 #include <linux/power/bq24735-charger.h>
50 struct power_supply *charger; member
111 static int bq24735_config_charger(struct bq24735 *charger) in bq24735_config_charger() argument
113 struct bq24735_platform *pdata = charger->pdata; in bq24735_config_charger()
117 if (pdata->ext_control) in bq24735_config_charger()
120 if (pdata->charge_current) { in bq24735_config_charger()
121 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK; in bq24735_config_charger()
123 ret = bq24735_write_word(charger->client, in bq24735_config_charger()
126 dev_err(&charger->client->dev, in bq24735_config_charger()
127 "Failed to write charger current : %d\n", in bq24735_config_charger()
133 if (pdata->charge_voltage) { in bq24735_config_charger()
134 value = pdata->charge_voltage & BQ24735_CHARGE_VOLTAGE_MASK; in bq24735_config_charger()
136 ret = bq24735_write_word(charger->client, in bq24735_config_charger()
139 dev_err(&charger->client->dev, in bq24735_config_charger()
140 "Failed to write charger voltage : %d\n", in bq24735_config_charger()
146 if (pdata->input_current) { in bq24735_config_charger()
147 value = pdata->input_current & BQ24735_INPUT_CURRENT_MASK; in bq24735_config_charger()
149 ret = bq24735_write_word(charger->client, in bq24735_config_charger()
152 dev_err(&charger->client->dev, in bq24735_config_charger()
162 static inline int bq24735_enable_charging(struct bq24735 *charger) in bq24735_enable_charging() argument
166 if (charger->pdata->ext_control) in bq24735_enable_charging()
169 ret = bq24735_config_charger(charger); in bq24735_enable_charging()
173 return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT, in bq24735_enable_charging()
177 static inline int bq24735_disable_charging(struct bq24735 *charger) in bq24735_disable_charging() argument
179 if (charger->pdata->ext_control) in bq24735_disable_charging()
182 return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT, in bq24735_disable_charging()
187 static bool bq24735_charger_is_present(struct bq24735 *charger) in bq24735_charger_is_present() argument
189 if (charger->status_gpio) { in bq24735_charger_is_present()
190 return !gpiod_get_value_cansleep(charger->status_gpio); in bq24735_charger_is_present()
194 ac = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT); in bq24735_charger_is_present()
196 dev_dbg(&charger->client->dev, in bq24735_charger_is_present()
197 "Failed to read charger options : %d\n", in bq24735_charger_is_present()
207 static int bq24735_charger_is_charging(struct bq24735 *charger) in bq24735_charger_is_charging() argument
211 if (!bq24735_charger_is_present(charger)) in bq24735_charger_is_charging()
214 ret = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT); in bq24735_charger_is_charging()
221 static void bq24735_update(struct bq24735 *charger) in bq24735_update() argument
223 mutex_lock(&charger->lock); in bq24735_update()
225 if (charger->charging && bq24735_charger_is_present(charger)) in bq24735_update()
226 bq24735_enable_charging(charger); in bq24735_update()
228 bq24735_disable_charging(charger); in bq24735_update()
230 mutex_unlock(&charger->lock); in bq24735_update()
232 power_supply_changed(charger->charger); in bq24735_update()
238 struct bq24735 *charger = to_bq24735(psy); in bq24735_charger_isr() local
240 bq24735_update(charger); in bq24735_charger_isr()
247 struct bq24735 *charger = container_of(work, struct bq24735, poll.work); in bq24735_poll() local
249 bq24735_update(charger); in bq24735_poll()
251 schedule_delayed_work(&charger->poll, in bq24735_poll()
252 msecs_to_jiffies(charger->poll_interval)); in bq24735_poll()
259 struct bq24735 *charger = to_bq24735(psy); in bq24735_charger_get_property() local
263 val->intval = bq24735_charger_is_present(charger) ? 1 : 0; in bq24735_charger_get_property()
266 switch (bq24735_charger_is_charging(charger)) { in bq24735_charger_get_property()
268 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bq24735_charger_get_property()
271 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bq24735_charger_get_property()
274 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in bq24735_charger_get_property()
279 return -EINVAL; in bq24735_charger_get_property()
289 struct bq24735 *charger = to_bq24735(psy); in bq24735_charger_set_property() local
294 switch (val->intval) { in bq24735_charger_set_property()
296 mutex_lock(&charger->lock); in bq24735_charger_set_property()
297 charger->charging = true; in bq24735_charger_set_property()
298 ret = bq24735_enable_charging(charger); in bq24735_charger_set_property()
299 mutex_unlock(&charger->lock); in bq24735_charger_set_property()
305 mutex_lock(&charger->lock); in bq24735_charger_set_property()
306 charger->charging = false; in bq24735_charger_set_property()
307 ret = bq24735_disable_charging(charger); in bq24735_charger_set_property()
308 mutex_unlock(&charger->lock); in bq24735_charger_set_property()
313 return -EINVAL; in bq24735_charger_set_property()
318 return -EPERM; in bq24735_charger_set_property()
327 struct device_node *np = client->dev.of_node; in bq24735_parse_dt_data()
331 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); in bq24735_parse_dt_data()
333 dev_err(&client->dev, in bq24735_parse_dt_data()
338 ret = of_property_read_u32(np, "ti,charge-current", &val); in bq24735_parse_dt_data()
340 pdata->charge_current = val; in bq24735_parse_dt_data()
342 ret = of_property_read_u32(np, "ti,charge-voltage", &val); in bq24735_parse_dt_data()
344 pdata->charge_voltage = val; in bq24735_parse_dt_data()
346 ret = of_property_read_u32(np, "ti,input-current", &val); in bq24735_parse_dt_data()
348 pdata->input_current = val; in bq24735_parse_dt_data()
350 pdata->ext_control = of_property_read_bool(np, "ti,external-control"); in bq24735_parse_dt_data()
358 struct bq24735 *charger; in bq24735_charger_probe() local
363 charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); in bq24735_charger_probe()
364 if (!charger) in bq24735_charger_probe()
365 return -ENOMEM; in bq24735_charger_probe()
367 mutex_init(&charger->lock); in bq24735_charger_probe()
368 charger->charging = true; in bq24735_charger_probe()
369 charger->pdata = client->dev.platform_data; in bq24735_charger_probe()
371 if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) in bq24735_charger_probe()
372 charger->pdata = bq24735_parse_dt_data(client); in bq24735_charger_probe()
374 if (!charger->pdata) { in bq24735_charger_probe()
375 dev_err(&client->dev, "no platform data provided\n"); in bq24735_charger_probe()
376 return -EINVAL; in bq24735_charger_probe()
379 name = (char *)charger->pdata->name; in bq24735_charger_probe()
381 name = devm_kasprintf(&client->dev, GFP_KERNEL, in bq24735_charger_probe()
383 dev_name(&client->dev)); in bq24735_charger_probe()
385 dev_err(&client->dev, "Failed to alloc device name\n"); in bq24735_charger_probe()
386 return -ENOMEM; in bq24735_charger_probe()
390 charger->client = client; in bq24735_charger_probe()
392 supply_desc = &charger->charger_desc; in bq24735_charger_probe()
394 supply_desc->name = name; in bq24735_charger_probe()
395 supply_desc->type = POWER_SUPPLY_TYPE_MAINS; in bq24735_charger_probe()
396 supply_desc->properties = bq24735_charger_properties; in bq24735_charger_probe()
397 supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); in bq24735_charger_probe()
398 supply_desc->get_property = bq24735_charger_get_property; in bq24735_charger_probe()
399 supply_desc->set_property = bq24735_charger_set_property; in bq24735_charger_probe()
400 supply_desc->property_is_writeable = in bq24735_charger_probe()
403 psy_cfg.supplied_to = charger->pdata->supplied_to; in bq24735_charger_probe()
404 psy_cfg.num_supplicants = charger->pdata->num_supplicants; in bq24735_charger_probe()
405 psy_cfg.of_node = client->dev.of_node; in bq24735_charger_probe()
406 psy_cfg.drv_data = charger; in bq24735_charger_probe()
408 i2c_set_clientdata(client, charger); in bq24735_charger_probe()
410 charger->status_gpio = devm_gpiod_get_optional(&client->dev, in bq24735_charger_probe()
411 "ti,ac-detect", in bq24735_charger_probe()
413 if (IS_ERR(charger->status_gpio)) { in bq24735_charger_probe()
414 ret = PTR_ERR(charger->status_gpio); in bq24735_charger_probe()
415 dev_err(&client->dev, "Getting gpio failed: %d\n", ret); in bq24735_charger_probe()
419 if (bq24735_charger_is_present(charger)) { in bq24735_charger_probe()
422 dev_err(&client->dev, "Failed to read manufacturer id : %d\n", in bq24735_charger_probe()
426 dev_err(&client->dev, in bq24735_charger_probe()
428 return -ENODEV; in bq24735_charger_probe()
433 dev_err(&client->dev, "Failed to read device id : %d\n", ret); in bq24735_charger_probe()
436 dev_err(&client->dev, in bq24735_charger_probe()
438 return -ENODEV; in bq24735_charger_probe()
441 ret = bq24735_enable_charging(charger); in bq24735_charger_probe()
443 dev_err(&client->dev, "Failed to enable charging\n"); in bq24735_charger_probe()
448 charger->charger = devm_power_supply_register(&client->dev, supply_desc, in bq24735_charger_probe()
450 if (IS_ERR(charger->charger)) { in bq24735_charger_probe()
451 ret = PTR_ERR(charger->charger); in bq24735_charger_probe()
452 dev_err(&client->dev, "Failed to register power supply: %d\n", in bq24735_charger_probe()
457 if (client->irq) { in bq24735_charger_probe()
458 ret = devm_request_threaded_irq(&client->dev, client->irq, in bq24735_charger_probe()
463 supply_desc->name, in bq24735_charger_probe()
464 charger->charger); in bq24735_charger_probe()
466 dev_err(&client->dev, in bq24735_charger_probe()
468 client->irq, ret); in bq24735_charger_probe()
472 ret = device_property_read_u32(&client->dev, "poll-interval", in bq24735_charger_probe()
473 &charger->poll_interval); in bq24735_charger_probe()
476 if (!charger->poll_interval) in bq24735_charger_probe()
479 ret = devm_delayed_work_autocancel(&client->dev, &charger->poll, in bq24735_charger_probe()
484 schedule_delayed_work(&charger->poll, in bq24735_charger_probe()
485 msecs_to_jiffies(charger->poll_interval)); in bq24735_charger_probe()
492 { "bq24735-charger" },
505 .name = "bq24735-charger",