2 * This file is part of the coreboot project.
4 * Copyright (C) 2008 Arastra, Inc.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 /* This code is based on src/southbridge/intel/esb6300/esb6300_smbus.h */
22 #include <device/smbus_def.h>
24 #define SMBHSTSTAT 0x0
27 #define SMBXMITADD 0x4
28 #define SMBHSTDAT0 0x5
29 #define SMBHSTDAT1 0x6
31 #define SMBTRNSADD 0x9
32 #define SMBSLVDATA 0xa
33 #define SMLINK_PIN_CTL 0xe
34 #define SMBUS_PIN_CTL 0xf
35 #define SMBSLVCMD 0x11
37 #define SMBUS_TIMEOUT (100*1000*10)
39 static void smbus_delay(void)
44 static int smbus_wait_until_ready(u32 smbus_io_base)
46 u32 loops = SMBUS_TIMEOUT;
52 byte = inb(smbus_io_base + SMBHSTSTAT);
54 return loops ? 0 : -1;
57 static int smbus_wait_until_done(u32 smbus_io_base)
59 u32 loops = SMBUS_TIMEOUT;
65 byte = inb(smbus_io_base + SMBHSTSTAT);
66 } while ((byte & 1) || (byte & ~((1 << 6)|(1 << 0))) == 0);
67 return loops ? 0 : -1;
70 static int do_smbus_read_byte(u32 smbus_io_base, u16 device, u8 address)
72 u8 global_status_register;
75 if (smbus_wait_until_ready(smbus_io_base) < 0) {
76 return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
78 /* setup transaction */
79 /* disable interrupts */
80 outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
81 /* set the device I'm talking too */
82 outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
83 /* set the command/address... */
84 outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
85 /* set up for a byte data read */
86 outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
87 /* clear any lingering errors, so the transaction will run */
88 outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
90 /* clear the data byte...*/
91 outb(0, smbus_io_base + SMBHSTDAT0);
93 /* start the command */
94 outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
96 /* poll for transaction completion */
97 if (smbus_wait_until_done(smbus_io_base) < 0) {
98 return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
101 global_status_register = inb(smbus_io_base + SMBHSTSTAT);
103 /* Ignore the In Use Status... */
104 global_status_register &= ~(3 << 5);
106 /* read results of transaction */
107 byte = inb(smbus_io_base + SMBHSTDAT0);
108 if (global_status_register != (1 << 1)) {