// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * The Netronix embedded controller is a microcontroller found in some
 * e-book readers designed by the original design manufacturer Netronix, Inc.
 * It contains RTC, battery monitoring, system power management, and PWM
 * functionality.
 *
 * This driver implements register access, version detection, and system
 * power-off/reset.
 *
 * Copyright 2020 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
 */

#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ntxec.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include <asm/unaligned.h>

#define NTXEC_REG_VERSION	0x00
#define NTXEC_REG_POWEROFF	0x50
#define NTXEC_REG_POWERKEEP	0x70
#define NTXEC_REG_RESET		0x90

#define NTXEC_POWEROFF_VALUE	0x0100
#define NTXEC_POWERKEEP_VALUE	0x0800
#define NTXEC_RESET_VALUE	0xff00

static struct i2c_client *poweroff_restart_client;

static void ntxec_poweroff(void)
{
	int res;
	u8 buf[3] = { NTXEC_REG_POWEROFF };
	struct i2c_msg msgs[] = {
		{
			.addr = poweroff_restart_client->addr,
			.flags = 0,
			.len = sizeof(buf),
			.buf = buf,
		},
	};

	put_unaligned_be16(NTXEC_POWEROFF_VALUE, buf + 1);

	res = i2c_transfer(poweroff_restart_client->adapter, msgs, ARRAY_SIZE(msgs));
	if (res < 0)
		dev_warn(&poweroff_restart_client->dev,
			 "Failed to power off (err = %d)\n", res);

	/*
	 * The time from the register write until the host CPU is powered off
	 * has been observed to be about 2.5 to 3 seconds. Sleep long enough to
	 * safely avoid returning from the poweroff handler.
	 */
	msleep(5000);
}

static int ntxec_restart(struct notifier_block *nb,
			 unsigned long action, void *data)
{
	int res;
	u8 buf[3] = { NTXEC_REG_RESET };
	/*
	 * NOTE: The lower half of the reset value is not sent, because sending
	 * it causes an I2C error. (The reset handler in the downstream driver
	 * does send the full two-byte value, but doesn't check the result).
	 */
	struct i2c_msg msgs[] = {
		{
			.addr = poweroff_restart_client->addr,
			.flags = 0,
			.len = sizeof(buf) - 1,
			.buf = buf,
		},
	};

	put_unaligned_be16(NTXEC_RESET_VALUE, buf + 1);

	res = i2c_transfer(poweroff_restart_client->adapter, msgs, ARRAY_SIZE(msgs));
	if (res < 0)
		dev_warn(&poweroff_restart_client->dev,
			 "Failed to restart (err = %d)\n", res);

	return NOTIFY_DONE;
}

static struct notifier_block ntxec_restart_handler = {
	.notifier_call = ntxec_restart,
	.priority = 128,
};

static int regmap_ignore_write(void *context,
			       unsigned int reg, unsigned int val)

{
	struct regmap *regmap = context;

	regmap_write(regmap, reg, val);

	return 0;
}

static int regmap_wrap_read(void *context, unsigned int reg,
			    unsigned int *val)
{
	struct regmap *regmap = context;

	return regmap_read(regmap, reg, val);
}

/*
 * Some firmware versions do not ack written data, add a wrapper. It
 * is used to stack another regmap on top.
 */
static const struct regmap_config regmap_config_noack = {
	.name = "ntxec_noack",
	.reg_bits = 8,
	.val_bits = 16,
	.cache_type = REGCACHE_NONE,
	.reg_write = regmap_ignore_write,
	.reg_read = regmap_wrap_read
};

static const struct regmap_config regmap_config = {
	.name = "ntxec",
	.reg_bits = 8,
	.val_bits = 16,
	.cache_type = REGCACHE_NONE,
	.val_format_endian = REGMAP_ENDIAN_BIG,
};

static const struct mfd_cell ntxec_subdev[] = {
	{ .name = "ntxec-rtc" },
	{ .name = "ntxec-pwm" },
};

static const struct mfd_cell ntxec_subdev_pwm[] = {
	{ .name = "ntxec-pwm" },
};

