Root/PS2_INTERFACE/drivers/ps2_kb.c

1
2#include <linux/types.h>
3#include <linux/init.h>
4#include <linux/input.h>
5#include <linux/irq.h>
6#include <linux/interrupt.h>
7#include <linux/module.h>
8#include <linux/gpio.h>
9#include <asm/mach-jz4740/gpio.h>
10
11#define FPGA_IRQ_PIN JZ_GPIO_PORTC(15)
12#define FPGA_CS JZ_GPIO_PORTB(26)
13#define FPGA_BASE_BEGIN 0x15000000
14#define FPGA_BASE_END 0x17FFFFFF
15
16static unsigned int key_p;
17static unsigned int key_e;
18
19/*
20 * Scancode to keycode tables. These are just the default setting, and
21 * are loadable via a userland utility.
22 */
23
24#define ATKBD_KEYMAP_SIZE 512
25
26static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
27
28#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
29//stream mode
30    iowrite32(0x000000EA,ioaddress);
31    mb();
32/* XXX: need a more general approach */
33
34#include "hpps2atkbd.h" /* include the keyboard scancodes */
35
36#else
37          0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117,
38          0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0,
39          0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
40          0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
41          0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
42          0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
43          0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
44         82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
45
46          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47        217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
48        173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
49        159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142,
50        157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
51        226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
52          0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
53        110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
54
55          0, 0, 0, 65, 99,
56#endif
57};
58
59static struct input_dev *ps2kbd_dev;
60static void __iomem *ioaddress;
61
62static irqreturn_t ps2_keyboard_interrupt(int irq, void *id)
63{
64        unsigned char scancode, keycode;
65        
66        scancode = (unsigned char)(ioread32(ioaddress)& 0XFF);
67        rmb();
68        
69        //printk(KERN_INFO "scancode %x\n", scancode);
70        
71        if (scancode == 0xAA)printk(KERN_INFO "PS/2 keyboard. ok\n");
72    else if (scancode == 0xFC)printk(KERN_INFO "PS/2 keyboard. error\n");
73        else if (scancode == 0xF0)key_p=0;
74        else if (scancode == 0xE0)key_e=1;
75        else if (scancode <= 0x7E){ /* scancodes < 0xf2 are keys */
76
77                keycode = atkbd_set2_keycode[scancode+0x80*key_e];
78
79                input_report_key(ps2kbd_dev, keycode, key_p);
80                input_sync(ps2kbd_dev);
81                key_p=1;
82                key_e=0;
83        } else /* scancodes >= 0xf2 are mouse data, most likely */
84                printk(KERN_INFO "ps2kbd: unhandled scancode %x\n", scancode);
85    
86        return IRQ_HANDLED;
87}
88        
89static int __init ps2_keyboard_init(void)
90{
91        
92        int i, error, res, irq;
93        
94        key_p=1;
95        key_e=0;
96        
97        ps2kbd_dev = input_allocate_device();
98        if (!ps2kbd_dev)
99                return -ENOMEM;
100        
101        ps2kbd_dev->name = "PS2 Keyboard";
102        ps2kbd_dev->phys = "ps2kbd/input0";
103        ps2kbd_dev->id.bustype = BUS_HOST;
104        ps2kbd_dev->id.vendor = 0x0001;
105        ps2kbd_dev->id.product = 0x0001;
106        ps2kbd_dev->id.version = 0x0100;
107
108        ps2kbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
109        ps2kbd_dev->keycode = atkbd_set2_keycode;
110        ps2kbd_dev->keycodesize = sizeof(unsigned short);
111        ps2kbd_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
112
113        for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) {
114                set_bit(atkbd_set2_keycode[i], ps2kbd_dev->keybit);
115        }
116        
117        /* error check */
118        error = input_register_device(ps2kbd_dev);
119        if (error) {
120                input_free_device(ps2kbd_dev);
121                return error;
122        }
123        
124        /* Set up the FGPA irq line */
125        irq = gpio_to_irq(FPGA_IRQ_PIN);
126        res = request_irq(irq, ps2_keyboard_interrupt, IRQF_DISABLED | IRQF_TRIGGER_RISING, "FPGA - IRQ", NULL); // IRQF_TRIGGER_FALLING
127        
128        /* Set GPIOB26 as part of External Memory Controller*/
129        jz_gpio_set_function (FPGA_CS, JZ_GPIO_FUNC_NONE);
130        /* Use ioremap to get a handle on our region */
131        ioaddress = __ioremap(FPGA_BASE_BEGIN, FPGA_BASE_END - FPGA_BASE_BEGIN, _CACHE_UNCACHED);
132
133        return 0;
134}
135
136static void __exit ps2_keyboard_exit(void)
137{
138        free_irq(FPGA_IRQ_PIN, NULL);
139        __iounmap(ioaddress);
140        input_unregister_device(ps2kbd_dev);
141}
142
143module_init(ps2_keyboard_init);
144module_exit(ps2_keyboard_exit);
145
146MODULE_AUTHOR("Ari Bejarano <aabejaranoh@unal.edu.co>");
147MODULE_DESCRIPTION("PS/2 Keyboard Driver");
148MODULE_LICENSE("GPL v2");
149MODULE_ALIAS("platform:ps2-keyboard");
150

Archive Download this file

Branches:
master



interactive