// SPDX-License-Identifier: GPL-2.0-only
/*
 * Compaq iPAQ h3xxx Atmel microcontroller companion support
 *
 * This is an Atmel AT90LS8535 with a special flashed-in firmware that
 * implements the special protocol used by this driver.
 *
 * based on previous kernel 2.4 version by Andrew Christian
 * Author : Alessandro Gardich <gremlin@gremlin.it>
 * Author : Dmitry Artamonow <mad_soft@inbox.ru>
 * Author : Linus Walleij <linus.walleij@linaro.org>
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ipaq-micro.h>
#include <linux/string.h>
#include <linux/string_choices.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/list.h>

#include <mach/hardware.h>

static void ipaq_micro_trigger_tx(struct ipaq_micro *micro)
{
	struct ipaq_micro_txdev *tx = &micro->tx;
	struct ipaq_micro_msg *msg = micro->msg;
	int i, bp;
	u8 checksum;
	u32 val;

	bp = 0;
	tx->buf[bp++] = CHAR_SOF;

	checksum = ((msg->id & 0x0f) << 4) | (msg->tx_len & 0x0f);
	tx->buf[bp++] = checksum;

	for (i = 0; i < msg->tx_len; i++) {
		tx->buf[bp++] = msg->tx_data[i];
		checksum += msg->tx_data[i];
	}

	tx->buf[bp++] = checksum;
	tx->len = bp;
	tx->index = 0;

	/* Enable interrupt */
	val = readl(micro->base + UTCR3);
	val |= UTCR3_TIE;
	writel(val, micro->base + UTCR3);
}

int ipaq_micro_tx_msg(struct ipaq_micro *micro, struct ipaq_micro_msg *msg)
{
	unsigned long flags;

	dev_dbg(micro->dev, "TX msg: %02x, %d bytes\n", msg->id, msg->tx_len);

	spin_lock_irqsave(&micro->lock, flags);
	if (micro->msg) {
		list_add_tail(&msg->node, &micro->queue);
		spin_unlock_irqrestore(&micro->lock, flags);
		return 0;
	}
	micro->msg = msg;
	ipaq_micro_trigger_tx(micro);
	spin_unlock_irqrestore(&micro->lock, flags);
	return 0;
}
EXPORT_SYMBOL(ipaq_micro_tx_msg);

static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data)
{
	dev_dbg(micro->dev, "RX msg: %02x, %d bytes\n", id, len);

	spin_lock(&micro->lock);
	switch (id) {
	case MSG_VERSION:
	case MSG_EEPROM_READ:
	case MSG_EEPROM_WRITE:
	case MSG_BACKLIGHT:
	case MSG_NOTIFY_LED:
	case MSG_THERMAL_SENSOR:
	case MSG_BATTERY:
		/* Handle synchronous messages */
		if (micro->msg && micro->msg->id == id) {
			struct ipaq_micro_msg *msg = micro->msg;

			memcpy(msg->rx_data, data, len);
			msg->rx_len = len;
			complete(&micro->msg->ack);
			if (!list_empty(&micro->queue)) {
				micro->msg = list_entry(micro->queue.next,
							struct ipaq_micro_msg,
							node);
				list_del_init(&micro->msg->node);
				ipaq_micro_trigger_tx(micro);
			} else
				micro->msg = NULL;
			dev_dbg(micro->dev, "OK RX message 0x%02x\n", id);
		} else {
			dev_err(micro->dev,
				"out of band RX message 0x%02x\n", id);
			if (!micro->msg)
				dev_info(micro->dev, "no message queued\n");
			else
				dev_info(micro->dev, "expected message %02x\n",
					 micro->msg->id);
		}
		break;
	case MSG_KEYBOARD:
		if (micro->key)
			micro->key(micro->key_data, len, data);
		else
			dev_dbg(micro->dev, "key message ignored, no handle\n");
		break;
	case MSG_TOUCHSCREEN:
		if (micro->ts)
			micro->ts(micro->ts_data, len, data);
		else
			dev_dbg(micro->dev, "touchscreen message ignored, no handle\n");
		break;
	default:
		dev_err(micro->dev,
			"unknown msg %d [%d] %*ph\n", id, len, len, data);
		break;
	}
	spin_unlock(&micro->lock);
}

