tizen 2.4 release
[kernel/u-boot-tm1.git] / board / gth2 / ee_access.c
1 /* Module for handling DALLAS DS2438, smart battery monitor
2    Chip can store up to 40 bytes of user data in EEPROM,
3    perform temp, voltage and current measurements.
4    Chip also contains a unique serial number.
5
6    Always read/write LSb first
7
8    For documentaion, see data sheet for DS2438, 2438.pdf
9
10    By Thomas.Lange@corelatus.com 001025
11
12    Copyright (C) 2000-2005 Corelatus AB */
13
14 /* This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 #include <common.h>
31 #include <command.h>
32 #include <asm/au1x00.h>
33 #include <asm/io.h>
34 #include "ee_dev.h"
35 #include "ee_access.h"
36
37 /* static int Debug = 1; */
38 #undef E_DEBUG
39 #define E_DEBUG(fmt,args...) /* */
40 /* #define E_DEBUG(fmt,args...) printk("EEA:"fmt,##args); */
41
42 /* We dont have kernel functions */
43 #define printk printf
44 #define KERN_DEBUG
45 #define KERN_ERR
46 #define EIO 1
47
48 #ifndef TRUE
49 #define TRUE 1
50 #endif
51 #ifndef FALSE
52 #define FALSE 0
53 #endif
54
55 /* lookup table ripped from DS app note 17, understanding and using cyclic redundancy checks... */
56
57 static u8 crc_lookup[256] = {
58         0,      94,     188,    226,    97,     63,     221,    131,
59         194,    156,    126,    32,     163,    253,    31,     65,
60         157,    195,    33,     127,    252,    162,    64,     30,
61         95,     1,      227,    189,    62,     96,     130,    220,
62         35,     125,    159,    193,    66,     28,     254,    160,
63         225,    191,    93,     3,      128,    222,    60,     98,
64         190,    224,    2,      92,     223,    129,    99,     61,
65         124,    34,     192,    158,    29,     67,     161,    255,
66         70,     24,     250,    164,    39,     121,    155,    197,
67         132,    218,    56,     102,    229,    187,    89,     7,
68         219,    133,    103,    57,     186,    228,    6,      88,
69         25,     71,     165,    251,    120,    38,     196,    154,
70         101,    59,     217,    135,    4,      90,     184,    230,
71         167,    249,    27,     69,     198,    152,    122,    36,
72         248,    166,    68,     26,     153,    199,    37,     123,
73         58,     100,    134,    216,    91,     5,      231,    185,
74         140,    210,    48,     110,    237,    179,    81,     15,
75         78,     16,     242,    172,    47,     113,    147,    205,
76         17,     79,     173,    243,    112,    46,     204,    146,
77         211,    141,    111,    49,     178,    236,    14,     80,
78         175,    241,    19,     77,     206,    144,    114,    44,
79         109,    51,     209,    143,    12,     82,     176,    238,
80         50,     108,    142,    208,    83,     13,     239,    177,
81         240,    174,    76,     18,     145,    207,    45,     115,
82         202,    148,    118,    40,     171,    245,    23,     73,
83         8,      86,     180,    234,    105,    55,     213,    139,
84         87,     9,      235,    181,    54,     104,    138,    212,
85         149,    203,    41,     119,    244,    170,    72,     22,
86         233,    183,    85,     11,     136,    214,    52,     106,
87         43,     117,    151,    201,    74,     20,     246,    168,
88         116,    42,     200,    150,    21,     75,     169,    247,
89         182,    232,    10,     84,     215,    137,    107,    53
90 };
91
92 static void
93 write_gpio_data(int value ){
94         if(value){
95                 /* Tristate */
96                 gpio_tristate(GPIO_EEDQ);
97         }
98         else{
99                 /* Drive 0 */
100                 gpio_clear(GPIO_EEDQ);
101         }
102 }
103
104 static u8 make_new_crc( u8 Old_crc, u8 New_value ){
105         /* Compute a new checksum with new byte, using previous checksum as input
106            See DS app note 17, understanding and using cyclic redundancy checks...
107            Also see DS2438, page 11 */
108         return( crc_lookup[Old_crc ^ New_value ]);
109 }
110
111 int ee_crc_ok( u8 *Buffer, int Len, u8 Crc ){
112         /* Check if the checksum for this buffer is correct */
113         u8 Curr_crc=0;
114         int i;
115         u8 *Curr_byte = Buffer;
116
117         for(i=0;i<Len;i++){
118                 Curr_crc = make_new_crc( Curr_crc, *Curr_byte);
119                 Curr_byte++;
120         }
121         E_DEBUG("Calculated CRC = 0x%x, read = 0x%x\n", Curr_crc, Crc);
122
123         if(Curr_crc == Crc){
124                 /* Good */
125                 return(TRUE);
126         }
127         printk(KERN_ERR"EE checksum error, Calculated CRC = 0x%x, read = 0x%x\n", Curr_crc, Crc);
128         return(FALSE);
129 }
130
131 static void
132 set_idle(void){
133         /* Send idle and keep start time
134            Continous 1 is idle */
135         WRITE_PORT(1);
136 }
137
138
139 static int
140 do_cpu_reset(void){
141         /* Release reset and verify that chip responds with presence pulse */
142         int Retries=0;
143         while(Retries<15){
144                 udelay(RESET_LOW_TIME);
145
146                 /* Send reset */
147                 WRITE_PORT(0);
148                 udelay(RESET_LOW_TIME);
149
150                 /* Release reset */
151                 WRITE_PORT(1);
152
153                 /* Wait for EEPROM to drive output */
154                 udelay(PRESENCE_TIMEOUT);
155                 if(!READ_PORT){
156                         /* Ok, EEPROM is driving a 0 */
157                         E_DEBUG("Presence detected\n");
158                         if(Retries){
159                                 E_DEBUG("Retries %d\n",Retries);
160                         }
161                         /* Make sure chip releases pin */
162                         udelay(PRESENCE_LOW_TIME);
163                         return 0;
164                 }
165                 Retries++;
166         }
167
168         printk(KERN_ERR"eeprom did not respond when releasing reset\n");
169
170         /* Make sure chip releases pin */
171         udelay(PRESENCE_LOW_TIME);
172
173         /* Set to idle again */
174         set_idle();
175
176         return(-EIO);
177 }
178
179 static u8
180 read_cpu_byte(void){
181         /* Read a single byte from EEPROM
182            Read LSb first */
183         int i;
184         int Value;
185         u8 Result=0;
186         u32 Flags;
187
188         E_DEBUG("Reading byte\n");
189
190         for(i=0;i<8;i++){
191                 /* Small delay between pulses */
192                 udelay(1);
193
194 #ifdef __KERNEL__
195                 /* Disable irq */
196                 save_flags(Flags);
197                 cli();
198 #endif
199
200                 /* Pull down pin short time to start read
201                    See page 26 in data sheet */
202
203                 WRITE_PORT(0);
204                 udelay(READ_LOW);
205                 WRITE_PORT(1);
206
207                 /* Wait for chip to drive pin */
208                 udelay(READ_TIMEOUT);
209
210                 Value = READ_PORT;
211                 if(Value)
212                         Value=1;
213
214 #ifdef __KERNEL__
215                 /* Enable irq */
216                 restore_flags(Flags);
217 #endif
218
219                 /* Wait for chip to release pin */
220                 udelay(TOTAL_READ_LOW-READ_TIMEOUT);
221
222                 /* LSb first */
223                 Result|=Value<<i;
224                 /* E_DEBUG("Read %d\n",Value); */
225
226         }
227
228         E_DEBUG("Read byte 0x%x\n",Result);
229
230         return(Result);
231 }
232
233 static void
234 write_cpu_byte(u8 Byte){
235         /* Write a single byte to EEPROM
236            Write LSb first */
237         int i;
238         int Value;
239         u32 Flags;
240
241         E_DEBUG("Writing byte 0x%x\n",Byte);
242
243         for(i=0;i<8;i++){
244                 /* Small delay between pulses */
245                 udelay(1);
246                 Value = Byte&1;
247
248 #ifdef __KERNEL__
249                 /* Disable irq */
250                 save_flags(Flags);
251                 cli();
252 #endif
253
254                 /* Pull down pin short time for a 1, long time for a 0
255                    See page 26 in data sheet */
256
257                 WRITE_PORT(0);
258                 if(Value){
259                         /* Write a 1 */
260                         udelay(WRITE_1_LOW);
261                 }
262                 else{
263                         /* Write a 0 */
264                         udelay(WRITE_0_LOW);
265                 }
266
267                 WRITE_PORT(1);
268
269 #ifdef __KERNEL__
270                 /* Enable irq */
271                 restore_flags(Flags);
272 #endif
273
274                 if(Value)
275                         /* Wait for chip to read the 1 */
276                         udelay(TOTAL_WRITE_LOW-WRITE_1_LOW);
277
278                 /* E_DEBUG("Wrote %d\n",Value); */
279                 Byte>>=1;
280         }
281 }
282
283 int ee_do_cpu_command( u8 *Tx, int Tx_len, u8 *Rx, int Rx_len, int Send_skip ){
284         /* Execute this command string, including
285            giving reset and setting to idle after command
286            if Rx_len is set, we read out data from EEPROM */
287         int i;
288
289         E_DEBUG("Command, Tx_len %d, Rx_len %d\n", Tx_len, Rx_len );
290
291         if(do_cpu_reset()){
292                 /* Failed! */
293                 return(-EIO);
294         }
295
296         if(Send_skip)
297                 /* Always send SKIP_ROM first to tell chip we are sending a command,
298                    except when we read out rom data for chip */
299                 write_cpu_byte(SKIP_ROM);
300
301         /* Always have Tx data */
302         for(i=0;i<Tx_len;i++){
303                 write_cpu_byte(Tx[i]);
304         }
305
306         if(Rx_len){
307                 for(i=0;i<Rx_len;i++){
308                         Rx[i]=read_cpu_byte();
309                 }
310         }
311
312         set_idle();
313
314         E_DEBUG("Command done\n");
315
316         return(0);
317 }
318
319 int ee_init_cpu_data(void){
320         int i;
321         u8 Tx[10];
322
323         /* Leave it floting since altera is driving the same pin */
324         set_idle();
325
326         /* Copy all User EEPROM data to scratchpad */
327         for(i=0;i<USER_PAGES;i++){
328                 Tx[0]=RECALL_MEMORY;
329                 Tx[1]=EE_USER_PAGE_0+i;
330                 if(ee_do_cpu_command(Tx,2,NULL,0,TRUE)) return(-EIO);
331         }
332
333         /* Make sure chip doesnt store measurements in NVRAM */
334         Tx[0]=WRITE_SCRATCHPAD;
335         Tx[1]=0; /* Page */
336         Tx[2]=9;
337         if(ee_do_cpu_command(Tx,3,NULL,0,TRUE)) return(-EIO);
338
339         Tx[0]=COPY_SCRATCHPAD;
340         if(ee_do_cpu_command(Tx,2,NULL,0,TRUE)) return(-EIO);
341
342         for(i=0;i<10;i++){
343                 udelay(1000);
344         }
345
346         return(0);
347 }