/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Google Battery Management System
 *
 * 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.
 */

#ifndef __GBMS_POWER_SUPPLY_H__
#define __GBMS_POWER_SUPPLY_H__

#include <linux/power_supply.h>

enum {
	GBMS_TAPER_CONTROL_OFF = 0,
	GBMS_TAPER_CONTROL_ON,
};

/* Indicates USB Type-C CC connection status */
/* Deprecated */
enum power_supply_typec_mode {
	POWER_SUPPLY_TYPEC_NONE,

	/* Acting as source */
	POWER_SUPPLY_TYPEC_SINK,		/* Rd only */
	POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE,	/* Rd/Ra */
	POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY,/* Rd/Rd */
	POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER,	/* Ra/Ra */
	POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY,	/* Ra only */

	/* Acting as sink */
	POWER_SUPPLY_TYPEC_SOURCE_DEFAULT,	/* Rp default */
	POWER_SUPPLY_TYPEC_SOURCE_MEDIUM,	/* Rp 1.5A */
	POWER_SUPPLY_TYPEC_SOURCE_HIGH,		/* Rp 3A */
	POWER_SUPPLY_TYPEC_DAM_DEFAULT,		/* Rp-1.5A/Rp-3A */
	POWER_SUPPLY_TYPEC_DAM_MEDIUM,		/* Rp-Default/Rp-1.5A */
	POWER_SUPPLY_TYPEC_DAM_HIGH,		/* Rp-Default/Rp-3A */

	/* Non Compliant */
	POWER_SUPPLY_TYPEC_NON_COMPLIANT,
	POWER_SUPPLY_TYPEC_RP_STD_STD,		/* Rp-Default/Rp-Default */
	POWER_SUPPLY_TYPEC_RP_MED_MED,		/* Rp-1.5A/Rp-1.5A */
	POWER_SUPPLY_TYPEC_RP_HIGH_HIGH,	/* Rp-3A/Rp-3A */
};

/* Deprecated */
enum power_supply_typec_src_rp {
	POWER_SUPPLY_TYPEC_SRC_RP_STD,
	POWER_SUPPLY_TYPEC_SRC_RP_1P5A,
	POWER_SUPPLY_TYPEC_SRC_RP_3A
};

/* Deprecated */
enum power_supply_typec_power_role {
	POWER_SUPPLY_TYPEC_PR_NONE,		/* CC lines in high-Z */
	POWER_SUPPLY_TYPEC_PR_DUAL,
	POWER_SUPPLY_TYPEC_PR_SINK,
	POWER_SUPPLY_TYPEC_PR_SOURCE,
};

enum gbms_property {
	/* I am not proud of this */
	GBMS_PROP_LOCAL_EXTENSIONS = POWER_SUPPLY_PROP_SERIAL_NUMBER + 100,

	GBMS_PROP_ADAPTER_DETAILS,	/* GBMS Adapter Details */
	GBMS_PROP_BATT_CE_CTRL,		/* GBMS plugged (replace with GBMS_PROP_CHARGING_ENABLED) */
	GBMS_PROP_CAPACITY_RAW,		/* GBMS used for ssoc */
	GBMS_PROP_CHARGING_ENABLED,	/* GBMS cpm control */
	GBMS_PROP_CHARGE_CHARGER_STATE,	/* GBMS charge, need uint64 */
	GBMS_PROP_CHARGE_DISABLE,	/* GBMS disconnect */
	GBMS_PROP_DEAD_BATTERY,		/* GBMS during boot */
	GBMS_PROP_INPUT_CURRENT_LIMITED, /* can be device prop */
	GBMS_PROP_TAPER_CONTROL,	/* GBMS DC, needs for last tier */
	GBMS_PROP_HEALTH_ACT_IMPEDANCE,	/* GBMS activation impedance, qualified */
	GBMS_PROP_HEALTH_IMPEDANCE,	/* GBMS impedance, qualified */
	GBMS_PROP_RESISTANCE,		/* GBMS battery resistance, unqualified */
	GBMS_PROP_RESISTANCE_RAW,	/* GBMS battery resistance, unqualified, u16 */
	GBMS_PROP_RESISTANCE_AVG,	/* GBMS google_resistance */
	GBMS_PROP_BATTERY_AGE,		/* GBMS time in field */
	GBMS_PROP_CAPACITY_FADE_RATE,	/* GBMS capaciy fade rate */
	GBMS_PROP_CHARGE_FULL_ESTIMATE,	/* GBMS google_capacity */
};

union gbms_propval {
	union power_supply_propval prop;
	int64_t int64val;
};

#define gbms_propval_int64val(psp) \
	container_of(psp, union gbms_propval, prop)->int64val

static inline int gpsy_set_int64_prop(struct power_supply *psy,
				      enum gbms_property psp,
				      union gbms_propval val,
				      const char *prop_name)
{
	int ret = 0;

	if (!psy)
		return -EINVAL;

	pr_debug("set %s for '%s' to %lld\n", prop_name,
		 psy->desc->name, (long long)val.int64val);

	ret = power_supply_set_property(psy, (enum power_supply_property)psp,
				        &val.prop);
	if (ret < 0)
		pr_err("failed to set %s for '%s', ret=%d\n",
		       prop_name, psy->desc->name, ret);

	return ret;
}

#define GPSY_SET_INT64_PROP(psy, psp, val) \
	gpsy_set_int64_prop(psy, psp, (union gbms_propval) \
			   { .int64val = (int64_t)(val) }, #psp)

static inline int64_t gpsy_get_int64_prop(struct power_supply *psy,
					  enum gbms_property psp,
					  const char *prop_name,
					  int *err)
{
	union gbms_propval val;

	if (!psy) {
		*err = -EINVAL;
		return *err;
	}

	*err = power_supply_get_property(psy, (enum power_supply_property)psp,
					 &val.prop);
	if (*err < 0) {
		pr_err("failed to get %s from '%s', ret=%d\n",
		       prop_name, psy->desc->name, *err);
		return *err;
	}

	pr_debug("get %s for '%s' => %lld\n", prop_name,
		 psy->desc->name, (long long)val.int64val);

	return val.int64val;
}

#define GPSY_GET_INT64_PROP(psy, psp, err) \
	gpsy_get_int64_prop(psy, psp, #psp, err)


/* GBMS properties -------------------------------------------------------- */

struct gbms_desc {
	struct power_supply_desc psy_dsc;
	bool forward;

	/* bgms properties */
	int (*get_property)(struct power_supply *psy, enum gbms_property psp,
			    union gbms_propval *val);
	int (*set_property)(struct power_supply *psy, enum gbms_property psp,
			    const union gbms_propval *val);
	int (*property_is_writeable)(struct power_supply *psy,
				     enum gbms_property psp);
};

extern int gbms_set_property(struct power_supply *psy, enum gbms_property psp,
			     const union gbms_propval *val);
extern int gbms_get_property(struct power_supply *psy, enum gbms_property psp,
			     union gbms_propval *val);

#endif /* __GBMS_POWER_SUPPLY_H__ */
