/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2020 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/of.h>
#include <linux/time.h>
#include <linux/usb/pd.h>
#include <linux/usb/tcpm.h>
#include <linux/alarmtimer.h>
#include "google_bms.h"
#include "google_psy.h"
#include "google_dc_pps.h"
#include "../../drivers/usb/typec/tcpm/google/max77759_export.h"

#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#endif

#define PPS_UPDATE_DELAY_MS		2000

#define get_boot_sec() div_u64(ktime_to_ns(ktime_get_boottime()), NSEC_PER_SEC)

void pps_log(struct pd_pps_data *pps, const char *fmt, ...)
{
	va_list args;

	if (!pps || !pps->log)
		return;

	va_start(args, fmt);
	logbuffer_vlog(pps->log, fmt, args);
	va_end(args);
}
// EXPORT_SYMBOL_GPL(pps_log);

/*
 * State is initialized to PPS_DISABLED and SW will enable detect setting
 * ->stage to PPS_NONE and calling pps_work() until the state becomes
 * PPS_ACTIVE or PPS_NOTSUPP.
 */
void pps_init_state(struct pd_pps_data *pps_data)
{
	/* pps_data->src_caps can be NULL */
	if (pps_data->src_caps) {
		if (!pps_data->nr_src_cap)
			pr_err("%s: %s non zero src_caps, zero nr_src_cap\n",
			       __func__, pps_name(pps_data->pps_psy));
		tcpm_put_partner_src_caps(&pps_data->src_caps);
	}

	pps_data->pd_online = PPS_PSY_OFFLINE;
	pps_data->stage = PPS_DISABLED;
	pps_data->keep_alive_cnt = 0;
	pps_data->nr_src_cap = 0;
	pps_data->src_caps = NULL;

	/* not reference counted */
	if (pps_data->stay_awake)
		__pm_relax(pps_data->pps_ws);

}
// EXPORT_SYMBOL_GPL(pps_init_state);

/*
 * pps_psy can be tcpm, wireless or gcpm_pps.
 * NOTE: gcpm_pps route the props to the underlying psy
 */
static int pps_check_type(struct pd_pps_data *pps_data,
			  struct power_supply *pps_psy)
{
	union power_supply_propval pval;
	int ret;

	if (!pps_psy->desc)
		return -EINVAL;

	/* TODO: add POWER_SUPPLY_TYPE_PPS_PORT? */
	pr_debug("%s: name=%s type=%d\n", __func__, pps_name(pps_psy),
		 pps_psy->desc->type);
	if (pps_psy->desc->type == POWER_SUPPLY_TYPE_WIRELESS)
		return true;

	/* NOTE: this keep trying with "slow" adapters */
	ret = power_supply_get_property(pps_psy, POWER_SUPPLY_PROP_USB_TYPE, &pval);
	pr_debug("%s: name=%s type=%d ret=%d\n", __func__, pps_name(pps_psy),
		 pval.intval, ret);
	if (ret == 0 && pval.intval == POWER_SUPPLY_USB_TYPE_PD_PPS)
		return true;
	if (ret == 0 && pval.intval == POWER_SUPPLY_USB_TYPE_PD)
		return true;
	if (ret == 0 && pval.intval == POWER_SUPPLY_USB_TYPE_C)
		return true;

	return false;
}

/* always call with a tcpm_psy */
struct tcpm_port *chg_get_tcpm_port(struct power_supply *tcpm_psy)
{
	union power_supply_propval pval;
	void *port = NULL;
	int ret;

	/* port is valid for a tcpm power supply but not for gcpm */
	ret = power_supply_get_property(tcpm_psy, POWER_SUPPLY_PROP_USB_TYPE, &pval);
	if (ret == 0 && (pval.intval == POWER_SUPPLY_USB_TYPE_PD_PPS ||
			 pval.intval == POWER_SUPPLY_USB_TYPE_PD ||
			 pval.intval == POWER_SUPPLY_USB_TYPE_C))
		port = power_supply_get_drvdata(tcpm_psy);

	/* TODO: make sure that tcpm_psy is really a tcpm source */

	return (struct tcpm_port *)port;
}


