tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / southbridge / nvidia / mcp55 / smbus.h
blob9db21171beccf676e34166f224f85928473ed2f7
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.
6 * Copyright (C) 2006,2007 AMD
7 * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 #include <device/smbus_def.h>
22 #define SMBHSTSTAT 0x1
23 #define SMBHSTPRTCL 0x0
24 #define SMBHSTCMD 0x3
25 #define SMBXMITADD 0x2
26 #define SMBHSTDAT0 0x4
27 #define SMBHSTDAT1 0x5
29 /* Between 1-10 seconds, We should never timeout normally
30 * Longer than this is just painful when a timeout condition occurs.
32 #define SMBUS_TIMEOUT (100*1000*10)
34 static inline void smbus_delay(void)
36 outb(0x80, 0x80);
39 static int smbus_wait_until_done(unsigned smbus_io_base)
41 unsigned long loops;
42 loops = SMBUS_TIMEOUT;
43 do {
44 unsigned char val;
45 smbus_delay();
47 val = inb(smbus_io_base + SMBHSTSTAT);
48 if ( (val & 0xff) != 0) {
49 return 0;
51 } while(--loops);
52 return -3;
54 static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
56 unsigned char global_status_register;
57 unsigned char byte;
59 /* set the device I'm talking too */
60 outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
61 smbus_delay();
63 /* byte data recv */
64 outb(0x05, smbus_io_base + SMBHSTPRTCL);
65 smbus_delay();
67 /* poll for transaction completion */
68 if (smbus_wait_until_done(smbus_io_base) < 0) {
69 return -3;
72 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
74 /* read results of transaction */
75 byte = inb(smbus_io_base + SMBHSTCMD);
77 if (global_status_register != 0x80) { // lose check, otherwise it should be 0
78 return -1;
80 return byte;
82 static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
84 unsigned global_status_register;
86 outb(val, smbus_io_base + SMBHSTDAT0);
87 smbus_delay();
89 /* set the command... */
90 outb(val, smbus_io_base + SMBHSTCMD);
91 smbus_delay();
93 /* set the device I'm talking too */
94 outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
95 smbus_delay();
97 /* set up for a byte data write */
98 outb(0x04, smbus_io_base + SMBHSTPRTCL);
99 smbus_delay();
101 /* poll for transaction completion */
102 if (smbus_wait_until_done(smbus_io_base) < 0) {
103 return -3;
105 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
107 if (global_status_register != 0x80) {
108 return -1;
110 return 0;
112 static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
114 unsigned char global_status_register;
115 unsigned char byte;
117 /* set the device I'm talking too */
118 outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
119 smbus_delay();
120 /* set the command/address... */
121 outb(address & 0xff, smbus_io_base + SMBHSTCMD);
122 smbus_delay();
123 /* byte data read */
124 outb(0x07, smbus_io_base + SMBHSTPRTCL);
125 smbus_delay();
127 /* poll for transaction completion */
128 if (smbus_wait_until_done(smbus_io_base) < 0) {
129 return -3;
132 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
134 /* read results of transaction */
135 byte = inb(smbus_io_base + SMBHSTDAT0);
137 if (global_status_register != 0x80) { // lose check, otherwise it should be 0
138 return -1;
140 return byte;
144 static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
146 unsigned global_status_register;
148 outb(val, smbus_io_base + SMBHSTDAT0);
149 smbus_delay();
151 /* set the device I'm talking too */
152 outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
153 smbus_delay();
155 outb(address & 0xff, smbus_io_base + SMBHSTCMD);
156 smbus_delay();
158 /* set up for a byte data write */
159 outb(0x06, smbus_io_base + SMBHSTPRTCL);
160 smbus_delay();
162 /* poll for transaction completion */
163 if (smbus_wait_until_done(smbus_io_base) < 0) {
164 return -3;
166 global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
168 if (global_status_register != 0x80) {
169 return -1;
171 return 0;