// SPDX-License-Identifier: GPL-2.0
/*
 *  Probe for F81216A LPC to 4 UART
 *
 *  Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S
 */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pnp.h>
#include <linux/kernel.h>
#include <linux/serial_core.h>
#include <linux/irq.h>
#include  "8250.h"

#define ADDR_PORT 0
#define DATA_PORT 1
#define EXIT_KEY 0xAA
#define CHIP_ID1  0x20
#define CHIP_ID2  0x21
#define CHIP_ID_F81865 0x0407
#define CHIP_ID_F81866 0x1010
#define CHIP_ID_F81216AD 0x1602
#define CHIP_ID_F81216H 0x0501
#define CHIP_ID_F81216 0x0802
#define VENDOR_ID1 0x23
#define VENDOR_ID1_VAL 0x19
#define VENDOR_ID2 0x24
#define VENDOR_ID2_VAL 0x34
#define IO_ADDR1 0x61
#define IO_ADDR2 0x60
#define LDN 0x7

#define FINTEK_IRQ_MODE	0x70
#define IRQ_SHARE	BIT(4)
#define IRQ_MODE_MASK	(BIT(6) | BIT(5))
#define IRQ_LEVEL_LOW	0
#define IRQ_EDGE_HIGH	BIT(5)

/*
 * F81216H clock source register, the value and mask is the same with F81866,
 * but it's on F0h.
 *
 * Clock speeds for UART (register F0h)
 * 00: 1.8432MHz.
 * 01: 18.432MHz.
 * 10: 24MHz.
 * 11: 14.769MHz.
 */
#define RS485  0xF0
#define RTS_INVERT BIT(5)
#define RS485_URA BIT(4)
#define RXW4C_IRA BIT(3)
#define TXW4C_IRA BIT(2)

#define FIFO_CTRL		0xF6
#define FIFO_MODE_MASK		(BIT(1) | BIT(0))
#define FIFO_MODE_128		(BIT(1) | BIT(0))
#define RXFTHR_MODE_MASK	(BIT(5) | BIT(4))
#define RXFTHR_MODE_4X		BIT(5)

#define F81216_LDN_LOW	0x0
#define F81216_LDN_HIGH	0x4

/*
 * F81866 registers
 *
 * The IRQ setting mode of F81866 is not the same with F81216 series.
 *	Level/Low: IRQ_MODE0:0, IRQ_MODE1:0
 *	Edge/High: IRQ_MODE0:1, IRQ_MODE1:0
 *
 * Clock speeds for UART (register F2h)
 * 00: 1.8432MHz.
 * 01: 18.432MHz.
 * 10: 24MHz.
 * 11: 14.769MHz.
 */
#define F81866_IRQ_MODE		0xf0
#define F81866_IRQ_SHARE	BIT(0)
#define F81866_IRQ_MODE0	BIT(1)

#define F81866_FIFO_CTRL	FIFO_CTRL
#define F81866_IRQ_MODE1	BIT(3)

#define F81866_LDN_LOW		0x10
#define F81866_LDN_HIGH		0x16

#define F81866_UART_CLK 0xF2
#define F81866_UART_CLK_MASK (BIT(1) | BIT(0))
#define F81866_UART_CLK_1_8432MHZ 0
#define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0))
#define F81866_UART_CLK_18_432MHZ BIT(0)
#define F81866_UART_CLK_24MHZ BIT(1)

struct fintek_8250 {
	u16 pid;
	u16 base_port;
	u8 index;
	u8 key;
};

static u8 sio_read_reg(struct fintek_8250 *pdata, u8 reg)
{
	outb(reg, pdata->base_port + ADDR_PORT);
	return inb(pdata->base_port + DATA_PORT);
}

static void sio_write_reg(struct fintek_8250 *pdata, u8 reg, u8 data)
{
	outb(reg, pdata->base_port + ADDR_PORT);
	outb(data, pdata->base_port + DATA_PORT);
}

static void sio_write_mask_reg(struct fintek_8250 *pdata, u8 reg, u8 mask,
			       u8 data)
{
	u8 tmp;

	tmp = (sio_read_reg(pdata, reg) & ~mask) | (mask & data);
	sio_write_reg(pdata, reg, tmp);
}

static int fintek_8250_enter_key(u16 base_port, u8 key)
{
	if (!request_muxed_region(base_port, 2, "8250_fintek"))
		return -EBUSY;

	/* Force to deactive all SuperIO in this base_port */
	outb(EXIT_KEY, base_port + ADDR_PORT);

	outb(key, base_port + ADDR_PORT);
	outb(key, base_port + ADDR_PORT);
	return 0;
}

static void fintek_8250_exit_key(u16 base_port)
{

	outb(EXIT_KEY, base_port + ADDR_PORT);
	release_region(base_port + ADDR_PORT, 2);
}