static int ntxec_probe(struct i2c_client *client)
{
	struct ntxec *ec;
	unsigned int version;
	int res;
	const struct mfd_cell *subdevs;
	size_t n_subdevs;

	ec = devm_kmalloc(&client->dev, sizeof(*ec), GFP_KERNEL);
	if (!ec)
		return -ENOMEM;

	ec->dev = &client->dev;

	ec->regmap = devm_regmap_init_i2c(client, &regmap_config);
	if (IS_ERR(ec->regmap)) {
		dev_err(ec->dev, "Failed to set up regmap for device\n");
		return PTR_ERR(ec->regmap);
	}

	/* Determine the firmware version */
	res = regmap_read(ec->regmap, NTXEC_REG_VERSION, &version);
	if (res < 0) {
		dev_err(ec->dev, "Failed to read firmware version number\n");
		return res;
	}

	/* Bail out if we encounter an unknown firmware version */
	switch (version) {
	case NTXEC_VERSION_KOBO_AURA:
	case NTXEC_VERSION_TOLINO_VISION:
		subdevs = ntxec_subdev;
		n_subdevs = ARRAY_SIZE(ntxec_subdev);
		break;
	case NTXEC_VERSION_TOLINO_SHINE2:
		subdevs = ntxec_subdev_pwm;
		n_subdevs = ARRAY_SIZE(ntxec_subdev_pwm);
		/* Another regmap stacked on top of the other */
		ec->regmap = devm_regmap_init(ec->dev, NULL,
					      ec->regmap,
					      &regmap_config_noack);
		if (IS_ERR(ec->regmap))
			return PTR_ERR(ec->regmap);
		break;
	default:
		dev_err(ec->dev,
			"Netronix embedded controller version %04x is not supported.\n",
			version);
		return -ENODEV;
	}

	dev_info(ec->dev,
		 "Netronix embedded controller version %04x detected.\n", version);

	if (of_device_is_system_power_controller(ec->dev->of_node)) {
		/*
		 * Set the 'powerkeep' bit. This is necessary on some boards
		 * in order to keep the system running.
		 */
		res = regmap_write(ec->regmap, NTXEC_REG_POWERKEEP,
				   NTXEC_POWERKEEP_VALUE);
		if (res < 0)
			return res;

		if (poweroff_restart_client)
			/*
			 * Another instance of the driver already took
			 * poweroff/restart duties.
			 */
			dev_err(ec->dev, "poweroff_restart_client already assigned\n");
		else
			poweroff_restart_client = client;

		if (pm_power_off)
			/* Another driver already registered a poweroff handler. */
			dev_err(ec->dev, "pm_power_off already assigned\n");
		else
			pm_power_off = ntxec_poweroff;

		res = register_restart_handler(&ntxec_restart_handler);
		if (res)
			dev_err(ec->dev,
				"Failed to register restart handler: %d\n", res);
	}

	i2c_set_clientdata(client, ec);

	res = devm_mfd_add_devices(ec->dev, PLATFORM_DEVID_NONE,
				   subdevs, n_subdevs, NULL, 0, NULL);
	if (res)
		dev_err(ec->dev, "Failed to add subdevices: %d\n", res);

	return res;
}

static void ntxec_remove(struct i2c_client *client)
{
	if (client == poweroff_restart_client) {
		poweroff_restart_client = NULL;
		pm_power_off = NULL;
		unregister_restart_handler(&ntxec_restart_handler);
	}
}

static const struct of_device_id of_ntxec_match_table[] = {
	{ .compatible = "netronix,ntxec", },
	{}
};
MODULE_DEVICE_TABLE(of, of_ntxec_match_table);

static struct i2c_driver ntxec_driver = {
	.driver = {
		.name = "ntxec",
		.of_match_table = of_ntxec_match_table,
	},
	.probe = ntxec_probe,
	.remove = ntxec_remove,
};
module_i2c_driver(ntxec_driver);

MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
MODULE_DESCRIPTION("Core driver for Netronix EC");
MODULE_LICENSE("GPL");
