~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/input/keyboard.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************************
 
2
 *
 
3
 * (C) Copyright 2004
 
4
 * DENX Software Engineering
 
5
 * Wolfgang Denk, wd@denx.de
 
6
 *
 
7
 * Keyboard driver
 
8
 *
 
9
 ***********************************************************************/
 
10
 
 
11
#include <common.h>
 
12
 
 
13
#include <stdio_dev.h>
 
14
#include <keyboard.h>
 
15
 
 
16
#undef KBG_DEBUG
 
17
 
 
18
#ifdef KBG_DEBUG
 
19
#define PRINTF(fmt,args...)     printf (fmt ,##args)
 
20
#else
 
21
#define PRINTF(fmt,args...)
 
22
#endif
 
23
 
 
24
 
 
25
#define DEVNAME                 "kbd"
 
26
 
 
27
#define LED_SCR                 0x01    /* scroll lock led */
 
28
#define LED_CAP                 0x04    /* caps lock led */
 
29
#define LED_NUM                 0x02    /* num lock led */
 
30
 
 
31
#define KBD_BUFFER_LEN          0x20  /* size of the keyboardbuffer */
 
32
 
 
33
#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
 
34
int ps2ser_check(void);
 
35
#endif
 
36
 
 
37
static volatile char kbd_buffer[KBD_BUFFER_LEN];
 
38
static volatile int in_pointer = 0;
 
39
static volatile int out_pointer = 0;
 
40
 
 
41
static unsigned char leds = 0;
 
42
static unsigned char num_lock = 0;
 
43
static unsigned char caps_lock = 0;
 
44
static unsigned char scroll_lock = 0;
 
45
static unsigned char shift = 0;
 
46
static unsigned char ctrl = 0;
 
47
static unsigned char alt = 0;
 
48
static unsigned char e0 = 0;
 
49
 
 
50
/******************************************************************
 
51
 * Queue handling
 
52
 ******************************************************************/
 
53
 
 
54
/* puts character in the queue and sets up the in and out pointer */
 
55
static void kbd_put_queue(char data)
 
56
{
 
57
        if((in_pointer+1)==KBD_BUFFER_LEN) {
 
58
                if(out_pointer==0) {
 
59
                        return; /* buffer full */
 
60
                } else{
 
61
                        in_pointer=0;
 
62
                }
 
63
        } else {
 
64
                if((in_pointer+1)==out_pointer)
 
65
                        return; /* buffer full */
 
66
                in_pointer++;
 
67
        }
 
68
        kbd_buffer[in_pointer]=data;
 
69
        return;
 
70
}
 
71
 
 
72
/* test if a character is in the queue */
 
73
static int kbd_testc(void)
 
74
{
 
75
#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
 
76
        /* no ISR is used, so received chars must be polled */
 
77
        ps2ser_check();
 
78
#endif
 
79
        if(in_pointer==out_pointer)
 
80
                return(0); /* no data */
 
81
        else
 
82
                return(1);
 
83
}
 
84
 
 
85
/* gets the character from the queue */
 
86
static int kbd_getc(void)
 
87
{
 
88
        char c;
 
89
        while(in_pointer==out_pointer) {
 
90
#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
 
91
        /* no ISR is used, so received chars must be polled */
 
92
        ps2ser_check();
 
93
#endif
 
94
        ;}
 
95
        if((out_pointer+1)==KBD_BUFFER_LEN)
 
96
                out_pointer=0;
 
97
        else
 
98
                out_pointer++;
 
99
        c=kbd_buffer[out_pointer];
 
100
        return (int)c;
 
101
 
 
102
}
 
103
 
 
104
/* Simple translation table for the keys */
 
105
 
 
106
static unsigned char kbd_plain_xlate[] = {
 
107
        0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t',        /* 0x00 - 0x0f */
 
108
         'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's',        /* 0x10 - 0x1f */
 
109
         'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v',        /* 0x20 - 0x2f */
 
110
         'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
 
111
        0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
 
112
         '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
 
113
        '\r',0xff,0xff
 
114
        };
 
115
 
 
116
static unsigned char kbd_shift_xlate[] = {
 
117
        0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t',        /* 0x00 - 0x0f */
 
118
         'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S',        /* 0x10 - 0x1f */
 
119
         'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V',        /* 0x20 - 0x2f */
 
120
         'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
 
121
        0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
 
122
         '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
 
123
        '\r',0xff,0xff
 
124
        };
 
125
 
 
126
static unsigned char kbd_ctrl_xlate[] = {
 
127
        0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t',        /* 0x00 - 0x0f */
 
128
        0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13,        /* 0x10 - 0x1f */
 
129
        0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16,        /* 0x20 - 0x2f */
 
130
        0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
 
131
        0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
 
132
         '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
 
133
        '\r',0xff,0xff
 
134
        };
 
135
 
 
136
 
 
137
void handle_scancode(unsigned char scancode)
 
