// SPDX-License-Identifier: GPL-2.0
/*
 * The Gateworks System Controller (GSC) is a multi-function
 * device designed for use in Gateworks Single Board Computers.
 * The control interface is I2C, with an interrupt. The device supports
 * system functions such as push-button monitoring, multiple ADC's for
 * voltage and temperature monitoring, fan controller and watchdog monitor.
 *
 * Copyright (C) 2020 Gateworks Corporation
 */

#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mfd/gsc.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <linux/unaligned.h>

/*
 * The GSC suffers from an errata where occasionally during
 * ADC cycles the chip can NAK I2C transactions. To ensure we have reliable
 * register access we place retries around register access.
 */
#define I2C_RETRIES	3

int gsc_write(void *context, unsigned int reg, unsigned int val)
{
	struct i2c_client *client = context;
	int retry, ret;

	for (retry = 0; retry < I2C_RETRIES; retry++) {
		ret = i2c_smbus_write_byte_data(client, reg, val);
		/*
		 * -EAGAIN returned when the i2c host controller is busy
		 * -EIO returned when i2c device is busy
		 */
		if (ret != -EAGAIN && ret != -EIO)
			break;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(gsc_write);

int gsc_read(void *context, unsigned int reg, unsigned int *val)
{
	struct i2c_client *client = context;
	int retry, ret;

	for (retry = 0; retry < I2C_RETRIES; retry++) {
		ret = i2c_smbus_read_byte_data(client, reg);
		/*
		 * -EAGAIN returned when the i2c host controller is busy
		 * -EIO returned when i2c device is busy
		 */
		if (ret != -EAGAIN && ret != -EIO)
			break;
	}
	*val = ret & 0xff;

	return 0;
}
EXPORT_SYMBOL_GPL(gsc_read);

/*
 * gsc_powerdown - API to use GSC to power down board for a specific time
 *
 * secs - number of seconds to remain powered off
 */
static int gsc_powerdown(struct gsc_dev *gsc, unsigned long secs)
{
	int ret;
	unsigned char regs[4];

	dev_info(&gsc->i2c->dev, "GSC powerdown for %ld seconds\n",
		 secs);

	put_unaligned_le32(secs, regs);
	ret = regmap_bulk_write(gsc->regmap, GSC_TIME_ADD, regs, 4);
	if (ret)
		return ret;

	ret = regmap_update_bits(gsc->regmap, GSC_CTRL_1,
				 BIT(GSC_CTRL_1_SLEEP_ADD),
				 BIT(GSC_CTRL_1_SLEEP_ADD));
	if (ret)
		return ret;

	ret = regmap_update_bits(gsc->regmap, GSC_CTRL_1,
				 BIT(GSC_CTRL_1_SLEEP_ACTIVATE) |
				 BIT(GSC_CTRL_1_SLEEP_ENABLE),
				 BIT(GSC_CTRL_1_SLEEP_ACTIVATE) |
				 BIT(GSC_CTRL_1_SLEEP_ENABLE));


	return ret;
}

static ssize_t gsc_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct gsc_dev *gsc = dev_get_drvdata(dev);
	const char *name = attr->attr.name;
	int rz = 0;

	if (strcasecmp(name, "fw_version") == 0)
		rz = sprintf(buf, "%d\n", gsc->fwver);
	else if (strcasecmp(name, "fw_crc") == 0)
		rz = sprintf(buf, "0x%04x\n", gsc->fwcrc);
	else
		dev_err(dev, "invalid command: '%s'\n", name);

	return rz;
}

static ssize_t gsc_store(struct device *dev, struct device_attribute *attr,
			 const char *buf, size_t count)
{
	struct gsc_dev *gsc = dev_get_drvdata(dev);
	const char *name = attr->attr.name;
	long value;

	if (strcasecmp(name, "powerdown") == 0) {
		if (kstrtol(buf, 0, &value) == 0)
			gsc_powerdown(gsc, value);
	} else {
		dev_err(dev, "invalid command: '%s\n", name);
	}

	return count;
}

static struct device_attribute attr_fwver =
	__ATTR(fw_version, 0440, gsc_show, NULL);
static struct device_attribute attr_fwcrc =
	__ATTR(fw_crc, 0440, gsc_show, NULL);
static struct device_attribute attr_pwrdown =
	__ATTR(powerdown, 0220, NULL, gsc_store);

static struct attribute *gsc_attrs[] = {
	&attr_fwver.attr,
	&attr_fwcrc.attr,
	&attr_pwrdown.attr,
	NULL,
};

static struct attribute_group attr_group = {
	.attrs = gsc_attrs,
};

static const struct of_device_id gsc_of_match[] = {
	{ .compatible = "gw,gsc", },
	{ }
};
MODULE_DEVICE_TABLE(of, gsc_of_match);

static const struct regmap_bus gsc_regmap_bus = {
	.reg_read = gsc_read,
	.reg_write = gsc_write,
};

static const struct regmap_config gsc_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.cache_type = REGCACHE_NONE,
	.max_register = GSC_WP,
};

