source: SVN/rincon/u-boot/board/eltec/elppc/mpc107_i2c.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 2 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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