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

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [libdev/] [kmi/] [pl050/] [kmi.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
 
2
/*
3
 * PL050 Primecell Keyboard, Mouse driver
4
 *
5
 * Copyright (C) 2010 Amit Mahajan
6
 */
7
 
8
#include <libdev/kmi.h>
9
#include "kmi.h"
10
#include "keymap.h"
11
 
12
/* Enable Rx irq */
13
void kmi_rx_irq_enable(unsigned long base)
14
{
15
        *(volatile unsigned long *)(base + PL050_KMICR) = KMI_RXINTR;
16
}
17
 
18
int kmi_data_read(unsigned long base)
19
{
20
        /* Check and return if data present */
21
        if (*(volatile unsigned long *)(base + PL050_KMISTAT) & KMI_RXFULL)
22
                return *(volatile unsigned long *)(base + PL050_KMIDATA);
23
        else
24
                return 0;
25
}
26
 
27
#if 0
28
char kmi_keyboard_read(int c, struct keyboard_state *state)
29
{
30
        int keycode, shkeycode;
31
        int keynum;
32
        int extflag;
33
        int modmask;
34
 
35
        /* Special codes */
36
        switch (c) {
37
        case 0xF0:
38
                /* release */
39
                state->modifiers |= MODIFIER_RELEASE;
40
                return 0;
41
        case 0xE0:
42
                /* extended */
43
                state->modifiers |= MODIFIER_EXTENDED;
44
                return 0;
45
        case 0xE1:
46
                /* extended for 2 characters - only used for Break in mode 2 */
47
                state->modifiers |= MODIFIER_EXTENDED;
48
                state->modifiers |= MODIFIER_EXTENDED2;
49
                return 0;
50
        }
51
 
52
                extflag = 1;
53
                modmask = 0xFFFFFFFF;
54
 
55
                /* Is this a scan code? */
56
                if (c > 0 && c <= 0x9F)
57
                {
58
                        keynum = scancode_mode2_extended[c];
59
 
60
                        /* ignore unrecognised codes */
61
                        if (!keynum)
62
                        {
63
                                state->modifiers &= ~MODIFIER_RELEASE;
64
                                return 0;
65
                        }
66
 
67
                        /* is this an extended code? */
68
                        if (state->modifiers & MODIFIER_EXTENDED)
69
                        {
70
                                keycode = keymap_uk2[keynum].ext_nomods;
71
                                extflag = 0;
72
                                state->modifiers &= ~MODIFIER_EXTENDED;
73
                                if (!keycode)
74
                                {
75
                                        state->modifiers &= ~MODIFIER_RELEASE;
76
                                        return 0;
77
                                }
78
                        }
79
                        else if (state->modifiers & MODIFIER_EXTENDED2)
80
                        {
81
                                keycode = keymap_uk2[keynum].ext_nomods;
82
                                extflag = 0;
83
                                state->modifiers &= ~MODIFIER_EXTENDED2;
84
                                if (!keycode)
85
                                {
86
                                        state->modifiers &= ~MODIFIER_RELEASE;
87
                                        return 0;
88
                                }
89
                        }
90
                        else
91
                        {
92
                                keycode = keymap_uk2[keynum].nomods;
93
                                if (!keycode)
94
                                {
95
                                        state->modifiers &= ~MODIFIER_RELEASE;
96
                                        return 0;
97
                                }
98
                        }
99
 
100
                        /* handle shift */
101
                        if (state->modifiers & MODIFIER_CAPSLK)
102
                        {
103
                                if (keycode >= 'a' && keycode <= 'z')
104
                                {
105
                                        if (!(state->modifiers & MODIFIER_SHIFT))
106
                                        {
107
                                                shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
108
                                                if (shkeycode)
109
                                                        keycode = shkeycode;
110
                                        }
111
                                }
112
                                else
113
                                {
114
                                        if (state->modifiers & MODIFIER_SHIFT)
115
                                        {
116
                                                shkeycode = !extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
117
                                                if (shkeycode)
118
                                                        keycode = shkeycode;
119
                                        }
120
                                }
121
                        }
122
                        else
123
                        {
124
                                if (state->modifiers & MODIFIER_SHIFT)
125
                                {
126
                                        shkeycode = extflag ? keymap_uk2[keynum].ext_shift : keymap_uk2[keynum].shift;
127
                                        if (shkeycode)
128
                                                keycode = shkeycode;
129
                                }
130
                        }
131
 
132
                        /* handle the numeric keypad */
133
                        if (keycode & MODIFIER_NUMLK)
134
                        {
135
                                keycode &= ~MODIFIER_NUMLK;
136
 
137
                                if (state->modifiers & MODIFIER_NUMLK)
138
                                {
139
                                        if (!(state->modifiers & MODIFIER_SHIFT))
140
                                        {
141
                                                switch (keycode)
142
                                                {
143
                                                        case KEYCODE_HOME:
144
                                                                keycode = '7';
145
                                                                break;
146
                                                        case KEYCODE_UP:
147
                                                                keycode = '8';
148
                                                                break;
149
                                                        case KEYCODE_PAGEUP:
150
                                                                keycode = '9';
151
                                                                break;
152
                                                        case KEYCODE_LEFT:
153
                                                                keycode = '4';
154
                                                                break;
155
                                                        case KEYCODE_CENTER:
156
                                                                keycode = '5';
157
                                                                break;
158
                                                        case KEYCODE_RIGHT:
159
                                                                keycode = '6';
160
                                                                break;
161
                                                        case KEYCODE_END:
162
                                                                keycode = '1';
163
                                                                break;
164
                                                        case KEYCODE_DOWN:
165
                                                                keycode = '2';
166
                                                                break;
167
                                                        case KEYCODE_PAGEDN:
168
                                                                keycode = '3';
169
                                                                break;
170
                                                        case KEYCODE_INSERT:
171
                                                                keycode = '0';
172
                                                                break;
173
                                                        case KEYCODE_DELETE:
174
                                                                keycode = '.';
175
                                                                break;
176
                                                }
177
                                        }
178
                                        else
179
                                                modmask = ~MODIFIER_SHIFT;
180
                                }
181
                        }
182
 
183
                        /* modifier keys */
184
                        switch (keycode)
185
                        {
186
                                case KEYCODE_LSHIFT:
187
                                        if (state->modifiers & MODIFIER_RELEASE)
188
                                                state->modifiers &= ~(MODIFIER_LSHIFT | MODIFIER_RELEASE);
189
                                        else
190
                                                state->modifiers |= MODIFIER_LSHIFT;
191
                                        return 0;
192
 
193
                                case KEYCODE_RSHIFT:
194
                                        if (state->modifiers & MODIFIER_RELEASE)
195
                                                state->modifiers &= ~(MODIFIER_RSHIFT | MODIFIER_RELEASE);
196
                                        else
197
                                                state->modifiers |= MODIFIER_RSHIFT;
198
                                        return 0;
199
 
200
                                case KEYCODE_LCTRL:
201
                                        if (state->modifiers & MODIFIER_RELEASE)
202
                                                state->modifiers &= ~(MODIFIER_LCTRL | MODIFIER_RELEASE);
203
                                        else
204
                                                state->modifiers |= MODIFIER_LCTRL;
205
                                        return 0;
206
 
207
                                case KEYCODE_RCTRL:
208
                                        if (state->modifiers & MODIFIER_RELEASE)
209
                                                state->modifiers &= ~(MODIFIER_RCTRL | MODIFIER_RELEASE);
210
                                        else
211
                                                state->modifiers |= MODIFIER_RCTRL;
212
                                        return 0;
213
 
214
                                case KEYCODE_ALT:
215
                                        if (state->modifiers & MODIFIER_RELEASE)
216
                                                state->modifiers &= ~(MODIFIER_ALT | MODIFIER_RELEASE);
217
                                        else
218
                                                state->modifiers |= MODIFIER_ALT;
219
                                        return 0;
220
 
221
                                case KEYCODE_ALTGR:
222
                                        if (state->modifiers & MODIFIER_RELEASE)
223
                                                state->modifiers &= ~(MODIFIER_ALTGR | MODIFIER_RELEASE);
224
                                        else
225
                                                state->modifiers |= MODIFIER_ALTGR;
226
                                        return 0;
227
 
228
                                case KEYCODE_CAPSLK:
229
                                        if (state->modifiers & MODIFIER_RELEASE)
230
                                                state->modifiers &= ~MODIFIER_RELEASE;
231
                                        else
232
                                        {
233
                                                state->modifiers ^= MODIFIER_CAPSLK;
234
                                                //__keyb_update_locks (state);
235
                                        }
236
                                        return 0;
237
 
238
                                case KEYCODE_SCRLK:
239
                                        if (state->modifiers & MODIFIER_RELEASE)
240
                                                state->modifiers &= ~MODIFIER_RELEASE;
241
                                        else
242
                                        {
243
                                                state->modifiers ^= MODIFIER_SCRLK;
244
                                                //__keyb_update_locks (state);
245
                                        }
246
                                        return 0;
247
 
248
                                case KEYCODE_NUMLK:
249
                                        if (state->modifiers & MODIFIER_RELEASE)
250
                                                state->modifiers &= ~MODIFIER_RELEASE;
251
                                        else
252
                                        {
253
                                                state->modifiers ^= MODIFIER_NUMLK;
254
                                                //__keyb_update_locks (state);
255
                                        }
256
                                        return 0;
257
                        }
258
 
259
                        if (state->modifiers & MODIFIER_RELEASE)
260
                        {
261
                                /* clear release condition */
262
                                state->modifiers &= ~MODIFIER_RELEASE;
263
                        }
264
                        else
265
                        {
266
                                /* write code into the buffer */
267
                                return keycode;
268
                        }
269
                        return 0;
270
                }
271
 
272
        return 0;
273
}
274
#endif
275
 
276
/*
277
 * Simple logic to interpret keyboard keys and shift keys
278
 * TODO: Add support for all the modifier keys
279
 *
280
 * Keyevents work in 3 phase manner, if you press 'A':
281
 * 1. scan code for 'A' is generated
282
 * 2. Key release event i.e KYBD_DATA_KEYUP
283
 * 3. scan code for 'A' again is generated
284
 */
285
char kmi_keyboard_read(unsigned long base, struct keyboard_state *state)
286
{
287
        int keynum, keycode = 0;
288
 
289
        /* Read Keyboard RX buffer */
290
        unsigned char data = kmi_data_read(base);
291
 
292
        /* if a key up occurred (key released) occured */
293
        if (data == KYBD_DATA_KEYUP) {
294
                state->keyup = 1;
295
                return 0;
296
        }
297
        else if (state->keyup){
298
                state->keyup = 0;
299
 
300
                /* Check if shift was lifted */
301
                if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
302
                        state->shift = 0;
303
                }
304
                else {
305
                        /*      Find key number */
306
                        keynum = scancode_mode2_extended[data];
307
                        if(state->shift)
308
                                keycode = keymap_uk2[keynum].shift;
309
                        else
310
                                keycode = keymap_uk2[keynum].nomods;
311
 
312
                }
313
 
314
        }
315
        else if ((data == KYBD_DATA_SHIFTL) || (data == KYBD_DATA_SHIFTR)) {
316
                state->shift = 1;
317
        }
318
 
319
        return (unsigned char)keycode;
320
}
321
 