/* false when not present or error (either way don't run) */
static enum pd_pps_stage pps_is_avail(struct pd_pps_data *pps,
				      struct power_supply *tcpm_psy)
{
	/* TODO: make silent, check return value and value */
	pps->max_uv = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_VOLTAGE_MAX);
	pps->min_uv = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_VOLTAGE_MIN);
	pps->max_ua = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_CURRENT_MAX);
	pps->out_uv = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW);
	pps->op_ua = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_CURRENT_NOW);
	if (pps->max_uv < 0 || pps->min_uv < 0 || pps->max_ua < 0 ||
		pps->out_uv < 0 || pps->op_ua < 0)
		return PPS_NONE;

	/* TODO: lower the loglevel after the development stage */
	pps_log(pps, "max_v %d, min_v %d, max_c %d, out_v %d, op_c %d",
		pps->max_uv, pps->min_uv, pps->max_ua, pps->out_uv,
		pps->op_ua);

	/* FIXME: set interval to PD_T_PPS_TIMEOUT here may cause timeout */
	return PPS_AVAILABLE;
}

/* make sure that the adapter doesn't revert back to FIXED PDO */
int pps_ping(struct pd_pps_data *pps, struct power_supply *tcpm_psy)
{
	int rc;

	if (!tcpm_psy)
		return -ENODEV;

	/* NOTE: the adapter should already be in PROG_ONLINE */
	rc = GPSY_SET_PROP(tcpm_psy, POWER_SUPPLY_PROP_ONLINE,
			   PPS_PSY_PROG_ONLINE);
	if (rc == 0)
		pps->pd_online = PPS_PSY_PROG_ONLINE;
	else if (rc != -EAGAIN && rc != -EOPNOTSUPP)
		pps_log(pps, "failed to ping, ret = %d", rc);

	return rc;
}
// EXPORT_SYMBOL_GPL(pps_ping);

/* */
int pps_get_src_cap(struct pd_pps_data *pps, struct power_supply *tcpm_psy)
{
	struct tcpm_port *port;

	if (!pps || !tcpm_psy)
		return -EINVAL;

	if (pps->nr_src_cap && pps->src_caps) {
		pr_debug("%s: %s using cached nr_src_cap=%d\n", __func__,
			 pps_name(tcpm_psy), pps->nr_src_cap);
		return pps->nr_src_cap;
	}

	port = chg_get_tcpm_port(tcpm_psy);
	if (port) {
		int nr_src_cap;

		if (pps->src_caps)
			pr_debug("%s: %s warning src_caps!=0, nr_src_cap=%d\n",
				 __func__, pps_name(tcpm_psy), pps->nr_src_cap);

		nr_src_cap = tcpm_get_partner_src_caps(port, &pps->src_caps);
		if (nr_src_cap < 0)
			return nr_src_cap;

		pr_debug("%s: %s found nr_src_cap=%d\n", __func__,
			 pps_name(tcpm_psy), nr_src_cap);
		pps->nr_src_cap = nr_src_cap;
	}

	return pps->nr_src_cap;
}
// EXPORT_SYMBOL_GPL(pps_get_src_cap);

bool pps_check_prog_online(struct pd_pps_data *pps_data)
{
	if (!pps_data || !pps_data->pps_psy)
		return false;

	return GPSY_GET_PROP(pps_data->pps_psy, POWER_SUPPLY_PROP_ONLINE) ==
	       PPS_PSY_PROG_ONLINE;
}

/*
 * bail if not online and PROG, query source caps and advance to ACTIVE
 * if not there.
 */
bool pps_prog_check_online(struct pd_pps_data *pps_data,
			  struct power_supply *tcpm_psy)
{
	int pd_online = 0;

	if (!pps_data || !tcpm_psy)
		return -ENODEV;

	pd_online = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_ONLINE);
	if (pd_online == 0) {
		pps_init_state(pps_data);
		return false;
	}

	if (pd_online != PPS_PSY_PROG_ONLINE)
		goto not_supp;

	/* make the transition to active */
	if (pps_data->stage != PPS_ACTIVE) {
		int rc;

		pps_data->stage = pps_is_avail(pps_data, tcpm_psy);
		if (pps_data->stage != PPS_AVAILABLE) {
			pr_debug("%s: not available\n", __func__);
			goto not_supp;
		}

		rc = pps_ping(pps_data, tcpm_psy);
		if (rc < 0) {
			pr_debug("%s: ping failed %d\n", __func__, rc);
			goto not_supp;
		}

		pps_data->last_update = get_boot_sec();
		rc = pps_get_src_cap(pps_data, tcpm_psy);
		if (rc < 0) {
			pr_debug("%s: no source caps %d\n", __func__, rc);
			goto not_supp;
		}

		pr_debug("%s: online & active nr_src_cap=%d\n",
			 __func__, pps_data->nr_src_cap);

		pps_data->pd_online = PPS_PSY_PROG_ONLINE;
		pps_data->stage = PPS_ACTIVE;
	}

	return true;

