]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/elppc/mpc107_i2c.c
mpc8xx: remove unused linker script
[karo-tx-uboot.git] / board / eltec / elppc / mpc107_i2c.c
1 /*
2  * (C) Copyright 2002 ELTEC Elektronik AG
3  * Frank Gottschling <fgottschling@eltec.de>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /* includes */
9 #include <common.h>
10 #include "srom.h"
11
12 /* locals */
13 static unsigned long mpc107_eumb_addr = 0;
14
15 /*----------------------------------------------------------------------------*/
16
17 /*
18  * calculate checksum for ELTEC revision srom
19  */
20 unsigned long el_srom_checksum (ptr, size)
21 register unsigned char *ptr;
22 unsigned long size;
23 {
24     u_long f, accu = 0;
25     u_int  i;
26     u_char byte;
27
28     for (; size; size--)
29     {
30         byte = *ptr++;
31         for (i = 8; i; i--)
32         {
33             f =  ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
34             accu >>= 1; accu ^= f;
35             byte >>= 1;
36         }
37     }
38     return(accu);
39 }
40
41 /*----------------------------------------------------------------------------*/
42
43 static int mpc107_i2c_wait ( unsigned long timeout )
44 {
45     unsigned long x;
46
47     while (((x = in32r(MPC107_I2CSR)) & 0x82) != 0x82)
48     {
49         if (!timeout--)
50             return -1;
51     }
52
53     if (x & 0x10)
54     {
55         return -1;
56     }
57     out32r(MPC107_I2CSR, 0);
58
59     return 0;
60 }
61
62 /*----------------------------------------------------------------------------*/
63
64 static int mpc107_i2c_wait_idle ( unsigned long timeout )
65 {
66     while (in32r(MPC107_I2CSR) & 0x20)
67     {
68         if (!timeout--)
69             return -1;
70     }
71     return 0;
72 }
73
74
75 /*----------------------------------------------------------------------------*/
76
77 int mpc107_i2c_read_byte (
78     unsigned char device,
79     unsigned char block,
80     unsigned char offset )
81 {
82     unsigned long timeout = MPC107_I2C_TIMEOUT;
83     int data;
84
85     if (!mpc107_eumb_addr)
86         return -6;
87
88     mpc107_i2c_wait_idle (timeout);
89
90     /* Start with MEN */
91     out32r(MPC107_I2CCR, 0x80);
92
93     /* Start as master */
94     out32r(MPC107_I2CCR, 0xB0);
95     out32r(MPC107_I2CDR, (0xA0 | device | block));
96
97     if (mpc107_i2c_wait(timeout) < 0)
98     {
99         printf("mpc107_i2c_read Error 1\n");
100         return -2;
101     }
102
103     if (in32r(MPC107_I2CSR)&0x1)
104     {
105         /* Generate STOP condition; device busy or not existing */
106         out32r(MPC107_I2CCR, 0x80);
107         return -1;
108     }
109
110     /* Data address */
111     out32r(MPC107_I2CDR, offset);
112
113     if (mpc107_i2c_wait(timeout) < 0)
114     {
115         printf("mpc107_i2c_read Error 2\n");
116         return -3;
117     }
118
119     /* Switch to read - restart */
120     out32r(MPC107_I2CCR, 0xB4);
121     out32r(MPC107_I2CDR, (0xA1 | device | block));
122
123     if (mpc107_i2c_wait(timeout) < 0)
124     {
125         printf("mpc107_i2c_read Error 3\n");
126         return -4;
127     }
128
129     out32r(MPC107_I2CCR, 0xA8); /* no ACK */
130     in32r(MPC107_I2CDR);
131
132     if (mpc107_i2c_wait(timeout) < 0)
133     {
134         printf("mpc107_i2c_read Error 4\n");
135         return -5;
136     }
137     /* Generate STOP condition */
138     out32r(MPC107_I2CCR, 0x88);
139
140     /* read */
141     data = in32r(MPC107_I2CDR);
142
143     return (data);
144 }
145
146 /*----------------------------------------------------------------------------*/
147
148 int mpc107_i2c_write_byte (
149     unsigned char device,
150     unsigned char block,
151     unsigned char offset,
152     unsigned char val )
153 {
154
155     unsigned long timeout = MPC107_I2C_TIMEOUT;
156
157     if (!mpc107_eumb_addr)
158         return -6;
159
160     mpc107_i2c_wait_idle(timeout);
161
162     /* Start with MEN */
163     out32r(MPC107_I2CCR, 0x80);
164
165     /* Start as master */
166     out32r(MPC107_I2CCR, 0xB0);
167     out32r(MPC107_I2CDR, (0xA0 | device | block));
168
169     if (mpc107_i2c_wait(timeout) < 0)
170     {
171         printf("mpc107_i2c_write Error 1\n");
172         return -1;
173     }
174
175     /* Data address */
176     out32r(MPC107_I2CDR, offset);
177
178     if (mpc107_i2c_wait(timeout) < 0)
179     {
180         printf("mpc107_i2c_write Error 2\n");
181         return -1;
182     }
183
184     /* Write */
185     out32r(MPC107_I2CDR, val);
186     if (mpc107_i2c_wait(timeout) < 0)
187     {
188         printf("mpc107_i2c_write Error 3\n");
189         return -1;
190     }
191
192     /* Generate Stop Condition */
193     out32r(MPC107_I2CCR, 0x80);
194
195     /* Return ACK or no ACK */
196     return (in32r(MPC107_I2CSR) & 0x01);
197 }
198
199 /*----------------------------------------------------------------------------*/
200
201 int mpc107_srom_load (
202     unsigned char addr,
203     unsigned char *pBuf,
204     int          cnt,
205     unsigned char device,
206     unsigned char block )
207 {
208     register int i;
209     int val;
210     int timeout;
211
212     for (i = 0; i < cnt; i++)
213     {
214         timeout=100;
215         do
216         {
217             val = mpc107_i2c_read_byte (device, block, addr);
218             if (val < -1)
219             {
220             printf("i2c_read_error %d at dev %x block %x addr %x\n",
221                    val, device, block, addr);
222             return -1;
223             }
224             else if (timeout==0)
225             {
226                 printf ("i2c_read_error: timeout at dev %x block %x addr %x\n",
227                         device, block, addr);
228                 return -1;
229             }
230             timeout--;
231         } while (val == -1); /* if no ack: try again! */
232
233         *pBuf++ = (unsigned char)val;
234         addr++;
235
236         if ((addr == 0) && (i != cnt-1))    /* is it the same block ? */
237         {
238             if (block == FIRST_BLOCK)
239                 block = SECOND_BLOCK;
240             else
241             {
242                 printf ("ic2_read_error: read beyond 2. block !\n");
243                 return -1;
244             }
245         }
246     }
247     udelay(100000);
248     return (cnt);
249 }
250
251 /*----------------------------------------------------------------------------*/
252
253 int mpc107_srom_store (
254     unsigned char addr,
255     unsigned char *pBuf,
256     int          cnt,
257     unsigned char device,
258     unsigned char block )
259 {
260     register int i;
261
262     for (i = 0; i < cnt; i++)
263     {
264         while (mpc107_i2c_write_byte (device,block,addr,*pBuf) == 1);
265         addr++;
266         pBuf++;
267
268         if ((addr == 0) && (i != cnt-1))     /* is it the same block ? */
269         {
270             if (block == FIRST_BLOCK)
271                 block = SECOND_BLOCK;
272             else
273             {
274                 printf ("ic2_write_error: write beyond 2. block !\n");
275                 return -1;
276             }
277         }
278     }
279     udelay(100000);
280     return(cnt);
281 }
282
283 /*----------------------------------------------------------------------------*/
284
285 int mpc107_i2c_init ( unsigned long eumb_addr, unsigned long divider )
286 {
287     unsigned long x;
288
289     if (eumb_addr)
290         mpc107_eumb_addr = eumb_addr;
291     else
292         return -1;
293
294     /* Set I2C clock */
295     x = in32r(MPC107_I2CFDR) & 0xffffff00;
296     out32r(MPC107_I2CFDR, (x | divider));
297
298     /* Clear arbitration */
299     out32r(MPC107_I2CSR, 0);
300
301     return mpc107_eumb_addr;
302 }
303
304 /*----------------------------------------------------------------------------*/