static int fintek_8250_check_id(struct fintek_8250 *pdata)
{
	u16 chip;

	if (sio_read_reg(pdata, VENDOR_ID1) != VENDOR_ID1_VAL)
		return -ENODEV;

	if (sio_read_reg(pdata, VENDOR_ID2) != VENDOR_ID2_VAL)
		return -ENODEV;

	chip = sio_read_reg(pdata, CHIP_ID1);
	chip |= sio_read_reg(pdata, CHIP_ID2) << 8;

	switch (chip) {
	case CHIP_ID_F81865:
	case CHIP_ID_F81866:
	case CHIP_ID_F81216AD:
	case CHIP_ID_F81216H:
	case CHIP_ID_F81216:
		break;
	default:
		return -ENODEV;
	}

	pdata->pid = chip;
	return 0;
}

static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
				     int *max)
{
	switch (pdata->pid) {
	case CHIP_ID_F81865:
	case CHIP_ID_F81866:
		*min = F81866_LDN_LOW;
		*max = F81866_LDN_HIGH;
		return 0;

	case CHIP_ID_F81216AD:
	case CHIP_ID_F81216H:
	case CHIP_ID_F81216:
		*min = F81216_LDN_LOW;
		*max = F81216_LDN_HIGH;
		return 0;
	}

	return -ENODEV;
}

static int fintek_8250_rs485_config(struct uart_port *port,
			      struct serial_rs485 *rs485)
{
	uint8_t config = 0;
	struct fintek_8250 *pdata = port->private_data;

	if (!pdata)
		return -EINVAL;

	/* Hardware do not support same RTS level on send and receive */
	if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==
			!(rs485->flags & SER_RS485_RTS_AFTER_SEND))
		return -EINVAL;

	if (rs485->flags & SER_RS485_ENABLED) {
		memset(rs485->padding, 0, sizeof(rs485->padding));
		config |= RS485_URA;
	} else {
		memset(rs485, 0, sizeof(*rs485));
	}

	rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
			SER_RS485_RTS_AFTER_SEND;

	/* Only the first port supports delays */
	if (pdata->index) {
		rs485->delay_rts_before_send = 0;
		rs485->delay_rts_after_send = 0;
	}

	if (rs485->delay_rts_before_send) {
		rs485->delay_rts_before_send = 1;
		config |= TXW4C_IRA;
	}

	if (rs485->delay_rts_after_send) {
		rs485->delay_rts_after_send = 1;
		config |= RXW4C_IRA;
	}

	if (rs485->flags & SER_RS485_RTS_ON_SEND)
		config |= RTS_INVERT;

	if (fintek_8250_enter_key(pdata->base_port, pdata->key))
		return -EBUSY;

	sio_write_reg(pdata, LDN, pdata->index);
	sio_write_reg(pdata, RS485, config);
	fintek_8250_exit_key(pdata->base_port);

	port->rs485 = *rs485;

	return 0;
}

static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
{
	sio_write_reg(pdata, LDN, pdata->index);

	switch (pdata->pid) {
	case CHIP_ID_F81866:
		sio_write_mask_reg(pdata, F81866_FIFO_CTRL, F81866_IRQ_MODE1,
				   0);
		/* fall through */
	case CHIP_ID_F81865:
		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_SHARE,
				   F81866_IRQ_SHARE);
		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_MODE0,
				   is_level ? 0 : F81866_IRQ_MODE0);
		break;

	case CHIP_ID_F81216AD:
	case CHIP_ID_F81216H:
	case CHIP_ID_F81216:
		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE,
				   IRQ_SHARE);
		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_MODE_MASK,
				   is_level ? IRQ_LEVEL_LOW : IRQ_EDGE_HIGH);
		break;
	}
}

static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)
{
	switch (pdata->pid) {
	case CHIP_ID_F81216H: /* 128Bytes FIFO */
	case CHIP_ID_F81866:
		sio_write_mask_reg(pdata, FIFO_CTRL,
				   FIFO_MODE_MASK | RXFTHR_MODE_MASK,
				   FIFO_MODE_128 | RXFTHR_MODE_4X);
		break;

	default: /* Default 16Bytes FIFO */
		break;
	}
}

static void fintek_8250_goto_highspeed(struct uart_8250_port *uart,
			      struct fintek_8250 *pdata)
{
	sio_write_reg(pdata, LDN, pdata->index);

	switch (pdata->pid) {
	case CHIP_ID_F81866: /* set uart clock for high speed serial mode */
		sio_write_mask_reg(pdata, F81866_UART_CLK,
			F81866_UART_CLK_MASK,
			F81866_UART_CLK_14_769MHZ);

		uart->port.uartclk = 921600 * 16;
		break;
	default: /* leave clock speed untouched */
		break;
	}
}