not_supp:
	pps_init_state(pps_data);
	pps_data->stage = PPS_NOTSUPP;
	return false;
}
// EXPORT_SYMBOL_GPL(pps_prog_check_online);

/*
 * enable PPS prog mode (Internal), also start the negotiation.
 * <0 when not supported, 0 if supported (and update state)
 */
static int pps_prog_online(struct pd_pps_data *pps,
			   struct power_supply *tcpm_psy)
{
	union power_supply_propval pval = { .intval = PPS_PSY_PROG_ONLINE, };
	int ret;

	ret = power_supply_set_property(tcpm_psy, POWER_SUPPLY_PROP_ONLINE, &pval);
	pr_debug("%s: name=%s ret=%d\n", __func__, pps_name(tcpm_psy), ret);

	if (ret == -EOPNOTSUPP) {
		pps->stage = PPS_NOTSUPP;
	} else if (ret == 0) {
		pps->pd_online = PPS_PSY_PROG_ONLINE;
		pps->stage = PPS_NONE;
	}

	pps->last_update = get_boot_sec();
	return ret;
}

/* Disable PPS prog mode, will end up in PPS_NOTSUP */
int pps_prog_offline(struct pd_pps_data *pps, struct power_supply *tcpm_psy)
{
	union power_supply_propval pval;
	int ret;

	if (!pps || !tcpm_psy)
		return -ENODEV;

	ret = power_supply_get_property(tcpm_psy, POWER_SUPPLY_PROP_ONLINE, &pval);
	if (ret < 0 || pval.intval != PPS_PSY_PROG_ONLINE)
		goto exit_done;

	pval.intval = PPS_PSY_FIXED_ONLINE;
	ret = power_supply_set_property(tcpm_psy, POWER_SUPPLY_PROP_ONLINE, &pval);

exit_done:
	pps_init_state(pps);
	return ret;
}
// EXPORT_SYMBOL_GPL(pps_prog_offline);

void pps_adjust_volt(struct pd_pps_data *pps, int mod)
{
	if (!pps)
		return;

	if (mod > 0) {
		pps->out_uv = (pps->out_uv + mod) < pps->max_uv ?
			      (pps->out_uv + mod) : pps->max_uv;
	} else if (mod < 0) {
		pps->out_uv = (pps->out_uv + mod) > pps->min_uv ?
			      (pps->out_uv + mod) : pps->min_uv;
	}
}


/* ------------------------------------------------------------------------ */

static int debug_get_pps_out_uv(void *data, u64 *val)
{
	struct pd_pps_data *pps_data = data;

	*val = pps_data->out_uv;
	return 0;
}

