// SPDX-License-Identifier: GPL-2.0+
/*
 * Supports for the power IC on the Surface 3 tablet.
 *
 * (C) Copyright 2016-2018 Red Hat, Inc
 * (C) Copyright 2016-2018 Benjamin Tissoires <benjamin.tissoires@gmail.com>
 * (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
 *
 * This driver has been reverse-engineered by parsing the DSDT of the Surface 3
 * and looking at the registers of the chips.
 *
 * The DSDT allowed to find out that:
 * - the driver is required for the ACPI BAT0 device to communicate to the chip
 *   through an operation region.
 * - the various defines for the operation region functions to communicate with
 *   this driver
 * - the DSM 3f99e367-6220-4955-8b0f-06ef2ae79412 allows to trigger ACPI
 *   events to BAT0 (the code is all available in the DSDT).
 *
 * Further findings regarding the 2 chips declared in the MSHW0011 are:
 * - there are 2 chips declared:
 *   . 0x22 seems to control the ADP1 line status (and probably the charger)
 *   . 0x55 controls the battery directly
 * - the battery chip uses a SMBus protocol (using plain SMBus allows non
 *   destructive commands):
 *   . the commands/registers used are in the range 0x00..0x7F
 *   . if bit 8 (0x80) is set in the SMBus command, the returned value is the
 *     same as when it is not set. There is a high chance this bit is the
 *     read/write
 *   . the various registers semantic as been deduced by observing the register
 *     dumps.
 */

#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/freezer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uuid.h>
#include <asm/unaligned.h>

#define SURFACE_3_POLL_INTERVAL		(2 * HZ)
#define SURFACE_3_STRLEN		10

struct mshw0011_data {
	struct i2c_client	*adp1;
	struct i2c_client	*bat0;
	unsigned short		notify_mask;
	struct task_struct	*poll_task;
	bool			kthread_running;

	bool			charging;
	bool			bat_charging;
	u8			trip_point;
	s32			full_capacity;
};

struct mshw0011_handler_data {
	struct acpi_connection_info	info;
	struct i2c_client		*client;
};

struct bix {
	u32	revision;
	u32	power_unit;
	u32	design_capacity;
	u32	last_full_charg_capacity;
	u32	battery_technology;
	u32	design_voltage;
	u32	design_capacity_of_warning;
	u32	design_capacity_of_low;
	u32	cycle_count;
	u32	measurement_accuracy;
	u32	max_sampling_time;
	u32	min_sampling_time;
	u32	max_average_interval;
	u32	min_average_interval;
	u32	battery_capacity_granularity_1;
	u32	battery_capacity_granularity_2;
	char	model[SURFACE_3_STRLEN];
	char	serial[SURFACE_3_STRLEN];
	char	type[SURFACE_3_STRLEN];
	char	OEM[SURFACE_3_STRLEN];
} __packed;

struct bst {
	u32	battery_state;
	s32	battery_present_rate;
	u32	battery_remaining_capacity;
	u32	battery_present_voltage;
} __packed;

struct gsb_command {
	u8	arg0;
	u8	arg1;
	u8	arg2;
} __packed;

struct gsb_buffer {
	u8	status;
	u8	len;
	u8	ret;
	union {
		struct gsb_command	cmd;
		struct bst		bst;
		struct bix		bix;
	} __packed;
} __packed;

#define ACPI_BATTERY_STATE_DISCHARGING	BIT(0)
#define ACPI_BATTERY_STATE_CHARGING	BIT(1)
#define ACPI_BATTERY_STATE_CRITICAL	BIT(2)

#define MSHW0011_CMD_DEST_BAT0		0x01
#define MSHW0011_CMD_DEST_ADP1		0x03

#define MSHW0011_CMD_BAT0_STA		0x01
#define MSHW0011_CMD_BAT0_BIX		0x02
#define MSHW0011_CMD_BAT0_BCT		0x03
#define MSHW0011_CMD_BAT0_BTM		0x04
#define MSHW0011_CMD_BAT0_BST		0x05
#define MSHW0011_CMD_BAT0_BTP		0x06
#define MSHW0011_CMD_ADP1_PSR		0x07
#define MSHW0011_CMD_BAT0_PSOC		0x09
#define MSHW0011_CMD_BAT0_PMAX		0x0a
#define MSHW0011_CMD_BAT0_PSRC		0x0b
#define MSHW0011_CMD_BAT0_CHGI		0x0c
#define MSHW0011_CMD_BAT0_ARTG		0x0d

