linux/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2003 PMC-Sierra Inc.
   3 *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
   4 *
   5 *  This program is free software; you can redistribute  it and/or modify it
   6 *  under  the terms of  the GNU General  Public License as published by the
   7 *  Free Software Foundation;  either version 2 of the  License, or (at your
   8 *  option) any later version.
   9 *
  10 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  11 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  12 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  13 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  14 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  16 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  17 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  18 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  19 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20 *
  21 *  You should have received a copy of the  GNU General Public License along
  22 *  with this program; if not, write  to the Free Software Foundation, Inc.,
  23 *  675 Mass Ave, Cambridge, MA 02139, USA.
  24 */
  25
  26/*
  27 * Description:
  28 *
  29 * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
  30 * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
  31 * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are
  32 * expected to have a connectivity from the EEPROM to the serial port. This program does
  33 * __not__ communicate using the I2C protocol
  34 */
  35
  36#include "atmel_read_eeprom.h"
  37
  38static void delay(int delay)
  39{
  40        while (delay--);
  41}
  42
  43static void send_bit(unsigned char bit)
  44{
  45        scl_lo;
  46        delay(TXX);
  47        if (bit)
  48                sda_hi;
  49        else
  50                sda_lo;
  51
  52        delay(TXX);
  53        scl_hi;
  54        delay(TXX);
  55}
  56
  57static void send_ack(void)
  58{
  59        send_bit(0);
  60}
  61
  62static void send_byte(unsigned char byte)
  63{
  64        int     i = 0;
  65
  66        for (i = 7; i >= 0; i--)
  67                send_bit((byte >> i) & 0x01);
  68}
  69
  70static void send_start(void)
  71{
  72        sda_hi;
  73        delay(TXX);
  74        scl_hi;
  75        delay(TXX);
  76        sda_lo;
  77        delay(TXX);
  78}
  79
  80static void send_stop(void)
  81{
  82        sda_lo;
  83        delay(TXX);
  84        scl_hi;
  85        delay(TXX);
  86        sda_hi;
  87        delay(TXX);
  88}
  89
  90static void do_idle(void)
  91{
  92        sda_hi;
  93        scl_hi;
  94        vcc_off;
  95}
  96
  97static int recv_bit(void)
  98{
  99        int     status;
 100
 101        scl_lo;
 102        delay(TXX);
 103        sda_hi;
 104        delay(TXX);
 105        scl_hi;
 106        delay(TXX);
 107
 108        return 1;
 109}
 110
 111static unsigned char recv_byte(void) {
 112        int i;
 113        unsigned char byte=0;
 114
 115        for (i=7;i>=0;i--)
 116                byte |= (recv_bit() << i);
 117
 118        return byte;
 119}
 120
 121static int recv_ack(void)
 122{
 123        unsigned int    ack;
 124
 125        ack = (unsigned int)recv_bit();
 126        scl_lo;
 127
 128        if (ack) {
 129                do_idle();
 130                printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n");
 131                return -1;
 132        }
 133
 134        return ack;
 135}
 136
 137/*
 138 * This function does the actual read of the EEPROM. It needs the buffer into which the
 139 * read data is copied, the size of the EEPROM being read and the buffer size
 140 */
 141int read_eeprom(char *buffer, int eeprom_size, int size)
 142{
 143        int     i = 0, err;
 144
 145        send_start();
 146        send_byte(W_HEADER);
 147        recv_ack();
 148
 149        /* EEPROM with size of more than 2K need two byte addressing */
 150        if (eeprom_size > 2048) {
 151                send_byte(0x00);
 152                recv_ack();
 153        }
 154
 155        send_start();
 156        send_byte(R_HEADER);
 157        err = recv_ack();
 158        if (err == -1)
 159                return err;
 160
 161        for (i = 0; i < size; i++) {
 162                *buffer++ = recv_byte();
 163                send_ack();
 164        }
 165
 166        /* Note : We should do some check if the buffer contains correct information */
 167
 168        send_stop();
 169}
 170