~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/cris/arch-v10/drivers/eeprom.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.10 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.83 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.153 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.200 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.200 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.76 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*!*****************************************************************************
  2 *!
  3 *!  Implements an interface for i2c compatible eeproms to run under Linux.
  4 *!  Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustments by
  5 *!  Johan.Adolfsson@axis.com
  6 *!
  7 *!  Probing results:
  8 *!    8k or not is detected (the assumes 2k or 16k)
  9 *!    2k or 16k detected using test reads and writes.
 10 *!
 11 *!------------------------------------------------------------------------
 12 *!  HISTORY
 13 *!
 14 *!  DATE          NAME              CHANGES
 15 *!  ----          ----              -------
 16 *!  Aug  28 1999  Edgar Iglesias    Initial Version
 17 *!  Aug  31 1999  Edgar Iglesias    Allow simultaneous users.
 18 *!  Sep  03 1999  Edgar Iglesias    Updated probe.
 19 *!  Sep  03 1999  Edgar Iglesias    Added bail-out stuff if we get interrupted
 20 *!                                  in the spin-lock.
 21 *!
 22 *!        (c) 1999 Axis Communications AB, Lund, Sweden
 23 *!*****************************************************************************/
 24 
 25 #include <linux/kernel.h>
 26 #include <linux/sched.h>
 27 #include <linux/fs.h>
 28 #include <linux/init.h>
 29 #include <linux/delay.h>
 30 #include <linux/interrupt.h>
 31 #include <linux/wait.h>
 32 #include <asm/uaccess.h>
 33 #include "i2c.h"
 34 
 35 #define D(x)
 36 
 37 /* If we should use adaptive timing or not: */
 38 /* #define EEPROM_ADAPTIVE_TIMING */
 39 
 40 #define EEPROM_MAJOR_NR 122  /* use a LOCAL/EXPERIMENTAL major for now */
 41 #define EEPROM_MINOR_NR 0
 42 
 43 /* Empirical sane initial value of the delay, the value will be adapted to
 44  * what the chip needs when using EEPROM_ADAPTIVE_TIMING.
 45  */
 46 #define INITIAL_WRITEDELAY_US 4000
 47 #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */
 48 
 49 /* This one defines how many times to try when eeprom fails. */
 50 #define EEPROM_RETRIES 10
 51 
 52 #define EEPROM_2KB (2 * 1024)
 53 /*#define EEPROM_4KB (4 * 1024)*/ /* Exists but not used in Axis products */
 54 #define EEPROM_8KB (8 * 1024 - 1 ) /* Last byte has write protection bit */
 55 #define EEPROM_16KB (16 * 1024)
 56 
 57 #define i2c_delay(x) udelay(x)
 58 
 59 /*
 60  *  This structure describes the attached eeprom chip.
 61  *  The values are probed for.
 62  */
 63 
 64 struct eeprom_type
 65 {
 66   unsigned long size;
 67   unsigned long sequential_write_pagesize;
 68   unsigned char select_cmd;
 69   unsigned long usec_delay_writecycles; /* Min time between write cycles
 70                                            (up to 10ms for some models) */
 71   unsigned long usec_delay_step; /* For adaptive algorithm */
 72   int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */
 73   
 74   /* this one is to keep the read/write operations atomic */
 75   struct mutex lock;
 76   int retry_cnt_addr; /* Used to keep track of number of retries for
 77                          adaptive timing adjustments */
 78   int retry_cnt_read;
 79 };
 80 
 81 static int  eeprom_open(struct inode * inode, struct file * file);
 82 static loff_t  eeprom_lseek(struct file * file, loff_t offset, int orig);
 83 static ssize_t  eeprom_read(struct file * file, char * buf, size_t count,
 84                             loff_t *off);
 85 static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count,
 86                              loff_t *off);
 87 static int eeprom_close(struct inode * inode, struct file * file);
 88 
 89 static int  eeprom_address(unsigned long addr);
 90 static int  read_from_eeprom(char * buf, int count);
 91 static int eeprom_write_buf(loff_t addr, const char * buf, int count);
 92 static int eeprom_read_buf(loff_t addr, char * buf, int count);
 93 
 94 static void eeprom_disable_write_protect(void);
 95 
 96 
 97 static const char eeprom_name[] = "eeprom";
 98 
 99 /* chip description */
