2 * This file is part of the coreboot project.
4 * Copyright (C) 2004 Ronald G. Minnich
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
26 #define PM_DEVFN PCI_DEVFN(0x1f,3)
28 void smbus_enable(void)
32 pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1);
34 pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40, 1);
36 pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
38 /* Disable interrupt generation */
39 outb(0, SMBUS_IO_BASE + SMBHSTCTL);
43 void smbus_setup(void)
45 outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
48 static void smbus_wait_until_ready(void)
50 while ((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
55 static void smbus_wait_until_done(void)
59 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
61 while ((byte & 1) == 1);
62 while ((byte & ~1) == 0) {
63 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
67 int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
69 unsigned char host_status_register;
72 smbus_wait_until_ready();
74 /* setup transaction */
75 /* disable interrupts */
76 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
77 /* set the device I'm talking too */
78 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
79 /* set the command/address... */
80 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
81 /* set up for a byte data read */
82 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
83 SMBUS_IO_BASE + SMBHSTCTL);
85 /* clear any lingering errors, so the transaction will run */
86 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
88 /* clear the data byte... */
89 outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
91 /* start the command */
92 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
93 SMBUS_IO_BASE + SMBHSTCTL);
95 /* poll for transaction completion */
96 smbus_wait_until_done();
98 host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
100 /* read results of transaction */
101 byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
104 return host_status_register != 0x02;