1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * NI 16550 UART Driver
4  *
5  * The National Instruments (NI) 16550 is a UART that is compatible with the
6  * TL16C550C and OX16C950B register interfaces, but has additional functions
7  * for RS-485 transceiver control. This driver implements support for the
8  * additional functionality on top of the standard serial8250 core.
9  *
10  * Copyright 2012-2023 National Instruments Corporation
11  */
12 
13 #include <linux/acpi.h>
14 #include <linux/bitfield.h>
15 #include <linux/device.h>
16 #include <linux/io.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/property.h>
20 #include <linux/clk.h>
21 
22 #include "8250.h"
23 
24 /* Extra bits in UART_ACR */
25 #define NI16550_ACR_AUTO_DTR_EN			BIT(4)
26 
27 /* TFS - TX FIFO Size */
28 #define NI16550_TFS_OFFSET	0x0C
29 /* RFS - RX FIFO Size */
30 #define NI16550_RFS_OFFSET	0x0D
31 
32 /* PMR - Port Mode Register */
33 #define NI16550_PMR_OFFSET	0x0E
34 /* PMR[1:0] - Port Capabilities */
35 #define NI16550_PMR_CAP_MASK		GENMASK(1, 0)
36 #define NI16550_PMR_NOT_IMPL		FIELD_PREP(NI16550_PMR_CAP_MASK, 0) /* not implemented */
37 #define NI16550_PMR_CAP_RS232		FIELD_PREP(NI16550_PMR_CAP_MASK, 1) /* RS-232 capable */
38 #define NI16550_PMR_CAP_RS485		FIELD_PREP(NI16550_PMR_CAP_MASK, 2) /* RS-485 capable */
39 #define NI16550_PMR_CAP_DUAL		FIELD_PREP(NI16550_PMR_CAP_MASK, 3) /* dual-port */
40 /* PMR[4] - Interface Mode */
41 #define NI16550_PMR_MODE_MASK		GENMASK(4, 4)
42 #define NI16550_PMR_MODE_RS232		FIELD_PREP(NI16550_PMR_MODE_MASK, 0) /* currently 232 */
43 #define NI16550_PMR_MODE_RS485		FIELD_PREP(NI16550_PMR_MODE_MASK, 1) /* currently 485 */
44 
45 /* PCR - Port Control Register */
46 /*
47  * Wire Mode      | Tx enabled?          | Rx enabled?
48  * ---------------|----------------------|--------------------------
49  * PCR_RS422      | Always               | Always
50  * PCR_ECHO_RS485 | When DTR asserted    | Always
51  * PCR_DTR_RS485  | When DTR asserted    | Disabled when TX enabled
52  * PCR_AUTO_RS485 | When data in TX FIFO | Disabled when TX enabled
53  */
54 #define NI16550_PCR_OFFSET	0x0F
55 #define NI16550_PCR_WIRE_MODE_MASK		GENMASK(1, 0)
56 #define NI16550_PCR_RS422			FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 0)
57 #define NI16550_PCR_ECHO_RS485			FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 1)
58 #define NI16550_PCR_DTR_RS485			FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 2)
59 #define NI16550_PCR_AUTO_RS485			FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 3)
60 #define NI16550_PCR_TXVR_ENABLE_BIT		BIT(3)
61 #define NI16550_PCR_RS485_TERMINATION_BIT	BIT(6)
62 
63 /* flags for ni16550_device_info */
64 #define NI_HAS_PMR		BIT(0)
65 
66 struct ni16550_device_info {
67 	u32 uartclk;
68 	u8 prescaler;
69 	u8 flags;
70 };
71 
72 struct ni16550_data {
73 	int line;
74 	struct clk *clk;
75 };
76 
ni16550_enable_transceivers(struct uart_port * port)77 static int ni16550_enable_transceivers(struct uart_port *port)
78 {
79 	u8 pcr;
80 
81 	pcr = port->serial_in(port, NI16550_PCR_OFFSET);
82 	pcr |= NI16550_PCR_TXVR_ENABLE_BIT;
83 	dev_dbg(port->dev, "enable transceivers: write pcr: 0x%02x\n", pcr);
84 	port->serial_out(port, NI16550_PCR_OFFSET, pcr);
85 
86 	return 0;
87 }
88 
ni16550_disable_transceivers(struct uart_port * port)89 static int ni16550_disable_transceivers(struct uart_port *port)
90 {
91 	u8 pcr;
92 
93 	pcr = port->serial_in(port, NI16550_PCR_OFFSET);
94 	pcr &= ~NI16550_PCR_TXVR_ENABLE_BIT;
95 	dev_dbg(port->dev, "disable transceivers: write pcr: 0x%02x\n", pcr);
96 	port->serial_out(port, NI16550_PCR_OFFSET, pcr);
97 
98 	return 0;
99 }
100 
ni16550_rs485_config(struct uart_port * port,struct ktermios * termios,struct serial_rs485 * rs485)101 static int ni16550_rs485_config(struct uart_port *port,
102 				struct ktermios *termios,
103 				struct serial_rs485 *rs485)
104 {
105 	struct uart_8250_port *up = container_of(port, struct uart_8250_port, port);
106 	u8 pcr;
107 
108 	pcr = serial_in(up, NI16550_PCR_OFFSET);
109 	pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
110 
111 	if ((rs485->flags & SER_RS485_MODE_RS422) ||
112 	    !(rs485->flags & SER_RS485_ENABLED)) {
113 		/* RS-422 */
114 		pcr |= NI16550_PCR_RS422;
115 		up->acr &= ~NI16550_ACR_AUTO_DTR_EN;
116 	} else {
117 		/* RS-485 2-wire Auto */
118 		pcr |= NI16550_PCR_AUTO_RS485;
119 		up->acr |= NI16550_ACR_AUTO_DTR_EN;
120 	}
121 
122 	dev_dbg(port->dev, "config rs485: write pcr: 0x%02x, acr: %02x\n", pcr, up->acr);
123 	serial_out(up, NI16550_PCR_OFFSET, pcr);
124 	serial_icr_write(up, UART_ACR, up->acr);
125 
126 	return 0;
127 }
128 
is_pmr_rs232_mode(struct uart_8250_port * up)129 static bool is_pmr_rs232_mode(struct uart_8250_port *up)
130 {
131 	u8 pmr = serial_in(up, NI16550_PMR_OFFSET);
132 	u8 pmr_mode = pmr & NI16550_PMR_MODE_MASK;
133 	u8 pmr_cap = pmr & NI16550_PMR_CAP_MASK;
134 
135 	/*
136 	 * If the PMR is not implemented, then by default NI UARTs are
137 	 * connected to RS-485 transceivers
138 	 */
139 	if (pmr_cap == NI16550_PMR_NOT_IMPL)
140 		return false;
141 
142 	if (pmr_cap == NI16550_PMR_CAP_DUAL)
143 		/*
144 		 * If the port is dual-mode capable, then read the mode bit
145 		 * to know the current mode
146 		 */
147 		return pmr_mode == NI16550_PMR_MODE_RS232;
148 	/*
149 	 * If it is not dual-mode capable, then decide based on the
150 	 * capability
151 	 */
152 	return pmr_cap == NI16550_PMR_CAP_RS232;
153 }
154 
ni16550_config_prescaler(struct uart_8250_port * up,u8 prescaler)155 static void ni16550_config_prescaler(struct uart_8250_port *up,
156 				     u8 prescaler)
157 {
158 	/*
159 	 * Page in the Enhanced Mode Registers
160 	 * Sets EFR[4] for Enhanced Mode.
161 	 */
162 	u8 lcr_value;
163 	u8 efr_value;
164 
165 	lcr_value = serial_in(up, UART_LCR);
166 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
167 
168 	efr_value = serial_in(up, UART_EFR);
169 	efr_value |= UART_EFR_ECB;
170 
171 	serial_out(up, UART_EFR, efr_value);
172 
173 	/* Page out the Enhanced Mode Registers */
174 	serial_out(up, UART_LCR, lcr_value);
175 
176 	/* Set prescaler to CPR register. */
177 	serial_out(up, UART_SCR, UART_CPR);
178 	serial_out(up, UART_ICR, prescaler);
179 }
180 
181 static const struct serial_rs485 ni16550_rs485_supported = {
182 	.flags = SER_RS485_ENABLED | SER_RS485_MODE_RS422 | SER_RS485_RTS_ON_SEND |
183 		 SER_RS485_RTS_AFTER_SEND,
184 	/*
185 	 * delay_rts_* and RX_DURING_TX are not supported.
186 	 *
187 	 * RTS_{ON,AFTER}_SEND are supported, but ignored; the transceiver
188 	 * is connected in only one way and we don't need userspace to tell
189 	 * us, but want to retain compatibility with applications that do.
190 	 */
191 };
192 
ni16550_rs485_setup(struct uart_port * port)193 static void ni16550_rs485_setup(struct uart_port *port)
194 {
195 	port->rs485_config = ni16550_rs485_config;
196 	port->rs485_supported = ni16550_rs485_supported;
197 	/*
198 	 * The hardware comes up by default in 2-wire auto mode and we
199 	 * set the flags to represent that
200 	 */
201 	port->rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
202 }
203 
ni16550_port_startup(struct uart_port * port)204 static int ni16550_port_startup(struct uart_port *port)
205 {
206 	int ret;
207 
208 	ret = serial8250_do_startup(port);
209 	if (ret)
210 		return ret;
211 
212 	return ni16550_enable_transceivers(port);
213 }
214 
ni16550_port_shutdown(struct uart_port * port)215 static void ni16550_port_shutdown(struct uart_port *port)
216 {
217 	ni16550_disable_transceivers(port);
218 
219 	serial8250_do_shutdown(port);
220 }
221 
ni16550_get_regs(struct platform_device * pdev,struct uart_port * port)222 static int ni16550_get_regs(struct platform_device *pdev,
223 			    struct uart_port *port)
224 {
225 	struct resource *regs;
226 
227 	regs = platform_get_resource(pdev, IORESOURCE_IO, 0);
228 	if (regs) {
229 		port->iotype = UPIO_PORT;
230 		port->iobase = regs->start;
231 
232 		return 0;
233 	}
234 
235 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
236 	if (regs) {
237 		port->iotype = UPIO_MEM;
238 		port->mapbase = regs->start;
239 		port->mapsize = resource_size(regs);
240 		port->flags |= UPF_IOREMAP;
241 
242 		port->membase = devm_ioremap(&pdev->dev, port->mapbase,
243 					     port->mapsize);
244 		if (!port->membase)
245 			return -ENOMEM;
246 
247 		return 0;
248 	}
249 
250 	dev_err(&pdev->dev, "no registers defined\n");
251 	return -EINVAL;
252 }
253 
254 /*
255  * Very old implementations don't have the TFS or RFS registers
256  * defined, so we may read all-0s or all-1s. For such devices,
257  * assume a FIFO size of 128.
258  */
ni16550_read_fifo_size(struct uart_8250_port * uart,int reg)259 static u8 ni16550_read_fifo_size(struct uart_8250_port *uart, int reg)
260 {
261 	u8 value = serial_in(uart, reg);
262 
263 	if (value == 0x00 || value == 0xFF)
264 		return 128;
265 
266 	return value;
267 }
268 
ni16550_set_mctrl(struct uart_port * port,unsigned int mctrl)269 static void ni16550_set_mctrl(struct uart_port *port, unsigned int mctrl)
270 {
271 	struct uart_8250_port *up = up_to_u8250p(port);
272 
273 	up->mcr |= UART_MCR_CLKSEL;
274 	serial8250_do_set_mctrl(port, mctrl);
275 }
276 
ni16550_probe(struct platform_device * pdev)277 static int ni16550_probe(struct platform_device *pdev)
278 {
279 	const struct ni16550_device_info *info;
280 	struct device *dev = &pdev->dev;
281 	struct uart_8250_port uart = {};
282 	unsigned int txfifosz, rxfifosz;
283 	unsigned int prescaler = 0;
284 	struct ni16550_data *data;
285 	const char *portmode;
286 	bool rs232_property;
287 	int ret;
288 	int irq;
289 
290 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
291 	if (!data)
292 		return -ENOMEM;
293 
294 	spin_lock_init(&uart.port.lock);
295 
296 	irq = platform_get_irq(pdev, 0);
297 	if (irq < 0)
298 		return irq;
299 
300 	ret = ni16550_get_regs(pdev, &uart.port);
301 	if (ret < 0)
302 		return ret;
303 
304 	/* early setup so that serial_in()/serial_out() work */
305 	serial8250_set_defaults(&uart);
306 
307 	info = device_get_match_data(dev);
308 
309 	uart.port.dev		= dev;
310 	uart.port.irq		= irq;
311 	uart.port.irqflags	= IRQF_SHARED;
312 	uart.port.flags		= UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
313 					| UPF_FIXED_PORT | UPF_FIXED_TYPE;
314 	uart.port.startup	= ni16550_port_startup;
315 	uart.port.shutdown	= ni16550_port_shutdown;
316 
317 	/*
318 	 * Hardware instantiation of FIFO sizes are held in registers.
319 	 */
320 	txfifosz = ni16550_read_fifo_size(&uart, NI16550_TFS_OFFSET);
321 	rxfifosz = ni16550_read_fifo_size(&uart, NI16550_RFS_OFFSET);
322 
323 	dev_dbg(dev, "NI 16550 has TX FIFO size %u, RX FIFO size %u\n",
324 		txfifosz, rxfifosz);
325 
326 	uart.port.type		= PORT_16550A;
327 	uart.port.fifosize	= txfifosz;
328 	uart.tx_loadsz		= txfifosz;
329 	uart.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
330 	uart.capabilities	= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR;
331 
332 	/*
333 	 * Declaration of the base clock frequency can come from one of:
334 	 * - static declaration in this driver (for older ACPI IDs)
335 	 * - a "clock-frquency" ACPI
336 	 */
337 	if (info->uartclk)
338 		uart.port.uartclk = info->uartclk;
339 	if (device_property_read_u32(dev, "clock-frequency",
340 				     &uart.port.uartclk)) {
341 		data->clk = devm_clk_get_enabled(dev, NULL);
342 		if (!IS_ERR(data->clk))
343 			uart.port.uartclk = clk_get_rate(data->clk);
344 	}
345 
346 	if (!uart.port.uartclk) {
347 		dev_err(dev, "unable to determine clock frequency!\n");
348 		ret = -ENODEV;
349 		goto err;
350 	}
351 
352 	if (info->prescaler)
353 		prescaler = info->prescaler;
354 	device_property_read_u32(dev, "clock-prescaler", &prescaler);
355 
356 	if (prescaler != 0) {
357 		uart.port.set_mctrl = ni16550_set_mctrl;
358 		ni16550_config_prescaler(&uart, (u8)prescaler);
359 	}
360 
361 	/*
362 	 * The determination of whether or not this is an RS-485 or RS-232 port
363 	 * can come from the PMR (if present), otherwise we're solely an RS-485
364 	 * port.
365 	 *
366 	 * This is a device-specific property, and there are old devices in the
367 	 * field using "transceiver" as an ACPI property, so we have to check
368 	 * for that as well.
369 	 */
370 	if (!device_property_read_string(dev, "transceiver", &portmode)) {
371 		rs232_property = strncmp(portmode, "RS-232", 6) == 0;
372 
373 		dev_dbg(dev, "port is in %s mode (via device property)\n",
374 			rs232_property ? "RS-232" : "RS-485");
375 	} else if (info->flags & NI_HAS_PMR) {
376 		rs232_property = is_pmr_rs232_mode(&uart);
377 
378 		dev_dbg(dev, "port is in %s mode (via PMR)\n",
379 			rs232_property ? "RS-232" : "RS-485");
380 	} else {
381 		rs232_property = 0;
382 
383 		dev_dbg(dev, "port is fixed as RS-485\n");
384 	}
385 
386 	if (!rs232_property) {
387 		/*
388 		 * Neither the 'transceiver' property nor the PMR indicate
389 		 * that this is an RS-232 port, so it must be an RS-485 one.
390 		 */
391 		ni16550_rs485_setup(&uart.port);
392 	}
393 
394 	ret = serial8250_register_8250_port(&uart);
395 	if (ret < 0)
396 		goto err;
397 	data->line = ret;
398 
399 	platform_set_drvdata(pdev, data);
400 	return 0;
401 
402 err:
403 	return ret;
404 }
405 
ni16550_remove(struct platform_device * pdev)406 static void ni16550_remove(struct platform_device *pdev)
407 {
408 	struct ni16550_data *data = platform_get_drvdata(pdev);
409 
410 	serial8250_unregister_port(data->line);
411 }
412 
413 #ifdef CONFIG_ACPI
414 /* NI 16550 RS-485 Interface */
415 static const struct ni16550_device_info nic7750 = {
416 	.uartclk = 33333333,
417 };
418 
419 /* NI CVS-145x RS-485 Interface */
420 static const struct ni16550_device_info nic7772 = {
421 	.uartclk = 1843200,
422 	.flags = NI_HAS_PMR,
423 };
424 
425 /* NI cRIO-904x RS-485 Interface */
426 static const struct ni16550_device_info nic792b = {
427 	/* Sets UART clock rate to 22.222 MHz with 1.125 prescale */
428 	.uartclk = 22222222,
429 	.prescaler = 0x09,
430 };
431 
432 /* NI sbRIO 96x8 RS-232/485 Interfaces */
433 static const struct ni16550_device_info nic7a69 = {
434 	/* Set UART clock rate to 29.629 MHz with 1.125 prescale */
435 	.uartclk = 29629629,
436 	.prescaler = 0x09,
437 };
438 static const struct acpi_device_id ni16550_acpi_match[] = {
439 	{ "NIC7750",	(kernel_ulong_t)&nic7750 },
440 	{ "NIC7772",	(kernel_ulong_t)&nic7772 },
441 	{ "NIC792B",	(kernel_ulong_t)&nic792b },
442 	{ "NIC7A69",	(kernel_ulong_t)&nic7a69 },
443 	{ },
444 };
445 MODULE_DEVICE_TABLE(acpi, ni16550_acpi_match);
446 #endif
447 
448 static struct platform_driver ni16550_driver = {
449 	.driver = {
450 		.name = "ni16550",
451 		.acpi_match_table = ACPI_PTR(ni16550_acpi_match),
452 	},
453 	.probe = ni16550_probe,
454 	.remove = ni16550_remove,
455 };
456 
457 module_platform_driver(ni16550_driver);
458 
459 MODULE_AUTHOR("Emerson Electric Co.");
460 MODULE_DESCRIPTION("NI 16550 Driver");
461 MODULE_LICENSE("GPL");
462