static int debug_set_pps_out_uv(void *data, u64 val)
{
	struct pd_pps_data *pps_data = data;

	/* TODO: use votable */
	pps_data->out_uv = val;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(debug_pps_out_uv_fops,
				debug_get_pps_out_uv,
				debug_set_pps_out_uv, "%llu\n");

static int debug_get_pps_op_ua(void *data, u64 *val)
{
	struct pd_pps_data *pps_data = data;

	*val = pps_data->op_ua;
	return 0;
}

static int debug_set_pps_op_ua(void *data, u64 val)
{
	struct pd_pps_data *pps_data = data;

	/* TODO: use votable */
	pps_data->op_ua = val;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(debug_pps_op_ua_fops,
					debug_get_pps_op_ua,
					debug_set_pps_op_ua, "%llu\n");

int pps_init_fs(struct pd_pps_data *pps_data, struct dentry *de)
{

	if (!de || !pps_data)
		return -EINVAL;

	debugfs_create_file("pps_out_uv", 0600, de, pps_data,
			    &debug_pps_out_uv_fops);
	debugfs_create_file("pps_out_ua", 0600, de, pps_data,
			    &debug_pps_op_ua_fops);
	debugfs_create_file("pps_op_ua", 0600, de, pps_data,
			    &debug_pps_op_ua_fops);

	return 0;
}

void pps_set_logbuffer(struct pd_pps_data *pps_data, struct logbuffer *log)
{
	pps_data->log = IS_ERR(log) ? NULL : log;
}

/* ------------------------------------------------------------------------ */

static int pps_get_sink_pdo(u32 *snk_pdo, int max, struct device_node *node)
{
	struct device_node *dn, *conn;
	unsigned int nr_snk_pdo;
	const __be32 *prop;
	int length, ret;

	prop = of_get_property(node, "google,usbc-connector", NULL);
	if (!prop)
		prop = of_get_property(node, "google,usb-c-connector", NULL);
	if (!prop)
		prop = of_get_property(node, "google,tcpm-power-supply", NULL);
	if (!prop)
		return -ENOENT;

	dn = of_find_node_by_phandle(be32_to_cpup(prop));
	if (!dn) {
		pr_err("Couldn't find usb_con node\n");
		return -ENOENT;
	}

	conn = of_get_child_by_name(dn, "connector");
	if (conn) {
		of_node_put(dn);
		dn = conn;
	}

	prop = of_get_property(dn, "sink-pdos", &length);
	if (!prop) {
		pr_err("Couldn't find sink-pdos property\n");
		of_node_put(dn);
		return -ENOENT;
	}

	nr_snk_pdo = length / sizeof(u32);
	if (nr_snk_pdo == 0 || nr_snk_pdo > max) {
		pr_err("Invalid length of sink-pdos\n");
		of_node_put(dn);
		return -EINVAL;
	}

	ret = of_property_read_u32_array(dn, "sink-pdos", snk_pdo, nr_snk_pdo);
	of_node_put(dn);
	if (ret < 0)
		return ret;

	return nr_snk_pdo;
}

static int pps_find_apdo(struct pd_pps_data *pps_data, int nr_snk_pdo)
{
	int i;

	for (i = 0; i < nr_snk_pdo; i++) {
		u32 pdo = pps_data->snk_pdo[i];

		if (pdo_type(pdo) != PDO_TYPE_FIXED)
			pr_debug("%s %d type=%d", __func__, i, pdo_type(pdo));
		else
			pr_debug("%s %d FIXED v=%d c=%d", __func__, i,
				 pdo_fixed_voltage(pdo),
				 pdo_max_current(pdo));

		if (pdo_type(pdo) == PDO_TYPE_APDO) {
			/* TODO: check APDO_TYPE_PPS */
			pps_data->default_pps_pdo = pdo;
			return 0;
		}
	}

	return -ENODATA;
}

static int pps_init_snk(struct pd_pps_data *pps_data,
			 struct device_node *node)
{
	int ret, nr_snk_pdo = 0;

	memset(pps_data, 0, sizeof(*pps_data));

	nr_snk_pdo = pps_get_sink_pdo(pps_data->snk_pdo, PDO_MAX_OBJECTS, node);
	if (nr_snk_pdo < 0) {
		pr_err("Couldn't find connector property (%d)\n", nr_snk_pdo);
		nr_snk_pdo = 0;
	} else {
		ret = pps_find_apdo(pps_data, nr_snk_pdo);
		if (ret < 0) {
			pr_err("nr_sink_pdo=%d sink APDO not found ret=%d\n",
				nr_snk_pdo, ret);
			return -ENOENT;
		}
	}

	pps_data->nr_snk_pdo = nr_snk_pdo;
	return 0;
}

/* Look for the connector and retrieve source capabilities.
 * pps_data->nr_snk_pdo == 0 means no PPS
 */
int pps_init(struct pd_pps_data *pps_data, struct device *dev,
	     struct power_supply *pps_psy, const char *pps_ws_name)
{
	int ret;

	if (!pps_data || !pps_psy || !dev)
		return -EINVAL;

	ret = pps_init_snk(pps_data, dev->of_node);
	if (ret < 0)
		return ret;

	/* TODO: look in the power supply device node ? maybe? */
	if (!pps_data->nr_snk_pdo)
		dev_warn(dev, "%s has nr_sink_pdo=0\n", pps_name(pps_psy));

	/*
	 * The port needs to ping or update the PPS adapter every 10 seconds
	 * (maximum). However, Qualcomm PD phy returns error when system is
	 * waking up. To prevent the timeout when system is resumed from
	 * suspend, hold a wakelock while PPS is active.
	 *
	 * Remove this wakeup source once we fix the Qualcomm PD phy issue.
	 */
	pps_data->stay_awake = of_property_read_bool(dev->of_node,
						     "google,pps-awake");
	if (pps_data->stay_awake) {
		pps_data->pps_ws = wakeup_source_register(NULL, pps_ws_name);
		if (!pps_data->pps_ws) {
			dev_err(dev, "Failed to register wakeup source\n");
			return -ENODEV;
		}
	}

	pps_data->pps_psy = pps_psy;
	return 0;
}

void pps_free(struct pd_pps_data *pps_data)
{
	if (!pps_data || !pps_data->pps_psy)
		return;
	if (pps_data->pps_ws)
		wakeup_source_unregister(pps_data->pps_ws);
	pps_data->pps_psy = NULL;
}


/* ------------------------------------------------------------------------- */

/*
 * This is the first part of the DC/PPS charging state machine.
 * Detect and configure the PPS adapter for the PPS profile.
 * pps->stage is updated to PPS_NONE, PPS_AVAILABLE, PPS_ACTIVE or
 * PPS_NOTSUPP.
 *
 * Returns:
 * . 0 to disable the PPS update interval voter
 * . <0 for error
 * . the max update interval pps should request
 */
int pps_work(struct pd_pps_data *pps, struct power_supply *pps_psy)
{
	union power_supply_propval pval;
	int ret, type_ok, pd_online;
	enum pd_pps_stage stage;

	if (!pps)
		return -EINVAL;
	if (!pps_psy) {
		pps->stage = PPS_NOTSUPP;
		return -EINVAL;
	}

	/*
	 * POWER_SUPPLY_PROP_PRESENT must reports cable (or field)
	 * NOTE: TCPM doesn't implement this, WLC and GCPM pps do.
	 */
	ret = power_supply_get_property(pps_psy, POWER_SUPPLY_PROP_PRESENT,
					&pval);
	if (ret == 0 && pval.intval == 0) {
		pr_debug("%s: %s pval.intval=%d ret=%d\n", __func__,
			 pps_name(pps_psy), pval.intval, ret);
		pps->stage = PPS_NOTSUPP;
	}

	/* detection is done for this cycle */
	if (pps->stage == PPS_NOTSUPP)
		return 0;

	/*
	 * 2) pps->pd_online == PPS_PSY_PROG_ONLINE && stage == PPS_NONE
	 *  If the source really support PPS (set in 1): set stage to
	 *  PPS_AVAILABLE and reschedule after PD_T_PPS_TIMEOUT
	 */
	if (pps->stage == PPS_NONE && pps->pd_online == PPS_PSY_PROG_ONLINE) {
		int rc;

		pps->stage = pps_is_avail(pps, pps_psy);
		if (pps->stage == PPS_AVAILABLE) {
			rc = pps_ping(pps, pps_psy);
			if (rc < 0) {
				pps->pd_online = PPS_PSY_FIXED_ONLINE;
				return 0;
			}

			if (pps->stay_awake)
				__pm_stay_awake(pps->pps_ws);

			pps->last_update = get_boot_sec();
			rc = pps_get_src_cap(pps, pps_psy);
			if (rc < 0)
				pps_log(pps, "Cannot get partner src caps");
		}

		return PD_T_PPS_TIMEOUT;
	}

	/*
	 * no need to retry (error) when I cannot read POWER_SUPPLY_PROP_ONLINE.
	 * The prop is set to PPS_PSY_PROG_ONLINE (from PPS_PSY_FIXED_ONLINE)
	 * when usbc_type is POWER_SUPPLY_USB_TYPE_PD_PPS.
	 */
	pd_online = GPSY_GET_PROP(pps_psy, POWER_SUPPLY_PROP_ONLINE);
	if (pd_online < 0)
		return 0;

	/*
	 * 3) pd_online == PPS_PSY_PROG_ONLINE == pps->pd_online
	 * pps is active now, we are done here. pd_online will change to
	 * if pd_online is !PPS_PSY_PROG_ONLINE go back to 1) OR exit.
	 */
	stage = (pd_online == pps->pd_online) &&
		     (pd_online == PPS_PSY_PROG_ONLINE) &&
		     (pps->stage == PPS_AVAILABLE || pps->stage == PPS_ACTIVE) ?
		     PPS_ACTIVE : PPS_NONE;
	if (stage != pps->stage) {
		pps_log(pps, "work: pd_online %d->%d stage %d->%d",
			pps->pd_online, pd_online, pps->stage,
			stage);
		pps->stage = stage;
	}

	if (pps->stage == PPS_ACTIVE)
		return 0;

	/*
	 * 1) stage == PPS_NONE && pps->pd_online!=PPS_PSY_PROG_ONLINE
	 *  If usbc_type is ok and pd_online is PPS_PSY_FIXED_ONLINE,
	 *  set POWER_SUPPLY_PROP_ONLINE to PPS_PSY_PROG_ONLINE (enable PPS)
	 *  and reschedule in PD_T_PPS_TIMEOUT.
	 */
	type_ok = pps_check_type(pps, pps_psy);
	if (!type_ok)
		pr_debug("%s: %s type not ok\n", __func__, pps_name(pps_psy));

	if (type_ok && pd_online == PPS_PSY_FIXED_ONLINE) {
		int rc;

		/* 0 = when in PROG */
		rc = pps_prog_online(pps, pps_psy);
		switch (rc) {
		case 0:
			return PD_T_PPS_TIMEOUT;
		case -EAGAIN:
			pps_log(pps, "work: not in SNK_READY, rerun");
			pps->pd_online = pd_online;
			return rc;
		case -EOPNOTSUPP:
			pps->stage = PPS_NOTSUPP;
			break;
		default:
			pps_log(pps, "work: PROP_ONLINE (%d)", rc);
			break;
		}
	}

	/* reset PPS_NOTSUPP with pps_init_state() */
	if (pps->stage == PPS_NOTSUPP) {
		if (pps->stay_awake)
			__pm_relax(pps->pps_ws);
		pps_log(pps, "work: PPS not supported");
	}

	pps->pd_online = pd_online;
	return 0;
}
// EXPORT_SYMBOL_GPL(pps_work);

int pps_keep_alive(struct pd_pps_data *pps, struct power_supply *tcpm_psy)
{
	int ret;

	if (!pps || !tcpm_psy)
		return -EINVAL;

	ret = pps_ping(pps, tcpm_psy);
	if (ret < 0) {
		pps->pd_online = PPS_PSY_FIXED_ONLINE;
		pps->keep_alive_cnt = 0;
		return ret;
	}

	pps->keep_alive_cnt += (pps->keep_alive_cnt < UINT_MAX);
	pps->last_update = get_boot_sec();
	return 0;
}
// EXPORT_SYMBOL_GPL(pps_keep_alive);

int pps_check_adapter(struct pd_pps_data *pps,
		      int pending_uv, int pending_ua,
		      struct power_supply *tcpm_psy)
{
	const int scale = 50000; /* HACK */
	int out_uv, op_ua;

	if (!pps || !tcpm_psy)
		return -EINVAL;

	out_uv = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW);
	op_ua = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_CURRENT_NOW);

	pr_debug("%s: mv=%d->%d ua=%d,%d\n", __func__,
		out_uv, pending_uv, op_ua, pending_ua);

	if (out_uv < 0 || op_ua < 0)
		return -EIO;

	return (out_uv / scale) >= (pending_uv /scale) &&
	       (op_ua / scale) >= (pending_ua / scale);
}

