tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / southbridge / nvidia / ck804 / smbus.h
blob6d0c510f893736261b99f812bd8b5c80136385c8
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2004 Tyan Computer
5 * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
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.
17 #include <device/smbus_def.h>
19 #define SMBHSTSTAT 0x1
20 #define SMBHSTPRTCL 0x0
21 #define SMBHSTCMD 0x3
22 #define SMBXMITADD 0x2
23 #define SMBHSTDAT0 0x4
24 #define SMBHSTDAT1 0x5
27 * Between 1-10 seconds, We should never timeout normally.
28 * Longer than this is just painful when a timeout condition occurs.
30 #define SMBUS_TIMEOUT (100 * 1000 * 10)
32 static inline void smbus_delay(void)
34 outb(0x80, 0x80);
37 #if 0
38 /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
39 static int smbus_wait_until_ready(unsigned smbus_io_base)
41 unsigned long loops;
42 loops = SMBUS_TIMEOUT;
43 do {
44 unsigned char val;
45 smbus_delay();
46 val = inb(smbus_io_base + SMBHSTSTAT);
47 val &= 0x1f;
48 if (val == 0)
49 return 0;
50 outb(val, smbus_io_base + SMBHSTSTAT);
51 } while (--loops);
52 return -2;
54 #endif
56 static int smbus_wait_until_done(unsigned smbus_io_base)
58 unsigned long loops;
59 loops = SMBUS_TIMEOUT;
60 do {
61 unsigned char val;
62 smbus_delay();
63 val = inb(smbus_io_base + SMBHSTSTAT);
64 if ((val & 0xff) != 0)
65 return 0;
66 } while (--loops);
67 return -3;
70 #ifndef __PRE_RAM__
71 static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
73 unsigned char global_status_register, byte;
75 #if 0
76 /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
77 if (smbus_wait_until_ready(smbus_io_base) < 0)
78 return -2;
79 #endif
81 /* Set the device I'm talking to. */
82 outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
83 smbus_delay();
85 /* Set the command/address. */
86 outb(0, smbus_io_base + SMBHSTCMD);
87 smbus_delay();
89 /* Byte data recv. */
90 outb(0x05, smbus_io_base + SMBHSTPRTCL);
91 smbus_delay();
93 /* Poll for transaction completion. */
94 if (smbus_wait_until_done(smbus_io_base) < 0)
95 return -3;
97 /* Lose check. */
98 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
100 /* Read results of transaction. */
101 byte = inb(smbus_io_base + SMBHSTDAT0);
103 /* Lose check, otherwise it should be 0. */
104 if (global_status_register != 0x80)
105 return -1;
107 return byte;
110 static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device,
111 unsigned char val)
113 unsigned global_status_register;
115 #if 0
116 /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
117 if (smbus_wait_until_ready(smbus_io_base) < 0)
118 return -2;
119 #endif
121 outb(val, smbus_io_base + SMBHSTDAT0);
122 smbus_delay();
124 /* Set the device I'm talking to. */
125 outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
126 smbus_delay();
128 outb(0, smbus_io_base + SMBHSTCMD);
129 smbus_delay();
131 /* Set up for a byte data write. */
132 outb(0x04, smbus_io_base + SMBHSTPRTCL);
133 smbus_delay();
135 /* Poll for transaction completion. */
136 if (smbus_wait_until_done(smbus_io_base) < 0)
137 return -3;
139 /* Lose check. */
140 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
142 if (global_status_register != 0x80)
143 return -1;
145 return 0;
147 #endif
149 static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device,
150 unsigned address)
152 unsigned char global_status_register, byte;
154 #if 0
155 /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
156 if (smbus_wait_until_ready(smbus_io_base) < 0)
157 return -2;
158 #endif
160 /* Set the device I'm talking to. */
161 outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
162 smbus_delay();
164 /* Set the command/address. */
165 outb(address & 0xff, smbus_io_base + SMBHSTCMD);
166 smbus_delay();
168 /* Byte data read. */
169 outb(0x07, smbus_io_base + SMBHSTPRTCL);
170 smbus_delay();
172 /* Poll for transaction completion. */
173 if (smbus_wait_until_done(smbus_io_base) < 0)
174 return -3;
176 /* Lose check. */
177 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
179 /* Read results of transaction. */
180 byte = inb(smbus_io_base + SMBHSTDAT0);
182 /* Lose check, otherwise it should be 0. */
183 if (global_status_register != 0x80)
184 return -1;
186 return byte;
189 static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device,
190 unsigned address, unsigned char val)
192 unsigned global_status_register;
194 #if 0
195 /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
196 if (smbus_wait_until_ready(smbus_io_base) < 0)
197 return -2;
198 #endif
200 outb(val, smbus_io_base + SMBHSTDAT0);
201 smbus_delay();
203 /* Set the device I'm talking to. */
204 outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
205 smbus_delay();
207 outb(address & 0xff, smbus_io_base + SMBHSTCMD);
208 smbus_delay();
210 /* Set up for a byte data write. */
211 outb(0x06, smbus_io_base + SMBHSTPRTCL);
212 smbus_delay();
214 /* Poll for transaction completion. */
215 if (smbus_wait_until_done(smbus_io_base) < 0)
216 return -3;
218 /* Lose check. */
219 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
221 if (global_status_register != 0x80)
222 return -1;
224 return 0;