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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [amiga/] [amikeyb.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 * linux/amiga/amikeyb.c
3
 *
4
 * Amiga Keyboard driver for 680x0 Linux
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/types.h>
16
#include <linux/sched.h>
17
#include <linux/interrupt.h>
18
#include <linux/errno.h>
19
#include <linux/keyboard.h>
20
#include <linux/delay.h>
21
#include <linux/timer.h>
22
#include <linux/kd.h>
23
#include <linux/random.h>
24
 
25
#include <asm/bootinfo.h>
26
#include <asm/amigatypes.h>
27
#include <asm/amigaints.h>
28
#include <asm/amigahw.h>
29
#include <asm/irq.h>
30
 
31
extern int do_poke_blanked_console;
32
extern void process_keycode (int);
33
 
34
#define AMIKEY_CAPS     (0x62)
35
#define BREAK_MASK      (0x80)
36
 
37
static u_short amiplain_map[NR_KEYS] = {
38
        0xf060, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
39
        0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf05c, 0xf200, 0xf300,
40
        0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
41
        0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf200, 0xf301, 0xf302, 0xf303,
42
        0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b,
43
        0xfb6c, 0xf03b, 0xf027, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
44
        0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d,
45
        0xf02c, 0xf02e, 0xf02f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
46
        0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200,
47
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
48
        0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
49
        0xf108, 0xf109, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf10a,
50
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
51
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
52
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
53
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
54
};
55
 
56
static u_short amishift_map[NR_KEYS] = {
57
        0xf07e, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026,
58
        0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07c, 0xf200, 0xf300,
59
        0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
60
        0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf200, 0xf301, 0xf302, 0xf303,
61
        0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b,
62
        0xfb4c, 0xf03a, 0xf022, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
63
        0xf200, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d,
64
        0xf03c, 0xf03e, 0xf03f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
65
        0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200,
66
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
67
        0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, 0xf111,
68
        0xf112, 0xf113, 0xf208, 0xf203, 0xf30d, 0xf30c, 0xf30a, 0xf10a,
69
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
70
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
71
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
72
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
73
};
74
 
75
static u_short amialtgr_map[NR_KEYS] = {
76
        0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b,
77
        0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, 0xf300,
78
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
79
        0xf200, 0xf200, 0xf200, 0xf07e, 0xf200, 0xf301, 0xf302, 0xf303,
80
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
81
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
82
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
83
        0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
84
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
85
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
86
        0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, 0xf511, 0xf512, 0xf513,
87
        0xf514, 0xf515, 0xf208, 0xf202, 0xf30d, 0xf30c, 0xf30a, 0xf516,
88
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
89
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
90
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
91
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
92
};
93
 
94
static u_short amictrl_map[NR_KEYS] = {
95
        0xf000, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
96
        0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf01c, 0xf200, 0xf300,
97
        0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
98
        0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf200, 0xf301, 0xf302, 0xf303,
99
        0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b,
100
        0xf00c, 0xf200, 0xf007, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
101
        0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d,
102
        0xf200, 0xf200, 0xf07f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
103
        0xf000, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
104
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
105
        0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
106
        0xf108, 0xf109, 0xf208, 0xf204, 0xf30d, 0xf30c, 0xf30a, 0xf10a,
107
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
108
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
109
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
110
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
111
};
112
 
113
static u_short amishift_ctrl_map[NR_KEYS] = {
114
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
115
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300,
116
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
117
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303,
118
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
119
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
120
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
121
        0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309,
122
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
123
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
124
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
125
        0xf200, 0xf200, 0xf208, 0xf200, 0xf30d, 0xf30c, 0xf30a, 0xf200,
126
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
127
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
128
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
129
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
130
};
131
 
132
static u_short amialt_map[NR_KEYS] = {
133
        0xf860, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, 0xf837,
134
        0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf85c, 0xf200, 0xf900,
135
        0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
136
        0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf200, 0xf901, 0xf902, 0xf903,
137
        0xf861, 0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b,
138
        0xf86c, 0xf83b, 0xf827, 0xf200, 0xf200, 0xf904, 0xf905, 0xf906,
139
        0xf200, 0xf87a, 0xf878, 0xf863, 0xf876, 0xf862, 0xf86e, 0xf86d,
140
        0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf310, 0xf907, 0xf908, 0xf909,
141
        0xf820, 0xf87f, 0xf809, 0xf30e, 0xf80d, 0xf81b, 0xf87f, 0xf200,
142
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
143
        0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507,
144
        0xf508, 0xf509, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf50a,
145
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
146
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
147
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
148
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
149
};
150
 
151
static u_short amictrl_alt_map[NR_KEYS] = {
152
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
153
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300,
154
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
155
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303,
156
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
157
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306,
158
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
159
        0xf200, 0xf200, 0xf200, 0xf200, 0xf20c, 0xf307, 0xf308, 0xf309,
160
        0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200,
161
        0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601,
162
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
163
        0xf200, 0xf200, 0xf208, 0xf200, 0xf30d, 0xf30c, 0xf30a, 0xf200,
164
        0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200,
165
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
166
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
167
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
168
};
169
 
170
#define DEFAULT_KEYB_REP_DELAY  (HZ/4)
171
#define DEFAULT_KEYB_REP_RATE   (HZ/25)
172
 
173
/* These could be settable by some ioctl() in future... */
174
static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
175
static unsigned int key_repeat_rate  = DEFAULT_KEYB_REP_RATE;
176
 
177
static unsigned char rep_scancode;
178
static void amikeyb_rep (unsigned long ignore);
179
static struct timer_list amikeyb_rep_timer = {NULL, NULL, 0, 0, amikeyb_rep};
180
 
181
extern struct pt_regs *pt_regs;
182
 
183
static void amikeyb_rep (unsigned long ignore)
184
{
185
        unsigned long flags;
186
        save_flags(flags);
187
        cli();
188
 
189
        pt_regs = NULL;
190
 
191
        amikeyb_rep_timer.expires = jiffies + key_repeat_rate;
192
        amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
193
        add_timer(&amikeyb_rep_timer);
194
        process_keycode (rep_scancode);
195
 
196
        restore_flags(flags);
197
}
198
 
199
static void keyboard_interrupt (int irq, struct pt_regs *fp, void *dummy)
200
{
201
    unsigned char scancode, break_flag;
202
 
203
    /* save frame for register dump */
204
    pt_regs = (struct 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
    /* wait until 85 us have expired */
212
    udelay(85);
213
    /* switch CIA serial port to input mode */
214
    ciaa.cra &= ~0x40;
215
 
216
    /* rotate scan code to get up/down bit in proper position */
217
    __asm__ __volatile__ ("rorb #1,%0" : "=g" (scancode) : "0" (scancode));
218
 
219
    /*
220
     * do machine independent keyboard processing of "normalized" scancode
221
     * A "normalized" scancode is one that an IBM PC might generate
222
     * Check make/break first
223
     */
224
    break_flag = scancode & BREAK_MASK;
225
    scancode &= (unsigned char )~BREAK_MASK;
226
 
227
    if (scancode == AMIKEY_CAPS) {
228
            /* if the key is CAPS, fake a press/release. */
229
            process_keycode (AMIKEY_CAPS);
230
            process_keycode (BREAK_MASK | AMIKEY_CAPS);
231
    } else {
232
            /* handle repeat */
233
            if (break_flag) {
234
                    del_timer(&amikeyb_rep_timer);
235
                    rep_scancode = 0;
236
            } else {
237
                    del_timer(&amikeyb_rep_timer);
238
                    rep_scancode = break_flag | scancode;
239
                    amikeyb_rep_timer.expires = jiffies + key_repeat_delay;
240
                    amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
241
                    add_timer(&amikeyb_rep_timer);
242
            }
243
            process_keycode (break_flag | scancode);
244
    }
245
 
246
    do_poke_blanked_console = 1;
247
    mark_bh(CONSOLE_BH);
248
    add_keyboard_randomness(scancode);
249
 
250
    return;
251
}
252
 
253
int amiga_keyb_init (void)
254
{
255
    if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
256
        return -EIO;
257
 
258
    /* setup key map */
259
    key_maps[0]  = amiplain_map;
260
    key_maps[1]  = amishift_map;
261
    key_maps[2]  = amialtgr_map;
262
    key_maps[4]  = amictrl_map;
263
    key_maps[5]  = amishift_ctrl_map;
264
    key_maps[8]  = amialt_map;
265
    key_maps[12] = amictrl_alt_map;
266
    memcpy (plain_map, amiplain_map, sizeof(plain_map));
267
 
268
    /*
269
     * Initialize serial data direction.
270
     */
271
    ciaa.cra &= ~0x41;       /* serial data in, turn off TA */
272
 
273
    /*
274
     * arrange for processing of keyboard interrupt
275
     */
276
    add_isr (IRQ_AMIGA_CIAA_SP, keyboard_interrupt, 0, NULL, "keyboard");
277
 
278
    return 0;
279
}
280
 
281
int amiga_kbdrate( struct kbd_repeat *k )
282
 
283
{
284
        if (k->delay > 0) {
285
                /* convert from msec to jiffies */
286
                key_repeat_delay = (k->delay * HZ + 500) / 1000;
287
                if (key_repeat_delay < 1)
288
                        key_repeat_delay = 1;
289
        }
290
        if (k->rate > 0) {
291
                key_repeat_rate = (k->rate * HZ + 500) / 1000;
292
                if (key_repeat_rate < 1)
293
                        key_repeat_rate = 1;
294
        }
295
 
296
        k->delay = key_repeat_delay * 1000 / HZ;
297
        k->rate  = key_repeat_rate  * 1000 / HZ;
298
 
299
        return( 0 );
300
}

powered by: WebSVN 2.1.0

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