• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/mips/pmc-sierra/yosemite/
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