#define MSHW0011_NOTIFY_GET_VERSION	0x00
#define MSHW0011_NOTIFY_ADP1		0x01
#define MSHW0011_NOTIFY_BAT0_BST	0x02
#define MSHW0011_NOTIFY_BAT0_BIX	0x05

#define MSHW0011_ADP1_REG_PSR		0x04

#define MSHW0011_BAT0_REG_CAPACITY		0x0c
#define MSHW0011_BAT0_REG_FULL_CHG_CAPACITY	0x0e
#define MSHW0011_BAT0_REG_DESIGN_CAPACITY	0x40
#define MSHW0011_BAT0_REG_VOLTAGE	0x08
#define MSHW0011_BAT0_REG_RATE		0x14
#define MSHW0011_BAT0_REG_OEM		0x45
#define MSHW0011_BAT0_REG_TYPE		0x4e
#define MSHW0011_BAT0_REG_SERIAL_NO	0x56
#define MSHW0011_BAT0_REG_CYCLE_CNT	0x6e

#define MSHW0011_EV_2_5_MASK		GENMASK(8, 0)

/* 3f99e367-6220-4955-8b0f-06ef2ae79412 */
static const guid_t mshw0011_guid =
	GUID_INIT(0x3F99E367, 0x6220, 0x4955, 0x8B, 0x0F, 0x06, 0xEF,
		  0x2A, 0xE7, 0x94, 0x12);

static int
mshw0011_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
		unsigned int *ret_value)
{
	union acpi_object *obj;
	acpi_handle handle;
	unsigned int i;

	handle = ACPI_HANDLE(&cdata->adp1->dev);
	if (!handle)
		return -ENODEV;

	obj = acpi_evaluate_dsm_typed(handle, &mshw0011_guid, arg1, arg2, NULL,
				      ACPI_TYPE_BUFFER);
	if (!obj) {
		dev_err(&cdata->adp1->dev, "device _DSM execution failed\n");
		return -ENODEV;
	}

	*ret_value = 0;
	for (i = 0; i < obj->buffer.length; i++)
		*ret_value |= obj->buffer.pointer[i] << (i * 8);

	ACPI_FREE(obj);
	return 0;
}

static const struct bix default_bix = {
	.revision = 0x00,
	.power_unit = 0x01,
	.design_capacity = 0x1dca,
	.last_full_charg_capacity = 0x1dca,
	.battery_technology = 0x01,
	.design_voltage = 0x10df,
	.design_capacity_of_warning = 0x8f,
	.design_capacity_of_low = 0x47,
	.cycle_count = 0xffffffff,
	.measurement_accuracy = 0x00015f90,
	.max_sampling_time = 0x03e8,
	.min_sampling_time = 0x03e8,
	.max_average_interval = 0x03e8,
	.min_average_interval = 0x03e8,
	.battery_capacity_granularity_1 = 0x45,
	.battery_capacity_granularity_2 = 0x11,
	.model = "P11G8M",
	.serial = "",
	.type = "LION",
	.OEM = "",
};

static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
{
	struct i2c_client *client = cdata->bat0;
	char buf[SURFACE_3_STRLEN];
	int ret;

	*bix = default_bix;

	/* get design capacity */
	ret = i2c_smbus_read_word_data(client,
				       MSHW0011_BAT0_REG_DESIGN_CAPACITY);
	if (ret < 0) {
		dev_err(&client->dev, "Error reading design capacity: %d\n",
			ret);
		return ret;
	}
	bix->design_capacity = ret;

	/* get last full charge capacity */
	ret = i2c_smbus_read_word_data(client,
				       MSHW0011_BAT0_REG_FULL_CHG_CAPACITY);
	if (ret < 0) {
		dev_err(&client->dev,
			"Error reading last full charge capacity: %d\n", ret);
		return ret;
	}
	bix->last_full_charg_capacity = ret;

	/*
	 * Get serial number, on some devices (with unofficial replacement
	 * battery?) reading any of the serial number range addresses gets
	 * nacked in this case just leave the serial number empty.
	 */
	ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
					    sizeof(buf), buf);
	if (ret == -EREMOTEIO) {
		/* no serial number available */
	} else if (ret != sizeof(buf)) {
		dev_err(&client->dev, "Error reading serial no: %d\n", ret);
		return ret;
	} else {
		snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
	}

	/* get cycle count */
	ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
	if (ret < 0) {
		dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
		return ret;
	}
	bix->cycle_count = ret;

	/* get OEM name */
	ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_OEM,
					    4, buf);
	if (ret != 4) {
		dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
		return ret;
	}
	snprintf(bix->OEM, ARRAY_SIZE(bix->OEM), "%3pE", buf);

	return 0;
}

