Lines Matching +full:usb +full:- +full:charger

1 // SPDX-License-Identifier: GPL-2.0
3 * TWL6030 charger
24 #include <linux/usb/otg.h>
26 #include <linux/devm-helpers.h>
48 /* TWL6032 registers 0xDA to 0xDE - TWL6032_MODULE_CHARGER */
139 #define UA_TO_VITERM(x) (((x) / 50000 - 1) << 5)
149 #define UV_TO_VOREG(x) (((x) - 3500000) / 20000)
161 #define UA_TO_VICHRG(x) (((x) / 100000) - 1)
194 struct power_supply *usb; member
218 static int twl6030_config_cinlimit_reg(struct twl6030_charger_info *charger, in twl6030_config_cinlimit_reg() argument
222 ua = (ua - 50000) / 50000; in twl6030_config_cinlimit_reg()
223 } else if ((ua > 750000) && (ua <= 1500000) && charger->extended_current_range) { in twl6030_config_cinlimit_reg()
224 ua = ((ua % 100000) ? 0x30 : 0x20) + ((ua - 100000) / 100000); in twl6030_config_cinlimit_reg()
227 dev_err(charger->dev, "invalid input current limit\n"); in twl6030_config_cinlimit_reg()
228 return -EINVAL; in twl6030_config_cinlimit_reg()
241 static int twl6030_enable_usb(struct twl6030_charger_info *charger) in twl6030_enable_usb() argument
246 UA_TO_VICHRG(charger->binfo->constant_charge_current_max_ua)); in twl6030_enable_usb()
254 charger->input_current_limit = 500000; in twl6030_enable_usb()
255 ret = twl6030_config_cinlimit_reg(charger, charger->input_current_limit); in twl6030_enable_usb()
264 UV_TO_VOREG(charger->binfo->constant_charge_voltage_max_uv)); in twl6030_enable_usb()
272 if (charger->binfo->charge_term_current_ua != -EINVAL) { in twl6030_enable_usb()
274 UA_TO_VITERM(charger->binfo->charge_term_current_ua)); in twl6030_enable_usb()
284 struct twl6030_charger_info *charger = in twl6030_charger_wdg() local
297 dev_dbg(charger->dev, in twl6030_charger_wdg()
299 val, (val & VBUS_DET) ? "usb online" : "usb offline", in twl6030_charger_wdg()
303 schedule_delayed_work(&charger->charger_monitor, in twl6030_charger_wdg()
309 struct twl6030_charger_info *charger = arg; in twl6030_charger_interrupt() local
327 dev_dbg(charger->dev, in twl6030_charger_interrupt()
328 "charger irq: stat1: %02x %s INT_STATUS %02x STATUS_INT1 %02x STATUS_INT2 %02x\n", in twl6030_charger_interrupt()
329 val, (val & VBUS_DET) ? "usb online" : "usb offline", in twl6030_charger_interrupt()
331 power_supply_changed(charger->usb); in twl6030_charger_interrupt()
338 if (twl6030_enable_usb(charger) < 0) in twl6030_charger_interrupt()
341 schedule_delayed_work(&charger->charger_monitor, in twl6030_charger_interrupt()
345 cancel_delayed_work(&charger->charger_monitor); in twl6030_charger_interrupt()
354 struct twl6030_charger_info *charger = power_supply_get_drvdata(psy); in twl6030_charger_usb_get_property() local
366 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in twl6030_charger_usb_get_property()
374 val->intval = POWER_SUPPLY_STATUS_FULL; in twl6030_charger_usb_get_property()
376 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in twl6030_charger_usb_get_property()
378 val->intval = POWER_SUPPLY_STATUS_CHARGING; in twl6030_charger_usb_get_property()
381 if (!charger->channel_vusb) in twl6030_charger_usb_get_property()
382 return -ENODATA; in twl6030_charger_usb_get_property()
384 ret = iio_read_channel_processed_scale(charger->channel_vusb, &val->intval, 1000); in twl6030_charger_usb_get_property()
390 val->intval = !!(stat1 & VBUS_DET); in twl6030_charger_usb_get_property()
393 val->intval = charger->input_current_limit; in twl6030_charger_usb_get_property()
396 return -EINVAL; in twl6030_charger_usb_get_property()
406 struct twl6030_charger_info *charger = power_supply_get_drvdata(psy); in twl6030_charger_usb_set_property() local
410 charger->input_current_limit = val->intval; in twl6030_charger_usb_set_property()
411 return twl6030_config_cinlimit_reg(charger, charger->input_current_limit); in twl6030_charger_usb_set_property()
413 return -EINVAL; in twl6030_charger_usb_set_property()
422 dev_info(&psy->dev, "is %d writeable?\n", (int)psp); in twl6030_charger_usb_property_is_writeable()
450 struct twl6030_charger_info *charger; in twl6030_charger_probe() local
456 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); in twl6030_charger_probe()
457 if (!charger) in twl6030_charger_probe()
458 return -ENOMEM; in twl6030_charger_probe()
460 charger->dev = &pdev->dev; in twl6030_charger_probe()
461 charger->irq_chg = platform_get_irq(pdev, 0); in twl6030_charger_probe()
463 chip_data = device_get_match_data(&pdev->dev); in twl6030_charger_probe()
465 return dev_err_probe(&pdev->dev, -EINVAL, "missing chip data\n"); in twl6030_charger_probe()
467 charger->extended_current_range = chip_data->extended_current_range; in twl6030_charger_probe()
468 platform_set_drvdata(pdev, charger); in twl6030_charger_probe()
469 psy_cfg.drv_data = charger; in twl6030_charger_probe()
470 psy_cfg.fwnode = dev_fwnode(&pdev->dev); in twl6030_charger_probe()
472 charger->channel_vusb = devm_iio_channel_get(&pdev->dev, "vusb"); in twl6030_charger_probe()
473 if (IS_ERR(charger->channel_vusb)) { in twl6030_charger_probe()
474 ret = PTR_ERR(charger->channel_vusb); in twl6030_charger_probe()
475 if (ret == -EPROBE_DEFER) in twl6030_charger_probe()
477 dev_warn(&pdev->dev, "could not request vusb iio channel (%d)", in twl6030_charger_probe()
479 charger->channel_vusb = NULL; in twl6030_charger_probe()
482 charger->usb = devm_power_supply_register(&pdev->dev, in twl6030_charger_probe()
485 if (IS_ERR(charger->usb)) in twl6030_charger_probe()
486 return dev_err_probe(&pdev->dev, PTR_ERR(charger->usb), in twl6030_charger_probe()
487 "Failed to register usb\n"); in twl6030_charger_probe()
489 ret = power_supply_get_battery_info(charger->usb, &charger->binfo); in twl6030_charger_probe()
491 return dev_err_probe(&pdev->dev, ret, in twl6030_charger_probe()
494 dev_info(&pdev->dev, "battery with vmax %d imax: %d\n", in twl6030_charger_probe()
495 charger->binfo->constant_charge_voltage_max_uv, in twl6030_charger_probe()
496 charger->binfo->constant_charge_current_max_ua); in twl6030_charger_probe()
498 if (charger->binfo->constant_charge_voltage_max_uv == -EINVAL) { in twl6030_charger_probe()
503 charger->binfo->constant_charge_voltage_max_uv = in twl6030_charger_probe()
507 if (charger->binfo->constant_charge_voltage_max_uv > 4760000 || in twl6030_charger_probe()
508 charger->binfo->constant_charge_voltage_max_uv < 350000) in twl6030_charger_probe()
509 return dev_err_probe(&pdev->dev, -EINVAL, in twl6030_charger_probe()
512 if (charger->binfo->constant_charge_current_max_ua == -EINVAL) { in twl6030_charger_probe()
517 charger->binfo->constant_charge_current_max_ua = VICHRG_TO_UA(val); in twl6030_charger_probe()
520 if (charger->binfo->constant_charge_current_max_ua < 100000 || in twl6030_charger_probe()
521 charger->binfo->constant_charge_current_max_ua > 1500000) { in twl6030_charger_probe()
522 return dev_err_probe(&pdev->dev, -EINVAL, in twl6030_charger_probe()
526 if ((charger->binfo->charge_term_current_ua != -EINVAL) && in twl6030_charger_probe()
527 (charger->binfo->charge_term_current_ua > 400000 || in twl6030_charger_probe()
528 charger->binfo->charge_term_current_ua < 50000)) { in twl6030_charger_probe()
529 return dev_err_probe(&pdev->dev, -EINVAL, in twl6030_charger_probe()
533 ret = devm_delayed_work_autocancel(&pdev->dev, in twl6030_charger_probe()
534 &charger->charger_monitor, in twl6030_charger_probe()
537 return dev_err_probe(&pdev->dev, ret, in twl6030_charger_probe()
540 ret = devm_request_threaded_irq(&pdev->dev, charger->irq_chg, NULL, in twl6030_charger_probe()
542 IRQF_ONESHOT, pdev->name, in twl6030_charger_probe()
543 charger); in twl6030_charger_probe()
545 return dev_err_probe(&pdev->dev, ret, in twl6030_charger_probe()
547 charger->irq_chg); in twl6030_charger_probe()
551 twl6030_charger_interrupt(0, charger); in twl6030_charger_probe()
565 {.compatible = "ti,twl6030-charger", .data = &twl6030_data},
566 {.compatible = "ti,twl6032-charger", .data = &twl6032_data},
580 MODULE_DESCRIPTION("TWL6030 Battery Charger Interface driver");