// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for the TAOS evaluation modules
 * These devices include an I2C master which can be controlled over the
 * serial port.
 *
 * Copyright (C) 2007 Jean Delvare <jdelvare@suse.de>
 */

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/i2c.h>

#define TAOS_BUFFER_SIZE	63

#define TAOS_STATE_INIT		0
#define TAOS_STATE_IDLE		1
#define TAOS_STATE_EOFF		2
#define TAOS_STATE_RECV		3

#define TAOS_CMD_RESET		0x12
#define TAOS_CMD_ECHO_ON	'+'
#define TAOS_CMD_ECHO_OFF	'-'

static DECLARE_WAIT_QUEUE_HEAD(wq);

struct taos_data {
	struct i2c_adapter adapter;
	struct i2c_client *client;
	int state;
	u8 addr;		/* last used address */
	unsigned char buffer[TAOS_BUFFER_SIZE];
	unsigned int pos;	/* position inside the buffer */
};

/* TAOS TSL2550 EVM */
static const struct i2c_board_info tsl2550_info = {
	I2C_BOARD_INFO("tsl2550", 0x39),
};

/* Instantiate i2c devices based on the adapter name */
static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
{
	if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
		dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
			tsl2550_info.type, tsl2550_info.addr);
		return i2c_new_device(adapter, &tsl2550_info);
	}

	return NULL;
}

static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
			   unsigned short flags, char read_write, u8 command,
			   int size, union i2c_smbus_data *data)
{
	struct serio *serio = adapter->algo_data;
	struct taos_data *taos = serio_get_drvdata(serio);
	char *p;

	/* Encode our transaction. "@" is for the device address, "$" for the
	   SMBus command and "#" for the data. */
	p = taos->buffer;

	/* The device remembers the last used address, no need to send it
	   again if it's the same */
	if (addr != taos->addr)
		p += sprintf(p, "@%02X", addr);

	switch (size) {
	case I2C_SMBUS_BYTE:
		if (read_write == I2C_SMBUS_WRITE)
			sprintf(p, "$#%02X", command);
		else
			sprintf(p, "$");
		break;
	case I2C_SMBUS_BYTE_DATA:
		if (read_write == I2C_SMBUS_WRITE)
			sprintf(p, "$%02X#%02X", command, data->byte);
		else
			sprintf(p, "$%02X", command);
		break;
	default:
		dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
		return -EOPNOTSUPP;
	}

	/* Send the transaction to the TAOS EVM */
	dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
	for (p = taos->buffer; *p; p++)
		serio_write(serio, *p);

	taos->addr = addr;

	/* Start the transaction and read the answer */
	taos->pos = 0;
	taos->state = TAOS_STATE_RECV;
	serio_write(serio, read_write == I2C_SMBUS_WRITE ? '>' : '<');
	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
					 msecs_to_jiffies(150));
	if (taos->state != TAOS_STATE_IDLE
	 || taos->pos != 5) {
		dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
			taos->pos);
		return -EIO;
	}
	dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);

	/* Interpret the returned string */
	p = taos->buffer + 1;
	p[3] = '\0';
	if (!strcmp(p, "NAK"))
		return -ENODEV;

	if (read_write == I2C_SMBUS_WRITE) {
		if (!strcmp(p, "ACK"))
			return 0;
	} else {
		if (p[0] == 'x') {
			/*
			 * Voluntarily dropping error code of kstrtou8 since all
			 * error code that it could return are invalid according
			 * to Documentation/i2c/fault-codes.rst.
			 */
			if (kstrtou8(p + 1, 16, &data->byte))
				return -EPROTO;
			return 0;
		}
	}

	return -EIO;
}

static u32 taos_smbus_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA;
}

static const struct i2c_algorithm taos_algorithm = {
	.smbus_xfer	= taos_smbus_xfer,
	.functionality	= taos_smbus_func,
};

