/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Maxim MAX77705 definitions.
 *
 * Copyright (C) 2015 Samsung Electronics, Inc.
 * Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com>
 */

#ifndef __MAX77705_CHARGER_H
#define __MAX77705_CHARGER_H __FILE__

#include <linux/regmap.h>

/* MAX77705_CHG_REG_CHG_INT */
#define MAX77705_BYP_I		(0)
#define MAX77705_INP_LIMIT_I	(1)
#define MAX77705_BATP_I		(2)
#define MAX77705_BAT_I		(3)
#define MAX77705_CHG_I		(4)
#define MAX77705_WCIN_I		(5)
#define MAX77705_CHGIN_I	(6)
#define MAX77705_AICL_I		(7)

/* MAX77705_CHG_REG_CHG_INT_OK */
#define MAX77705_BYP_OK		BIT(MAX77705_BYP_I)
#define MAX77705_DISQBAT_OK	BIT(MAX77705_INP_LIMIT_I)
#define MAX77705_BATP_OK	BIT(MAX77705_BATP_I)
#define MAX77705_BAT_OK		BIT(MAX77705_BAT_I)
#define MAX77705_CHG_OK		BIT(MAX77705_CHG_I)
#define MAX77705_WCIN_OK	BIT(MAX77705_WCIN_I)
#define MAX77705_CHGIN_OK	BIT(MAX77705_CHGIN_I)
#define MAX77705_AICL_OK	BIT(MAX77705_AICL_I)

/* MAX77705_CHG_REG_DETAILS_00 */
#define MAX77705_BATP_DTLS		BIT(0)
#define MAX77705_WCIN_DTLS		GENMASK(4, 3)
#define MAX77705_WCIN_DTLS_SHIFT	3
#define MAX77705_CHGIN_DTLS		GENMASK(6, 5)
#define MAX77705_CHGIN_DTLS_SHIFT	5

/* MAX77705_CHG_REG_DETAILS_01 */
#define MAX77705_CHG_DTLS	GENMASK(3, 0)
#define MAX77705_CHG_DTLS_SHIFT	0
#define MAX77705_BAT_DTLS	GENMASK(6, 4)
#define MAX77705_BAT_DTLS_SHIFT	4

/* MAX77705_CHG_REG_DETAILS_02 */
#define MAX77705_BYP_DTLS	GENMASK(3, 0)
#define MAX77705_BYP_DTLS_SHIFT	0

/* MAX77705_CHG_REG_CNFG_00 */
#define MAX77705_CHG_SHIFT	0
#define MAX77705_UNO_SHIFT	1
#define MAX77705_OTG_SHIFT	1
#define MAX77705_BUCK_SHIFT	2
#define MAX77705_BOOST_SHIFT	3
#define MAX77705_WDTEN_SHIFT	4
#define MAX77705_CHG_MASK	BIT(MAX77705_CHG_SHIFT)
#define MAX77705_UNO_MASK	BIT(MAX77705_UNO_SHIFT)
#define MAX77705_OTG_MASK	BIT(MAX77705_OTG_SHIFT)
#define MAX77705_BUCK_MASK	BIT(MAX77705_BUCK_SHIFT)
#define MAX77705_BOOST_MASK	BIT(MAX77705_BOOST_SHIFT)
#define MAX77705_WDTEN_MASK	BIT(MAX77705_WDTEN_SHIFT)
#define MAX77705_UNO_CTRL	(MAX77705_UNO_MASK | MAX77705_BOOST_MASK)
#define MAX77705_OTG_CTRL	(MAX77705_OTG_MASK | MAX77705_BOOST_MASK)

/* MAX77705_CHG_REG_CNFG_01 */
#define MAX77705_FCHGTIME_DISABLE	0
#define MAX77705_CHG_RSTRT_DISABLE	0x3

#define MAX77705_CHG_PQEN_DISABLE	0
#define MAX77705_CHG_PQEN_ENABLE	1

/* MAX77705_CHG_REG_CNFG_02 */
#define MAX77705_OTG_ILIM_500		0
#define MAX77705_OTG_ILIM_900		1
#define MAX77705_OTG_ILIM_1200		2
#define MAX77705_OTG_ILIM_1500		3

/* MAX77705_CHG_REG_CNFG_03 */
#define MAX77705_TO_ITH_150MA		0
#define MAX77705_TO_TIME_30M		3
#define MAX77705_SYS_TRACK_ENABLE	0
#define MAX77705_SYS_TRACK_DISABLE	1

/* MAX77705_CHG_REG_CNFG_04 */
#define MAX77705_CHG_MINVSYS_SHIFT	6
#define MAX77705_CHG_MINVSYS_MASK	GENMASK(7, 6)

/* MAX77705_CHG_REG_CNFG_05 */
#define MAX77705_B2SOVRC_DISABLE	0
#define MAX77705_B2SOVRC_4_5A		6
#define MAX77705_B2SOVRC_4_8A		8
#define MAX77705_B2SOVRC_5_0A		9

/* MAX77705_CHG_CNFG_06 */
#define MAX77705_WDTCLR_SHIFT		0
#define MAX77705_WDTCLR_MASK		GENMASK(1, 0)
#define MAX77705_WDTCLR			1
#define MAX77705_CHGPROT_UNLOCKED	3
#define MAX77705_SLOWEST_LX_SLOPE	3