322
void kmi_keyboard_init(unsigned long base, unsigned int div)
323
{
324
        /* STOP KMI */
325
        *(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
326
 
327
        /*
328
         * For versatile, KMI refernce clock = 24MHz
329
         * KMI manual says we need 8MHz clock,
330
         * so divide by 3
331
         */
332
        *(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
333
 
334
        /* Enable KMI and TX/RX interrupts */
335
        *(volatile unsigned long *)(base + PL050_KMICR) =
336
                                                KMI_RXINTR | KMI_EN;
337
 
338
        /* Reset and wait for reset to complete */
339
        *(volatile unsigned long *)(base + PL050_KMIDATA) =
340
                                                KYBD_DATA_RESET;
341
        while(kmi_data_read(base) != KYBD_DATA_RTR);
342
}
343
 
344
void kmi_mouse_enable(unsigned long base)
345
{
346
        unsigned long *datareg = (unsigned long *)(base + PL050_KMIDATA);
347
 
348
        *datareg = MOUSE_DATA_ENABLE;
349
 
350
        /*sleep for sometime here */
351
 
352
        while (*datareg != MOUSE_DATA_ACK);
353
}
354
 
355
void kmi_mouse_init(unsigned long base, unsigned int div)
356
{
357
        int data[2];
358
 
359
        /* STOP KMI */
360
        *(volatile unsigned long *)(base + PL050_KMICR) = 0x0;
361
 
362
        /*
363
         * For versatile, KMI refernce clock = 24MHz
364
         * KMI manual says we need 8MHz clock,
365
         * so divide by 3
366
         */
367
        *(volatile unsigned long *)(base + PL050_KMICLKDIV) = div;
368
 
369
        /* Enable KMI and TX/RX interrupts */
370
        *(volatile unsigned long *)(base + PL050_KMICR) =
371
                                                KMI_RXINTR | KMI_EN;
372
 
373
        /* Reset and wait for reset to complete */
374
        *(volatile unsigned long *)(base + PL050_KMIDATA) =
375
                                                MOUSE_DATA_RESET;
376
 
377
        do {
378
                data[0] = kmi_data_read(base);
379
                /* Some sleep here */
380
                data[1] = kmi_data_read(base);
381
        }while((data[0] != MOUSE_DATA_ACK) && (data[1] != MOUSE_DATA_RTR));
382
 
383
        /* Set enable data code to mouse */
384
        kmi_mouse_enable(base);
385
}
386
 

powered by: WebSVN 2.1.0

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