static int pps_set_prop(struct pd_pps_data *pps,
			enum power_supply_property prop, int val,
			struct power_supply *tcpm_psy)
{
	int ret;

	ret = GPSY_SET_PROP(tcpm_psy, prop, val);
	if (ret == 0) {
		pps->keep_alive_cnt = 0;
	} else if (ret == -EOPNOTSUPP) {
		pps->pd_online = PPS_PSY_FIXED_ONLINE;
		pps->keep_alive_cnt = 0;
		if (pps->stay_awake)
			__pm_relax(pps->pps_ws);
	}

	return ret;
}

static void pps_log_keepalive(struct pd_pps_data *pps)
{
	pps_log(pps, "%d KEEP ALIVE", pps->keep_alive_cnt);
	pps->keep_alive_cnt = 0;
}

/*
 * return negative values on errors
 * return PD_T_PPS_TIMEOUT after successful updates or pings
 * return PPS_UPDATE_DELAY_MS when the update interval is less than
 *	  PPS_UPDATE_DELAY_MS
 * return the delta to the nex ping deadline otherwise
 */
int pps_update_adapter(struct pd_pps_data *pps,
		       int pending_uv, int pending_ua,
		       struct power_supply *tcpm_psy)
{
	int interval = get_boot_sec() - pps->last_update;
	int ret;

