diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/cris/arch-v10/drivers |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/cris/arch-v10/drivers')
-rw-r--r-- | arch/cris/arch-v10/drivers/Kconfig | 963 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/Makefile | 12 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/axisflashmap.c | 541 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/ds1302.c | 602 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/eeprom.c | 945 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/gpio.c | 944 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/i2c.c | 730 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/i2c.h | 18 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/pcf8563.c | 313 |
9 files changed, 5068 insertions, 0 deletions
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig new file mode 100644 index 000000000000..748374f25b87 --- /dev/null +++ b/arch/cris/arch-v10/drivers/Kconfig | |||
@@ -0,0 +1,963 @@ | |||
1 | config ETRAX_ETHERNET | ||
2 | bool "Ethernet support" | ||
3 | depends on ETRAX_ARCH_V10 | ||
4 | help | ||
5 | This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet | ||
6 | controller. | ||
7 | |||
8 | # this is just so that the user does not have to go into the | ||
9 | # normal ethernet driver section just to enable ethernetworking | ||
10 | config NET_ETHERNET | ||
11 | bool | ||
12 | depends on ETRAX_ETHERNET | ||
13 | default y | ||
14 | |||
15 | choice | ||
16 | prompt "Network LED behavior" | ||
17 | depends on ETRAX_ETHERNET | ||
18 | default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
19 | |||
20 | config ETRAX_NETWORK_LED_ON_WHEN_LINK | ||
21 | bool "LED_on_when_link" | ||
22 | help | ||
23 | Selecting LED_on_when_link will light the LED when there is a | ||
24 | connection and will flash off when there is activity. | ||
25 | |||
26 | Selecting LED_on_when_activity will light the LED only when | ||
27 | there is activity. | ||
28 | |||
29 | This setting will also affect the behaviour of other activity LEDs | ||
30 | e.g. Bluetooth. | ||
31 | |||
32 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
33 | bool "LED_on_when_activity" | ||
34 | help | ||
35 | Selecting LED_on_when_link will light the LED when there is a | ||
36 | connection and will flash off when there is activity. | ||
37 | |||
38 | Selecting LED_on_when_activity will light the LED only when | ||
39 | there is activity. | ||
40 | |||
41 | This setting will also affect the behaviour of other activity LEDs | ||
42 | e.g. Bluetooth. | ||
43 | |||
44 | endchoice | ||
45 | |||
46 | config ETRAX_SERIAL | ||
47 | bool "Serial-port support" | ||
48 | depends on ETRAX_ARCH_V10 | ||
49 | help | ||
50 | Enables the ETRAX 100 serial driver for ser0 (ttyS0) | ||
51 | You probably want this enabled. | ||
52 | |||
53 | config ETRAX_SERIAL_FAST_TIMER | ||
54 | bool "Use fast timers for serial DMA flush (experimental)" | ||
55 | depends on ETRAX_SERIAL | ||
56 | help | ||
57 | Select this to have the serial DMAs flushed at a higher rate than | ||
58 | normally, possible by using the fast timer API, the timeout is | ||
59 | approx. 4 character times. | ||
60 | If unsure, say N. | ||
61 | |||
62 | config ETRAX_SERIAL_FLUSH_DMA_FAST | ||
63 | bool "Fast serial port DMA flush" | ||
64 | depends on ETRAX_SERIAL && !ETRAX_SERIAL_FAST_TIMER | ||
65 | help | ||
66 | Select this to have the serial DMAs flushed at a higher rate than | ||
67 | normally possible through a fast timer interrupt (currently at | ||
68 | 15360 Hz). | ||
69 | If unsure, say N. | ||
70 | |||
71 | config ETRAX_SERIAL_RX_TIMEOUT_TICKS | ||
72 | int "Receive flush timeout (ticks) " | ||
73 | depends on ETRAX_SERIAL && !ETRAX_SERIAL_FAST_TIMER && !ETRAX_SERIAL_FLUSH_DMA_FAST | ||
74 | default "5" | ||
75 | help | ||
76 | Number of timer ticks between flush of receive fifo (1 tick = 10ms). | ||
77 | Try 0-3 for low latency applications. Approx 5 for high load | ||
78 | applications (e.g. PPP). Maybe this should be more adaptive some | ||
79 | day... | ||
80 | |||
81 | config ETRAX_SERIAL_PORT0 | ||
82 | bool "Serial port 0 enabled" | ||
83 | depends on ETRAX_SERIAL | ||
84 | help | ||
85 | Enables the ETRAX 100 serial driver for ser0 (ttyS0) | ||
86 | Normally you want this on, unless you use external DMA 1 that uses | ||
87 | the same DMA channels. | ||
88 | |||
89 | choice | ||
90 | prompt "Ser0 DMA out assignment" | ||
91 | depends on ETRAX_SERIAL_PORT0 | ||
92 | default ETRAX_SERIAL_PORT0_DMA6_OUT | ||
93 | |||
94 | config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT | ||
95 | bool "No DMA out" | ||
96 | |||
97 | config CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT | ||
98 | bool "DMA 6" | ||
99 | |||
100 | endchoice | ||
101 | |||
102 | choice | ||
103 | prompt "Ser0 DMA in assignment" | ||
104 | depends on ETRAX_SERIAL_PORT0 | ||
105 | default ETRAX_SERIAL_PORT0_DMA7_IN | ||
106 | |||
107 | config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN | ||
108 | bool "No DMA in" | ||
109 | |||
110 | config CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN | ||
111 | bool "DMA 7" | ||
112 | |||
113 | endchoice | ||
114 | |||
115 | choice | ||
116 | prompt "Ser0 DTR, RI, DSR and CD assignment" | ||
117 | depends on ETRAX_SERIAL_PORT0 | ||
118 | default ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE | ||
119 | |||
120 | config ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE | ||
121 | bool "No_DTR_RI_DSR_CD" | ||
122 | |||
123 | config ETRAX_SER0_DTR_RI_DSR_CD_ON_PA | ||
124 | bool "DTR_RI_DSR_CD_on_PA" | ||
125 | |||
126 | config ETRAX_SER0_DTR_RI_DSR_CD_ON_PB | ||
127 | bool "DTR_RI_DSR_CD_on_PB" | ||
128 | help | ||
129 | Enables the status and control signals DTR, RI, DSR and CD on PB for | ||
130 | ser0. | ||
131 | |||
132 | config ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
133 | bool "DTR_RI_DSR_CD_mixed_on_PA_and_PB" | ||
134 | |||
135 | endchoice | ||
136 | |||
137 | config ETRAX_SER0_DTR_ON_PA_BIT | ||
138 | int "Ser0 DTR on PA bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
139 | depends on ETRAX_SERIAL_PORT0 | ||
140 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
141 | default "4" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
142 | |||
143 | config ETRAX_SER0_RI_ON_PA_BIT | ||
144 | int "Ser0 RI on PA bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
145 | depends on ETRAX_SERIAL_PORT0 | ||
146 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
147 | default "5" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
148 | |||
149 | config ETRAX_SER0_DSR_ON_PA_BIT | ||
150 | int "Ser0 DSR on PA bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
151 | depends on ETRAX_SERIAL_PORT0 | ||
152 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
153 | default "6" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
154 | |||
155 | config ETRAX_SER0_CD_ON_PA_BIT | ||
156 | int "Ser0 CD on PA bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
157 | depends on ETRAX_SERIAL_PORT0 | ||
158 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
159 | default "7" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PA || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
160 | |||
161 | config ETRAX_SER0_DTR_ON_PB_BIT | ||
162 | int "Ser0 DTR on PB bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
163 | depends on ETRAX_SERIAL_PORT0 | ||
164 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
165 | default "4" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
166 | help | ||
167 | Specify the pin of the PB port to carry the DTR signal for serial | ||
168 | port 0. | ||
169 | |||
170 | config ETRAX_SER0_RI_ON_PB_BIT | ||
171 | int "Ser0 RI on PB bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
172 | depends on ETRAX_SERIAL_PORT0 | ||
173 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
174 | default "5" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
175 | help | ||
176 | Specify the pin of the PB port to carry the RI signal for serial | ||
177 | port 0. | ||
178 | |||
179 | config ETRAX_SER0_DSR_ON_PB_BIT | ||
180 | int "Ser0 DSR on PB bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
181 | depends on ETRAX_SERIAL_PORT0 | ||
182 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
183 | default "6" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
184 | help | ||
185 | Specify the pin of the PB port to carry the DSR signal for serial | ||
186 | port 0. | ||
187 | |||
188 | config ETRAX_SER0_CD_ON_PB_BIT | ||
189 | int "Ser0 CD on PB bit (-1 = not used)" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
190 | depends on ETRAX_SERIAL_PORT0 | ||
191 | default "-1" if !ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
192 | default "7" if ETRAX_SER0_DTR_RI_DSR_CD_ON_PB || ETRAX_SER0_DTR_RI_DSR_CD_MIXED | ||
193 | help | ||
194 | Specify the pin of the PB port to carry the CD signal for serial | ||
195 | port 0. | ||
196 | |||
197 | config ETRAX_SERIAL_PORT1 | ||
198 | bool "Serial port 1 enabled" | ||
199 | depends on ETRAX_SERIAL | ||
200 | help | ||
201 | Enables the ETRAX 100 serial driver for ser1 (ttyS1). | ||
202 | |||
203 | choice | ||
204 | prompt "Ser1 DMA out assignment" | ||
205 | depends on ETRAX_SERIAL_PORT1 | ||
206 | default ETRAX_SERIAL_PORT1_DMA8_OUT | ||
207 | |||
208 | config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT | ||
209 | bool "No DMA out" | ||
210 | |||
211 | config CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT | ||
212 | bool "DMA 8" | ||
213 | |||
214 | endchoice | ||
215 | |||
216 | choice | ||
217 | prompt "Ser1 DMA in assignment" | ||
218 | depends on ETRAX_SERIAL_PORT1 | ||
219 | default ETRAX_SERIAL_PORT1_DMA9_IN | ||
220 | |||
221 | config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN | ||
222 | bool "No DMA in" | ||
223 | |||
224 | config CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN | ||
225 | bool "DMA 9" | ||
226 | |||
227 | endchoice | ||
228 | |||
229 | choice | ||
230 | prompt "Ser1 DTR, RI, DSR and CD assignment" | ||
231 | depends on ETRAX_SERIAL_PORT1 | ||
232 | default ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE | ||
233 | |||
234 | config ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE | ||
235 | bool "No_DTR_RI_DSR_CD" | ||
236 | |||
237 | config ETRAX_SER1_DTR_RI_DSR_CD_ON_PA | ||
238 | bool "DTR_RI_DSR_CD_on_PA" | ||
239 | |||
240 | config ETRAX_SER1_DTR_RI_DSR_CD_ON_PB | ||
241 | bool "DTR_RI_DSR_CD_on_PB" | ||
242 | help | ||
243 | Enables the status and control signals DTR, RI, DSR and CD on PB for | ||
244 | ser1. | ||
245 | |||
246 | config ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
247 | bool "DTR_RI_DSR_CD_mixed_on_PA_and_PB" | ||
248 | |||
249 | endchoice | ||
250 | |||
251 | config ETRAX_SER1_DTR_ON_PA_BIT | ||
252 | int "Ser1 DTR on PA bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
253 | depends on ETRAX_SERIAL_PORT1 | ||
254 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
255 | default "4" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
256 | |||
257 | config ETRAX_SER1_RI_ON_PA_BIT | ||
258 | int "Ser1 RI on PA bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
259 | depends on ETRAX_SERIAL_PORT1 | ||
260 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
261 | default "5" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
262 | |||
263 | config ETRAX_SER1_DSR_ON_PA_BIT | ||
264 | int "Ser1 DSR on PA bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
265 | depends on ETRAX_SERIAL_PORT1 | ||
266 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
267 | default "6" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
268 | |||
269 | config ETRAX_SER1_CD_ON_PA_BIT | ||
270 | int "Ser1 CD on PA bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
271 | depends on ETRAX_SERIAL_PORT1 | ||
272 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
273 | default "7" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PA || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
274 | |||
275 | config ETRAX_SER1_DTR_ON_PB_BIT | ||
276 | int "Ser1 DTR on PB bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
277 | depends on ETRAX_SERIAL_PORT1 | ||
278 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
279 | default "4" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
280 | help | ||
281 | Specify the pin of the PB port to carry the DTR signal for serial | ||
282 | port 1. | ||
283 | |||
284 | config ETRAX_SER1_RI_ON_PB_BIT | ||
285 | int "Ser1 RI on PB bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
286 | depends on ETRAX_SERIAL_PORT1 | ||
287 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
288 | default "5" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
289 | help | ||
290 | Specify the pin of the PB port to carry the RI signal for serial | ||
291 | port 1. | ||
292 | |||
293 | config ETRAX_SER1_DSR_ON_PB_BIT | ||
294 | int "Ser1 DSR on PB bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
295 | depends on ETRAX_SERIAL_PORT1 | ||
296 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
297 | default "6" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
298 | help | ||
299 | Specify the pin of the PB port to carry the DSR signal for serial | ||
300 | port 1. | ||
301 | |||
302 | config ETRAX_SER1_CD_ON_PB_BIT | ||
303 | int "Ser1 CD on PB bit (-1 = not used)" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
304 | depends on ETRAX_SERIAL_PORT1 | ||
305 | default "-1" if !ETRAX_SER1_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
306 | default "7" if ETRAX_SER1_DTR_RI_DSR_CD_ON_PB || ETRAX_SER1_DTR_RI_DSR_CD_MIXED | ||
307 | help | ||
308 | Specify the pin of the PB port to carry the CD signal for serial | ||
309 | port 1. | ||
310 | |||
311 | comment "Make sure you dont have the same PB bits more than once!" | ||
312 | depends on ETRAX_SERIAL && ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && ETRAX_SER1_DTR_RI_DSR_CD_ON_PB | ||
313 | |||
314 | config ETRAX_SERIAL_PORT2 | ||
315 | bool "Serial port 2 enabled" | ||
316 | depends on ETRAX_SERIAL | ||
317 | help | ||
318 | Enables the ETRAX 100 serial driver for ser2 (ttyS2). | ||
319 | |||
320 | choice | ||
321 | prompt "Ser2 DMA out assignment" | ||
322 | depends on ETRAX_SERIAL_PORT2 | ||
323 | default ETRAX_SERIAL_PORT2_DMA2_OUT | ||
324 | |||
325 | config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT | ||
326 | bool "No DMA out" | ||
327 | |||
328 | config CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT | ||
329 | bool "DMA 2" | ||
330 | |||
331 | endchoice | ||
332 | |||
333 | choice | ||
334 | prompt "Ser2 DMA in assignment" | ||
335 | depends on ETRAX_SERIAL_PORT2 | ||
336 | default ETRAX_SERIAL_PORT2_DMA3_IN | ||
337 | |||
338 | config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN | ||
339 | bool "No DMA in" | ||
340 | |||
341 | config CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN | ||
342 | bool "DMA 3" | ||
343 | |||
344 | endchoice | ||
345 | |||
346 | choice | ||
347 | prompt "Ser2 DTR, RI, DSR and CD assignment" | ||
348 | depends on ETRAX_SERIAL_PORT2 | ||
349 | default ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE | ||
350 | |||
351 | config ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE | ||
352 | bool "No_DTR_RI_DSR_CD" | ||
353 | |||
354 | config ETRAX_SER2_DTR_RI_DSR_CD_ON_PA | ||
355 | bool "DTR_RI_DSR_CD_on_PA" | ||
356 | help | ||
357 | Enables the status and control signals DTR, RI, DSR and CD on PA for | ||
358 | ser2. | ||
359 | |||
360 | config ETRAX_SER2_DTR_RI_DSR_CD_ON_PB | ||
361 | bool "DTR_RI_DSR_CD_on_PB" | ||
362 | |||
363 | config ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
364 | bool "DTR_RI_DSR_CD_mixed_on_PA_and_PB" | ||
365 | |||
366 | endchoice | ||
367 | |||
368 | config ETRAX_SER2_DTR_ON_PA_BIT | ||
369 | int "Ser2 DTR on PA bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
370 | depends on ETRAX_SERIAL_PORT2 | ||
371 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
372 | default "4" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
373 | help | ||
374 | Specify the pin of the PA port to carry the DTR signal for serial | ||
375 | port 2. | ||
376 | |||
377 | config ETRAX_SER2_RI_ON_PA_BIT | ||
378 | int "Ser2 RI on PA bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
379 | depends on ETRAX_SERIAL_PORT2 | ||
380 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
381 | default "5" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
382 | help | ||
383 | Specify the pin of the PA port to carry the RI signal for serial | ||
384 | port 2. | ||
385 | |||
386 | config ETRAX_SER2_DSR_ON_PA_BIT | ||
387 | int "Ser2 DSR on PA bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
388 | depends on ETRAX_SERIAL_PORT2 | ||
389 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
390 | default "6" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
391 | help | ||
392 | Specify the pin of the PA port to carry the DTR signal for serial | ||
393 | port 2. | ||
394 | |||
395 | config ETRAX_SER2_CD_ON_PA_BIT | ||
396 | int "Ser2 CD on PA bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
397 | depends on ETRAX_SERIAL_PORT2 | ||
398 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PA && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
399 | default "7" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PA || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
400 | help | ||
401 | Specify the pin of the PA port to carry the CD signal for serial | ||
402 | port 2. | ||
403 | |||
404 | config ETRAX_SER2_DTR_ON_PB_BIT | ||
405 | int "Ser2 DTR on PB bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
406 | depends on ETRAX_SERIAL_PORT2 | ||
407 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
408 | default "4" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
409 | |||
410 | config ETRAX_SER2_RI_ON_PB_BIT | ||
411 | int "Ser2 RI on PB bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
412 | depends on ETRAX_SERIAL_PORT2 | ||
413 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
414 | default "5" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
415 | |||
416 | config ETRAX_SER2_DSR_ON_PB_BIT | ||
417 | int "Ser2 DSR on PB bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
418 | depends on ETRAX_SERIAL_PORT2 | ||
419 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
420 | default "6" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
421 | |||
422 | config ETRAX_SER2_CD_ON_PB_BIT | ||
423 | int "Ser2 CD on PB bit (-1 = not used)" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
424 | depends on ETRAX_SERIAL_PORT2 | ||
425 | default "-1" if !ETRAX_SER2_DTR_RI_DSR_CD_ON_PB && !ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
426 | default "7" if ETRAX_SER2_DTR_RI_DSR_CD_ON_PB || ETRAX_SER2_DTR_RI_DSR_CD_MIXED | ||
427 | |||
428 | config ETRAX_SERIAL_PORT3 | ||
429 | bool "Serial port 3 enabled" | ||
430 | depends on ETRAX_SERIAL | ||
431 | help | ||
432 | Enables the ETRAX 100 serial driver for ser3 (ttyS3). | ||
433 | |||
434 | choice | ||
435 | prompt "Ser3 DMA out assignment" | ||
436 | depends on ETRAX_SERIAL_PORT3 | ||
437 | default ETRAX_SERIAL_PORT3_DMA4_OUT | ||
438 | |||
439 | config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT | ||
440 | bool "No DMA out" | ||
441 | |||
442 | config CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT | ||
443 | bool "DMA 4" | ||
444 | |||
445 | endchoice | ||
446 | |||
447 | choice | ||
448 | prompt "Ser3 DMA in assignment" | ||
449 | depends on ETRAX_SERIAL_PORT3 | ||
450 | default ETRAX_SERIAL_PORT3_DMA5_IN | ||
451 | |||
452 | config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN | ||
453 | bool "No DMA in" | ||
454 | |||
455 | config CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN | ||
456 | bool "DMA 5" | ||
457 | |||
458 | endchoice | ||
459 | |||
460 | choice | ||
461 | prompt "Ser3 DTR, RI, DSR and CD assignment" | ||
462 | depends on ETRAX_SERIAL_PORT3 | ||
463 | default ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE | ||
464 | |||
465 | config ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE | ||
466 | bool "No_DTR_RI_DSR_CD" | ||
467 | |||
468 | config ETRAX_SER3_DTR_RI_DSR_CD_ON_PA | ||
469 | bool "DTR_RI_DSR_CD_on_PA" | ||
470 | |||
471 | config ETRAX_SER3_DTR_RI_DSR_CD_ON_PB | ||
472 | bool "DTR_RI_DSR_CD_on_PB" | ||
473 | |||
474 | config ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
475 | bool "DTR_RI_DSR_CD_mixed_on_PA_and_PB" | ||
476 | |||
477 | endchoice | ||
478 | |||
479 | config ETRAX_SER3_DTR_ON_PA_BIT | ||
480 | int "Ser3 DTR on PA bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PA || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
481 | depends on ETRAX_SERIAL_PORT3 | ||
482 | default "-1" | ||
483 | |||
484 | config ETRAX_SER3_RI_ON_PA_BIT | ||
485 | int "Ser3 RI on PA bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PA || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
486 | depends on ETRAX_SERIAL_PORT3 | ||
487 | default "-1" | ||
488 | |||
489 | config ETRAX_SER3_DSR_ON_PA_BIT | ||
490 | int "Ser3 DSR on PA bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PA || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
491 | depends on ETRAX_SERIAL_PORT3 | ||
492 | default "-1" | ||
493 | |||
494 | config ETRAX_SER3_CD_ON_PA_BIT | ||
495 | int "Ser3 CD on PA bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PA || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
496 | depends on ETRAX_SERIAL_PORT3 | ||
497 | default "-1" | ||
498 | |||
499 | config ETRAX_SER3_DTR_ON_PB_BIT | ||
500 | int "Ser3 DTR on PB bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PB || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
501 | depends on ETRAX_SERIAL_PORT3 | ||
502 | default "-1" | ||
503 | |||
504 | config ETRAX_SER3_RI_ON_PB_BIT | ||
505 | int "Ser3 RI on PB bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PB || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
506 | depends on ETRAX_SERIAL_PORT3 | ||
507 | default "-1" | ||
508 | |||
509 | config ETRAX_SER3_DSR_ON_PB_BIT | ||
510 | int "Ser3 DSR on PB bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PB || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
511 | depends on ETRAX_SERIAL_PORT3 | ||
512 | default "-1" | ||
513 | |||
514 | config ETRAX_SER3_CD_ON_PB_BIT | ||
515 | int "Ser3 CD on PB bit (-1 = not used)" if ETRAX_SER3_DTR_RI_DSR_CD_ON_PB || ETRAX_SER3_DTR_RI_DSR_CD_MIXED | ||
516 | depends on ETRAX_SERIAL_PORT3 | ||
517 | default "-1" | ||
518 | |||
519 | config ETRAX_RS485 | ||
520 | bool "RS-485 support" | ||
521 | depends on ETRAX_SERIAL | ||
522 | help | ||
523 | Enables support for RS-485 serial communication. For a primer on | ||
524 | RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. | ||
525 | |||
526 | config ETRAX_RS485_ON_PA | ||
527 | bool "RS-485 mode on PA" | ||
528 | depends on ETRAX_RS485 | ||
529 | help | ||
530 | Control Driver Output Enable on RS485 transceiver using a pin on PA | ||
531 | port: | ||
532 | Axis 2400/2401 uses PA 3. | ||
533 | |||
534 | config ETRAX_RS485_ON_PA_BIT | ||
535 | int "RS-485 mode on PA bit" | ||
536 | depends on ETRAX_RS485_ON_PA | ||
537 | default "3" | ||
538 | help | ||
539 | Control Driver Output Enable on RS485 transceiver using a this bit | ||
540 | on PA port. | ||
541 | |||
542 | config ETRAX_RS485_DISABLE_RECEIVER | ||
543 | bool "Disable serial receiver" | ||
544 | depends on ETRAX_RS485 | ||
545 | help | ||
546 | It's necessary to disable the serial receiver to avoid serial | ||
547 | loopback. Not all products are able to do this in software only. | ||
548 | Axis 2400/2401 must disable receiver. | ||
549 | |||
550 | config ETRAX_IDE | ||
551 | bool "ATA/IDE support" | ||
552 | select IDE | ||
553 | select BLK_DEV_IDE | ||
554 | select BLK_DEV_IDEDISK | ||
555 | select BLK_DEV_IDECD | ||
556 | select BLK_DEV_IDEDMA | ||
557 | select DMA_NONPCI | ||
558 | help | ||
559 | Enable this to get support for ATA/IDE. | ||
560 | You can't use paralell ports or SCSI ports | ||
561 | at the same time. | ||
562 | |||
563 | |||
564 | config ETRAX_IDE_DELAY | ||
565 | int "Delay for drives to regain consciousness" | ||
566 | depends on ETRAX_IDE | ||
567 | default 15 | ||
568 | help | ||
569 | Number of seconds to wait for IDE drives to spin up after an IDE | ||
570 | reset. | ||
571 | choice | ||
572 | prompt "IDE reset pin" | ||
573 | depends on ETRAX_IDE | ||
574 | default ETRAX_IDE_PB7_RESET | ||
575 | |||
576 | config ETRAX_IDE_PB7_RESET | ||
577 | bool "Port_PB_Bit_7" | ||
578 | help | ||
579 | IDE reset on pin 7 on port B | ||
580 | |||
581 | config ETRAX_IDE_G27_RESET | ||
582 | bool "Port_G_Bit_27" | ||
583 | help | ||
584 | IDE reset on pin 27 on port G | ||
585 | |||
586 | endchoice | ||
587 | |||
588 | |||
589 | config ETRAX_USB_HOST | ||
590 | bool "USB host" | ||
591 | help | ||
592 | This option enables the host functionality of the ETRAX 100LX | ||
593 | built-in USB controller. In host mode the controller is designed | ||
594 | for CTRL and BULK traffic only, INTR traffic may work as well | ||
595 | however (depending on the requirements of timeliness). | ||
596 | |||
597 | config USB | ||
598 | tristate | ||
599 | depends on ETRAX_USB_HOST | ||
600 | default y | ||
601 | |||
602 | config ETRAX_USB_HOST_PORT1 | ||
603 | bool " USB port 1 enabled" | ||
604 | depends on ETRAX_USB_HOST | ||
605 | default n | ||
606 | |||
607 | config ETRAX_USB_HOST_PORT2 | ||
608 | bool " USB port 2 enabled" | ||
609 | depends on ETRAX_USB_HOST | ||
610 | default n | ||
611 | |||
612 | config ETRAX_AXISFLASHMAP | ||
613 | bool "Axis flash-map support" | ||
614 | depends on ETRAX_ARCH_V10 | ||
615 | help | ||
616 | This option enables MTD mapping of flash devices. Needed to use | ||
617 | flash memories. If unsure, say Y. | ||
618 | |||
619 | config ETRAX_PTABLE_SECTOR | ||
620 | int "Byte-offset of partition table sector" | ||
621 | depends on ETRAX_AXISFLASHMAP | ||
622 | default "65536" | ||
623 | help | ||
624 | Byte-offset of the partition table in the first flash chip. | ||
625 | The default value is 64kB and should not be changed unless | ||
626 | you know exactly what you are doing. The only valid reason | ||
627 | for changing this is when the flash block size is bigger | ||
628 | than 64kB (e.g. when using two parallel 16 bit flashes). | ||
629 | |||
630 | # here we define the CONFIG_'s necessary to enable MTD support | ||
631 | # for the flash | ||
632 | config MTD | ||
633 | tristate | ||
634 | depends on ETRAX_AXISFLASHMAP | ||
635 | default y | ||
636 | help | ||
637 | Memory Technology Devices are flash, RAM and similar chips, often | ||
638 | used for solid state file systems on embedded devices. This option | ||
639 | will provide the generic support for MTD drivers to register | ||
640 | themselves with the kernel and for potential users of MTD devices | ||
641 | to enumerate the devices which are present and obtain a handle on | ||
642 | them. It will also allow you to select individual drivers for | ||
643 | particular hardware and users of MTD devices. If unsure, say N. | ||
644 | |||
645 | config MTD_CFI | ||
646 | tristate | ||
647 | depends on ETRAX_AXISFLASHMAP | ||
648 | default y | ||
649 | help | ||
650 | The Common Flash Interface specification was developed by Intel, | ||
651 | AMD and other flash manufactures that provides a universal method | ||
652 | for probing the capabilities of flash devices. If you wish to | ||
653 | support any device that is CFI-compliant, you need to enable this | ||
654 | option. Visit <http://www.amd.com/products/nvd/overview/cfi.html> | ||
655 | for more information on CFI. | ||
656 | |||
657 | config MTD_CFI_AMDSTD | ||
658 | tristate | ||
659 | depends on ETRAX_AXISFLASHMAP | ||
660 | default y | ||
661 | help | ||
662 | The Common Flash Interface defines a number of different command | ||
663 | sets which a CFI-compliant chip may claim to implement. This code | ||
664 | provides support for one of those command sets, used on chips | ||
665 | chips including the AMD Am29LV320. | ||
666 | |||
667 | config MTD_OBSOLETE_CHIPS | ||
668 | bool | ||
669 | depends on ETRAX_AXISFLASHMAP | ||
670 | default y | ||
671 | help | ||
672 | This option does not enable any code directly, but will allow you to | ||
673 | select some other chip drivers which are now considered obsolete, | ||
674 | because the generic CONFIG_JEDEC_PROBE code above should now detect | ||
675 | the chips which are supported by these drivers, and allow the generic | ||
676 | CFI-compatible drivers to drive the chips. Say 'N' here unless you have | ||
677 | already tried the CONFIG_JEDEC_PROBE method and reported its failure | ||
678 | to the MTD mailing list at <linux-mtd@lists.infradead.org> | ||
679 | |||
680 | config MTD_AMDSTD | ||
681 | tristate | ||
682 | depends on ETRAX_AXISFLASHMAP | ||
683 | default y | ||
684 | help | ||
685 | This option enables support for flash chips using AMD-compatible | ||
686 | commands, including some which are not CFI-compatible and hence | ||
687 | cannot be used with the CONFIG_MTD_CFI_AMDSTD option. | ||
688 | |||
689 | It also works on AMD compatible chips that do conform to CFI. | ||
690 | |||
691 | config MTD_CHAR | ||
692 | tristate | ||
693 | depends on ETRAX_AXISFLASHMAP | ||
694 | default y | ||
695 | help | ||
696 | This provides a character device for each MTD device present in | ||
697 | the system, allowing the user to read and write directly to the | ||
698 | memory chips, and also use ioctl() to obtain information about | ||
699 | the device, or to erase parts of it. | ||
700 | |||
701 | config MTD_BLOCK | ||
702 | tristate | ||
703 | depends on ETRAX_AXISFLASHMAP | ||
704 | default y | ||
705 | ---help--- | ||
706 | Although most flash chips have an erase size too large to be useful | ||
707 | as block devices, it is possible to use MTD devices which are based | ||
708 | on RAM chips in this manner. This block device is a user of MTD | ||
709 | devices performing that function. | ||
710 | |||
711 | At the moment, it is also required for the Journalling Flash File | ||
712 | System(s) to obtain a handle on the MTD device when it's mounted | ||
713 | (although JFFS and JFFS2 don't actually use any of the functionality | ||
714 | of the mtdblock device). | ||
715 | |||
716 | Later, it may be extended to perform read/erase/modify/write cycles | ||
717 | on flash chips to emulate a smaller block size. Needless to say, | ||
718 | this is very unsafe, but could be useful for file systems which are | ||
719 | almost never written to. | ||
720 | |||
721 | You do not need this option for use with the DiskOnChip devices. For | ||
722 | those, enable NFTL support (CONFIG_NFTL) instead. | ||
723 | |||
724 | config MTD_PARTITIONS | ||
725 | tristate | ||
726 | depends on ETRAX_AXISFLASHMAP | ||
727 | default y | ||
728 | help | ||
729 | If you have a device which needs to divide its flash chip(s) up | ||
730 | into multiple 'partitions', each of which appears to the user as | ||
731 | a separate MTD device, you require this option to be enabled. If | ||
732 | unsure, say 'Y'. | ||
733 | |||
734 | Note, however, that you don't need this option for the DiskOnChip | ||
735 | devices. Partitioning on NFTL 'devices' is a different - that's the | ||
736 | 'normal' form of partitioning used on a block device. | ||
737 | |||
738 | config MTD_CONCAT | ||
739 | tristate | ||
740 | depends on ETRAX_AXISFLASHMAP | ||
741 | default y | ||
742 | |||
743 | config ETRAX_I2C | ||
744 | bool "I2C support" | ||
745 | depends on ETRAX_ARCH_V10 | ||
746 | help | ||
747 | Enables an I2C driver on ETRAX100. | ||
748 | EXAMPLE usage: | ||
749 | i2c_arg = I2C_WRITEARG(STA013_WRITE_ADDR, reg, val); | ||
750 | ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_WRITEREG), i2c_arg); | ||
751 | i2c_arg = I2C_READARG(STA013_READ_ADDR, reg); | ||
752 | val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg); | ||
753 | |||
754 | # this is true for most products since PB-I2C seems to be somewhat | ||
755 | # flawed.. | ||
756 | config ETRAX_I2C_USES_PB_NOT_PB_I2C | ||
757 | bool "I2C uses PB not PB-I2C" | ||
758 | depends on ETRAX_I2C | ||
759 | help | ||
760 | Select whether to use the special I2C mode in the PB I/O register or | ||
761 | not. This option needs to be selected in order to use some drivers | ||
762 | that access the I2C I/O pins directly instead of going through the | ||
763 | I2C driver, like the DS1302 realtime-clock driver. If you are | ||
764 | uncertain, choose Y here. | ||
765 | |||
766 | config ETRAX_I2C_DATA_PORT | ||
767 | int "I2C SDA bit number" | ||
768 | depends on ETRAX_I2C_USES_PB_NOT_PB_I2C | ||
769 | default "0" | ||
770 | help | ||
771 | Selects the pin on Port B where the data pin is connected | ||
772 | |||
773 | config ETRAX_I2C_CLK_PORT | ||
774 | int "I2C SCL bit number" | ||
775 | depends on ETRAX_I2C_USES_PB_NOT_PB_I2C | ||
776 | default "1" | ||
777 | help | ||
778 | Select the pin on Port B where the clock pin is connected | ||
779 | |||
780 | config ETRAX_I2C_EEPROM | ||
781 | bool "I2C EEPROM (non-volatile RAM) support" | ||
782 | depends on ETRAX_I2C | ||
783 | help | ||
784 | Enables I2C EEPROM (non-volatile RAM) on PB0 and PB1 using the I2C | ||
785 | driver. Select size option: Probed, 2k, 8k, 16k. | ||
786 | (Probing works for 2k and 8k but not that well for 16k) | ||
787 | |||
788 | choice | ||
789 | prompt "EEPROM size" | ||
790 | depends on ETRAX_I2C_EEPROM | ||
791 | default ETRAX_I2C_EEPROM_PROBE | ||
792 | |||
793 | config ETRAX_I2C_EEPROM_PROBE | ||
794 | bool "Probed" | ||
795 | help | ||
796 | Specifies size or auto probe of the EEPROM size. | ||
797 | Options: Probed, 2k, 8k, 16k. | ||
798 | (Probing works for 2k and 8k but not that well for 16k) | ||
799 | |||
800 | config ETRAX_I2C_EEPROM_2KB | ||
801 | bool "2kB" | ||
802 | help | ||
803 | Use a 2kB EEPROM. | ||
804 | |||
805 | config ETRAX_I2C_EEPROM_8KB | ||
806 | bool "8kB" | ||
807 | help | ||
808 | Use a 8kB EEPROM. | ||
809 | |||
810 | config ETRAX_I2C_EEPROM_16KB | ||
811 | bool "16kB" | ||
812 | help | ||
813 | Use a 16kB EEPROM. | ||
814 | |||
815 | endchoice | ||
816 | |||
817 | config ETRAX_GPIO | ||
818 | bool "GPIO support" | ||
819 | depends on ETRAX_ARCH_V10 | ||
820 | ---help--- | ||
821 | Enables the ETRAX general port device (major 120, minors 0 and 1). | ||
822 | You can use this driver to access the general port bits. It supports | ||
823 | these ioctl's: | ||
824 | #include <linux/etraxgpio.h> | ||
825 | fd = open("/dev/gpioa", O_RDWR); // or /dev/gpiob | ||
826 | ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS), bits_to_set); | ||
827 | ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS), bits_to_clear); | ||
828 | val = ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_READBITS), NULL); | ||
829 | Remember that you need to setup the port directions appropriately in | ||
830 | the General configuration. | ||
831 | |||
832 | config ETRAX_PA_BUTTON_BITMASK | ||
833 | hex "PA-buttons bitmask" | ||
834 | depends on ETRAX_GPIO | ||
835 | default "02" | ||
836 | help | ||
837 | This is a bitmask with information about what bits on PA that | ||
838 | are used for buttons. | ||
839 | Most products has a so called TEST button on PA1, if that's true | ||
840 | use 02 here. | ||
841 | Use 00 if there are no buttons on PA. | ||
842 | If the bitmask is <> 00 a button driver will be included in the gpio | ||
843 | driver. ETRAX general I/O support must be enabled. | ||
844 | |||
845 | config ETRAX_PA_CHANGEABLE_DIR | ||
846 | hex "PA user changeable dir mask" | ||
847 | depends on ETRAX_GPIO | ||
848 | default "00" | ||
849 | help | ||
850 | This is a bitmask with information of what bits in PA that a user | ||
851 | can change direction on using ioctl's. | ||
852 | Bit set = changeable. | ||
853 | You probably want 00 here. | ||
854 | |||
855 | config ETRAX_PA_CHANGEABLE_BITS | ||
856 | hex "PA user changeable bits mask" | ||
857 | depends on ETRAX_GPIO | ||
858 | default "FF" | ||
859 | help | ||
860 | This is a bitmask with information of what bits in PA that a user | ||
861 | can change change the value on using ioctl's. | ||
862 | Bit set = changeable. | ||
863 | You probably want 00 here. | ||
864 | |||
865 | config ETRAX_PB_CHANGEABLE_DIR | ||
866 | hex "PB user changeable dir mask" | ||
867 | depends on ETRAX_GPIO | ||
868 | default "00" | ||
869 | help | ||
870 | This is a bitmask with information of what bits in PB that a user | ||
871 | can change direction on using ioctl's. | ||
872 | Bit set = changeable. | ||
873 | You probably want 00 here. | ||
874 | |||
875 | config ETRAX_PB_CHANGEABLE_BITS | ||
876 | hex "PB user changeable bits mask" | ||
877 | depends on ETRAX_GPIO | ||
878 | default "FF" | ||
879 | help | ||
880 | This is a bitmask with information of what bits in PB that a user | ||
881 | can change the value on using ioctl's. | ||
882 | Bit set = changeable. | ||
883 | You probably want 00 here. | ||
884 | |||
885 | config ETRAX_RTC | ||
886 | bool "Real Time Clock support" | ||
887 | depends on ETRAX_ARCH_V10 | ||
888 | help | ||
889 | Enables drivers for the Real-Time Clock battery-backed chips on | ||
890 | some products. The kernel reads the time when booting, and | ||
891 | the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a | ||
892 | rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc | ||
893 | device, major 121. You can check the time with cat /proc/rtc, but | ||
894 | normal time reading should be done using libc function time and | ||
895 | friends. | ||
896 | |||
897 | choice | ||
898 | prompt "RTC chip" | ||
899 | depends on ETRAX_RTC | ||
900 | default ETRAX_DS1302 | ||
901 | |||
902 | config ETRAX_DS1302 | ||
903 | bool "DS1302" | ||
904 | help | ||
905 | Enables the driver for the DS1302 Real-Time Clock battery-backed | ||
906 | chip on some products. | ||
907 | |||
908 | config ETRAX_PCF8563 | ||
909 | bool "PCF8563" | ||
910 | help | ||
911 | Enables the driver for the PCF8563 Real-Time Clock battery-backed | ||
912 | chip on some products. | ||
913 | |||
914 | endchoice | ||
915 | |||
916 | config ETRAX_DS1302_RST_ON_GENERIC_PORT | ||
917 | bool "DS1302 RST on Generic Port" | ||
918 | depends on ETRAX_DS1302 | ||
919 | help | ||
920 | If your product has the RST signal line for the DS1302 RTC on the | ||
921 | Generic Port then say Y here, otherwise leave it as N in which | ||
922 | case the RST signal line is assumed to be connected to Port PB | ||
923 | (just like the SCL and SDA lines). | ||
924 | |||
925 | config ETRAX_DS1302_RSTBIT | ||
926 | int "DS1302 RST bit number" | ||
927 | depends on ETRAX_DS1302 | ||
928 | default "2" | ||
929 | help | ||
930 | This is the bit number for the RST signal line of the DS1302 RTC on | ||
931 | the selected port. If you have selected the generic port then it | ||
932 | should be bit 27, otherwise your best bet is bit 5. | ||
933 | |||
934 | config ETRAX_DS1302_SCLBIT | ||
935 | int "DS1302 SCL bit number" | ||
936 | depends on ETRAX_DS1302 | ||
937 | default "1" | ||
938 | help | ||
939 | This is the bit number for the SCL signal line of the DS1302 RTC on | ||
940 | Port PB. This is probably best left at 3. | ||
941 | |||
942 | config ETRAX_DS1302_SDABIT | ||
943 | int "DS1302 SDA bit number" | ||
944 | depends on ETRAX_DS1302 | ||
945 | default "0" | ||
946 | help | ||
947 | This is the bit number for the SDA signal line of the DS1302 RTC on | ||
948 | Port PB. This is probably best left at 2. | ||
949 | |||
950 | config ETRAX_DS1302_TRICKLE_CHARGE | ||
951 | int "DS1302 Trickle charger value" | ||
952 | depends on ETRAX_DS1302 | ||
953 | default "0" | ||
954 | help | ||
955 | This controls the initial value of the trickle charge register. | ||
956 | 0 = disabled (use this if you are unsure or have a non rechargable battery) | ||
957 | Otherwise the following values can be OR:ed together to control the | ||
958 | charge current: | ||
959 | 1 = 2kohm, 2 = 4kohm, 3 = 4kohm | ||
960 | 4 = 1 diode, 8 = 2 diodes | ||
961 | Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 | ||
962 | |||
963 | |||
diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile new file mode 100644 index 000000000000..20258e36f384 --- /dev/null +++ b/arch/cris/arch-v10/drivers/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | # | ||
2 | # Makefile for Etrax-specific drivers | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o | ||
6 | obj-$(CONFIG_ETRAX_I2C) += i2c.o | ||
7 | obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o | ||
8 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o | ||
9 | obj-$(CONFIG_ETRAX_DS1302) += ds1302.o | ||
10 | obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o | ||
11 | |||
12 | |||
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c new file mode 100644 index 000000000000..fb7d4855ea62 --- /dev/null +++ b/arch/cris/arch-v10/drivers/axisflashmap.c | |||
@@ -0,0 +1,541 @@ | |||
1 | /* | ||
2 | * Physical mapping layer for MTD using the Axis partitiontable format | ||
3 | * | ||
4 | * Copyright (c) 2001, 2002 Axis Communications AB | ||
5 | * | ||
6 | * This file is under the GPL. | ||
7 | * | ||
8 | * First partition is always sector 0 regardless of if we find a partitiontable | ||
9 | * or not. In the start of the next sector, there can be a partitiontable that | ||
10 | * tells us what other partitions to define. If there isn't, we use a default | ||
11 | * partition split defined below. | ||
12 | * | ||
13 | * $Log: axisflashmap.c,v $ | ||
14 | * Revision 1.10 2004/08/16 12:37:22 starvik | ||
15 | * Merge of Linux 2.6.8 | ||
16 | * | ||
17 | * Revision 1.8 2004/05/14 07:58:03 starvik | ||
18 | * Merge of changes from 2.4 | ||
19 | * | ||
20 | * Revision 1.6 2003/07/04 08:27:37 starvik | ||
21 | * Merge of Linux 2.5.74 | ||
22 | * | ||
23 | * Revision 1.5 2002/12/11 13:13:57 starvik | ||
24 | * Added arch/ to v10 specific includes | ||
25 | * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
26 | * | ||
27 | * Revision 1.4 2002/11/20 11:56:10 starvik | ||
28 | * Merge of Linux 2.5.48 | ||
29 | * | ||
30 | * Revision 1.3 2002/11/13 14:54:13 starvik | ||
31 | * Copied from linux 2.4 | ||
32 | * | ||
33 | * Revision 1.28 2002/10/01 08:08:43 jonashg | ||
34 | * The first partition ends at the start of the partition table. | ||
35 | * | ||
36 | * Revision 1.27 2002/08/21 09:23:13 jonashg | ||
37 | * Speling. | ||
38 | * | ||
39 | * Revision 1.26 2002/08/21 08:35:20 jonashg | ||
40 | * Cosmetic change to printouts. | ||
41 | * | ||
42 | * Revision 1.25 2002/08/21 08:15:42 jonashg | ||
43 | * Made it compile even without CONFIG_MTD_CONCAT defined. | ||
44 | * | ||
45 | * Revision 1.24 2002/08/20 13:12:35 jonashg | ||
46 | * * New approach to probing. Probe cse0 and cse1 separately and (mtd)concat | ||
47 | * the results. | ||
48 | * * Removed compile time tests concerning how the mtdram driver has been | ||
49 | * configured. The user will know about the misconfiguration at runtime | ||
50 | * instead. (The old approach made it impossible to use mtdram for anything | ||
51 | * else than RAM boot). | ||
52 | * | ||
53 | * Revision 1.23 2002/05/13 12:12:28 johana | ||
54 | * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and | ||
55 | * be informative at runtime. | ||
56 | * | ||
57 | * Revision 1.22 2002/05/13 10:24:44 johana | ||
58 | * Added #if checks on MTDRAM CONFIG | ||
59 | * | ||
60 | * Revision 1.21 2002/05/06 16:05:20 johana | ||
61 | * Removed debug printout. | ||
62 | * | ||
63 | * Revision 1.20 2002/05/06 16:03:00 johana | ||
64 | * No more cramfs as root hack in generic code. | ||
65 | * It's handled by axisflashmap using mtdram. | ||
66 | * | ||
67 | * Revision 1.19 2002/03/15 17:10:28 bjornw | ||
68 | * Changed comment about cached access since we changed this before | ||
69 | * | ||
70 | * Revision 1.18 2002/03/05 17:06:15 jonashg | ||
71 | * Try amd_flash probe before cfi_probe since amd_flash driver can handle two | ||
72 | * (or more) flash chips of different model and the cfi driver cannot. | ||
73 | * | ||
74 | * Revision 1.17 2001/11/12 19:42:38 pkj | ||
75 | * Fixed compiler warnings. | ||
76 | * | ||
77 | * Revision 1.16 2001/11/08 11:18:58 jonashg | ||
78 | * Always read from uncached address to avoid problems with flushing | ||
79 | * cachelines after write and MTD-erase. No performance loss have been | ||
80 | * seen yet. | ||
81 | * | ||
82 | * Revision 1.15 2001/10/19 12:41:04 jonashg | ||
83 | * Name of probe has changed in MTD. | ||
84 | * | ||
85 | * Revision 1.14 2001/09/21 07:14:10 jonashg | ||
86 | * Made root filesystem (cramfs) use mtdblock driver when booting from flash. | ||
87 | * | ||
88 | * Revision 1.13 2001/08/15 13:57:35 jonashg | ||
89 | * Entire MTD updated to the linux 2.4.7 version. | ||
90 | * | ||
91 | * Revision 1.12 2001/06/11 09:50:30 jonashg | ||
92 | * Oops, 2MB is 0x200000 bytes. | ||
93 | * | ||
94 | * Revision 1.11 2001/06/08 11:39:44 jonashg | ||
95 | * Changed sizes and offsets in axis_default_partitions to use | ||
96 | * CONFIG_ETRAX_PTABLE_SECTOR. | ||
97 | * | ||
98 | * Revision 1.10 2001/05/29 09:42:03 jonashg | ||
99 | * Use macro for end marker length instead of sizeof. | ||
100 | * | ||
101 | * Revision 1.9 2001/05/29 08:52:52 jonashg | ||
102 | * Gave names to the magic fours (size of the ptable end marker). | ||
103 | * | ||
104 | * Revision 1.8 2001/05/28 15:36:20 jonashg | ||
105 | * * Removed old comment about ptable location in flash (it's a CONFIG_ option). | ||
106 | * * Variable ptable was initialized twice to the same value. | ||
107 | * | ||
108 | * Revision 1.7 2001/04/05 13:41:46 markusl | ||
109 | * Updated according to review remarks | ||
110 | * | ||
111 | * Revision 1.6 2001/03/07 09:21:21 bjornw | ||
112 | * No need to waste .data | ||
113 | * | ||
114 | * Revision 1.5 2001/03/06 16:27:01 jonashg | ||
115 | * Probe the entire flash area for flash devices. | ||
116 | * | ||
117 | * Revision 1.4 2001/02/23 12:47:15 bjornw | ||
118 | * Uncached flash in LOW_MAP moved from 0xe to 0x8 | ||
119 | * | ||
120 | * Revision 1.3 2001/02/16 12:11:45 jonashg | ||
121 | * MTD driver amd_flash is now included in MTD CVS repository. | ||
122 | * (It's now in drivers/mtd). | ||
123 | * | ||
124 | * Revision 1.2 2001/02/09 11:12:22 jonashg | ||
125 | * Support for AMD compatible non-CFI flash chips. | ||
126 | * Only tested with Toshiba TC58FVT160 so far. | ||
127 | * | ||
128 | * Revision 1.1 2001/01/12 17:01:18 bjornw | ||
129 | * * Added axisflashmap.c, a physical mapping for MTD that reads and understands | ||
130 | * Axis partition-table format. | ||
131 | * | ||
132 | * | ||
133 | */ | ||
134 | |||
135 | #include <linux/module.h> | ||
136 | #include <linux/types.h> | ||
137 | #include <linux/kernel.h> | ||
138 | #include <linux/config.h> | ||
139 | #include <linux/init.h> | ||
140 | |||
141 | #include <linux/mtd/concat.h> | ||
142 | #include <linux/mtd/map.h> | ||
143 | #include <linux/mtd/mtd.h> | ||
144 | #include <linux/mtd/mtdram.h> | ||
145 | #include <linux/mtd/partitions.h> | ||
146 | |||
147 | #include <asm/axisflashmap.h> | ||
148 | #include <asm/mmu.h> | ||
149 | #include <asm/arch/sv_addr_ag.h> | ||
150 | |||
151 | #ifdef CONFIG_CRIS_LOW_MAP | ||
152 | #define FLASH_UNCACHED_ADDR KSEG_8 | ||
153 | #define FLASH_CACHED_ADDR KSEG_5 | ||
154 | #else | ||
155 | #define FLASH_UNCACHED_ADDR KSEG_E | ||
156 | #define FLASH_CACHED_ADDR KSEG_F | ||
157 | #endif | ||
158 | |||
159 | #if CONFIG_ETRAX_FLASH_BUSWIDTH==1 | ||
160 | #define flash_data __u8 | ||
161 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 | ||
162 | #define flash_data __u16 | ||
163 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 | ||
164 | #define flash_data __u16 | ||
165 | #endif | ||
166 | |||
167 | /* From head.S */ | ||
168 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; | ||
169 | |||
170 | /* The master mtd for the entire flash. */ | ||
171 | struct mtd_info* axisflash_mtd = NULL; | ||
172 | |||
173 | /* Map driver functions. */ | ||
174 | |||
175 | static map_word flash_read(struct map_info *map, unsigned long ofs) | ||
176 | { | ||
177 | map_word tmp; | ||
178 | tmp.x[0] = *(flash_data *)(map->map_priv_1 + ofs); | ||
179 | return tmp; | ||
180 | } | ||
181 | |||
182 | static void flash_copy_from(struct map_info *map, void *to, | ||
183 | unsigned long from, ssize_t len) | ||
184 | { | ||
185 | memcpy(to, (void *)(map->map_priv_1 + from), len); | ||
186 | } | ||
187 | |||
188 | static void flash_write(struct map_info *map, map_word d, unsigned long adr) | ||
189 | { | ||
190 | *(flash_data *)(map->map_priv_1 + adr) = (flash_data)d.x[0]; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * The map for chip select e0. | ||
195 | * | ||
196 | * We run into tricky coherence situations if we mix cached with uncached | ||
197 | * accesses to we only use the uncached version here. | ||
198 | * | ||
199 | * The size field is the total size where the flash chips may be mapped on the | ||
200 | * chip select. MTD probes should find all devices there and it does not matter | ||
201 | * if there are unmapped gaps or aliases (mirrors of flash devices). The MTD | ||
202 | * probes will ignore them. | ||
203 | * | ||
204 | * The start address in map_priv_1 is in virtual memory so we cannot use | ||
205 | * MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start | ||
206 | * address of cse0. | ||
207 | */ | ||
208 | static struct map_info map_cse0 = { | ||
209 | .name = "cse0", | ||
210 | .size = MEM_CSE0_SIZE, | ||
211 | .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, | ||
212 | .read = flash_read, | ||
213 | .copy_from = flash_copy_from, | ||
214 | .write = flash_write, | ||
215 | .map_priv_1 = FLASH_UNCACHED_ADDR | ||
216 | }; | ||
217 | |||
218 | /* | ||
219 | * The map for chip select e1. | ||
220 | * | ||
221 | * If there was a gap between cse0 and cse1, map_priv_1 would get the wrong | ||
222 | * address, but there isn't. | ||
223 | */ | ||
224 | static struct map_info map_cse1 = { | ||
225 | .name = "cse1", | ||
226 | .size = MEM_CSE1_SIZE, | ||
227 | .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, | ||
228 | .read = flash_read, | ||
229 | .copy_from = flash_copy_from, | ||
230 | .write = flash_write, | ||
231 | .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE | ||
232 | }; | ||
233 | |||
234 | /* If no partition-table was found, we use this default-set. */ | ||
235 | #define MAX_PARTITIONS 7 | ||
236 | #define NUM_DEFAULT_PARTITIONS 3 | ||
237 | |||
238 | /* | ||
239 | * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the | ||
240 | * size of one flash block and "filesystem"-partition needs 5 blocks to be able | ||
241 | * to use JFFS. | ||
242 | */ | ||
243 | static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { | ||
244 | { | ||
245 | .name = "boot firmware", | ||
246 | .size = CONFIG_ETRAX_PTABLE_SECTOR, | ||
247 | .offset = 0 | ||
248 | }, | ||
249 | { | ||
250 | .name = "kernel", | ||
251 | .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR), | ||
252 | .offset = CONFIG_ETRAX_PTABLE_SECTOR | ||
253 | }, | ||
254 | { | ||
255 | .name = "filesystem", | ||
256 | .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR, | ||
257 | .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR) | ||
258 | } | ||
259 | }; | ||
260 | |||
261 | /* Initialize the ones normally used. */ | ||
262 | static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { | ||
263 | { | ||
264 | .name = "part0", | ||
265 | .size = CONFIG_ETRAX_PTABLE_SECTOR, | ||
266 | .offset = 0 | ||
267 | }, | ||
268 | { | ||
269 | .name = "part1", | ||
270 | .size = 0, | ||
271 | .offset = 0 | ||
272 | }, | ||
273 | { | ||
274 | .name = "part2", | ||
275 | .size = 0, | ||
276 | .offset = 0 | ||
277 | }, | ||
278 | { | ||
279 | .name = "part3", | ||
280 | .size = 0, | ||
281 | .offset = 0 | ||
282 | }, | ||
283 | { | ||
284 | .name = "part4", | ||
285 | .size = 0, | ||
286 | .offset = 0 | ||
287 | }, | ||
288 | { | ||
289 | .name = "part5", | ||
290 | .size = 0, | ||
291 | .offset = 0 | ||
292 | }, | ||
293 | { | ||
294 | .name = "part6", | ||
295 | .size = 0, | ||
296 | .offset = 0 | ||
297 | }, | ||
298 | }; | ||
299 | |||
300 | /* | ||
301 | * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash | ||
302 | * chips in that order (because the amd_flash-driver is faster). | ||
303 | */ | ||
304 | static struct mtd_info *probe_cs(struct map_info *map_cs) | ||
305 | { | ||
306 | struct mtd_info *mtd_cs = NULL; | ||
307 | |||
308 | printk(KERN_INFO | ||
309 | "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", | ||
310 | map_cs->name, map_cs->size, map_cs->map_priv_1); | ||
311 | |||
312 | #ifdef CONFIG_MTD_AMDSTD | ||
313 | mtd_cs = do_map_probe("amd_flash", map_cs); | ||
314 | #endif | ||
315 | #ifdef CONFIG_MTD_CFI | ||
316 | if (!mtd_cs) { | ||
317 | mtd_cs = do_map_probe("cfi_probe", map_cs); | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | return mtd_cs; | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * Probe each chip select individually for flash chips. If there are chips on | ||
326 | * both cse0 and cse1, the mtd_info structs will be concatenated to one struct | ||
327 | * so that MTD partitions can cross chip boundries. | ||
328 | * | ||
329 | * The only known restriction to how you can mount your chips is that each | ||
330 | * chip select must hold similar flash chips. But you need external hardware | ||
331 | * to do that anyway and you can put totally different chips on cse0 and cse1 | ||
332 | * so it isn't really much of a restriction. | ||
333 | */ | ||
334 | static struct mtd_info *flash_probe(void) | ||
335 | { | ||
336 | struct mtd_info *mtd_cse0; | ||
337 | struct mtd_info *mtd_cse1; | ||
338 | struct mtd_info *mtd_cse; | ||
339 | |||
340 | mtd_cse0 = probe_cs(&map_cse0); | ||
341 | mtd_cse1 = probe_cs(&map_cse1); | ||
342 | |||
343 | if (!mtd_cse0 && !mtd_cse1) { | ||
344 | /* No chip found. */ | ||
345 | return NULL; | ||
346 | } | ||
347 | |||
348 | if (mtd_cse0 && mtd_cse1) { | ||
349 | #ifdef CONFIG_MTD_CONCAT | ||
350 | struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; | ||
351 | |||
352 | /* Since the concatenation layer adds a small overhead we | ||
353 | * could try to figure out if the chips in cse0 and cse1 are | ||
354 | * identical and reprobe the whole cse0+cse1 window. But since | ||
355 | * flash chips are slow, the overhead is relatively small. | ||
356 | * So we use the MTD concatenation layer instead of further | ||
357 | * complicating the probing procedure. | ||
358 | */ | ||
359 | mtd_cse = mtd_concat_create(mtds, | ||
360 | sizeof(mtds) / sizeof(mtds[0]), | ||
361 | "cse0+cse1"); | ||
362 | #else | ||
363 | printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " | ||
364 | "(mis)configuration!\n", map_cse0.name, map_cse1.name); | ||
365 | mtd_cse = NULL; | ||
366 | #endif | ||
367 | if (!mtd_cse) { | ||
368 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", | ||
369 | map_cse0.name, map_cse1.name); | ||
370 | |||
371 | /* The best we can do now is to only use what we found | ||
372 | * at cse0. | ||
373 | */ | ||
374 | mtd_cse = mtd_cse0; | ||
375 | map_destroy(mtd_cse1); | ||
376 | } | ||
377 | } else { | ||
378 | mtd_cse = mtd_cse0? mtd_cse0 : mtd_cse1; | ||
379 | } | ||
380 | |||
381 | return mtd_cse; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * Probe the flash chip(s) and, if it succeeds, read the partition-table | ||
386 | * and register the partitions with MTD. | ||
387 | */ | ||
388 | static int __init init_axis_flash(void) | ||
389 | { | ||
390 | struct mtd_info *mymtd; | ||
391 | int err = 0; | ||
392 | int pidx = 0; | ||
393 | struct partitiontable_head *ptable_head = NULL; | ||
394 | struct partitiontable_entry *ptable; | ||
395 | int use_default_ptable = 1; /* Until proven otherwise. */ | ||
396 | const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n"; | ||
397 | |||
398 | if (!(mymtd = flash_probe())) { | ||
399 | /* There's no reason to use this module if no flash chip can | ||
400 | * be identified. Make sure that's understood. | ||
401 | */ | ||
402 | printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); | ||
403 | } else { | ||
404 | printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", | ||
405 | mymtd->name, mymtd->size); | ||
406 | axisflash_mtd = mymtd; | ||
407 | } | ||
408 | |||
409 | if (mymtd) { | ||
410 | mymtd->owner = THIS_MODULE; | ||
411 | ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + | ||
412 | CONFIG_ETRAX_PTABLE_SECTOR + | ||
413 | PARTITION_TABLE_OFFSET); | ||
414 | } | ||
415 | pidx++; /* First partition is always set to the default. */ | ||
416 | |||
417 | if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) | ||
418 | && (ptable_head->size < | ||
419 | (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + | ||
420 | PARTITIONTABLE_END_MARKER_SIZE)) | ||
421 | && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + | ||
422 | ptable_head->size - | ||
423 | PARTITIONTABLE_END_MARKER_SIZE) | ||
424 | == PARTITIONTABLE_END_MARKER)) { | ||
425 | /* Looks like a start, sane length and end of a | ||
426 | * partition table, lets check csum etc. | ||
427 | */ | ||
428 | int ptable_ok = 0; | ||
429 | struct partitiontable_entry *max_addr = | ||
430 | (struct partitiontable_entry *) | ||
431 | ((unsigned long)ptable_head + sizeof(*ptable_head) + | ||
432 | ptable_head->size); | ||
433 | unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; | ||
434 | unsigned char *p; | ||
435 | unsigned long csum = 0; | ||
436 | |||
437 | ptable = (struct partitiontable_entry *) | ||
438 | ((unsigned long)ptable_head + sizeof(*ptable_head)); | ||
439 | |||
440 | /* Lets be PARANOID, and check the checksum. */ | ||
441 | p = (unsigned char*) ptable; | ||
442 | |||
443 | while (p <= (unsigned char*)max_addr) { | ||
444 | csum += *p++; | ||
445 | csum += *p++; | ||
446 | csum += *p++; | ||
447 | csum += *p++; | ||
448 | } | ||
449 | ptable_ok = (csum == ptable_head->checksum); | ||
450 | |||
451 | /* Read the entries and use/show the info. */ | ||
452 | printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", | ||
453 | (ptable_ok ? " valid" : "n invalid"), ptable_head, | ||
454 | max_addr); | ||
455 | |||
456 | /* We have found a working bootblock. Now read the | ||
457 | * partition table. Scan the table. It ends when | ||
458 | * there is 0xffffffff, that is, empty flash. | ||
459 | */ | ||
460 | while (ptable_ok | ||
461 | && ptable->offset != 0xffffffff | ||
462 | && ptable < max_addr | ||
463 | && pidx < MAX_PARTITIONS) { | ||
464 | |||
465 | axis_partitions[pidx].offset = offset + ptable->offset; | ||
466 | axis_partitions[pidx].size = ptable->size; | ||
467 | |||
468 | printk(pmsg, pidx, axis_partitions[pidx].offset, | ||
469 | axis_partitions[pidx].size); | ||
470 | pidx++; | ||
471 | ptable++; | ||
472 | } | ||
473 | use_default_ptable = !ptable_ok; | ||
474 | } | ||
475 | |||
476 | if (romfs_in_flash) { | ||
477 | /* Add an overlapping device for the root partition (romfs). */ | ||
478 | |||
479 | axis_partitions[pidx].name = "romfs"; | ||
480 | axis_partitions[pidx].size = romfs_length; | ||
481 | axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; | ||
482 | axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; | ||
483 | |||
484 | printk(KERN_INFO | ||
485 | " Adding readonly flash partition for romfs image:\n"); | ||
486 | printk(pmsg, pidx, axis_partitions[pidx].offset, | ||
487 | axis_partitions[pidx].size); | ||
488 | pidx++; | ||
489 | } | ||
490 | |||
491 | if (mymtd) { | ||
492 | if (use_default_ptable) { | ||
493 | printk(KERN_INFO " Using default partition table.\n"); | ||
494 | err = add_mtd_partitions(mymtd, axis_default_partitions, | ||
495 | NUM_DEFAULT_PARTITIONS); | ||
496 | } else { | ||
497 | err = add_mtd_partitions(mymtd, axis_partitions, pidx); | ||
498 | } | ||
499 | |||
500 | if (err) { | ||
501 | panic("axisflashmap could not add MTD partitions!\n"); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | if (!romfs_in_flash) { | ||
506 | /* Create an RAM device for the root partition (romfs). */ | ||
507 | |||
508 | #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) | ||
509 | /* No use trying to boot this kernel from RAM. Panic! */ | ||
510 | printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " | ||
511 | "device due to kernel (mis)configuration!\n"); | ||
512 | panic("This kernel cannot boot from RAM!\n"); | ||
513 | #else | ||
514 | struct mtd_info *mtd_ram; | ||
515 | |||
516 | mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), | ||
517 | GFP_KERNEL); | ||
518 | if (!mtd_ram) { | ||
519 | panic("axisflashmap couldn't allocate memory for " | ||
520 | "mtd_info!\n"); | ||
521 | } | ||
522 | |||
523 | printk(KERN_INFO " Adding RAM partition for romfs image:\n"); | ||
524 | printk(pmsg, pidx, romfs_start, romfs_length); | ||
525 | |||
526 | err = mtdram_init_device(mtd_ram, (void*)romfs_start, | ||
527 | romfs_length, "romfs"); | ||
528 | if (err) { | ||
529 | panic("axisflashmap could not initialize MTD RAM " | ||
530 | "device!\n"); | ||
531 | } | ||
532 | #endif | ||
533 | } | ||
534 | |||
535 | return err; | ||
536 | } | ||
537 | |||
538 | /* This adds the above to the kernels init-call chain. */ | ||
539 | module_init(init_axis_flash); | ||
540 | |||
541 | EXPORT_SYMBOL(axisflash_mtd); | ||
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c new file mode 100644 index 000000000000..fba530fcfaeb --- /dev/null +++ b/arch/cris/arch-v10/drivers/ds1302.c | |||
@@ -0,0 +1,602 @@ | |||
1 | /*!*************************************************************************** | ||
2 | *! | ||
3 | *! FILE NAME : ds1302.c | ||
4 | *! | ||
5 | *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O | ||
6 | *! | ||
7 | *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init | ||
8 | *! | ||
9 | *! $Log: ds1302.c,v $ | ||
10 | *! Revision 1.14 2004/08/24 06:48:43 starvik | ||
11 | *! Whitespace cleanup | ||
12 | *! | ||
13 | *! Revision 1.13 2004/05/28 09:26:59 starvik | ||
14 | *! Modified I2C initialization to work in 2.6. | ||
15 | *! | ||
16 | *! Revision 1.12 2004/05/14 07:58:03 starvik | ||
17 | *! Merge of changes from 2.4 | ||
18 | *! | ||
19 | *! Revision 1.10 2004/02/04 09:25:12 starvik | ||
20 | *! Merge of Linux 2.6.2 | ||
21 | *! | ||
22 | *! Revision 1.9 2003/07/04 08:27:37 starvik | ||
23 | *! Merge of Linux 2.5.74 | ||
24 | *! | ||
25 | *! Revision 1.8 2003/04/09 05:20:47 starvik | ||
26 | *! Merge of Linux 2.5.67 | ||
27 | *! | ||
28 | *! Revision 1.6 2003/01/09 14:42:51 starvik | ||
29 | *! Merge of Linux 2.5.55 | ||
30 | *! | ||
31 | *! Revision 1.4 2002/12/11 13:13:57 starvik | ||
32 | *! Added arch/ to v10 specific includes | ||
33 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
34 | *! | ||
35 | *! Revision 1.3 2002/11/20 11:56:10 starvik | ||
36 | *! Merge of Linux 2.5.48 | ||
37 | *! | ||
38 | *! Revision 1.2 2002/11/18 13:16:06 starvik | ||
39 | *! Linux 2.5 port of latest 2.4 drivers | ||
40 | *! | ||
41 | *! Revision 1.15 2002/10/11 16:14:33 johana | ||
42 | *! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the | ||
43 | *! trcklecharge register. | ||
44 | *! | ||
45 | *! Revision 1.14 2002/10/10 12:15:38 magnusmn | ||
46 | *! Added support for having the RST signal on bit g0 | ||
47 | *! | ||
48 | *! Revision 1.13 2002/05/29 15:16:08 johana | ||
49 | *! Removed unused variables. | ||
50 | *! | ||
51 | *! Revision 1.12 2002/04/10 15:35:25 johana | ||
52 | *! Moved probe function closer to init function and marked it __init. | ||
53 | *! | ||
54 | *! Revision 1.11 2001/06/14 12:35:52 jonashg | ||
55 | *! The ATA hack is back. It is unfortunately the only way to set g27 to output. | ||
56 | *! | ||
57 | *! Revision 1.9 2001/06/14 10:00:14 jonashg | ||
58 | *! No need for tempudelay to be inline anymore (had to adjust the usec to | ||
59 | *! loops conversion because of this to make it slow enough to be a udelay). | ||
60 | *! | ||
61 | *! Revision 1.8 2001/06/14 08:06:32 jonashg | ||
62 | *! Made tempudelay delay usecs (well, just a tad more). | ||
63 | *! | ||
64 | *! Revision 1.7 2001/06/13 14:18:11 jonashg | ||
65 | *! Only allow processes with SYS_TIME capability to set time and charge. | ||
66 | *! | ||
67 | *! Revision 1.6 2001/06/12 15:22:07 jonashg | ||
68 | *! * Made init function __init. | ||
69 | *! * Parameter to out_byte() is unsigned char. | ||
70 | *! * The magic number 42 has got a name. | ||
71 | *! * Removed comment about /proc (nothing is exported there). | ||
72 | *! | ||
73 | *! Revision 1.5 2001/06/12 14:35:13 jonashg | ||
74 | *! Gave the module a name and added it to printk's. | ||
75 | *! | ||
76 | *! Revision 1.4 2001/05/31 14:53:40 jonashg | ||
77 | *! Made tempudelay() inline so that the watchdog doesn't reset (see | ||
78 | *! function comment). | ||
79 | *! | ||
80 | *! Revision 1.3 2001/03/26 16:03:06 bjornw | ||
81 | *! Needs linux/config.h | ||
82 | *! | ||
83 | *! Revision 1.2 2001/03/20 19:42:00 bjornw | ||
84 | *! Use the ETRAX prefix on the DS1302 options | ||
85 | *! | ||
86 | *! Revision 1.1 2001/03/20 09:13:50 magnusmn | ||
87 | *! Linux 2.4 port | ||
88 | *! | ||
89 | *! Revision 1.10 2000/07/05 15:38:23 bjornw | ||
90 | *! Dont update kernel time when a RTC_SET_TIME is done | ||
91 | *! | ||
92 | *! Revision 1.9 2000/03/02 15:42:59 macce | ||
93 | *! * Hack to make RTC work on all 2100/2400 | ||
94 | *! | ||
95 | *! Revision 1.8 2000/02/23 16:59:18 torbjore | ||
96 | *! added setup of R_GEN_CONFIG when RTC is connected to the generic port. | ||
97 | *! | ||
98 | *! Revision 1.7 2000/01/17 15:51:43 johana | ||
99 | *! Added RTC_SET_CHARGE ioctl to enable trickle charger. | ||
100 | *! | ||
101 | *! Revision 1.6 1999/10/27 13:19:47 bjornw | ||
102 | *! Added update_xtime_from_cmos which reads back the updated RTC into the kernel. | ||
103 | *! /dev/rtc calls it now. | ||
104 | *! | ||
105 | *! Revision 1.5 1999/10/27 12:39:37 bjornw | ||
106 | *! Disabled superuser check. Anyone can now set the time. | ||
107 | *! | ||
108 | *! Revision 1.4 1999/09/02 13:27:46 pkj | ||
109 | *! Added shadow for R_PORT_PB_CONFIG. | ||
110 | *! Renamed port_g_shadow to port_g_data_shadow. | ||
111 | *! | ||
112 | *! Revision 1.3 1999/09/02 08:28:06 pkj | ||
113 | *! Made it possible to select either port PB or the generic port for the RST | ||
114 | *! signal line to the DS1302 RTC. | ||
115 | *! Also make sure the RST bit is configured as output on Port PB (if used). | ||
116 | *! | ||
117 | *! Revision 1.2 1999/09/01 14:47:20 bjornw | ||
118 | *! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read | ||
119 | *! and set the date. Register as major 121. | ||
120 | *! | ||
121 | *! Revision 1.1 1999/09/01 09:45:29 bjornw | ||
122 | *! Implemented a DS1302 RTC driver. | ||
123 | *! | ||
124 | *! | ||
125 | *! --------------------------------------------------------------------------- | ||
126 | *! | ||
127 | *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN | ||
128 | *! | ||
129 | *! $Id: ds1302.c,v 1.14 2004/08/24 06:48:43 starvik Exp $ | ||
130 | *! | ||
131 | *!***************************************************************************/ | ||
132 | |||
133 | #include <linux/config.h> | ||
134 | |||
135 | #include <linux/fs.h> | ||
136 | #include <linux/init.h> | ||
137 | #include <linux/mm.h> | ||
138 | #include <linux/module.h> | ||
139 | #include <linux/miscdevice.h> | ||
140 | #include <linux/delay.h> | ||
141 | #include <linux/bcd.h> | ||
142 | |||
143 | #include <asm/uaccess.h> | ||
144 | #include <asm/system.h> | ||
145 | #include <asm/arch/svinto.h> | ||
146 | #include <asm/io.h> | ||
147 | #include <asm/rtc.h> | ||
148 | |||
149 | #define RTC_MAJOR_NR 121 /* local major, change later */ | ||
150 | |||
151 | static const char ds1302_name[] = "ds1302"; | ||
152 | |||
153 | /* The DS1302 might be connected to different bits on different products. | ||
154 | * It has three signals - SDA, SCL and RST. RST and SCL are always outputs, | ||
155 | * but SDA can have a selected direction. | ||
156 | * For now, only PORT_PB is hardcoded. | ||
157 | */ | ||
158 | |||
159 | /* The RST bit may be on either the Generic Port or Port PB. */ | ||
160 | #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT | ||
161 | #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) | ||
162 | #define TK_RST_DIR(x) | ||
163 | #else | ||
164 | #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) | ||
165 | #define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x) | ||
166 | #endif | ||
167 | |||
168 | |||
169 | #define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x) | ||
170 | #define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x) | ||
171 | |||
172 | #define TK_SDA_IN() ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1) | ||
173 | /* 1 is out, 0 is in */ | ||
174 | #define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SDABIT, x) | ||
175 | #define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x) | ||
176 | |||
177 | |||
178 | /* | ||
179 | * The reason for tempudelay and not udelay is that loops_per_usec | ||
180 | * (used in udelay) is not set when functions here are called from time.c | ||
181 | */ | ||
182 | |||
183 | static void tempudelay(int usecs) | ||
184 | { | ||
185 | volatile int loops; | ||
186 | |||
187 | for(loops = usecs * 12; loops > 0; loops--) | ||
188 | /* nothing */; | ||
189 | } | ||
190 | |||
191 | |||
192 | /* Send 8 bits. */ | ||
193 | static void | ||
194 | out_byte(unsigned char x) | ||
195 | { | ||
196 | int i; | ||
197 | TK_SDA_DIR(1); | ||
198 | for (i = 8; i--;) { | ||
199 | /* The chip latches incoming bits on the rising edge of SCL. */ | ||
200 | TK_SCL_OUT(0); | ||
201 | TK_SDA_OUT(x & 1); | ||
202 | tempudelay(1); | ||
203 | TK_SCL_OUT(1); | ||
204 | tempudelay(1); | ||
205 | x >>= 1; | ||
206 | } | ||
207 | TK_SDA_DIR(0); | ||
208 | } | ||
209 | |||
210 | static unsigned char | ||
211 | in_byte(void) | ||
212 | { | ||
213 | unsigned char x = 0; | ||
214 | int i; | ||
215 | |||
216 | /* Read byte. Bits come LSB first, on the falling edge of SCL. | ||
217 | * Assume SDA is in input direction already. | ||
218 | */ | ||
219 | TK_SDA_DIR(0); | ||
220 | |||
221 | for (i = 8; i--;) { | ||
222 | TK_SCL_OUT(0); | ||
223 | tempudelay(1); | ||
224 | x >>= 1; | ||
225 | x |= (TK_SDA_IN() << 7); | ||
226 | TK_SCL_OUT(1); | ||
227 | tempudelay(1); | ||
228 | } | ||
229 | |||
230 | return x; | ||
231 | } | ||
232 | |||
233 | /* Prepares for a transaction by de-activating RST (active-low). */ | ||
234 | |||
235 | static void | ||
236 | start(void) | ||
237 | { | ||
238 | TK_SCL_OUT(0); | ||
239 | tempudelay(1); | ||
240 | TK_RST_OUT(0); | ||
241 | tempudelay(5); | ||
242 | TK_RST_OUT(1); | ||
243 | } | ||
244 | |||
245 | /* Ends a transaction by taking RST active again. */ | ||
246 | |||
247 | static void | ||
248 | stop(void) | ||
249 | { | ||
250 | tempudelay(2); | ||
251 | TK_RST_OUT(0); | ||
252 | } | ||
253 | |||
254 | /* Enable writing. */ | ||
255 | |||
256 | static void | ||
257 | ds1302_wenable(void) | ||
258 | { | ||
259 | start(); | ||
260 | out_byte(0x8e); /* Write control register */ | ||
261 | out_byte(0x00); /* Disable write protect bit 7 = 0 */ | ||
262 | stop(); | ||
263 | } | ||
264 | |||
265 | /* Disable writing. */ | ||
266 | |||
267 | static void | ||
268 | ds1302_wdisable(void) | ||
269 | { | ||
270 | start(); | ||
271 | out_byte(0x8e); /* Write control register */ | ||
272 | out_byte(0x80); /* Disable write protect bit 7 = 0 */ | ||
273 | stop(); | ||
274 | } | ||
275 | |||
276 | |||
277 | |||
278 | /* Read a byte from the selected register in the DS1302. */ | ||
279 | |||
280 | unsigned char | ||
281 | ds1302_readreg(int reg) | ||
282 | { | ||
283 | unsigned char x; | ||
284 | |||
285 | start(); | ||
286 | out_byte(0x81 | (reg << 1)); /* read register */ | ||
287 | x = in_byte(); | ||
288 | stop(); | ||
289 | |||
290 | return x; | ||
291 | } | ||
292 | |||
293 | /* Write a byte to the selected register. */ | ||
294 | |||
295 | void | ||
296 | ds1302_writereg(int reg, unsigned char val) | ||
297 | { | ||
298 | #ifndef CONFIG_ETRAX_RTC_READONLY | ||
299 | int do_writereg = 1; | ||
300 | #else | ||
301 | int do_writereg = 0; | ||
302 | |||
303 | if (reg == RTC_TRICKLECHARGER) | ||
304 | do_writereg = 1; | ||
305 | #endif | ||
306 | |||
307 | if (do_writereg) { | ||
308 | ds1302_wenable(); | ||
309 | start(); | ||
310 | out_byte(0x80 | (reg << 1)); /* write register */ | ||
311 | out_byte(val); | ||
312 | stop(); | ||
313 | ds1302_wdisable(); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | void | ||
318 | get_rtc_time(struct rtc_time *rtc_tm) | ||
319 | { | ||
320 | unsigned long flags; | ||
321 | |||
322 | local_irq_save(flags); | ||
323 | local_irq_disable(); | ||
324 | |||
325 | rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); | ||
326 | rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); | ||
327 | rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); | ||
328 | rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); | ||
329 | rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); | ||
330 | rtc_tm->tm_year = CMOS_READ(RTC_YEAR); | ||
331 | |||
332 | local_irq_restore(flags); | ||
333 | |||
334 | BCD_TO_BIN(rtc_tm->tm_sec); | ||
335 | BCD_TO_BIN(rtc_tm->tm_min); | ||
336 | BCD_TO_BIN(rtc_tm->tm_hour); | ||
337 | BCD_TO_BIN(rtc_tm->tm_mday); | ||
338 | BCD_TO_BIN(rtc_tm->tm_mon); | ||
339 | BCD_TO_BIN(rtc_tm->tm_year); | ||
340 | |||
341 | /* | ||
342 | * Account for differences between how the RTC uses the values | ||
343 | * and how they are defined in a struct rtc_time; | ||
344 | */ | ||
345 | |||
346 | if (rtc_tm->tm_year <= 69) | ||
347 | rtc_tm->tm_year += 100; | ||
348 | |||
349 | rtc_tm->tm_mon--; | ||
350 | } | ||
351 | |||
352 | static unsigned char days_in_mo[] = | ||
353 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||
354 | |||
355 | /* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */ | ||
356 | |||
357 | static int | ||
358 | rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
359 | unsigned long arg) | ||
360 | { | ||
361 | unsigned long flags; | ||
362 | |||
363 | switch(cmd) { | ||
364 | case RTC_RD_TIME: /* read the time/date from RTC */ | ||
365 | { | ||
366 | struct rtc_time rtc_tm; | ||
367 | |||
368 | memset(&rtc_tm, 0, sizeof (struct rtc_time)); | ||
369 | get_rtc_time(&rtc_tm); | ||
370 | if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) | ||
371 | return -EFAULT; | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | case RTC_SET_TIME: /* set the RTC */ | ||
376 | { | ||
377 | struct rtc_time rtc_tm; | ||
378 | unsigned char mon, day, hrs, min, sec, leap_yr; | ||
379 | unsigned int yrs; | ||
380 | |||
381 | if (!capable(CAP_SYS_TIME)) | ||
382 | return -EPERM; | ||
383 | |||
384 | if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time))) | ||
385 | return -EFAULT; | ||
386 | |||
387 | yrs = rtc_tm.tm_year + 1900; | ||
388 | mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ | ||
389 | day = rtc_tm.tm_mday; | ||
390 | hrs = rtc_tm.tm_hour; | ||
391 | min = rtc_tm.tm_min; | ||
392 | sec = rtc_tm.tm_sec; | ||
393 | |||
394 | |||
395 | if ((yrs < 1970) || (yrs > 2069)) | ||
396 | return -EINVAL; | ||
397 | |||
398 | leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); | ||
399 | |||
400 | if ((mon > 12) || (day == 0)) | ||
401 | return -EINVAL; | ||
402 | |||
403 | if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) | ||
404 | return -EINVAL; | ||
405 | |||
406 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) | ||
407 | return -EINVAL; | ||
408 | |||
409 | if (yrs >= 2000) | ||
410 | yrs -= 2000; /* RTC (0, 1, ... 69) */ | ||
411 | else | ||
412 | yrs -= 1900; /* RTC (70, 71, ... 99) */ | ||
413 | |||
414 | BIN_TO_BCD(sec); | ||
415 | BIN_TO_BCD(min); | ||
416 | BIN_TO_BCD(hrs); | ||
417 | BIN_TO_BCD(day); | ||
418 | BIN_TO_BCD(mon); | ||
419 | BIN_TO_BCD(yrs); | ||
420 | |||
421 | local_irq_save(flags); | ||
422 | local_irq_disable(); | ||
423 | CMOS_WRITE(yrs, RTC_YEAR); | ||
424 | CMOS_WRITE(mon, RTC_MONTH); | ||
425 | CMOS_WRITE(day, RTC_DAY_OF_MONTH); | ||
426 | CMOS_WRITE(hrs, RTC_HOURS); | ||
427 | CMOS_WRITE(min, RTC_MINUTES); | ||
428 | CMOS_WRITE(sec, RTC_SECONDS); | ||
429 | local_irq_restore(flags); | ||
430 | |||
431 | /* Notice that at this point, the RTC is updated but | ||
432 | * the kernel is still running with the old time. | ||
433 | * You need to set that separately with settimeofday | ||
434 | * or adjtimex. | ||
435 | */ | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */ | ||
440 | { | ||
441 | int tcs_val; | ||
442 | |||
443 | if (!capable(CAP_SYS_TIME)) | ||
444 | return -EPERM; | ||
445 | |||
446 | if(copy_from_user(&tcs_val, (int*)arg, sizeof(int))) | ||
447 | return -EFAULT; | ||
448 | |||
449 | tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); | ||
450 | ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); | ||
451 | return 0; | ||
452 | } | ||
453 | case RTC_VLOW_RD: | ||
454 | { | ||
455 | /* TODO: | ||
456 | * Implement voltage low detection support | ||
457 | */ | ||
458 | printk(KERN_WARNING "DS1302: RTC Voltage Low detection" | ||
459 | " is not supported\n"); | ||
460 | return 0; | ||
461 | } | ||
462 | case RTC_VLOW_SET: | ||
463 | { | ||
464 | /* TODO: | ||
465 | * Nothing to do since Voltage Low detection is not supported | ||
466 | */ | ||
467 | return 0; | ||
468 | } | ||
469 | default: | ||
470 | return -ENOIOCTLCMD; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static void | ||
475 | print_rtc_status(void) | ||
476 | { | ||
477 | struct rtc_time tm; | ||
478 | |||
479 | get_rtc_time(&tm); | ||
480 | |||
481 | /* | ||
482 | * There is no way to tell if the luser has the RTC set for local | ||
483 | * time or for Universal Standard Time (GMT). Probably local though. | ||
484 | */ | ||
485 | |||
486 | printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n", | ||
487 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
488 | printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n", | ||
489 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); | ||
490 | } | ||
491 | |||
492 | /* The various file operations we support. */ | ||
493 | |||
494 | static struct file_operations rtc_fops = { | ||
495 | .owner = THIS_MODULE, | ||
496 | .ioctl = rtc_ioctl, | ||
497 | }; | ||
498 | |||
499 | /* Probe for the chip by writing something to its RAM and try reading it back. */ | ||
500 | |||
501 | #define MAGIC_PATTERN 0x42 | ||
502 | |||
503 | static int __init | ||
504 | ds1302_probe(void) | ||
505 | { | ||
506 | int retval, res; | ||
507 | |||
508 | TK_RST_DIR(1); | ||
509 | TK_SCL_DIR(1); | ||
510 | TK_SDA_DIR(0); | ||
511 | |||
512 | /* Try to talk to timekeeper. */ | ||
513 | |||
514 | ds1302_wenable(); | ||
515 | start(); | ||
516 | out_byte(0xc0); /* write RAM byte 0 */ | ||
517 | out_byte(MAGIC_PATTERN); /* write something magic */ | ||
518 | start(); | ||
519 | out_byte(0xc1); /* read RAM byte 0 */ | ||
520 | |||
521 | if((res = in_byte()) == MAGIC_PATTERN) { | ||
522 | stop(); | ||
523 | ds1302_wdisable(); | ||
524 | printk(KERN_INFO "%s: RTC found.\n", ds1302_name); | ||
525 | printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", | ||
526 | ds1302_name, | ||
527 | CONFIG_ETRAX_DS1302_SDABIT, | ||
528 | CONFIG_ETRAX_DS1302_SCLBIT, | ||
529 | #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT | ||
530 | "GENIO", | ||
531 | #else | ||
532 | "PB", | ||
533 | #endif | ||
534 | CONFIG_ETRAX_DS1302_RSTBIT); | ||
535 | print_rtc_status(); | ||
536 | retval = 1; | ||
537 | } else { | ||
538 | stop(); | ||
539 | retval = 0; | ||
540 | } | ||
541 | |||
542 | return retval; | ||
543 | } | ||
544 | |||
545 | |||
546 | /* Just probe for the RTC and register the device to handle the ioctl needed. */ | ||
547 | |||
548 | int __init | ||
549 | ds1302_init(void) | ||
550 | { | ||
551 | i2c_init(); | ||
552 | |||
553 | if (!ds1302_probe()) { | ||
554 | #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT | ||
555 | #if CONFIG_ETRAX_DS1302_RSTBIT == 27 | ||
556 | /* | ||
557 | * The only way to set g27 to output is to enable ATA. | ||
558 | * | ||
559 | * Make sure that R_GEN_CONFIG is setup correct. | ||
560 | */ | ||
561 | genconfig_shadow = ((genconfig_shadow & | ||
562 | ~IO_MASK(R_GEN_CONFIG, ata)) | | ||
563 | (IO_STATE(R_GEN_CONFIG, ata, select))); | ||
564 | *R_GEN_CONFIG = genconfig_shadow; | ||
565 | #elif CONFIG_ETRAX_DS1302_RSTBIT == 0 | ||
566 | |||
567 | /* Set the direction of this bit to out. */ | ||
568 | genconfig_shadow = ((genconfig_shadow & | ||
569 | ~IO_MASK(R_GEN_CONFIG, g0dir)) | | ||
570 | (IO_STATE(R_GEN_CONFIG, g0dir, out))); | ||
571 | *R_GEN_CONFIG = genconfig_shadow; | ||
572 | #endif | ||
573 | if (!ds1302_probe()) { | ||
574 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); | ||
575 | return -1; | ||
576 | } | ||
577 | #else | ||
578 | printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); | ||
579 | return -1; | ||
580 | #endif | ||
581 | } | ||
582 | /* Initialise trickle charger */ | ||
583 | ds1302_writereg(RTC_TRICKLECHARGER, | ||
584 | RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F)); | ||
585 | /* Start clock by resetting CLOCK_HALT */ | ||
586 | ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F)); | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int __init ds1302_register(void) | ||
591 | { | ||
592 | ds1302_init(); | ||
593 | if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) { | ||
594 | printk(KERN_INFO "%s: unable to get major %d for rtc\n", | ||
595 | ds1302_name, RTC_MAJOR_NR); | ||
596 | return -1; | ||
597 | } | ||
598 | return 0; | ||
599 | |||
600 | } | ||
601 | |||
602 | module_init(ds1302_register); | ||
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c new file mode 100644 index 000000000000..316ca15d6802 --- /dev/null +++ b/arch/cris/arch-v10/drivers/eeprom.c | |||
@@ -0,0 +1,945 @@ | |||
1 | /*!***************************************************************************** | ||
2 | *! | ||
3 | *! Implements an interface for i2c compatible eeproms to run under linux. | ||
4 | *! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by | ||
5 | *! Johan.Adolfsson@axis.com | ||
6 | *! | ||
7 | *! Probing results: | ||
8 | *! 8k or not is detected (the assumes 2k or 16k) | ||
9 | *! 2k or 16k detected using test reads and writes. | ||
10 | *! | ||
11 | *!------------------------------------------------------------------------ | ||
12 | *! HISTORY | ||
13 | *! | ||
14 | *! DATE NAME CHANGES | ||
15 | *! ---- ---- ------- | ||
16 | *! Aug 28 1999 Edgar Iglesias Initial Version | ||
17 | *! Aug 31 1999 Edgar Iglesias Allow simultaneous users. | ||
18 | *! Sep 03 1999 Edgar Iglesias Updated probe. | ||
19 | *! Sep 03 1999 Edgar Iglesias Added bail-out stuff if we get interrupted | ||
20 | *! in the spin-lock. | ||
21 | *! | ||
22 | *! $Log: eeprom.c,v $ | ||
23 | *! Revision 1.10 2003/09/11 07:29:48 starvik | ||
24 | *! Merge of Linux 2.6.0-test5 | ||
25 | *! | ||
26 | *! Revision 1.9 2003/07/04 08:27:37 starvik | ||
27 | *! Merge of Linux 2.5.74 | ||
28 | *! | ||
29 | *! Revision 1.8 2003/04/09 05:20:47 starvik | ||
30 | *! Merge of Linux 2.5.67 | ||
31 | *! | ||
32 | *! Revision 1.6 2003/02/10 07:19:28 starvik | ||
33 | *! Removed misplaced ; | ||
34 | *! | ||
35 | *! Revision 1.5 2002/12/11 13:13:57 starvik | ||
36 | *! Added arch/ to v10 specific includes | ||
37 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
38 | *! | ||
39 | *! Revision 1.4 2002/11/20 11:56:10 starvik | ||
40 | *! Merge of Linux 2.5.48 | ||
41 | *! | ||
42 | *! Revision 1.3 2002/11/18 13:16:06 starvik | ||
43 | *! Linux 2.5 port of latest 2.4 drivers | ||
44 | *! | ||
45 | *! Revision 1.8 2001/06/15 13:24:29 jonashg | ||
46 | *! * Added verification of pointers from userspace in read and write. | ||
47 | *! * Made busy counter volatile. | ||
48 | *! * Added define for inital write delay. | ||
49 | *! * Removed warnings by using loff_t instead of unsigned long. | ||
50 | *! | ||
51 | *! Revision 1.7 2001/06/14 15:26:54 jonashg | ||
52 | *! Removed test because condition is always true. | ||
53 | *! | ||
54 | *! Revision 1.6 2001/06/14 15:18:20 jonashg | ||
55 | *! Kb -> kB (makes quite a difference if you don't know if you have 2k or 16k). | ||
56 | *! | ||
57 | *! Revision 1.5 2001/06/14 14:39:51 jonashg | ||
58 | *! Forgot to use name when registering the driver. | ||
59 | *! | ||
60 | *! Revision 1.4 2001/06/14 14:35:47 jonashg | ||
61 | *! * Gave driver a name and used it in printk's. | ||
62 | *! * Cleanup. | ||
63 | *! | ||
64 | *! Revision 1.3 2001/03/19 16:04:46 markusl | ||
65 | *! Fixed init of fops struct | ||
66 | *! | ||
67 | *! Revision 1.2 2001/03/19 10:35:07 markusl | ||
68 | *! 2.4 port of eeprom driver | ||
69 | *! | ||
70 | *! Revision 1.8 2000/05/18 10:42:25 edgar | ||
71 | *! Make sure to end write cycle on _every_ write | ||
72 | *! | ||
73 | *! Revision 1.7 2000/01/17 17:41:01 johana | ||
74 | *! Adjusted probing and return -ENOSPC when writing outside EEPROM | ||
75 | *! | ||
76 | *! Revision 1.6 2000/01/17 15:50:36 johana | ||
77 | *! Added adaptive timing adjustments and fixed autoprobing for 2k and 16k(?) | ||
78 | *! EEPROMs | ||
79 | *! | ||
80 | *! Revision 1.5 1999/09/03 15:07:37 edgar | ||
81 | *! Added bail-out check to the spinlock | ||
82 | *! | ||
83 | *! Revision 1.4 1999/09/03 12:11:17 bjornw | ||
84 | *! Proper atomicity (need to use spinlocks, not if's). users -> busy. | ||
85 | *! | ||
86 | *! | ||
87 | *! (c) 1999 Axis Communications AB, Lund, Sweden | ||
88 | *!*****************************************************************************/ | ||
89 | |||
90 | #include <linux/config.h> | ||
91 | #include <linux/kernel.h> | ||
92 | #include <linux/sched.h> | ||
93 | #include <linux/fs.h> | ||
94 | #include <linux/init.h> | ||
95 | #include <linux/delay.h> | ||
96 | #include <linux/interrupt.h> | ||
97 | #include <asm/uaccess.h> | ||
98 | #include "i2c.h" | ||
99 | |||
100 | #define D(x) | ||
101 | |||
102 | /* If we should use adaptive timing or not: */ | ||
103 | //#define EEPROM_ADAPTIVE_TIMING | ||
104 | |||
105 | #define EEPROM_MAJOR_NR 122 /* use a LOCAL/EXPERIMENTAL major for now */ | ||
106 | #define EEPROM_MINOR_NR 0 | ||
107 | |||
108 | /* Empirical sane initial value of the delay, the value will be adapted to | ||
109 | * what the chip needs when using EEPROM_ADAPTIVE_TIMING. | ||
110 | */ | ||
111 | #define INITIAL_WRITEDELAY_US 4000 | ||
112 | #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */ | ||
113 | |||
114 | /* This one defines how many times to try when eeprom fails. */ | ||
115 | #define EEPROM_RETRIES 10 | ||
116 | |||
117 | #define EEPROM_2KB (2 * 1024) | ||
118 | /*#define EEPROM_4KB (4 * 1024)*/ /* Exists but not used in Axis products */ | ||
119 | #define EEPROM_8KB (8 * 1024 - 1 ) /* Last byte has write protection bit */ | ||
120 | #define EEPROM_16KB (16 * 1024) | ||
121 | |||
122 | #define i2c_delay(x) udelay(x) | ||
123 | |||
124 | /* | ||
125 | * This structure describes the attached eeprom chip. | ||
126 | * The values are probed for. | ||
127 | */ | ||
128 | |||
129 | struct eeprom_type | ||
130 | { | ||
131 | unsigned long size; | ||
132 | unsigned long sequential_write_pagesize; | ||
133 | unsigned char select_cmd; | ||
134 | unsigned long usec_delay_writecycles; /* Min time between write cycles | ||
135 | (up to 10ms for some models) */ | ||
136 | unsigned long usec_delay_step; /* For adaptive algorithm */ | ||
137 | int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */ | ||
138 | |||
139 | /* this one is to keep the read/write operations atomic */ | ||
140 | wait_queue_head_t wait_q; | ||
141 | volatile int busy; | ||
142 | int retry_cnt_addr; /* Used to keep track of number of retries for | ||
143 | adaptive timing adjustments */ | ||
144 | int retry_cnt_read; | ||
145 | }; | ||
146 | |||
147 | static int eeprom_open(struct inode * inode, struct file * file); | ||
148 | static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig); | ||
149 | static ssize_t eeprom_read(struct file * file, char * buf, size_t count, | ||
150 | loff_t *off); | ||
151 | static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | ||
152 | loff_t *off); | ||
153 | static int eeprom_close(struct inode * inode, struct file * file); | ||
154 | |||
155 | static int eeprom_address(unsigned long addr); | ||
156 | static int read_from_eeprom(char * buf, int count); | ||
157 | static int eeprom_write_buf(loff_t addr, const char * buf, int count); | ||
158 | static int eeprom_read_buf(loff_t addr, char * buf, int count); | ||
159 | |||
160 | static void eeprom_disable_write_protect(void); | ||
161 | |||
162 | |||
163 | static const char eeprom_name[] = "eeprom"; | ||
164 | |||
165 | /* chip description */ | ||
166 | static struct eeprom_type eeprom; | ||
167 | |||
168 | /* This is the exported file-operations structure for this device. */ | ||
169 | struct file_operations eeprom_fops = | ||
170 | { | ||
171 | .llseek = eeprom_lseek, | ||
172 | .read = eeprom_read, | ||
173 | .write = eeprom_write, | ||
174 | .open = eeprom_open, | ||
175 | .release = eeprom_close | ||
176 | }; | ||
177 | |||
178 | /* eeprom init call. Probes for different eeprom models. */ | ||
179 | |||
180 | int __init eeprom_init(void) | ||
181 | { | ||
182 | init_waitqueue_head(&eeprom.wait_q); | ||
183 | eeprom.busy = 0; | ||
184 | |||
185 | #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE | ||
186 | #define EETEXT "Found" | ||
187 | #else | ||
188 | #define EETEXT "Assuming" | ||
189 | #endif | ||
190 | if (register_chrdev(EEPROM_MAJOR_NR, eeprom_name, &eeprom_fops)) | ||
191 | { | ||
192 | printk(KERN_INFO "%s: unable to get major %d for eeprom device\n", | ||
193 | eeprom_name, EEPROM_MAJOR_NR); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | printk("EEPROM char device v0.3, (c) 2000 Axis Communications AB\n"); | ||
198 | |||
199 | /* | ||
200 | * Note: Most of this probing method was taken from the printserver (5470e) | ||
201 | * codebase. It did not contain a way of finding the 16kB chips | ||
202 | * (M24128 or variants). The method used here might not work | ||
203 | * for all models. If you encounter problems the easiest way | ||
204 | * is probably to define your model within #ifdef's, and hard- | ||
205 | * code it. | ||
206 | */ | ||
207 | |||
208 | eeprom.size = 0; | ||
209 | eeprom.usec_delay_writecycles = INITIAL_WRITEDELAY_US; | ||
210 | eeprom.usec_delay_step = 128; | ||
211 | eeprom.adapt_state = 0; | ||
212 | |||
213 | #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE | ||
214 | i2c_start(); | ||
215 | i2c_outbyte(0x80); | ||
216 | if(!i2c_getack()) | ||
217 | { | ||
218 | /* It's not 8k.. */ | ||
219 | int success = 0; | ||
220 | unsigned char buf_2k_start[16]; | ||
221 | |||
222 | /* Im not sure this will work... :) */ | ||
223 | /* assume 2kB, if failure go for 16kB */ | ||
224 | /* Test with 16kB settings.. */ | ||
225 | /* If it's a 2kB EEPROM and we address it outside it's range | ||
226 | * it will mirror the address space: | ||
227 | * 1. We read two locations (that are mirrored), | ||
228 | * if the content differs * it's a 16kB EEPROM. | ||
229 | * 2. if it doesn't differ - write different value to one of the locations, | ||
230 | * check the other - if content still is the same it's a 2k EEPROM, | ||
231 | * restore original data. | ||
232 | */ | ||
233 | #define LOC1 8 | ||
234 | #define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */ | ||
235 | |||
236 | /* 2k settings */ | ||
237 | i2c_stop(); | ||
238 | eeprom.size = EEPROM_2KB; | ||
239 | eeprom.select_cmd = 0xA0; | ||
240 | eeprom.sequential_write_pagesize = 16; | ||
241 | if( eeprom_read_buf( 0, buf_2k_start, 16 ) == 16 ) | ||
242 | { | ||
243 | D(printk("2k start: '%16.16s'\n", buf_2k_start)); | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | printk(KERN_INFO "%s: Failed to read in 2k mode!\n", eeprom_name); | ||
248 | } | ||
249 | |||
250 | /* 16k settings */ | ||
251 | eeprom.size = EEPROM_16KB; | ||
252 | eeprom.select_cmd = 0xA0; | ||
253 | eeprom.sequential_write_pagesize = 64; | ||
254 | |||
255 | { | ||
256 | unsigned char loc1[4], loc2[4], tmp[4]; | ||
257 | if( eeprom_read_buf(LOC2, loc2, 4) == 4) | ||
258 | { | ||
259 | if( eeprom_read_buf(LOC1, loc1, 4) == 4) | ||
260 | { | ||
261 | D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", | ||
262 | LOC1, loc1, LOC2, loc2)); | ||
263 | #if 0 | ||
264 | if (memcmp(loc1, loc2, 4) != 0 ) | ||
265 | { | ||
266 | /* It's 16k */ | ||
267 | printk(KERN_INFO "%s: 16k detected in step 1\n", eeprom_name); | ||
268 | eeprom.size = EEPROM_16KB; | ||
269 | success = 1; | ||
270 | } | ||
271 | else | ||
272 | #endif | ||
273 | { | ||
274 | /* Do step 2 check */ | ||
275 | /* Invert value */ | ||
276 | loc1[0] = ~loc1[0]; | ||
277 | if (eeprom_write_buf(LOC1, loc1, 1) == 1) | ||
278 | { | ||
279 | /* If 2k EEPROM this write will actually write 10 bytes | ||
280 | * from pos 0 | ||
281 | */ | ||
282 | D(printk("1 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", | ||
283 | LOC1, loc1, LOC2, loc2)); | ||
284 | if( eeprom_read_buf(LOC1, tmp, 4) == 4) | ||
285 | { | ||
286 | D(printk("2 loc1: (%i) '%4.4s' tmp '%4.4s'\n", | ||
287 | LOC1, loc1, tmp)); | ||
288 | if (memcmp(loc1, tmp, 4) != 0 ) | ||
289 | { | ||
290 | printk(KERN_INFO "%s: read and write differs! Not 16kB\n", | ||
291 | eeprom_name); | ||
292 | loc1[0] = ~loc1[0]; | ||
293 | |||
294 | if (eeprom_write_buf(LOC1, loc1, 1) == 1) | ||
295 | { | ||
296 | success = 1; | ||
297 | } | ||
298 | else | ||
299 | { | ||
300 | printk(KERN_INFO "%s: Restore 2k failed during probe," | ||
301 | " EEPROM might be corrupt!\n", eeprom_name); | ||
302 | |||
303 | } | ||
304 | i2c_stop(); | ||
305 | /* Go to 2k mode and write original data */ | ||
306 | eeprom.size = EEPROM_2KB; | ||
307 | eeprom.select_cmd = 0xA0; | ||
308 | eeprom.sequential_write_pagesize = 16; | ||
309 | if( eeprom_write_buf(0, buf_2k_start, 16) == 16) | ||
310 | { | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | printk(KERN_INFO "%s: Failed to write back 2k start!\n", | ||
315 | eeprom_name); | ||
316 | } | ||
317 | |||
318 | eeprom.size = EEPROM_2KB; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | if(!success) | ||
323 | { | ||
324 | if( eeprom_read_buf(LOC2, loc2, 1) == 1) | ||
325 | { | ||
326 | D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", | ||
327 | LOC1, loc1, LOC2, loc2)); | ||
328 | if (memcmp(loc1, loc2, 4) == 0 ) | ||
329 | { | ||
330 | /* Data the same, must be mirrored -> 2k */ | ||
331 | /* Restore data */ | ||
332 | printk(KERN_INFO "%s: 2k detected in step 2\n", eeprom_name); | ||
333 | loc1[0] = ~loc1[0]; | ||
334 | if (eeprom_write_buf(LOC1, loc1, 1) == 1) | ||
335 | { | ||
336 | success = 1; | ||
337 | } | ||
338 | else | ||
339 | { | ||
340 | printk(KERN_INFO "%s: Restore 2k failed during probe," | ||
341 | " EEPROM might be corrupt!\n", eeprom_name); | ||
342 | |||
343 | } | ||
344 | |||
345 | eeprom.size = EEPROM_2KB; | ||
346 | } | ||
347 | else | ||
348 | { | ||
349 | printk(KERN_INFO "%s: 16k detected in step 2\n", | ||
350 | eeprom_name); | ||
351 | loc1[0] = ~loc1[0]; | ||
352 | /* Data differs, assume 16k */ | ||
353 | /* Restore data */ | ||
354 | if (eeprom_write_buf(LOC1, loc1, 1) == 1) | ||
355 | { | ||
356 | success = 1; | ||
357 | } | ||
358 | else | ||
359 | { | ||
360 | printk(KERN_INFO "%s: Restore 16k failed during probe," | ||
361 | " EEPROM might be corrupt!\n", eeprom_name); | ||
362 | } | ||
363 | |||
364 | eeprom.size = EEPROM_16KB; | ||
365 | } | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | } /* read LOC1 */ | ||
370 | } /* address LOC1 */ | ||
371 | if (!success) | ||
372 | { | ||
373 | printk(KERN_INFO "%s: Probing failed!, using 2KB!\n", eeprom_name); | ||
374 | eeprom.size = EEPROM_2KB; | ||
375 | } | ||
376 | } /* read */ | ||
377 | } | ||
378 | } | ||
379 | else | ||
380 | { | ||
381 | i2c_outbyte(0x00); | ||
382 | if(!i2c_getack()) | ||
383 | { | ||
384 | /* No 8k */ | ||
385 | eeprom.size = EEPROM_2KB; | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | i2c_start(); | ||
390 | i2c_outbyte(0x81); | ||
391 | if (!i2c_getack()) | ||
392 | { | ||
393 | eeprom.size = EEPROM_2KB; | ||
394 | } | ||
395 | else | ||
396 | { | ||
397 | /* It's a 8kB */ | ||
398 | i2c_inbyte(); | ||
399 | eeprom.size = EEPROM_8KB; | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | i2c_stop(); | ||
404 | #elif defined(CONFIG_ETRAX_I2C_EEPROM_16KB) | ||
405 | eeprom.size = EEPROM_16KB; | ||
406 | #elif defined(CONFIG_ETRAX_I2C_EEPROM_8KB) | ||
407 | eeprom.size = EEPROM_8KB; | ||
408 | #elif defined(CONFIG_ETRAX_I2C_EEPROM_2KB) | ||
409 | eeprom.size = EEPROM_2KB; | ||
410 | #endif | ||
411 | |||
412 | switch(eeprom.size) | ||
413 | { | ||
414 | case (EEPROM_2KB): | ||
415 | printk("%s: " EETEXT " i2c compatible 2kB eeprom.\n", eeprom_name); | ||
416 | eeprom.sequential_write_pagesize = 16; | ||
417 | eeprom.select_cmd = 0xA0; | ||
418 | break; | ||
419 | case (EEPROM_8KB): | ||
420 | printk("%s: " EETEXT " i2c compatible 8kB eeprom.\n", eeprom_name); | ||
421 | eeprom.sequential_write_pagesize = 16; | ||
422 | eeprom.select_cmd = 0x80; | ||
423 | break; | ||
424 | case (EEPROM_16KB): | ||
425 | printk("%s: " EETEXT " i2c compatible 16kB eeprom.\n", eeprom_name); | ||
426 | eeprom.sequential_write_pagesize = 64; | ||
427 | eeprom.select_cmd = 0xA0; | ||
428 | break; | ||
429 | default: | ||
430 | eeprom.size = 0; | ||
431 | printk("%s: Did not find a supported eeprom\n", eeprom_name); | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | |||
436 | |||
437 | eeprom_disable_write_protect(); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | /* Opens the device. */ | ||
443 | |||
444 | static int eeprom_open(struct inode * inode, struct file * file) | ||
445 | { | ||
446 | |||
447 | if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR) | ||
448 | return -ENXIO; | ||
449 | if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR) | ||
450 | return -ENXIO; | ||
451 | |||
452 | if( eeprom.size > 0 ) | ||
453 | { | ||
454 | /* OK */ | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | /* No EEprom found */ | ||
459 | return -EFAULT; | ||
460 | } | ||
461 | |||
462 | /* Changes the current file position. */ | ||
463 | |||
464 | static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) | ||
465 | { | ||
466 | /* | ||
467 | * orig 0: position from begning of eeprom | ||
468 | * orig 1: relative from current position | ||
469 | * orig 2: position from last eeprom address | ||
470 | */ | ||
471 | |||
472 | switch (orig) | ||
473 | { | ||
474 | case 0: | ||
475 | file->f_pos = offset; | ||
476 | break; | ||
477 | case 1: | ||
478 | file->f_pos += offset; | ||
479 | break; | ||
480 | case 2: | ||
481 | file->f_pos = eeprom.size - offset; | ||
482 | break; | ||
483 | default: | ||
484 | return -EINVAL; | ||
485 | } | ||
486 | |||
487 | /* truncate position */ | ||
488 | if (file->f_pos < 0) | ||
489 | { | ||
490 | file->f_pos = 0; | ||
491 | return(-EOVERFLOW); | ||
492 | } | ||
493 | |||
494 | if (file->f_pos >= eeprom.size) | ||
495 | { | ||
496 | file->f_pos = eeprom.size - 1; | ||
497 | return(-EOVERFLOW); | ||
498 | } | ||
499 | |||
500 | return ( file->f_pos ); | ||
501 | } | ||
502 | |||
503 | /* Reads data from eeprom. */ | ||
504 | |||
505 | static int eeprom_read_buf(loff_t addr, char * buf, int count) | ||
506 | { | ||
507 | struct file f; | ||
508 | |||
509 | f.f_pos = addr; | ||
510 | return eeprom_read(&f, buf, count, &addr); | ||
511 | } | ||
512 | |||
513 | |||
514 | |||
515 | /* Reads data from eeprom. */ | ||
516 | |||
517 | static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) | ||
518 | { | ||
519 | int read=0; | ||
520 | unsigned long p = file->f_pos; | ||
521 | |||
522 | unsigned char page; | ||
523 | |||
524 | if(p >= eeprom.size) /* Address i 0 - (size-1) */ | ||
525 | { | ||
526 | return -EFAULT; | ||
527 | } | ||
528 | |||
529 | while(eeprom.busy) | ||
530 | { | ||
531 | interruptible_sleep_on(&eeprom.wait_q); | ||
532 | |||
533 | /* bail out if we get interrupted */ | ||
534 | if (signal_pending(current)) | ||
535 | return -EINTR; | ||
536 | |||
537 | } | ||
538 | eeprom.busy++; | ||
539 | |||
540 | page = (unsigned char) (p >> 8); | ||
541 | |||
542 | if(!eeprom_address(p)) | ||
543 | { | ||
544 | printk(KERN_INFO "%s: Read failed to address the eeprom: " | ||
545 | "0x%08X (%i) page: %i\n", eeprom_name, (int)p, (int)p, page); | ||
546 | i2c_stop(); | ||
547 | |||
548 | /* don't forget to wake them up */ | ||
549 | eeprom.busy--; | ||
550 | wake_up_interruptible(&eeprom.wait_q); | ||
551 | return -EFAULT; | ||
552 | } | ||
553 | |||
554 | if( (p + count) > eeprom.size) | ||
555 | { | ||
556 | /* truncate count */ | ||
557 | count = eeprom.size - p; | ||
558 | } | ||
559 | |||
560 | /* stop dummy write op and initiate the read op */ | ||
561 | i2c_start(); | ||
562 | |||
563 | /* special case for small eeproms */ | ||
564 | if(eeprom.size < EEPROM_16KB) | ||
565 | { | ||
566 | i2c_outbyte( eeprom.select_cmd | 1 | (page << 1) ); | ||
567 | } | ||
568 | |||
569 | /* go on with the actual read */ | ||
570 | read = read_from_eeprom( buf, count); | ||
571 | |||
572 | if(read > 0) | ||
573 | { | ||
574 | file->f_pos += read; | ||
575 | } | ||
576 | |||
577 | eeprom.busy--; | ||
578 | wake_up_interruptible(&eeprom.wait_q); | ||
579 | return read; | ||
580 | } | ||
581 | |||
582 | /* Writes data to eeprom. */ | ||
583 | |||
584 | static int eeprom_write_buf(loff_t addr, const char * buf, int count) | ||
585 | { | ||
586 | struct file f; | ||
587 | |||
588 | f.f_pos = addr; | ||
589 | |||
590 | return eeprom_write(&f, buf, count, &addr); | ||
591 | } | ||
592 | |||
593 | |||
594 | /* Writes data to eeprom. */ | ||
595 | |||
596 | static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | ||
597 | loff_t *off) | ||
598 | { | ||
599 | int i, written, restart=1; | ||
600 | unsigned long p; | ||
601 | |||
602 | if (!access_ok(VERIFY_READ, buf, count)) | ||
603 | { | ||
604 | return -EFAULT; | ||
605 | } | ||
606 | |||
607 | while(eeprom.busy) | ||
608 | { | ||
609 | interruptible_sleep_on(&eeprom.wait_q); | ||
610 | /* bail out if we get interrupted */ | ||
611 | if (signal_pending(current)) | ||
612 | return -EINTR; | ||
613 | } | ||
614 | eeprom.busy++; | ||
615 | for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) | ||
616 | { | ||
617 | restart = 0; | ||
618 | written = 0; | ||
619 | p = file->f_pos; | ||
620 | |||
621 | |||
622 | while( (written < count) && (p < eeprom.size)) | ||
623 | { | ||
624 | /* address the eeprom */ | ||
625 | if(!eeprom_address(p)) | ||
626 | { | ||
627 | printk(KERN_INFO "%s: Write failed to address the eeprom: " | ||
628 | "0x%08X (%i) \n", eeprom_name, (int)p, (int)p); | ||
629 | i2c_stop(); | ||
630 | |||
631 | /* don't forget to wake them up */ | ||
632 | eeprom.busy--; | ||
633 | wake_up_interruptible(&eeprom.wait_q); | ||
634 | return -EFAULT; | ||
635 | } | ||
636 | #ifdef EEPROM_ADAPTIVE_TIMING | ||
637 | /* Adaptive algorithm to adjust timing */ | ||
638 | if (eeprom.retry_cnt_addr > 0) | ||
639 | { | ||
640 | /* To Low now */ | ||
641 | D(printk(">D=%i d=%i\n", | ||
642 | eeprom.usec_delay_writecycles, eeprom.usec_delay_step)); | ||
643 | |||
644 | if (eeprom.usec_delay_step < 4) | ||
645 | { | ||
646 | eeprom.usec_delay_step++; | ||
647 | eeprom.usec_delay_writecycles += eeprom.usec_delay_step; | ||
648 | } | ||
649 | else | ||
650 | { | ||
651 | |||
652 | if (eeprom.adapt_state > 0) | ||
653 | { | ||
654 | /* To Low before */ | ||
655 | eeprom.usec_delay_step *= 2; | ||
656 | if (eeprom.usec_delay_step > 2) | ||
657 | { | ||
658 | eeprom.usec_delay_step--; | ||
659 | } | ||
660 | eeprom.usec_delay_writecycles += eeprom.usec_delay_step; | ||
661 | } | ||
662 | else if (eeprom.adapt_state < 0) | ||
663 | { | ||
664 | /* To High before (toggle dir) */ | ||
665 | eeprom.usec_delay_writecycles += eeprom.usec_delay_step; | ||
666 | if (eeprom.usec_delay_step > 1) | ||
667 | { | ||
668 | eeprom.usec_delay_step /= 2; | ||
669 | eeprom.usec_delay_step--; | ||
670 | } | ||
671 | } | ||
672 | } | ||
673 | |||
674 | eeprom.adapt_state = 1; | ||
675 | } | ||
676 | else | ||
677 | { | ||
678 | /* To High (or good) now */ | ||
679 | D(printk("<D=%i d=%i\n", | ||
680 | eeprom.usec_delay_writecycles, eeprom.usec_delay_step)); | ||
681 | |||
682 | if (eeprom.adapt_state < 0) | ||
683 | { | ||
684 | /* To High before */ | ||
685 | if (eeprom.usec_delay_step > 1) | ||
686 | { | ||
687 | eeprom.usec_delay_step *= 2; | ||
688 | eeprom.usec_delay_step--; | ||
689 | |||
690 | if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step) | ||
691 | { | ||
692 | eeprom.usec_delay_writecycles -= eeprom.usec_delay_step; | ||
693 | } | ||
694 | } | ||
695 | } | ||
696 | else if (eeprom.adapt_state > 0) | ||
697 | { | ||
698 | /* To Low before (toggle dir) */ | ||
699 | if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step) | ||
700 | { | ||
701 | eeprom.usec_delay_writecycles -= eeprom.usec_delay_step; | ||
702 | } | ||
703 | if (eeprom.usec_delay_step > 1) | ||
704 | { | ||
705 | eeprom.usec_delay_step /= 2; | ||
706 | eeprom.usec_delay_step--; | ||
707 | } | ||
708 | |||
709 | eeprom.adapt_state = -1; | ||
710 | } | ||
711 | |||
712 | if (eeprom.adapt_state > -100) | ||
713 | { | ||
714 | eeprom.adapt_state--; | ||
715 | } | ||
716 | else | ||
717 | { | ||
718 | /* Restart adaption */ | ||
719 | D(printk("#Restart\n")); | ||
720 | eeprom.usec_delay_step++; | ||
721 | } | ||
722 | } | ||
723 | #endif /* EEPROM_ADAPTIVE_TIMING */ | ||
724 | /* write until we hit a page boundary or count */ | ||
725 | do | ||
726 | { | ||
727 | i2c_outbyte(buf[written]); | ||
728 | if(!i2c_getack()) | ||
729 | { | ||
730 | restart=1; | ||
731 | printk(KERN_INFO "%s: write error, retrying. %d\n", eeprom_name, i); | ||
732 | i2c_stop(); | ||
733 | break; | ||
734 | } | ||
735 | written++; | ||
736 | p++; | ||
737 | } while( written < count && ( p % eeprom.sequential_write_pagesize )); | ||
738 | |||
739 | /* end write cycle */ | ||
740 | i2c_stop(); | ||
741 | i2c_delay(eeprom.usec_delay_writecycles); | ||
742 | } /* while */ | ||
743 | } /* for */ | ||
744 | |||
745 | eeprom.busy--; | ||
746 | wake_up_interruptible(&eeprom.wait_q); | ||
747 | if (written == 0 && file->f_pos >= eeprom.size){ | ||
748 | return -ENOSPC; | ||
749 | } | ||
750 | file->f_pos += written; | ||
751 | return written; | ||
752 | } | ||
753 | |||
754 | /* Closes the device. */ | ||
755 | |||
756 | static int eeprom_close(struct inode * inode, struct file * file) | ||
757 | { | ||
758 | /* do nothing for now */ | ||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | /* Sets the current address of the eeprom. */ | ||
763 | |||
764 | static int eeprom_address(unsigned long addr) | ||
765 | { | ||
766 | int i; | ||
767 | unsigned char page, offset; | ||
768 | |||
769 | page = (unsigned char) (addr >> 8); | ||
770 | offset = (unsigned char) addr; | ||
771 | |||
772 | for(i = 0; i < EEPROM_RETRIES; i++) | ||
773 | { | ||
774 | /* start a dummy write for addressing */ | ||
775 | i2c_start(); | ||
776 | |||
777 | if(eeprom.size == EEPROM_16KB) | ||
778 | { | ||
779 | i2c_outbyte( eeprom.select_cmd ); | ||
780 | i2c_getack(); | ||
781 | i2c_outbyte(page); | ||
782 | } | ||
783 | else | ||
784 | { | ||
785 | i2c_outbyte( eeprom.select_cmd | (page << 1) ); | ||
786 | } | ||
787 | if(!i2c_getack()) | ||
788 | { | ||
789 | /* retry */ | ||
790 | i2c_stop(); | ||
791 | /* Must have a delay here.. 500 works, >50, 100->works 5th time*/ | ||
792 | i2c_delay(MAX_WRITEDELAY_US / EEPROM_RETRIES * i); | ||
793 | /* The chip needs up to 10 ms from write stop to next start */ | ||
794 | |||
795 | } | ||
796 | else | ||
797 | { | ||
798 | i2c_outbyte(offset); | ||
799 | |||
800 | if(!i2c_getack()) | ||
801 | { | ||
802 | /* retry */ | ||
803 | i2c_stop(); | ||
804 | } | ||
805 | else | ||
806 | break; | ||
807 | } | ||
808 | } | ||
809 | |||
810 | |||
811 | eeprom.retry_cnt_addr = i; | ||
812 | D(printk("%i\n", eeprom.retry_cnt_addr)); | ||
813 | if(eeprom.retry_cnt_addr == EEPROM_RETRIES) | ||
814 | { | ||
815 | /* failed */ | ||
816 | return 0; | ||
817 | } | ||
818 | return 1; | ||
819 | } | ||
820 | |||
821 | /* Reads from current address. */ | ||
822 | |||
823 | static int read_from_eeprom(char * buf, int count) | ||
824 | { | ||
825 | int i, read=0; | ||
826 | |||
827 | for(i = 0; i < EEPROM_RETRIES; i++) | ||
828 | { | ||
829 | if(eeprom.size == EEPROM_16KB) | ||
830 | { | ||
831 | i2c_outbyte( eeprom.select_cmd | 1 ); | ||
832 | } | ||
833 | |||
834 | if(i2c_getack()) | ||
835 | { | ||
836 | break; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | if(i == EEPROM_RETRIES) | ||
841 | { | ||
842 | printk(KERN_INFO "%s: failed to read from eeprom\n", eeprom_name); | ||
843 | i2c_stop(); | ||
844 | |||
845 | return -EFAULT; | ||
846 | } | ||
847 | |||
848 | while( (read < count)) | ||
849 | { | ||
850 | if (put_user(i2c_inbyte(), &buf[read++])) | ||
851 | { | ||
852 | i2c_stop(); | ||
853 | |||
854 | return -EFAULT; | ||
855 | } | ||
856 | |||
857 | /* | ||
858 | * make sure we don't ack last byte or you will get very strange | ||
859 | * results! | ||
860 | */ | ||
861 | if(read < count) | ||
862 | { | ||
863 | i2c_sendack(); | ||
864 | } | ||
865 | } | ||
866 | |||
867 | /* stop the operation */ | ||
868 | i2c_stop(); | ||
869 | |||
870 | return read; | ||
871 | } | ||
872 | |||
873 | /* Disables write protection if applicable. */ | ||
874 | |||
875 | #define DBP_SAVE(x) | ||
876 | #define ax_printf printk | ||
877 | static void eeprom_disable_write_protect(void) | ||
878 | { | ||
879 | /* Disable write protect */ | ||
880 | if (eeprom.size == EEPROM_8KB) | ||
881 | { | ||
882 | /* Step 1 Set WEL = 1 (write 00000010 to address 1FFFh */ | ||
883 | i2c_start(); | ||
884 | i2c_outbyte(0xbe); | ||
885 | if(!i2c_getack()) | ||
886 | { | ||
887 | DBP_SAVE(ax_printf("Get ack returns false\n")); | ||
888 | } | ||
889 | i2c_outbyte(0xFF); | ||
890 | if(!i2c_getack()) | ||
891 | { | ||
892 | DBP_SAVE(ax_printf("Get ack returns false 2\n")); | ||
893 | } | ||
894 | i2c_outbyte(0x02); | ||
895 | if(!i2c_getack()) | ||
896 | { | ||
897 | DBP_SAVE(ax_printf("Get ack returns false 3\n")); | ||
898 | } | ||
899 | i2c_stop(); | ||
900 | |||
901 | i2c_delay(1000); | ||
902 | |||
903 | /* Step 2 Set RWEL = 1 (write 00000110 to address 1FFFh */ | ||
904 | i2c_start(); | ||
905 | i2c_outbyte(0xbe); | ||
906 | if(!i2c_getack()) | ||
907 | { | ||
908 | DBP_SAVE(ax_printf("Get ack returns false 55\n")); | ||
909 | } | ||
910 | i2c_outbyte(0xFF); | ||
911 | if(!i2c_getack()) | ||
912 | { | ||
913 | DBP_SAVE(ax_printf("Get ack returns false 52\n")); | ||
914 | } | ||
915 | i2c_outbyte(0x06); | ||
916 | if(!i2c_getack()) | ||
917 | { | ||
918 | DBP_SAVE(ax_printf("Get ack returns false 53\n")); | ||
919 | } | ||
920 | i2c_stop(); | ||
921 | |||
922 | /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */ | ||
923 | i2c_start(); | ||
924 | i2c_outbyte(0xbe); | ||
925 | if(!i2c_getack()) | ||
926 | { | ||
927 | DBP_SAVE(ax_printf("Get ack returns false 56\n")); | ||
928 | } | ||
929 | i2c_outbyte(0xFF); | ||
930 | if(!i2c_getack()) | ||
931 | { | ||
932 | DBP_SAVE(ax_printf("Get ack returns false 57\n")); | ||
933 | } | ||
934 | i2c_outbyte(0x06); | ||
935 | if(!i2c_getack()) | ||
936 | { | ||
937 | DBP_SAVE(ax_printf("Get ack returns false 58\n")); | ||
938 | } | ||
939 | i2c_stop(); | ||
940 | |||
941 | /* Write protect disabled */ | ||
942 | } | ||
943 | } | ||
944 | |||
945 | module_init(eeprom_init); | ||
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c new file mode 100644 index 000000000000..c095de82a0da --- /dev/null +++ b/arch/cris/arch-v10/drivers/gpio.c | |||
@@ -0,0 +1,944 @@ | |||
1 | /* $Id: gpio.c,v 1.12 2004/08/24 07:19:59 starvik Exp $ | ||
2 | * | ||
3 | * Etrax general port I/O device | ||
4 | * | ||
5 | * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB | ||
6 | * | ||
7 | * Authors: Bjorn Wesen (initial version) | ||
8 | * Ola Knutsson (LED handling) | ||
9 | * Johan Adolfsson (read/set directions, write, port G) | ||
10 | * | ||
11 | * $Log: gpio.c,v $ | ||
12 | * Revision 1.12 2004/08/24 07:19:59 starvik | ||
13 | * Whitespace cleanup | ||
14 | * | ||
15 | * Revision 1.11 2004/05/14 07:58:03 starvik | ||
16 | * Merge of changes from 2.4 | ||
17 | * | ||
18 | * Revision 1.9 2003/09/11 07:29:48 starvik | ||
19 | * Merge of Linux 2.6.0-test5 | ||
20 | * | ||
21 | * Revision 1.8 2003/07/04 08:27:37 starvik | ||
22 | * Merge of Linux 2.5.74 | ||
23 | * | ||
24 | * Revision 1.7 2003/01/10 07:44:07 starvik | ||
25 | * init_ioremap is now called by kernel before drivers are initialized | ||
26 | * | ||
27 | * Revision 1.6 2002/12/11 13:13:57 starvik | ||
28 | * Added arch/ to v10 specific includes | ||
29 | * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
30 | * | ||
31 | * Revision 1.5 2002/11/20 11:56:11 starvik | ||
32 | * Merge of Linux 2.5.48 | ||
33 | * | ||
34 | * Revision 1.4 2002/11/18 10:10:05 starvik | ||
35 | * Linux 2.5 port of latest gpio.c from Linux 2.4 | ||
36 | * | ||
37 | * Revision 1.20 2002/10/16 21:16:24 johana | ||
38 | * Added support for PA high level interrupt. | ||
39 | * That gives 2ms response time with iodtest for high levels and 2-12 ms | ||
40 | * response time on low levels if the check is not made in | ||
41 | * process.c:cpu_idle() as well. | ||
42 | * | ||
43 | * Revision 1.19 2002/10/14 18:27:33 johana | ||
44 | * Implemented alarm handling so select() now works. | ||
45 | * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in | ||
46 | * cpu_idle(). | ||
47 | * Otherwise I get 15-18 ms (same as doing the poll in userspace - | ||
48 | * but less overhead). | ||
49 | * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it | ||
50 | * is in 2.4) as well? | ||
51 | * TODO? Perhaps call request_irq()/free_irq() only when needed? | ||
52 | * Increased version to 2.5 | ||
53 | * | ||
54 | * Revision 1.18 2002/10/11 15:02:00 johana | ||
55 | * Mask inverted 8 bit value in setget_input(). | ||
56 | * | ||
57 | * Revision 1.17 2002/06/17 15:53:01 johana | ||
58 | * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT | ||
59 | * that take a pointer as argument and thus can handle 32 bit ports (G) | ||
60 | * correctly. | ||
61 | * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT. | ||
62 | * (especially if Port G bit 31 is used) | ||
63 | * | ||
64 | * Revision 1.16 2002/06/17 09:59:51 johana | ||
65 | * Returning 32 bit values in the ioctl return value doesn't work if bit | ||
66 | * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF. | ||
67 | * A new set of ioctl's will be added. | ||
68 | * | ||
69 | * Revision 1.15 2002/05/06 13:19:13 johana | ||
70 | * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well. | ||
71 | * | ||
72 | * Revision 1.14 2002/04/12 12:01:53 johana | ||
73 | * Use global r_port_g_data_shadow. | ||
74 | * Moved gpio_init_port_g() closer to gpio_init() and marked it __init. | ||
75 | * | ||
76 | * Revision 1.13 2002/04/10 12:03:55 johana | ||
77 | * Added support for port G /dev/gpiog (minor 3). | ||
78 | * Changed indentation on switch cases. | ||
79 | * Fixed other spaces to tabs. | ||
80 | * | ||
81 | * Revision 1.12 2001/11/12 19:42:15 pkj | ||
82 | * * Corrected return values from gpio_leds_ioctl(). | ||
83 | * * Fixed compiler warnings. | ||
84 | * | ||
85 | * Revision 1.11 2001/10/30 14:39:12 johana | ||
86 | * Added D() around gpio_write printk. | ||
87 | * | ||
88 | * Revision 1.10 2001/10/25 10:24:42 johana | ||
89 | * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast | ||
90 | * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB | ||
91 | * from ~60 seconds to 4 seconds). | ||
92 | * Added save_flags/cli/restore_flags in ioctl. | ||
93 | * | ||
94 | * Revision 1.9 2001/05/04 14:16:07 matsfg | ||
95 | * Corrected spelling error | ||
96 | * | ||
97 | * Revision 1.8 2001/04/27 13:55:26 matsfg | ||
98 | * Moved initioremap. | ||
99 | * Turns off all LEDS on init. | ||
100 | * Added support for shutdown and powerbutton. | ||
101 | * | ||
102 | * Revision 1.7 2001/04/04 13:30:08 matsfg | ||
103 | * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping | ||
104 | * | ||
105 | * Revision 1.6 2001/03/26 16:03:06 bjornw | ||
106 | * Needs linux/config.h | ||
107 | * | ||
108 | * Revision 1.5 2001/03/26 14:22:03 bjornw | ||
109 | * Namechange of some config options | ||
110 | * | ||
111 | * Revision 1.4 2001/02/27 13:52:48 bjornw | ||
112 | * malloc.h -> slab.h | ||
113 | * | ||
114 | * Revision 1.3 2001/01/24 15:06:48 bjornw | ||
115 | * gpio_wq correct type | ||
116 | * | ||
117 | * Revision 1.2 2001/01/18 16:07:30 bjornw | ||
118 | * 2.4 port | ||
119 | * | ||
120 | * Revision 1.1 2001/01/18 15:55:16 bjornw | ||
121 | * Verbatim copy of etraxgpio.c from elinux 2.0 added | ||
122 | * | ||
123 | * | ||
124 | */ | ||
125 | |||
126 | #include <linux/config.h> | ||
127 | |||
128 | #include <linux/module.h> | ||
129 | #include <linux/sched.h> | ||
130 | #include <linux/slab.h> | ||
131 | #include <linux/ioport.h> | ||
132 | #include <linux/errno.h> | ||
133 | #include <linux/kernel.h> | ||
134 | #include <linux/fs.h> | ||
135 | #include <linux/string.h> | ||
136 | #include <linux/poll.h> | ||
137 | #include <linux/init.h> | ||
138 | #include <linux/interrupt.h> | ||
139 | |||
140 | #include <asm/etraxgpio.h> | ||
141 | #include <asm/arch/svinto.h> | ||
142 | #include <asm/io.h> | ||
143 | #include <asm/system.h> | ||
144 | #include <asm/irq.h> | ||
145 | |||
146 | #define GPIO_MAJOR 120 /* experimental MAJOR number */ | ||
147 | |||
148 | #define D(x) | ||
149 | |||
150 | #if 0 | ||
151 | static int dp_cnt; | ||
152 | #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0) | ||
153 | #else | ||
154 | #define DP(x) | ||
155 | #endif | ||
156 | |||
157 | static char gpio_name[] = "etrax gpio"; | ||
158 | |||
159 | #if 0 | ||
160 | static wait_queue_head_t *gpio_wq; | ||
161 | #endif | ||
162 | |||
163 | static int gpio_ioctl(struct inode *inode, struct file *file, | ||
164 | unsigned int cmd, unsigned long arg); | ||
165 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | ||
166 | loff_t *off); | ||
167 | static int gpio_open(struct inode *inode, struct file *filp); | ||
168 | static int gpio_release(struct inode *inode, struct file *filp); | ||
169 | static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait); | ||
170 | |||
171 | /* private data per open() of this driver */ | ||
172 | |||
173 | struct gpio_private { | ||
174 | struct gpio_private *next; | ||
175 | /* These fields are for PA and PB only */ | ||
176 | volatile unsigned char *port, *shadow; | ||
177 | volatile unsigned char *dir, *dir_shadow; | ||
178 | unsigned char changeable_dir; | ||
179 | unsigned char changeable_bits; | ||
180 | unsigned char clk_mask; | ||
181 | unsigned char data_mask; | ||
182 | unsigned char write_msb; | ||
183 | unsigned char pad1, pad2, pad3; | ||
184 | /* These fields are generic */ | ||
185 | unsigned long highalarm, lowalarm; | ||
186 | wait_queue_head_t alarm_wq; | ||
187 | int minor; | ||
188 | }; | ||
189 | |||
190 | /* linked list of alarms to check for */ | ||
191 | |||
192 | static struct gpio_private *alarmlist = 0; | ||
193 | |||
194 | static int gpio_some_alarms = 0; /* Set if someone uses alarm */ | ||
195 | static unsigned long gpio_pa_irq_enabled_mask = 0; | ||
196 | |||
197 | /* Port A and B use 8 bit access, but Port G is 32 bit */ | ||
198 | #define NUM_PORTS (GPIO_MINOR_B+1) | ||
199 | |||
200 | static volatile unsigned char *ports[NUM_PORTS] = { | ||
201 | R_PORT_PA_DATA, | ||
202 | R_PORT_PB_DATA, | ||
203 | }; | ||
204 | static volatile unsigned char *shads[NUM_PORTS] = { | ||
205 | &port_pa_data_shadow, | ||
206 | &port_pb_data_shadow | ||
207 | }; | ||
208 | |||
209 | /* What direction bits that are user changeable 1=changeable*/ | ||
210 | #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR | ||
211 | #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00 | ||
212 | #endif | ||
213 | #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR | ||
214 | #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00 | ||
215 | #endif | ||
216 | |||
217 | #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS | ||
218 | #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF | ||
219 | #endif | ||
220 | #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS | ||
221 | #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF | ||
222 | #endif | ||
223 | |||
224 | |||
225 | static unsigned char changeable_dir[NUM_PORTS] = { | ||
226 | CONFIG_ETRAX_PA_CHANGEABLE_DIR, | ||
227 | CONFIG_ETRAX_PB_CHANGEABLE_DIR | ||
228 | }; | ||
229 | static unsigned char changeable_bits[NUM_PORTS] = { | ||
230 | CONFIG_ETRAX_PA_CHANGEABLE_BITS, | ||
231 | CONFIG_ETRAX_PB_CHANGEABLE_BITS | ||
232 | }; | ||
233 | |||
234 | static volatile unsigned char *dir[NUM_PORTS] = { | ||
235 | R_PORT_PA_DIR, | ||
236 | R_PORT_PB_DIR | ||
237 | }; | ||
238 | |||
239 | static volatile unsigned char *dir_shadow[NUM_PORTS] = { | ||
240 | &port_pa_dir_shadow, | ||
241 | &port_pb_dir_shadow | ||
242 | }; | ||
243 | |||
244 | /* Port G is 32 bit, handle it special, some bits are both inputs | ||
245 | and outputs at the same time, only some of the bits can change direction | ||
246 | and some of them in groups of 8 bit. */ | ||
247 | static unsigned long changeable_dir_g; | ||
248 | static unsigned long dir_g_in_bits; | ||
249 | static unsigned long dir_g_out_bits; | ||
250 | static unsigned long dir_g_shadow; /* 1=output */ | ||
251 | |||
252 | #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B) | ||
253 | |||
254 | |||
255 | |||
256 | static unsigned int | ||
257 | gpio_poll(struct file *file, | ||
258 | poll_table *wait) | ||
259 | { | ||
260 | unsigned int mask = 0; | ||
261 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | ||
262 | unsigned long data; | ||
263 | poll_wait(file, &priv->alarm_wq, wait); | ||
264 | if (priv->minor == GPIO_MINOR_A) { | ||
265 | unsigned long flags; | ||
266 | unsigned long tmp; | ||
267 | data = *R_PORT_PA_DATA; | ||
268 | /* PA has support for high level interrupt - | ||
269 | * lets activate for those low and with highalarm set | ||
270 | */ | ||
271 | tmp = ~data & priv->highalarm & 0xFF; | ||
272 | tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); | ||
273 | save_flags(flags); cli(); | ||
274 | gpio_pa_irq_enabled_mask |= tmp; | ||
275 | *R_IRQ_MASK1_SET = tmp; | ||
276 | restore_flags(flags); | ||
277 | |||
278 | } else if (priv->minor == GPIO_MINOR_B) | ||
279 | data = *R_PORT_PB_DATA; | ||
280 | else if (priv->minor == GPIO_MINOR_G) | ||
281 | data = *R_PORT_G_DATA; | ||
282 | else | ||
283 | return 0; | ||
284 | |||
285 | if ((data & priv->highalarm) || | ||
286 | (~data & priv->lowalarm)) { | ||
287 | mask = POLLIN|POLLRDNORM; | ||
288 | } | ||
289 | |||
290 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); | ||
291 | return mask; | ||
292 | } | ||
293 | |||
294 | int etrax_gpio_wake_up_check(void) | ||
295 | { | ||
296 | struct gpio_private *priv = alarmlist; | ||
297 | unsigned long data = 0; | ||
298 | int ret = 0; | ||
299 | while (priv) { | ||
300 | if (USE_PORTS(priv)) { | ||
301 | data = *priv->port; | ||
302 | } else if (priv->minor == GPIO_MINOR_G) { | ||
303 | data = *R_PORT_G_DATA; | ||
304 | } | ||
305 | if ((data & priv->highalarm) || | ||
306 | (~data & priv->lowalarm)) { | ||
307 | DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor)); | ||
308 | wake_up_interruptible(&priv->alarm_wq); | ||
309 | ret = 1; | ||
310 | } | ||
311 | priv = priv->next; | ||
312 | } | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | static irqreturn_t | ||
317 | gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
318 | { | ||
319 | if (gpio_some_alarms) { | ||
320 | etrax_gpio_wake_up_check(); | ||
321 | return IRQ_HANDLED; | ||
322 | } | ||
323 | return IRQ_NONE; | ||
324 | } | ||
325 | |||
326 | static irqreturn_t | ||
327 | gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
328 | { | ||
329 | unsigned long tmp; | ||
330 | /* Find what PA interrupts are active */ | ||
331 | tmp = (*R_IRQ_READ1); | ||
332 | |||
333 | /* Find those that we have enabled */ | ||
334 | tmp &= gpio_pa_irq_enabled_mask; | ||
335 | |||
336 | /* Clear them.. */ | ||
337 | *R_IRQ_MASK1_CLR = tmp; | ||
338 | gpio_pa_irq_enabled_mask &= ~tmp; | ||
339 | |||
340 | if (gpio_some_alarms) { | ||
341 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); | ||
342 | } | ||
343 | return IRQ_NONE; | ||
344 | } | ||
345 | |||
346 | |||
347 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | ||
348 | loff_t *off) | ||
349 | { | ||
350 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | ||
351 | unsigned char data, clk_mask, data_mask, write_msb; | ||
352 | unsigned long flags; | ||
353 | ssize_t retval = count; | ||
354 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { | ||
355 | return -EFAULT; | ||
356 | } | ||
357 | |||
358 | if (!access_ok(VERIFY_READ, buf, count)) { | ||
359 | return -EFAULT; | ||
360 | } | ||
361 | clk_mask = priv->clk_mask; | ||
362 | data_mask = priv->data_mask; | ||
363 | /* It must have been configured using the IO_CFG_WRITE_MODE */ | ||
364 | /* Perhaps a better error code? */ | ||
365 | if (clk_mask == 0 || data_mask == 0) { | ||
366 | return -EPERM; | ||
367 | } | ||
368 | write_msb = priv->write_msb; | ||
369 | D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); | ||
370 | while (count--) { | ||
371 | int i; | ||
372 | data = *buf++; | ||
373 | if (priv->write_msb) { | ||
374 | for (i = 7; i >= 0;i--) { | ||
375 | local_irq_save(flags); local_irq_disable(); | ||
376 | *priv->port = *priv->shadow &= ~clk_mask; | ||
377 | if (data & 1<<i) | ||
378 | *priv->port = *priv->shadow |= data_mask; | ||
379 | else | ||
380 | *priv->port = *priv->shadow &= ~data_mask; | ||
381 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
382 | *priv->port = *priv->shadow |= clk_mask; | ||
383 | local_irq_restore(flags); | ||
384 | } | ||
385 | } else { | ||
386 | for (i = 0; i <= 7;i++) { | ||
387 | local_irq_save(flags); local_irq_disable(); | ||
388 | *priv->port = *priv->shadow &= ~clk_mask; | ||
389 | if (data & 1<<i) | ||
390 | *priv->port = *priv->shadow |= data_mask; | ||
391 | else | ||
392 | *priv->port = *priv->shadow &= ~data_mask; | ||
393 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
394 | *priv->port = *priv->shadow |= clk_mask; | ||
395 | local_irq_restore(flags); | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | return retval; | ||
400 | } | ||
401 | |||
402 | |||
403 | |||
404 | static int | ||
405 | gpio_open(struct inode *inode, struct file *filp) | ||
406 | { | ||
407 | struct gpio_private *priv; | ||
408 | int p = MINOR(inode->i_rdev); | ||
409 | |||
410 | if (p > GPIO_MINOR_LAST) | ||
411 | return -EINVAL; | ||
412 | |||
413 | priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), | ||
414 | GFP_KERNEL); | ||
415 | |||
416 | if (!priv) | ||
417 | return -ENOMEM; | ||
418 | |||
419 | priv->minor = p; | ||
420 | |||
421 | /* initialize the io/alarm struct and link it into our alarmlist */ | ||
422 | |||
423 | priv->next = alarmlist; | ||
424 | alarmlist = priv; | ||
425 | if (USE_PORTS(priv)) { /* A and B */ | ||
426 | priv->port = ports[p]; | ||
427 | priv->shadow = shads[p]; | ||
428 | priv->dir = dir[p]; | ||
429 | priv->dir_shadow = dir_shadow[p]; | ||
430 | priv->changeable_dir = changeable_dir[p]; | ||
431 | priv->changeable_bits = changeable_bits[p]; | ||
432 | } else { | ||
433 | priv->port = NULL; | ||
434 | priv->shadow = NULL; | ||
435 | priv->dir = NULL; | ||
436 | priv->dir_shadow = NULL; | ||
437 | priv->changeable_dir = 0; | ||
438 | priv->changeable_bits = 0; | ||
439 | } | ||
440 | |||
441 | priv->highalarm = 0; | ||
442 | priv->lowalarm = 0; | ||
443 | priv->clk_mask = 0; | ||
444 | priv->data_mask = 0; | ||
445 | init_waitqueue_head(&priv->alarm_wq); | ||
446 | |||
447 | filp->private_data = (void *)priv; | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int | ||
453 | gpio_release(struct inode *inode, struct file *filp) | ||
454 | { | ||
455 | struct gpio_private *p = alarmlist; | ||
456 | struct gpio_private *todel = (struct gpio_private *)filp->private_data; | ||
457 | |||
458 | /* unlink from alarmlist and free the private structure */ | ||
459 | |||
460 | if (p == todel) { | ||
461 | alarmlist = todel->next; | ||
462 | } else { | ||
463 | while (p->next != todel) | ||
464 | p = p->next; | ||
465 | p->next = todel->next; | ||
466 | } | ||
467 | |||
468 | kfree(todel); | ||
469 | /* Check if there are still any alarms set */ | ||
470 | p = alarmlist; | ||
471 | while (p) { | ||
472 | if (p->highalarm | p->lowalarm) { | ||
473 | gpio_some_alarms = 1; | ||
474 | return 0; | ||
475 | } | ||
476 | p = p->next; | ||
477 | } | ||
478 | gpio_some_alarms = 0; | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* Main device API. ioctl's to read/set/clear bits, as well as to | ||
484 | * set alarms to wait for using a subsequent select(). | ||
485 | */ | ||
486 | |||
487 | unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | ||
488 | { | ||
489 | /* Set direction 0=unchanged 1=input, | ||
490 | * return mask with 1=input | ||
491 | */ | ||
492 | unsigned long flags; | ||
493 | if (USE_PORTS(priv)) { | ||
494 | local_irq_save(flags); local_irq_disable(); | ||
495 | *priv->dir = *priv->dir_shadow &= | ||
496 | ~((unsigned char)arg & priv->changeable_dir); | ||
497 | local_irq_restore(flags); | ||
498 | return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ | ||
499 | } else if (priv->minor == GPIO_MINOR_G) { | ||
500 | /* We must fiddle with R_GEN_CONFIG to change dir */ | ||
501 | save_flags(flags); cli(); | ||
502 | if (((arg & dir_g_in_bits) != arg) && | ||
503 | (arg & changeable_dir_g)) { | ||
504 | arg &= changeable_dir_g; | ||
505 | /* Clear bits in genconfig to set to input */ | ||
506 | if (arg & (1<<0)) { | ||
507 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir); | ||
508 | dir_g_in_bits |= (1<<0); | ||
509 | dir_g_out_bits &= ~(1<<0); | ||
510 | } | ||
511 | if ((arg & 0x0000FF00) == 0x0000FF00) { | ||
512 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir); | ||
513 | dir_g_in_bits |= 0x0000FF00; | ||
514 | dir_g_out_bits &= ~0x0000FF00; | ||
515 | } | ||
516 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
517 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir); | ||
518 | dir_g_in_bits |= 0x00FF0000; | ||
519 | dir_g_out_bits &= ~0x00FF0000; | ||
520 | } | ||
521 | if (arg & (1<<24)) { | ||
522 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir); | ||
523 | dir_g_in_bits |= (1<<24); | ||
524 | dir_g_out_bits &= ~(1<<24); | ||
525 | } | ||
526 | D(printk(KERN_INFO "gpio: SETINPUT on port G set " | ||
527 | "genconfig to 0x%08lX " | ||
528 | "in_bits: 0x%08lX " | ||
529 | "out_bits: 0x%08lX\n", | ||
530 | (unsigned long)genconfig_shadow, | ||
531 | dir_g_in_bits, dir_g_out_bits)); | ||
532 | *R_GEN_CONFIG = genconfig_shadow; | ||
533 | /* Must be a >120 ns delay before writing this again */ | ||
534 | |||
535 | } | ||
536 | restore_flags(flags); | ||
537 | return dir_g_in_bits; | ||
538 | } | ||
539 | return 0; | ||
540 | } /* setget_input */ | ||
541 | |||
542 | unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) | ||
543 | { | ||
544 | unsigned long flags; | ||
545 | if (USE_PORTS(priv)) { | ||
546 | local_irq_save(flags); local_irq_disable(); | ||
547 | *priv->dir = *priv->dir_shadow |= | ||
548 | ((unsigned char)arg & priv->changeable_dir); | ||
549 | local_irq_restore(flags); | ||
550 | return *priv->dir_shadow; | ||
551 | } else if (priv->minor == GPIO_MINOR_G) { | ||
552 | /* We must fiddle with R_GEN_CONFIG to change dir */ | ||
553 | save_flags(flags); cli(); | ||
554 | if (((arg & dir_g_out_bits) != arg) && | ||
555 | (arg & changeable_dir_g)) { | ||
556 | /* Set bits in genconfig to set to output */ | ||
557 | if (arg & (1<<0)) { | ||
558 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir); | ||
559 | dir_g_out_bits |= (1<<0); | ||
560 | dir_g_in_bits &= ~(1<<0); | ||
561 | } | ||
562 | if ((arg & 0x0000FF00) == 0x0000FF00) { | ||
563 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir); | ||
564 | dir_g_out_bits |= 0x0000FF00; | ||
565 | dir_g_in_bits &= ~0x0000FF00; | ||
566 | } | ||
567 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
568 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir); | ||
569 | dir_g_out_bits |= 0x00FF0000; | ||
570 | dir_g_in_bits &= ~0x00FF0000; | ||
571 | } | ||
572 | if (arg & (1<<24)) { | ||
573 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir); | ||
574 | dir_g_out_bits |= (1<<24); | ||
575 | dir_g_in_bits &= ~(1<<24); | ||
576 | } | ||
577 | D(printk(KERN_INFO "gpio: SETOUTPUT on port G set " | ||
578 | "genconfig to 0x%08lX " | ||
579 | "in_bits: 0x%08lX " | ||
580 | "out_bits: 0x%08lX\n", | ||
581 | (unsigned long)genconfig_shadow, | ||
582 | dir_g_in_bits, dir_g_out_bits)); | ||
583 | *R_GEN_CONFIG = genconfig_shadow; | ||
584 | /* Must be a >120 ns delay before writing this again */ | ||
585 | } | ||
586 | restore_flags(flags); | ||
587 | return dir_g_out_bits & 0x7FFFFFFF; | ||
588 | } | ||
589 | return 0; | ||
590 | } /* setget_output */ | ||
591 | |||
592 | static int | ||
593 | gpio_leds_ioctl(unsigned int cmd, unsigned long arg); | ||
594 | |||
595 | static int | ||
596 | gpio_ioctl(struct inode *inode, struct file *file, | ||
597 | unsigned int cmd, unsigned long arg) | ||
598 | { | ||
599 | unsigned long flags; | ||
600 | unsigned long val; | ||
601 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | ||
602 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | switch (_IOC_NR(cmd)) { | ||
607 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ | ||
608 | // read the port | ||
609 | if (USE_PORTS(priv)) { | ||
610 | return *priv->port; | ||
611 | } else if (priv->minor == GPIO_MINOR_G) { | ||
612 | return (*R_PORT_G_DATA) & 0x7FFFFFFF; | ||
613 | } | ||
614 | break; | ||
615 | case IO_SETBITS: | ||
616 | local_irq_save(flags); local_irq_disable(); | ||
617 | // set changeable bits with a 1 in arg | ||
618 | if (USE_PORTS(priv)) { | ||
619 | *priv->port = *priv->shadow |= | ||
620 | ((unsigned char)arg & priv->changeable_bits); | ||
621 | } else if (priv->minor == GPIO_MINOR_G) { | ||
622 | *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits); | ||
623 | } | ||
624 | local_irq_restore(flags); | ||
625 | break; | ||
626 | case IO_CLRBITS: | ||
627 | local_irq_save(flags); local_irq_disable(); | ||
628 | // clear changeable bits with a 1 in arg | ||
629 | if (USE_PORTS(priv)) { | ||
630 | *priv->port = *priv->shadow &= | ||
631 | ~((unsigned char)arg & priv->changeable_bits); | ||
632 | } else if (priv->minor == GPIO_MINOR_G) { | ||
633 | *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits); | ||
634 | } | ||
635 | local_irq_restore(flags); | ||
636 | break; | ||
637 | case IO_HIGHALARM: | ||
638 | // set alarm when bits with 1 in arg go high | ||
639 | priv->highalarm |= arg; | ||
640 | gpio_some_alarms = 1; | ||
641 | break; | ||
642 | case IO_LOWALARM: | ||
643 | // set alarm when bits with 1 in arg go low | ||
644 | priv->lowalarm |= arg; | ||
645 | gpio_some_alarms = 1; | ||
646 | break; | ||
647 | case IO_CLRALARM: | ||
648 | // clear alarm for bits with 1 in arg | ||
649 | priv->highalarm &= ~arg; | ||
650 | priv->lowalarm &= ~arg; | ||
651 | { | ||
652 | /* Must update gpio_some_alarms */ | ||
653 | struct gpio_private *p = alarmlist; | ||
654 | int some_alarms; | ||
655 | some_alarms = 0; | ||
656 | while (p) { | ||
657 | if (p->highalarm | p->lowalarm) { | ||
658 | some_alarms = 1; | ||
659 | break; | ||
660 | } | ||
661 | p = p->next; | ||
662 | } | ||
663 | gpio_some_alarms = some_alarms; | ||
664 | } | ||
665 | break; | ||
666 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ | ||
667 | /* Read direction 0=input 1=output */ | ||
668 | if (USE_PORTS(priv)) { | ||
669 | return *priv->dir_shadow; | ||
670 | } else if (priv->minor == GPIO_MINOR_G) { | ||
671 | /* Note: Some bits are both in and out, | ||
672 | * Those that are dual is set here as well. | ||
673 | */ | ||
674 | return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF; | ||
675 | } | ||
676 | case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */ | ||
677 | /* Set direction 0=unchanged 1=input, | ||
678 | * return mask with 1=input | ||
679 | */ | ||
680 | return setget_input(priv, arg) & 0x7FFFFFFF; | ||
681 | break; | ||
682 | case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */ | ||
683 | /* Set direction 0=unchanged 1=output, | ||
684 | * return mask with 1=output | ||
685 | */ | ||
686 | return setget_output(priv, arg) & 0x7FFFFFFF; | ||
687 | |||
688 | case IO_SHUTDOWN: | ||
689 | SOFT_SHUTDOWN(); | ||
690 | break; | ||
691 | case IO_GET_PWR_BT: | ||
692 | #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN) | ||
693 | return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT)); | ||
694 | #else | ||
695 | return 0; | ||
696 | #endif | ||
697 | break; | ||
698 | case IO_CFG_WRITE_MODE: | ||
699 | priv->clk_mask = arg & 0xFF; | ||
700 | priv->data_mask = (arg >> 8) & 0xFF; | ||
701 | priv->write_msb = (arg >> 16) & 0x01; | ||
702 | /* Check if we're allowed to change the bits and | ||
703 | * the direction is correct | ||
704 | */ | ||
705 | if (!((priv->clk_mask & priv->changeable_bits) && | ||
706 | (priv->data_mask & priv->changeable_bits) && | ||
707 | (priv->clk_mask & *priv->dir_shadow) && | ||
708 | (priv->data_mask & *priv->dir_shadow))) | ||
709 | { | ||
710 | priv->clk_mask = 0; | ||
711 | priv->data_mask = 0; | ||
712 | return -EPERM; | ||
713 | } | ||
714 | break; | ||
715 | case IO_READ_INBITS: | ||
716 | /* *arg is result of reading the input pins */ | ||
717 | if (USE_PORTS(priv)) { | ||
718 | val = *priv->port; | ||
719 | } else if (priv->minor == GPIO_MINOR_G) { | ||
720 | val = *R_PORT_G_DATA; | ||
721 | } | ||
722 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | ||
723 | return -EFAULT; | ||
724 | return 0; | ||
725 | break; | ||
726 | case IO_READ_OUTBITS: | ||
727 | /* *arg is result of reading the output shadow */ | ||
728 | if (USE_PORTS(priv)) { | ||
729 | val = *priv->shadow; | ||
730 | } else if (priv->minor == GPIO_MINOR_G) { | ||
731 | val = port_g_data_shadow; | ||
732 | } | ||
733 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | ||
734 | return -EFAULT; | ||
735 | break; | ||
736 | case IO_SETGET_INPUT: | ||
737 | /* bits set in *arg is set to input, | ||
738 | * *arg updated with current input pins. | ||
739 | */ | ||
740 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | ||
741 | return -EFAULT; | ||
742 | val = setget_input(priv, val); | ||
743 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | ||
744 | return -EFAULT; | ||
745 | break; | ||
746 | case IO_SETGET_OUTPUT: | ||
747 | /* bits set in *arg is set to output, | ||
748 | * *arg updated with current output pins. | ||
749 | */ | ||
750 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | ||
751 | return -EFAULT; | ||
752 | val = setget_output(priv, val); | ||
753 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | ||
754 | return -EFAULT; | ||
755 | break; | ||
756 | default: | ||
757 | if (priv->minor == GPIO_MINOR_LEDS) | ||
758 | return gpio_leds_ioctl(cmd, arg); | ||
759 | else | ||
760 | return -EINVAL; | ||
761 | } /* switch */ | ||
762 | |||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int | ||
767 | gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | ||
768 | { | ||
769 | unsigned char green; | ||
770 | unsigned char red; | ||
771 | |||
772 | switch (_IOC_NR(cmd)) { | ||
773 | case IO_LEDACTIVE_SET: | ||
774 | green = ((unsigned char) arg) & 1; | ||
775 | red = (((unsigned char) arg) >> 1) & 1; | ||
776 | LED_ACTIVE_SET_G(green); | ||
777 | LED_ACTIVE_SET_R(red); | ||
778 | break; | ||
779 | |||
780 | case IO_LED_SETBIT: | ||
781 | LED_BIT_SET(arg); | ||
782 | break; | ||
783 | |||
784 | case IO_LED_CLRBIT: | ||
785 | LED_BIT_CLR(arg); | ||
786 | break; | ||
787 | |||
788 | default: | ||
789 | return -EINVAL; | ||
790 | } /* switch */ | ||
791 | |||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | struct file_operations gpio_fops = { | ||
796 | .owner = THIS_MODULE, | ||
797 | .poll = gpio_poll, | ||
798 | .ioctl = gpio_ioctl, | ||
799 | .write = gpio_write, | ||
800 | .open = gpio_open, | ||
801 | .release = gpio_release, | ||
802 | }; | ||
803 | |||
804 | |||
805 | static void __init gpio_init_port_g(void) | ||
806 | { | ||
807 | #define GROUPA (0x0000FF3F) | ||
808 | #define GROUPB (1<<6 | 1<<7) | ||
809 | #define GROUPC (1<<30 | 1<<31) | ||
810 | #define GROUPD (0x3FFF0000) | ||
811 | #define GROUPD_LOW (0x00FF0000) | ||
812 | unsigned long used_in_bits = 0; | ||
813 | unsigned long used_out_bits = 0; | ||
814 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){ | ||
815 | used_in_bits |= GROUPA | GROUPB | 0 | 0; | ||
816 | used_out_bits |= GROUPA | GROUPB | 0 | 0; | ||
817 | } | ||
818 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) { | ||
819 | used_in_bits |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26)); | ||
820 | used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD; | ||
821 | } | ||
822 | |||
823 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) { | ||
824 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0; | ||
825 | used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0; | ||
826 | } | ||
827 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) { | ||
828 | used_in_bits |= 0 | GROUPB | 0 | 0; | ||
829 | used_out_bits |= 0 | GROUPB | 0 | 0; | ||
830 | } | ||
831 | /* mio same as shared RAM ? */ | ||
832 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) { | ||
833 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW; | ||
834 | used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW; | ||
835 | } | ||
836 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) { | ||
837 | used_in_bits |= 0 | 0 | GROUPC | GROUPD; | ||
838 | used_out_bits |= 0 | 0 | GROUPC | GROUPD; | ||
839 | } | ||
840 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) { | ||
841 | used_in_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24); | ||
842 | used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26); | ||
843 | } | ||
844 | |||
845 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) { | ||
846 | used_in_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24)); | ||
847 | used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24)); | ||
848 | } | ||
849 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) { | ||
850 | used_in_bits |= 0 | 0 | GROUPC | 0; | ||
851 | used_out_bits |= 0 | 0 | GROUPC | 0; | ||
852 | } | ||
853 | /* mio same as shared RAM-W? */ | ||
854 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) { | ||
855 | used_in_bits |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW; | ||
856 | used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW; | ||
857 | } | ||
858 | /* TODO: USB p2, parw, sync ser3? */ | ||
859 | |||
860 | /* Initialise the dir_g_shadow etc. depending on genconfig */ | ||
861 | /* 0=input 1=output */ | ||
862 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) | ||
863 | dir_g_shadow |= (1 << 0); | ||
864 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out)) | ||
865 | dir_g_shadow |= 0x0000FF00; | ||
866 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out)) | ||
867 | dir_g_shadow |= 0x00FF0000; | ||
868 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out)) | ||
869 | dir_g_shadow |= (1 << 24); | ||
870 | |||
871 | dir_g_in_bits = ~used_in_bits; | ||
872 | dir_g_out_bits = ~used_out_bits; | ||
873 | |||
874 | changeable_dir_g = 0x01FFFF01; /* all that can change dir */ | ||
875 | changeable_dir_g &= dir_g_out_bits; | ||
876 | changeable_dir_g &= dir_g_in_bits; | ||
877 | /* Correct the bits that can change direction */ | ||
878 | dir_g_out_bits &= ~changeable_dir_g; | ||
879 | dir_g_out_bits |= dir_g_shadow; | ||
880 | dir_g_in_bits &= ~changeable_dir_g; | ||
881 | dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); | ||
882 | |||
883 | |||
884 | printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", | ||
885 | dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); | ||
886 | printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n", | ||
887 | dir_g_shadow, changeable_dir_g); | ||
888 | } | ||
889 | |||
890 | /* main driver initialization routine, called from mem.c */ | ||
891 | |||
892 | static __init int | ||
893 | gpio_init(void) | ||
894 | { | ||
895 | int res; | ||
896 | #if defined (CONFIG_ETRAX_CSP0_LEDS) | ||
897 | int i; | ||
898 | #endif | ||
899 | |||
900 | /* do the formalities */ | ||
901 | |||
902 | res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops); | ||
903 | if (res < 0) { | ||
904 | printk(KERN_ERR "gpio: couldn't get a major number.\n"); | ||
905 | return res; | ||
906 | } | ||
907 | |||
908 | /* Clear all leds */ | ||
909 | #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) | ||
910 | LED_NETWORK_SET(0); | ||
911 | LED_ACTIVE_SET(0); | ||
912 | LED_DISK_READ(0); | ||
913 | LED_DISK_WRITE(0); | ||
914 | |||
915 | #if defined (CONFIG_ETRAX_CSP0_LEDS) | ||
916 | for (i = 0; i < 32; i++) { | ||
917 | LED_BIT_SET(i); | ||
918 | } | ||
919 | #endif | ||
920 | |||
921 | #endif | ||
922 | gpio_init_port_g(); | ||
923 | printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); | ||
924 | /* We call etrax_gpio_wake_up_check() from timer interrupt and | ||
925 | * from cpu_idle() in kernel/process.c | ||
926 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms | ||
927 | * in some tests. | ||
928 | */ | ||
929 | if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, | ||
930 | SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) { | ||
931 | printk(KERN_CRIT "err: timer0 irq for gpio\n"); | ||
932 | } | ||
933 | if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt, | ||
934 | SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) { | ||
935 | printk(KERN_CRIT "err: PA irq for gpio\n"); | ||
936 | } | ||
937 | |||
938 | |||
939 | return res; | ||
940 | } | ||
941 | |||
942 | /* this makes sure that gpio_init is called during kernel boot */ | ||
943 | |||
944 | module_init(gpio_init); | ||
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c new file mode 100644 index 000000000000..8bbe233ba7b1 --- /dev/null +++ b/arch/cris/arch-v10/drivers/i2c.c | |||
@@ -0,0 +1,730 @@ | |||
1 | /*!*************************************************************************** | ||
2 | *! | ||
3 | *! FILE NAME : i2c.c | ||
4 | *! | ||
5 | *! DESCRIPTION: implements an interface for IIC/I2C, both directly from other | ||
6 | *! kernel modules (i2c_writereg/readreg) and from userspace using | ||
7 | *! ioctl()'s | ||
8 | *! | ||
9 | *! Nov 30 1998 Torbjorn Eliasson Initial version. | ||
10 | *! Bjorn Wesen Elinux kernel version. | ||
11 | *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff - | ||
12 | *! don't use PB_I2C if DS1302 uses same bits, | ||
13 | *! use PB. | ||
14 | *! $Log: i2c.c,v $ | ||
15 | *! Revision 1.9 2004/08/24 06:49:14 starvik | ||
16 | *! Whitespace cleanup | ||
17 | *! | ||
18 | *! Revision 1.8 2004/06/08 08:48:26 starvik | ||
19 | *! Removed unused code | ||
20 | *! | ||
21 | *! Revision 1.7 2004/05/28 09:26:59 starvik | ||
22 | *! Modified I2C initialization to work in 2.6. | ||
23 | *! | ||
24 | *! Revision 1.6 2004/05/14 07:58:03 starvik | ||
25 | *! Merge of changes from 2.4 | ||
26 | *! | ||
27 | *! Revision 1.4 2002/12/11 13:13:57 starvik | ||
28 | *! Added arch/ to v10 specific includes | ||
29 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
30 | *! | ||
31 | *! Revision 1.3 2002/11/20 11:56:11 starvik | ||
32 | *! Merge of Linux 2.5.48 | ||
33 | *! | ||
34 | *! Revision 1.2 2002/11/18 13:16:06 starvik | ||
35 | *! Linux 2.5 port of latest 2.4 drivers | ||
36 | *! | ||
37 | *! Revision 1.9 2002/10/31 15:32:26 starvik | ||
38 | *! Update Port B register and shadow even when running with hardware support | ||
39 | *! to avoid glitches when reading bits | ||
40 | *! Never set direction to out in i2c_inbyte | ||
41 | *! Removed incorrect clock togling at end of i2c_inbyte | ||
42 | *! | ||
43 | *! Revision 1.8 2002/08/13 06:31:53 starvik | ||
44 | *! Made SDA and SCL line configurable | ||
45 | *! Modified i2c_inbyte to work with PCF8563 | ||
46 | *! | ||
47 | *! Revision 1.7 2001/04/04 13:11:36 markusl | ||
48 | *! Updated according to review remarks | ||
49 | *! | ||
50 | *! Revision 1.6 2001/03/19 12:43:00 markusl | ||
51 | *! Made some symbols unstatic (used by the eeprom driver) | ||
52 | *! | ||
53 | *! Revision 1.5 2001/02/27 13:52:48 bjornw | ||
54 | *! malloc.h -> slab.h | ||
55 | *! | ||
56 | *! Revision 1.4 2001/02/15 07:17:40 starvik | ||
57 | *! Corrected usage if port_pb_i2c_shadow | ||
58 | *! | ||
59 | *! Revision 1.3 2001/01/26 17:55:13 bjornw | ||
60 | *! * Made I2C_USES_PB_NOT_PB_I2C a CONFIG option instead of assigning it | ||
61 | *! magically. Config.in needs to set it for the options that need it, like | ||
62 | *! Dallas 1302 support. Actually, it should be default since it screws up | ||
63 | *! the PB bits even if you don't use I2C.. | ||
64 | *! * Include linux/config.h to get the above | ||
65 | *! | ||
66 | *! Revision 1.2 2001/01/18 15:49:30 bjornw | ||
67 | *! 2.4 port of I2C including some cleanups (untested of course) | ||
68 | *! | ||
69 | *! Revision 1.1 2001/01/18 15:35:25 bjornw | ||
70 | *! Verbatim copy of the Etrax i2c driver, 2.0 elinux version | ||
71 | *! | ||
72 | *! | ||
73 | *! --------------------------------------------------------------------------- | ||
74 | *! | ||
75 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN | ||
76 | *! | ||
77 | *!***************************************************************************/ | ||
78 | /* $Id: i2c.c,v 1.9 2004/08/24 06:49:14 starvik Exp $ */ | ||
79 | |||
80 | /****************** INCLUDE FILES SECTION ***********************************/ | ||
81 | |||
82 | #include <linux/module.h> | ||
83 | #include <linux/sched.h> | ||
84 | #include <linux/slab.h> | ||
85 | #include <linux/errno.h> | ||
86 | #include <linux/kernel.h> | ||
87 | #include <linux/fs.h> | ||
88 | #include <linux/string.h> | ||
89 | #include <linux/init.h> | ||
90 | #include <linux/config.h> | ||
91 | |||
92 | #include <asm/etraxi2c.h> | ||
93 | |||
94 | #include <asm/system.h> | ||
95 | #include <asm/arch/svinto.h> | ||
96 | #include <asm/io.h> | ||
97 | #include <asm/delay.h> | ||
98 | |||
99 | #include "i2c.h" | ||
100 | |||
101 | /****************** I2C DEFINITION SECTION *************************/ | ||
102 | |||
103 | #define D(x) | ||
104 | |||
105 | #define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */ | ||
106 | static const char i2c_name[] = "i2c"; | ||
107 | |||
108 | #define CLOCK_LOW_TIME 8 | ||
109 | #define CLOCK_HIGH_TIME 8 | ||
110 | #define START_CONDITION_HOLD_TIME 8 | ||
111 | #define STOP_CONDITION_HOLD_TIME 8 | ||
112 | #define ENABLE_OUTPUT 0x01 | ||
113 | #define ENABLE_INPUT 0x00 | ||
114 | #define I2C_CLOCK_HIGH 1 | ||
115 | #define I2C_CLOCK_LOW 0 | ||
116 | #define I2C_DATA_HIGH 1 | ||
117 | #define I2C_DATA_LOW 0 | ||
118 | |||
119 | #ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C | ||
120 | /* Use PB and not PB_I2C */ | ||
121 | #ifndef CONFIG_ETRAX_I2C_DATA_PORT | ||
122 | #define CONFIG_ETRAX_I2C_DATA_PORT 0 | ||
123 | #endif | ||
124 | #ifndef CONFIG_ETRAX_I2C_CLK_PORT | ||
125 | #define CONFIG_ETRAX_I2C_CLK_PORT 1 | ||
126 | #endif | ||
127 | |||
128 | #define SDABIT CONFIG_ETRAX_I2C_DATA_PORT | ||
129 | #define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT | ||
130 | #define i2c_enable() | ||
131 | #define i2c_disable() | ||
132 | |||
133 | /* enable or disable output-enable, to select output or input on the i2c bus */ | ||
134 | |||
135 | #define i2c_dir_out() \ | ||
136 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 1) | ||
137 | #define i2c_dir_in() \ | ||
138 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 0) | ||
139 | |||
140 | /* control the i2c clock and data signals */ | ||
141 | |||
142 | #define i2c_clk(x) \ | ||
143 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SCLBIT, x) | ||
144 | #define i2c_data(x) \ | ||
145 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SDABIT, x) | ||
146 | |||
147 | /* read a bit from the i2c interface */ | ||
148 | |||
149 | #define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT) | ||
150 | |||
151 | #else | ||
152 | /* enable or disable the i2c interface */ | ||
153 | |||
154 | #define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en)) | ||
155 | #define i2c_disable() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_en)) | ||
156 | |||
157 | /* enable or disable output-enable, to select output or input on the i2c bus */ | ||
158 | |||
159 | #define i2c_dir_out() \ | ||
160 | *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ | ||
161 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1); | ||
162 | #define i2c_dir_in() \ | ||
163 | *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \ | ||
164 | REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0); | ||
165 | |||
166 | /* control the i2c clock and data signals */ | ||
167 | |||
168 | #define i2c_clk(x) \ | ||
169 | *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \ | ||
170 | ~IO_MASK(R_PORT_PB_I2C, i2c_clk)) | IO_FIELD(R_PORT_PB_I2C, i2c_clk, (x))); \ | ||
171 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 1, x); | ||
172 | |||
173 | #define i2c_data(x) \ | ||
174 | *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \ | ||
175 | ~IO_MASK(R_PORT_PB_I2C, i2c_d)) | IO_FIELD(R_PORT_PB_I2C, i2c_d, (x))); \ | ||
176 | REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 0, x); | ||
177 | |||
178 | /* read a bit from the i2c interface */ | ||
179 | |||
180 | #define i2c_getbit() (*R_PORT_PB_READ & 0x1) | ||
181 | #endif | ||
182 | |||
183 | /* use the kernels delay routine */ | ||
184 | |||
185 | #define i2c_delay(usecs) udelay(usecs) | ||
186 | |||
187 | |||
188 | /****************** FUNCTION DEFINITION SECTION *************************/ | ||
189 | |||
190 | |||
191 | /* generate i2c start condition */ | ||
192 | |||
193 | void | ||
194 | i2c_start(void) | ||
195 | { | ||
196 | /* | ||
197 | * SCL=1 SDA=1 | ||
198 | */ | ||
199 | i2c_dir_out(); | ||
200 | i2c_delay(CLOCK_HIGH_TIME/6); | ||
201 | i2c_data(I2C_DATA_HIGH); | ||
202 | i2c_clk(I2C_CLOCK_HIGH); | ||
203 | i2c_delay(CLOCK_HIGH_TIME); | ||
204 | /* | ||
205 | * SCL=1 SDA=0 | ||
206 | */ | ||
207 | i2c_data(I2C_DATA_LOW); | ||
208 | i2c_delay(START_CONDITION_HOLD_TIME); | ||
209 | /* | ||
210 | * SCL=0 SDA=0 | ||
211 | */ | ||
212 | i2c_clk(I2C_CLOCK_LOW); | ||
213 | i2c_delay(CLOCK_LOW_TIME); | ||
214 | } | ||
215 | |||
216 | /* generate i2c stop condition */ | ||
217 | |||
218 | void | ||
219 | i2c_stop(void) | ||
220 | { | ||
221 | i2c_dir_out(); | ||
222 | |||
223 | /* | ||
224 | * SCL=0 SDA=0 | ||
225 | */ | ||
226 | i2c_clk(I2C_CLOCK_LOW); | ||
227 | i2c_data(I2C_DATA_LOW); | ||
228 | i2c_delay(CLOCK_LOW_TIME*2); | ||
229 | /* | ||
230 | * SCL=1 SDA=0 | ||
231 | */ | ||
232 | i2c_clk(I2C_CLOCK_HIGH); | ||
233 | i2c_delay(CLOCK_HIGH_TIME*2); | ||
234 | /* | ||
235 | * SCL=1 SDA=1 | ||
236 | */ | ||
237 | i2c_data(I2C_DATA_HIGH); | ||
238 | i2c_delay(STOP_CONDITION_HOLD_TIME); | ||
239 | |||
240 | i2c_dir_in(); | ||
241 | } | ||
242 | |||
243 | /* write a byte to the i2c interface */ | ||
244 | |||
245 | void | ||
246 | i2c_outbyte(unsigned char x) | ||
247 | { | ||
248 | int i; | ||
249 | |||
250 | i2c_dir_out(); | ||
251 | |||
252 | for (i = 0; i < 8; i++) { | ||
253 | if (x & 0x80) { | ||
254 | i2c_data(I2C_DATA_HIGH); | ||
255 | } else { | ||
256 | i2c_data(I2C_DATA_LOW); | ||
257 | } | ||
258 | |||
259 | i2c_delay(CLOCK_LOW_TIME/2); | ||
260 | i2c_clk(I2C_CLOCK_HIGH); | ||
261 | i2c_delay(CLOCK_HIGH_TIME); | ||
262 | i2c_clk(I2C_CLOCK_LOW); | ||
263 | i2c_delay(CLOCK_LOW_TIME/2); | ||
264 | x <<= 1; | ||
265 | } | ||
266 | i2c_data(I2C_DATA_LOW); | ||
267 | i2c_delay(CLOCK_LOW_TIME/2); | ||
268 | |||
269 | /* | ||
270 | * enable input | ||
271 | */ | ||
272 | i2c_dir_in(); | ||
273 | } | ||
274 | |||
275 | /* read a byte from the i2c interface */ | ||
276 | |||
277 | unsigned char | ||
278 | i2c_inbyte(void) | ||
279 | { | ||
280 | unsigned char aBitByte = 0; | ||
281 | int i; | ||
282 | |||
283 | /* Switch off I2C to get bit */ | ||
284 | i2c_disable(); | ||
285 | i2c_dir_in(); | ||
286 | i2c_delay(CLOCK_HIGH_TIME/2); | ||
287 | |||
288 | /* Get bit */ | ||
289 | aBitByte |= i2c_getbit(); | ||
290 | |||
291 | /* Enable I2C */ | ||
292 | i2c_enable(); | ||
293 | i2c_delay(CLOCK_LOW_TIME/2); | ||
294 | |||
295 | for (i = 1; i < 8; i++) { | ||
296 | aBitByte <<= 1; | ||
297 | /* Clock pulse */ | ||
298 | i2c_clk(I2C_CLOCK_HIGH); | ||
299 | i2c_delay(CLOCK_HIGH_TIME); | ||
300 | i2c_clk(I2C_CLOCK_LOW); | ||
301 | i2c_delay(CLOCK_LOW_TIME); | ||
302 | |||
303 | /* Switch off I2C to get bit */ | ||
304 | i2c_disable(); | ||
305 | i2c_dir_in(); | ||
306 | i2c_delay(CLOCK_HIGH_TIME/2); | ||
307 | |||
308 | /* Get bit */ | ||
309 | aBitByte |= i2c_getbit(); | ||
310 | |||
311 | /* Enable I2C */ | ||
312 | i2c_enable(); | ||
313 | i2c_delay(CLOCK_LOW_TIME/2); | ||
314 | } | ||
315 | i2c_clk(I2C_CLOCK_HIGH); | ||
316 | i2c_delay(CLOCK_HIGH_TIME); | ||
317 | |||
318 | /* | ||
319 | * we leave the clock low, getbyte is usually followed | ||
320 | * by sendack/nack, they assume the clock to be low | ||
321 | */ | ||
322 | i2c_clk(I2C_CLOCK_LOW); | ||
323 | return aBitByte; | ||
324 | } | ||
325 | |||
326 | /*#--------------------------------------------------------------------------- | ||
327 | *# | ||
328 | *# FUNCTION NAME: i2c_getack | ||
329 | *# | ||
330 | *# DESCRIPTION : checks if ack was received from ic2 | ||
331 | *# | ||
332 | *#--------------------------------------------------------------------------*/ | ||
333 | |||
334 | int | ||
335 | i2c_getack(void) | ||
336 | { | ||
337 | int ack = 1; | ||
338 | /* | ||
339 | * enable output | ||
340 | */ | ||
341 | i2c_dir_out(); | ||
342 | /* | ||
343 | * Release data bus by setting | ||
344 | * data high | ||
345 | */ | ||
346 | i2c_data(I2C_DATA_HIGH); | ||
347 | /* | ||
348 | * enable input | ||
349 | */ | ||
350 | i2c_dir_in(); | ||
351 | i2c_delay(CLOCK_HIGH_TIME/4); | ||
352 | /* | ||
353 | * generate ACK clock pulse | ||
354 | */ | ||
355 | i2c_clk(I2C_CLOCK_HIGH); | ||
356 | /* | ||
357 | * Use PORT PB instead of I2C | ||
358 | * for input. (I2C not working) | ||
359 | */ | ||
360 | i2c_clk(1); | ||
361 | i2c_data(1); | ||
362 | /* | ||
363 | * switch off I2C | ||
364 | */ | ||
365 | i2c_data(1); | ||
366 | i2c_disable(); | ||
367 | i2c_dir_in(); | ||
368 | /* | ||
369 | * now wait for ack | ||
370 | */ | ||
371 | i2c_delay(CLOCK_HIGH_TIME/2); | ||
372 | /* | ||
373 | * check for ack | ||
374 | */ | ||
375 | if(i2c_getbit()) | ||
376 | ack = 0; | ||
377 | i2c_delay(CLOCK_HIGH_TIME/2); | ||
378 | if(!ack){ | ||
379 | if(!i2c_getbit()) /* receiver pulld SDA low */ | ||
380 | ack = 1; | ||
381 | i2c_delay(CLOCK_HIGH_TIME/2); | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * our clock is high now, make sure data is low | ||
386 | * before we enable our output. If we keep data high | ||
387 | * and enable output, we would generate a stop condition. | ||
388 | */ | ||
389 | i2c_data(I2C_DATA_LOW); | ||
390 | |||
391 | /* | ||
392 | * end clock pulse | ||
393 | */ | ||
394 | i2c_enable(); | ||
395 | i2c_dir_out(); | ||
396 | i2c_clk(I2C_CLOCK_LOW); | ||
397 | i2c_delay(CLOCK_HIGH_TIME/4); | ||
398 | /* | ||
399 | * enable output | ||
400 | */ | ||
401 | i2c_dir_out(); | ||
402 | /* | ||
403 | * remove ACK clock pulse | ||
404 | */ | ||
405 | i2c_data(I2C_DATA_HIGH); | ||
406 | i2c_delay(CLOCK_LOW_TIME/2); | ||
407 | return ack; | ||
408 | } | ||
409 | |||
410 | /*#--------------------------------------------------------------------------- | ||
411 | *# | ||
412 | *# FUNCTION NAME: I2C::sendAck | ||
413 | *# | ||
414 | *# DESCRIPTION : Send ACK on received data | ||
415 | *# | ||
416 | *#--------------------------------------------------------------------------*/ | ||
417 | void | ||
418 | i2c_sendack(void) | ||
419 | { | ||
420 | /* | ||
421 | * enable output | ||
422 | */ | ||
423 | i2c_delay(CLOCK_LOW_TIME); | ||
424 | i2c_dir_out(); | ||
425 | /* | ||
426 | * set ack pulse high | ||
427 | */ | ||
428 | i2c_data(I2C_DATA_LOW); | ||
429 | /* | ||
430 | * generate clock pulse | ||
431 | */ | ||
432 | i2c_delay(CLOCK_HIGH_TIME/6); | ||
433 | i2c_clk(I2C_CLOCK_HIGH); | ||
434 | i2c_delay(CLOCK_HIGH_TIME); | ||
435 | i2c_clk(I2C_CLOCK_LOW); | ||
436 | i2c_delay(CLOCK_LOW_TIME/6); | ||
437 | /* | ||
438 | * reset data out | ||
439 | */ | ||
440 | i2c_data(I2C_DATA_HIGH); | ||
441 | i2c_delay(CLOCK_LOW_TIME); | ||
442 | |||
443 | i2c_dir_in(); | ||
444 | } | ||
445 | |||
446 | /*#--------------------------------------------------------------------------- | ||
447 | *# | ||
448 | *# FUNCTION NAME: i2c_sendnack | ||
449 | *# | ||
450 | *# DESCRIPTION : Sends NACK on received data | ||
451 | *# | ||
452 | *#--------------------------------------------------------------------------*/ | ||
453 | void | ||
454 | i2c_sendnack(void) | ||
455 | { | ||
456 | /* | ||
457 | * enable output | ||
458 | */ | ||
459 | i2c_delay(CLOCK_LOW_TIME); | ||
460 | i2c_dir_out(); | ||
461 | /* | ||
462 | * set data high | ||
463 | */ | ||
464 | i2c_data(I2C_DATA_HIGH); | ||
465 | /* | ||
466 | * generate clock pulse | ||
467 | */ | ||
468 | i2c_delay(CLOCK_HIGH_TIME/6); | ||
469 | i2c_clk(I2C_CLOCK_HIGH); | ||
470 | i2c_delay(CLOCK_HIGH_TIME); | ||
471 | i2c_clk(I2C_CLOCK_LOW); | ||
472 | i2c_delay(CLOCK_LOW_TIME); | ||
473 | |||
474 | i2c_dir_in(); | ||
475 | } | ||
476 | |||
477 | /*#--------------------------------------------------------------------------- | ||
478 | *# | ||
479 | *# FUNCTION NAME: i2c_writereg | ||
480 | *# | ||
481 | *# DESCRIPTION : Writes a value to an I2C device | ||
482 | *# | ||
483 | *#--------------------------------------------------------------------------*/ | ||
484 | int | ||
485 | i2c_writereg(unsigned char theSlave, unsigned char theReg, | ||
486 | unsigned char theValue) | ||
487 | { | ||
488 | int error, cntr = 3; | ||
489 | unsigned long flags; | ||
490 | |||
491 | do { | ||
492 | error = 0; | ||
493 | /* | ||
494 | * we don't like to be interrupted | ||
495 | */ | ||
496 | local_irq_save(flags); | ||
497 | local_irq_disable(); | ||
498 | |||
499 | i2c_start(); | ||
500 | /* | ||
501 | * send slave address | ||
502 | */ | ||
503 | i2c_outbyte((theSlave & 0xfe)); | ||
504 | /* | ||
505 | * wait for ack | ||
506 | */ | ||
507 | if(!i2c_getack()) | ||
508 | error = 1; | ||
509 | /* | ||
510 | * now select register | ||
511 | */ | ||
512 | i2c_dir_out(); | ||
513 | i2c_outbyte(theReg); | ||
514 | /* | ||
515 | * now it's time to wait for ack | ||
516 | */ | ||
517 | if(!i2c_getack()) | ||
518 | error |= 2; | ||
519 | /* | ||
520 | * send register register data | ||
521 | */ | ||
522 | i2c_outbyte(theValue); | ||
523 | /* | ||
524 | * now it's time to wait for ack | ||
525 | */ | ||
526 | if(!i2c_getack()) | ||
527 | error |= 4; | ||
528 | /* | ||
529 | * end byte stream | ||
530 | */ | ||
531 | i2c_stop(); | ||
532 | /* | ||
533 | * enable interrupt again | ||
534 | */ | ||
535 | local_irq_restore(flags); | ||
536 | |||
537 | } while(error && cntr--); | ||
538 | |||
539 | i2c_delay(CLOCK_LOW_TIME); | ||
540 | |||
541 | return -error; | ||
542 | } | ||
543 | |||
544 | /*#--------------------------------------------------------------------------- | ||
545 | *# | ||
546 | *# FUNCTION NAME: i2c_readreg | ||
547 | *# | ||
548 | *# DESCRIPTION : Reads a value from the decoder registers. | ||
549 | *# | ||
550 | *#--------------------------------------------------------------------------*/ | ||
551 | unsigned char | ||
552 | i2c_readreg(unsigned char theSlave, unsigned char theReg) | ||
553 | { | ||
554 | unsigned char b = 0; | ||
555 | int error, cntr = 3; | ||
556 | unsigned long flags; | ||
557 | |||
558 | do { | ||
559 | error = 0; | ||
560 | /* | ||
561 | * we don't like to be interrupted | ||
562 | */ | ||
563 | local_irq_save(flags); | ||
564 | local_irq_disable(); | ||
565 | /* | ||
566 | * generate start condition | ||
567 | */ | ||
568 | i2c_start(); | ||
569 | |||
570 | /* | ||
571 | * send slave address | ||
572 | */ | ||
573 | i2c_outbyte((theSlave & 0xfe)); | ||
574 | /* | ||
575 | * wait for ack | ||
576 | */ | ||
577 | if(!i2c_getack()) | ||
578 | error = 1; | ||
579 | /* | ||
580 | * now select register | ||
581 | */ | ||
582 | i2c_dir_out(); | ||
583 | i2c_outbyte(theReg); | ||
584 | /* | ||
585 | * now it's time to wait for ack | ||
586 | */ | ||
587 | if(!i2c_getack()) | ||
588 | error = 1; | ||
589 | /* | ||
590 | * repeat start condition | ||
591 | */ | ||
592 | i2c_delay(CLOCK_LOW_TIME); | ||
593 | i2c_start(); | ||
594 | /* | ||
595 | * send slave address | ||
596 | */ | ||
597 | i2c_outbyte(theSlave | 0x01); | ||
598 | /* | ||
599 | * wait for ack | ||
600 | */ | ||
601 | if(!i2c_getack()) | ||
602 | error = 1; | ||
603 | /* | ||
604 | * fetch register | ||
605 | */ | ||
606 | b = i2c_inbyte(); | ||
607 | /* | ||
608 | * last received byte needs to be nacked | ||
609 | * instead of acked | ||
610 | */ | ||
611 | i2c_sendack(); | ||
612 | /* | ||
613 | * end sequence | ||
614 | */ | ||
615 | i2c_stop(); | ||
616 | /* | ||
617 | * enable interrupt again | ||
618 | */ | ||
619 | local_irq_restore(flags); | ||
620 | |||
621 | } while(error && cntr--); | ||
622 | |||
623 | return b; | ||
624 | } | ||
625 | |||
626 | static int | ||
627 | i2c_open(struct inode *inode, struct file *filp) | ||
628 | { | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static int | ||
633 | i2c_release(struct inode *inode, struct file *filp) | ||
634 | { | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* Main device API. ioctl's to write or read to/from i2c registers. | ||
639 | */ | ||
640 | |||
641 | static int | ||
642 | i2c_ioctl(struct inode *inode, struct file *file, | ||
643 | unsigned int cmd, unsigned long arg) | ||
644 | { | ||
645 | if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { | ||
646 | return -EINVAL; | ||
647 | } | ||
648 | |||
649 | switch (_IOC_NR(cmd)) { | ||
650 | case I2C_WRITEREG: | ||
651 | /* write to an i2c slave */ | ||
652 | D(printk("i2cw %d %d %d\n", | ||
653 | I2C_ARGSLAVE(arg), | ||
654 | I2C_ARGREG(arg), | ||
655 | I2C_ARGVALUE(arg))); | ||
656 | |||
657 | return i2c_writereg(I2C_ARGSLAVE(arg), | ||
658 | I2C_ARGREG(arg), | ||
659 | I2C_ARGVALUE(arg)); | ||
660 | case I2C_READREG: | ||
661 | { | ||
662 | unsigned char val; | ||
663 | /* read from an i2c slave */ | ||
664 | D(printk("i2cr %d %d ", | ||
665 | I2C_ARGSLAVE(arg), | ||
666 | I2C_ARGREG(arg))); | ||
667 | val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); | ||
668 | D(printk("= %d\n", val)); | ||
669 | return val; | ||
670 | } | ||
671 | default: | ||
672 | return -EINVAL; | ||
673 | |||
674 | } | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | static struct file_operations i2c_fops = { | ||
680 | .owner = THIS_MODULE, | ||
681 | .ioctl = i2c_ioctl, | ||
682 | .open = i2c_open, | ||
683 | .release = i2c_release, | ||
684 | }; | ||
685 | |||
686 | int __init | ||
687 | i2c_init(void) | ||
688 | { | ||
689 | /* Setup and enable the Port B I2C interface */ | ||
690 | |||
691 | #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C | ||
692 | *R_PORT_PB_I2C = port_pb_i2c_shadow |= | ||
693 | IO_STATE(R_PORT_PB_I2C, i2c_en, on) | | ||
694 | IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) | | ||
695 | IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) | | ||
696 | IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable); | ||
697 | #endif | ||
698 | |||
699 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0); | ||
700 | port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1); | ||
701 | |||
702 | *R_PORT_PB_DIR = (port_pb_dir_shadow |= | ||
703 | IO_STATE(R_PORT_PB_DIR, dir0, input) | | ||
704 | IO_STATE(R_PORT_PB_DIR, dir1, output)); | ||
705 | |||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | static int __init | ||
710 | i2c_register(void) | ||
711 | { | ||
712 | int res; | ||
713 | |||
714 | i2c_init(); | ||
715 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); | ||
716 | if(res < 0) { | ||
717 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); | ||
718 | return res; | ||
719 | } | ||
720 | |||
721 | printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | /* this makes sure that i2c_register is called during boot */ | ||
727 | |||
728 | module_init(i2c_register); | ||
729 | |||
730 | /****************** END OF FILE i2c.c ********************************/ | ||
diff --git a/arch/cris/arch-v10/drivers/i2c.h b/arch/cris/arch-v10/drivers/i2c.h new file mode 100644 index 000000000000..4ee91426bd40 --- /dev/null +++ b/arch/cris/arch-v10/drivers/i2c.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* $Id: i2c.h,v 1.3 2004/05/28 09:26:59 starvik Exp $ */ | ||
2 | |||
3 | int i2c_init(void); | ||
4 | |||
5 | /* High level I2C actions */ | ||
6 | int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); | ||
7 | unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg); | ||
8 | |||
9 | /* Low level I2C */ | ||
10 | void i2c_start(void); | ||
11 | void i2c_stop(void); | ||
12 | void i2c_outbyte(unsigned char x); | ||
13 | unsigned char i2c_inbyte(void); | ||
14 | int i2c_getack(void); | ||
15 | void i2c_sendack(void); | ||
16 | |||
17 | |||
18 | |||
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c new file mode 100644 index 000000000000..b3dfdf7b8fc5 --- /dev/null +++ b/arch/cris/arch-v10/drivers/pcf8563.c | |||
@@ -0,0 +1,313 @@ | |||
1 | /* | ||
2 | * PCF8563 RTC | ||
3 | * | ||
4 | * From Phillips' datasheet: | ||
5 | * | ||
6 | * The PCF8563 is a CMOS real-time clock/calendar optimized for low power | ||
7 | * consumption. A programmable clock output, interupt output and voltage | ||
8 | * low detector are also provided. All address and data are transferred | ||
9 | * serially via two-line bidirectional I2C-bus. Maximum bus speed is | ||
10 | * 400 kbits/s. The built-in word address register is incremented | ||
11 | * automatically after each written or read bute. | ||
12 | * | ||
13 | * Copyright (c) 2002, Axis Communications AB | ||
14 | * All rights reserved. | ||
15 | * | ||
16 | * Author: Tobias Anderberg <tobiasa@axis.com>. | ||
17 | * | ||
18 | * $Id: pcf8563.c,v 1.8 2004/08/24 06:42:51 starvik Exp $ | ||
19 | */ | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/version.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/fs.h> | ||
29 | #include <linux/ioctl.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/bcd.h> | ||
32 | |||
33 | #include <asm/uaccess.h> | ||
34 | #include <asm/system.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/arch/svinto.h> | ||
37 | #include <asm/rtc.h> | ||
38 | #include "i2c.h" | ||
39 | |||
40 | #define PCF8563_MAJOR 121 /* Local major number. */ | ||
41 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ | ||
42 | #define PCF8563_NAME "PCF8563" | ||
43 | #define DRIVER_VERSION "$Revision: 1.8 $" | ||
44 | |||
45 | /* I2C bus slave registers. */ | ||
46 | #define RTC_I2C_READ 0xa3 | ||
47 | #define RTC_I2C_WRITE 0xa2 | ||
48 | |||
49 | /* Two simple wrapper macros, saves a few keystrokes. */ | ||
50 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) | ||
51 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) | ||
52 | |||
53 | static const unsigned char days_in_month[] = | ||
54 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | ||
55 | |||
56 | int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | ||
57 | |||
58 | static struct file_operations pcf8563_fops = { | ||
59 | .owner = THIS_MODULE, | ||
60 | .ioctl = pcf8563_ioctl, | ||
61 | }; | ||
62 | |||
63 | unsigned char | ||
64 | pcf8563_readreg(int reg) | ||
65 | { | ||
66 | unsigned char res = i2c_readreg(RTC_I2C_READ, reg); | ||
67 | |||
68 | /* The PCF8563 does not return 0 for unimplemented bits */ | ||
69 | switch(reg) | ||
70 | { | ||
71 | case RTC_SECONDS: | ||
72 | case RTC_MINUTES: | ||
73 | res &= 0x7f; | ||
74 | break; | ||
75 | case RTC_HOURS: | ||
76 | case RTC_DAY_OF_MONTH: | ||
77 | res &= 0x3f; | ||
78 | break; | ||
79 | case RTC_MONTH: | ||
80 | res = (res & 0x1f) - 1; /* PCF8563 returns month in range 1-12 */ | ||
81 | break; | ||
82 | } | ||
83 | return res; | ||
84 | } | ||
85 | |||
86 | void | ||
87 | pcf8563_writereg(int reg, unsigned char val) | ||
88 | { | ||
89 | #ifdef CONFIG_ETRAX_RTC_READONLY | ||
90 | if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR)) | ||
91 | return; | ||
92 | #endif | ||
93 | |||
94 | rtc_write(reg, val); | ||
95 | } | ||
96 | |||
97 | void | ||
98 | get_rtc_time(struct rtc_time *tm) | ||
99 | { | ||
100 | tm->tm_sec = rtc_read(RTC_SECONDS); | ||
101 | tm->tm_min = rtc_read(RTC_MINUTES); | ||
102 | tm->tm_hour = rtc_read(RTC_HOURS); | ||
103 | tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); | ||
104 | tm->tm_mon = rtc_read(RTC_MONTH); | ||
105 | tm->tm_year = rtc_read(RTC_YEAR); | ||
106 | |||
107 | if (tm->tm_sec & 0x80) | ||
108 | printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); | ||
109 | |||
110 | tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); | ||
111 | tm->tm_sec &= 0x7f; | ||
112 | tm->tm_min &= 0x7f; | ||
113 | tm->tm_hour &= 0x3f; | ||
114 | tm->tm_mday &= 0x3f; | ||
115 | tm->tm_mon &= 0x1f; | ||
116 | |||
117 | BCD_TO_BIN(tm->tm_sec); | ||
118 | BCD_TO_BIN(tm->tm_min); | ||
119 | BCD_TO_BIN(tm->tm_hour); | ||
120 | BCD_TO_BIN(tm->tm_mday); | ||
121 | BCD_TO_BIN(tm->tm_mon); | ||
122 | tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */ | ||
123 | } | ||
124 | |||
125 | int __init | ||
126 | pcf8563_init(void) | ||
127 | { | ||
128 | unsigned char ret; | ||
129 | |||
130 | i2c_init(); | ||
131 | |||
132 | /* | ||
133 | * First of all we need to reset the chip. This is done by | ||
134 | * clearing control1, control2 and clk freq, clear the | ||
135 | * Voltage Low bit, and resetting all alarms. | ||
136 | */ | ||
137 | if (rtc_write(RTC_CONTROL1, 0x00) < 0) | ||
138 | goto err; | ||
139 | |||
140 | if (rtc_write(RTC_CONTROL2, 0x00) < 0) | ||
141 | goto err; | ||
142 | |||
143 | if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) | ||
144 | goto err; | ||
145 | |||
146 | /* Clear the VL bit in the seconds register. */ | ||
147 | ret = rtc_read(RTC_SECONDS); | ||
148 | |||
149 | if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0) | ||
150 | goto err; | ||
151 | |||
152 | /* Reset the alarms. */ | ||
153 | if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0) | ||
154 | goto err; | ||
155 | |||
156 | if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0) | ||
157 | goto err; | ||
158 | |||
159 | if (rtc_write(RTC_DAY_ALARM, 0x00) < 0) | ||
160 | goto err; | ||
161 | |||
162 | if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0) | ||
163 | goto err; | ||
164 | |||
165 | /* Check for low voltage, and warn about it.. */ | ||
166 | if (rtc_read(RTC_SECONDS) & 0x80) | ||
167 | printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); | ||
168 | |||
169 | return 0; | ||
170 | |||
171 | err: | ||
172 | printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); | ||
173 | return -1; | ||
174 | } | ||
175 | |||
176 | void __exit | ||
177 | pcf8563_exit(void) | ||
178 | { | ||
179 | if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) { | ||
180 | printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because | ||
186 | * POSIX says so! | ||
187 | */ | ||
188 | int | ||
189 | pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) | ||
190 | { | ||
191 | /* Some sanity checks. */ | ||
192 | if (_IOC_TYPE(cmd) != RTC_MAGIC) | ||
193 | return -ENOTTY; | ||
194 | |||
195 | if (_IOC_NR(cmd) > RTC_MAX_IOCTL) | ||
196 | return -ENOTTY; | ||
197 | |||
198 | switch (cmd) { | ||
199 | case RTC_RD_TIME: | ||
200 | { | ||
201 | struct rtc_time tm; | ||
202 | |||
203 | get_rtc_time(&tm); | ||
204 | |||
205 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { | ||
206 | return -EFAULT; | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | break; | ||
212 | case RTC_SET_TIME: | ||
213 | { | ||
214 | #ifdef CONFIG_ETRAX_RTC_READONLY | ||
215 | return -EPERM; | ||
216 | #else | ||
217 | int leap; | ||
218 | int century; | ||
219 | struct rtc_time tm; | ||
220 | |||
221 | memset(&tm, 0, sizeof (struct rtc_time)); | ||
222 | if (!capable(CAP_SYS_TIME)) | ||
223 | return -EPERM; | ||
224 | |||
225 | if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time))) | ||
226 | return -EFAULT; | ||
227 | |||
228 | /* Convert from struct tm to struct rtc_time. */ | ||
229 | tm.tm_year += 1900; | ||
230 | tm.tm_mon += 1; | ||
231 | |||
232 | leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0; | ||
233 | |||
234 | /* Perform some sanity checks. */ | ||
235 | if ((tm.tm_year < 1970) || | ||
236 | (tm.tm_mon > 12) || | ||
237 | (tm.tm_mday == 0) || | ||
238 | (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || | ||
239 | (tm.tm_hour >= 24) || | ||
240 | (tm.tm_min >= 60) || | ||
241 | (tm.tm_sec >= 60)) | ||
242 | return -EINVAL; | ||
243 | |||
244 | century = (tm.tm_year >= 2000) ? 0x80 : 0; | ||
245 | tm.tm_year = tm.tm_year % 100; | ||
246 | |||
247 | BIN_TO_BCD(tm.tm_year); | ||
248 | BIN_TO_BCD(tm.tm_mday); | ||
249 | BIN_TO_BCD(tm.tm_hour); | ||
250 | BIN_TO_BCD(tm.tm_min); | ||
251 | BIN_TO_BCD(tm.tm_sec); | ||
252 | tm.tm_mon |= century; | ||
253 | |||
254 | rtc_write(RTC_YEAR, tm.tm_year); | ||
255 | rtc_write(RTC_MONTH, tm.tm_mon); | ||
256 | rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); | ||
257 | rtc_write(RTC_HOURS, tm.tm_hour); | ||
258 | rtc_write(RTC_MINUTES, tm.tm_min); | ||
259 | rtc_write(RTC_SECONDS, tm.tm_sec); | ||
260 | |||
261 | return 0; | ||
262 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ | ||
263 | } | ||
264 | |||
265 | case RTC_VLOW_RD: | ||
266 | { | ||
267 | int vl_bit = 0; | ||
268 | |||
269 | if (rtc_read(RTC_SECONDS) & 0x80) { | ||
270 | vl_bit = 1; | ||
271 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable " | ||
272 | "date/time information is no longer guaranteed!\n", | ||
273 | PCF8563_NAME); | ||
274 | } | ||
275 | if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) | ||
276 | return -EFAULT; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | case RTC_VLOW_SET: | ||
282 | { | ||
283 | /* Clear the VL bit in the seconds register */ | ||
284 | int ret = rtc_read(RTC_SECONDS); | ||
285 | |||
286 | rtc_write(RTC_SECONDS, (ret & 0x7F)); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | default: | ||
292 | return -ENOTTY; | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int __init | ||
299 | pcf8563_register(void) | ||
300 | { | ||
301 | pcf8563_init(); | ||
302 | if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { | ||
303 | printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", | ||
304 | PCF8563_NAME, PCF8563_MAJOR); | ||
305 | return -1; | ||
306 | } | ||
307 | |||
308 | printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | module_init(pcf8563_register); | ||
313 | module_exit(pcf8563_exit); | ||