Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | |
42a3b4f2 | 33 | * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are |
1da177e4 LT |
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 | ||
40 | static void delay(int delay) | |
41 | { | |
42 | while (delay--); | |
43 | } | |
44 | ||
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 | ||
59 | static void send_ack(void) | |
60 | { | |
61 | send_bit(0); | |
62 | } | |
63 | ||
64 | static void send_byte(unsigned char byte) | |
65 | { | |
66 | int i = 0; | |
42a3b4f2 RB |
67 | |
68 | for (i = 7; i >= 0; i--) | |
1da177e4 LT |
69 | send_bit((byte >> i) & 0x01); |
70 | } | |
42a3b4f2 | 71 | |
1da177e4 LT |
72 | static void send_start(void) |
73 | { | |
42a3b4f2 | 74 | sda_hi; |
1da177e4 LT |
75 | delay(TXX); |
76 | scl_hi; | |
77 | delay(TXX); | |
78 | sda_lo; | |
79 | delay(TXX); | |
80 | } | |
81 | ||
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 | ||
92 | static void do_idle(void) | |
93 | { | |
94 | sda_hi; | |
95 | scl_hi; | |
96 | vcc_off; | |
97 | } | |
98 | ||
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 | ||
113 | static unsigned char recv_byte(void) { | |
114 | int i; | |
115 | unsigned char byte=0; | |
116 | ||
42a3b4f2 | 117 | for (i=7;i>=0;i--) |
1da177e4 | 118 | byte |= (recv_bit() << i); |
42a3b4f2 | 119 | |
1da177e4 LT |
120 | return byte; |
121 | } | |
122 | ||
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 | */ | |
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 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 | } |