/* 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 */
	GBMS_PROP_WLC_OP_FREQ,		/* GBMS wlc frequency */
	GBMS_PROP_WLC_VRECT,		/* GBMS wlc Vrect */
};

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__ */