static const struct regmap_irq gsc_irqs[] = {
	REGMAP_IRQ_REG(GSC_IRQ_PB, 0, BIT(GSC_IRQ_PB)),
	REGMAP_IRQ_REG(GSC_IRQ_KEY_ERASED, 0, BIT(GSC_IRQ_KEY_ERASED)),
	REGMAP_IRQ_REG(GSC_IRQ_EEPROM_WP, 0, BIT(GSC_IRQ_EEPROM_WP)),
	REGMAP_IRQ_REG(GSC_IRQ_RESV, 0, BIT(GSC_IRQ_RESV)),
	REGMAP_IRQ_REG(GSC_IRQ_GPIO, 0, BIT(GSC_IRQ_GPIO)),
	REGMAP_IRQ_REG(GSC_IRQ_TAMPER, 0, BIT(GSC_IRQ_TAMPER)),
	REGMAP_IRQ_REG(GSC_IRQ_WDT_TIMEOUT, 0, BIT(GSC_IRQ_WDT_TIMEOUT)),
	REGMAP_IRQ_REG(GSC_IRQ_SWITCH_HOLD, 0, BIT(GSC_IRQ_SWITCH_HOLD)),
};

static const struct regmap_irq_chip gsc_irq_chip = {
	.name = "gateworks-gsc",
	.irqs = gsc_irqs,
	.num_irqs = ARRAY_SIZE(gsc_irqs),
	.num_regs = 1,
	.status_base = GSC_IRQ_STATUS,
	.unmask_base = GSC_IRQ_ENABLE,
	.ack_base = GSC_IRQ_STATUS,
	.ack_invert = true,
};

static int gsc_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct gsc_dev *gsc;
	struct regmap_irq_chip_data *irq_data;
	int ret;
	unsigned int reg;

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

	gsc->dev = &client->dev;
	gsc->i2c = client;
	i2c_set_clientdata(client, gsc);

	gsc->regmap = devm_regmap_init(dev, &gsc_regmap_bus, client,
				       &gsc_regmap_config);
	if (IS_ERR(gsc->regmap))
		return PTR_ERR(gsc->regmap);

	if (regmap_read(gsc->regmap, GSC_FW_VER, &reg))
		return -EIO;
	gsc->fwver = reg;

	regmap_read(gsc->regmap, GSC_FW_CRC, &reg);
	gsc->fwcrc = reg;
	regmap_read(gsc->regmap, GSC_FW_CRC + 1, &reg);
	gsc->fwcrc |= reg << 8;

	gsc->i2c_hwmon = devm_i2c_new_dummy_device(dev, client->adapter,
						   GSC_HWMON);
	if (IS_ERR(gsc->i2c_hwmon)) {
		dev_err(dev, "Failed to allocate I2C device for HWMON\n");
		return PTR_ERR(gsc->i2c_hwmon);
	}

	ret = devm_regmap_add_irq_chip(dev, gsc->regmap, client->irq,
				       IRQF_ONESHOT | IRQF_SHARED |
				       IRQF_TRIGGER_LOW, 0,
				       &gsc_irq_chip, &irq_data);
	if (ret)
		return ret;

	dev_info(dev, "Gateworks System Controller v%d: fw 0x%04x\n",
		 gsc->fwver, gsc->fwcrc);

	ret = sysfs_create_group(&dev->kobj, &attr_group);
	if (ret)
		dev_err(dev, "failed to create sysfs attrs\n");

	ret = devm_of_platform_populate(dev);
	if (ret) {
		sysfs_remove_group(&dev->kobj, &attr_group);
		return ret;
	}

	return 0;
}

static void gsc_remove(struct i2c_client *client)
{
	sysfs_remove_group(&client->dev.kobj, &attr_group);
}

static struct i2c_driver gsc_driver = {
	.driver = {
		.name	= "gateworks-gsc",
		.of_match_table = gsc_of_match,
	},
	.probe		= gsc_probe,
	.remove		= gsc_remove,
};
module_i2c_driver(gsc_driver);

MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>");
MODULE_DESCRIPTION("I2C Core interface for GSC");
MODULE_LICENSE("GPL v2");