100 static struct eeprom_type eeprom;
101 
102 /* This is the exported file-operations structure for this device. */
103 const struct file_operations eeprom_fops =
104 {
105   .llseek  = eeprom_lseek,
106   .read    = eeprom_read,
107   .write   = eeprom_write,
108   .open    = eeprom_open,
109   .release = eeprom_close
110 };
111 
112 /* eeprom init call. Probes for different eeprom models. */
113 
114 int __init eeprom_init(void)
115 {
116   mutex_init(&eeprom.lock);
117 
118 #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE
119 #define EETEXT "Found"
120 #else
121 #define EETEXT "Assuming"
122 #endif
123   if (register_chrdev(EEPROM_MAJOR_NR, eeprom_name, &eeprom_fops))
124   {
125     printk(KERN_INFO "%s: unable to get major %d for eeprom device\n",
126            eeprom_name, EEPROM_MAJOR_NR);
127     return -1;
128   }
129   
130   printk("EEPROM char device v0.3, (c) 2000 Axis Communications AB\n");
131 
132   /*
133    *  Note: Most of this probing method was taken from the printserver (5470e)
134    *        codebase. It did not contain a way of finding the 16kB chips
135    *        (M24128 or variants). The method used here might not work
136    *        for all models. If you encounter problems the easiest way
137    *        is probably to define your model within #ifdef's, and hard-
138    *        code it.
139    */
140 
141   eeprom.size = 0;
142   eeprom.usec_delay_writecycles = INITIAL_WRITEDELAY_US;
143   eeprom.usec_delay_step = 128;
144   eeprom.adapt_state = 0;
145   
146 #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE
147   i2c_start();
148   i2c_outbyte(0x80);
149   if(!i2c_getack())
150   {
151     /* It's not 8k.. */
152     int success = 0;
153     unsigned char buf_2k_start[16];
154     
155     /* Im not sure this will work... :) */
156     /* assume 2kB, if failure go for 16kB */
157     /* Test with 16kB settings.. */
158     /* If it's a 2kB EEPROM and we address it outside it's range
159      * it will mirror the address space:
160      * 1. We read two locations (that are mirrored), 
161      *    if the content differs * it's a 16kB EEPROM.
162      * 2. if it doesn't differ - write different value to one of the locations,
163      *    check the other - if content still is the same it's a 2k EEPROM,
164      *    restore original data.
165      */
166 #define LOC1 8
167 #define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */
168 
169    /* 2k settings */  
170     i2c_stop();
171     eeprom.size = EEPROM_2KB;
172     eeprom.select_cmd = 0xA0;   
173     eeprom.sequential_write_pagesize = 16;
174     if( eeprom_read_buf( 0, buf_2k_start, 16 ) == 16 )
175     {
176       D(printk("2k start: '%16.16s'\n", buf_2k_start));
177     }
178     else
179     {
180       printk(KERN_INFO "%s: Failed to read in 2k mode!\n", eeprom_name);  
181     }
182     
183     /* 16k settings */
184     eeprom.size = EEPROM_16KB;
185     eeprom.select_cmd = 0xA0;   
186     eeprom.sequential_write_pagesize = 64;
187 
188     {
189       unsigned char loc1[4], loc2[4], tmp[4];
190       if( eeprom_read_buf(LOC2, loc2, 4) == 4)
191       {
192         if( eeprom_read_buf(LOC1, loc1, 4) == 4)
193         {
194           D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
195                    LOC1, loc1, LOC2, loc2));
196 #if 0
197           if (memcmp(loc1, loc2, 4) != 0 )
198           {
199             /* It's 16k */
200             printk(KERN_INFO "%s: 16k detected in step 1\n", eeprom_name);
201             eeprom.size = EEPROM_16KB;     
202             success = 1;
203           }
204           else
205 #endif
206           {
207             /* Do step 2 check */
208             /* Invert value */
209             loc1[0] = ~loc1[0];
210             if (eeprom_write_buf(LOC1, loc1, 1) == 1)
211             {
212               /* If 2k EEPROM this write will actually write 10 bytes
213                * from pos 0
214                */
215               D(printk("1 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
216                        LOC1, loc1, LOC2, loc2));
217               if( eeprom_read_buf(LOC1, tmp, 4) == 4)
218               {
219                 D(printk("2 loc1: (%i) '%4.4s' tmp '%4.4s'\n", 
220                          LOC1, loc1, tmp));
221                 if (memcmp(loc1, tmp, 4) != 0 )
222                 {
223                   printk(KERN_INFO "%s: read and write differs! Not 16kB\n",
224                          eeprom_name);
225                   loc1[0] = ~loc1[0];
226                   
227                   if (eeprom_write_buf(LOC1, loc1, 1) == 1)
228                   {
229                     success = 1;
230                   }
231                   else
232                   {
233                     printk(KERN_INFO "%s: Restore 2k failed during probe,"
234                            " EEPROM might be corrupt!\n", eeprom_name);
235                     
236                   }
237                   i2c_stop();
238                   /* Go to 2k mode and write original data */
239                   eeprom.size = EEPROM_2KB;
240                   eeprom.select_cmd = 0xA0;   
241                   eeprom.sequential_write_pagesize = 16;
242                   if( eeprom_write_buf(0, buf_2k_start, 16) == 16)
243                   {
244                   }
245                   else
246                   {
247                     printk(KERN_INFO "%s: Failed to write back 2k start!\n",
248                            eeprom_name);
249                   }
250                   
251                   eeprom.size = EEPROM_2KB;
252                 }
253               }
254                 
255               if(!success)
256               {
257                 if( eeprom_read_buf(LOC2, loc2, 1) == 1)
258                 {
259                   D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
260                            LOC1, loc1, LOC2, loc2));
261                   if (memcmp(loc1, loc2, 4) == 0 )
262                   {
263                     /* Data the same, must be mirrored -> 2k */
264                     /* Restore data */
265                     printk(KERN_INFO "%s: 2k detected in step 2\n", eeprom_name);
266                     loc1[0] = ~loc1[0];
267                     if (eeprom_write_buf(LOC1, loc1, 1) == 1)
268                     {
269                       success = 1;
270                     }
271                     else
272                     {
273                       printk(KERN_INFO "%s: Restore 2k failed during probe,"
274                              " EEPROM might be corrupt!\n", eeprom_name);
275                       
276                     }
277                     
278                     eeprom.size = EEPROM_2KB;     
279                   }
280                   else
281                   {
282                     printk(KERN_INFO "%s: 16k detected in step 2\n",
283                            eeprom_name);
284                     loc1[0] = ~loc1[0];
285                     /* Data differs, assume 16k */
286                     /* Restore data */
287                     if (eeprom_write_buf(LOC1, loc1, 1) == 1)
288                     {
289                       success = 1;
290                     }
291                     else
292                     {
293                       printk(KERN_INFO "%s: Restore 16k failed during probe,"
294                              " EEPROM might be corrupt!\n", eeprom_name);
295                     }
296                     
297                     eeprom.size = EEPROM_16KB;
298                   }
299                 }
300               }
301             }
302           } /* read LOC1 */
303         } /* address LOC1 */
304         if (!success)
305         {
306           printk(KERN_INFO "%s: Probing failed!, using 2KB!\n", eeprom_name);
307           eeprom.size = EEPROM_2KB;               
308         }
309       } /* read */
310     }
311   }
312   else
313   {
314     i2c_outbyte(0x00);
315     if(!i2c_getack())
316     {
317       /* No 8k */
318       eeprom.size = EEPROM_2KB;
319     }
320     else
321     {
322       i2c_start();
323       i2c_outbyte(0x81);
324       if (!i2c_getack())
325       {
326         eeprom.size = EEPROM_2KB;
327       }
328       else
329       {
330         /* It's a 8kB */
331         i2c_inbyte();
332         eeprom.size = EEPROM_8KB;
333       }
334     }
335   }
336   i2c_stop();
337 #elif defined(CONFIG_ETRAX_I2C_EEPROM_16KB)
338   eeprom.size = EEPROM_16KB;
339 #elif defined(CONFIG_ETRAX_I2C_EEPROM_8KB)
340   eeprom.size = EEPROM_8KB;
341 #elif defined(CONFIG_ETRAX_I2C_EEPROM_2KB)
342   eeprom.size = EEPROM_2KB;
343 #endif
344 
345   switch(eeprom.size)
346   {
347    case (EEPROM_2KB):
348      printk("%s: " EETEXT " i2c compatible 2kB eeprom.\n", eeprom_name);
349      eeprom.sequential_write_pagesize = 16;
350      eeprom.select_cmd = 0xA0;
351      break;
352    case (EEPROM_8KB):
353      printk("%s: " EETEXT " i2c compatible 8kB eeprom.\n", eeprom_name);
354      eeprom.sequential_write_pagesize = 16;
355      eeprom.select_cmd = 0x80;
356      break;
357    case (EEPROM_16KB):
358      printk("%s: " EETEXT " i2c compatible 16kB eeprom.\n", eeprom_name);
359      eeprom.sequential_write_pagesize = 64;
360      eeprom.select_cmd = 0xA0;     
361      break;
362    default:
363      eeprom.size = 0;
364      printk("%s: Did not find a supported eeprom\n", eeprom_name);
365      break;
366   }
367 
368   
369 
370   eeprom_disable_write_protect();
371 
372   return 0;
373 }
374 
375 /* Opens the device. */
376 static int eeprom_open(struct inode * inode, struct file * file)
377 {
378   if(iminor(inode) != EEPROM_MINOR_NR)
379      return -ENXIO;
380   if(imajor(inode) != EEPROM_MAJOR_NR)
381      return -ENXIO;
382 
383   if( eeprom.size > 0 )
384   {
385     /* OK */
386     return 0;
387   }
388 
389   /* No EEprom found */
390   return -EFAULT;
391 }
392 
393 /* Changes the current file position. */
394 
395 static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
396 {
397 /*
398  *  orig 0: position from begning of eeprom
399  *  orig 1: relative from current position
400  *  orig 2: position from last eeprom address
401  */
402   
403   switch (orig)
404   {
405    case 0:
406      file->f_pos = offset;
407      break;
408    case 1:
409      file->f_pos += offset;
410      break;
411    case 2:
412      file->f_pos = eeprom.size - offset;
413      break;
414    default:
415      return -EINVAL;
416   }
417 
418   /* truncate position */
419   if (file->f_pos < 0)
420   {
421     file->f_pos = 0;    
422     return(-EOVERFLOW);
423   }
424   
425   if (file->f_pos >= eeprom.size)
426   {
427     file->f_pos = eeprom.size - 1;
428     return(-EOVERFLOW);
429   }
430 
431   return ( file->f_pos );
432 }
433 
434 /* Reads data from eeprom. */
435 
436 static int eeprom_read_buf(loff_t addr, char * buf, int count)
437 {
438   return eeprom_read(NULL, buf, count, &addr);
439 }
440 
441 
442 
443 /* Reads data from eeprom. */
444 
445 static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
446 {
447   int read=0;
448   unsigned long p = *off;
449 
450   unsigned char page;
451 
452   if(p >= eeprom.size)  /* Address i 0 - (size-1) */
453   {
454     return -EFAULT;
455   }
456   
457   if (mutex_lock_interruptible(&eeprom.lock))
458     return -EINTR;
459 
460   page = (unsigned char) (p >> 8);
461   
462   if(!eeprom_address(p))
463   {
464     printk(KERN_INFO "%s: Read failed to address the eeprom: "
465            "0x%08X (%i) page: %i\n", eeprom_name, (int)p, (int)p, page);
466     i2c_stop();
467     
468     /* don't forget to wake them up */
469     mutex_unlock(&eeprom.lock);
470     return -EFAULT;
471   }
472 
473   if( (p + count) > eeprom.size)
474   {
475     /* truncate count */
476     count = eeprom.size - p;
477   }
478 
479   /* stop dummy write op and initiate the read op */
480   i2c_start();
481 
482   /* special case for small eeproms */
483   if(eeprom.size < EEPROM_16KB)
484   {
485     i2c_outbyte( eeprom.select_cmd | 1 | (page << 1) );
486   }
487 
488   /* go on with the actual read */
489   read = read_from_eeprom( buf, count);
490   
491   if(read > 0)
492   {
493     *off += read;
494   }
495 
496   mutex_unlock(&eeprom.lock);
497   return read;
498 }
499 
500 /* Writes data to eeprom. */
501 
502 static int eeprom_write_buf(loff_t addr, const char * buf, int count)
503 {
504   return eeprom_write(NULL, buf, count, &addr);
505 }
506 
507 
508 /* Writes data to eeprom. */
509 
510 static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
511                             loff_t *off)
512 {
513   int i, written, restart=1;
514   unsigned long p;
515 
516   if (!access_ok(VERIFY_READ, buf, count))
517   {
518     return -EFAULT;
519   }
520 
521   /* bail out if we get interrupted */
522   if (mutex_lock_interruptible(&eeprom.lock))
523     return -EINTR;
524   for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++)
525   {
526     restart = 0;
527     written = 0;
528     p = *off;
529    
530     
531     while( (written < count) && (p < eeprom.size))
532     {
533       /* address the eeprom */
534       if(!eeprom_address(p))
535       {
536         printk(KERN_INFO "%s: Write failed to address the eeprom: "
537                "0x%08X (%i) \n", eeprom_name, (int)p, (int)p);
538         i2c_stop();
539         
540         /* don't forget to wake them up */
541         mutex_unlock(&eeprom.lock);
542         return -EFAULT;
543       }
544 #ifdef EEPROM_ADAPTIVE_TIMING      
545       /* Adaptive algorithm to adjust timing */
546       if (eeprom.retry_cnt_addr > 0)
547       {
548         /* To Low now */
549         D(printk(">D=%i d=%i\n",
550                eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
551 
552         if (eeprom.usec_delay_step < 4)
553         {
554           eeprom.usec_delay_step++;
555           eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
556         }
557         else
558         {
559 
560           if (eeprom.adapt_state > 0)
561           {
562             /* To Low before */
563             eeprom.usec_delay_step *= 2;
564             if (eeprom.usec_delay_step > 2)
565             {
566               eeprom.usec_delay_step--;
567             }
568             eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
569           }
570           else if (eeprom.adapt_state < 0)
571           {
572             /* To High before (toggle dir) */
573             eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
574             if (eeprom.usec_delay_step > 1)
575             {
576               eeprom.usec_delay_step /= 2;
577               eeprom.usec_delay_step--;
578             }
579           }
580         }
581 
582         eeprom.adapt_state = 1;
583       }
584       else
585       {
586         /* To High (or good) now */
587         D(printk("<D=%i d=%i\n",
588                eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
589         
590         if (eeprom.adapt_state < 0)
591         {
592           /* To High before */
593           if (eeprom.usec_delay_step > 1)
594           {
595             eeprom.usec_delay_step *= 2;
596             eeprom.usec_delay_step--;
597             
598             if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
599             {
600               eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
601             }
602           }
603         }
604         else if (eeprom.adapt_state > 0)
605         {
606           /* To Low before (toggle dir) */
607           if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
608           {
609             eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
610           }
611           if (eeprom.usec_delay_step > 1)
612           {
613             eeprom.usec_delay_step /= 2;
614             eeprom.usec_delay_step--;
615           }
616           
617           eeprom.adapt_state = -1;
618         }
619 
620         if (eeprom.adapt_state > -100)
621         {
622           eeprom.adapt_state--;
623         }
624         else
625         {
626           /* Restart adaption */
627           D(printk("#Restart\n"));
628           eeprom.usec_delay_step++;
629         }
630       }
631 #endif /* EEPROM_ADAPTIVE_TIMING */
632       /* write until we hit a page boundary or count */
633       do
634       {
635         i2c_outbyte(buf[written]);        
636         if(!i2c_getack())
637         {
638           restart=1;
639           printk(KERN_INFO "%s: write error, retrying. %d\n", eeprom_name, i);
640           i2c_stop();
641           break;
642         }
643         written++;
644         p++;        
645       } while( written < count && ( p % eeprom.sequential_write_pagesize ));
646 
647       /* end write cycle */
648       i2c_stop();
649       i2c_delay(eeprom.usec_delay_writecycles);
650     } /* while */
651   } /* for  */
652 
653   mutex_unlock(&eeprom.lock);
654   if (written == 0 && p >= eeprom.size){
655     return -ENOSPC;
656   }
657   *off = p;
658   return written;
659 }
660 
661 /* Closes the device. */
662 
663 static int eeprom_close(struct inode * inode, struct file * file)
664 {
665   /* do nothing for now */
666   return 0;
667 }
668 
669 /* Sets the current address of the eeprom. */
670 
671 static int eeprom_address(unsigned long addr)
672 {
673   int i;
674   unsigned char page, offset;
675 
676   page   = (unsigned char) (addr >> 8);
677   offset = (unsigned char)  addr;
678 
679   for(i = 0; i < EEPROM_RETRIES; i++)
680   {
681     /* start a dummy write for addressing */
682     i2c_start();
683 
684     if(eeprom.size == EEPROM_16KB)
685     {
686       i2c_outbyte( eeprom.select_cmd ); 
687       i2c_getack();
688       i2c_outbyte(page); 
689     }
690     else
691     {
692       i2c_outbyte( eeprom.select_cmd | (page << 1) ); 
693     }
694     if(!i2c_getack())
695     {
696       /* retry */
697       i2c_stop();
698       /* Must have a delay here.. 500 works, >50, 100->works 5th time*/
699       i2c_delay(MAX_WRITEDELAY_US / EEPROM_RETRIES * i);
700       /* The chip needs up to 10 ms from write stop to next start */
701      
702     }
703     else
704     {
705       i2c_outbyte(offset);
706       
707       if(!i2c_getack())
708       {
709         /* retry */
710         i2c_stop();
711       }
712       else
713         break;
714     }
715   }    
716 
717   
718   eeprom.retry_cnt_addr = i;
719   D(printk("%i\n", eeprom.retry_cnt_addr));
720   if(eeprom.retry_cnt_addr == EEPROM_RETRIES)
721   {
722     /* failed */
723     return 0;
724   }
725   return 1;
726 }
727 
728 /* Reads from current address. */
729 
730 static int read_from_eeprom(char * buf, int count)
731 {
732   int i, read=0;
733 
734   for(i = 0; i < EEPROM_RETRIES; i++)
735   {    
736     if(eeprom.size == EEPROM_16KB)
737     {
738       i2c_outbyte( eeprom.select_cmd | 1 );
739     }
740 
741     if(i2c_getack())
742     {
743       break;
744     }
745   }
746   
747   if(i == EEPROM_RETRIES)
748   {
749     printk(KERN_INFO "%s: failed to read from eeprom\n", eeprom_name);
750     i2c_stop();
751     
752     return -EFAULT;
753   }
754 
755   while( (read < count))
756   {    
757     if (put_user(i2c_inbyte(), &buf[read++]))
758     {
759       i2c_stop();
760 
761       return -EFAULT;
762     }
763 
764     /*
765      *  make sure we don't ack last byte or you will get very strange
766      *  results!
767      */
768     if(read < count)
769     {
770       i2c_sendack();
771     }
772   }
773 
774   /* stop the operation */
775   i2c_stop();
776 
777   return read;
778 }
779 
780 /* Disables write protection if applicable. */
781 
782 #define DBP_SAVE(x)
783 #define ax_printf printk
784 static void eeprom_disable_write_protect(void)
785 {
786   /* Disable write protect */
787   if (eeprom.size == EEPROM_8KB)
788   {
789     /* Step 1 Set WEL = 1 (write 00000010 to address 1FFFh */
790     i2c_start();
791     i2c_outbyte(0xbe);
792     if(!i2c_getack())
793     {
794       DBP_SAVE(ax_printf("Get ack returns false\n"));
795     }
796     i2c_outbyte(0xFF);
797     if(!i2c_getack())
798     {
799       DBP_SAVE(ax_printf("Get ack returns false 2\n"));
800     }
801     i2c_outbyte(0x02);
802     if(!i2c_getack())
803     {
804       DBP_SAVE(ax_printf("Get ack returns false 3\n"));
805     }
806     i2c_stop();
807 
808     i2c_delay(1000);
809 
810     /* Step 2 Set RWEL = 1 (write 00000110 to address 1FFFh */
811     i2c_start();
812     i2c_outbyte(0xbe);
813     if(!i2c_getack())
814     {
815       DBP_SAVE(ax_printf("Get ack returns false 55\n"));
816     }
817     i2c_outbyte(0xFF);
818     if(!i2c_getack())
819     {
820       DBP_SAVE(ax_printf("Get ack returns false 52\n"));
821     }
822     i2c_outbyte(0x06);
823     if(!i2c_getack())
824     {
825       DBP_SAVE(ax_printf("Get ack returns false 53\n"));
826     }
827     i2c_stop();
828     
829     /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */
830     i2c_start();
831     i2c_outbyte(0xbe);
832     if(!i2c_getack())
833     {
834       DBP_SAVE(ax_printf("Get ack returns false 56\n"));
835     }
836     i2c_outbyte(0xFF);
837     if(!i2c_getack())
838     {
839       DBP_SAVE(ax_printf("Get ack returns false 57\n"));
840     }
841     i2c_outbyte(0x06);
842     if(!i2c_getack())
843     {
844       DBP_SAVE(ax_printf("Get ack returns false 58\n"));
845     }
846     i2c_stop();
847     
848     /* Write protect disabled */
849   }
850 }
851 
852 module_init(eeprom_init);
853 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp