• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
delay(int delay)40 static void delay(int delay)
41 {
42 	while (delay--);
43 }
44 
send_bit(unsigned char bit)45 static 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 
send_ack(void)59 static void send_ack(void)
60 {
61 	send_bit(0);
62 }
63 
send_byte(unsigned char byte)64 static 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 
send_start(void)72 static 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 
send_stop(void)82 static 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 
do_idle(void)92 static void do_idle(void)
93 {
94 	sda_hi;
95 	scl_hi;
96 	vcc_off;
97 }
98 
recv_bit(void)99 static 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 
recv_byte(void)113 static 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 
recv_ack(void)123 static 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  */
read_eeprom(char * buffer,int eeprom_size,int size)143 int 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 than 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