1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <config.h>
25#include <common.h>
26#include <asm/io.h>
27
28#include "hardware.h"
29#include "i2c.h"
30
31static void i2c_start (void);
32static void i2c_stop (void);
33static int i2c_write (u8 data);
34static void i2c_read (u8 * data);
35
36static inline void i2c_port_start (void);
37static inline void i2c_clock (unsigned int val);
38static inline void i2c_data (unsigned int val);
39static inline unsigned int
40 i2c_in (void);
41static inline void i2c_write_bit (unsigned int val);
42static inline unsigned int
43 i2c_read_bit (void);
44
45static inline void i2c_udelay (unsigned int time);
46
47int i2c_read_byte (
48 u8 * data,
49 u8 dev,
50 u8 offset)
51{
52 int err = 0;
53
54 i2c_start();
55
56 err = ! i2c_write(dev);
57
58 if (! err)
59 {
60 err = ! i2c_write(offset);
61 }
62
63 if (! err)
64 {
65 i2c_start();
66 }
67
68 if (! err)
69 {
70 err = ! i2c_write(dev | 0x01);
71 }
72
73 if (! err)
74 {
75 i2c_read(data);
76 }
77
78 i2c_stop();
79
80 return ! err;
81}
82
83static inline void i2c_udelay (
84 unsigned int time)
85{
86 int v;
87
88 asm volatile("mtdec %0" : : "r" (time * ((CONFIG_SYS_BUS_CLK / 4) / 1000000)));
89
90 do
91 {
92 asm volatile("isync; mfdec %0" : "=r" (v));
93 } while (v >= 0);
94}
95
96
97
98
99#define BIT_GPDATA 0x80000000
100#define BIT_GPCLK 0x40000000
101
102static inline void i2c_port_start (void)
103{
104 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~(BIT_GPCLK | BIT_GPDATA));
105 out32(REG(CPC0, GPOUT), in32(REG(CPC0, GPOUT)) & ~(BIT_GPCLK | BIT_GPDATA));
106 iobarrier_rw();
107
108 i2c_udelay(1);
109}
110
111static inline void i2c_clock (
112 unsigned int val)
113{
114 if (val)
115 {
116 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
117 }
118 else
119 {
120 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
121 }
122
123 iobarrier_rw();
124
125 i2c_udelay(1);
126}
127
128static inline void i2c_data (
129 unsigned int val)
130{
131 if (val)
132 {
133 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
134 }
135 else
136 {
137 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
138 }
139
140 iobarrier_rw();
141
142 i2c_udelay(1);
143}
144
145static inline unsigned int i2c_in (void)
146{
147 unsigned int val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
148
149 iobarrier_rw();
150
151 return val;
152}
153
154
155
156
157
158static inline void i2c_write_bit (
159 unsigned int val)
160{
161 i2c_data(val);
162 i2c_udelay(10);
163 i2c_clock(1);
164 i2c_udelay(10);
165 i2c_clock(0);
166 i2c_udelay(10);
167}
168
169static inline unsigned int i2c_read_bit (void)
170{
171 unsigned int val;
172
173 i2c_data(1);
174 i2c_udelay(10);
175
176 i2c_clock(1);
177 i2c_udelay(10);
178
179 val = i2c_in();
180
181 i2c_clock(0);
182 i2c_udelay(10);
183
184 return val;
185}
186
187unsigned int i2c_reset (void)
188{
189 unsigned int val;
190 int i;
191
192 i2c_port_start();
193
194 i=0;
195 do {
196 i2c_udelay(10);
197 i2c_clock(0);
198 i2c_udelay(10);
199 i2c_clock(1);
200 i2c_udelay(10);
201 val = i2c_in();
202 i++;
203 } while ((i<9)&&(val==0));
204 return (val);
205}
206
207
208static void i2c_start (void)
209{
210 i2c_data(1);
211 i2c_clock(1);
212 i2c_udelay(10);
213 i2c_data(0);
214 i2c_udelay(10);
215 i2c_clock(0);
216 i2c_udelay(10);
217}
218
219static void i2c_stop (void)
220{
221 i2c_data(0);
222 i2c_udelay(10);
223 i2c_clock(1);
224 i2c_udelay(10);
225 i2c_data(1);
226 i2c_udelay(10);
227}
228
229static int i2c_write (
230 u8 data)
231{
232 unsigned int i;
233
234 for (i = 0; i < 8; i++)
235 {
236 i2c_write_bit(data >> 7);
237 data <<= 1;
238 }
239
240 return i2c_read_bit() == 0;
241}
242
243static void i2c_read (
244 u8 * data)
245{
246 unsigned int i;
247 u8 val = 0;
248
249 for (i = 0; i < 8; i++)
250 {
251 val <<= 1;
252 val |= i2c_read_bit();
253 }
254
255 *data = val;
256 i2c_write_bit(1);
257}
258