	if (!tcpm_psy)
		return -EINVAL;

	pps->out_uv = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW);
	pps->op_ua = GPSY_GET_PROP(tcpm_psy, POWER_SUPPLY_PROP_CURRENT_NOW);
	if (pps->out_uv < 0 || pps->op_ua < 0) {
		pr_debug("%s: %s error out_uv=%d op_ua=%d\n", __func__,
			 pps_name(tcpm_psy), pps->out_uv, pps->op_ua);
		return -EIO;
	}

	if (pending_uv < 0)
		pending_uv = pps->out_uv;
	if (pending_ua < 0)
		pending_ua = pps->op_ua;

	/*
	 * TCPM accepts one change per power negotiation cycle.
	 * TODO: change voltage, current or current, voltage depending on
	 *       the values.
	 */
	if (pps->op_ua != pending_ua) {

		if (pps->keep_alive_cnt)
			pps_log_keepalive(pps);

		ret = pps_set_prop(pps, POWER_SUPPLY_PROP_CURRENT_NOW,
				   pending_ua, tcpm_psy);
		pr_debug("%s: %s SET_UA out_ua %d->%d, ret=%d", __func__,
			pps_name(tcpm_psy), pps->op_ua, pending_ua, ret);

		pps_log(pps, "SET_UA out_ua %d->%d, ret=%d",
			pps->op_ua, pending_ua, ret);

		if (ret == 0) {
			pps->last_update = get_boot_sec();
			pps->op_ua = pending_ua;

			/* voltage is pending too */
			if (pps->out_uv != pending_uv)
				return 0;

			return PD_T_PPS_TIMEOUT;
		}

		if (ret != -EAGAIN && ret != -EOPNOTSUPP)
			pps_log(pps, "failed to set CURRENT_NOW, ret = %d",
				ret);
	} else if (pps->out_uv != pending_uv) {
		ret = pps_set_prop(pps, POWER_SUPPLY_PROP_VOLTAGE_NOW,
				   pending_uv,  tcpm_psy);

		if (pps->keep_alive_cnt)
			pps_log_keepalive(pps);

		pr_debug("%s: %s SET_UV out_v %d->%d, ret=%d\n", __func__,
			pps_name(tcpm_psy), pps->out_uv, pending_uv, ret);
		pps_log(pps, "SET_UV out_v %d->%d, ret=%d",
			pps->out_uv, pending_uv, ret);

		if (ret == 0) {
			pps->last_update = get_boot_sec();
			pps->out_uv = pending_uv;
			return PD_T_PPS_TIMEOUT;
		}

		if (ret != -EAGAIN && ret != -EOPNOTSUPP)
			pps_log(pps, "failed to set VOLTAGE_NOW, ret = %d",
				ret);

	} else if (interval < PD_T_PPS_DEADLINE_S) {
		pr_debug("%s: %s mv=%d->%d ua=%d->%d interval=%d\n", __func__,
			pps_name(tcpm_psy), pps->out_uv, pending_uv,
			pps->op_ua, pending_ua, interval);
		/* TODO: tune this, now assume that PD_T_PPS_TIMEOUT >= 7s */
		return PD_T_PPS_TIMEOUT - (interval * MSEC_PER_SEC);
	} else {
		ret = pps_keep_alive(pps, tcpm_psy);
		if (ret < 0) {
			if (pps->keep_alive_cnt)
				pps_log_keepalive(pps);
			pps_log(pps, "KEEP ALIVE out_v %d, op_c %d (%d)",
				pps->out_uv, pps->op_ua, ret);
		} else {
			pps->keep_alive_cnt += 1;
		}

		pr_debug("%s: %s KEEP ALIVE out_v %d, op_c %d (%d)", __func__,
			pps_name(tcpm_psy), pps->out_uv, pps->op_ua, ret);

		if (ret == 0)
			return PD_T_PPS_TIMEOUT;
	}

	if (ret == -EOPNOTSUPP)
		pps_log(pps, "PPS deactivated while updating");

	return ret;
}
// EXPORT_SYMBOL_GPL(pps_update_adapter);