static int mshw0011_bst(struct mshw0011_data *cdata, struct bst *bst)
{
	struct i2c_client *client = cdata->bat0;
	int rate, capacity, voltage, state;
	s16 tmp;

	rate = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_RATE);
	if (rate < 0)
		return rate;

	capacity = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CAPACITY);
	if (capacity < 0)
		return capacity;

	voltage = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_VOLTAGE);
	if (voltage < 0)
		return voltage;

	tmp = rate;
	bst->battery_present_rate = abs((s32)tmp);

	state = 0;
	if ((s32) tmp > 0)
		state |= ACPI_BATTERY_STATE_CHARGING;
	else if ((s32) tmp < 0)
		state |= ACPI_BATTERY_STATE_DISCHARGING;
	bst->battery_state = state;

	bst->battery_remaining_capacity = capacity;
	bst->battery_present_voltage = voltage;

	return 0;
}

static int mshw0011_adp_psr(struct mshw0011_data *cdata)
{
	return i2c_smbus_read_byte_data(cdata->adp1, MSHW0011_ADP1_REG_PSR);
}

static int mshw0011_isr(struct mshw0011_data *cdata)
{
	struct bst bst;
	struct bix bix;
	int ret;
	bool status, bat_status;

	ret = mshw0011_adp_psr(cdata);
	if (ret < 0)
		return ret;

	status = ret;
	if (status != cdata->charging)
		mshw0011_notify(cdata, cdata->notify_mask,
				MSHW0011_NOTIFY_ADP1, &ret);

	cdata->charging = status;

	ret = mshw0011_bst(cdata, &bst);
	if (ret < 0)
		return ret;

	bat_status = bst.battery_state;
	if (bat_status != cdata->bat_charging)
		mshw0011_notify(cdata, cdata->notify_mask,
				MSHW0011_NOTIFY_BAT0_BST, &ret);

	cdata->bat_charging = bat_status;

	ret = mshw0011_bix(cdata, &bix);
	if (ret < 0)
		return ret;

	if (bix.last_full_charg_capacity != cdata->full_capacity)
		mshw0011_notify(cdata, cdata->notify_mask,
				MSHW0011_NOTIFY_BAT0_BIX, &ret);

	cdata->full_capacity = bix.last_full_charg_capacity;

	return 0;
}

static int mshw0011_poll_task(void *data)
{
	struct mshw0011_data *cdata = data;
	int ret = 0;

	cdata->kthread_running = true;

	set_freezable();

	while (!kthread_should_stop()) {
		schedule_timeout_interruptible(SURFACE_3_POLL_INTERVAL);
		try_to_freeze();
		ret = mshw0011_isr(data);
		if (ret)
			break;
	}

	cdata->kthread_running = false;
	return ret;
}

static acpi_status
mshw0011_space_handler(u32 function, acpi_physical_address command,
			u32 bits, u64 *value64,
			void *handler_context, void *region_context)
{
	struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
	struct mshw0011_handler_data *data = handler_context;
	struct acpi_connection_info *info = &data->info;
	struct acpi_resource_i2c_serialbus *sb;
	struct i2c_client *client = data->client;
	struct mshw0011_data *cdata = i2c_get_clientdata(client);
	struct acpi_resource *ares;
	u32 accessor_type = function >> 16;
	acpi_status ret;
	int status = 1;

	ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
	if (ACPI_FAILURE(ret))
		return ret;

	if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	if (gsb->cmd.arg0 == MSHW0011_CMD_DEST_ADP1 &&
	    gsb->cmd.arg1 == MSHW0011_CMD_ADP1_PSR) {
		status = mshw0011_adp_psr(cdata);
		if (status >= 0) {
			ret = AE_OK;
			goto out;
		} else {
			ret = AE_ERROR;
			goto err;
		}
	}

	if (gsb->cmd.arg0 != MSHW0011_CMD_DEST_BAT0) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	switch (gsb->cmd.arg1) {
	case MSHW0011_CMD_BAT0_STA:
		break;
	case MSHW0011_CMD_BAT0_BIX:
		ret = mshw0011_bix(cdata, &gsb->bix);
		break;
	case MSHW0011_CMD_BAT0_BTP:
		cdata->trip_point = gsb->cmd.arg2;
		break;
	case MSHW0011_CMD_BAT0_BST:
		ret = mshw0011_bst(cdata, &gsb->bst);
		break;
	default:
		dev_info(&cdata->bat0->dev, "command(0x%02x) is not supported.\n", gsb->cmd.arg1);
		ret = AE_BAD_PARAMETER;
		goto err;
	}

 out:
	gsb->ret = status;
	gsb->status = 0;

 err:
	ACPI_FREE(ares);
	return ret;
}

