• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/cris/arch-v10/drivers/
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
64struct 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
81static int  eeprom_open(struct inode * inode, struct file * file);
82static loff_t  eeprom_lseek(struct file * file, loff_t offset, int orig);
83static ssize_t  eeprom_read(struct file * file, char * buf, size_t count,
84                            loff_t *off);
85static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count,
86                             loff_t *off);
87static int eeprom_close(struct inode * inode, struct file * file);
88
89static int  eeprom_address(unsigned long addr);
90static int  read_from_eeprom(char * buf, int count);
91static int eeprom_write_buf(loff_t addr, const char * buf, int count);
92static int eeprom_read_buf(loff_t addr, char * buf, int count);
93
94static void eeprom_disable_write_protect(void);
95
96
97static const char eeprom_name[] = "eeprom";
98
99/* chip description */
100static struct eeprom_type eeprom;
101
102/* This is the exported file-operations structure for this device. */
103const 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
114int __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          {
197            /* Do step 2 check */
198            /* Invert value */
199            loc1[0] = ~loc1[0];
200            if (eeprom_write_buf(LOC1, loc1, 1) == 1)
201            {
202              /* If 2k EEPROM this write will actually write 10 bytes
203               * from pos 0
204               */
205              D(printk("1 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n",
206                       LOC1, loc1, LOC2, loc2));
207              if( eeprom_read_buf(LOC1, tmp, 4) == 4)
208              {
209                D(printk("2 loc1: (%i) '%4.4s' tmp '%4.4s'\n",
210                         LOC1, loc1, tmp));
211                if (memcmp(loc1, tmp, 4) != 0 )
212                {
213                  printk(KERN_INFO "%s: read and write differs! Not 16kB\n",
214                         eeprom_name);
215                  loc1[0] = ~loc1[0];
216
217                  if (eeprom_write_buf(LOC1, loc1, 1) == 1)
218                  {
219                    success = 1;
220                  }
221                  else
222                  {
223                    printk(KERN_INFO "%s: Restore 2k failed during probe,"
224                           " EEPROM might be corrupt!\n", eeprom_name);
225
226                  }
227                  i2c_stop();
228                  /* Go to 2k mode and write original data */
229                  eeprom.size = EEPROM_2KB;
230                  eeprom.select_cmd = 0xA0;
231                  eeprom.sequential_write_pagesize = 16;
232                  if( eeprom_write_buf(0, buf_2k_start, 16) == 16)
233                  {
234                  }
235                  else
236                  {
237                    printk(KERN_INFO "%s: Failed to write back 2k start!\n",
238                           eeprom_name);
239                  }
240
241                  eeprom.size = EEPROM_2KB;
242                }
243              }
244
245              if(!success)
246              {
247                if( eeprom_read_buf(LOC2, loc2, 1) == 1)
248                {
249                  D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n",
250                           LOC1, loc1, LOC2, loc2));
251                  if (memcmp(loc1, loc2, 4) == 0 )
252                  {
253                    /* Data the same, must be mirrored -> 2k */
254                    /* Restore data */
255                    printk(KERN_INFO "%s: 2k detected in step 2\n", eeprom_name);
256                    loc1[0] = ~loc1[0];
257                    if (eeprom_write_buf(LOC1, loc1, 1) == 1)
258                    {
259                      success = 1;
260                    }
261                    else
262                    {
263                      printk(KERN_INFO "%s: Restore 2k failed during probe,"
264                             " EEPROM might be corrupt!\n", eeprom_name);
265
266                    }
267
268                    eeprom.size = EEPROM_2KB;
269                  }
270                  else
271                  {
272                    printk(KERN_INFO "%s: 16k detected in step 2\n",
273                           eeprom_name);
274                    loc1[0] = ~loc1[0];
275                    /* Data differs, assume 16k */
276                    /* Restore data */
277                    if (eeprom_write_buf(LOC1, loc1, 1) == 1)
278                    {
279                      success = 1;
280                    }
281                    else
282                    {
283                      printk(KERN_INFO "%s: Restore 16k failed during probe,"
284                             " EEPROM might be corrupt!\n", eeprom_name);
285                    }
286
287                    eeprom.size = EEPROM_16KB;
288                  }
289                }
290              }
291            }
292          } /* read LOC1 */
293        } /* address LOC1 */
294        if (!success)
295        {
296          printk(KERN_INFO "%s: Probing failed!, using 2KB!\n", eeprom_name);
297          eeprom.size = EEPROM_2KB;
298        }
299      } /* read */
300    }
301  }
302  else
303  {
304    i2c_outbyte(0x00);
305    if(!i2c_getack())
306    {
307      /* No 8k */
308      eeprom.size = EEPROM_2KB;
309    }
310    else
311    {
312      i2c_start();
313      i2c_outbyte(0x81);
314      if (!i2c_getack())
315      {
316        eeprom.size = EEPROM_2KB;
317      }
318      else
319      {
320        /* It's a 8kB */
321        i2c_inbyte();
322        eeprom.size = EEPROM_8KB;
323      }
324    }
325  }
326  i2c_stop();
327#elif defined(CONFIG_ETRAX_I2C_EEPROM_16KB)
328  eeprom.size = EEPROM_16KB;
329#elif defined(CONFIG_ETRAX_I2C_EEPROM_8KB)
330  eeprom.size = EEPROM_8KB;
331#elif defined(CONFIG_ETRAX_I2C_EEPROM_2KB)
332  eeprom.size = EEPROM_2KB;
333#endif
334
335  switch(eeprom.size)
336  {
337   case (EEPROM_2KB):
338     printk("%s: " EETEXT " i2c compatible 2kB eeprom.\n", eeprom_name);
339     eeprom.sequential_write_pagesize = 16;
340     eeprom.select_cmd = 0xA0;
341     break;
342   case (EEPROM_8KB):
343     printk("%s: " EETEXT " i2c compatible 8kB eeprom.\n", eeprom_name);
344     eeprom.sequential_write_pagesize = 16;
345     eeprom.select_cmd = 0x80;
346     break;
347   case (EEPROM_16KB):
348     printk("%s: " EETEXT " i2c compatible 16kB eeprom.\n", eeprom_name);
349     eeprom.sequential_write_pagesize = 64;
350     eeprom.select_cmd = 0xA0;
351     break;
352   default:
353     eeprom.size = 0;
354     printk("%s: Did not find a supported eeprom\n", eeprom_name);
355     break;
356  }
357
358
359
360  eeprom_disable_write_protect();
361
362  return 0;
363}
364
365/* Opens the device. */
366static int eeprom_open(struct inode * inode, struct file * file)
367{
368  if(iminor(inode) != EEPROM_MINOR_NR)
369     return -ENXIO;
370  if(imajor(inode) != EEPROM_MAJOR_NR)
371     return -ENXIO;
372
373  if( eeprom.size > 0 )
374  {
375    /* OK */
376    return 0;
377  }
378
379  /* No EEprom found */
380  return -EFAULT;
381}
382
383/* Changes the current file position. */
384
385static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
386{
387/*
388 *  orig 0: position from begning of eeprom
389 *  orig 1: relative from current position
390 *  orig 2: position from last eeprom address
391 */
392
393  switch (orig)
394  {
395   case 0:
396     file->f_pos = offset;
397     break;
398   case 1:
399     file->f_pos += offset;
400     break;
401   case 2:
402     file->f_pos = eeprom.size - offset;
403     break;
404   default:
405     return -EINVAL;
406  }
407
408  /* truncate position */
409  if (file->f_pos < 0)
410  {
411    file->f_pos = 0;
412    return(-EOVERFLOW);
413  }
414
415  if (file->f_pos >= eeprom.size)
416  {
417    file->f_pos = eeprom.size - 1;
418    return(-EOVERFLOW);
419  }
420
421  return ( file->f_pos );
422}
423
424/* Reads data from eeprom. */
425
426static int eeprom_read_buf(loff_t addr, char * buf, int count)
427{
428  return eeprom_read(NULL, buf, count, &addr);
429}
430
431
432
433/* Reads data from eeprom. */
434
435static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
436{
437  int read=0;
438  unsigned long p = *off;
439
440  unsigned char page;
441
442  if(p >= eeprom.size)  /* Address i 0 - (size-1) */
443  {
444    return -EFAULT;
445  }
446
447  if (mutex_lock_interruptible(&eeprom.lock))
448    return -EINTR;
449
450  page = (unsigned char) (p >> 8);
451
452  if(!eeprom_address(p))
453  {
454    printk(KERN_INFO "%s: Read failed to address the eeprom: "
455           "0x%08X (%i) page: %i\n", eeprom_name, (int)p, (int)p, page);
456    i2c_stop();
457
458    /* don't forget to wake them up */
459    mutex_unlock(&eeprom.lock);
460    return -EFAULT;
461  }
462
463  if( (p + count) > eeprom.size)
464  {
465    /* truncate count */
466    count = eeprom.size - p;
467  }
468
469  /* stop dummy write op and initiate the read op */
470  i2c_start();
471
472  /* special case for small eeproms */
473  if(eeprom.size < EEPROM_16KB)
474  {
475    i2c_outbyte( eeprom.select_cmd | 1 | (page << 1) );
476  }
477
478  /* go on with the actual read */
479  read = read_from_eeprom( buf, count);
480
481  if(read > 0)
482  {
483    *off += read;
484  }
485
486  mutex_unlock(&eeprom.lock);
487  return read;
488}
489
490/* Writes data to eeprom. */
491
492static int eeprom_write_buf(loff_t addr, const char * buf, int count)
493{
494  return eeprom_write(NULL, buf, count, &addr);
495}
496
497
498/* Writes data to eeprom. */
499
500static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
501                            loff_t *off)
502{
503  int i, written, restart=1;
504  unsigned long p;
505
506  if (!access_ok(VERIFY_READ, buf, count))
507  {
508    return -EFAULT;
509  }
510
511  /* bail out if we get interrupted */
512  if (mutex_lock_interruptible(&eeprom.lock))
513    return -EINTR;
514  for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++)
515  {
516    restart = 0;
517    written = 0;
518    p = *off;
519
520
521    while( (written < count) && (p < eeprom.size))
522    {
523      /* address the eeprom */
524      if(!eeprom_address(p))
525      {
526        printk(KERN_INFO "%s: Write failed to address the eeprom: "
527               "0x%08X (%i) \n", eeprom_name, (int)p, (int)p);
528        i2c_stop();
529
530        /* don't forget to wake them up */
531        mutex_unlock(&eeprom.lock);
532        return -EFAULT;
533      }
534#ifdef EEPROM_ADAPTIVE_TIMING
535      /* Adaptive algorithm to adjust timing */
536      if (eeprom.retry_cnt_addr > 0)
537      {
538        /* To Low now */
539        D(printk(">D=%i d=%i\n",
540               eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
541
542        if (eeprom.usec_delay_step < 4)
543        {
544          eeprom.usec_delay_step++;
545          eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
546        }
547        else
548        {
549
550          if (eeprom.adapt_state > 0)
551          {
552            /* To Low before */
553            eeprom.usec_delay_step *= 2;
554            if (eeprom.usec_delay_step > 2)
555            {
556              eeprom.usec_delay_step--;
557            }
558            eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
559          }
560          else if (eeprom.adapt_state < 0)
561          {
562            /* To High before (toggle dir) */
563            eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
564            if (eeprom.usec_delay_step > 1)
565            {
566              eeprom.usec_delay_step /= 2;
567              eeprom.usec_delay_step--;
568            }
569          }
570        }
571
572        eeprom.adapt_state = 1;
573      }
574      else
575      {
576        /* To High (or good) now */
577        D(printk("<D=%i d=%i\n",
578               eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
579
580        if (eeprom.adapt_state < 0)
581        {
582          /* To High before */
583          if (eeprom.usec_delay_step > 1)
584          {
585            eeprom.usec_delay_step *= 2;
586            eeprom.usec_delay_step--;
587
588            if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
589            {
590              eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
591            }
592          }
593        }
594        else if (eeprom.adapt_state > 0)
595        {
596          /* To Low before (toggle dir) */
597          if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
598          {
599            eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
600          }
601          if (eeprom.usec_delay_step > 1)
602          {
603            eeprom.usec_delay_step /= 2;
604            eeprom.usec_delay_step--;
605          }
606
607          eeprom.adapt_state = -1;
608        }
609
610        if (eeprom.adapt_state > -100)
611        {
612          eeprom.adapt_state--;
613        }
614        else
615        {
616          /* Restart adaption */
617          D(printk("#Restart\n"));
618          eeprom.usec_delay_step++;
619        }
620      }
621#endif /* EEPROM_ADAPTIVE_TIMING */
622      /* write until we hit a page boundary or count */
623      do
624      {
625        i2c_outbyte(buf[written]);
626        if(!i2c_getack())
627        {
628          restart=1;
629          printk(KERN_INFO "%s: write error, retrying. %d\n", eeprom_name, i);
630          i2c_stop();
631          break;
632        }
633        written++;
634        p++;
635      } while( written < count && ( p % eeprom.sequential_write_pagesize ));
636
637      /* end write cycle */
638      i2c_stop();
639      i2c_delay(eeprom.usec_delay_writecycles);
640    } /* while */
641  } /* for  */
642
643  mutex_unlock(&eeprom.lock);
644  if (written == 0 && p >= eeprom.size){
645    return -ENOSPC;
646  }
647  *off = p;
648  return written;
649}
650
651/* Closes the device. */
652
653static int eeprom_close(struct inode * inode, struct file * file)
654{
655  /* do nothing for now */
656  return 0;
657}
658
659/* Sets the current address of the eeprom. */
660
661static int eeprom_address(unsigned long addr)
662{
663  int i;
664  unsigned char page, offset;
665
666  page   = (unsigned char) (addr >> 8);
667  offset = (unsigned char)  addr;
668
669  for(i = 0; i < EEPROM_RETRIES; i++)
670  {
671    /* start a dummy write for addressing */
672    i2c_start();
673
674    if(eeprom.size == EEPROM_16KB)
675    {
676      i2c_outbyte( eeprom.select_cmd );
677      i2c_getack();
678      i2c_outbyte(page);
679    }
680    else
681    {
682      i2c_outbyte( eeprom.select_cmd | (page << 1) );
683    }
684    if(!i2c_getack())
685    {
686      /* retry */
687      i2c_stop();
688      /* Must have a delay here.. 500 works, >50, 100->works 5th time*/
689      i2c_delay(MAX_WRITEDELAY_US / EEPROM_RETRIES * i);
690      /* The chip needs up to 10 ms from write stop to next start */
691
692    }
693    else
694    {
695      i2c_outbyte(offset);
696
697      if(!i2c_getack())
698      {
699        /* retry */
700        i2c_stop();
701      }
702      else
703        break;
704    }
705  }
706
707
708  eeprom.retry_cnt_addr = i;
709  D(printk("%i\n", eeprom.retry_cnt_addr));
710  if(eeprom.retry_cnt_addr == EEPROM_RETRIES)
711  {
712    /* failed */
713    return 0;
714  }
715  return 1;
716}
717
718/* Reads from current address. */
719
720static int read_from_eeprom(char * buf, int count)
721{
722  int i, read=0;
723
724  for(i = 0; i < EEPROM_RETRIES; i++)
725  {
726    if(eeprom.size == EEPROM_16KB)
727    {
728      i2c_outbyte( eeprom.select_cmd | 1 );
729    }
730
731    if(i2c_getack())
732    {
733      break;
734    }
735  }
736
737  if(i == EEPROM_RETRIES)
738  {
739    printk(KERN_INFO "%s: failed to read from eeprom\n", eeprom_name);
740    i2c_stop();
741
742    return -EFAULT;
743  }
744
745  while( (read < count))
746  {
747    if (put_user(i2c_inbyte(), &buf[read++]))
748    {
749      i2c_stop();
750
751      return -EFAULT;
752    }
753
754    /*
755     *  make sure we don't ack last byte or you will get very strange
756     *  results!
757     */
758    if(read < count)
759    {
760      i2c_sendack();
761    }
762  }
763
764  /* stop the operation */
765  i2c_stop();
766
767  return read;
768}
769
770/* Disables write protection if applicable. */
771
772#define DBP_SAVE(x)
773#define ax_printf printk
774static void eeprom_disable_write_protect(void)
775{
776  /* Disable write protect */
777  if (eeprom.size == EEPROM_8KB)
778  {
779    /* Step 1 Set WEL = 1 (write 00000010 to address 1FFFh */
780    i2c_start();
781    i2c_outbyte(0xbe);
782    if(!i2c_getack())
783    {
784      DBP_SAVE(ax_printf("Get ack returns false\n"));
785    }
786    i2c_outbyte(0xFF);
787    if(!i2c_getack())
788    {
789      DBP_SAVE(ax_printf("Get ack returns false 2\n"));
790    }
791    i2c_outbyte(0x02);
792    if(!i2c_getack())
793    {
794      DBP_SAVE(ax_printf("Get ack returns false 3\n"));
795    }
796    i2c_stop();
797
798    i2c_delay(1000);
799
800    /* Step 2 Set RWEL = 1 (write 00000110 to address 1FFFh */
801    i2c_start();
802    i2c_outbyte(0xbe);
803    if(!i2c_getack())
804    {
805      DBP_SAVE(ax_printf("Get ack returns false 55\n"));
806    }
807    i2c_outbyte(0xFF);
808    if(!i2c_getack())
809    {
810      DBP_SAVE(ax_printf("Get ack returns false 52\n"));
811    }
812    i2c_outbyte(0x06);
813    if(!i2c_getack())
814    {
815      DBP_SAVE(ax_printf("Get ack returns false 53\n"));
816    }
817    i2c_stop();
818
819    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */
820    i2c_start();
821    i2c_outbyte(0xbe);
822    if(!i2c_getack())
823    {
824      DBP_SAVE(ax_printf("Get ack returns false 56\n"));
825    }
826    i2c_outbyte(0xFF);
827    if(!i2c_getack())
828    {
829      DBP_SAVE(ax_printf("Get ack returns false 57\n"));
830    }
831    i2c_outbyte(0x06);
832    if(!i2c_getack())
833    {
834      DBP_SAVE(ax_printf("Get ack returns false 58\n"));
835    }
836    i2c_stop();
837
838    /* Write protect disabled */
839  }
840}
841
842module_init(eeprom_init);
843