/* MAX77705_CHG_REG_CNFG_07 */
#define MAX77705_CHG_FMBST		4
#define MAX77705_REG_FMBST_SHIFT	2
#define MAX77705_REG_FMBST_MASK		BIT(MAX77705_REG_FMBST_SHIFT)
#define MAX77705_REG_FGSRC_SHIFT	1
#define MAX77705_REG_FGSRC_MASK		BIT(MAX77705_REG_FGSRC_SHIFT)

/* MAX77705_CHG_REG_CNFG_08 */
#define MAX77705_CHG_FSW_3MHz		0
#define MAX77705_CHG_FSW_2MHz		1
#define MAX77705_CHG_FSW_1_5MHz		2

/* MAX77705_CHG_REG_CNFG_09 */
#define MAX77705_CHG_DISABLE			0

/* MAX77705_CHG_REG_CNFG_12 */
/* REG=4.5V, UVLO=4.7V */
#define MAX77705_VCHGIN_4_5		0
/* REG=4.5V, UVLO=4.7V */
#define MAX77705_WCIN_4_5		0
#define MAX77705_DISABLE_SKIP		1
#define MAX77705_AUTO_SKIP		0

#define AICL_WORK_DELAY_MS		100

/* uA */
#define MAX77705_CURRENT_CHGIN_STEP	25000
#define MAX77705_CURRENT_CHG_STEP	50000
#define MAX77705_CURRENT_CHGIN_MIN	100000
#define MAX77705_CURRENT_CHGIN_MAX	3200000

enum max77705_field_idx {
	MAX77705_CHGPROT,
	MAX77705_CHG_EN,
	MAX77705_CHG_CC_LIM,
	MAX77705_CHG_CHGIN_LIM,
	MAX77705_CHG_CV_PRM,
	MAX77705_CHG_PQEN,
	MAX77705_CHG_RSTRT,
	MAX77705_CHG_WCIN,
	MAX77705_FCHGTIME,
	MAX77705_LX_SLOPE,
	MAX77705_MODE,
	MAX77705_OTG_ILIM,
	MAX77705_REG_B2SOVRC,
	MAX77705_REG_DISKIP,
	MAX77705_REG_FSW,
	MAX77705_SYS_TRACK,
	MAX77705_TO,
	MAX77705_TO_TIME,
	MAX77705_VBYPSET,
	MAX77705_VCHGIN,
	MAX77705_WCIN,
	MAX77705_N_REGMAP_FIELDS,
};

static const struct reg_field max77705_reg_field[MAX77705_N_REGMAP_FIELDS] = {
	[MAX77705_MODE]			= REG_FIELD(MAX77705_CHG_REG_CNFG_00,   0, 3),
	[MAX77705_FCHGTIME]		= REG_FIELD(MAX77705_CHG_REG_CNFG_01,   0, 2),
	[MAX77705_CHG_RSTRT]		= REG_FIELD(MAX77705_CHG_REG_CNFG_01,   4, 5),
	[MAX77705_CHG_PQEN]		= REG_FIELD(MAX77705_CHG_REG_CNFG_01,   7, 7),
	[MAX77705_CHG_CC_LIM]		= REG_FIELD(MAX77705_CHG_REG_CNFG_02,   0, 5),
	[MAX77705_OTG_ILIM]		= REG_FIELD(MAX77705_CHG_REG_CNFG_02,   6, 7),
	[MAX77705_TO]			= REG_FIELD(MAX77705_CHG_REG_CNFG_03,   0, 2),
	[MAX77705_TO_TIME]		= REG_FIELD(MAX77705_CHG_REG_CNFG_03,   3, 5),
	[MAX77705_SYS_TRACK]		= REG_FIELD(MAX77705_CHG_REG_CNFG_03,   7, 7),
	[MAX77705_CHG_CV_PRM]		= REG_FIELD(MAX77705_CHG_REG_CNFG_04,   0, 5),
	[MAX77705_REG_B2SOVRC]		= REG_FIELD(MAX77705_CHG_REG_CNFG_05,   0, 3),
	[MAX77705_CHGPROT]		= REG_FIELD(MAX77705_CHG_REG_CNFG_06,   2, 3),
	[MAX77705_LX_SLOPE]		= REG_FIELD(MAX77705_CHG_REG_CNFG_06,   5, 6),
	[MAX77705_REG_FSW]		= REG_FIELD(MAX77705_CHG_REG_CNFG_08,   0, 1),
	[MAX77705_CHG_CHGIN_LIM]	= REG_FIELD(MAX77705_CHG_REG_CNFG_09,   0, 6),
	[MAX77705_CHG_EN]		= REG_FIELD(MAX77705_CHG_REG_CNFG_09,   7, 7),
	[MAX77705_CHG_WCIN]		= REG_FIELD(MAX77705_CHG_REG_CNFG_10,   0, 5),
	[MAX77705_VBYPSET]		= REG_FIELD(MAX77705_CHG_REG_CNFG_11,   0, 6),
	[MAX77705_REG_DISKIP]		= REG_FIELD(MAX77705_CHG_REG_CNFG_12,   0, 0),
	[MAX77705_WCIN]			= REG_FIELD(MAX77705_CHG_REG_CNFG_12,   1, 2),
	[MAX77705_VCHGIN]		= REG_FIELD(MAX77705_CHG_REG_CNFG_12,   3, 4),
};

struct max77705_charger_data {
	struct device			*dev;
	struct regmap		*regmap;
	struct regmap_field	*rfield[MAX77705_N_REGMAP_FIELDS];
	struct power_supply_battery_info *bat_info;
	struct workqueue_struct *wqueue;
	struct work_struct	chgin_work;
	struct power_supply	*psy_chg;
};

#endif /* __MAX77705_CHARGER_H */
