brintos

brintos / linux-shallow public Read only

0
0
Text · 10.6 KiB · e2aa2a1 Raw
465 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  Probe for F81216A LPC to 4 UART4 *5 *  Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S6 */7#include <linux/module.h>8#include <linux/pci.h>9#include <linux/pnp.h>10#include <linux/kernel.h>11#include <linux/serial_core.h>12#include <linux/irq.h>13#include  "8250.h"14 15#define ADDR_PORT 016#define DATA_PORT 117#define EXIT_KEY 0xAA18#define CHIP_ID1  0x2019#define CHIP_ID2  0x2120#define CHIP_ID_F81865 0x040721#define CHIP_ID_F81866 0x101022#define CHIP_ID_F81966 0x021523#define CHIP_ID_F81216AD 0x160224#define CHIP_ID_F81216H 0x050125#define CHIP_ID_F81216 0x080226#define VENDOR_ID1 0x2327#define VENDOR_ID1_VAL 0x1928#define VENDOR_ID2 0x2429#define VENDOR_ID2_VAL 0x3430#define IO_ADDR1 0x6131#define IO_ADDR2 0x6032#define LDN 0x733 34#define FINTEK_IRQ_MODE	0x7035#define IRQ_SHARE	BIT(4)36#define IRQ_MODE_MASK	(BIT(6) | BIT(5))37#define IRQ_LEVEL_LOW	038#define IRQ_EDGE_HIGH	BIT(5)39 40/*41 * F81216H clock source register, the value and mask is the same with F81866,42 * but it's on F0h.43 *44 * Clock speeds for UART (register F0h)45 * 00: 1.8432MHz.46 * 01: 18.432MHz.47 * 10: 24MHz.48 * 11: 14.769MHz.49 */50#define RS485  0xF051#define RTS_INVERT BIT(5)52#define RS485_URA BIT(4)53#define RXW4C_IRA BIT(3)54#define TXW4C_IRA BIT(2)55 56#define FIFO_CTRL		0xF657#define FIFO_MODE_MASK		(BIT(1) | BIT(0))58#define FIFO_MODE_128		(BIT(1) | BIT(0))59#define RXFTHR_MODE_MASK	(BIT(5) | BIT(4))60#define RXFTHR_MODE_4X		BIT(5)61 62#define F81216_LDN_LOW	0x063#define F81216_LDN_HIGH	0x464 65/*66 * F81866/966 registers67 *68 * The IRQ setting mode of F81866/966 is not the same with F81216 series.69 *	Level/Low: IRQ_MODE0:0, IRQ_MODE1:070 *	Edge/High: IRQ_MODE0:1, IRQ_MODE1:071 *72 * Clock speeds for UART (register F2h)73 * 00: 1.8432MHz.74 * 01: 18.432MHz.75 * 10: 24MHz.76 * 11: 14.769MHz.77 */78#define F81866_IRQ_MODE		0xf079#define F81866_IRQ_SHARE	BIT(0)80#define F81866_IRQ_MODE0	BIT(1)81 82#define F81866_FIFO_CTRL	FIFO_CTRL83#define F81866_IRQ_MODE1	BIT(3)84 85#define F81866_LDN_LOW		0x1086#define F81866_LDN_HIGH		0x1687 88#define F81866_UART_CLK 0xF289#define F81866_UART_CLK_MASK (BIT(1) | BIT(0))90#define F81866_UART_CLK_1_8432MHZ 091#define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0))92#define F81866_UART_CLK_18_432MHZ BIT(0)93#define F81866_UART_CLK_24MHZ BIT(1)94 95struct fintek_8250 {96	u16 pid;97	u16 base_port;98	u8 index;99	u8 key;100};101 102static u8 sio_read_reg(struct fintek_8250 *pdata, u8 reg)103{104	outb(reg, pdata->base_port + ADDR_PORT);105	return inb(pdata->base_port + DATA_PORT);106}107 108static void sio_write_reg(struct fintek_8250 *pdata, u8 reg, u8 data)109{110	outb(reg, pdata->base_port + ADDR_PORT);111	outb(data, pdata->base_port + DATA_PORT);112}113 114static void sio_write_mask_reg(struct fintek_8250 *pdata, u8 reg, u8 mask,115			       u8 data)116{117	u8 tmp;118 119	tmp = (sio_read_reg(pdata, reg) & ~mask) | (mask & data);120	sio_write_reg(pdata, reg, tmp);121}122 123static int fintek_8250_enter_key(u16 base_port, u8 key)124{125	if (!request_muxed_region(base_port, 2, "8250_fintek"))126		return -EBUSY;127 128	/* Force to deactive all SuperIO in this base_port */129	outb(EXIT_KEY, base_port + ADDR_PORT);130 131	outb(key, base_port + ADDR_PORT);132	outb(key, base_port + ADDR_PORT);133	return 0;134}135 136static void fintek_8250_exit_key(u16 base_port)137{138 139	outb(EXIT_KEY, base_port + ADDR_PORT);140	release_region(base_port + ADDR_PORT, 2);141}142 143static int fintek_8250_check_id(struct fintek_8250 *pdata)144{145	u16 chip;146 147	if (sio_read_reg(pdata, VENDOR_ID1) != VENDOR_ID1_VAL)148		return -ENODEV;149 150	if (sio_read_reg(pdata, VENDOR_ID2) != VENDOR_ID2_VAL)151		return -ENODEV;152 153	chip = sio_read_reg(pdata, CHIP_ID1);154	chip |= sio_read_reg(pdata, CHIP_ID2) << 8;155 156	switch (chip) {157	case CHIP_ID_F81865:158	case CHIP_ID_F81866:159	case CHIP_ID_F81966:160	case CHIP_ID_F81216AD:161	case CHIP_ID_F81216H:162	case CHIP_ID_F81216:163		break;164	default:165		return -ENODEV;166	}167 168	pdata->pid = chip;169	return 0;170}171 172static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,173				     int *max)174{175	switch (pdata->pid) {176	case CHIP_ID_F81966:177	case CHIP_ID_F81865:178	case CHIP_ID_F81866:179		*min = F81866_LDN_LOW;180		*max = F81866_LDN_HIGH;181		return 0;182 183	case CHIP_ID_F81216AD:184	case CHIP_ID_F81216H:185	case CHIP_ID_F81216:186		*min = F81216_LDN_LOW;187		*max = F81216_LDN_HIGH;188		return 0;189	}190 191	return -ENODEV;192}193 194static int fintek_8250_rs485_config(struct uart_port *port, struct ktermios *termios,195			      struct serial_rs485 *rs485)196{197	uint8_t config = 0;198	struct fintek_8250 *pdata = port->private_data;199 200	if (!pdata)201		return -EINVAL;202 203 204	if (rs485->flags & SER_RS485_ENABLED) {205		/* Hardware do not support same RTS level on send and receive */206		if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==207		    !(rs485->flags & SER_RS485_RTS_AFTER_SEND))208			return -EINVAL;209		config |= RS485_URA;210	}211 212	if (rs485->delay_rts_before_send) {213		rs485->delay_rts_before_send = 1;214		config |= TXW4C_IRA;215	}216 217	if (rs485->delay_rts_after_send) {218		rs485->delay_rts_after_send = 1;219		config |= RXW4C_IRA;220	}221 222	if (rs485->flags & SER_RS485_RTS_ON_SEND)223		config |= RTS_INVERT;224 225	if (fintek_8250_enter_key(pdata->base_port, pdata->key))226		return -EBUSY;227 228	sio_write_reg(pdata, LDN, pdata->index);229	sio_write_reg(pdata, RS485, config);230	fintek_8250_exit_key(pdata->base_port);231 232	return 0;233}234 235static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)236{237	sio_write_reg(pdata, LDN, pdata->index);238 239	switch (pdata->pid) {240	case CHIP_ID_F81966:241	case CHIP_ID_F81866:242		sio_write_mask_reg(pdata, F81866_FIFO_CTRL, F81866_IRQ_MODE1,243				   0);244		fallthrough;245	case CHIP_ID_F81865:246		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_SHARE,247				   F81866_IRQ_SHARE);248		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_MODE0,249				   is_level ? 0 : F81866_IRQ_MODE0);250		break;251 252	case CHIP_ID_F81216AD:253	case CHIP_ID_F81216H:254	case CHIP_ID_F81216:255		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE,256				   IRQ_SHARE);257		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_MODE_MASK,258				   is_level ? IRQ_LEVEL_LOW : IRQ_EDGE_HIGH);259		break;260	}261}262 263static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)264{265	switch (pdata->pid) {266	case CHIP_ID_F81216H: /* 128Bytes FIFO */267	case CHIP_ID_F81966:268	case CHIP_ID_F81866:269		sio_write_mask_reg(pdata, FIFO_CTRL,270				   FIFO_MODE_MASK | RXFTHR_MODE_MASK,271				   FIFO_MODE_128 | RXFTHR_MODE_4X);272		break;273 274	default: /* Default 16Bytes FIFO */275		break;276	}277}278 279static void fintek_8250_set_termios(struct uart_port *port,280				    struct ktermios *termios,281				    const struct ktermios *old)282{283	struct fintek_8250 *pdata = port->private_data;284	unsigned int baud = tty_termios_baud_rate(termios);285	int i;286	u8 reg;287	static u32 baudrate_table[] = {115200, 921600, 1152000, 1500000};288	static u8 clock_table[] = { F81866_UART_CLK_1_8432MHZ,289			F81866_UART_CLK_14_769MHZ, F81866_UART_CLK_18_432MHZ,290			F81866_UART_CLK_24MHZ };291 292	/*293	 * We'll use serial8250_do_set_termios() for baud = 0, otherwise It'll294	 * crash on baudrate_table[i] % baud with "division by zero".295	 */296	if (!baud)297		goto exit;298 299	switch (pdata->pid) {300	case CHIP_ID_F81216H:301		reg = RS485;302		break;303	case CHIP_ID_F81966:304	case CHIP_ID_F81866:305		reg = F81866_UART_CLK;306		break;307	default:308		/* Don't change clocksource with unknown PID */309		dev_warn(port->dev,310			"%s: pid: %x Not support. use default set_termios.\n",311			__func__, pdata->pid);312		goto exit;313	}314 315	for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {316		if (baud > baudrate_table[i] || baudrate_table[i] % baud != 0)317			continue;318 319		if (port->uartclk == baudrate_table[i] * 16)320			break;321 322		if (fintek_8250_enter_key(pdata->base_port, pdata->key))323			continue;324 325		port->uartclk = baudrate_table[i] * 16;326 327		sio_write_reg(pdata, LDN, pdata->index);328		sio_write_mask_reg(pdata, reg, F81866_UART_CLK_MASK,329				clock_table[i]);330 331		fintek_8250_exit_key(pdata->base_port);332		break;333	}334 335	if (i == ARRAY_SIZE(baudrate_table)) {336		baud = tty_termios_baud_rate(old);337		tty_termios_encode_baud_rate(termios, baud, baud);338	}339 340exit:341	serial8250_do_set_termios(port, termios, old);342}343 344static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)345{346	struct fintek_8250 *pdata = uart->port.private_data;347 348	switch (pdata->pid) {349	case CHIP_ID_F81216H:350	case CHIP_ID_F81966:351	case CHIP_ID_F81866:352		uart->port.set_termios = fintek_8250_set_termios;353		break;354 355	default:356		break;357	}358}359 360static int probe_setup_port(struct fintek_8250 *pdata,361					struct uart_8250_port *uart)362{363	static const u16 addr[] = {0x4e, 0x2e};364	static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};365	struct irq_data *irq_data;366	bool level_mode = false;367	int i, j, k, min, max;368 369	for (i = 0; i < ARRAY_SIZE(addr); i++) {370		for (j = 0; j < ARRAY_SIZE(keys); j++) {371			pdata->base_port = addr[i];372			pdata->key = keys[j];373 374			if (fintek_8250_enter_key(addr[i], keys[j]))375				continue;376			if (fintek_8250_check_id(pdata) ||377			    fintek_8250_get_ldn_range(pdata, &min, &max)) {378				fintek_8250_exit_key(addr[i]);379				continue;380			}381 382			for (k = min; k < max; k++) {383				u16 aux;384 385				sio_write_reg(pdata, LDN, k);386				aux = sio_read_reg(pdata, IO_ADDR1);387				aux |= sio_read_reg(pdata, IO_ADDR2) << 8;388				if (aux != uart->port.iobase)389					continue;390 391				pdata->index = k;392 393				irq_data = irq_get_irq_data(uart->port.irq);394				if (irq_data)395					level_mode =396						irqd_is_level_type(irq_data);397 398				fintek_8250_set_irq_mode(pdata, level_mode);399				fintek_8250_set_max_fifo(pdata);400 401				fintek_8250_exit_key(addr[i]);402 403				return 0;404			}405 406			fintek_8250_exit_key(addr[i]);407		}408	}409 410	return -ENODEV;411}412 413/* Only the first port supports delays */414static const struct serial_rs485 fintek_8250_rs485_supported_port0 = {415	.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,416	.delay_rts_before_send = 1,417	.delay_rts_after_send = 1,418};419 420static const struct serial_rs485 fintek_8250_rs485_supported = {421	.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,422};423 424static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart)425{426	struct fintek_8250 *pdata = uart->port.private_data;427 428	switch (pdata->pid) {429	case CHIP_ID_F81216AD:430	case CHIP_ID_F81216H:431	case CHIP_ID_F81966:432	case CHIP_ID_F81866:433	case CHIP_ID_F81865:434		uart->port.rs485_config = fintek_8250_rs485_config;435		if (!pdata->index)436			uart->port.rs485_supported = fintek_8250_rs485_supported_port0;437		else438			uart->port.rs485_supported = fintek_8250_rs485_supported;439		break;440 441	default: /* No RS485 Auto direction functional */442		break;443	}444}445 446int fintek_8250_probe(struct uart_8250_port *uart)447{448	struct fintek_8250 *pdata;449	struct fintek_8250 probe_data;450 451	if (probe_setup_port(&probe_data, uart))452		return -ENODEV;453 454	pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);455	if (!pdata)456		return -ENOMEM;457 458	memcpy(pdata, &probe_data, sizeof(probe_data));459	uart->port.private_data = pdata;460	fintek_8250_set_rs485_handler(uart);461	fintek_8250_set_termios_handler(uart);462 463	return 0;464}465