Lines Matching +full:gpio +full:- +full:charger

1 // SPDX-License-Identifier: GPL-2.0
3 * Extcon charger detection driver for Intel Cherrytrail Whiskey Cove PMIC
7 * Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
10 #include <linux/extcon-provider.h>
20 #include "extcon-intel.h"
63 /* 0 - open drain, 1 - regular push-pull output */
65 /* 0 - pin is controlled by SW, 1 - by HW */
132 /* Charger detection can take upto 600ms, wait 800ms max. */ in cht_wc_extcon_get_charger()
135 ret = regmap_read(ext->regmap, CHT_WC_USBSRC, &usbsrc); in cht_wc_extcon_get_charger()
137 dev_err(ext->dev, "Error reading usbsrc: %d\n", ret); in cht_wc_extcon_get_charger()
154 dev_warn(ext->dev, "Could not detect charger type\n"); in cht_wc_extcon_get_charger()
156 dev_warn(ext->dev, "Timeout detecting charger type\n"); in cht_wc_extcon_get_charger()
163 dev_warn(ext->dev, in cht_wc_extcon_get_charger()
164 "Unhandled charger type %d, defaulting to SDP\n", in cht_wc_extcon_get_charger()
186 ret = regmap_write(ext->regmap, CHT_WC_PHYCTRL, state); in cht_wc_extcon_set_phymux()
188 dev_err(ext->dev, "Error writing phyctrl: %d\n", ret); in cht_wc_extcon_set_phymux()
197 * The 5V boost converter is enabled through a gpio on the PMIC, since in cht_wc_extcon_set_5v_boost()
198 * there currently is no gpio driver we access the gpio reg directly. in cht_wc_extcon_set_5v_boost()
204 ret = regmap_write(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, val); in cht_wc_extcon_set_5v_boost()
206 dev_err(ext->dev, "Error writing Vbus GPIO CTLO: %d\n", ret); in cht_wc_extcon_set_5v_boost()
215 ret = regmap_update_bits(ext->regmap, CHT_WC_CHGRCTRL1, in cht_wc_extcon_set_otgmode()
218 dev_err(ext->dev, "Error updating CHGRCTRL1 reg: %d\n", ret); in cht_wc_extcon_set_otgmode()
227 ret = regmap_update_bits(ext->regmap, CHT_WC_CHGDISCTRL, in cht_wc_extcon_enable_charging()
230 dev_err(ext->dev, "Error updating CHGDISCTRL reg: %d\n", ret); in cht_wc_extcon_enable_charging()
237 extcon_set_state_sync(ext->edev, cable, state); in cht_wc_extcon_set_state()
239 extcon_set_state_sync(ext->edev, EXTCON_USB, state); in cht_wc_extcon_set_state()
247 bool ignore_get_charger_errors = ext->usb_host; in cht_wc_extcon_pwrsrc_event()
249 ret = regmap_read(ext->regmap, CHT_WC_PWRSRC_STS, &pwrsrc_sts); in cht_wc_extcon_pwrsrc_event()
251 dev_err(ext->dev, "Error reading pwrsrc status: %d\n", ret); in cht_wc_extcon_pwrsrc_event()
267 /* Plugged into a host/charger or not connected? */ in cht_wc_extcon_pwrsrc_event()
269 /* Route D+ and D- to PMIC for future charger detection */ in cht_wc_extcon_pwrsrc_event()
279 /* Route D+ and D- to SoC for the host or gadget controller */ in cht_wc_extcon_pwrsrc_event()
283 if (cable != ext->previous_cable) { in cht_wc_extcon_pwrsrc_event()
285 cht_wc_extcon_set_state(ext, ext->previous_cable, false); in cht_wc_extcon_pwrsrc_event()
286 ext->previous_cable = cable; in cht_wc_extcon_pwrsrc_event()
289 ext->usb_host = ((id == INTEL_USB_ID_GND) || (id == INTEL_USB_RID_A)); in cht_wc_extcon_pwrsrc_event()
290 extcon_set_state_sync(ext->edev, EXTCON_USB_HOST, ext->usb_host); in cht_wc_extcon_pwrsrc_event()
298 ret = regmap_read(ext->regmap, CHT_WC_PWRSRC_IRQ, &irqs); in cht_wc_extcon_isr()
300 dev_err(ext->dev, "Error reading irqs: %d\n", ret); in cht_wc_extcon_isr()
306 ret = regmap_write(ext->regmap, CHT_WC_PWRSRC_IRQ, irqs); in cht_wc_extcon_isr()
308 dev_err(ext->dev, "Error writing irqs: %d\n", ret); in cht_wc_extcon_isr()
320 ret = regmap_update_bits(ext->regmap, CHT_WC_CHGDISCTRL, in cht_wc_extcon_sw_control()
323 dev_err(ext->dev, in cht_wc_extcon_sw_control()
329 ret = regmap_update_bits(ext->regmap, CHT_WC_CHGRCTRL0, mask, val); in cht_wc_extcon_sw_control()
331 dev_err(ext->dev, "Error setting sw control: %d\n", ret); in cht_wc_extcon_sw_control()
338 struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); in cht_wc_extcon_probe()
348 ext = devm_kzalloc(&pdev->dev, sizeof(*ext), GFP_KERNEL); in cht_wc_extcon_probe()
350 return -ENOMEM; in cht_wc_extcon_probe()
352 ext->dev = &pdev->dev; in cht_wc_extcon_probe()
353 ext->regmap = pmic->regmap; in cht_wc_extcon_probe()
354 ext->previous_cable = EXTCON_NONE; in cht_wc_extcon_probe()
357 ext->edev = devm_extcon_dev_allocate(ext->dev, cht_wc_extcon_cables); in cht_wc_extcon_probe()
358 if (IS_ERR(ext->edev)) in cht_wc_extcon_probe()
359 return PTR_ERR(ext->edev); in cht_wc_extcon_probe()
362 * When a host-cable is detected the BIOS enables an external 5v boost in cht_wc_extcon_probe()
364 * 1) This gets seen by the external battery charger as a valid Vbus in cht_wc_extcon_probe()
367 * (and unless we drive the external-charger-disable pin high it in cht_wc_extcon_probe()
370 * Since the external battery charger has its own 5v boost converter in cht_wc_extcon_probe()
381 /* Disable charging by external battery charger */ in cht_wc_extcon_probe()
385 ret = devm_extcon_dev_register(ext->dev, ext->edev); in cht_wc_extcon_probe()
387 dev_err(ext->dev, "Error registering extcon device: %d\n", ret); in cht_wc_extcon_probe()
391 ret = regmap_read(ext->regmap, CHT_WC_PWRSRC_STS, &pwrsrc_sts); in cht_wc_extcon_probe()
393 dev_err(ext->dev, "Error reading pwrsrc status: %d\n", ret); in cht_wc_extcon_probe()
398 * If no USB host or device connected, route D+ and D- to PMIC for in cht_wc_extcon_probe()
399 * initial charger detection in cht_wc_extcon_probe()
408 ret = devm_request_threaded_irq(ext->dev, irq, NULL, cht_wc_extcon_isr, in cht_wc_extcon_probe()
409 IRQF_ONESHOT, pdev->name, ext); in cht_wc_extcon_probe()
411 dev_err(ext->dev, "Error requesting interrupt: %d\n", ret); in cht_wc_extcon_probe()
416 ret = regmap_write(ext->regmap, CHT_WC_PWRSRC_IRQ_MASK, mask); in cht_wc_extcon_probe()
418 dev_err(ext->dev, "Error writing irq-mask: %d\n", ret); in cht_wc_extcon_probe()