/* just a wrapper for power_supply_get_by_phandle_array() */
struct power_supply *pps_get_tcpm_psy(struct device_node *node, size_t size)
{
	const char *propname = "google,tcpm-power-supply";
	struct power_supply *tcpm_psy = NULL;
	struct power_supply *psy[2];
	int i, ret;

	if (!node)
		return ERR_PTR(-EINVAL);

	ret = power_supply_get_by_phandle_array(node, propname, psy,
						ARRAY_SIZE(psy));
	if (ret < 0)
		return ERR_PTR(-EAGAIN);

	for (i = 0; i < ret; i++) {
		const char *name = psy[i]->desc ? psy[i]->desc->name : NULL;

		if (!tcpm_psy && name && !strncmp(name, "tcpm", 4))
			tcpm_psy = psy[i];
		else
			power_supply_put(psy[i]);
	}

	return tcpm_psy;
}
// EXPORT_SYMBOL_GPL(pps_get_tcpm_psy);

/* TODO:  */
int pps_request_pdo(struct pd_pps_data *pps_data, unsigned int ta_idx,
		    unsigned int ta_max_vol, unsigned int ta_max_cur)
{
	const unsigned int max_mw = ta_max_vol * ta_max_cur;
	struct tcpm_port *port;
	int ret = -ENODEV;

	if (!pps_data || !pps_data->pps_psy || ta_idx > PDO_MAX_OBJECTS)
		return -EINVAL;

	/* tcpm pport */
	port = chg_get_tcpm_port(pps_data->pps_psy);
	if (port)
		ret = tcpm_update_sink_capabilities(port, pps_data->snk_pdo,
						    ta_idx, max_mw);


	return ret;
}
// EXPORT_SYMBOL_GPL(pps_request_pdo);


