// SPDX-License-Identifier: GPL-2.0-only
/*
 * Support Infineon TLE62x0 driver chips
 *
 * Copyright (c) 2007 Simtec Electronics
 *	Ben Dooks, <ben@simtec.co.uk>
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/spi/spi.h>
#include <linux/spi/tle62x0.h>


#define CMD_READ	0x00
#define CMD_SET		0xff

#define DIAG_NORMAL	0x03
#define DIAG_OVERLOAD	0x02
#define DIAG_OPEN	0x01
#define DIAG_SHORTGND	0x00

struct tle62x0_state {
	struct spi_device	*us;
	struct mutex		lock;
	unsigned int		nr_gpio;
	unsigned int		gpio_state;

	unsigned char		tx_buff[4];
	unsigned char		rx_buff[4];
};

static int to_gpio_num(struct device_attribute *attr);

static inline int tle62x0_write(struct tle62x0_state *st)
{
	unsigned char *buff = st->tx_buff;
	unsigned int gpio_state = st->gpio_state;

	buff[0] = CMD_SET;

	if (st->nr_gpio == 16) {
		buff[1] = gpio_state >> 8;
		buff[2] = gpio_state;
	} else {
		buff[1] = gpio_state;
	}

	dev_dbg(&st->us->dev, "buff %3ph\n", buff);

	return spi_write(st->us, buff, (st->nr_gpio == 16) ? 3 : 2);
}

static inline int tle62x0_read(struct tle62x0_state *st)
{
	unsigned char *txbuff = st->tx_buff;
	struct spi_transfer xfer = {
		.tx_buf		= txbuff,
		.rx_buf		= st->rx_buff,
		.len		= (st->nr_gpio * 2) / 8,
	};
	struct spi_message msg;

	txbuff[0] = CMD_READ;
	txbuff[1] = 0x00;
	txbuff[2] = 0x00;
	txbuff[3] = 0x00;

	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	return spi_sync(st->us, &msg);
}

static unsigned char *decode_fault(unsigned int fault_code)
{
	fault_code &= 3;

	switch (fault_code) {
	case DIAG_NORMAL:
		return "N";
	case DIAG_OVERLOAD:
		return "V";
	case DIAG_OPEN:
		return "O";
	case DIAG_SHORTGND:
		return "G";
	}

	return "?";
}

static ssize_t tle62x0_status_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct tle62x0_state *st = dev_get_drvdata(dev);
	char *bp = buf;
	unsigned char *buff = st->rx_buff;
	unsigned long fault = 0;
	int ptr;
	int ret;

	mutex_lock(&st->lock);
	ret = tle62x0_read(st);
	dev_dbg(dev, "tle62x0_read() returned %d\n", ret);
	if (ret < 0) {
		mutex_unlock(&st->lock);
		return ret;
	}

	for (ptr = 0; ptr < (st->nr_gpio * 2)/8; ptr += 1) {
		fault <<= 8;
		fault  |= ((unsigned long)buff[ptr]);

		dev_dbg(dev, "byte %d is %02x\n", ptr, buff[ptr]);
	}

	for (ptr = 0; ptr < st->nr_gpio; ptr++) {
		bp += sprintf(bp, "%s ", decode_fault(fault >> (ptr * 2)));
	}

	*bp++ = '\n';

	mutex_unlock(&st->lock);
	return bp - buf;
}

static DEVICE_ATTR(status_show, S_IRUGO, tle62x0_status_show, NULL);

static ssize_t tle62x0_gpio_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct tle62x0_state *st = dev_get_drvdata(dev);
	int gpio_num = to_gpio_num(attr);
	int value;

	mutex_lock(&st->lock);
	value = (st->gpio_state >> gpio_num) & 1;
	mutex_unlock(&st->lock);

	return snprintf(buf, PAGE_SIZE, "%d", value);
}

static ssize_t tle62x0_gpio_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t len)
{
	struct tle62x0_state *st = dev_get_drvdata(dev);
	int gpio_num = to_gpio_num(attr);
	unsigned long val;
	char *endp;

	val = simple_strtoul(buf, &endp, 0);
	if (buf == endp)
		return -EINVAL;

	dev_dbg(dev, "setting gpio %d to %ld\n", gpio_num, val);

	mutex_lock(&st->lock);

	if (val)
		st->gpio_state |= 1 << gpio_num;
	else
		st->gpio_state &= ~(1 << gpio_num);

	tle62x0_write(st);
	mutex_unlock(&st->lock);

	return len;
}

static DEVICE_ATTR(gpio1, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio2, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio3, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio4, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio5, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio6, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio7, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio8, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio9, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio10, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio11, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio12, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio13, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio14, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio15, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);
static DEVICE_ATTR(gpio16, S_IWUSR|S_IRUGO,
		tle62x0_gpio_show, tle62x0_gpio_store);

static struct device_attribute *gpio_attrs[] = {
	[0]		= &dev_attr_gpio1,
	[1]		= &dev_attr_gpio2,
	[2]		= &dev_attr_gpio3,
	[3]		= &dev_attr_gpio4,
	[4]		= &dev_attr_gpio5,
	[5]		= &dev_attr_gpio6,
	[6]		= &dev_attr_gpio7,
	[7]		= &dev_attr_gpio8,
	[8]		= &dev_attr_gpio9,
	[9]		= &dev_attr_gpio10,
	[10]		= &dev_attr_gpio11,
	[11]		= &dev_attr_gpio12,
	[12]		= &dev_attr_gpio13,
	[13]		= &dev_attr_gpio14,
	[14]		= &dev_attr_gpio15,
	[15]		= &dev_attr_gpio16
};

static int to_gpio_num(struct device_attribute *attr)
{
	int ptr;

	for (ptr = 0; ptr < ARRAY_SIZE(gpio_attrs); ptr++) {
		if (gpio_attrs[ptr] == attr)
			return ptr;
	}

	return -1;
}

static int tle62x0_probe(struct spi_device *spi)
{
	struct tle62x0_state *st;
	struct tle62x0_pdata *pdata;
	int ptr;
	int ret;

	pdata = dev_get_platdata(&spi->dev);
	if (pdata == NULL) {
		dev_err(&spi->dev, "no device data specified\n");
		return -EINVAL;
	}

	st = kzalloc(sizeof(struct tle62x0_state), GFP_KERNEL);
	if (st == NULL)
		return -ENOMEM;

	st->us = spi;
	st->nr_gpio = pdata->gpio_count;
	st->gpio_state = pdata->init_state;

	mutex_init(&st->lock);

	ret = device_create_file(&spi->dev, &dev_attr_status_show);
	if (ret) {
		dev_err(&spi->dev, "cannot create status attribute\n");
		goto err_status;
	}

	for (ptr = 0; ptr < pdata->gpio_count; ptr++) {
		ret = device_create_file(&spi->dev, gpio_attrs[ptr]);
		if (ret) {
			dev_err(&spi->dev, "cannot create gpio attribute\n");
			goto err_gpios;
		}
	}

	/* tle62x0_write(st); */
	spi_set_drvdata(spi, st);
	return 0;

 err_gpios:
	while (--ptr >= 0)
		device_remove_file(&spi->dev, gpio_attrs[ptr]);

	device_remove_file(&spi->dev, &dev_attr_status_show);

 err_status:
	kfree(st);
	return ret;
}

static int tle62x0_remove(struct spi_device *spi)
{
	struct tle62x0_state *st = spi_get_drvdata(spi);
	int ptr;

	for (ptr = 0; ptr < st->nr_gpio; ptr++)
		device_remove_file(&spi->dev, gpio_attrs[ptr]);

	device_remove_file(&spi->dev, &dev_attr_status_show);
	kfree(st);
	return 0;
}

static struct spi_driver tle62x0_driver = {
	.driver = {
		.name	= "tle62x0",
	},
	.probe		= tle62x0_probe,
	.remove		= tle62x0_remove,
};

module_spi_driver(tle62x0_driver);

MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("TLE62x0 SPI driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:tle62x0");