static void micro_process_char(struct ipaq_micro *micro, u8 ch)
{
	struct ipaq_micro_rxdev *rx = &micro->rx;

	switch (rx->state) {
	case STATE_SOF:	/* Looking for SOF */
		if (ch == CHAR_SOF)
			rx->state = STATE_ID; /* Next byte is the id and len */
		break;
	case STATE_ID: /* Looking for id and len byte */
		rx->id = (ch & 0xf0) >> 4;
		rx->len = (ch & 0x0f);
		rx->index = 0;
		rx->chksum = ch;
		rx->state = (rx->len > 0) ? STATE_DATA : STATE_CHKSUM;
		break;
	case STATE_DATA: /* Looking for 'len' data bytes */
		rx->chksum += ch;
		rx->buf[rx->index] = ch;
		if (++rx->index == rx->len)
			rx->state = STATE_CHKSUM;
		break;
	case STATE_CHKSUM: /* Looking for the checksum */
		if (ch == rx->chksum)
			micro_rx_msg(micro, rx->id, rx->len, rx->buf);
		rx->state = STATE_SOF;
		break;
	}
}

static void micro_rx_chars(struct ipaq_micro *micro)
{
	u32 status, ch;

	while ((status = readl(micro->base + UTSR1)) & UTSR1_RNE) {
		ch = readl(micro->base + UTDR);
		if (status & UTSR1_PRE)
			dev_err(micro->dev, "rx: parity error\n");
		else if (status & UTSR1_FRE)
			dev_err(micro->dev, "rx: framing error\n");
		else if (status & UTSR1_ROR)
			dev_err(micro->dev, "rx: overrun error\n");
		micro_process_char(micro, ch);
	}
}

static void ipaq_micro_get_version(struct ipaq_micro *micro)
{
	struct ipaq_micro_msg msg = {
		.id = MSG_VERSION,
	};

	ipaq_micro_tx_msg_sync(micro, &msg);
	if (msg.rx_len == 4) {
		memcpy(micro->version, msg.rx_data, 4);
		micro->version[4] = '\0';
	} else if (msg.rx_len == 9) {
		memcpy(micro->version, msg.rx_data, 4);
		micro->version[4] = '\0';
		/* Bytes 4-7 are "pack", byte 8 is "boot type" */
	} else {
		dev_err(micro->dev,
			"illegal version message %d bytes\n", msg.rx_len);
	}
}

static void ipaq_micro_eeprom_read(struct ipaq_micro *micro,
				   u8 address, u8 len, u8 *data)
{
	struct ipaq_micro_msg msg = {
		.id = MSG_EEPROM_READ,
	};
	u8 i;

	for (i = 0; i < len; i++) {
		msg.tx_data[0] = address + i;
		msg.tx_data[1] = 1;
		msg.tx_len = 2;
		ipaq_micro_tx_msg_sync(micro, &msg);
		memcpy(data + (i * 2), msg.rx_data, 2);
	}
}

static char *ipaq_micro_str(u8 *wchar, u8 len)
{
	char retstr[256];
	u8 i;

	for (i = 0; i < len / 2; i++)
		retstr[i] = wchar[i * 2];
	return kstrdup(retstr, GFP_KERNEL);
}

static u16 ipaq_micro_to_u16(u8 *data)
{
	return data[1] << 8 | data[0];
}

static void __init ipaq_micro_eeprom_dump(struct ipaq_micro *micro)
{
	u8 dump[256];
	char *str;

	ipaq_micro_eeprom_read(micro, 0, 128, dump);
	str = ipaq_micro_str(dump, 10);
	if (str) {
		dev_info(micro->dev, "HW version %s\n", str);
		kfree(str);
	}
	str = ipaq_micro_str(dump+10, 40);
	if (str) {
		dev_info(micro->dev, "serial number: %s\n", str);
		/* Feed the random pool with this */
		add_device_randomness(str, strlen(str));
		kfree(str);
	}
	str = ipaq_micro_str(dump+50, 20);
	if (str) {
		dev_info(micro->dev, "module ID: %s\n", str);
		kfree(str);
	}
	str = ipaq_micro_str(dump+70, 10);
	if (str) {
		dev_info(micro->dev, "product revision: %s\n", str);
		kfree(str);
	}
	dev_info(micro->dev, "product ID: %u\n", ipaq_micro_to_u16(dump+80));
	dev_info(micro->dev, "frame rate: %u fps\n",
		 ipaq_micro_to_u16(dump+82));
	dev_info(micro->dev, "page mode: %u\n", ipaq_micro_to_u16(dump+84));
	dev_info(micro->dev, "country ID: %u\n", ipaq_micro_to_u16(dump+86));
	dev_info(micro->dev, "color display: %s\n",
		 str_yes_no(ipaq_micro_to_u16(dump + 88)));
	dev_info(micro->dev, "ROM size: %u MiB\n", ipaq_micro_to_u16(dump+90));
	dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92));
	dev_info(micro->dev, "screen: %u x %u\n",
		 ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96));
}

static void micro_tx_chars(struct ipaq_micro *micro)
{
	struct ipaq_micro_txdev *tx = &micro->tx;
	u32 val;

	while ((tx->index < tx->len) &&
	       (readl(micro->base + UTSR1) & UTSR1_TNF)) {
		writel(tx->buf[tx->index], micro->base + UTDR);
		tx->index++;
	}

	/* Stop interrupts */
	val = readl(micro->base + UTCR3);
	val &= ~UTCR3_TIE;
	writel(val, micro->base + UTCR3);
}

