blob: 8445e01caf0be5773d24f97b89e86d48ed402774 [file] [log] [blame]
Jean-Christophe PLAGNIOL-VILLARDac09d352009-03-29 23:01:40 +02001/*
2 * (C) Copyright 2004
3 * DAVE Srl
4 * http://www.dave-tech.it
5 * http://www.wawnet.biz
6 * mailto:info@wawnet.biz
7 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Jean-Christophe PLAGNIOL-VILLARDac09d352009-03-29 23:01:40 +02009 */
10
11#include <common.h>
12#include <command.h>
13#include <asm/hardware.h>
14
15/*
16 * Initialization, must be called once on start up, may be called
17 * repeatedly to change the speed and slave addresses.
18 */
19void i2c_init(int speed, int slaveaddr)
20{
21 /*
22 setting up I2C support
23 */
24 unsigned int save_F,save_PF,rIICCON,rPCONA,rPDATA,rPCONF,rPUPF;
25
26 save_F = PCONF;
27 save_PF = PUPF;
28
29 rPCONF = ((save_F & ~(0xF))| 0xa);
30 rPUPF = (save_PF | 0x3);
31 PCONF = rPCONF; /*PF0:IICSCL, PF1:IICSDA*/
32 PUPF = rPUPF; /* Disable pull-up */
33
34 /* Configuring pin for WC pin of EEprom */
35 rPCONA = PCONA;
36 rPCONA &= ~(1<<9);
37 PCONA = rPCONA;
38
39 rPDATA = PDATA;
40 rPDATA &= ~(1<<9);
41 PDATA = rPDATA;
42
43 /*
44 Enable ACK, IICCLK=MCLK/16, enable interrupt
45 75MHz/16/(12+1) = 390625 Hz
46 */
47 rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xC);
48 IICCON = rIICCON;
49
50 IICADD = slaveaddr;
51}
52
53/*
54 * Probe the given I2C chip address. Returns 0 if a chip responded,
55 * not 0 on failure.
56 */
57int i2c_probe(uchar chip)
58{
59 /*
60 not implemented
61 */
62
63 printf("i2c_probe chip %d\n", (int) chip);
64 return -1;
65}
66
67/*
68 * Read/Write interface:
69 * chip: I2C chip address, range 0..127
70 * addr: Memory (register) address within the chip
71 * alen: Number of bytes to use for addr (typically 1, 2 for larger
72 * memories, 0 for register type devices with only one
73 * register)
74 * buffer: Where to read/write the data
75 * len: How many bytes to read/write
76 *
77 * Returns: 0 on success, not 0 on failure
78 */
79
80#define S3C44B0X_rIIC_INTPEND (1<<4)
81#define S3C44B0X_rIIC_LAST_RECEIV_BIT (1<<0)
82#define S3C44B0X_rIIC_INTERRUPT_ENABLE (1<<5)
83#define S3C44B0_IIC_TIMEOUT 100
84
85int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
86{
87
88 int k, j, temp;
89 u32 rIICSTAT;
90
91 /*
92 send the device offset
93 */
94
95 rIICSTAT = 0xD0;
96 IICSTAT = rIICSTAT;
97
98 IICDS = chip; /* this is a write operation... */
99
100 rIICSTAT |= (1<<5);
101 IICSTAT = rIICSTAT;
102
103 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
104 temp = IICCON;
105 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
106 break;
107 udelay(2000);
108 }
109 if (k==S3C44B0_IIC_TIMEOUT)
110 return -1;
111
112 /* wait and check ACK */
113 temp = IICSTAT;
114 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
115 return -1;
116
117 IICDS = addr;
118 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
119
120 /* wait and check ACK */
121 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
122 temp = IICCON;
123 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
124 break;
125 udelay(2000);
126 }
127 if (k==S3C44B0_IIC_TIMEOUT)
128 return -1;
129
130 temp = IICSTAT;
131 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
132 return -1;
133
134 /*
135 now we can start with the read operation...
136 */
137
138 IICDS = chip | 0x01; /* this is a read operation... */
139
140 rIICSTAT = 0x90; /*master recv*/
141 rIICSTAT |= (1<<5);
142 IICSTAT = rIICSTAT;
143
144 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
145
146 /* wait and check ACK */
147 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
148 temp = IICCON;
149 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
150 break;
151 udelay(2000);
152 }
153 if (k==S3C44B0_IIC_TIMEOUT)
154 return -1;
155
156 temp = IICSTAT;
157 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
158 return -1;
159
160 for (j=0; j<len-1; j++) {
161
162 /*clear pending bit to resume */
163
164 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
165 IICCON = temp;
166
167 /* wait and check ACK */
168 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
169 temp = IICCON;
170 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
171 break;
172 udelay(2000);
173 }
174 if (k==S3C44B0_IIC_TIMEOUT)
175 return -1;
176
177
178 buffer[j] = IICDS; /*save readed data*/
179
180 } /*end for(j)*/
181
182 /*
183 reading the last data
184 unset ACK generation
185 */
186 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND | (1<<7));
187 IICCON = temp;
188
189 /* wait but NOT check ACK */
190 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
191 temp = IICCON;
192 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
193 break;
194 udelay(2000);
195 }
196 if (k==S3C44B0_IIC_TIMEOUT)
197 return -1;
198
199 buffer[j] = IICDS; /*save readed data*/
200
201 rIICSTAT = 0x90; /*master recv*/
202
203 /* Write operation Terminate sending STOP */
204 IICSTAT = rIICSTAT;
205 /*Clear Int Pending Bit to RESUME*/
206 temp = IICCON;
207 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
208
209 IICCON = IICCON | (1<<7); /*restore ACK generation*/
210
211 return 0;
212}
213
214int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
215{
216 int j, k;
217 u32 rIICSTAT, temp;
218
219
220 /*
221 send the device offset
222 */
223
224 rIICSTAT = 0xD0;
225 IICSTAT = rIICSTAT;
226
227 IICDS = chip; /* this is a write operation... */
228
229 rIICSTAT |= (1<<5);
230 IICSTAT = rIICSTAT;
231
232 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
233
234 /* wait and check ACK */
235 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
236 temp = IICCON;
237 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
238 break;
239 udelay(2000);
240 }
241 if (k==S3C44B0_IIC_TIMEOUT)
242 return -1;
243
244 temp = IICSTAT;
245 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
246 return -1;
247
248 IICDS = addr;
249 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
250
251 /* wait and check ACK */
252 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
253 temp = IICCON;
254 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
255 break;
256 udelay(2000);
257 }
258 if (k==S3C44B0_IIC_TIMEOUT)
259 return -1;
260
261 temp = IICSTAT;
262 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
263 return -1;
264
265 /*
266 now we can start with the read write operation
267 */
268 for (j=0; j<len; j++) {
269
270 IICDS = buffer[j]; /*prerare data to write*/
271
272 /*clear pending bit to resume*/
273
274 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
275 IICCON = temp;
276
277 /* wait but NOT check ACK */
278 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
279 temp = IICCON;
280 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
281 break;
282
283 udelay(2000);
284 }
285
286 if (k==S3C44B0_IIC_TIMEOUT)
287 return -1;
288
289 } /* end for(j) */
290
291 /* sending stop to terminate */
292 rIICSTAT = 0xD0; /*master send*/
293 IICSTAT = rIICSTAT;
294 /*Clear Int Pending Bit to RESUME*/
295 temp = IICCON;
296 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
297
298 return 0;
299}