void fintek_8250_set_termios(struct uart_port *port, struct ktermios *termios,
			struct ktermios *old)
{
	struct fintek_8250 *pdata = port->private_data;
	unsigned int baud = tty_termios_baud_rate(termios);
	int i;
	u8 reg;
	static u32 baudrate_table[] = {115200, 921600, 1152000, 1500000};
	static u8 clock_table[] = { F81866_UART_CLK_1_8432MHZ,
			F81866_UART_CLK_14_769MHZ, F81866_UART_CLK_18_432MHZ,
			F81866_UART_CLK_24MHZ };

	/*
	 * We'll use serial8250_do_set_termios() for baud = 0, otherwise It'll
	 * crash on baudrate_table[i] % baud with "division by zero".
	 */
	if (!baud)
		goto exit;

	switch (pdata->pid) {
	case CHIP_ID_F81216H:
		reg = RS485;
		break;
	case CHIP_ID_F81866:
		reg = F81866_UART_CLK;
		break;
	default:
		/* Don't change clocksource with unknown PID */
		dev_warn(port->dev,
			"%s: pid: %x Not support. use default set_termios.\n",
			__func__, pdata->pid);
		goto exit;
	}

	for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
		if (baud > baudrate_table[i] || baudrate_table[i] % baud != 0)
			continue;

		if (port->uartclk == baudrate_table[i] * 16)
			break;

		if (fintek_8250_enter_key(pdata->base_port, pdata->key))
			continue;

		port->uartclk = baudrate_table[i] * 16;

		sio_write_reg(pdata, LDN, pdata->index);
		sio_write_mask_reg(pdata, reg, F81866_UART_CLK_MASK,
				clock_table[i]);

		fintek_8250_exit_key(pdata->base_port);
		break;
	}

	if (i == ARRAY_SIZE(baudrate_table)) {
		baud = tty_termios_baud_rate(old);
		tty_termios_encode_baud_rate(termios, baud, baud);
	}

exit:
	serial8250_do_set_termios(port, termios, old);
}

static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)
{
	struct fintek_8250 *pdata = uart->port.private_data;

	switch (pdata->pid) {
	case CHIP_ID_F81216H:
	case CHIP_ID_F81866:
		uart->port.set_termios = fintek_8250_set_termios;
		break;

	default:
		break;
	}
}

static int probe_setup_port(struct fintek_8250 *pdata,
					struct uart_8250_port *uart)
{
	static const u16 addr[] = {0x4e, 0x2e};
	static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};
	struct irq_data *irq_data;
	bool level_mode = false;
	int i, j, k, min, max;

	for (i = 0; i < ARRAY_SIZE(addr); i++) {
		for (j = 0; j < ARRAY_SIZE(keys); j++) {
			pdata->base_port = addr[i];
			pdata->key = keys[j];

			if (fintek_8250_enter_key(addr[i], keys[j]))
				continue;
			if (fintek_8250_check_id(pdata) ||
			    fintek_8250_get_ldn_range(pdata, &min, &max)) {
				fintek_8250_exit_key(addr[i]);
				continue;
			}

			for (k = min; k < max; k++) {
				u16 aux;

				sio_write_reg(pdata, LDN, k);
				aux = sio_read_reg(pdata, IO_ADDR1);
				aux |= sio_read_reg(pdata, IO_ADDR2) << 8;
				if (aux != uart->port.iobase)
					continue;

				pdata->index = k;

				irq_data = irq_get_irq_data(uart->port.irq);
				if (irq_data)
					level_mode =
						irqd_is_level_type(irq_data);

				fintek_8250_set_irq_mode(pdata, level_mode);
				fintek_8250_set_max_fifo(pdata);
				fintek_8250_goto_highspeed(uart, pdata);

				fintek_8250_exit_key(addr[i]);

				return 0;
			}

			fintek_8250_exit_key(addr[i]);
		}
	}

	return -ENODEV;
}

static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart)
{
	struct fintek_8250 *pdata = uart->port.private_data;

	switch (pdata->pid) {
	case CHIP_ID_F81216AD:
	case CHIP_ID_F81216H:
	case CHIP_ID_F81866:
	case CHIP_ID_F81865:
		uart->port.rs485_config = fintek_8250_rs485_config;
		break;

	default: /* No RS485 Auto direction functional */
		break;
	}
}

int fintek_8250_probe(struct uart_8250_port *uart)
{
	struct fintek_8250 *pdata;
	struct fintek_8250 probe_data;

	if (probe_setup_port(&probe_data, uart))
		return -ENODEV;

	pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	memcpy(pdata, &probe_data, sizeof(probe_data));
	uart->port.private_data = pdata;
	fintek_8250_set_rs485_handler(uart);
	fintek_8250_set_termios_handler(uart);

	return 0;
}