static void micro_reset_comm(struct ipaq_micro *micro)
{
	struct ipaq_micro_rxdev *rx = &micro->rx;
	u32 val;

	if (micro->msg)
		complete(&micro->msg->ack);

	/* Initialize Serial channel protocol frame */
	rx->state = STATE_SOF;  /* Reset the state machine */

	/* Set up interrupts */
	writel(0x01, micro->sdlc + 0x0); /* Select UART mode */

	/* Clean up CR3 */
	writel(0x0, micro->base + UTCR3);

	/* Format: 8N1 */
	writel(UTCR0_8BitData | UTCR0_1StpBit, micro->base + UTCR0);

	/* Baud rate: 115200 */
	writel(0x0, micro->base + UTCR1);
	writel(0x1, micro->base + UTCR2);

	/* Clear SR0 */
	writel(0xff, micro->base + UTSR0);

	/* Enable RX int, disable TX int */
	writel(UTCR3_TXE | UTCR3_RXE | UTCR3_RIE, micro->base + UTCR3);
	val = readl(micro->base + UTCR3);
	val &= ~UTCR3_TIE;
	writel(val, micro->base + UTCR3);
}

static irqreturn_t micro_serial_isr(int irq, void *dev_id)
{
	struct ipaq_micro *micro = dev_id;
	struct ipaq_micro_txdev *tx = &micro->tx;
	u32 status;

	status = readl(micro->base + UTSR0);
	do {
		if (status & (UTSR0_RID | UTSR0_RFS)) {
			if (status & UTSR0_RID)
				/* Clear the Receiver IDLE bit */
				writel(UTSR0_RID, micro->base + UTSR0);
			micro_rx_chars(micro);
		}

		/* Clear break bits */
		if (status & (UTSR0_RBB | UTSR0_REB))
			writel(status & (UTSR0_RBB | UTSR0_REB),
			       micro->base + UTSR0);

		if (status & UTSR0_TFS)
			micro_tx_chars(micro);

		status = readl(micro->base + UTSR0);

	} while (((tx->index < tx->len) && (status & UTSR0_TFS)) ||
		 (status & (UTSR0_RFS | UTSR0_RID)));

	return IRQ_HANDLED;
}

static const struct mfd_cell micro_cells[] = {
	{ .name = "ipaq-micro-backlight", },
	{ .name = "ipaq-micro-battery", },
	{ .name = "ipaq-micro-keys", },
	{ .name = "ipaq-micro-ts", },
	{ .name = "ipaq-micro-leds", },
};

static int __maybe_unused micro_resume(struct device *dev)
{
	struct ipaq_micro *micro = dev_get_drvdata(dev);

	micro_reset_comm(micro);
	mdelay(10);

	return 0;
}

static int __init micro_probe(struct platform_device *pdev)
{
	struct ipaq_micro *micro;
	int ret;
	int irq;

	micro = devm_kzalloc(&pdev->dev, sizeof(*micro), GFP_KERNEL);
	if (!micro)
		return -ENOMEM;

	micro->dev = &pdev->dev;

	micro->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
	if (IS_ERR(micro->base))
		return PTR_ERR(micro->base);

	micro->sdlc = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(micro->sdlc))
		return PTR_ERR(micro->sdlc);

	micro_reset_comm(micro);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return -EINVAL;
	ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr,
			       IRQF_SHARED, "ipaq-micro",
			       micro);
	if (ret) {
		dev_err(&pdev->dev, "unable to grab serial port IRQ\n");
		return ret;
	} else
		dev_info(&pdev->dev, "grabbed serial port IRQ\n");

	spin_lock_init(&micro->lock);
	INIT_LIST_HEAD(&micro->queue);
	platform_set_drvdata(pdev, micro);

	ret = mfd_add_devices(&pdev->dev, pdev->id, micro_cells,
			      ARRAY_SIZE(micro_cells), NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev, "error adding MFD cells");
		return ret;
	}

	/* Check version */
	ipaq_micro_get_version(micro);
	dev_info(&pdev->dev, "Atmel micro ASIC version %s\n", micro->version);
	ipaq_micro_eeprom_dump(micro);

	return 0;
}

static const struct dev_pm_ops micro_dev_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(NULL, micro_resume)
};

static struct platform_driver micro_device_driver = {
	.driver   = {
		.name	= "ipaq-h3xxx-micro",
		.pm	= &micro_dev_pm_ops,
		.suppress_bind_attrs = true,
	},
};
builtin_platform_driver_probe(micro_device_driver, micro_probe);
