source: SVN/rincon/u-boot/board/eltec/bab7xx/el_srom.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

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

File size: 7.5 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#include <common.h>
25#include "srom.h"
26
27/*----------------------------------------------------------------------------*/
28/*
29 *  START sequence
30 *        _ _________
31 *  SCLK  _>         \____
32 *        _ ____
33 *  SDIO  _>    \_________
34 *         :    :    :
35 */
36static void eepStart (void)
37{
38    out8(I2C_BUS_DAT, 0x60);     /* SCLK = high  SDIO = high */
39    out8(I2C_BUS_DIR, 0x60);     /* set output direction for SCLK/SDIO */
40    udelay(10);
41    out8(I2C_BUS_DAT, 0x40);     /* SCLK = high  SDIO = low */
42    udelay(10);
43    out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = low */
44    udelay(10);
45}
46
47/*----------------------------------------------------------------------------*/
48/*
49 *  STOP sequence
50 *              _______
51 *  SCLK  _____/
52 *        _         ___
53 *  SDIO  _>_______/
54 *         :   :   :
55 */
56static void eepStop (void)
57{
58    out8(I2C_BUS_DAT, 0x00);      /* SCLK = low   SDIO = low */
59    out8(I2C_BUS_DIR, 0x60);      /* set output direction for SCLK/SDIO */
60    udelay(10);
61    out8(I2C_BUS_DAT, 0x40);      /* SCLK = high  SDIO = low */
62    udelay(10);
63    out8(I2C_BUS_DAT, 0x60);      /* SCLK = high  SDIO = high */
64    udelay(10);
65    out8(I2C_BUS_DIR, 0x00);      /* reset to input direction */
66}
67
68/*----------------------------------------------------------------------------*/
69/*
70 *  Read one byte from EEPROM
71 *            ___     ___     ___     ___     ___     ___     ___     ___
72 *  SCLK  ___/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \
73 *        _________________________________________________________________
74 *  SDIO  >     ^       ^       ^       ^       ^       ^       ^       ^
75 *        :  :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
76 */
77static unsigned char eepReadByte (void)
78{
79    register unsigned char buf = 0x00;
80    register int i;
81
82    out8(I2C_BUS_DIR, 0x40);
83
84    for (i = 0; i < 8; i++)
85    {
86        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
87        udelay(10);
88        out8(I2C_BUS_DAT, 0x40);    /* SCLK = high  SDIO = high */
89        udelay(15);
90        buf <<= 1;
91        buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
92        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
93        udelay(10);
94    }
95    return(buf);
96}
97
98/*----------------------------------------------------------------------------*/
99/*
100 *  Write one byte to EEPROM
101 *           ___     ___     ___     ___     ___     ___     ___     ___
102 *  SCLK  __/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \__
103 *         _______ _______ _______ _______ _______ _______ _______ ________
104 *  SDIO  X_______X_______X_______X_______X_______X_______X_______X________
105 *      :   7   :   6   :   5   :   4   :   3   :   2   :   1   :   0
106 */
107static void eepWriteByte (register unsigned char buf)
108{
109    register int    i;
110
111    (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = data */
112    out8(I2C_BUS_DIR, 0x60);
113
114    for (i = 7; i >= 0; i--)
115    {
116        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
117        udelay(10);
118        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
119        udelay(15);
120        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
121        udelay(10);
122        buf <<= 1;
123    }
124}
125
126/*----------------------------------------------------------------------------*/
127/*
128 *  Read data acknowledge of EEPROM
129 *             _______
130 *  SCLK  ____/       \___
131 *         _______________
132 *  SDIO  >
133 *        :   :   ^   :
134 */
135static int eepReadAck (void)
136{
137    int retval;
138
139    out8(I2C_BUS_DIR, 0x40);
140    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
141    udelay(10);
142    out8(I2C_BUS_DAT, 0x40);            /* SCLK = high  SDIO = high */
143    udelay(10);
144    retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
145    udelay(10);
146    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
147    udelay(10);
148
149    return(retval);
150}
151
152/*----------------------------------------------------------------------------*/
153/*
154 *  Write data acknowledge to EEPROM
155 *             _______
156 *  SCLK  ____/       \___
157 *
158 *  SDIO  >_______________
159 *        :   :       :
160 */
161static void eepWriteAck (unsigned char ack)
162{
163    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
164    out8(I2C_BUS_DIR, 0x60);
165    udelay(10);
166    ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high  SDIO = ack */
167    udelay(15);
168    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
169    udelay(10);
170}
171
172/*----------------------------------------------------------------------------*/
173/*
174 * Read bytes from EEPROM
175 */
176int el_srom_load (addr, buf, cnt, device, block)
177unsigned char addr;
178unsigned char *buf;
179int cnt;
180unsigned char device;
181unsigned char block;
182{
183    register int i;
184
185    for (i=0;i<cnt;i++)
186    {
187        eepStart();
188        eepWriteByte(0xA0 | device | block);
189        if (eepReadAck() == ERROR)
190        {
191           eepStop();
192            return(ERROR);
193        }
194        eepWriteByte(addr++);
195        if (eepReadAck() == ERROR)
196        {
197            eepStop();
198            return(ERROR);
199        }
200        eepStart();
201
202        eepWriteByte(0xA1 | device | block);
203        if (eepReadAck() == ERROR)
204        {
205            eepStop();
206            return(ERROR);
207        }
208
209        *buf++ = eepReadByte();
210        eepWriteAck(1);
211        eepStop();
212
213        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
214        {
215            if (block == FIRST_BLOCK)
216                block = SECOND_BLOCK;
217            else
218                return(ERROR);
219        }
220    }
221    return(cnt);
222}
223
224/*----------------------------------------------------------------------------*/
225/*
226 *
227 * Write bytes to EEPROM
228 *
229 */
230int el_srom_store (addr, buf, cnt, device, block)
231unsigned char    addr, *buf, device, block;
232int        cnt;
233{
234    register int i, retVal;
235
236    for (i=0;i<cnt;i++)
237    {
238        retVal = ERROR;
239        do
240        {
241            eepStart();
242            eepWriteByte(0xA0 | device | block);
243            if ((retVal = eepReadAck()) == ERROR)
244                eepStop();
245        } while (retVal == ERROR);
246
247        eepWriteByte(addr++);
248        if (eepReadAck() == ERROR)  return(ERROR);
249
250        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
251        {
252            if (block == FIRST_BLOCK)
253                block = SECOND_BLOCK;
254            else
255            return(ERROR);
256        }
257
258        eepWriteByte(*buf++);
259        if (eepReadAck() == ERROR)
260            return(ERROR);
261
262        eepStop();
263    }
264    return(cnt);
265}
266
267/*----------------------------------------------------------------------------*/
268/*
269 * calculate checksum for ELTEC revision srom
270 */
271unsigned long el_srom_checksum (ptr, size)
272register unsigned char *ptr;
273unsigned long size;
274{
275    u_long f, accu = 0;
276    u_int  i;
277    u_char byte;
278
279    for (; size; size--)
280    {
281        byte = *ptr++;
282        for (i = 8; i; i--)
283        {
284            f =  ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
285            accu >>= 1; accu ^= f;
286            byte >>= 1;
287        }
288    }
289    return(accu);
290}
291
292/*----------------------------------------------------------------------------*/
Note: See TracBrowser for help on using the repository browser.