2 * (C) Copyright 2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
5 * See file CREDITS for list of people who contributed to this
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,
27 /*----------------------------------------------------------------------------*/
36 static void eepStart (void)
38 out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
39 out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
41 out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
43 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
47 /*----------------------------------------------------------------------------*/
56 static void eepStop (void)
58 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = low */
59 out8(I2C_BUS_DIR, 0x60); /* set output direction for SCLK/SDIO */
61 out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = low */
63 out8(I2C_BUS_DAT, 0x60); /* SCLK = high SDIO = high */
65 out8(I2C_BUS_DIR, 0x00); /* reset to input direction */
68 /*----------------------------------------------------------------------------*/
70 * Read one byte from EEPROM
71 * ___ ___ ___ ___ ___ ___ ___ ___
72 * SCLK ___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \
73 * _________________________________________________________________
74 * SDIO > ^ ^ ^ ^ ^ ^ ^ ^
75 * : : : : : : : : : : : : : : : : :
77 static unsigned char eepReadByte (void)
79 register unsigned char buf = 0x00;
82 out8(I2C_BUS_DIR, 0x40);
84 for (i = 0; i < 8; i++)
86 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
88 out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
91 buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
92 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
98 /*----------------------------------------------------------------------------*/
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
107 static void eepWriteByte (register unsigned char buf)
111 (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = data */
112 out8(I2C_BUS_DIR, 0x60);
114 for (i = 7; i >= 0; i--)
116 (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
118 (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
120 (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low SDIO=data */
126 /*----------------------------------------------------------------------------*/
128 * Read data acknowledge of EEPROM
135 static int eepReadAck (void)
139 out8(I2C_BUS_DIR, 0x40);
140 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
142 out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = high */
144 retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
146 out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = high */
152 /*----------------------------------------------------------------------------*/
154 * Write data acknowledge to EEPROM
158 * SDIO >_______________
161 static void eepWriteAck (unsigned char ack)
163 ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
164 out8(I2C_BUS_DIR, 0x60);
166 ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high SDIO = ack */
168 ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low SDIO = ack */
172 /*----------------------------------------------------------------------------*/
174 * Read bytes from EEPROM
176 int el_srom_load (addr, buf, cnt, device, block)
180 unsigned char device;
188 eepWriteByte(0xA0 | device | block);
189 if (eepReadAck() == ERROR)
194 eepWriteByte(addr++);
195 if (eepReadAck() == ERROR)
202 eepWriteByte(0xA1 | device | block);
203 if (eepReadAck() == ERROR)
209 *buf++ = eepReadByte();
213 if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
215 if (block == FIRST_BLOCK)
216 block = SECOND_BLOCK;
224 /*----------------------------------------------------------------------------*/
227 * Write bytes to EEPROM
230 int el_srom_store (addr, buf, cnt, device, block)
231 unsigned char addr, *buf, device, block;
234 register int i, retVal;
242 eepWriteByte(0xA0 | device | block);
243 if ((retVal = eepReadAck()) == ERROR)
245 } while (retVal == ERROR);
247 eepWriteByte(addr++);
248 if (eepReadAck() == ERROR) return(ERROR);
250 if ((addr == 0) && (i != (cnt-1))) /* is it the same block ? */
252 if (block == FIRST_BLOCK)
253 block = SECOND_BLOCK;
258 eepWriteByte(*buf++);
259 if (eepReadAck() == ERROR)
267 /*----------------------------------------------------------------------------*/
269 * calculate checksum for ELTEC revision srom
271 unsigned long el_srom_checksum (ptr, size)
272 register unsigned char *ptr;
284 f = ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
285 accu >>= 1; accu ^= f;
292 /*----------------------------------------------------------------------------*/