OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [amikeyb.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/arch/m68k/amiga/amikeyb.c
3
 *
4
 * Amiga Keyboard driver for Linux/m68k
5
 *
6
 * This file is subject to the terms and conditions of the GNU General Public
7
 * License.  See the file COPYING in the main directory of this archive
8
 * for more details.
9
 */
10
 
11
/*
12
 * Amiga support by Hamish Macdonald
13
 */
14
 
15
#include <linux/config.h>
16
#include <linux/types.h>
17
#include <linux/sched.h>
18
#include <linux/interrupt.h>
19
#include <linux/errno.h>
20
#include <linux/keyboard.h>
21
#include <linux/kd.h>
22
#include <linux/kbd_ll.h>
23
#include <linux/delay.h>
24
#include <linux/timer.h>
25
#include <linux/random.h>
26
#include <linux/kernel.h>
27
#include <linux/ioport.h>
28
#include <linux/init.h>
29
#include <linux/kbd_kern.h>
30
 
31
#include <asm/amigaints.h>
32
#include <asm/amigahw.h>
33
#include <asm/irq.h>
34
 
35
#define AMIKEY_CAPS     (0x62)
36
#define BREAK_MASK      (0x80)
37
#define RESET_WARNING   (0xf0)  /* before rotation */
38
 
39
static u_short amiplain_map[NR_KEYS] __initdata = {
40
        0xf060, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
41
        0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf05c, 0xf200, 0xf300,
42
        0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
43
        0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf200, 0xf301, 0xf302, 0xf303,
44
        0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b,
45
        0xfb6c, 0xf03b, 0xf027, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
46
        0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d,
47
        0xf02c, 0xf02e, 0xf02f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
48
        0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200,
49
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
50
        0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
51
        0xf108, 0xf109, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf30a, 0xf11b,
52
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
53
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
54
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
55
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
56
};
57
 
58
static u_short amishift_map[NR_KEYS] __initdata = {
59
        0xf07e, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026,
60
        0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07c, 0xf200, 0xf300,
61
        0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
62
        0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf200, 0xf301, 0xf302, 0xf303,
63
        0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b,
64
        0xfb4c, 0xf03a, 0xf022, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
65
        0xf200, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d,
66
        0xf03c, 0xf03e, 0xf03f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
67
        0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200,
68
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
69
        0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, 0xf111,
70
        0xf112, 0xf113, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf203,
71
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
72
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
73
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
74
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
75
};
76
 
77
static u_short amialtgr_map[NR_KEYS] __initdata = {
78
        0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b,
79
        0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, 0xf300,
80
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
81
        0xf200, 0xf200, 0xf200, 0xf07e, 0xf200, 0xf301, 0xf302, 0xf303,
82
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
83
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
84
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
85
        0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
86
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
87
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
88
        0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, 0xf511, 0xf512, 0xf513,
89
        0xf514, 0xf515, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf204,
90
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
91
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
92
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
93
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
94
};
95
 
96
static u_short amictrl_map[NR_KEYS] __initdata = {
97
        0xf000, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
98
        0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf01c, 0xf200, 0xf300,
99
        0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
100
        0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf200, 0xf301, 0xf302, 0xf303,
101
        0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b,
102
        0xf00c, 0xf200, 0xf007, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
103
        0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d,
104
        0xf200, 0xf200, 0xf07f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
105
        0xf000, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
106
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
107
        0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
108
        0xf108, 0xf109, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf202,
109
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
110
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
111
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
112
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
113
};
114
 
115
static u_short amishift_ctrl_map[NR_KEYS] __initdata = {
116
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
117
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300,
118
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
119
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303,
120
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
121
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
122
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
123
        0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
124
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
125
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
126
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
127
        0xf200, 0xf200, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf200,
128
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
129
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
130
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
131
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
132
};
133
 
134
static u_short amialt_map[NR_KEYS] __initdata = {
135
        0xf860, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, 0xf837,
136
        0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf85c, 0xf200, 0xf900,
137
        0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
138
        0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf200, 0xf901, 0xf902, 0xf903,
139
        0xf861, 0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b,
140
        0xf86c, 0xf83b, 0xf827, 0xf200, 0xf200, 0xf904, 0xf905, 0xf906,
141
        0xf200, 0xf87a, 0xf878, 0xf863, 0xf876, 0xf862, 0xf86e, 0xf86d,
142
        0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf310, 0xf907, 0xf908, 0xf909,
143
        0xf820, 0xf87f, 0xf809, 0xf30e, 0xf80d, 0xf81b, 0xf87f, 0xf200,
144
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
145
        0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507,
146
        0xf508, 0xf509, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf204,
147
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
148
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
149
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
150
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
151
};
152
 
153
static u_short amictrl_alt_map[NR_KEYS] __initdata = {
154
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
155
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300,
156
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
157
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303,
158
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
159
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
160
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
161
        0xf200, 0xf200, 0xf200, 0xf200, 0xf20c, 0xf307, 0xf308, 0xf309,
162
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
163
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
164
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
165
        0xf200, 0xf200, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf200,
166
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
167
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
168
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
169
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
170
};
171
 
172
#define DEFAULT_KEYB_REP_DELAY  (HZ/4)
173
#define DEFAULT_KEYB_REP_RATE   (HZ/25)
174
 
175
/* These could be settable by some ioctl() in future... */
176
static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
177
static unsigned int key_repeat_rate  = DEFAULT_KEYB_REP_RATE;
178
 
179
static unsigned char rep_scancode;
180
static void amikeyb_rep(unsigned long ignore);
181
static struct timer_list amikeyb_rep_timer = {function: amikeyb_rep};
182
 
183
static void amikeyb_rep(unsigned long ignore)
184
{
185
    unsigned long flags;
186
    save_flags(flags);
187
    cli();
188
 
189
    kbd_pt_regs = NULL;
190
 
191
    amikeyb_rep_timer.expires = jiffies + key_repeat_rate;
192
    add_timer(&amikeyb_rep_timer);
193
    handle_scancode(rep_scancode, 1);
194
 
195
    restore_flags(flags);
196
}
197
 
198
static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
199
{
200
    unsigned char scancode, break_flag, keycode;
201
    static int reset_warning = 0;
202
 
203
    /* save frame for register dump */
204
    kbd_pt_regs = fp;
205
 
206
    /* get and invert scancode (keyboard is active low) */
207
    scancode = ~ciaa.sdr;
208
 
209
    /* switch SP pin to output for handshake */
210
    ciaa.cra |= 0x40;
211
 
212
#if 0 /* No longer used */
213
    /*
214
     *  On receipt of the second RESET_WARNING, we must not pull KDAT high
215
     *  again to delay the hard reset as long as possible.
216
     *
217
     *  Note that not all keyboards send reset warnings...
218
     */
219
    if (reset_warning)
220
        if (scancode == RESET_WARNING) {
221
            printk(KERN_ALERT "amikeyb: Ctrl-Amiga-Amiga reset warning!!\n"
222
                   "The system will be reset within 10 seconds!!\n");
223
            /* Panic doesn't sync from within an interrupt, so we do nothing */
224
            return;
225
        } else
226
            /* Probably a mistake, cancel the alert */
227
            reset_warning = 0;
228
#endif
229
 
230
    /* wait until 85 us have expired */
231
    udelay(85);
232
    /* switch CIA serial port to input mode */
233
    ciaa.cra &= ~0x40;
234
 
235
    tasklet_schedule(&keyboard_tasklet);
236
 
237
    /* rotate scan code to get up/down bit in proper position */
238
    scancode = ((scancode >> 1) & 0x7f) | ((scancode << 7) & 0x80);
239
 
240
    /*
241
     * Check make/break first
242
     */
243
    break_flag = scancode & BREAK_MASK;
244
    keycode = scancode & (unsigned char)~BREAK_MASK;
245
 
246
    if (keycode == AMIKEY_CAPS) {
247
        /* if the key is CAPS, fake a press/release. */
248
        handle_scancode(AMIKEY_CAPS, 1);
249
        handle_scancode(AMIKEY_CAPS, 0);
250
    } else if (keycode < 0x78) {
251
        /* handle repeat */
252
        if (break_flag) {
253
            del_timer(&amikeyb_rep_timer);
254
            rep_scancode = 0;
255
        } else {
256
            del_timer(&amikeyb_rep_timer);
257
            rep_scancode = keycode;
258
            amikeyb_rep_timer.expires = jiffies + key_repeat_delay;
259
            add_timer(&amikeyb_rep_timer);
260
        }
261
        handle_scancode(keycode, !break_flag);
262
    } else
263
        switch (keycode) {
264
            case 0x78:
265
                reset_warning = 1;
266
                break;
267
            case 0x79:
268
                printk(KERN_WARNING "amikeyb: keyboard lost sync\n");
269
                break;
270
            case 0x7a:
271
                printk(KERN_WARNING "amikeyb: keyboard buffer overflow\n");
272
                break;
273
#if 0 /* obsolete according to the HRM */
274
            case 0x7b:
275
                printk(KERN_WARNING "amikeyb: keyboard controller failure\n");
276
                break;
277
#endif
278
            case 0x7c:
279
                printk(KERN_ERR "amikeyb: keyboard selftest failure\n");
280
                break;
281
            case 0x7d:
282
                printk(KERN_INFO "amikeyb: initiate power-up key stream\n");
283
                break;
284
            case 0x7e:
285
                printk(KERN_INFO "amikeyb: terminate power-up key stream\n");
286
                break;
287
#if 0 /* obsolete according to the HRM */
288
            case 0x7f:
289
                printk(KERN_WARNING "amikeyb: keyboard interrupt\n");
290
                break;
291
#endif
292
            default:
293
                printk(KERN_WARNING "amikeyb: unknown keyboard communication code 0x%02x\n",
294
                       scancode);
295
                break;
296
        }
297
}
298
 
299
int __init amiga_keyb_init(void)
300
{
301
    if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
302
        return -EIO;
303
    if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
304
        return -EBUSY;
305
 
306
    /* setup key map */
307
    memcpy(key_maps[0], amiplain_map, sizeof(plain_map));
308
    memcpy(key_maps[1], amishift_map, sizeof(plain_map));
309
    memcpy(key_maps[2], amialtgr_map, sizeof(plain_map));
310
    memcpy(key_maps[4], amictrl_map, sizeof(plain_map));
311
    memcpy(key_maps[5], amishift_ctrl_map, sizeof(plain_map));
312
    memcpy(key_maps[8], amialt_map, sizeof(plain_map));
313
    memcpy(key_maps[12], amictrl_alt_map, sizeof(plain_map));
314
 
315
    /*
316
     * Initialize serial data direction.
317
     */
318
    ciaa.cra &= ~0x41;       /* serial data in, turn off TA */
319
 
320
    /*
321
     * arrange for processing of keyboard interrupt
322
     */
323
    request_irq(IRQ_AMIGA_CIAA_SP, keyboard_interrupt, 0, "keyboard", NULL);
324
 
325
    return 0;
326
}
327
 
328
int amiga_kbdrate( struct kbd_repeat *k )
329
{
330
    if (k->delay > 0) {
331
        /* convert from msec to jiffies */
332
        key_repeat_delay = (k->delay * HZ + 500) / 1000;
333
        if (key_repeat_delay < 1)
334
            key_repeat_delay = 1;
335
    }
336
    if (k->rate > 0) {
337
        key_repeat_rate = (k->rate * HZ + 500) / 1000;
338
        if (key_repeat_rate < 1)
339
            key_repeat_rate = 1;
340
    }
341
 
342
    k->delay = key_repeat_delay * 1000 / HZ;
343
    k->rate  = key_repeat_rate  * 1000 / HZ;
344
 
345
    return( 0 );
346
}
347
 
348
int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
349
{
350
#ifdef CONFIG_MAGIC_SYSRQ
351
        /* SHIFT+ALTGR+HELP pressed? */
352
        if ((keycode == 0x5f) && ((shift_state & 0xff) == 3))
353
                *keycodep = 0xff;
354
        else
355
#endif
356
                *keycodep = keycode;
357
        return 1;
358
}
359
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.