/* ------------------------------------------------------------------------- */

/*
 * return the first APDO from the TCPM source which voltage greater or equal
 * to *ta_max_vol and current greater or equal to *ta_max_cur.
 * NOTE: 0 in ta_max_vol and ta_max_cur will select the first APDO.
 */
int pps_get_apdo_max_power(struct pd_pps_data *pps_data, unsigned int *ta_idx,
			   unsigned int *ta_max_vol, unsigned int *ta_max_cur,
			   unsigned long *ta_max_pwr)
{
	int max_current, max_voltage, max_power;
	const int ta_max_vol_mv = *ta_max_vol / 1000;
	const int ta_max_cur_mv = *ta_max_cur / 1000;
	int i;

	if (!pps_data)
		return -EINVAL;

	if (pps_data->nr_src_cap <= 0)
		return -ENOENT;

	/* already done that */
	if (*ta_idx != 0)
		return -ENOTSUPP;

	/* find the new max_uv, max_ua, and max_pwr */
	for (i = 0; i < pps_data->nr_src_cap; i++) {
		const u32 pdo = pps_data->src_caps[i];

		if (pdo_type(pdo) != PDO_TYPE_FIXED)
			continue;

		max_voltage = pdo_max_voltage(pdo); /* mV */
		max_current = pdo_max_current(pdo); /* mA */
		max_power = pdo_max_power(pdo); /* mW */
		*ta_max_pwr = max_power * 1000; /* uW */
	}

	/* Get the first APDO that that exceeds the limits */
	for (i = 0; i < pps_data->nr_src_cap; i++) {
		const u32 pdo = pps_data->src_caps[i];
		bool voltage_ok, current_ok;

		if (pdo_type(pdo) != PDO_TYPE_APDO)
			continue;

		max_current = pdo_pps_apdo_max_current(pdo); /* mA */
		max_voltage = pdo_pps_apdo_max_voltage(pdo); /* mV */

		/* stop on first match */
		voltage_ok = max_voltage >= ta_max_vol_mv;
		current_ok = max_current >= ta_max_cur_mv;
		if (voltage_ok && current_ok) {
			*ta_max_vol = max_voltage * 1000;	/* uV */
			*ta_max_cur = max_current * 1000;	/* uA */
			*ta_idx = i + 1;
			return 0;
		}

	}

	pr_debug("%s: max_uv (%u) and max_ua (%u) out of APDO src caps\n",
		 __func__, *ta_max_vol, *ta_max_cur);
	return -EINVAL;
}
// EXPORT_SYMBOL_GPL(pps_get_apdo_max_power);
