Get rid of some unneeded function prototypes in romstage.c files.
[coreboot.git] / src / southbridge / intel / i82801ax / i82801ax_smbus.h
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
5  *
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; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <device/smbus_def.h>
22 #include "i82801ax.h"
23
24 int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address);
25
26 static void smbus_delay(void)
27 {
28         inb(0x80);
29 }
30
31 static int smbus_wait_until_ready(u16 smbus_io_base)
32 {
33         unsigned loops = SMBUS_TIMEOUT;
34         unsigned char byte;
35         do {
36                 smbus_delay();
37                 if (--loops == 0)
38                         break;
39                 byte = inb(smbus_io_base + SMBHSTSTAT);
40         } while (byte & 1);
41         return loops ? 0 : -1;
42 }
43
44 static int smbus_wait_until_done(u16 smbus_io_base)
45 {
46         unsigned loops = SMBUS_TIMEOUT;
47         unsigned char byte;
48         do {
49                 smbus_delay();
50                 if (--loops == 0)
51                         break;
52                 byte = inb(smbus_io_base + SMBHSTSTAT);
53         } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
54         return loops ? 0 : -1;
55 }
56
57 int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
58 {
59         unsigned char global_status_register;
60         unsigned char byte;
61
62         if (smbus_wait_until_ready(smbus_io_base) < 0) {
63                 return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
64         }
65         /* Setup transaction */
66         /* Disable interrupts */
67         outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
68         /* Set the device I'm talking too */
69         outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
70         /* Set the command/address... */
71         outb(address & 0xff, smbus_io_base + SMBHSTCMD);
72         /* Set up for a byte data read */
73         outb((inb(smbus_io_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
74              (smbus_io_base + SMBHSTCTL));
75         /* Clear any lingering errors, so the transaction will run */
76         outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
77
78         /* Clear the data byte... */
79         outb(0, smbus_io_base + SMBHSTDAT0);
80
81         /* Start the command */
82         outb((inb(smbus_io_base + SMBHSTCTL) | 0x40),
83              smbus_io_base + SMBHSTCTL);
84
85         /* Poll for transaction completion */
86         if (smbus_wait_until_done(smbus_io_base) < 0) {
87                 return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
88         }
89
90         global_status_register = inb(smbus_io_base + SMBHSTSTAT);
91
92         /* Ignore the "In Use" status... */
93         global_status_register &= ~(3 << 5);
94
95         /* Read results of transaction */
96         byte = inb(smbus_io_base + SMBHSTDAT0);
97         if (global_status_register != (1 << 1)) {
98                 return SMBUS_ERROR;
99         }
100         return byte;
101 }