// SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0-or-later
/*
 * ENE KB3930 Embedded Controller Driver
 *
 * Copyright (C) 2020 Lubomir Rintel
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/regmap.h>

/* I2C registers that are multiplexing access to the EC RAM. */
enum {
	EC_DATA_IN	= 0x00,
	EC_RAM_OUT	= 0x80,
	EC_RAM_IN	= 0x81,
};

/* EC RAM registers. */
enum {
	EC_MODEL	= 0x30,
	EC_VERSION_MAJ	= 0x31,
	EC_VERSION_MIN	= 0x32,
};

struct kb3930 {
	struct i2c_client *client;
	struct regmap *ram_regmap;
	struct gpio_descs *off_gpios;
};

static struct kb3930 *kb3930_power_off;

#define EC_GPIO_WAVE		0
#define EC_GPIO_OFF_MODE	1

#define EC_OFF_MODE_REBOOT	0
#define EC_OFF_MODE_POWER	1

static void kb3930_off(struct kb3930 *ddata, int off_mode)
{
	gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_OFF_MODE],
			       off_mode);

	/*
	 * This creates a 10 Hz wave on EC_GPIO_WAVE that signals a
	 * shutdown request to the EC. Once the EC detects it, it will
	 * proceed to turn the power off or reset the board depending on
	 * the value of EC_GPIO_OFF_MODE.
	 */
	while (1) {
		mdelay(50);
		gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_WAVE], 0);
		mdelay(50);
		gpiod_direction_output(ddata->off_gpios->desc[EC_GPIO_WAVE], 1);
	}
}

static int kb3930_restart(struct notifier_block *this,
			  unsigned long mode, void *cmd)
{
	kb3930_off(kb3930_power_off, EC_OFF_MODE_REBOOT);
	return NOTIFY_DONE;
}

static void kb3930_pm_power_off(void)
{
	kb3930_off(kb3930_power_off, EC_OFF_MODE_POWER);
}

static struct notifier_block kb3930_restart_nb = {
	.notifier_call = kb3930_restart,
};

static const struct mfd_cell ariel_ec_cells[] = {
	{ .name = "dell-wyse-ariel-led", },
	{ .name = "dell-wyse-ariel-power", },
};

static int kb3930_ec_ram_reg_write(void *context, unsigned int reg,
				   unsigned int val)
{
	struct kb3930 *ddata = context;

	return i2c_smbus_write_word_data(ddata->client, EC_RAM_OUT,
					 (val << 8) | reg);
}

static int kb3930_ec_ram_reg_read(void *context, unsigned int reg,
				  unsigned int *val)
{
	struct kb3930 *ddata = context;
	int ret;

	ret = i2c_smbus_write_word_data(ddata->client, EC_RAM_IN, reg);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_word_data(ddata->client, EC_DATA_IN);
	if (ret < 0)
		return ret;

	*val = ret >> 8;
	return 0;
}

static const struct regmap_config kb3930_ram_regmap_config = {
	.name = "ec_ram",
	.reg_bits = 8,
	.val_bits = 8,
	.reg_stride = 1,
	.max_register = 0xff,
	.reg_write = kb3930_ec_ram_reg_write,
	.reg_read = kb3930_ec_ram_reg_read,
	.fast_io = false,
};

static int kb3930_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device_node *np = dev->of_node;
	struct kb3930 *ddata;
	unsigned int model;
	int ret;

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

	kb3930_power_off = ddata;
	ddata->client = client;
	i2c_set_clientdata(client, ddata);

	ddata->ram_regmap = devm_regmap_init(dev, NULL, ddata,
					     &kb3930_ram_regmap_config);
	if (IS_ERR(ddata->ram_regmap))
		return PTR_ERR(ddata->ram_regmap);

	ret = regmap_read(ddata->ram_regmap, EC_MODEL, &model);
	if (ret < 0)
		return ret;

	/* Currently we only support the cells present on Dell Ariel model. */
	if (model != 'J') {
		dev_err(dev, "unknown board model: %02x\n", model);
		return -ENODEV;
	}

	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
				   ariel_ec_cells,
				   ARRAY_SIZE(ariel_ec_cells),
				   NULL, 0, NULL);
	if (ret)
		return ret;

	if (of_property_read_bool(np, "system-power-controller")) {
		ddata->off_gpios =
			devm_gpiod_get_array_optional(dev, "off", GPIOD_IN);
		if (IS_ERR(ddata->off_gpios))
			return PTR_ERR(ddata->off_gpios);
		if (ddata->off_gpios->ndescs < 2) {
			dev_err(dev, "invalid off-gpios property\n");
			return -EINVAL;
		}
	}

	if (ddata->off_gpios) {
		register_restart_handler(&kb3930_restart_nb);
		if (!pm_power_off)
			pm_power_off = kb3930_pm_power_off;
	}

	return 0;
}

static int kb3930_remove(struct i2c_client *client)
{
	struct kb3930 *ddata = i2c_get_clientdata(client);

	if (ddata->off_gpios) {
		if (pm_power_off == kb3930_pm_power_off)
			pm_power_off = NULL;
		unregister_restart_handler(&kb3930_restart_nb);
	}
	kb3930_power_off = NULL;

	return 0;
}

static const struct of_device_id kb3930_dt_ids[] = {
	{ .compatible = "ene,kb3930" },
	{ }
};
MODULE_DEVICE_TABLE(of, kb3930_dt_ids);

static struct i2c_driver kb3930_driver = {
	.probe_new = kb3930_probe,
	.remove = kb3930_remove,
	.driver = {
		.name = "ene-kb3930",
		.of_match_table = kb3930_dt_ids,
	},
};
module_i2c_driver(kb3930_driver);

MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("ENE KB3930 Embedded Controller Driver");
MODULE_LICENSE("Dual BSD/GPL");
