/*
 * 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>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#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/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;
	print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1,
		       tx->buf, tx->len, true);

	/* 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)
{
	int i;

	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] ", id, len);
		for (i = 0; i < len; ++i)
			pr_cont("0x%02x ", data[i]);
		pr_cont("\n");
	}
	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 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, "HM 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",
		 ipaq_micro_to_u16(dump+88) ? "yes" : "no");
	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));
	print_hex_dump(KERN_DEBUG, "eeprom: ", DUMP_PREFIX_OFFSET, 16, 1,
		       dump, 256, true);

}

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 micro_resume(struct device *dev)
{
	struct ipaq_micro *micro = dev_get_drvdata(dev);

	micro_reset_comm(micro);
	mdelay(10);

	return 0;
}

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

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

	micro->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -EINVAL;

	micro->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(micro->base))
		return PTR_ERR(micro->base);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res)
		return -EINVAL;

	micro->sdlc = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(micro->sdlc))
		return PTR_ERR(micro->sdlc);

	micro_reset_comm(micro);

	irq = platform_get_irq(pdev, 0);
	if (!irq)
		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 int micro_remove(struct platform_device *pdev)
{
	struct ipaq_micro *micro = platform_get_drvdata(pdev);
	u32 val;

	mfd_remove_devices(&pdev->dev);

	val = readl(micro->base + UTCR3);
	val &= ~(UTCR3_RXE | UTCR3_RIE); /* disable receive interrupt */
	val &= ~(UTCR3_TXE | UTCR3_TIE); /* disable transmit interrupt */
	writel(val, micro->base + UTCR3);

	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,
	},
	.probe    = micro_probe,
	.remove   = micro_remove,
	/* .shutdown = micro_suspend, // FIXME */
};
module_platform_driver(micro_device_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("driver for iPAQ Atmel micro core and backlight");
