to make u-boot work for fat32 filesystem
[jz_uboot.git] / board / pcippc2 / i2c.c
blob36b1d0f44d8ceba85d4f5afb0fab01c8404291cb
1 /*
2 * (C) Copyright 2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
6 * project.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
24 #include <config.h>
25 #include <common.h>
26 #include <asm/io.h>
28 #include "hardware.h"
29 #include "i2c.h"
31 static void i2c_start (void);
32 static void i2c_stop (void);
33 static int i2c_write (u8 data);
34 static void i2c_read (u8 * data);
36 static inline void i2c_port_start (void);
37 static inline void i2c_clock (unsigned int val);
38 static inline void i2c_data (unsigned int val);
39 static inline unsigned int
40 i2c_in (void);
41 static inline void i2c_write_bit (unsigned int val);
42 static inline unsigned int
43 i2c_read_bit (void);
45 static inline void i2c_udelay (unsigned int time);
47 int i2c_read_byte (
48 u8 * data,
49 u8 dev,
50 u8 offset)
52 int err = 0;
54 i2c_start();
56 err = ! i2c_write(dev);
58 if (! err)
60 err = ! i2c_write(offset);
63 if (! err)
65 i2c_start();
68 if (! err)
70 err = ! i2c_write(dev | 0x01);
73 if (! err)
75 i2c_read(data);
78 i2c_stop();
80 return ! err;
83 static inline void i2c_udelay (
84 unsigned int time)
86 int v;
88 asm volatile("mtdec %0" : : "r" (time * ((CFG_BUS_CLK / 4) / 1000000)));
92 asm volatile("isync; mfdec %0" : "=r" (v));
93 } while (v >= 0);
96 /* Low-level hardware access
99 #define BIT_GPDATA 0x80000000
100 #define BIT_GPCLK 0x40000000
102 static inline void i2c_port_start (void)
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();
108 i2c_udelay(1);
111 static inline void i2c_clock (
112 unsigned int val)
114 if (val)
116 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
118 else
120 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
123 iobarrier_rw();
125 i2c_udelay(1);
128 static inline void i2c_data (
129 unsigned int val)
131 if (val)
133 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
135 else
137 out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
140 iobarrier_rw();
142 i2c_udelay(1);
145 static inline unsigned int i2c_in (void)
147 unsigned int val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
149 iobarrier_rw();
151 return val;
155 /* Protocol implementation
158 static inline void i2c_write_bit (
159 unsigned int val)
161 i2c_data(val);
162 i2c_udelay(10);
163 i2c_clock(1);
164 i2c_udelay(10);
165 i2c_clock(0);
166 i2c_udelay(10);
169 static inline unsigned int i2c_read_bit (void)
171 unsigned int val;
173 i2c_data(1);
174 i2c_udelay(10);
176 i2c_clock(1);
177 i2c_udelay(10);
179 val = i2c_in();
181 i2c_clock(0);
182 i2c_udelay(10);
184 return val;
187 unsigned int i2c_reset (void)
189 unsigned int val;
190 int i;
192 i2c_port_start();
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);
208 static void i2c_start (void)
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);
219 static void i2c_stop (void)
221 i2c_data(0);
222 i2c_udelay(10);
223 i2c_clock(1);
224 i2c_udelay(10);
225 i2c_data(1);
226 i2c_udelay(10);
229 static int i2c_write (
230 u8 data)
232 unsigned int i;
234 for (i = 0; i < 8; i++)
236 i2c_write_bit(data >> 7);
237 data <<= 1;
240 return i2c_read_bit() == 0;
243 static void i2c_read (
244 u8 * data)
246 unsigned int i;
247 u8 val = 0;
249 for (i = 0; i < 8; i++)
251 val <<= 1;
252 val |= i2c_read_bit();
255 *data = val;
256 i2c_write_bit(1); /* NoAck */