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