static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
				  unsigned int flags)
{
	struct taos_data *taos = serio_get_drvdata(serio);

	switch (taos->state) {
	case TAOS_STATE_INIT:
		taos->buffer[taos->pos++] = data;
		if (data == ':'
		 || taos->pos == TAOS_BUFFER_SIZE - 1) {
			taos->buffer[taos->pos] = '\0';
			taos->state = TAOS_STATE_IDLE;
			wake_up_interruptible(&wq);
		}
		break;
	case TAOS_STATE_EOFF:
		taos->state = TAOS_STATE_IDLE;
		wake_up_interruptible(&wq);
		break;
	case TAOS_STATE_RECV:
		taos->buffer[taos->pos++] = data;
		if (data == ']') {
			taos->buffer[taos->pos] = '\0';
			taos->state = TAOS_STATE_IDLE;
			wake_up_interruptible(&wq);
		}
		break;
	}

	return IRQ_HANDLED;
}

/* Extract the adapter name from the buffer received after reset.
   The buffer is modified and a pointer inside the buffer is returned. */
static char *taos_adapter_name(char *buffer)
{
	char *start, *end;

	start = strstr(buffer, "TAOS ");
	if (!start)
		return NULL;

	end = strchr(start, '\r');
	if (!end)
		return NULL;
	*end = '\0';

	return start;
}

static int taos_connect(struct serio *serio, struct serio_driver *drv)
{
	struct taos_data *taos;
	struct i2c_adapter *adapter;
	char *name;
	int err;

	taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL);
	if (!taos) {
		err = -ENOMEM;
		goto exit;
	}
	taos->state = TAOS_STATE_INIT;
	serio_set_drvdata(serio, taos);

	err = serio_open(serio, drv);
	if (err)
		goto exit_kfree;

	adapter = &taos->adapter;
	adapter->owner = THIS_MODULE;
	adapter->algo = &taos_algorithm;
	adapter->algo_data = serio;
	adapter->dev.parent = &serio->dev;

	/* Reset the TAOS evaluation module to identify it */
	serio_write(serio, TAOS_CMD_RESET);
	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
					 msecs_to_jiffies(2000));

	if (taos->state != TAOS_STATE_IDLE) {
		err = -ENODEV;
		dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, "
			"pos=%d)\n", taos->state, taos->pos);
		goto exit_close;
	}

	name = taos_adapter_name(taos->buffer);
	if (!name) {
		err = -ENODEV;
		dev_err(&serio->dev, "TAOS EVM identification failed\n");
		goto exit_close;
	}
	strlcpy(adapter->name, name, sizeof(adapter->name));

	/* Turn echo off for better performance */
	taos->state = TAOS_STATE_EOFF;
	serio_write(serio, TAOS_CMD_ECHO_OFF);

	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
					 msecs_to_jiffies(250));
	if (taos->state != TAOS_STATE_IDLE) {
		err = -ENODEV;
		dev_err(&serio->dev, "TAOS EVM echo off failed "
			"(state=%d)\n", taos->state);
		goto exit_close;
	}

	err = i2c_add_adapter(adapter);
	if (err)
		goto exit_close;
	dev_info(&serio->dev, "Connected to TAOS EVM\n");

	taos->client = taos_instantiate_device(adapter);
	return 0;

 exit_close:
	serio_close(serio);
 exit_kfree:
	kfree(taos);
 exit:
	return err;
}

static void taos_disconnect(struct serio *serio)
{
	struct taos_data *taos = serio_get_drvdata(serio);

	i2c_unregister_device(taos->client);
	i2c_del_adapter(&taos->adapter);
	serio_close(serio);
	kfree(taos);

	dev_info(&serio->dev, "Disconnected from TAOS EVM\n");
}

static const struct serio_device_id taos_serio_ids[] = {
	{
		.type	= SERIO_RS232,
		.proto	= SERIO_TAOSEVM,
		.id	= SERIO_ANY,
		.extra	= SERIO_ANY,
	},
	{ 0 }
};
MODULE_DEVICE_TABLE(serio, taos_serio_ids);

static struct serio_driver taos_drv = {
	.driver		= {
		.name	= "taos-evm",
	},
	.description	= "TAOS evaluation module driver",
	.id_table	= taos_serio_ids,
	.connect	= taos_connect,
	.disconnect	= taos_disconnect,
	.interrupt	= taos_interrupt,
};

module_serio_driver(taos_drv);

MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("TAOS evaluation module driver");
MODULE_LICENSE("GPL");
