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