add the correct input file to makeindex call
[Rockbox.git] / firmware / drivers / eeprom_24cxx.c
blobe045a13fa6a310d9f99c0726b3bbecf4230a3b28
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 by Miika Pekkarinen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "lcd.h"
20 #include "cpu.h"
21 #include "system.h"
22 #include "kernel.h"
23 #include "thread.h"
24 #include "debug.h"
25 #include "logf.h"
26 #include "sprintf.h"
27 #include "string.h"
29 #include "eeprom_24cxx.h"
31 /**
32 * I2C-functions are copied and ported from fmradio.c.
35 #define SW_I2C_WRITE 0
36 #define SW_I2C_READ 1
38 /* h1x0 needs its own i2c driver,
39 h3x0 uses the pcf i2c driver */
41 #ifdef IRIVER_H100_SERIES
43 /* cute little functions, atomic read-modify-write */
45 /* SCL is GPIO, 12 */
46 #define SCL ( 0x00001000 & GPIO_READ)
47 #define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT)
48 #define SCL_LO or_l( 0x00001000, &GPIO_ENABLE)
49 #define SCL_HI and_l(~0x00001000, &GPIO_ENABLE)
51 /* SDA is GPIO1, 13 */
52 #define SDA ( 0x00002000 & GPIO1_READ)
53 #define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT)
54 #define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE)
55 #define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE)
57 /* delay loop to achieve 400kHz at 120MHz CPU frequency */
58 #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0)
60 static void sw_i2c_init(void)
62 logf("sw_i2c_init");
63 or_l(0x00001000, &GPIO_FUNCTION);
64 or_l(0x00002000, &GPIO1_FUNCTION);
65 SDA_HI;
66 SCL_HI;
67 SDA_OUT_LO;
68 SCL_OUT_LO;
71 static void sw_i2c_start(void)
73 SCL_LO;
74 DELAY;
75 SDA_HI;
76 DELAY;
77 SCL_HI;
78 DELAY;
79 SDA_LO;
80 DELAY;
81 SCL_LO;
84 static void sw_i2c_stop(void)
86 SCL_HI;
87 DELAY;
88 SDA_HI;
89 DELAY;
92 static void sw_i2c_ack(void)
94 SCL_LO;
95 DELAY;
96 SDA_LO;
97 DELAY;
99 SCL_HI;
100 DELAY;
103 static bool sw_i2c_getack(void)
105 bool ret = true;
106 int count = 10;
108 SCL_LO;
109 DELAY;
110 SDA_HI; /* sets to input */
111 DELAY;
112 SCL_HI;
113 DELAY;
115 while (SDA && count--)
116 DELAY;
118 if (SDA)
119 /* ack failed */
120 ret = false;
122 SCL_LO;
123 DELAY;
124 SDA_LO;
126 return ret;
129 static void sw_i2c_outb(unsigned char byte)
131 int i;
133 /* clock out each bit, MSB first */
134 for ( i=0x80; i; i>>=1 )
136 SCL_LO;
137 DELAY;
138 if ( i & byte )
139 SDA_HI;
140 else
141 SDA_LO;
142 DELAY;
143 SCL_HI;
144 DELAY;
148 static unsigned char sw_i2c_inb(void)
150 int i;
151 unsigned char byte = 0;
153 SDA_HI; /* sets to input */
155 /* clock in each bit, MSB first */
156 for ( i=0x80; i; i>>=1 )
158 SCL_HI;
159 DELAY;
160 if ( SDA )
161 byte |= i;
162 SCL_LO;
163 DELAY;
166 sw_i2c_ack();
168 return byte;
171 #else
173 #include "pcf50606.h"
175 #define sw_i2c_init() /* no extra init required */
176 #define sw_i2c_start() pcf50606_i2c_start()
177 #define sw_i2c_stop() pcf50606_i2c_stop()
178 #define sw_i2c_ack() pcf50606_i2c_ack(true)
179 #define sw_i2c_getack() pcf50606_i2c_getack()
180 #define sw_i2c_outb(x) pcf50606_i2c_outb(x)
181 #define sw_i2c_inb() pcf50606_i2c_inb(false)
183 #endif /* IRIVER_H100_SERIES */
186 int sw_i2c_write(int location, const unsigned char* buf, int count)
188 int i;
190 sw_i2c_start();
191 sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
192 if (!sw_i2c_getack())
194 sw_i2c_stop();
195 return -1;
198 sw_i2c_outb(location);
199 if (!sw_i2c_getack())
201 sw_i2c_stop();
202 return -2;
205 for (i=0; i<count; i++)
207 sw_i2c_outb(buf[i]);
208 if (!sw_i2c_getack())
210 sw_i2c_stop();
211 return -3;
215 sw_i2c_stop();
217 return 0;
220 int sw_i2c_write_byte(int location, unsigned char byte)
222 sw_i2c_start();
223 sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
224 if (!sw_i2c_getack())
226 sw_i2c_stop();
227 return -1;
230 sw_i2c_outb(location);
231 if (!sw_i2c_getack())
233 sw_i2c_stop();
234 return -2;
237 sw_i2c_outb(byte);
238 if (!sw_i2c_getack())
240 sw_i2c_stop();
241 return -3;
244 sw_i2c_stop();
246 return 0;
249 int sw_i2c_read(unsigned char location, unsigned char* byte)
251 sw_i2c_start();
252 sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
253 if (!sw_i2c_getack())
255 sw_i2c_stop();
256 return -1;
259 sw_i2c_outb(location);
260 if (!sw_i2c_getack())
262 sw_i2c_stop();
263 return -2;
266 sw_i2c_start();
267 sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_READ);
268 if (!sw_i2c_getack())
270 sw_i2c_stop();
271 return -3;
274 *byte = sw_i2c_inb();
275 sw_i2c_stop();
277 return 0;
280 void eeprom_24cxx_init(void)
282 sw_i2c_init();
285 int eeprom_24cxx_read_byte(unsigned int address, char *c)
287 int ret;
288 char byte;
289 int count = 0;
291 if (address >= EEPROM_SIZE)
293 logf("EEPROM address: %d", address);
294 return -9;
297 *c = 0;
300 ret = sw_i2c_read(address, &byte);
301 } while (ret < 0 && count++ < 200);
303 if (ret < 0)
305 logf("EEPROM RFail: %d/%d/%d", ret, address, count);
306 return ret;
309 if (count)
311 /* keep between {} as logf is whitespace in normal builds */
312 logf("EEPROM rOK: %d retries", count);
315 *c = byte;
316 return 0;
319 int eeprom_24cxx_write_byte(unsigned int address, char c)
321 int ret;
322 int count = 0;
324 if (address >= EEPROM_SIZE)
326 logf("EEPROM address: %d", address);
327 return -9;
332 ret = sw_i2c_write_byte(address, c);
333 } while (ret < 0 && count++ < 200) ;
335 if (ret < 0)
337 logf("EEPROM WFail: %d/%d", ret, address);
338 return ret;
341 if (count)
343 /* keep between {} as logf is whitespace in normal builds */
344 logf("EEPROM wOK: %d retries", count);
347 return 0;
350 int eeprom_24cxx_read(unsigned char address, void *dest, int length)
352 char *buf = (char *)dest;
353 int ret = 0;
354 int i;
356 for (i = 0; i < length; i++)
358 ret = eeprom_24cxx_read_byte(address+i, &buf[i]);
359 if (ret < 0)
360 return ret;
363 return ret;
366 int eeprom_24cxx_write(unsigned char address, const void *src, int length)
368 const char *buf = (const char *)src;
369 int count = 5;
370 int i;
371 bool ok;
373 while (count-- > 0)
375 for (i = 0; i < length; i++)
376 eeprom_24cxx_write_byte(address+i, buf[i]);
378 ok = true;
379 for (i = 0; i < length; i++)
381 char byte;
383 eeprom_24cxx_read_byte(address+i, &byte);
384 if (byte != buf[i])
386 logf("Verify failed: %d/%d", address+i, count);
387 ok = false;
388 break;
392 if (ok)
393 return 0;
396 return -1;