Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a09572d0 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-smbcharger: add support for HVDCP detection



Currently, we detect SDP, CDP and DCP chargers over the USB. Extend
the support for the detection of HVDCP chargers as well. Notify the
detection of HVDCP to usb power supply (if present) after the charger
insertion.

CRs-Fixed: 775241
Change-Id: I37072d63f7ecbbced5c3bf44f2586ea9a4fc46e8
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 7c2f2dda
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -199,6 +199,7 @@ struct smbchg_chip {
	struct work_struct		usb_set_online_work;
	struct work_struct		batt_soc_work;
	struct delayed_work		vfloat_adjust_work;
	struct delayed_work		hvdcp_det_work;
	spinlock_t			sec_access_lock;
	struct mutex			current_change_lock;
	struct mutex			usb_set_online_lock;
@@ -3345,6 +3346,30 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip)
		get_prop_charge_type(chip) == POWER_SUPPLY_CHARGE_TYPE_TAPER);
}

static void smbchg_hvdcp_det_work(struct work_struct *work)
{
	struct smbchg_chip *chip = container_of(work,
				struct smbchg_chip,
				hvdcp_det_work.work);
	int rc;
	u8 reg;

	rc = smbchg_read(chip, &reg,
			chip->usb_chgpth_base + USBIN_HVDCP_STS, 1);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't read hvdcp status rc = %d\n", rc);
		return;
	}

	/*
	 * If a valid HVDCP is detected, notify it to the usb_psy only
	 * if USB is still present.
	 */
	if ((reg & USBIN_HVDCP_SEL_BIT) && is_usb_present(chip))
		power_supply_set_supply_type(chip->usb_psy,
				POWER_SUPPLY_TYPE_USB_HVDCP);
}

static irqreturn_t chg_term_handler(int irq, void *_chip)
{
	struct smbchg_chip *chip = _chip;
@@ -3465,6 +3490,7 @@ static void handle_usb_removal(struct smbchg_chip *chip)
	}
}

#define HVDCP_NOTIFY_MS		2500
static void handle_usb_insertion(struct smbchg_chip *chip)
{
	struct power_supply *parallel_psy = get_parallel_psy(chip);
@@ -3490,6 +3516,8 @@ static void handle_usb_insertion(struct smbchg_chip *chip)
				chip->usb_present);
		power_supply_set_present(chip->usb_psy, chip->usb_present);
		schedule_work(&chip->usb_set_online_work);
		schedule_delayed_work(&chip->hvdcp_det_work,
					msecs_to_jiffies(HVDCP_NOTIFY_MS));
	}
	if (parallel_psy)
		power_supply_set_present(parallel_psy, true);
@@ -4678,6 +4706,7 @@ static int smbchg_probe(struct spmi_device *spmi)
	INIT_DELAYED_WORK(&chip->parallel_en_work,
			smbchg_parallel_usb_en_work);
	INIT_DELAYED_WORK(&chip->vfloat_adjust_work, smbchg_vfloat_adjust_work);
	INIT_DELAYED_WORK(&chip->hvdcp_det_work, smbchg_hvdcp_det_work);
	chip->vadc_dev = vadc_dev;
	chip->spmi = spmi;
	chip->dev = &spmi->dev;