1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/pnp.h>
10 * This code tries to discover the SMSC LPC47N207 superio chip which can be
11 * connected over an LPC dongle. The chip could be bootstrap mapped to one of
12 * four LPC addresses: 0x2e, 0x4e, 0x162e, and 0x164e.
14 * Initializing the UART requires accesses to a few control registers. This
15 * structure includes the register offset and the value to write (along with
24 /* All regs/values to write to initialize the LPC47N207 UART */
25 static const uart_conf uart_conf_data
[] = {
26 {2, (1 << 3), (1 << 3)}, /* cr02, enable Primary UART power */
27 {0xc, (1 << 6), (1 << 6)}, /* cr0c, enable Primary UART high speed */
28 {0x24, (CONFIG_TTYS0_BASE
>> 3) << 1, 0xff}, /* cr24, base addr */
31 void try_enabling_LPC47N207_uart(void)
34 const uart_conf
* conf_item
;
35 u16 lpc_ports
[] = {0x2e, 0x4e, 0x162e, 0x164e};
39 #define CONF_ENABLE 0x55
40 #define CONF_DISABLE 0xaa
42 for (j
= 0; j
< ARRAY_SIZE(lpc_ports
); j
++) {
43 lpc_port
= lpc_ports
[j
];
45 /* enable CONFIG mode */
46 outb(CONF_ENABLE
, lpc_port
);
47 reg_value
= inb(lpc_port
);
48 if (reg_value
!= CONF_ENABLE
) {
49 continue; /* There is no LPC device at this address */
54 * Registers 12 and 13 hold config address, look for a
58 reg_value
= inb(lpc_port
+ 1);
59 if (reg_value
!= (lpc_port
& 0xff))
63 reg_value
= inb(lpc_port
+ 1);
64 if (reg_value
!= (lpc_port
>> 8))
67 /* This must be the SMSC LPC 47N207, enable the UART. */
68 for (i
= 0; i
< ARRAY_SIZE(uart_conf_data
); i
++) {
71 conf_item
= uart_conf_data
+ i
;
73 reg
= conf_item
->conf_reg
;
74 value
= conf_item
->value
;
75 mask
= conf_item
->mask
;
78 reg_value
= inb(lpc_port
+ 1);
80 reg_value
|= (value
& mask
);
81 outb(reg_value
, lpc_port
+ 1);
84 outb(CONF_DISABLE
, lpc_port
);