aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acorn/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acorn/char
Linux-2.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 'drivers/acorn/char')
-rw-r--r--drivers/acorn/char/Makefile6
-rw-r--r--drivers/acorn/char/defkeymap-l7200.c386
-rw-r--r--drivers/acorn/char/i2c.c369
-rw-r--r--drivers/acorn/char/pcf8583.c239
-rw-r--r--drivers/acorn/char/pcf8583.h41
5 files changed, 1041 insertions, 0 deletions
diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile
new file mode 100644
index 00000000000..2fa9a8bf48a
--- /dev/null
+++ b/drivers/acorn/char/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the acorn character device drivers.
3#
4
5obj-$(CONFIG_ARCH_ACORN) += i2c.o pcf8583.o
6obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c
new file mode 100644
index 00000000000..9e18ce742e3
--- /dev/null
+++ b/drivers/acorn/char/defkeymap-l7200.c
@@ -0,0 +1,386 @@
1/*
2 * linux/drivers/acorn/char/defkeymap-l7200.c
3 *
4 * Default keyboard maps for LinkUp Systems L7200 board
5 *
6 * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
7 *
8 * Changelog:
9 * 08-04-2000 SJH Created file
10 */
11
12#include <linux/types.h>
13#include <linux/keyboard.h>
14#include <linux/kd.h>
15
16/* Normal (maps 1:1 with no processing) */
17#define KTn 0xF0
18/* Function keys */
19#define KTf 0xF1
20/* Special (Performs special house-keeping funcs) */
21#define KTs 0xF2
22#define KIGNORE K(KTs, 0) /* Ignore */
23#define KENTER K(KTs, 1) /* Enter */
24#define KREGS K(KTs, 2) /* Regs */
25#define KMEM K(KTs, 3) /* Mem */
26#define KSTAT K(KTs, 4) /* State */
27#define KINTR K(KTs, 5) /* Intr */
28#define Ksl 6 /* Last console */
29#define KCAPSLK K(KTs, 7) /* Caps lock */
30#define KNUMLK K(KTs, 8) /* Num-lock */
31#define KSCRLLK K(KTs, 9) /* Scroll-lock */
32#define KSCRLFOR K(KTs,10) /* Scroll forward */
33#define KSCRLBAK K(KTs,11) /* Scroll back */
34#define KREBOOT K(KTs,12) /* Reboot */
35#define KCAPSON K(KTs,13) /* Caps on */
36#define KCOMPOSE K(KTs,14) /* Compose */
37#define KSAK K(KTs,15) /* SAK */
38#define CONS_DEC K(KTs,16) /* Dec console */
39#define CONS_INC K(KTs,17) /* Incr console */
40#define KFLOPPY K(KTs,18) /* Floppy */
41/* Key pad (0-9 = digits, 10=+, 11=-, 12=*, 13=/, 14=enter, 16=., 17=# */
42#define KTp 0xF3
43#define KPAD_0 K(KTp, 0 )
44#define KPAD_1 K(KTp, 1 )
45#define KPAD_2 K(KTp, 2 )
46#define KPAD_3 K(KTp, 3 )
47#define KPAD_4 K(KTp, 4 )
48#define KPAD_5 K(KTp, 5 )
49#define KPAD_6 K(KTp, 6 )
50#define KPAD_7 K(KTp, 7 )
51#define KPAD_8 K(KTp, 8 )
52#define KPAD_9 K(KTp, 9 )
53#define KPAD_PL K(KTp,10 )
54#define KPAD_MI K(KTp,11 )
55#define KPAD_ML K(KTp,12 )
56#define KPAD_DV K(KTp,13 )
57#define KPAD_EN K(KTp,14 )
58#define KPAD_DT K(KTp,16 )
59#define KPAD_HS K(KTp,20 )
60/* Console switching */
61#define KCn 0xF5
62/* Cursor */
63#define KTc 0xF6
64#define Kcd 0 /* Cursor down */
65#define Kcl 1 /* Cursor left */
66#define Kcr 2 /* Cursor right */
67#define Kcu 3 /* Cursor up */
68/* Shift/alt modifiers etc */
69#define KMd 0xF7
70#define KSHIFT K(KMd, 0 )
71#define KALTGR K(KMd, 1 )
72#define KCTRL K(KMd, 2 )
73#define KALT K(KMd, 3 )
74/* Meta */
75#define KMt 0xF8
76#define KAs 0xF9
77#define KPADA_0 K(KAs, 0 )
78#define KPADA_1 K(KAs, 1 )
79#define KPADA_2 K(KAs, 2 )
80#define KPADA_3 K(KAs, 3 )
81#define KPADA_4 K(KAs, 4 )
82#define KPADA_5 K(KAs, 5 )
83#define KPADA_6 K(KAs, 6 )
84#define KPADA_7 K(KAs, 7 )
85#define KPADA_8 K(KAs, 8 )
86#define KPADA_9 K(KAs, 9 )
87#define KPADB_0 K(KAs,10 )
88#define KPADB_1 K(KAs,11 )
89#define KPADB_2 K(KAs,12 )
90#define KPADB_3 K(KAs,13 )
91#define KPADB_4 K(KAs,14 )
92#define KPADB_5 K(KAs,15 )
93#define KPADB_6 K(KAs,16 )
94#define KPADB_7 K(KAs,17 )
95#define KPADB_8 K(KAs,18 )
96#define KPADB_9 K(KAs,19 )
97/* Locking keys */
98#define KLk 0xFA
99/* Letters */
100#define KTl 0xFB
101
102/*
103 * Here is the layout of the keys for the Fujitsu QWERTY
104 * style keyboard:
105 *
106 * static char Fujitsu_Key_Table[] =
107 * {
108 * KALT, '`' , KNUL, KCTL, KFUN, KESC, '1' , '2' ,
109 * '9' , '0' , '-' , '=' , KNUL, KBSP, KNUL, KNUL,
110 * KNUL, KBSL, KSHF, KNUL, KNUL, KDEL, KNUL, 't' ,
111 * 'y' , 'u' , 'i' , KRET, KSHF, KPGD, KNUL, KNUL,
112 * KNUL, KTAB, KNUL, KNUL, KNUL, 'q' , 'w' , 'e' ,
113 * 'r' , 'o' , 'p' , '[' , KNUL, ']' , KNUL, KNUL,
114 * KNUL, 'z' , KNUL, KNUL, KNUL, KSHL, KNUL, KNUL,
115 * 'k' , 'l' , ';' , KSQT, KNUL, KPGU, KNUL, KNUL,
116 * KNUL, 'a' , KNUL, KNUL, KNUL, 's' , 'd' , 'f' ,
117 * 'g' , 'h' , 'j' , '/' , KNUL, KHME, KNUL, KNUL,
118 * KNUL, 'x' , KNUL, KNUL, KNUL, 'c' , 'v' , 'b' ,
119 * 'n' , 'm' , ',' , '.' , KNUL, ' ' , KNUL, KNUL,
120 * KNUL, KNUL, KNUL, KNUL, KNUL, '3' , '4' , '5' ,
121 * '6' , '7' , '8' , KNUL, KPRG, KNUL, KEND, KNUL,
122 * };
123 */
124
125u_short plain_map[NR_KEYS]=
126{
127 0xf703, 0xf060, 0xf200, 0xf702, 0xf200, 0xf01b, 0xf031, 0xf032,
128 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf200, 0xf07f, 0xf200, 0xf200,
129 0xf200, 0xf05c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xfb74,
130 0xfb79, 0xfb75, 0xfb69, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
131 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xfb71, 0xfb77, 0xfb65,
132 0xfb72, 0xfb6f, 0xfb70, 0xf05b, 0xf200, 0xf05d, 0xf200, 0xf200,
133 0xf200, 0xfb7a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
134 0xfb6b, 0xfb6c, 0xf03b, 0xf027, 0xf200, 0xf603, 0xf200, 0xf200,
135 0xf200, 0xfb61, 0xf200, 0xf200, 0xf200, 0xfb73, 0xfb64, 0xfb66,
136 0xfb67, 0xfb68, 0xfb6a, 0xf02f, 0xf200, 0xf601, 0xf200, 0xf200,
137 0xf200, 0xfb78, 0xf200, 0xf200, 0xf200, 0xfb63, 0xfb76, 0xfb62,
138 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf200, 0xf020, 0xf200, 0xf200,
139 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf033, 0xf034, 0xf035,
140 0xf036, 0xf037, 0xf038, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
141 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
142 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
143};
144
145u_short shift_map[NR_KEYS]=
146{
147 0xf703, 0xf07e, 0xf200, 0xf702, 0xf200, 0xf01b, 0xf021, 0xf040,
148 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf200, 0xf07f, 0xf200, 0xf200,
149 0xf200, 0xf07c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xfb54,
150 0xfb59, 0xfb55, 0xfb49, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
151 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xfb51, 0xfb57, 0xfb45,
152 0xfb52, 0xfb4f, 0xfb50, 0xf07b, 0xf200, 0xf07d, 0xf200, 0xf200,
153 0xf200, 0xfb5a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
154 0xfb4b, 0xfb4c, 0xf03a, 0xf022, 0xf200, 0xf603, 0xf200, 0xf200,
155 0xf200, 0xfb41, 0xf200, 0xf200, 0xf200, 0xfb53, 0xfb44, 0xfb46,
156 0xfb47, 0xfb48, 0xfb4a, 0xf03f, 0xf200, 0xf601, 0xf200, 0xf200,
157 0xf200, 0xfb58, 0xf200, 0xf200, 0xf200, 0xfb43, 0xfb56, 0xfb42,
158 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf200, 0xf020, 0xf200, 0xf200,
159 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf023, 0xf024, 0xf025,
160 0xf05e, 0xf026, 0xf02a, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
161 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
162 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
163};
164
165u_short altgr_map[NR_KEYS]=
166{
167 KIGNORE ,K(KCn,12 ),K(KCn,13 ),K(KCn,14 ),K(KCn,15 ),K(KCn,16 ),K(KCn,17 ),K(KCn, 18),
168 K(KCn, 19),K(KCn,20 ),K(KCn,21 ),K(KCn,22 ),K(KCn,23 ),KIGNORE ,KREGS ,KINTR ,
169 KIGNORE ,KIGNORE ,K(KTn,'@'),KIGNORE ,K(KTn,'$'),KIGNORE ,KIGNORE ,K(KTn,'{'),
170 K(KTn,'['),K(KTn,']'),K(KTn,'}'),K(KTn,'\\'),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
171 K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KTl,'q'),
172 K(KTl,'w'),K(KTl,'e'),K(KTl,'r'),K(KTl,'t' ),K(KTl,'y'),K(KTl,'u'),K(KTl,'i' ),K(KTl,'o'),
173 K(KTl,'p'),KIGNORE ,K(KTn,'~'),KIGNORE ,K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPADB_7 ,
174 KPADB_8 ,KPADB_9 ,KPAD_MI ,KCTRL ,K(KAs,20 ),K(KTl,'s'),K(KAs,23 ),K(KAs,25 ),
175 K(KTl,'g'),K(KTl,'h'),K(KTl,'j'),K(KTl,'k' ),K(KTl,'l'),KIGNORE ,KIGNORE ,KENTER ,
176 KPADB_4 ,KPADB_5 ,KPADB_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KTl,'z' ),K(KTl,'x'),
177 K(KAs,22 ),K(KTl,'v'),K(KTl,21 ),K(KTl,'n' ),K(KTl,'m'),KIGNORE ,KIGNORE ,KIGNORE ,
178 KSHIFT ,K(KTc,Kcu),KPADB_1 ,KPADB_2 ,KPADB_3 ,KCAPSLK ,KALT ,KIGNORE ,
179 KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPADB_0 ,KPAD_DT ,KPAD_EN ,
180 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
181 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
182 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
183};
184
185u_short ctrl_map[NR_KEYS]=
186{
187 0xf703, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200, 0xf001, 0xf002,
188 0xf009, 0xf000, 0xf031, 0xf200, 0xf200, 0xf07f, 0xf200, 0xf200,
189 0xf200, 0xf01c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xf020,
190 0xf019, 0xf015, 0xf009, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
191 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005,
192 0xf012, 0xf00f, 0xf010, 0xf01b, 0xf200, 0xf01d, 0xf200, 0xf200,
193 0xf200, 0xf01a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
194 0xf00b, 0xf00c, 0xf200, 0xf007, 0xf200, 0xf603, 0xf200, 0xf200,
195 0xf200, 0xf001, 0xf200, 0xf200, 0xf200, 0xf001, 0xf013, 0xf006,
196 0xf007, 0xf008, 0xf00a, 0xf07f, 0xf200, 0xf601, 0xf200, 0xf200,
197 0xf200, 0xf018, 0xf200, 0xf200, 0xf200, 0xf003, 0xf016, 0xf002,
198 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200,
199 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b, 0xf01c, 0xf01d,
200 0xf036, 0xf037, 0xf038, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
201 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
202 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
203};
204
205u_short shift_ctrl_map[NR_KEYS]=
206{
207 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
208 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KFLOPPY ,KINTR ,
209 KIGNORE ,KIGNORE ,K(KTn, 0 ),KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
210 KIGNORE ,KIGNORE ,KIGNORE ,K(KTn,31 ),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
211 K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KTn,17 ),
212 K(KTn,23 ),K(KTn, 5 ),K(KTn,18 ),K(KTn,20 ),K(KTn,25 ),K(KTn,21 ),K(KTn, 9 ),K(KTn,15 ),
213 K(KTn,16 ),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPAD_7 ,
214 KPAD_8 ,KPAD_9 ,KPAD_MI ,KCTRL ,K(KTn, 1 ),K(KTn,19 ),K(KTn, 4 ),K(KTn, 6 ),
215 K(KTn, 7 ),K(KTn, 8 ),K(KTn,10 ),K(KTn,11 ),K(KTn,12 ),KIGNORE ,K(KTn, 7 ),KENTER ,
216 KPAD_4 ,KPAD_5 ,KPAD_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KTn,26 ),K(KTn,24 ),
217 K(KTn, 3 ),K(KTn,22 ),K(KTn, 2 ),K(KTn,14 ),K(KTn,13 ),KIGNORE ,KIGNORE ,KIGNORE ,
218 KSHIFT ,K(KTc,Kcu),KPAD_1 ,KPAD_2 ,KPAD_3 ,KCAPSLK ,KALT ,K(KTn, 0 ),
219 KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPAD_0 ,KPAD_DT ,KPAD_EN ,
220 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
221 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
222 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
223};
224
225u_short alt_map[NR_KEYS]=
226{
227 K(KMt,27 ),K(KCn, 0 ),K(KCn, 1 ),K(KCn, 2 ),K(KCn, 3 ),K(KCn, 4 ),K(KCn, 5 ),K(KCn, 6 ),
228 K(KCn, 7 ),K(KCn, 8 ),K(KCn, 9 ),K(KCn,10 ),K(KCn,11 ),KIGNORE ,KSCRLLK ,KINTR ,
229 K(KMt,'`'),K(KMt,'1'),K(KMt,'2'),K(KMt,'3' ),K(KMt,'4'),K(KMt,'5'),K(KMt,'6' ),K(KMt,'7'),
230 K(KMt,'8'),K(KMt,'9'),K(KMt,'0'),K(KMt,'-' ),K(KMt,'='),K(KMt,'£'),K(KMt,127 ),K(KTf,21 ),
231 K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,K(KMt, 9 ),K(KMt,'q'),
232 K(KMt,'w'),K(KMt,'e'),K(KMt,'r'),K(KMt,'t' ),K(KMt,'y'),K(KMt,'u'),K(KMt,'i' ),K(KMt,'o'),
233 K(KMt,'p'),K(KMt,'['),K(KMt,']'),K(KMt,'\\'),K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPADA_7 ,
234 KPADA_8 ,KPADA_9 ,KPAD_MI ,KCTRL ,K(KMt,'a'),K(KMt,'s'),K(KMt,'d' ),K(KMt,'f'),
235 K(KMt,'g'),K(KMt,'h'),K(KMt,'j'),K(KMt,'k' ),K(KMt,'l'),K(KMt,';'),K(KMt,'\''),K(KMt,13 ),
236 KPADA_4 ,KPADA_5 ,KPADA_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KMt,'z' ),K(KMt,'x'),
237 K(KMt,'c'),K(KMt,'v'),K(KMt,'b'),K(KMt,'n' ),K(KMt,'m'),K(KMt,','),K(KMt,'.' ),KIGNORE ,
238 KSHIFT ,K(KTc,Kcu),KPADA_1 ,KPADA_2 ,KPADA_3 ,KCAPSLK ,KALT ,K(KMt,' '),
239 KALTGR ,KCTRL ,CONS_DEC ,K(KTc,Kcd ),CONS_INC ,KPADA_0 ,KPAD_DT ,KPAD_EN ,
240 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
241 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
242 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
243};
244
245u_short ctrl_alt_map[NR_KEYS]=
246{
247 KIGNORE ,K(KCn, 0 ),K(KCn, 1 ),K(KCn, 2 ),K(KCn, 3 ),K(KCn, 4 ),K(KCn, 5 ),K(KCn, 6 ),
248 K(KCn, 7 ),K(KCn, 8 ),K(KCn, 9 ),K(KCn,10 ),K(KCn,11 ),KIGNORE ,KIGNORE ,KINTR ,
249 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
250 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
251 K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KMt,17 ),
252 K(KMt,23 ),K(KMt, 5 ),K(KMt,18 ),K(KMt,20 ),K(KMt,25 ),K(KMt,21 ),K(KMt, 9 ),K(KMt,15 ),
253 K(KMt,16 ),KIGNORE ,KIGNORE ,KIGNORE ,KREBOOT ,K(KTf,23 ),K(KTf,25 ),KPAD_7 ,
254 KPAD_8 ,KPAD_9 ,KPAD_MI ,KCTRL ,K(KMt, 1 ),K(KMt,19 ),K(KMt, 4 ),K(KMt, 6 ),
255 K(KMt, 7 ),K(KMt, 8 ),K(KMt,10 ),K(KMt,11 ),K(KMt,12 ),KIGNORE ,KIGNORE ,KENTER ,
256 KPAD_4 ,KPAD_5 ,KPAD_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KMt,26 ),K(KMt,24 ),
257 K(KMt, 3 ),K(KMt,22 ),K(KMt, 2 ),K(KMt,14 ),K(KMt,13 ),KIGNORE ,KIGNORE ,KIGNORE ,
258 KSHIFT ,K(KTc,Kcu),KPAD_1 ,KPAD_2 ,KPAD_3 ,KCAPSLK ,KALT ,KIGNORE ,
259 KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPAD_0 ,KREBOOT ,KPAD_EN ,
260 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
261 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
262 KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
263};
264
265ushort *key_maps[MAX_NR_KEYMAPS] = {
266 plain_map, shift_map, altgr_map, 0,
267 ctrl_map, shift_ctrl_map, 0, 0,
268 alt_map, 0, 0, 0,
269 ctrl_alt_map, 0
270};
271
272unsigned int keymap_count = 7;
273
274/*
275 * Philosophy: most people do not define more strings, but they who do
276 * often want quite a lot of string space. So, we statically allocate
277 * the default and allocate dynamically in chunks of 512 bytes.
278 */
279
280char func_buf[] = {
281 '\033', '[', '[', 'A', 0,
282 '\033', '[', '[', 'B', 0,
283 '\033', '[', '[', 'C', 0,
284 '\033', '[', '[', 'D', 0,
285 '\033', '[', '[', 'E', 0,
286 '\033', '[', '1', '7', '~', 0,
287 '\033', '[', '1', '8', '~', 0,
288 '\033', '[', '1', '9', '~', 0,
289 '\033', '[', '2', '0', '~', 0,
290 '\033', '[', '2', '1', '~', 0,
291 '\033', '[', '2', '3', '~', 0,
292 '\033', '[', '2', '4', '~', 0,
293 '\033', '[', '2', '5', '~', 0,
294 '\033', '[', '2', '6', '~', 0,
295 '\033', '[', '2', '8', '~', 0,
296 '\033', '[', '2', '9', '~', 0,
297 '\033', '[', '3', '1', '~', 0,
298 '\033', '[', '3', '2', '~', 0,
299 '\033', '[', '3', '3', '~', 0,
300 '\033', '[', '3', '4', '~', 0,
301 '\033', '[', '1', '~', 0,
302 '\033', '[', '2', '~', 0,
303 '\033', '[', '3', '~', 0,
304 '\033', '[', '4', '~', 0,
305 '\033', '[', '5', '~', 0,
306 '\033', '[', '6', '~', 0,
307 '\033', '[', 'M', 0,
308 '\033', '[', 'P', 0,
309};
310
311char *funcbufptr = func_buf;
312int funcbufsize = sizeof(func_buf);
313int funcbufleft = 0; /* space left */
314
315char *func_table[MAX_NR_FUNC] = {
316 func_buf + 0,
317 func_buf + 5,
318 func_buf + 10,
319 func_buf + 15,
320 func_buf + 20,
321 func_buf + 25,
322 func_buf + 31,
323 func_buf + 37,
324 func_buf + 43,
325 func_buf + 49,
326 func_buf + 55,
327 func_buf + 61,
328 func_buf + 67,
329 func_buf + 73,
330 func_buf + 79,
331 func_buf + 85,
332 func_buf + 91,
333 func_buf + 97,
334 func_buf + 103,
335 func_buf + 109,
336 func_buf + 115,
337 func_buf + 120,
338 func_buf + 125,
339 func_buf + 130,
340 func_buf + 135,
341 func_buf + 140,
342 func_buf + 145,
343 0,
344 0,
345 func_buf + 149,
346 0,
347};
348
349struct kbdiacr accent_table[MAX_DIACR] = {
350 {'`', 'A', '\300'}, {'`', 'a', '\340'},
351 {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
352 {'^', 'A', '\302'}, {'^', 'a', '\342'},
353 {'~', 'A', '\303'}, {'~', 'a', '\343'},
354 {'"', 'A', '\304'}, {'"', 'a', '\344'},
355 {'O', 'A', '\305'}, {'o', 'a', '\345'},
356 {'0', 'A', '\305'}, {'0', 'a', '\345'},
357 {'A', 'A', '\305'}, {'a', 'a', '\345'},
358 {'A', 'E', '\306'}, {'a', 'e', '\346'},
359 {',', 'C', '\307'}, {',', 'c', '\347'},
360 {'`', 'E', '\310'}, {'`', 'e', '\350'},
361 {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
362 {'^', 'E', '\312'}, {'^', 'e', '\352'},
363 {'"', 'E', '\313'}, {'"', 'e', '\353'},
364 {'`', 'I', '\314'}, {'`', 'i', '\354'},
365 {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
366 {'^', 'I', '\316'}, {'^', 'i', '\356'},
367 {'"', 'I', '\317'}, {'"', 'i', '\357'},
368 {'-', 'D', '\320'}, {'-', 'd', '\360'},
369 {'~', 'N', '\321'}, {'~', 'n', '\361'},
370 {'`', 'O', '\322'}, {'`', 'o', '\362'},
371 {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
372 {'^', 'O', '\324'}, {'^', 'o', '\364'},
373 {'~', 'O', '\325'}, {'~', 'o', '\365'},
374 {'"', 'O', '\326'}, {'"', 'o', '\366'},
375 {'/', 'O', '\330'}, {'/', 'o', '\370'},
376 {'`', 'U', '\331'}, {'`', 'u', '\371'},
377 {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
378 {'^', 'U', '\333'}, {'^', 'u', '\373'},
379 {'"', 'U', '\334'}, {'"', 'u', '\374'},
380 {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
381 {'T', 'H', '\336'}, {'t', 'h', '\376'},
382 {'s', 's', '\337'}, {'"', 'y', '\377'},
383 {'s', 'z', '\337'}, {'i', 'j', '\377'},
384};
385
386unsigned int accent_table_size = 68;
diff --git a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c
new file mode 100644
index 00000000000..c22bb9dca1e
--- /dev/null
+++ b/drivers/acorn/char/i2c.c
@@ -0,0 +1,369 @@
1/*
2 * linux/drivers/acorn/char/i2c.c
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM IOC/IOMD i2c driver.
11 *
12 * On Acorn machines, the following i2c devices are on the bus:
13 * - PCF8583 real time clock & static RAM
14 */
15#include <linux/init.h>
16#include <linux/sched.h>
17#include <linux/time.h>
18#include <linux/miscdevice.h>
19#include <linux/rtc.h>
20#include <linux/i2c.h>
21#include <linux/i2c-algo-bit.h>
22#include <linux/fs.h>
23
24#include <asm/hardware.h>
25#include <asm/io.h>
26#include <asm/hardware/ioc.h>
27#include <asm/system.h>
28#include <asm/uaccess.h>
29
30#include "pcf8583.h"
31
32extern int (*set_rtc)(void);
33
34static struct i2c_client *rtc_client;
35static const unsigned char days_in_mon[] =
36 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
37
38#define CMOS_CHECKSUM (63)
39
40/*
41 * Acorn machines store the year in the static RAM at
42 * location 128.
43 */
44#define CMOS_YEAR (64 + 128)
45
46static inline int rtc_command(int cmd, void *data)
47{
48 int ret = -EIO;
49
50 if (rtc_client)
51 ret = rtc_client->driver->command(rtc_client, cmd, data);
52
53 return ret;
54}
55
56/*
57 * Update the century + year bytes in the CMOS RAM, ensuring
58 * that the check byte is correctly adjusted for the change.
59 */
60static int rtc_update_year(unsigned int new_year)
61{
62 unsigned char yr[2], chk;
63 struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr };
64 struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
65 int ret;
66
67 ret = rtc_command(MEM_READ, &cmos_check);
68 if (ret)
69 goto out;
70 ret = rtc_command(MEM_READ, &cmos_year);
71 if (ret)
72 goto out;
73
74 chk -= yr[1] + yr[0];
75
76 yr[1] = new_year / 100;
77 yr[0] = new_year % 100;
78
79 chk += yr[1] + yr[0];
80
81 ret = rtc_command(MEM_WRITE, &cmos_year);
82 if (ret == 0)
83 ret = rtc_command(MEM_WRITE, &cmos_check);
84 out:
85 return ret;
86}
87
88/*
89 * Read the current RTC time and date, and update xtime.
90 */
91static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year)
92{
93 unsigned char ctrl, yr[2];
94 struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr };
95 int real_year, year_offset;
96
97 /*
98 * Ensure that the RTC is running.
99 */
100 rtc_command(RTC_GETCTRL, &ctrl);
101 if (ctrl & 0xc0) {
102 unsigned char new_ctrl = ctrl & ~0xc0;
103
104 printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n",
105 ctrl, new_ctrl);
106
107 rtc_command(RTC_SETCTRL, &new_ctrl);
108 }
109
110 if (rtc_command(RTC_GETDATETIME, rtctm) ||
111 rtc_command(MEM_READ, &rtcmem))
112 return;
113
114 real_year = yr[0];
115
116 /*
117 * The RTC year holds the LSB two bits of the current
118 * year, which should reflect the LSB two bits of the
119 * CMOS copy of the year. Any difference indicates
120 * that we have to correct the CMOS version.
121 */
122 year_offset = rtctm->year_off - (real_year & 3);
123 if (year_offset < 0)
124 /*
125 * RTC year wrapped. Adjust it appropriately.
126 */
127 year_offset += 4;
128
129 *year = real_year + year_offset + yr[1] * 100;
130}
131
132static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year)
133{
134 unsigned char leap;
135 int ret;
136
137 leap = (!(year % 4) && (year % 100)) || !(year % 400);
138
139 if (rtctm->mon > 12 || rtctm->mon == 0 || rtctm->mday == 0)
140 return -EINVAL;
141
142 if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap)))
143 return -EINVAL;
144
145 if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60)
146 return -EINVAL;
147
148 /*
149 * The RTC's own 2-bit year must reflect the least
150 * significant two bits of the CMOS year.
151 */
152 rtctm->year_off = (year % 100) & 3;
153
154 ret = rtc_command(RTC_SETDATETIME, rtctm);
155 if (ret == 0)
156 ret = rtc_update_year(year);
157
158 return ret;
159}
160
161/*
162 * Set the RTC time only. Note that
163 * we do not touch the date.
164 */
165static int k_set_rtc_time(void)
166{
167 struct rtc_tm new_rtctm, old_rtctm;
168 unsigned long nowtime = xtime.tv_sec;
169
170 if (rtc_command(RTC_GETDATETIME, &old_rtctm))
171 return 0;
172
173 new_rtctm.cs = xtime.tv_nsec / 10000000;
174 new_rtctm.secs = nowtime % 60; nowtime /= 60;
175 new_rtctm.mins = nowtime % 60; nowtime /= 60;
176 new_rtctm.hours = nowtime % 24;
177
178 /*
179 * avoid writing when we're going to change the day
180 * of the month. We will retry in the next minute.
181 * This basically means that if the RTC must not drift
182 * by more than 1 minute in 11 minutes.
183 *
184 * [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00,
185 * rtc gets set to 1/1/2000 00:01:00 ]
186 */
187 if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) ||
188 (new_rtctm.hours == 23 && new_rtctm.mins == 59))
189 return 1;
190
191 return rtc_command(RTC_SETTIME, &new_rtctm);
192}
193
194static int rtc_ioctl(struct inode *inode, struct file *file,
195 unsigned int cmd, unsigned long arg)
196{
197 unsigned int year;
198 struct rtc_time rtctm;
199 struct rtc_tm rtc_raw;
200
201 switch (cmd) {
202 case RTC_ALM_READ:
203 case RTC_ALM_SET:
204 break;
205
206 case RTC_RD_TIME:
207 memset(&rtctm, 0, sizeof(struct rtc_time));
208 get_rtc_time(&rtc_raw, &year);
209 rtctm.tm_sec = rtc_raw.secs;
210 rtctm.tm_min = rtc_raw.mins;
211 rtctm.tm_hour = rtc_raw.hours;
212 rtctm.tm_mday = rtc_raw.mday;
213 rtctm.tm_mon = rtc_raw.mon - 1; /* month starts at 0 */
214 rtctm.tm_year = year - 1900; /* starts at 1900 */
215 return copy_to_user((void *)arg, &rtctm, sizeof(rtctm))
216 ? -EFAULT : 0;
217
218 case RTC_SET_TIME:
219 if (!capable(CAP_SYS_TIME))
220 return -EACCES;
221
222 if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm)))
223 return -EFAULT;
224 rtc_raw.secs = rtctm.tm_sec;
225 rtc_raw.mins = rtctm.tm_min;
226 rtc_raw.hours = rtctm.tm_hour;
227 rtc_raw.mday = rtctm.tm_mday;
228 rtc_raw.mon = rtctm.tm_mon + 1;
229 year = rtctm.tm_year + 1900;
230 return set_rtc_time(&rtc_raw, year);
231 break;
232
233 case RTC_EPOCH_READ:
234 return put_user(1900, (unsigned long *)arg);
235
236 }
237 return -EINVAL;
238}
239
240static struct file_operations rtc_fops = {
241 .ioctl = rtc_ioctl,
242};
243
244static struct miscdevice rtc_dev = {
245 .minor = RTC_MINOR,
246 .name = "rtc",
247 .fops = &rtc_fops,
248};
249
250/* IOC / IOMD i2c driver */
251
252#define FORCE_ONES 0xdc
253#define SCL 0x02
254#define SDA 0x01
255
256/*
257 * We must preserve all non-i2c output bits in IOC_CONTROL.
258 * Note also that we need to preserve the value of SCL and
259 * SDA outputs as well (which may be different from the
260 * values read back from IOC_CONTROL).
261 */
262static u_int force_ones;
263
264static void ioc_setscl(void *data, int state)
265{
266 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
267 u_int ones = force_ones;
268
269 if (state)
270 ones |= SCL;
271 else
272 ones &= ~SCL;
273
274 force_ones = ones;
275
276 ioc_writeb(ioc_control | ones, IOC_CONTROL);
277}
278
279static void ioc_setsda(void *data, int state)
280{
281 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
282 u_int ones = force_ones;
283
284 if (state)
285 ones |= SDA;
286 else
287 ones &= ~SDA;
288
289 force_ones = ones;
290
291 ioc_writeb(ioc_control | ones, IOC_CONTROL);
292}
293
294static int ioc_getscl(void *data)
295{
296 return (ioc_readb(IOC_CONTROL) & SCL) != 0;
297}
298
299static int ioc_getsda(void *data)
300{
301 return (ioc_readb(IOC_CONTROL) & SDA) != 0;
302}
303
304static struct i2c_algo_bit_data ioc_data = {
305 .setsda = ioc_setsda,
306 .setscl = ioc_setscl,
307 .getsda = ioc_getsda,
308 .getscl = ioc_getscl,
309 .udelay = 80,
310 .mdelay = 80,
311 .timeout = 100
312};
313
314static int ioc_client_reg(struct i2c_client *client)
315{
316 if (client->driver->id == I2C_DRIVERID_PCF8583 &&
317 client->addr == 0x50) {
318 struct rtc_tm rtctm;
319 unsigned int year;
320 struct timespec tv;
321
322 rtc_client = client;
323 get_rtc_time(&rtctm, &year);
324
325 tv.tv_nsec = rtctm.cs * 10000000;
326 tv.tv_sec = mktime(year, rtctm.mon, rtctm.mday,
327 rtctm.hours, rtctm.mins, rtctm.secs);
328 do_settimeofday(&tv);
329 set_rtc = k_set_rtc_time;
330 }
331
332 return 0;
333}
334
335static int ioc_client_unreg(struct i2c_client *client)
336{
337 if (client == rtc_client) {
338 set_rtc = NULL;
339 rtc_client = NULL;
340 }
341
342 return 0;
343}
344
345static struct i2c_adapter ioc_ops = {
346 .id = I2C_HW_B_IOC,
347 .algo_data = &ioc_data,
348 .client_register = ioc_client_reg,
349 .client_unregister = ioc_client_unreg,
350};
351
352static int __init i2c_ioc_init(void)
353{
354 int ret;
355
356 force_ones = FORCE_ONES | SCL | SDA;
357
358 ret = i2c_bit_add_bus(&ioc_ops);
359
360 if (ret >= 0){
361 ret = misc_register(&rtc_dev);
362 if(ret < 0)
363 i2c_bit_del_bus(&ioc_ops);
364 }
365
366 return ret;
367}
368
369__initcall(i2c_ioc_init);
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
new file mode 100644
index 00000000000..ad7ae7ab892
--- /dev/null
+++ b/drivers/acorn/char/pcf8583.c
@@ -0,0 +1,239 @@
1/*
2 * linux/drivers/acorn/char/pcf8583.c
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Driver for PCF8583 RTC & RAM chip
11 */
12#include <linux/i2c.h>
13#include <linux/slab.h>
14#include <linux/string.h>
15#include <linux/mc146818rtc.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/bcd.h>
19
20#include "pcf8583.h"
21
22static struct i2c_driver pcf8583_driver;
23
24static unsigned short ignore[] = { I2C_CLIENT_END };
25static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
26
27static struct i2c_client_address_data addr_data = {
28 .normal_i2c = normal_addr,
29 .normal_i2c_range = ignore,
30 .probe = ignore,
31 .probe_range = ignore,
32 .ignore = ignore,
33 .ignore_range = ignore,
34 .force = ignore,
35};
36
37#define DAT(x) ((unsigned int)(x->dev.driver_data))
38
39static int
40pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
41{
42 struct i2c_client *c;
43 unsigned char buf[1], ad[1] = { 0 };
44 struct i2c_msg msgs[2] = {
45 { addr, 0, 1, ad },
46 { addr, I2C_M_RD, 1, buf }
47 };
48
49 c = kmalloc(sizeof(*c), GFP_KERNEL);
50 if (!c)
51 return -ENOMEM;
52
53 memset(c, 0, sizeof(*c));
54 c->addr = addr;
55 c->adapter = adap;
56 c->driver = &pcf8583_driver;
57
58 if (i2c_transfer(c->adapter, msgs, 2) == 2)
59 DAT(c) = buf[0];
60
61 return i2c_attach_client(c);
62}
63
64static int
65pcf8583_probe(struct i2c_adapter *adap)
66{
67 return i2c_probe(adap, &addr_data, pcf8583_attach);
68}
69
70static int
71pcf8583_detach(struct i2c_client *client)
72{
73 i2c_detach_client(client);
74 kfree(client);
75 return 0;
76}
77
78static int
79pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
80{
81 unsigned char buf[8], addr[1] = { 1 };
82 struct i2c_msg msgs[2] = {
83 { client->addr, 0, 1, addr },
84 { client->addr, I2C_M_RD, 6, buf }
85 };
86 int ret = -EIO;
87
88 memset(buf, 0, sizeof(buf));
89
90 ret = i2c_transfer(client->adapter, msgs, 2);
91 if (ret == 2) {
92 dt->year_off = buf[4] >> 6;
93 dt->wday = buf[5] >> 5;
94
95 buf[4] &= 0x3f;
96 buf[5] &= 0x1f;
97
98 dt->cs = BCD_TO_BIN(buf[0]);
99 dt->secs = BCD_TO_BIN(buf[1]);
100 dt->mins = BCD_TO_BIN(buf[2]);
101 dt->hours = BCD_TO_BIN(buf[3]);
102 dt->mday = BCD_TO_BIN(buf[4]);
103 dt->mon = BCD_TO_BIN(buf[5]);
104
105 ret = 0;
106 }
107
108 return ret;
109}
110
111static int
112pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
113{
114 unsigned char buf[8];
115 int ret, len = 6;
116
117 buf[0] = 0;
118 buf[1] = DAT(client) | 0x80;
119 buf[2] = BIN_TO_BCD(dt->cs);
120 buf[3] = BIN_TO_BCD(dt->secs);
121 buf[4] = BIN_TO_BCD(dt->mins);
122 buf[5] = BIN_TO_BCD(dt->hours);
123
124 if (datetoo) {
125 len = 8;
126 buf[6] = BIN_TO_BCD(dt->mday) | (dt->year_off << 6);
127 buf[7] = BIN_TO_BCD(dt->mon) | (dt->wday << 5);
128 }
129
130 ret = i2c_master_send(client, (char *)buf, len);
131 if (ret == len)
132 ret = 0;
133
134 buf[1] = DAT(client);
135 i2c_master_send(client, (char *)buf, 2);
136
137 return ret;
138}
139
140static int
141pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
142{
143 *ctrl = DAT(client);
144 return 0;
145}
146
147static int
148pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
149{
150 unsigned char buf[2];
151
152 buf[0] = 0;
153 buf[1] = *ctrl;
154 DAT(client) = *ctrl;
155
156 return i2c_master_send(client, (char *)buf, 2);
157}
158
159static int
160pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
161{
162 unsigned char addr[1];
163 struct i2c_msg msgs[2] = {
164 { client->addr, 0, 1, addr },
165 { client->addr, I2C_M_RD, 0, mem->data }
166 };
167
168 if (mem->loc < 8)
169 return -EINVAL;
170
171 addr[0] = mem->loc;
172 msgs[1].len = mem->nr;
173
174 return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
175}
176
177static int
178pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
179{
180 unsigned char addr[1];
181 struct i2c_msg msgs[2] = {
182 { client->addr, 0, 1, addr },
183 { client->addr, 0, 0, mem->data }
184 };
185
186 if (mem->loc < 8)
187 return -EINVAL;
188
189 addr[0] = mem->loc;
190 msgs[1].len = mem->nr;
191
192 return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
193}
194
195static int
196pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg)
197{
198 switch (cmd) {
199 case RTC_GETDATETIME:
200 return pcf8583_get_datetime(client, arg);
201
202 case RTC_SETTIME:
203 return pcf8583_set_datetime(client, arg, 0);
204
205 case RTC_SETDATETIME:
206 return pcf8583_set_datetime(client, arg, 1);
207
208 case RTC_GETCTRL:
209 return pcf8583_get_ctrl(client, arg);
210
211 case RTC_SETCTRL:
212 return pcf8583_set_ctrl(client, arg);
213
214 case MEM_READ:
215 return pcf8583_read_mem(client, arg);
216
217 case MEM_WRITE:
218 return pcf8583_write_mem(client, arg);
219
220 default:
221 return -EINVAL;
222 }
223}
224
225static struct i2c_driver pcf8583_driver = {
226 .name = "PCF8583",
227 .id = I2C_DRIVERID_PCF8583,
228 .flags = I2C_DF_NOTIFY,
229 .attach_adapter = pcf8583_probe,
230 .detach_client = pcf8583_detach,
231 .command = pcf8583_command
232};
233
234static __init int pcf8583_init(void)
235{
236 return i2c_add_driver(&pcf8583_driver);
237}
238
239__initcall(pcf8583_init);
diff --git a/drivers/acorn/char/pcf8583.h b/drivers/acorn/char/pcf8583.h
new file mode 100644
index 00000000000..847f7fdb876
--- /dev/null
+++ b/drivers/acorn/char/pcf8583.h
@@ -0,0 +1,41 @@
1/*
2 * linux/drivers/acorn/char/pcf8583.h
3 *
4 * Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10struct rtc_tm {
11 unsigned char cs;
12 unsigned char secs;
13 unsigned char mins;
14 unsigned char hours;
15 unsigned char mday;
16 unsigned char mon;
17 unsigned char year_off;
18 unsigned char wday;
19};
20
21struct mem {
22 unsigned int loc;
23 unsigned int nr;
24 unsigned char *data;
25};
26
27#define RTC_GETDATETIME 0
28#define RTC_SETTIME 1
29#define RTC_SETDATETIME 2
30#define RTC_GETCTRL 3
31#define RTC_SETCTRL 4
32#define MEM_READ 5
33#define MEM_WRITE 6
34
35#define CTRL_STOP 0x80
36#define CTRL_HOLD 0x40
37#define CTRL_32KHZ 0x00
38#define CTRL_MASK 0x08
39#define CTRL_ALARMEN 0x04
40#define CTRL_ALARM 0x02
41#define CTRL_TIMER 0x01