static int mshw0011_install_space_handler(struct i2c_client *client)
{
	struct acpi_device *adev;
	struct mshw0011_handler_data *data;
	acpi_status status;

	adev = ACPI_COMPANION(&client->dev);
	if (!adev)
		return -ENODEV;

	data = kzalloc(sizeof(struct mshw0011_handler_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;
	status = acpi_bus_attach_private_data(adev->handle, (void *)data);
	if (ACPI_FAILURE(status)) {
		kfree(data);
		return -ENOMEM;
	}

	status = acpi_install_address_space_handler(adev->handle,
						    ACPI_ADR_SPACE_GSBUS,
						    &mshw0011_space_handler,
						    NULL,
						    data);
	if (ACPI_FAILURE(status)) {
		dev_err(&client->dev, "Error installing i2c space handler\n");
		acpi_bus_detach_private_data(adev->handle);
		kfree(data);
		return -ENOMEM;
	}

	acpi_dev_clear_dependencies(adev);
	return 0;
}

static void mshw0011_remove_space_handler(struct i2c_client *client)
{
	struct mshw0011_handler_data *data;
	acpi_handle handle;
	acpi_status status;

	handle = ACPI_HANDLE(&client->dev);
	if (!handle)
		return;

	acpi_remove_address_space_handler(handle,
				ACPI_ADR_SPACE_GSBUS,
				&mshw0011_space_handler);

	status = acpi_bus_get_private_data(handle, (void **)&data);
	if (ACPI_SUCCESS(status))
		kfree(data);

	acpi_bus_detach_private_data(handle);
}

static int mshw0011_probe(struct i2c_client *client)
{
	struct i2c_board_info board_info;
	struct device *dev = &client->dev;
	struct i2c_client *bat0;
	struct mshw0011_data *data;
	int error, mask;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->adp1 = client;
	i2c_set_clientdata(client, data);

	memset(&board_info, 0, sizeof(board_info));
	strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE);

	bat0 = i2c_acpi_new_device(dev, 1, &board_info);
	if (IS_ERR(bat0))
		return PTR_ERR(bat0);

	data->bat0 = bat0;
	i2c_set_clientdata(bat0, data);

	error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &mask);
	if (error)
		goto out_err;

	data->notify_mask = mask == MSHW0011_EV_2_5_MASK;

	data->poll_task = kthread_run(mshw0011_poll_task, data, "mshw0011_adp");
	if (IS_ERR(data->poll_task)) {
		error = PTR_ERR(data->poll_task);
		dev_err(&client->dev, "Unable to run kthread err %d\n", error);
		goto out_err;
	}

	error = mshw0011_install_space_handler(client);
	if (error)
		goto out_err;

	return 0;

out_err:
	if (data->kthread_running)
		kthread_stop(data->poll_task);
	i2c_unregister_device(data->bat0);
	return error;
}

static int mshw0011_remove(struct i2c_client *client)
{
	struct mshw0011_data *cdata = i2c_get_clientdata(client);

	mshw0011_remove_space_handler(client);

	if (cdata->kthread_running)
		kthread_stop(cdata->poll_task);

	i2c_unregister_device(cdata->bat0);

	return 0;
}

static const struct acpi_device_id mshw0011_acpi_match[] = {
	{ "MSHW0011", 0 },
	{ }
};
MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);

static struct i2c_driver mshw0011_driver = {
	.probe_new = mshw0011_probe,
	.remove = mshw0011_remove,
	.driver = {
		.name = "mshw0011",
		.acpi_match_table = mshw0011_acpi_match,
	},
};
module_i2c_driver(mshw0011_driver);

MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
MODULE_DESCRIPTION("mshw0011 driver");
MODULE_LICENSE("GPL v2");