138
{
 
139
        unsigned char keycode;
 
140
 
 
141
        /*  Convert scancode to keycode */
 
142
        PRINTF("scancode %x\n",scancode);
 
143
        if(scancode==0xe0) {
 
144
                e0=1; /* special charakters */
 
145
                return;
 
146
        }
 
147
        if(e0==1) {
 
148
                e0=0; /* delete flag */
 
149
                if(!(   ((scancode&0x7F)==0x38)|| /* the right ctrl key */
 
150
                                        ((scancode&0x7F)==0x1D)|| /* the right alt key */
 
151
                                        ((scancode&0x7F)==0x35)||       /* the right '/' key */
 
152
                                        ((scancode&0x7F)==0x1C) ))  /* the right enter key */
 
153
                        /* we swallow unknown e0 codes */
 
154
                        return;
 
155
        }
 
156
        /* special cntrl keys */
 
157
        switch(scancode) {
 
158
        case 0x2A:
 
159
        case 0x36: /* shift pressed */
 
160
                shift=1;
 
161
                return; /* do nothing else */
 
162
        case 0xAA:
 
163
        case 0xB6: /* shift released */
 
164
                shift=0;
 
165
                return; /* do nothing else */
 
166
        case 0x38: /* alt pressed */
 
167
                alt=1;
 
168
                return; /* do nothing else */
 
169
        case 0xB8: /* alt released */
 
170
                alt=0;
 
171
                return; /* do nothing else */
 
172
        case 0x1d: /* ctrl pressed */
 
173
                ctrl=1;
 
174
                return; /* do nothing else */
 
175
        case 0x9d: /* ctrl released */
 
176
                ctrl=0;
 
177
                return; /* do nothing else */
 
178
        case 0x46: /* scrollock pressed */
 
179
                scroll_lock=~scroll_lock;
 
180
                if(scroll_lock==0)
 
181
                        leds&=~LED_SCR; /* switch LED off */
 
182
                else
 
183
                        leds|=LED_SCR; /* switch on LED */
 
184
                pckbd_leds(leds);
 
185
                return; /* do nothing else */
 
186
        case 0x3A: /* capslock pressed */
 
187
                caps_lock=~caps_lock;
 
188
                if(caps_lock==0)
 
189
                        leds&=~LED_CAP; /* switch caps_lock off */
 
190
                else
 
191
                        leds|=LED_CAP; /* switch on LED */
 
192
                pckbd_leds(leds);
 
193
                return;
 
194
        case 0x45: /* numlock pressed */
 
195
                num_lock=~num_lock;
 
196
                if(num_lock==0)
 
197
                        leds&=~LED_NUM; /* switch LED off */
 
198
                else
 
199
                        leds|=LED_NUM;  /* switch on LED */
 
200
                pckbd_leds(leds);
 
201
                return;
 
202
        case 0xC6: /* scroll lock released */
 
203
        case 0xC5: /* num lock released */
 
204
        case 0xBA: /* caps lock released */
 
205
                return; /* just swallow */
 
206
        }
 
207
#if 1
 
208
        if((scancode&0x80)==0x80) /* key released */
 
209
                return;
 
210
#else
 
211
        if((scancode&0x80)==0x00) /* key pressed */
 
212
                return;
 
213
        scancode &= ~0x80;
 
214
#endif
 
215
        /* now, decide which table we need */
 
216
        if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */
 
217
                PRINTF("unkown scancode %X\n",scancode);
 
218
                return; /* swallow it */
 
219
        }
 
220
        /* setup plain code first */
 
221
        keycode=kbd_plain_xlate[scancode];
 
222
        if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */
 
223
                if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
 
224
                        PRINTF("unkown caps-locked scancode %X\n",scancode);
 
225
                        return; /* swallow it */
 
226
                }
 
227
                keycode=kbd_shift_xlate[scancode];
 
228
                if(keycode<'A') { /* we only want the alphas capital */
 
229
                        keycode=kbd_plain_xlate[scancode];
 
230
                }
 
231
        }
 
232
        if(shift==1) { /* shift overwrites caps_lock */
 
233
                if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
 
234
                        PRINTF("unkown shifted scancode %X\n",scancode);
 
235
                        return; /* swallow it */
 
236
                }
 
237
                keycode=kbd_shift_xlate[scancode];
 
238
        }
 
239
        if(ctrl==1) { /* ctrl overwrites caps_lock and shift */
 
240
                if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */
 
241
                        PRINTF("unkown ctrl scancode %X\n",scancode);
 
242
                        return; /* swallow it */
 
243
                }
 
244
                keycode=kbd_ctrl_xlate[scancode];
 
245
        }
 
246
        /* check if valid keycode */
 
247
        if(keycode==0xff) {
 
248
                PRINTF("unkown scancode %X\n",scancode);
 
249
                return; /* swallow unknown codes */
 
250
        }
 
251
 
 
252
        kbd_put_queue(keycode);
 
253
        PRINTF("%x\n",keycode);
 
254
}
 
255
 
 
256
/******************************************************************
 
257
 * Init
 
258
 ******************************************************************/
 
259
 
 
260
#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
 
261
extern int overwrite_console (void);
 
262
#define OVERWRITE_CONSOLE overwrite_console ()
 
263
#else
 
264
#define OVERWRITE_CONSOLE 0
 
265
#endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
 
266
 
 
267
int kbd_init (void)
 
268
{
 
269
        int error;
 
270
        struct stdio_dev kbddev ;
 
271
        char *stdinname  = getenv ("stdin");
 
272
 
 
273
        if(kbd_init_hw()==-1)
 
274
                return -1;
 
275
        memset (&kbddev, 0, sizeof(kbddev));
 
276
        strcpy(kbddev.name, DEVNAME);
 
277
        kbddev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
 
278
        kbddev.putc = NULL ;
 
279
        kbddev.puts = NULL ;
 
280
        kbddev.getc = kbd_getc ;
 
281
        kbddev.tstc = kbd_testc ;
 
282
 
 
283
        error = stdio_register (&kbddev);
 
284
        if(error==0) {
 
285
                /* check if this is the standard input device */
 
286
                if(strcmp(stdinname,DEVNAME)==0) {
 
287
                        /* reassign the console */
 
288
                        if(OVERWRITE_CONSOLE) {
 
289
                                return 1;
 
290
                        }
 
291
                        error=console_assign(stdin,DEVNAME);
 
292
                        if(error==0)
 
293
                                return 1;
 
294
                        else
 
295
                                return error;
 
296
                }
 
297
                return 1;
 
298
        }
 
299
        return error;
 
300
}