Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
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 | |
16 | static unsigned int key_p; |
17 | static 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 | |
26 | static 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 | |
59 | static struct input_dev *ps2kbd_dev; |
60 | static void __iomem *ioaddress; |
61 | |
62 | static 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 | |
89 | static 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 | |
136 | static 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 | |
143 | module_init(ps2_keyboard_init); |
144 | module_exit(ps2_keyboard_exit); |
145 | |
146 | MODULE_AUTHOR("Ari Bejarano <aabejaranoh@unal.edu.co>"); |
147 | MODULE_DESCRIPTION("PS/2 Keyboard Driver"); |
148 | MODULE_LICENSE("GPL v2"); |
149 | MODULE_ALIAS("platform:ps2-keyboard"); |
150 |
Branches:
master