2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <device/pnp.h>
20 #include "lpc47n207.h"
23 * This code tries to discover the SMSC LPC47N207 superio chip which can be
24 * connected over an LPC dongle. The chip could be bootstrap mapped to one of
25 * four LPC addresses: 0x2e, 0x4e, 0x162e, and 0x164e.
27 * Initializing the UART requires accesses to a few control registers. This
28 * structure includes the register offset and the value to write (along with
37 /* All regs/values to write to initialize the LPC47N207 UART */
38 static const uart_conf uart_conf_data
[] = {
39 {2, (1 << 3), (1 << 3)}, /* cr02, enable Primary UART power */
40 {0xc, (1 << 6), (1 << 6)}, /* cr0c, enable Primary UART high speed */
41 {0x24, (CONFIG_TTYS0_BASE
>> 3) << 1, 0xff}, /* cr24, base addr */
44 void try_enabling_LPC47N207_uart(void)
47 const uart_conf
* conf_item
;
48 u16 lpc_ports
[] = {0x2e, 0x4e, 0x162e, 0x164e};
52 #define CONFIG_ENABLE 0x55
53 #define CONFIG_DISABLE 0xaa
55 for (j
= 0; j
< ARRAY_SIZE(lpc_ports
); j
++) {
56 lpc_port
= lpc_ports
[j
];
58 /* enable CONFIG mode */
59 outb(CONFIG_ENABLE
, lpc_port
);
60 reg_value
=inb(lpc_port
);
61 if (reg_value
!= CONFIG_ENABLE
) {
62 continue; /* There is no LPC device at this address */
67 * Registers 12 and 13 hold config address, look for a
71 reg_value
=inb(lpc_port
+ 1);
72 if (reg_value
!= (lpc_port
& 0xff))
76 reg_value
=inb(lpc_port
+ 1);
77 if (reg_value
!= (lpc_port
>> 8))
80 /* This must be the SMSC LPC 47N207, enable the UART. */
81 for (i
= 0; i
< ARRAY_SIZE(uart_conf_data
); i
++) {
84 conf_item
= uart_conf_data
+ i
;
86 reg
= conf_item
->conf_reg
;
87 value
= conf_item
->value
;
88 mask
= conf_item
->mask
;
91 reg_value
= inb(lpc_port
+ 1);
93 reg_value
|= (value
& mask
);
94 outb(reg_value
, lpc_port
+ 1);
97 outb(CONFIG_DISABLE
, lpc_port
);