diff options
Diffstat (limited to 'drivers/input/keyboard/aaed2000_kbd.c')
-rw-r--r-- | drivers/input/keyboard/aaed2000_kbd.c | 62 |
1 files changed, 20 insertions, 42 deletions
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index 3a37505f067c..63d6ead6b877 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c | |||
@@ -14,12 +14,11 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/input.h> | 17 | #include <linux/input-polldev.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/workqueue.h> | ||
23 | 22 | ||
24 | #include <asm/arch/hardware.h> | 23 | #include <asm/arch/hardware.h> |
25 | #include <asm/arch/aaed2000.h> | 24 | #include <asm/arch/aaed2000.h> |
@@ -46,8 +45,7 @@ static unsigned char aaedkbd_keycode[NR_SCANCODES] = { | |||
46 | 45 | ||
47 | struct aaedkbd { | 46 | struct aaedkbd { |
48 | unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; | 47 | unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; |
49 | struct input_dev *input; | 48 | struct input_polled_dev *poll_dev; |
50 | struct work_struct workq; | ||
51 | int kbdscan_state[KB_COLS]; | 49 | int kbdscan_state[KB_COLS]; |
52 | int kbdscan_count[KB_COLS]; | 50 | int kbdscan_count[KB_COLS]; |
53 | }; | 51 | }; |
@@ -64,14 +62,15 @@ static void aaedkbd_report_col(struct aaedkbd *aaedkbd, | |||
64 | scancode = SCANCODE(row, col); | 62 | scancode = SCANCODE(row, col); |
65 | pressed = rowd & KB_ROWMASK(row); | 63 | pressed = rowd & KB_ROWMASK(row); |
66 | 64 | ||
67 | input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed); | 65 | input_report_key(aaedkbd->poll_dev->input, |
66 | aaedkbd->keycode[scancode], pressed); | ||
68 | } | 67 | } |
69 | } | 68 | } |
70 | 69 | ||
71 | /* Scan the hardware keyboard and push any changes up through the input layer */ | 70 | /* Scan the hardware keyboard and push any changes up through the input layer */ |
72 | static void aaedkbd_work(void *data) | 71 | static void aaedkbd_poll(struct input_polled_dev *dev) |
73 | { | 72 | { |
74 | struct aaedkbd *aaedkbd = data; | 73 | struct aaedkbd *aaedkbd = dev->private; |
75 | unsigned int col, rowd; | 74 | unsigned int col, rowd; |
76 | 75 | ||
77 | col = 0; | 76 | col = 0; |
@@ -90,51 +89,34 @@ static void aaedkbd_work(void *data) | |||
90 | } while (col < KB_COLS); | 89 | } while (col < KB_COLS); |
91 | 90 | ||
92 | AAEC_GPIO_KSCAN = 0x07; | 91 | AAEC_GPIO_KSCAN = 0x07; |
93 | input_sync(aaedkbd->input); | 92 | input_sync(dev->input); |
94 | |||
95 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); | ||
96 | } | ||
97 | |||
98 | static int aaedkbd_open(struct input_dev *indev) | ||
99 | { | ||
100 | struct aaedkbd *aaedkbd = input_get_drvdata(indev); | ||
101 | |||
102 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void aaedkbd_close(struct input_dev *indev) | ||
108 | { | ||
109 | struct aaedkbd *aaedkbd = input_get_drvdata(indev); | ||
110 | |||
111 | cancel_delayed_work(&aaedkbd->workq); | ||
112 | flush_scheduled_work(); | ||
113 | } | 93 | } |
114 | 94 | ||
115 | static int __devinit aaedkbd_probe(struct platform_device *pdev) | 95 | static int __devinit aaedkbd_probe(struct platform_device *pdev) |
116 | { | 96 | { |
117 | struct aaedkbd *aaedkbd; | 97 | struct aaedkbd *aaedkbd; |
98 | struct input_polled_dev *poll_dev; | ||
118 | struct input_dev *input_dev; | 99 | struct input_dev *input_dev; |
119 | int i; | 100 | int i; |
120 | int error; | 101 | int error; |
121 | 102 | ||
122 | aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); | 103 | aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); |
123 | input_dev = input_allocate_device(); | 104 | poll_dev = input_allocate_polled_device(); |
124 | if (!aaedkbd || !input_dev) { | 105 | if (!aaedkbd || !poll_dev) { |
125 | error = -ENOMEM; | 106 | error = -ENOMEM; |
126 | goto fail; | 107 | goto fail; |
127 | } | 108 | } |
128 | 109 | ||
129 | platform_set_drvdata(pdev, aaedkbd); | 110 | platform_set_drvdata(pdev, aaedkbd); |
130 | 111 | ||
131 | aaedkbd->input = input_dev; | 112 | aaedkbd->poll_dev = poll_dev; |
132 | |||
133 | /* Init keyboard rescan workqueue */ | ||
134 | INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd); | ||
135 | |||
136 | memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); | 113 | memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); |
137 | 114 | ||
115 | poll_dev->private = aaedkbd; | ||
116 | poll_dev->poll = aaedkbd_poll; | ||
117 | poll_dev->poll_interval = SCAN_INTERVAL; | ||
118 | |||
119 | input_dev = poll_dev->input; | ||
138 | input_dev->name = "AAED-2000 Keyboard"; | 120 | input_dev->name = "AAED-2000 Keyboard"; |
139 | input_dev->phys = "aaedkbd/input0"; | 121 | input_dev->phys = "aaedkbd/input0"; |
140 | input_dev->id.bustype = BUS_HOST; | 122 | input_dev->id.bustype = BUS_HOST; |
@@ -143,8 +125,6 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) | |||
143 | input_dev->id.version = 0x0100; | 125 | input_dev->id.version = 0x0100; |
144 | input_dev->dev.parent = &pdev->dev; | 126 | input_dev->dev.parent = &pdev->dev; |
145 | 127 | ||
146 | input_set_drvdata(input_dev, aaedkbd); | ||
147 | |||
148 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 128 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
149 | input_dev->keycode = aaedkbd->keycode; | 129 | input_dev->keycode = aaedkbd->keycode; |
150 | input_dev->keycodesize = sizeof(unsigned char); | 130 | input_dev->keycodesize = sizeof(unsigned char); |
@@ -154,17 +134,14 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) | |||
154 | set_bit(aaedkbd->keycode[i], input_dev->keybit); | 134 | set_bit(aaedkbd->keycode[i], input_dev->keybit); |
155 | clear_bit(0, input_dev->keybit); | 135 | clear_bit(0, input_dev->keybit); |
156 | 136 | ||
157 | input_dev->open = aaedkbd_open; | 137 | error = input_register_polled_device(aaedkbd->poll_dev); |
158 | input_dev->close = aaedkbd_close; | ||
159 | |||
160 | error = input_register_device(aaedkbd->input); | ||
161 | if (error) | 138 | if (error) |
162 | goto fail; | 139 | goto fail; |
163 | 140 | ||
164 | return 0; | 141 | return 0; |
165 | 142 | ||
166 | fail: kfree(aaedkbd); | 143 | fail: kfree(aaedkbd); |
167 | input_free_device(input_dev); | 144 | input_free_polled_device(poll_dev); |
168 | return error; | 145 | return error; |
169 | } | 146 | } |
170 | 147 | ||
@@ -172,7 +149,8 @@ static int __devexit aaedkbd_remove(struct platform_device *pdev) | |||
172 | { | 149 | { |
173 | struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); | 150 | struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); |
174 | 151 | ||
175 | input_unregister_device(aaedkbd->input); | 152 | input_unregister_polled_device(aaedkbd->poll_dev); |
153 | input_free_polled_device(aaedkbd->poll_dev); | ||
176 | kfree(aaedkbd); | 154 | kfree(aaedkbd); |
177 | 155 | ||
178 | return 0; | 156 | return 0; |