diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-09-16 00:48:32 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-09-16 00:48:32 -0400 |
commit | ea88023b3491a384575ebcd5e8a449e841a28a24 (patch) | |
tree | f46e3d8302e44dc55ce31823501e100472d29683 /drivers/input/keyboard | |
parent | a6f15ade97989d414e9bf33874c9d5d1f39808ec (diff) | |
parent | 0cb583fd2862f19ea88b02eb307d11c09e51e2f8 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
arch/sh/kernel/vmlinux.lds.S
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 26 | ||||
-rw-r--r-- | drivers/input/keyboard/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 43 | ||||
-rw-r--r-- | drivers/input/keyboard/bf54x-keys.c | 26 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 19 | ||||
-rw-r--r-- | drivers/input/keyboard/hil_kbd.c | 607 | ||||
-rw-r--r-- | drivers/input/keyboard/lkkbd.c | 62 | ||||
-rw-r--r-- | drivers/input/keyboard/matrix_keypad.c | 15 | ||||
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 219 | ||||
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 22 | ||||
-rw-r--r-- | drivers/input/keyboard/sunkbd.c | 142 | ||||
-rw-r--r-- | drivers/input/keyboard/tosakbd.c | 18 | ||||
-rw-r--r-- | drivers/input/keyboard/twl4030_keypad.c | 480 | ||||
-rw-r--r-- | drivers/input/keyboard/w90p910_keypad.c | 281 |
14 files changed, 1497 insertions, 465 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a6b989a9dc07..3525c19be428 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -187,7 +187,7 @@ config KEYBOARD_HIL_OLD | |||
187 | submenu. | 187 | submenu. |
188 | 188 | ||
189 | config KEYBOARD_HIL | 189 | config KEYBOARD_HIL |
190 | tristate "HP HIL keyboard support" | 190 | tristate "HP HIL keyboard/pointer support" |
191 | depends on GSC || HP300 | 191 | depends on GSC || HP300 |
192 | default y | 192 | default y |
193 | select HP_SDC | 193 | select HP_SDC |
@@ -196,7 +196,8 @@ config KEYBOARD_HIL | |||
196 | help | 196 | help |
197 | The "Human Interface Loop" is a older, 8-channel USB-like | 197 | The "Human Interface Loop" is a older, 8-channel USB-like |
198 | controller used in several Hewlett Packard models. | 198 | controller used in several Hewlett Packard models. |
199 | This driver implements support for HIL-keyboards attached | 199 | This driver implements support for HIL-keyboards and pointing |
200 | devices (mice, tablets, touchscreens) attached | ||
200 | to your machine, so normally you should say Y here. | 201 | to your machine, so normally you should say Y here. |
201 | 202 | ||
202 | config KEYBOARD_HP6XX | 203 | config KEYBOARD_HP6XX |
@@ -329,6 +330,17 @@ config KEYBOARD_OMAP | |||
329 | To compile this driver as a module, choose M here: the | 330 | To compile this driver as a module, choose M here: the |
330 | module will be called omap-keypad. | 331 | module will be called omap-keypad. |
331 | 332 | ||
333 | config KEYBOARD_TWL4030 | ||
334 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | ||
335 | depends on TWL4030_CORE | ||
336 | help | ||
337 | Say Y here if your board use the keypad controller on | ||
338 | TWL4030 family chips. It's safe to say enable this | ||
339 | even on boards that don't use the keypad controller. | ||
340 | |||
341 | To compile this driver as a module, choose M here: the | ||
342 | module will be called twl4030_keypad. | ||
343 | |||
332 | config KEYBOARD_TOSA | 344 | config KEYBOARD_TOSA |
333 | tristate "Tosa keyboard" | 345 | tristate "Tosa keyboard" |
334 | depends on MACH_TOSA | 346 | depends on MACH_TOSA |
@@ -361,4 +373,14 @@ config KEYBOARD_XTKBD | |||
361 | To compile this driver as a module, choose M here: the | 373 | To compile this driver as a module, choose M here: the |
362 | module will be called xtkbd. | 374 | module will be called xtkbd. |
363 | 375 | ||
376 | config KEYBOARD_W90P910 | ||
377 | tristate "W90P910 Matrix Keypad support" | ||
378 | depends on ARCH_W90X900 | ||
379 | help | ||
380 | Say Y here to enable the matrix keypad on evaluation board | ||
381 | based on W90P910. | ||
382 | |||
383 | To compile this driver as a module, choose M here: the | ||
384 | module will be called w90p910_keypad. | ||
385 | |||
364 | endif | 386 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index b5b5eae9724f..8a7a22b30266 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -30,4 +30,6 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | |||
30 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 30 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
31 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 31 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
32 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o | 32 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o |
33 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o | ||
33 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 34 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
35 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6c6a09b1c0fe..c9523e48c6ad 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -68,7 +68,9 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and | |||
68 | * are loadable via a userland utility. | 68 | * are loadable via a userland utility. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | static const unsigned short atkbd_set2_keycode[512] = { | 71 | #define ATKBD_KEYMAP_SIZE 512 |
72 | |||
73 | static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = { | ||
72 | 74 | ||
73 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES | 75 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES |
74 | 76 | ||
@@ -99,7 +101,7 @@ static const unsigned short atkbd_set2_keycode[512] = { | |||
99 | #endif | 101 | #endif |
100 | }; | 102 | }; |
101 | 103 | ||
102 | static const unsigned short atkbd_set3_keycode[512] = { | 104 | static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = { |
103 | 105 | ||
104 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, | 106 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, |
105 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, | 107 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, |
@@ -200,8 +202,8 @@ struct atkbd { | |||
200 | char phys[32]; | 202 | char phys[32]; |
201 | 203 | ||
202 | unsigned short id; | 204 | unsigned short id; |
203 | unsigned short keycode[512]; | 205 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
204 | DECLARE_BITMAP(force_release_mask, 512); | 206 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
205 | unsigned char set; | 207 | unsigned char set; |
206 | unsigned char translated; | 208 | unsigned char translated; |
207 | unsigned char extra; | 209 | unsigned char extra; |
@@ -253,6 +255,7 @@ static struct device_attribute atkbd_attr_##_name = \ | |||
253 | __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); | 255 | __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); |
254 | 256 | ||
255 | ATKBD_DEFINE_ATTR(extra); | 257 | ATKBD_DEFINE_ATTR(extra); |
258 | ATKBD_DEFINE_ATTR(force_release); | ||
256 | ATKBD_DEFINE_ATTR(scroll); | 259 | ATKBD_DEFINE_ATTR(scroll); |
257 | ATKBD_DEFINE_ATTR(set); | 260 | ATKBD_DEFINE_ATTR(set); |
258 | ATKBD_DEFINE_ATTR(softrepeat); | 261 | ATKBD_DEFINE_ATTR(softrepeat); |
@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count); | |||
272 | 275 | ||
273 | static struct attribute *atkbd_attributes[] = { | 276 | static struct attribute *atkbd_attributes[] = { |
274 | &atkbd_attr_extra.attr, | 277 | &atkbd_attr_extra.attr, |
278 | &atkbd_attr_force_release.attr, | ||
275 | &atkbd_attr_scroll.attr, | 279 | &atkbd_attr_scroll.attr, |
276 | &atkbd_attr_set.attr, | 280 | &atkbd_attr_set.attr, |
277 | &atkbd_attr_softrepeat.attr, | 281 | &atkbd_attr_softrepeat.attr, |
@@ -934,7 +938,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) | |||
934 | int i, j; | 938 | int i, j; |
935 | 939 | ||
936 | memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); | 940 | memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); |
937 | bitmap_zero(atkbd->force_release_mask, 512); | 941 | bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); |
938 | 942 | ||
939 | if (atkbd->translated) { | 943 | if (atkbd->translated) { |
940 | for (i = 0; i < 128; i++) { | 944 | for (i = 0; i < 128; i++) { |
@@ -1041,7 +1045,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1041 | input_dev->keycodesize = sizeof(unsigned short); | 1045 | input_dev->keycodesize = sizeof(unsigned short); |
1042 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1046 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1043 | 1047 | ||
1044 | for (i = 0; i < 512; i++) | 1048 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) |
1045 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1049 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) |
1046 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1050 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1047 | } | 1051 | } |
@@ -1309,6 +1313,33 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1309 | return count; | 1313 | return count; |
1310 | } | 1314 | } |
1311 | 1315 | ||
1316 | static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf) | ||
1317 | { | ||
1318 | size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, | ||
1319 | atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); | ||
1320 | |||
1321 | buf[len++] = '\n'; | ||
1322 | buf[len] = '\0'; | ||
1323 | |||
1324 | return len; | ||
1325 | } | ||
1326 | |||
1327 | static ssize_t atkbd_set_force_release(struct atkbd *atkbd, | ||
1328 | const char *buf, size_t count) | ||
1329 | { | ||
1330 | /* 64 bytes on stack should be acceptable */ | ||
1331 | DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE); | ||
1332 | int err; | ||
1333 | |||
1334 | err = bitmap_parselist(buf, new_mask, ATKBD_KEYMAP_SIZE); | ||
1335 | if (err) | ||
1336 | return err; | ||
1337 | |||
1338 | memcpy(atkbd->force_release_mask, new_mask, sizeof(atkbd->force_release_mask)); | ||
1339 | return count; | ||
1340 | } | ||
1341 | |||
1342 | |||
1312 | static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) | 1343 | static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) |
1313 | { | 1344 | { |
1314 | return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); | 1345 | return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index d427f322e207..fe376a27fe57 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -184,14 +184,13 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
184 | int i, error; | 184 | int i, error; |
185 | 185 | ||
186 | if (!pdata->rows || !pdata->cols || !pdata->keymap) { | 186 | if (!pdata->rows || !pdata->cols || !pdata->keymap) { |
187 | printk(KERN_ERR DRV_NAME | 187 | dev_err(&pdev->dev, "no rows, cols or keymap from pdata\n"); |
188 | ": No rows, cols or keymap from pdata\n"); | ||
189 | return -EINVAL; | 188 | return -EINVAL; |
190 | } | 189 | } |
191 | 190 | ||
192 | if (!pdata->keymapsize || | 191 | if (!pdata->keymapsize || |
193 | pdata->keymapsize > (pdata->rows * pdata->cols)) { | 192 | pdata->keymapsize > (pdata->rows * pdata->cols)) { |
194 | printk(KERN_ERR DRV_NAME ": Invalid keymapsize\n"); | 193 | dev_err(&pdev->dev, "invalid keymapsize\n"); |
195 | return -EINVAL; | 194 | return -EINVAL; |
196 | } | 195 | } |
197 | 196 | ||
@@ -211,8 +210,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
211 | 210 | ||
212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || | 211 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || |
213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { | 212 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { |
214 | printk(KERN_WARNING DRV_NAME | 213 | dev_warn(&pdev->dev, |
215 | ": Invalid Debounce/Columndrive Time in platform data\n"); | 214 | "invalid platform debounce/columndrive time\n"); |
216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ | 215 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ |
217 | } else { | 216 | } else { |
218 | bfin_write_KPAD_MSEL( | 217 | bfin_write_KPAD_MSEL( |
@@ -231,16 +230,14 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
231 | 230 | ||
232 | if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows], | 231 | if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows], |
233 | DRV_NAME)) { | 232 | DRV_NAME)) { |
234 | printk(KERN_ERR DRV_NAME | 233 | dev_err(&pdev->dev, "requesting peripherals failed\n"); |
235 | ": Requesting Peripherals failed\n"); | ||
236 | error = -EFAULT; | 234 | error = -EFAULT; |
237 | goto out0; | 235 | goto out0; |
238 | } | 236 | } |
239 | 237 | ||
240 | if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols], | 238 | if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols], |
241 | DRV_NAME)) { | 239 | DRV_NAME)) { |
242 | printk(KERN_ERR DRV_NAME | 240 | dev_err(&pdev->dev, "requesting peripherals failed\n"); |
243 | ": Requesting Peripherals failed\n"); | ||
244 | error = -EFAULT; | 241 | error = -EFAULT; |
245 | goto out1; | 242 | goto out1; |
246 | } | 243 | } |
@@ -254,9 +251,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
254 | error = request_irq(bf54x_kpad->irq, bfin_kpad_isr, | 251 | error = request_irq(bf54x_kpad->irq, bfin_kpad_isr, |
255 | 0, DRV_NAME, pdev); | 252 | 0, DRV_NAME, pdev); |
256 | if (error) { | 253 | if (error) { |
257 | printk(KERN_ERR DRV_NAME | 254 | dev_err(&pdev->dev, "unable to claim irq %d\n", |
258 | ": unable to claim irq %d; error %d\n", | 255 | bf54x_kpad->irq); |
259 | bf54x_kpad->irq, error); | ||
260 | goto out2; | 256 | goto out2; |
261 | } | 257 | } |
262 | 258 | ||
@@ -297,8 +293,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
297 | 293 | ||
298 | error = input_register_device(input); | 294 | error = input_register_device(input); |
299 | if (error) { | 295 | if (error) { |
300 | printk(KERN_ERR DRV_NAME | 296 | dev_err(&pdev->dev, "unable to register input device\n"); |
301 | ": Unable to register input device (%d)\n", error); | ||
302 | goto out4; | 297 | goto out4; |
303 | } | 298 | } |
304 | 299 | ||
@@ -316,9 +311,6 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
316 | 311 | ||
317 | device_init_wakeup(&pdev->dev, 1); | 312 | device_init_wakeup(&pdev->dev, 1); |
318 | 313 | ||
319 | printk(KERN_ERR DRV_NAME | ||
320 | ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq); | ||
321 | |||
322 | return 0; | 314 | return 0; |
323 | 315 | ||
324 | out4: | 316 | out4: |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index efed0c9e242e..a88aff3816a0 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -216,8 +216,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
216 | 216 | ||
217 | 217 | ||
218 | #ifdef CONFIG_PM | 218 | #ifdef CONFIG_PM |
219 | static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state) | 219 | static int gpio_keys_suspend(struct device *dev) |
220 | { | 220 | { |
221 | struct platform_device *pdev = to_platform_device(dev); | ||
221 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 222 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
222 | int i; | 223 | int i; |
223 | 224 | ||
@@ -234,8 +235,9 @@ static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state) | |||
234 | return 0; | 235 | return 0; |
235 | } | 236 | } |
236 | 237 | ||
237 | static int gpio_keys_resume(struct platform_device *pdev) | 238 | static int gpio_keys_resume(struct device *dev) |
238 | { | 239 | { |
240 | struct platform_device *pdev = to_platform_device(dev); | ||
239 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 241 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
240 | int i; | 242 | int i; |
241 | 243 | ||
@@ -251,19 +253,22 @@ static int gpio_keys_resume(struct platform_device *pdev) | |||
251 | 253 | ||
252 | return 0; | 254 | return 0; |
253 | } | 255 | } |
254 | #else | 256 | |
255 | #define gpio_keys_suspend NULL | 257 | static const struct dev_pm_ops gpio_keys_pm_ops = { |
256 | #define gpio_keys_resume NULL | 258 | .suspend = gpio_keys_suspend, |
259 | .resume = gpio_keys_resume, | ||
260 | }; | ||
257 | #endif | 261 | #endif |
258 | 262 | ||
259 | static struct platform_driver gpio_keys_device_driver = { | 263 | static struct platform_driver gpio_keys_device_driver = { |
260 | .probe = gpio_keys_probe, | 264 | .probe = gpio_keys_probe, |
261 | .remove = __devexit_p(gpio_keys_remove), | 265 | .remove = __devexit_p(gpio_keys_remove), |
262 | .suspend = gpio_keys_suspend, | ||
263 | .resume = gpio_keys_resume, | ||
264 | .driver = { | 266 | .driver = { |
265 | .name = "gpio-keys", | 267 | .name = "gpio-keys", |
266 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
269 | #ifdef CONFIG_PM | ||
270 | .pm = &gpio_keys_pm_ops, | ||
271 | #endif | ||
267 | } | 272 | } |
268 | }; | 273 | }; |
269 | 274 | ||
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 6f356705ee3b..c83f4b2ec7d3 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -37,19 +37,19 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/semaphore.h> | 40 | #include <linux/completion.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/pci_ids.h> | 42 | #include <linux/pci_ids.h> |
43 | 43 | ||
44 | #define PREFIX "HIL KEYB: " | 44 | #define PREFIX "HIL: " |
45 | #define HIL_GENERIC_NAME "HIL keyboard" | ||
46 | 45 | ||
47 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | 46 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); |
48 | MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); | 47 | MODULE_DESCRIPTION("HIL keyboard/mouse driver"); |
49 | MODULE_LICENSE("Dual BSD/GPL"); | 48 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | MODULE_ALIAS("serio:ty03pr25id00ex*"); | 49 | MODULE_ALIAS("serio:ty03pr25id00ex*"); /* HIL keyboard */ |
50 | MODULE_ALIAS("serio:ty03pr25id0Fex*"); /* HIL mouse */ | ||
51 | 51 | ||
52 | #define HIL_KBD_MAX_LENGTH 16 | 52 | #define HIL_PACKET_MAX_LENGTH 16 |
53 | 53 | ||
54 | #define HIL_KBD_SET1_UPBIT 0x01 | 54 | #define HIL_KBD_SET1_UPBIT 0x01 |
55 | #define HIL_KBD_SET1_SHIFT 1 | 55 | #define HIL_KBD_SET1_SHIFT 1 |
@@ -67,308 +67,497 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly = | |||
67 | 67 | ||
68 | static const char hil_language[][16] = { HIL_LOCALE_MAP }; | 68 | static const char hil_language[][16] = { HIL_LOCALE_MAP }; |
69 | 69 | ||
70 | struct hil_kbd { | 70 | struct hil_dev { |
71 | struct input_dev *dev; | 71 | struct input_dev *dev; |
72 | struct serio *serio; | 72 | struct serio *serio; |
73 | 73 | ||
74 | /* Input buffer and index for packets from HIL bus. */ | 74 | /* Input buffer and index for packets from HIL bus. */ |
75 | hil_packet data[HIL_KBD_MAX_LENGTH]; | 75 | hil_packet data[HIL_PACKET_MAX_LENGTH]; |
76 | int idx4; /* four counts per packet */ | 76 | int idx4; /* four counts per packet */ |
77 | 77 | ||
78 | /* Raw device info records from HIL bus, see hil.h for fields. */ | 78 | /* Raw device info records from HIL bus, see hil.h for fields. */ |
79 | char idd[HIL_KBD_MAX_LENGTH]; /* DID byte and IDD record */ | 79 | char idd[HIL_PACKET_MAX_LENGTH]; /* DID byte and IDD record */ |
80 | char rsc[HIL_KBD_MAX_LENGTH]; /* RSC record */ | 80 | char rsc[HIL_PACKET_MAX_LENGTH]; /* RSC record */ |
81 | char exd[HIL_KBD_MAX_LENGTH]; /* EXD record */ | 81 | char exd[HIL_PACKET_MAX_LENGTH]; /* EXD record */ |
82 | char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */ | 82 | char rnm[HIL_PACKET_MAX_LENGTH + 1]; /* RNM record + NULL term. */ |
83 | 83 | ||
84 | /* Something to sleep around with. */ | 84 | struct completion cmd_done; |
85 | struct semaphore sem; | 85 | |
86 | bool is_pointer; | ||
87 | /* Extra device details needed for pointing devices. */ | ||
88 | unsigned int nbtn, naxes; | ||
89 | unsigned int btnmap[7]; | ||
86 | }; | 90 | }; |
87 | 91 | ||
88 | /* Process a complete packet after transfer from the HIL */ | 92 | static bool hil_dev_is_command_response(hil_packet p) |
89 | static void hil_kbd_process_record(struct hil_kbd *kbd) | ||
90 | { | 93 | { |
91 | struct input_dev *dev = kbd->dev; | 94 | if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
92 | hil_packet *data = kbd->data; | 95 | return false; |
93 | hil_packet p; | ||
94 | int idx, i, cnt; | ||
95 | 96 | ||
96 | idx = kbd->idx4/4; | 97 | if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) |
97 | p = data[idx - 1]; | 98 | return false; |
98 | 99 | ||
99 | if ((p & ~HIL_CMDCT_POL) == | 100 | return true; |
100 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) | 101 | } |
101 | goto report; | 102 | |
102 | if ((p & ~HIL_CMDCT_RPL) == | 103 | static void hil_dev_handle_command_response(struct hil_dev *dev) |
103 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | 104 | { |
104 | goto report; | 105 | hil_packet p; |
106 | char *buf; | ||
107 | int i, idx; | ||
108 | |||
109 | idx = dev->idx4 / 4; | ||
110 | p = dev->data[idx - 1]; | ||
105 | 111 | ||
106 | /* Not a poll response. See if we are loading config records. */ | ||
107 | switch (p & HIL_PKT_DATA_MASK) { | 112 | switch (p & HIL_PKT_DATA_MASK) { |
108 | case HIL_CMD_IDD: | 113 | case HIL_CMD_IDD: |
109 | for (i = 0; i < idx; i++) | 114 | buf = dev->idd; |
110 | kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
111 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
112 | kbd->idd[i] = 0; | ||
113 | break; | 115 | break; |
114 | 116 | ||
115 | case HIL_CMD_RSC: | 117 | case HIL_CMD_RSC: |
116 | for (i = 0; i < idx; i++) | 118 | buf = dev->rsc; |
117 | kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
118 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
119 | kbd->rsc[i] = 0; | ||
120 | break; | 119 | break; |
121 | 120 | ||
122 | case HIL_CMD_EXD: | 121 | case HIL_CMD_EXD: |
123 | for (i = 0; i < idx; i++) | 122 | buf = dev->exd; |
124 | kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
125 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
126 | kbd->exd[i] = 0; | ||
127 | break; | 123 | break; |
128 | 124 | ||
129 | case HIL_CMD_RNM: | 125 | case HIL_CMD_RNM: |
130 | for (i = 0; i < idx; i++) | 126 | dev->rnm[HIL_PACKET_MAX_LENGTH] = 0; |
131 | kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 127 | buf = dev->rnm; |
132 | for (; i < HIL_KBD_MAX_LENGTH + 1; i++) | ||
133 | kbd->rnm[i] = '\0'; | ||
134 | break; | 128 | break; |
135 | 129 | ||
136 | default: | 130 | default: |
137 | /* These occur when device isn't present */ | 131 | /* These occur when device isn't present */ |
138 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) | 132 | if (p != (HIL_ERR_INT | HIL_PKT_CMD)) { |
139 | break; | 133 | /* Anything else we'd like to know about. */ |
140 | /* Anything else we'd like to know about. */ | 134 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
141 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 135 | } |
142 | break; | 136 | goto out; |
143 | } | 137 | } |
144 | goto out; | ||
145 | 138 | ||
146 | report: | 139 | for (i = 0; i < idx; i++) |
147 | cnt = 1; | 140 | buf[i] = dev->data[i] & HIL_PKT_DATA_MASK; |
141 | for (; i < HIL_PACKET_MAX_LENGTH; i++) | ||
142 | buf[i] = 0; | ||
143 | out: | ||
144 | complete(&dev->cmd_done); | ||
145 | } | ||
146 | |||
147 | static void hil_dev_handle_kbd_events(struct hil_dev *kbd) | ||
148 | { | ||
149 | struct input_dev *dev = kbd->dev; | ||
150 | int idx = kbd->idx4 / 4; | ||
151 | int i; | ||
152 | |||
148 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { | 153 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { |
149 | case HIL_POL_CHARTYPE_NONE: | 154 | case HIL_POL_CHARTYPE_NONE: |
150 | break; | 155 | return; |
151 | 156 | ||
152 | case HIL_POL_CHARTYPE_ASCII: | 157 | case HIL_POL_CHARTYPE_ASCII: |
153 | while (cnt < idx - 1) | 158 | for (i = 1; i < idx - 1; i++) |
154 | input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); | 159 | input_report_key(dev, kbd->data[i] & 0x7f, 1); |
155 | break; | 160 | break; |
156 | 161 | ||
157 | case HIL_POL_CHARTYPE_RSVD1: | 162 | case HIL_POL_CHARTYPE_RSVD1: |
158 | case HIL_POL_CHARTYPE_RSVD2: | 163 | case HIL_POL_CHARTYPE_RSVD2: |
159 | case HIL_POL_CHARTYPE_BINARY: | 164 | case HIL_POL_CHARTYPE_BINARY: |
160 | while (cnt < idx - 1) | 165 | for (i = 1; i < idx - 1; i++) |
161 | input_report_key(dev, kbd->data[cnt++], 1); | 166 | input_report_key(dev, kbd->data[i], 1); |
162 | break; | 167 | break; |
163 | 168 | ||
164 | case HIL_POL_CHARTYPE_SET1: | 169 | case HIL_POL_CHARTYPE_SET1: |
165 | while (cnt < idx - 1) { | 170 | for (i = 1; i < idx - 1; i++) { |
166 | unsigned int key; | 171 | unsigned int key = kbd->data[i]; |
167 | int up; | 172 | int up = key & HIL_KBD_SET1_UPBIT; |
168 | key = kbd->data[cnt++]; | 173 | |
169 | up = key & HIL_KBD_SET1_UPBIT; | ||
170 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 174 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
171 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; | 175 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; |
172 | if (key != KEY_RESERVED) | 176 | input_report_key(dev, key, !up); |
173 | input_report_key(dev, key, !up); | ||
174 | } | 177 | } |
175 | break; | 178 | break; |
176 | 179 | ||
177 | case HIL_POL_CHARTYPE_SET2: | 180 | case HIL_POL_CHARTYPE_SET2: |
178 | while (cnt < idx - 1) { | 181 | for (i = 1; i < idx - 1; i++) { |
179 | unsigned int key; | 182 | unsigned int key = kbd->data[i]; |
180 | int up; | 183 | int up = key & HIL_KBD_SET2_UPBIT; |
181 | key = kbd->data[cnt++]; | 184 | |
182 | up = key & HIL_KBD_SET2_UPBIT; | ||
183 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 185 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
184 | key = key >> HIL_KBD_SET2_SHIFT; | 186 | key = key >> HIL_KBD_SET2_SHIFT; |
185 | if (key != KEY_RESERVED) | 187 | input_report_key(dev, key, !up); |
186 | input_report_key(dev, key, !up); | ||
187 | } | 188 | } |
188 | break; | 189 | break; |
189 | 190 | ||
190 | case HIL_POL_CHARTYPE_SET3: | 191 | case HIL_POL_CHARTYPE_SET3: |
191 | while (cnt < idx - 1) { | 192 | for (i = 1; i < idx - 1; i++) { |
192 | unsigned int key; | 193 | unsigned int key = kbd->data[i]; |
193 | int up; | 194 | int up = key & HIL_KBD_SET3_UPBIT; |
194 | key = kbd->data[cnt++]; | 195 | |
195 | up = key & HIL_KBD_SET3_UPBIT; | ||
196 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 196 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
197 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; | 197 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; |
198 | if (key != KEY_RESERVED) | 198 | input_report_key(dev, key, !up); |
199 | input_report_key(dev, key, !up); | ||
200 | } | 199 | } |
201 | break; | 200 | break; |
202 | } | 201 | } |
203 | out: | 202 | |
204 | kbd->idx4 = 0; | 203 | input_sync(dev); |
205 | up(&kbd->sem); | ||
206 | } | 204 | } |
207 | 205 | ||
208 | static void hil_kbd_process_err(struct hil_kbd *kbd) | 206 | static void hil_dev_handle_ptr_events(struct hil_dev *ptr) |
207 | { | ||
208 | struct input_dev *dev = ptr->dev; | ||
209 | int idx = ptr->idx4 / 4; | ||
210 | hil_packet p = ptr->data[idx - 1]; | ||
211 | int i, cnt, laxis; | ||
212 | bool absdev, ax16; | ||
213 | |||
214 | if ((p & HIL_CMDCT_POL) != idx - 1) { | ||
215 | printk(KERN_WARNING PREFIX | ||
216 | "Malformed poll packet %x (idx = %i)\n", p, idx); | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | i = (p & HIL_POL_AXIS_ALT) ? 3 : 0; | ||
221 | laxis = (p & HIL_POL_NUM_AXES_MASK) + i; | ||
222 | |||
223 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ | ||
224 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; | ||
225 | |||
226 | for (cnt = 1; i < laxis; i++) { | ||
227 | unsigned int lo, hi, val; | ||
228 | |||
229 | lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK; | ||
230 | hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0; | ||
231 | |||
232 | if (absdev) { | ||
233 | val = lo + (hi << 8); | ||
234 | #ifdef TABLET_AUTOADJUST | ||
235 | if (val < dev->absmin[ABS_X + i]) | ||
236 | dev->absmin[ABS_X + i] = val; | ||
237 | if (val > dev->absmax[ABS_X + i]) | ||
238 | dev->absmax[ABS_X + i] = val; | ||
239 | #endif | ||
240 | if (i%3) val = dev->absmax[ABS_X + i] - val; | ||
241 | input_report_abs(dev, ABS_X + i, val); | ||
242 | } else { | ||
243 | val = (int) (((int8_t)lo) | ((int8_t)hi << 8)); | ||
244 | if (i % 3) | ||
245 | val *= -1; | ||
246 | input_report_rel(dev, REL_X + i, val); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | while (cnt < idx - 1) { | ||
251 | unsigned int btn = ptr->data[cnt++]; | ||
252 | int up = btn & 1; | ||
253 | |||
254 | btn &= 0xfe; | ||
255 | if (btn == 0x8e) | ||
256 | continue; /* TODO: proximity == touch? */ | ||
257 | if (btn > 0x8c || btn < 0x80) | ||
258 | continue; | ||
259 | btn = (btn - 0x80) >> 1; | ||
260 | btn = ptr->btnmap[btn]; | ||
261 | input_report_key(dev, btn, !up); | ||
262 | } | ||
263 | |||
264 | input_sync(dev); | ||
265 | } | ||
266 | |||
267 | static void hil_dev_process_err(struct hil_dev *dev) | ||
209 | { | 268 | { |
210 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 269 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
211 | kbd->idx4 = 0; | 270 | dev->idx4 = 0; |
212 | up(&kbd->sem); | 271 | complete(&dev->cmd_done); /* just in case somebody is waiting */ |
213 | } | 272 | } |
214 | 273 | ||
215 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, | 274 | static irqreturn_t hil_dev_interrupt(struct serio *serio, |
216 | unsigned char data, unsigned int flags) | 275 | unsigned char data, unsigned int flags) |
217 | { | 276 | { |
218 | struct hil_kbd *kbd; | 277 | struct hil_dev *dev; |
219 | hil_packet packet; | 278 | hil_packet packet; |
220 | int idx; | 279 | int idx; |
221 | 280 | ||
222 | kbd = serio_get_drvdata(serio); | 281 | dev = serio_get_drvdata(serio); |
223 | BUG_ON(kbd == NULL); | 282 | BUG_ON(dev == NULL); |
224 | 283 | ||
225 | if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { | 284 | if (dev->idx4 >= HIL_PACKET_MAX_LENGTH * sizeof(hil_packet)) { |
226 | hil_kbd_process_err(kbd); | 285 | hil_dev_process_err(dev); |
227 | return IRQ_HANDLED; | 286 | goto out; |
228 | } | 287 | } |
229 | idx = kbd->idx4/4; | 288 | |
230 | if (!(kbd->idx4 % 4)) | 289 | idx = dev->idx4 / 4; |
231 | kbd->data[idx] = 0; | 290 | if (!(dev->idx4 % 4)) |
232 | packet = kbd->data[idx]; | 291 | dev->data[idx] = 0; |
233 | packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); | 292 | packet = dev->data[idx]; |
234 | kbd->data[idx] = packet; | 293 | packet |= ((hil_packet)data) << ((3 - (dev->idx4 % 4)) * 8); |
294 | dev->data[idx] = packet; | ||
235 | 295 | ||
236 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 296 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
237 | if ((++(kbd->idx4)) % 4) | 297 | if ((++dev->idx4 % 4) == 0) { |
238 | return IRQ_HANDLED; | 298 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
239 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 299 | hil_dev_process_err(dev); |
240 | hil_kbd_process_err(kbd); | 300 | } else if (packet & HIL_PKT_CMD) { |
241 | return IRQ_HANDLED; | 301 | if (hil_dev_is_command_response(packet)) |
302 | hil_dev_handle_command_response(dev); | ||
303 | else if (dev->is_pointer) | ||
304 | hil_dev_handle_ptr_events(dev); | ||
305 | else | ||
306 | hil_dev_handle_kbd_events(dev); | ||
307 | dev->idx4 = 0; | ||
308 | } | ||
242 | } | 309 | } |
243 | if (packet & HIL_PKT_CMD) | 310 | out: |
244 | hil_kbd_process_record(kbd); | ||
245 | return IRQ_HANDLED; | 311 | return IRQ_HANDLED; |
246 | } | 312 | } |
247 | 313 | ||
248 | static void hil_kbd_disconnect(struct serio *serio) | 314 | static void hil_dev_disconnect(struct serio *serio) |
249 | { | 315 | { |
250 | struct hil_kbd *kbd; | 316 | struct hil_dev *dev = serio_get_drvdata(serio); |
251 | 317 | ||
252 | kbd = serio_get_drvdata(serio); | 318 | BUG_ON(dev == NULL); |
253 | BUG_ON(kbd == NULL); | ||
254 | 319 | ||
255 | serio_close(serio); | 320 | serio_close(serio); |
256 | input_unregister_device(kbd->dev); | 321 | input_unregister_device(dev->dev); |
257 | kfree(kbd); | 322 | serio_set_drvdata(serio, NULL); |
323 | kfree(dev); | ||
324 | } | ||
325 | |||
326 | static void hil_dev_keyboard_setup(struct hil_dev *kbd) | ||
327 | { | ||
328 | struct input_dev *input_dev = kbd->dev; | ||
329 | uint8_t did = kbd->idd[0]; | ||
330 | int i; | ||
331 | |||
332 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
333 | input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | ||
334 | BIT_MASK(LED_SCROLLL); | ||
335 | |||
336 | for (i = 0; i < 128; i++) { | ||
337 | __set_bit(hil_kbd_set1[i], input_dev->keybit); | ||
338 | __set_bit(hil_kbd_set3[i], input_dev->keybit); | ||
339 | } | ||
340 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
341 | |||
342 | input_dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | ||
343 | input_dev->keycodesize = sizeof(hil_kbd_set1[0]); | ||
344 | input_dev->keycode = hil_kbd_set1; | ||
345 | |||
346 | input_dev->name = strlen(kbd->rnm) ? kbd->rnm : "HIL keyboard"; | ||
347 | input_dev->phys = "hpkbd/input0"; | ||
348 | |||
349 | printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n", | ||
350 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); | ||
258 | } | 351 | } |
259 | 352 | ||
260 | static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | 353 | static void hil_dev_pointer_setup(struct hil_dev *ptr) |
261 | { | 354 | { |
262 | struct hil_kbd *kbd; | 355 | struct input_dev *input_dev = ptr->dev; |
263 | uint8_t did, *idd; | 356 | uint8_t did = ptr->idd[0]; |
264 | int i; | 357 | uint8_t *idd = ptr->idd + 1; |
358 | unsigned int naxsets = HIL_IDD_NUM_AXSETS(*idd); | ||
359 | unsigned int i, btntype; | ||
360 | const char *txt; | ||
361 | |||
362 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); | ||
363 | |||
364 | switch (did & HIL_IDD_DID_TYPE_MASK) { | ||
365 | case HIL_IDD_DID_TYPE_REL: | ||
366 | input_dev->evbit[0] = BIT_MASK(EV_REL); | ||
265 | 367 | ||
266 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); | 368 | for (i = 0; i < ptr->naxes; i++) |
267 | if (!kbd) | 369 | __set_bit(REL_X + i, input_dev->relbit); |
268 | return -ENOMEM; | ||
269 | 370 | ||
270 | kbd->dev = input_allocate_device(); | 371 | for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++) |
271 | if (!kbd->dev) | 372 | __set_bit(REL_X + i, input_dev->relbit); |
373 | |||
374 | txt = "relative"; | ||
375 | break; | ||
376 | |||
377 | case HIL_IDD_DID_TYPE_ABS: | ||
378 | input_dev->evbit[0] = BIT_MASK(EV_ABS); | ||
379 | |||
380 | for (i = 0; i < ptr->naxes; i++) | ||
381 | input_set_abs_params(input_dev, ABS_X + i, | ||
382 | 0, HIL_IDD_AXIS_MAX(idd, i), 0, 0); | ||
383 | |||
384 | for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++) | ||
385 | input_set_abs_params(input_dev, ABS_X + i, | ||
386 | 0, HIL_IDD_AXIS_MAX(idd, i - 3), 0, 0); | ||
387 | |||
388 | #ifdef TABLET_AUTOADJUST | ||
389 | for (i = 0; i < ABS_MAX; i++) { | ||
390 | int diff = input_dev->absmax[ABS_X + i] / 10; | ||
391 | input_dev->absmin[ABS_X + i] += diff; | ||
392 | input_dev->absmax[ABS_X + i] -= diff; | ||
393 | } | ||
394 | #endif | ||
395 | |||
396 | txt = "absolute"; | ||
397 | break; | ||
398 | |||
399 | default: | ||
400 | BUG(); | ||
401 | } | ||
402 | |||
403 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | ||
404 | if (ptr->nbtn) | ||
405 | input_dev->evbit[0] |= BIT_MASK(EV_KEY); | ||
406 | |||
407 | btntype = BTN_MISC; | ||
408 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) | ||
409 | #ifdef TABLET_SIMULATES_MOUSE | ||
410 | btntype = BTN_TOUCH; | ||
411 | #else | ||
412 | btntype = BTN_DIGI; | ||
413 | #endif | ||
414 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) | ||
415 | btntype = BTN_TOUCH; | ||
416 | |||
417 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) | ||
418 | btntype = BTN_MOUSE; | ||
419 | |||
420 | for (i = 0; i < ptr->nbtn; i++) { | ||
421 | __set_bit(btntype | i, input_dev->keybit); | ||
422 | ptr->btnmap[i] = btntype | i; | ||
423 | } | ||
424 | |||
425 | if (btntype == BTN_MOUSE) { | ||
426 | /* Swap buttons 2 and 3 */ | ||
427 | ptr->btnmap[1] = BTN_MIDDLE; | ||
428 | ptr->btnmap[2] = BTN_RIGHT; | ||
429 | } | ||
430 | |||
431 | input_dev->name = strlen(ptr->rnm) ? ptr->rnm : "HIL pointer device"; | ||
432 | |||
433 | printk(KERN_INFO PREFIX | ||
434 | "HIL pointer device found (did: 0x%02x, axis: %s)\n", | ||
435 | did, txt); | ||
436 | printk(KERN_INFO PREFIX | ||
437 | "HIL pointer has %i buttons and %i sets of %i axes\n", | ||
438 | ptr->nbtn, naxsets, ptr->naxes); | ||
439 | } | ||
440 | |||
441 | static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) | ||
442 | { | ||
443 | struct hil_dev *dev; | ||
444 | struct input_dev *input_dev; | ||
445 | uint8_t did, *idd; | ||
446 | int error; | ||
447 | |||
448 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
449 | input_dev = input_allocate_device(); | ||
450 | if (!dev || !input_dev) { | ||
451 | error = -ENOMEM; | ||
272 | goto bail0; | 452 | goto bail0; |
453 | } | ||
273 | 454 | ||
274 | if (serio_open(serio, drv)) | 455 | dev->serio = serio; |
275 | goto bail1; | 456 | dev->dev = input_dev; |
276 | 457 | ||
277 | serio_set_drvdata(serio, kbd); | 458 | error = serio_open(serio, drv); |
278 | kbd->serio = serio; | 459 | if (error) |
460 | goto bail0; | ||
279 | 461 | ||
280 | init_MUTEX_LOCKED(&kbd->sem); | 462 | serio_set_drvdata(serio, dev); |
281 | 463 | ||
282 | /* Get device info. MLC driver supplies devid/status/etc. */ | 464 | /* Get device info. MLC driver supplies devid/status/etc. */ |
283 | serio->write(serio, 0); | 465 | init_completion(&dev->cmd_done); |
284 | serio->write(serio, 0); | 466 | serio_write(serio, 0); |
285 | serio->write(serio, HIL_PKT_CMD >> 8); | 467 | serio_write(serio, 0); |
286 | serio->write(serio, HIL_CMD_IDD); | 468 | serio_write(serio, HIL_PKT_CMD >> 8); |
287 | down(&kbd->sem); | 469 | serio_write(serio, HIL_CMD_IDD); |
288 | 470 | error = wait_for_completion_killable(&dev->cmd_done); | |
289 | serio->write(serio, 0); | 471 | if (error) |
290 | serio->write(serio, 0); | 472 | goto bail1; |
291 | serio->write(serio, HIL_PKT_CMD >> 8); | 473 | |
292 | serio->write(serio, HIL_CMD_RSC); | 474 | init_completion(&dev->cmd_done); |
293 | down(&kbd->sem); | 475 | serio_write(serio, 0); |
294 | 476 | serio_write(serio, 0); | |
295 | serio->write(serio, 0); | 477 | serio_write(serio, HIL_PKT_CMD >> 8); |
296 | serio->write(serio, 0); | 478 | serio_write(serio, HIL_CMD_RSC); |
297 | serio->write(serio, HIL_PKT_CMD >> 8); | 479 | error = wait_for_completion_killable(&dev->cmd_done); |
298 | serio->write(serio, HIL_CMD_RNM); | 480 | if (error) |
299 | down(&kbd->sem); | 481 | goto bail1; |
300 | 482 | ||
301 | serio->write(serio, 0); | 483 | init_completion(&dev->cmd_done); |
302 | serio->write(serio, 0); | 484 | serio_write(serio, 0); |
303 | serio->write(serio, HIL_PKT_CMD >> 8); | 485 | serio_write(serio, 0); |
304 | serio->write(serio, HIL_CMD_EXD); | 486 | serio_write(serio, HIL_PKT_CMD >> 8); |
305 | down(&kbd->sem); | 487 | serio_write(serio, HIL_CMD_RNM); |
306 | 488 | error = wait_for_completion_killable(&dev->cmd_done); | |
307 | up(&kbd->sem); | 489 | if (error) |
308 | 490 | goto bail1; | |
309 | did = kbd->idd[0]; | 491 | |
310 | idd = kbd->idd + 1; | 492 | init_completion(&dev->cmd_done); |
493 | serio_write(serio, 0); | ||
494 | serio_write(serio, 0); | ||
495 | serio_write(serio, HIL_PKT_CMD >> 8); | ||
496 | serio_write(serio, HIL_CMD_EXD); | ||
497 | error = wait_for_completion_killable(&dev->cmd_done); | ||
498 | if (error) | ||
499 | goto bail1; | ||
500 | |||
501 | did = dev->idd[0]; | ||
502 | idd = dev->idd + 1; | ||
503 | |||
311 | switch (did & HIL_IDD_DID_TYPE_MASK) { | 504 | switch (did & HIL_IDD_DID_TYPE_MASK) { |
312 | case HIL_IDD_DID_TYPE_KB_INTEGRAL: | 505 | case HIL_IDD_DID_TYPE_KB_INTEGRAL: |
313 | case HIL_IDD_DID_TYPE_KB_ITF: | 506 | case HIL_IDD_DID_TYPE_KB_ITF: |
314 | case HIL_IDD_DID_TYPE_KB_RSVD: | 507 | case HIL_IDD_DID_TYPE_KB_RSVD: |
315 | case HIL_IDD_DID_TYPE_CHAR: | 508 | case HIL_IDD_DID_TYPE_CHAR: |
316 | printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n", | 509 | if (HIL_IDD_NUM_BUTTONS(idd) || |
317 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); | 510 | HIL_IDD_NUM_AXES_PER_SET(*idd)) { |
318 | break; | 511 | printk(KERN_INFO PREFIX |
319 | default: | 512 | "combo devices are not supported.\n"); |
320 | goto bail2; | 513 | goto bail1; |
321 | } | 514 | } |
322 | 515 | ||
323 | if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { | 516 | dev->is_pointer = false; |
324 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); | 517 | hil_dev_keyboard_setup(dev); |
325 | goto bail2; | 518 | break; |
326 | } | ||
327 | 519 | ||
328 | kbd->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 520 | case HIL_IDD_DID_TYPE_REL: |
329 | kbd->dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | 521 | case HIL_IDD_DID_TYPE_ABS: |
330 | BIT_MASK(LED_SCROLLL); | 522 | dev->is_pointer = true; |
331 | kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 523 | hil_dev_pointer_setup(dev); |
332 | kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); | 524 | break; |
333 | kbd->dev->keycode = hil_kbd_set1; | ||
334 | kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; | ||
335 | kbd->dev->phys = "hpkbd/input0"; /* XXX */ | ||
336 | |||
337 | kbd->dev->id.bustype = BUS_HIL; | ||
338 | kbd->dev->id.vendor = PCI_VENDOR_ID_HP; | ||
339 | kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ | ||
340 | kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | ||
341 | kbd->dev->dev.parent = &serio->dev; | ||
342 | 525 | ||
343 | for (i = 0; i < 128; i++) { | 526 | default: |
344 | set_bit(hil_kbd_set1[i], kbd->dev->keybit); | 527 | goto bail1; |
345 | set_bit(hil_kbd_set3[i], kbd->dev->keybit); | ||
346 | } | 528 | } |
347 | clear_bit(0, kbd->dev->keybit); | ||
348 | 529 | ||
349 | input_register_device(kbd->dev); | 530 | input_dev->id.bustype = BUS_HIL; |
350 | printk(KERN_INFO "input: %s, ID: %d\n", | 531 | input_dev->id.vendor = PCI_VENDOR_ID_HP; |
351 | kbd->dev->name, did); | 532 | input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ |
533 | input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | ||
534 | input_dev->dev.parent = &serio->dev; | ||
535 | |||
536 | if (!dev->is_pointer) { | ||
537 | serio_write(serio, 0); | ||
538 | serio_write(serio, 0); | ||
539 | serio_write(serio, HIL_PKT_CMD >> 8); | ||
540 | /* Enable Keyswitch Autorepeat 1 */ | ||
541 | serio_write(serio, HIL_CMD_EK1); | ||
542 | /* No need to wait for completion */ | ||
543 | } | ||
352 | 544 | ||
353 | serio->write(serio, 0); | 545 | error = input_register_device(input_dev); |
354 | serio->write(serio, 0); | 546 | if (error) |
355 | serio->write(serio, HIL_PKT_CMD >> 8); | 547 | goto bail1; |
356 | serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ | ||
357 | down(&kbd->sem); | ||
358 | up(&kbd->sem); | ||
359 | 548 | ||
360 | return 0; | 549 | return 0; |
361 | bail2: | 550 | |
551 | bail1: | ||
362 | serio_close(serio); | 552 | serio_close(serio); |
363 | serio_set_drvdata(serio, NULL); | 553 | serio_set_drvdata(serio, NULL); |
364 | bail1: | ||
365 | input_free_device(kbd->dev); | ||
366 | bail0: | 554 | bail0: |
367 | kfree(kbd); | 555 | input_free_device(input_dev); |
368 | return -EIO; | 556 | kfree(dev); |
557 | return error; | ||
369 | } | 558 | } |
370 | 559 | ||
371 | static struct serio_device_id hil_kbd_ids[] = { | 560 | static struct serio_device_id hil_dev_ids[] = { |
372 | { | 561 | { |
373 | .type = SERIO_HIL_MLC, | 562 | .type = SERIO_HIL_MLC, |
374 | .proto = SERIO_HIL, | 563 | .proto = SERIO_HIL, |
@@ -378,26 +567,26 @@ static struct serio_device_id hil_kbd_ids[] = { | |||
378 | { 0 } | 567 | { 0 } |
379 | }; | 568 | }; |
380 | 569 | ||
381 | static struct serio_driver hil_kbd_serio_drv = { | 570 | static struct serio_driver hil_serio_drv = { |
382 | .driver = { | 571 | .driver = { |
383 | .name = "hil_kbd", | 572 | .name = "hil_dev", |
384 | }, | 573 | }, |
385 | .description = "HP HIL keyboard driver", | 574 | .description = "HP HIL keyboard/mouse/tablet driver", |
386 | .id_table = hil_kbd_ids, | 575 | .id_table = hil_dev_ids, |
387 | .connect = hil_kbd_connect, | 576 | .connect = hil_dev_connect, |
388 | .disconnect = hil_kbd_disconnect, | 577 | .disconnect = hil_dev_disconnect, |
389 | .interrupt = hil_kbd_interrupt | 578 | .interrupt = hil_dev_interrupt |
390 | }; | 579 | }; |
391 | 580 | ||
392 | static int __init hil_kbd_init(void) | 581 | static int __init hil_dev_init(void) |
393 | { | 582 | { |
394 | return serio_register_driver(&hil_kbd_serio_drv); | 583 | return serio_register_driver(&hil_serio_drv); |
395 | } | 584 | } |
396 | 585 | ||
397 | static void __exit hil_kbd_exit(void) | 586 | static void __exit hil_dev_exit(void) |
398 | { | 587 | { |
399 | serio_unregister_driver(&hil_kbd_serio_drv); | 588 | serio_unregister_driver(&hil_serio_drv); |
400 | } | 589 | } |
401 | 590 | ||
402 | module_init(hil_kbd_init); | 591 | module_init(hil_dev_init); |
403 | module_exit(hil_kbd_exit); | 592 | module_exit(hil_dev_exit); |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 4730ef35c732..f9847e0fb553 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -525,12 +525,12 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
525 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | 525 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); |
526 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | 526 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); |
527 | if (leds_on != 0) { | 527 | if (leds_on != 0) { |
528 | lk->serio->write (lk->serio, LK_CMD_LED_ON); | 528 | serio_write (lk->serio, LK_CMD_LED_ON); |
529 | lk->serio->write (lk->serio, leds_on); | 529 | serio_write (lk->serio, leds_on); |
530 | } | 530 | } |
531 | if (leds_off != 0) { | 531 | if (leds_off != 0) { |
532 | lk->serio->write (lk->serio, LK_CMD_LED_OFF); | 532 | serio_write (lk->serio, LK_CMD_LED_OFF); |
533 | lk->serio->write (lk->serio, leds_off); | 533 | serio_write (lk->serio, leds_off); |
534 | } | 534 | } |
535 | return 0; | 535 | return 0; |
536 | 536 | ||
@@ -539,20 +539,20 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
539 | case SND_CLICK: | 539 | case SND_CLICK: |
540 | if (value == 0) { | 540 | if (value == 0) { |
541 | DBG ("%s: Deactivating key clicks\n", __func__); | 541 | DBG ("%s: Deactivating key clicks\n", __func__); |
542 | lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 542 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); |
543 | lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 543 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); |
544 | } else { | 544 | } else { |
545 | DBG ("%s: Activating key clicks\n", __func__); | 545 | DBG ("%s: Activating key clicks\n", __func__); |
546 | lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 546 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); |
547 | lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 547 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); |
548 | lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 548 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); |
549 | lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | 549 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); |
550 | } | 550 | } |
551 | return 0; | 551 | return 0; |
552 | 552 | ||
553 | case SND_BELL: | 553 | case SND_BELL: |
554 | if (value != 0) | 554 | if (value != 0) |
555 | lk->serio->write (lk->serio, LK_CMD_SOUND_BELL); | 555 | serio_write (lk->serio, LK_CMD_SOUND_BELL); |
556 | 556 | ||
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
@@ -579,10 +579,10 @@ lkkbd_reinit (struct work_struct *work) | |||
579 | unsigned char leds_off = 0; | 579 | unsigned char leds_off = 0; |
580 | 580 | ||
581 | /* Ask for ID */ | 581 | /* Ask for ID */ |
582 | lk->serio->write (lk->serio, LK_CMD_REQUEST_ID); | 582 | serio_write (lk->serio, LK_CMD_REQUEST_ID); |
583 | 583 | ||
584 | /* Reset parameters */ | 584 | /* Reset parameters */ |
585 | lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS); | 585 | serio_write (lk->serio, LK_CMD_SET_DEFAULTS); |
586 | 586 | ||
587 | /* Set LEDs */ | 587 | /* Set LEDs */ |
588 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 588 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); |
@@ -590,12 +590,12 @@ lkkbd_reinit (struct work_struct *work) | |||
590 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | 590 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); |
591 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | 591 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); |
592 | if (leds_on != 0) { | 592 | if (leds_on != 0) { |
593 | lk->serio->write (lk->serio, LK_CMD_LED_ON); | 593 | serio_write (lk->serio, LK_CMD_LED_ON); |
594 | lk->serio->write (lk->serio, leds_on); | 594 | serio_write (lk->serio, leds_on); |
595 | } | 595 | } |
596 | if (leds_off != 0) { | 596 | if (leds_off != 0) { |
597 | lk->serio->write (lk->serio, LK_CMD_LED_OFF); | 597 | serio_write (lk->serio, LK_CMD_LED_OFF); |
598 | lk->serio->write (lk->serio, leds_off); | 598 | serio_write (lk->serio, leds_off); |
599 | } | 599 | } |
600 | 600 | ||
601 | /* | 601 | /* |
@@ -603,31 +603,31 @@ lkkbd_reinit (struct work_struct *work) | |||
603 | * only work with a LK401 keyboard and grants access to | 603 | * only work with a LK401 keyboard and grants access to |
604 | * LAlt, RAlt, RCompose and RShift. | 604 | * LAlt, RAlt, RCompose and RShift. |
605 | */ | 605 | */ |
606 | lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401); | 606 | serio_write (lk->serio, LK_CMD_ENABLE_LK401); |
607 | 607 | ||
608 | /* Set all keys to UPDOWN mode */ | 608 | /* Set all keys to UPDOWN mode */ |
609 | for (division = 1; division <= 14; division++) | 609 | for (division = 1; division <= 14; division++) |
610 | lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN, | 610 | serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN, |
611 | division)); | 611 | division)); |
612 | 612 | ||
613 | /* Enable bell and set volume */ | 613 | /* Enable bell and set volume */ |
614 | lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL); | 614 | serio_write (lk->serio, LK_CMD_ENABLE_BELL); |
615 | lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume)); | 615 | serio_write (lk->serio, volume_to_hw (lk->bell_volume)); |
616 | 616 | ||
617 | /* Enable/disable keyclick (and possibly set volume) */ | 617 | /* Enable/disable keyclick (and possibly set volume) */ |
618 | if (test_bit (SND_CLICK, lk->dev->snd)) { | 618 | if (test_bit (SND_CLICK, lk->dev->snd)) { |
619 | lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 619 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); |
620 | lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 620 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); |
621 | lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 621 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); |
622 | lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | 622 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); |
623 | } else { | 623 | } else { |
624 | lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 624 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); |
625 | lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 625 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); |
626 | } | 626 | } |
627 | 627 | ||
628 | /* Sound the bell if needed */ | 628 | /* Sound the bell if needed */ |
629 | if (test_bit (SND_BELL, lk->dev->snd)) | 629 | if (test_bit (SND_BELL, lk->dev->snd)) |
630 | lk->serio->write (lk->serio, LK_CMD_SOUND_BELL); | 630 | serio_write (lk->serio, LK_CMD_SOUND_BELL); |
631 | } | 631 | } |
632 | 632 | ||
633 | /* | 633 | /* |
@@ -684,8 +684,10 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
684 | input_dev->keycode = lk->keycode; | 684 | input_dev->keycode = lk->keycode; |
685 | input_dev->keycodesize = sizeof (lk_keycode_t); | 685 | input_dev->keycodesize = sizeof (lk_keycode_t); |
686 | input_dev->keycodemax = LK_NUM_KEYCODES; | 686 | input_dev->keycodemax = LK_NUM_KEYCODES; |
687 | |||
687 | for (i = 0; i < LK_NUM_KEYCODES; i++) | 688 | for (i = 0; i < LK_NUM_KEYCODES; i++) |
688 | set_bit (lk->keycode[i], input_dev->keybit); | 689 | __set_bit (lk->keycode[i], input_dev->keybit); |
690 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
689 | 691 | ||
690 | serio_set_drvdata (serio, lk); | 692 | serio_set_drvdata (serio, lk); |
691 | 693 | ||
@@ -697,7 +699,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
697 | if (err) | 699 | if (err) |
698 | goto fail3; | 700 | goto fail3; |
699 | 701 | ||
700 | lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); | 702 | serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET); |
701 | 703 | ||
702 | return 0; | 704 | return 0; |
703 | 705 | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 541b981ff075..91cfe5170265 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -319,7 +319,6 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
319 | struct input_dev *input_dev; | 319 | struct input_dev *input_dev; |
320 | unsigned short *keycodes; | 320 | unsigned short *keycodes; |
321 | unsigned int row_shift; | 321 | unsigned int row_shift; |
322 | int i; | ||
323 | int err; | 322 | int err; |
324 | 323 | ||
325 | pdata = pdev->dev.platform_data; | 324 | pdata = pdev->dev.platform_data; |
@@ -363,18 +362,10 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
363 | 362 | ||
364 | input_dev->keycode = keycodes; | 363 | input_dev->keycode = keycodes; |
365 | input_dev->keycodesize = sizeof(*keycodes); | 364 | input_dev->keycodesize = sizeof(*keycodes); |
366 | input_dev->keycodemax = pdata->num_row_gpios << keypad->row_shift; | 365 | input_dev->keycodemax = pdata->num_row_gpios << row_shift; |
367 | |||
368 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
369 | unsigned int key = keymap_data->keymap[i]; | ||
370 | unsigned int row = KEY_ROW(key); | ||
371 | unsigned int col = KEY_COL(key); | ||
372 | unsigned short code = KEY_VAL(key); | ||
373 | 366 | ||
374 | keycodes[MATRIX_SCAN_CODE(row, col, row_shift)] = code; | 367 | matrix_keypad_build_keymap(keymap_data, row_shift, |
375 | __set_bit(code, input_dev->keybit); | 368 | input_dev->keycode, input_dev->keybit); |
376 | } | ||
377 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
378 | 369 | ||
379 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 370 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
380 | input_set_drvdata(input_dev, keypad); | 371 | input_set_drvdata(input_dev, keypad); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 0d2fc64a5e1c..79cd3e9fdf2e 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Based on a previous implementations by Kevin O'Connor | 9 | * Based on a previous implementations by Kevin O'Connor |
10 | * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and | 10 | * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and |
11 | * on some suggestions by Nicolas Pitre <nico@cam.org>. | 11 | * on some suggestions by Nicolas Pitre <nico@fluxnic.net>. |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
@@ -25,13 +25,13 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | ||
28 | 29 | ||
29 | #include <asm/mach/arch.h> | 30 | #include <asm/mach/arch.h> |
30 | #include <asm/mach/map.h> | 31 | #include <asm/mach/map.h> |
31 | 32 | ||
32 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
33 | #include <mach/pxa27x_keypad.h> | 34 | #include <mach/pxa27x_keypad.h> |
34 | |||
35 | /* | 35 | /* |
36 | * Keypad Controller registers | 36 | * Keypad Controller registers |
37 | */ | 37 | */ |
@@ -95,7 +95,8 @@ | |||
95 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) | 95 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) |
96 | #define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off)) | 96 | #define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off)) |
97 | 97 | ||
98 | #define MAX_MATRIX_KEY_NUM (8 * 8) | 98 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) |
99 | #define MAX_KEYPAD_KEYS (MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM) | ||
99 | 100 | ||
100 | struct pxa27x_keypad { | 101 | struct pxa27x_keypad { |
101 | struct pxa27x_keypad_platform_data *pdata; | 102 | struct pxa27x_keypad_platform_data *pdata; |
@@ -106,73 +107,82 @@ struct pxa27x_keypad { | |||
106 | 107 | ||
107 | int irq; | 108 | int irq; |
108 | 109 | ||
109 | /* matrix key code map */ | 110 | unsigned short keycodes[MAX_KEYPAD_KEYS]; |
110 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; | 111 | int rotary_rel_code[2]; |
111 | 112 | ||
112 | /* state row bits of each column scan */ | 113 | /* state row bits of each column scan */ |
113 | uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; | 114 | uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; |
114 | uint32_t direct_key_state; | 115 | uint32_t direct_key_state; |
115 | 116 | ||
116 | unsigned int direct_key_mask; | 117 | unsigned int direct_key_mask; |
117 | |||
118 | int rotary_rel_code[2]; | ||
119 | int rotary_up_key[2]; | ||
120 | int rotary_down_key[2]; | ||
121 | }; | 118 | }; |
122 | 119 | ||
123 | static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) | 120 | static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) |
124 | { | 121 | { |
125 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 122 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
126 | struct input_dev *input_dev = keypad->input_dev; | 123 | struct input_dev *input_dev = keypad->input_dev; |
127 | unsigned int *key; | 124 | unsigned short keycode; |
128 | int i; | 125 | int i; |
129 | 126 | ||
130 | key = &pdata->matrix_key_map[0]; | 127 | for (i = 0; i < pdata->matrix_key_map_size; i++) { |
131 | for (i = 0; i < pdata->matrix_key_map_size; i++, key++) { | 128 | unsigned int key = pdata->matrix_key_map[i]; |
132 | int row = ((*key) >> 28) & 0xf; | 129 | unsigned int row = KEY_ROW(key); |
133 | int col = ((*key) >> 24) & 0xf; | 130 | unsigned int col = KEY_COL(key); |
134 | int code = (*key) & 0xffffff; | 131 | unsigned int scancode = MATRIX_SCAN_CODE(row, col, |
132 | MATRIX_ROW_SHIFT); | ||
135 | 133 | ||
136 | keypad->matrix_keycodes[(row << 3) + col] = code; | 134 | keycode = KEY_VAL(key); |
137 | set_bit(code, input_dev->keybit); | 135 | keypad->keycodes[scancode] = keycode; |
136 | __set_bit(keycode, input_dev->keybit); | ||
138 | } | 137 | } |
139 | 138 | ||
140 | for (i = 0; i < pdata->direct_key_num; i++) | 139 | for (i = 0; i < pdata->direct_key_num; i++) { |
141 | set_bit(pdata->direct_key_map[i], input_dev->keybit); | 140 | keycode = pdata->direct_key_map[i]; |
142 | 141 | keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode; | |
143 | keypad->rotary_up_key[0] = pdata->rotary0_up_key; | 142 | __set_bit(keycode, input_dev->keybit); |
144 | keypad->rotary_up_key[1] = pdata->rotary1_up_key; | 143 | } |
145 | keypad->rotary_down_key[0] = pdata->rotary0_down_key; | ||
146 | keypad->rotary_down_key[1] = pdata->rotary1_down_key; | ||
147 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; | ||
148 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; | ||
149 | 144 | ||
150 | if (pdata->enable_rotary0) { | 145 | if (pdata->enable_rotary0) { |
151 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { | 146 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { |
152 | set_bit(pdata->rotary0_up_key, input_dev->keybit); | 147 | keycode = pdata->rotary0_up_key; |
153 | set_bit(pdata->rotary0_down_key, input_dev->keybit); | 148 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 0] = keycode; |
154 | } else | 149 | __set_bit(keycode, input_dev->keybit); |
155 | set_bit(pdata->rotary0_rel_code, input_dev->relbit); | 150 | |
151 | keycode = pdata->rotary0_down_key; | ||
152 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 1] = keycode; | ||
153 | __set_bit(keycode, input_dev->keybit); | ||
154 | |||
155 | keypad->rotary_rel_code[0] = -1; | ||
156 | } else { | ||
157 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; | ||
158 | __set_bit(pdata->rotary0_rel_code, input_dev->relbit); | ||
159 | } | ||
156 | } | 160 | } |
157 | 161 | ||
158 | if (pdata->enable_rotary1) { | 162 | if (pdata->enable_rotary1) { |
159 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { | 163 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { |
160 | set_bit(pdata->rotary1_up_key, input_dev->keybit); | 164 | keycode = pdata->rotary1_up_key; |
161 | set_bit(pdata->rotary1_down_key, input_dev->keybit); | 165 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 2] = keycode; |
162 | } else | 166 | __set_bit(keycode, input_dev->keybit); |
163 | set_bit(pdata->rotary1_rel_code, input_dev->relbit); | 167 | |
168 | keycode = pdata->rotary1_down_key; | ||
169 | keypad->keycodes[MAX_MATRIX_KEY_NUM + 3] = keycode; | ||
170 | __set_bit(keycode, input_dev->keybit); | ||
171 | |||
172 | keypad->rotary_rel_code[1] = -1; | ||
173 | } else { | ||
174 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; | ||
175 | __set_bit(pdata->rotary1_rel_code, input_dev->relbit); | ||
176 | } | ||
164 | } | 177 | } |
165 | } | ||
166 | 178 | ||
167 | static inline unsigned int lookup_matrix_keycode( | 179 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
168 | struct pxa27x_keypad *keypad, int row, int col) | ||
169 | { | ||
170 | return keypad->matrix_keycodes[(row << 3) + col]; | ||
171 | } | 180 | } |
172 | 181 | ||
173 | static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) | 182 | static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) |
174 | { | 183 | { |
175 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 184 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
185 | struct input_dev *input_dev = keypad->input_dev; | ||
176 | int row, col, num_keys_pressed = 0; | 186 | int row, col, num_keys_pressed = 0; |
177 | uint32_t new_state[MAX_MATRIX_KEY_COLS]; | 187 | uint32_t new_state[MAX_MATRIX_KEY_COLS]; |
178 | uint32_t kpas = keypad_readl(KPAS); | 188 | uint32_t kpas = keypad_readl(KPAS); |
@@ -215,6 +225,7 @@ static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) | |||
215 | scan: | 225 | scan: |
216 | for (col = 0; col < pdata->matrix_key_cols; col++) { | 226 | for (col = 0; col < pdata->matrix_key_cols; col++) { |
217 | uint32_t bits_changed; | 227 | uint32_t bits_changed; |
228 | int code; | ||
218 | 229 | ||
219 | bits_changed = keypad->matrix_key_state[col] ^ new_state[col]; | 230 | bits_changed = keypad->matrix_key_state[col] ^ new_state[col]; |
220 | if (bits_changed == 0) | 231 | if (bits_changed == 0) |
@@ -224,12 +235,13 @@ scan: | |||
224 | if ((bits_changed & (1 << row)) == 0) | 235 | if ((bits_changed & (1 << row)) == 0) |
225 | continue; | 236 | continue; |
226 | 237 | ||
227 | input_report_key(keypad->input_dev, | 238 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); |
228 | lookup_matrix_keycode(keypad, row, col), | 239 | input_event(input_dev, EV_MSC, MSC_SCAN, code); |
229 | new_state[col] & (1 << row)); | 240 | input_report_key(input_dev, keypad->keycodes[code], |
241 | new_state[col] & (1 << row)); | ||
230 | } | 242 | } |
231 | } | 243 | } |
232 | input_sync(keypad->input_dev); | 244 | input_sync(input_dev); |
233 | memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); | 245 | memcpy(keypad->matrix_key_state, new_state, sizeof(new_state)); |
234 | } | 246 | } |
235 | 247 | ||
@@ -252,13 +264,15 @@ static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta) | |||
252 | if (delta == 0) | 264 | if (delta == 0) |
253 | return; | 265 | return; |
254 | 266 | ||
255 | if (keypad->rotary_up_key[r] && keypad->rotary_down_key[r]) { | 267 | if (keypad->rotary_rel_code[r] == -1) { |
256 | int keycode = (delta > 0) ? keypad->rotary_up_key[r] : | 268 | int code = MAX_MATRIX_KEY_NUM + 2 * r + (delta > 0 ? 0 : 1); |
257 | keypad->rotary_down_key[r]; | 269 | unsigned char keycode = keypad->keycodes[code]; |
258 | 270 | ||
259 | /* simulate a press-n-release */ | 271 | /* simulate a press-n-release */ |
272 | input_event(dev, EV_MSC, MSC_SCAN, code); | ||
260 | input_report_key(dev, keycode, 1); | 273 | input_report_key(dev, keycode, 1); |
261 | input_sync(dev); | 274 | input_sync(dev); |
275 | input_event(dev, EV_MSC, MSC_SCAN, code); | ||
262 | input_report_key(dev, keycode, 0); | 276 | input_report_key(dev, keycode, 0); |
263 | input_sync(dev); | 277 | input_sync(dev); |
264 | } else { | 278 | } else { |
@@ -286,6 +300,7 @@ static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad) | |||
286 | static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | 300 | static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) |
287 | { | 301 | { |
288 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 302 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
303 | struct input_dev *input_dev = keypad->input_dev; | ||
289 | unsigned int new_state; | 304 | unsigned int new_state; |
290 | uint32_t kpdk, bits_changed; | 305 | uint32_t kpdk, bits_changed; |
291 | int i; | 306 | int i; |
@@ -295,9 +310,6 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
295 | if (pdata->enable_rotary0 || pdata->enable_rotary1) | 310 | if (pdata->enable_rotary0 || pdata->enable_rotary1) |
296 | pxa27x_keypad_scan_rotary(keypad); | 311 | pxa27x_keypad_scan_rotary(keypad); |
297 | 312 | ||
298 | if (pdata->direct_key_map == NULL) | ||
299 | return; | ||
300 | |||
301 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; | 313 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; |
302 | bits_changed = keypad->direct_key_state ^ new_state; | 314 | bits_changed = keypad->direct_key_state ^ new_state; |
303 | 315 | ||
@@ -305,12 +317,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
305 | return; | 317 | return; |
306 | 318 | ||
307 | for (i = 0; i < pdata->direct_key_num; i++) { | 319 | for (i = 0; i < pdata->direct_key_num; i++) { |
308 | if (bits_changed & (1 << i)) | 320 | if (bits_changed & (1 << i)) { |
309 | input_report_key(keypad->input_dev, | 321 | int code = MAX_MATRIX_KEY_NUM + i; |
310 | pdata->direct_key_map[i], | 322 | |
311 | (new_state & (1 << i))); | 323 | input_event(input_dev, EV_MSC, MSC_SCAN, code); |
324 | input_report_key(input_dev, keypad->keycodes[code], | ||
325 | new_state & (1 << i)); | ||
326 | } | ||
312 | } | 327 | } |
313 | input_sync(keypad->input_dev); | 328 | input_sync(input_dev); |
314 | keypad->direct_key_state = new_state; | 329 | keypad->direct_key_state = new_state; |
315 | } | 330 | } |
316 | 331 | ||
@@ -388,8 +403,9 @@ static void pxa27x_keypad_close(struct input_dev *dev) | |||
388 | } | 403 | } |
389 | 404 | ||
390 | #ifdef CONFIG_PM | 405 | #ifdef CONFIG_PM |
391 | static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 406 | static int pxa27x_keypad_suspend(struct device *dev) |
392 | { | 407 | { |
408 | struct platform_device *pdev = to_platform_device(dev); | ||
393 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 409 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
394 | 410 | ||
395 | clk_disable(keypad->clk); | 411 | clk_disable(keypad->clk); |
@@ -400,8 +416,9 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat | |||
400 | return 0; | 416 | return 0; |
401 | } | 417 | } |
402 | 418 | ||
403 | static int pxa27x_keypad_resume(struct platform_device *pdev) | 419 | static int pxa27x_keypad_resume(struct device *dev) |
404 | { | 420 | { |
421 | struct platform_device *pdev = to_platform_device(dev); | ||
405 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 422 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
406 | struct input_dev *input_dev = keypad->input_dev; | 423 | struct input_dev *input_dev = keypad->input_dev; |
407 | 424 | ||
@@ -420,55 +437,58 @@ static int pxa27x_keypad_resume(struct platform_device *pdev) | |||
420 | 437 | ||
421 | return 0; | 438 | return 0; |
422 | } | 439 | } |
423 | #else | ||
424 | #define pxa27x_keypad_suspend NULL | ||
425 | #define pxa27x_keypad_resume NULL | ||
426 | #endif | ||
427 | 440 | ||
428 | #define res_size(res) ((res)->end - (res)->start + 1) | 441 | static const struct dev_pm_ops pxa27x_keypad_pm_ops = { |
442 | .suspend = pxa27x_keypad_suspend, | ||
443 | .resume = pxa27x_keypad_resume, | ||
444 | }; | ||
445 | #endif | ||
429 | 446 | ||
430 | static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | 447 | static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) |
431 | { | 448 | { |
449 | struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; | ||
432 | struct pxa27x_keypad *keypad; | 450 | struct pxa27x_keypad *keypad; |
433 | struct input_dev *input_dev; | 451 | struct input_dev *input_dev; |
434 | struct resource *res; | 452 | struct resource *res; |
435 | int irq, error; | 453 | int irq, error; |
436 | 454 | ||
437 | keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); | 455 | if (pdata == NULL) { |
438 | if (keypad == NULL) { | ||
439 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
440 | return -ENOMEM; | ||
441 | } | ||
442 | |||
443 | keypad->pdata = pdev->dev.platform_data; | ||
444 | if (keypad->pdata == NULL) { | ||
445 | dev_err(&pdev->dev, "no platform data defined\n"); | 456 | dev_err(&pdev->dev, "no platform data defined\n"); |
446 | error = -EINVAL; | 457 | return -EINVAL; |
447 | goto failed_free; | ||
448 | } | 458 | } |
449 | 459 | ||
450 | irq = platform_get_irq(pdev, 0); | 460 | irq = platform_get_irq(pdev, 0); |
451 | if (irq < 0) { | 461 | if (irq < 0) { |
452 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | 462 | dev_err(&pdev->dev, "failed to get keypad irq\n"); |
453 | error = -ENXIO; | 463 | return -ENXIO; |
454 | goto failed_free; | ||
455 | } | 464 | } |
456 | 465 | ||
457 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 466 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
458 | if (res == NULL) { | 467 | if (res == NULL) { |
459 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | 468 | dev_err(&pdev->dev, "failed to get I/O memory\n"); |
460 | error = -ENXIO; | 469 | return -ENXIO; |
470 | } | ||
471 | |||
472 | keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); | ||
473 | input_dev = input_allocate_device(); | ||
474 | if (!keypad || !input_dev) { | ||
475 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
476 | error = -ENOMEM; | ||
461 | goto failed_free; | 477 | goto failed_free; |
462 | } | 478 | } |
463 | 479 | ||
464 | res = request_mem_region(res->start, res_size(res), pdev->name); | 480 | keypad->pdata = pdata; |
481 | keypad->input_dev = input_dev; | ||
482 | keypad->irq = irq; | ||
483 | |||
484 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
465 | if (res == NULL) { | 485 | if (res == NULL) { |
466 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 486 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
467 | error = -EBUSY; | 487 | error = -EBUSY; |
468 | goto failed_free; | 488 | goto failed_free; |
469 | } | 489 | } |
470 | 490 | ||
471 | keypad->mmio_base = ioremap(res->start, res_size(res)); | 491 | keypad->mmio_base = ioremap(res->start, resource_size(res)); |
472 | if (keypad->mmio_base == NULL) { | 492 | if (keypad->mmio_base == NULL) { |
473 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 493 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
474 | error = -ENXIO; | 494 | error = -ENXIO; |
@@ -482,43 +502,35 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | |||
482 | goto failed_free_io; | 502 | goto failed_free_io; |
483 | } | 503 | } |
484 | 504 | ||
485 | /* Create and register the input driver. */ | ||
486 | input_dev = input_allocate_device(); | ||
487 | if (!input_dev) { | ||
488 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
489 | error = -ENOMEM; | ||
490 | goto failed_put_clk; | ||
491 | } | ||
492 | |||
493 | input_dev->name = pdev->name; | 505 | input_dev->name = pdev->name; |
494 | input_dev->id.bustype = BUS_HOST; | 506 | input_dev->id.bustype = BUS_HOST; |
495 | input_dev->open = pxa27x_keypad_open; | 507 | input_dev->open = pxa27x_keypad_open; |
496 | input_dev->close = pxa27x_keypad_close; | 508 | input_dev->close = pxa27x_keypad_close; |
497 | input_dev->dev.parent = &pdev->dev; | 509 | input_dev->dev.parent = &pdev->dev; |
498 | 510 | ||
499 | keypad->input_dev = input_dev; | 511 | input_dev->keycode = keypad->keycodes; |
512 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
513 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
514 | |||
500 | input_set_drvdata(input_dev, keypad); | 515 | input_set_drvdata(input_dev, keypad); |
501 | 516 | ||
502 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 517 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
503 | if ((keypad->pdata->enable_rotary0 && | 518 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
504 | keypad->pdata->rotary0_rel_code) || | ||
505 | (keypad->pdata->enable_rotary1 && | ||
506 | keypad->pdata->rotary1_rel_code)) { | ||
507 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | ||
508 | } | ||
509 | 519 | ||
510 | pxa27x_keypad_build_keycode(keypad); | 520 | pxa27x_keypad_build_keycode(keypad); |
511 | platform_set_drvdata(pdev, keypad); | 521 | |
522 | if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || | ||
523 | (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { | ||
524 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | ||
525 | } | ||
512 | 526 | ||
513 | error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, | 527 | error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, |
514 | pdev->name, keypad); | 528 | pdev->name, keypad); |
515 | if (error) { | 529 | if (error) { |
516 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 530 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
517 | goto failed_free_dev; | 531 | goto failed_put_clk; |
518 | } | 532 | } |
519 | 533 | ||
520 | keypad->irq = irq; | ||
521 | |||
522 | /* Register the input device */ | 534 | /* Register the input device */ |
523 | error = input_register_device(input_dev); | 535 | error = input_register_device(input_dev); |
524 | if (error) { | 536 | if (error) { |
@@ -526,22 +538,21 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | |||
526 | goto failed_free_irq; | 538 | goto failed_free_irq; |
527 | } | 539 | } |
528 | 540 | ||
541 | platform_set_drvdata(pdev, keypad); | ||
529 | device_init_wakeup(&pdev->dev, 1); | 542 | device_init_wakeup(&pdev->dev, 1); |
530 | 543 | ||
531 | return 0; | 544 | return 0; |
532 | 545 | ||
533 | failed_free_irq: | 546 | failed_free_irq: |
534 | free_irq(irq, pdev); | 547 | free_irq(irq, pdev); |
535 | platform_set_drvdata(pdev, NULL); | ||
536 | failed_free_dev: | ||
537 | input_free_device(input_dev); | ||
538 | failed_put_clk: | 548 | failed_put_clk: |
539 | clk_put(keypad->clk); | 549 | clk_put(keypad->clk); |
540 | failed_free_io: | 550 | failed_free_io: |
541 | iounmap(keypad->mmio_base); | 551 | iounmap(keypad->mmio_base); |
542 | failed_free_mem: | 552 | failed_free_mem: |
543 | release_mem_region(res->start, res_size(res)); | 553 | release_mem_region(res->start, resource_size(res)); |
544 | failed_free: | 554 | failed_free: |
555 | input_free_device(input_dev); | ||
545 | kfree(keypad); | 556 | kfree(keypad); |
546 | return error; | 557 | return error; |
547 | } | 558 | } |
@@ -552,8 +563,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
552 | struct resource *res; | 563 | struct resource *res; |
553 | 564 | ||
554 | free_irq(keypad->irq, pdev); | 565 | free_irq(keypad->irq, pdev); |
555 | |||
556 | clk_disable(keypad->clk); | ||
557 | clk_put(keypad->clk); | 566 | clk_put(keypad->clk); |
558 | 567 | ||
559 | input_unregister_device(keypad->input_dev); | 568 | input_unregister_device(keypad->input_dev); |
@@ -562,10 +571,11 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
562 | iounmap(keypad->mmio_base); | 571 | iounmap(keypad->mmio_base); |
563 | 572 | ||
564 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 573 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
565 | release_mem_region(res->start, res_size(res)); | 574 | release_mem_region(res->start, resource_size(res)); |
566 | 575 | ||
567 | platform_set_drvdata(pdev, NULL); | 576 | platform_set_drvdata(pdev, NULL); |
568 | kfree(keypad); | 577 | kfree(keypad); |
578 | |||
569 | return 0; | 579 | return 0; |
570 | } | 580 | } |
571 | 581 | ||
@@ -575,11 +585,12 @@ MODULE_ALIAS("platform:pxa27x-keypad"); | |||
575 | static struct platform_driver pxa27x_keypad_driver = { | 585 | static struct platform_driver pxa27x_keypad_driver = { |
576 | .probe = pxa27x_keypad_probe, | 586 | .probe = pxa27x_keypad_probe, |
577 | .remove = __devexit_p(pxa27x_keypad_remove), | 587 | .remove = __devexit_p(pxa27x_keypad_remove), |
578 | .suspend = pxa27x_keypad_suspend, | ||
579 | .resume = pxa27x_keypad_resume, | ||
580 | .driver = { | 588 | .driver = { |
581 | .name = "pxa27x-keypad", | 589 | .name = "pxa27x-keypad", |
582 | .owner = THIS_MODULE, | 590 | .owner = THIS_MODULE, |
591 | #ifdef CONFIG_PM | ||
592 | .pm = &pxa27x_keypad_pm_ops, | ||
593 | #endif | ||
583 | }, | 594 | }, |
584 | }; | 595 | }; |
585 | 596 | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 68fd502fcfef..887af79b7bff 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -131,7 +131,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
131 | struct resource *res; | 131 | struct resource *res; |
132 | struct input_dev *input; | 132 | struct input_dev *input; |
133 | char clk_name[8]; | 133 | char clk_name[8]; |
134 | int i, k; | 134 | int i; |
135 | int irq, error; | 135 | int irq, error; |
136 | 136 | ||
137 | if (!pdev->dev.platform_data) { | 137 | if (!pdev->dev.platform_data) { |
@@ -198,17 +198,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
198 | input->id.product = 0x0001; | 198 | input->id.product = 0x0001; |
199 | input->id.version = 0x0100; | 199 | input->id.version = 0x0100; |
200 | 200 | ||
201 | input->keycode = pdata->keycodes; | ||
202 | input->keycodesize = sizeof(pdata->keycodes[0]); | ||
203 | input->keycodemax = ARRAY_SIZE(pdata->keycodes); | ||
204 | |||
201 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); | 205 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); |
202 | if (error) { | 206 | if (error) { |
203 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 207 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
204 | goto err4; | 208 | goto err4; |
205 | } | 209 | } |
206 | 210 | ||
207 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 211 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) |
208 | k = pdata->keycodes[i]; | 212 | __set_bit(pdata->keycodes[i], input->keybit); |
209 | if (k) | 213 | __clear_bit(KEY_RESERVED, input->keybit); |
210 | input_set_capability(input, EV_KEY, k); | ||
211 | } | ||
212 | 214 | ||
213 | error = input_register_device(input); | 215 | error = input_register_device(input); |
214 | if (error) { | 216 | if (error) { |
@@ -224,7 +226,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
224 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | 226 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); |
225 | 227 | ||
226 | device_init_wakeup(&pdev->dev, 1); | 228 | device_init_wakeup(&pdev->dev, 1); |
229 | |||
227 | return 0; | 230 | return 0; |
231 | |||
228 | err5: | 232 | err5: |
229 | free_irq(irq, pdev); | 233 | free_irq(irq, pdev); |
230 | err4: | 234 | err4: |
@@ -255,6 +259,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
255 | 259 | ||
256 | platform_set_drvdata(pdev, NULL); | 260 | platform_set_drvdata(pdev, NULL); |
257 | kfree(priv); | 261 | kfree(priv); |
262 | |||
258 | return 0; | 263 | return 0; |
259 | } | 264 | } |
260 | 265 | ||
@@ -270,11 +275,12 @@ static int sh_keysc_suspend(struct device *dev) | |||
270 | if (device_may_wakeup(dev)) { | 275 | if (device_may_wakeup(dev)) { |
271 | value |= 0x80; | 276 | value |= 0x80; |
272 | enable_irq_wake(irq); | 277 | enable_irq_wake(irq); |
273 | } | 278 | } else { |
274 | else | ||
275 | value &= ~0x80; | 279 | value &= ~0x80; |
280 | } | ||
276 | 281 | ||
277 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | 282 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); |
283 | |||
278 | return 0; | 284 | return 0; |
279 | } | 285 | } |
280 | 286 | ||
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 9fce6d1e29b2..472b56639cdb 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -73,7 +73,7 @@ static unsigned char sunkbd_keycode[128] = { | |||
73 | */ | 73 | */ |
74 | 74 | ||
75 | struct sunkbd { | 75 | struct sunkbd { |
76 | unsigned char keycode[128]; | 76 | unsigned char keycode[ARRAY_SIZE(sunkbd_keycode)]; |
77 | struct input_dev *dev; | 77 | struct input_dev *dev; |
78 | struct serio *serio; | 78 | struct serio *serio; |
79 | struct work_struct tq; | 79 | struct work_struct tq; |
@@ -81,7 +81,7 @@ struct sunkbd { | |||
81 | char name[64]; | 81 | char name[64]; |
82 | char phys[32]; | 82 | char phys[32]; |
83 | char type; | 83 | char type; |
84 | unsigned char enabled; | 84 | bool enabled; |
85 | volatile s8 reset; | 85 | volatile s8 reset; |
86 | volatile s8 layout; | 86 | volatile s8 layout; |
87 | }; | 87 | }; |
@@ -94,10 +94,14 @@ struct sunkbd { | |||
94 | static irqreturn_t sunkbd_interrupt(struct serio *serio, | 94 | static irqreturn_t sunkbd_interrupt(struct serio *serio, |
95 | unsigned char data, unsigned int flags) | 95 | unsigned char data, unsigned int flags) |
96 | { | 96 | { |
97 | struct sunkbd* sunkbd = serio_get_drvdata(serio); | 97 | struct sunkbd *sunkbd = serio_get_drvdata(serio); |
98 | 98 | ||
99 | if (sunkbd->reset <= -1) { /* If cp[i] is 0xff, sunkbd->reset will stay -1. */ | 99 | if (sunkbd->reset <= -1) { |
100 | sunkbd->reset = data; /* The keyboard sends 0xff 0xff 0xID on powerup */ | 100 | /* |
101 | * If cp[i] is 0xff, sunkbd->reset will stay -1. | ||
102 | * The keyboard sends 0xff 0xff 0xID on powerup. | ||
103 | */ | ||
104 | sunkbd->reset = data; | ||
101 | wake_up_interruptible(&sunkbd->wait); | 105 | wake_up_interruptible(&sunkbd->wait); |
102 | goto out; | 106 | goto out; |
103 | } | 107 | } |
@@ -110,29 +114,33 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio, | |||
110 | 114 | ||
111 | switch (data) { | 115 | switch (data) { |
112 | 116 | ||
113 | case SUNKBD_RET_RESET: | 117 | case SUNKBD_RET_RESET: |
114 | schedule_work(&sunkbd->tq); | 118 | schedule_work(&sunkbd->tq); |
115 | sunkbd->reset = -1; | 119 | sunkbd->reset = -1; |
116 | break; | 120 | break; |
117 | 121 | ||
118 | case SUNKBD_RET_LAYOUT: | 122 | case SUNKBD_RET_LAYOUT: |
119 | sunkbd->layout = -1; | 123 | sunkbd->layout = -1; |
120 | break; | 124 | break; |
125 | |||
126 | case SUNKBD_RET_ALLUP: /* All keys released */ | ||
127 | break; | ||
121 | 128 | ||
122 | case SUNKBD_RET_ALLUP: /* All keys released */ | 129 | default: |
130 | if (!sunkbd->enabled) | ||
123 | break; | 131 | break; |
124 | 132 | ||
125 | default: | 133 | if (sunkbd->keycode[data & SUNKBD_KEY]) { |
126 | if (!sunkbd->enabled) | 134 | input_report_key(sunkbd->dev, |
127 | break; | 135 | sunkbd->keycode[data & SUNKBD_KEY], |
128 | 136 | !(data & SUNKBD_RELEASE)); | |
129 | if (sunkbd->keycode[data & SUNKBD_KEY]) { | 137 | input_sync(sunkbd->dev); |
130 | input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); | 138 | } else { |
131 | input_sync(sunkbd->dev); | 139 | printk(KERN_WARNING |
132 | } else { | 140 | "sunkbd.c: Unknown key (scancode %#x) %s.\n", |
133 | printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n", | 141 | data & SUNKBD_KEY, |
134 | data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed"); | 142 | data & SUNKBD_RELEASE ? "released" : "pressed"); |
135 | } | 143 | } |
136 | } | 144 | } |
137 | out: | 145 | out: |
138 | return IRQ_HANDLED; | 146 | return IRQ_HANDLED; |
@@ -142,34 +150,37 @@ out: | |||
142 | * sunkbd_event() handles events from the input module. | 150 | * sunkbd_event() handles events from the input module. |
143 | */ | 151 | */ |
144 | 152 | ||
145 | static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 153 | static int sunkbd_event(struct input_dev *dev, |
154 | unsigned int type, unsigned int code, int value) | ||
146 | { | 155 | { |
147 | struct sunkbd *sunkbd = input_get_drvdata(dev); | 156 | struct sunkbd *sunkbd = input_get_drvdata(dev); |
148 | 157 | ||
149 | switch (type) { | 158 | switch (type) { |
150 | 159 | ||
151 | case EV_LED: | 160 | case EV_LED: |
152 | 161 | ||
153 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED); | 162 | serio_write(sunkbd->serio, SUNKBD_CMD_SETLED); |
154 | sunkbd->serio->write(sunkbd->serio, | 163 | serio_write(sunkbd->serio, |
155 | (!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) | | 164 | (!!test_bit(LED_CAPSL, dev->led) << 3) | |
156 | (!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led)); | 165 | (!!test_bit(LED_SCROLLL, dev->led) << 2) | |
157 | return 0; | 166 | (!!test_bit(LED_COMPOSE, dev->led) << 1) | |
167 | !!test_bit(LED_NUML, dev->led)); | ||
168 | return 0; | ||
158 | 169 | ||
159 | case EV_SND: | 170 | case EV_SND: |
160 | 171 | ||
161 | switch (code) { | 172 | switch (code) { |
162 | 173 | ||
163 | case SND_CLICK: | 174 | case SND_CLICK: |
164 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value); | 175 | serio_write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value); |
165 | return 0; | 176 | return 0; |
166 | 177 | ||
167 | case SND_BELL: | 178 | case SND_BELL: |
168 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value); | 179 | serio_write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value); |
169 | return 0; | 180 | return 0; |
170 | } | 181 | } |
171 | 182 | ||
172 | break; | 183 | break; |
173 | } | 184 | } |
174 | 185 | ||
175 | return -1; | 186 | return -1; |
@@ -183,7 +194,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c | |||
183 | static int sunkbd_initialize(struct sunkbd *sunkbd) | 194 | static int sunkbd_initialize(struct sunkbd *sunkbd) |
184 | { | 195 | { |
185 | sunkbd->reset = -2; | 196 | sunkbd->reset = -2; |
186 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET); | 197 | serio_write(sunkbd->serio, SUNKBD_CMD_RESET); |
187 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); | 198 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); |
188 | if (sunkbd->reset < 0) | 199 | if (sunkbd->reset < 0) |
189 | return -1; | 200 | return -1; |
@@ -192,10 +203,13 @@ static int sunkbd_initialize(struct sunkbd *sunkbd) | |||
192 | 203 | ||
193 | if (sunkbd->type == 4) { /* Type 4 keyboard */ | 204 | if (sunkbd->type == 4) { /* Type 4 keyboard */ |
194 | sunkbd->layout = -2; | 205 | sunkbd->layout = -2; |
195 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_LAYOUT); | 206 | serio_write(sunkbd->serio, SUNKBD_CMD_LAYOUT); |
196 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->layout >= 0, HZ/4); | 207 | wait_event_interruptible_timeout(sunkbd->wait, |
197 | if (sunkbd->layout < 0) return -1; | 208 | sunkbd->layout >= 0, HZ / 4); |
198 | if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) sunkbd->type = 5; | 209 | if (sunkbd->layout < 0) |
210 | return -1; | ||
211 | if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) | ||
212 | sunkbd->type = 5; | ||
199 | } | 213 | } |
200 | 214 | ||
201 | return 0; | 215 | return 0; |
@@ -212,15 +226,19 @@ static void sunkbd_reinit(struct work_struct *work) | |||
212 | 226 | ||
213 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); | 227 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); |
214 | 228 | ||
215 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED); | 229 | serio_write(sunkbd->serio, SUNKBD_CMD_SETLED); |
216 | sunkbd->serio->write(sunkbd->serio, | 230 | serio_write(sunkbd->serio, |
217 | (!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) | | 231 | (!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | |
218 | (!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led)); | 232 | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) | |
219 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd)); | 233 | (!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | |
220 | sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd)); | 234 | !!test_bit(LED_NUML, sunkbd->dev->led)); |
235 | serio_write(sunkbd->serio, | ||
236 | SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd)); | ||
237 | serio_write(sunkbd->serio, | ||
238 | SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd)); | ||
221 | } | 239 | } |
222 | 240 | ||
223 | static void sunkbd_enable(struct sunkbd *sunkbd, int enable) | 241 | static void sunkbd_enable(struct sunkbd *sunkbd, bool enable) |
224 | { | 242 | { |
225 | serio_pause_rx(sunkbd->serio); | 243 | serio_pause_rx(sunkbd->serio); |
226 | sunkbd->enabled = enable; | 244 | sunkbd->enabled = enable; |
@@ -228,7 +246,8 @@ static void sunkbd_enable(struct sunkbd *sunkbd, int enable) | |||
228 | } | 246 | } |
229 | 247 | ||
230 | /* | 248 | /* |
231 | * sunkbd_connect() probes for a Sun keyboard and fills the necessary structures. | 249 | * sunkbd_connect() probes for a Sun keyboard and fills the necessary |
250 | * structures. | ||
232 | */ | 251 | */ |
233 | 252 | ||
234 | static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | 253 | static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) |
@@ -260,7 +279,8 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
260 | goto fail3; | 279 | goto fail3; |
261 | } | 280 | } |
262 | 281 | ||
263 | snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); | 282 | snprintf(sunkbd->name, sizeof(sunkbd->name), |
283 | "Sun Type %d keyboard", sunkbd->type); | ||
264 | memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); | 284 | memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); |
265 | 285 | ||
266 | input_dev->name = sunkbd->name; | 286 | input_dev->name = sunkbd->name; |
@@ -284,11 +304,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
284 | input_dev->keycode = sunkbd->keycode; | 304 | input_dev->keycode = sunkbd->keycode; |
285 | input_dev->keycodesize = sizeof(unsigned char); | 305 | input_dev->keycodesize = sizeof(unsigned char); |
286 | input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode); | 306 | input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode); |
287 | for (i = 0; i < 128; i++) | 307 | for (i = 0; i < ARRAY_SIZE(sunkbd_keycode); i++) |
288 | set_bit(sunkbd->keycode[i], input_dev->keybit); | 308 | __set_bit(sunkbd->keycode[i], input_dev->keybit); |
289 | clear_bit(0, input_dev->keybit); | 309 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
290 | 310 | ||
291 | sunkbd_enable(sunkbd, 1); | 311 | sunkbd_enable(sunkbd, true); |
292 | 312 | ||
293 | err = input_register_device(sunkbd->dev); | 313 | err = input_register_device(sunkbd->dev); |
294 | if (err) | 314 | if (err) |
@@ -296,7 +316,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
296 | 316 | ||
297 | return 0; | 317 | return 0; |
298 | 318 | ||
299 | fail4: sunkbd_enable(sunkbd, 0); | 319 | fail4: sunkbd_enable(sunkbd, false); |
300 | fail3: serio_close(serio); | 320 | fail3: serio_close(serio); |
301 | fail2: serio_set_drvdata(serio, NULL); | 321 | fail2: serio_set_drvdata(serio, NULL); |
302 | fail1: input_free_device(input_dev); | 322 | fail1: input_free_device(input_dev); |
@@ -312,7 +332,7 @@ static void sunkbd_disconnect(struct serio *serio) | |||
312 | { | 332 | { |
313 | struct sunkbd *sunkbd = serio_get_drvdata(serio); | 333 | struct sunkbd *sunkbd = serio_get_drvdata(serio); |
314 | 334 | ||
315 | sunkbd_enable(sunkbd, 0); | 335 | sunkbd_enable(sunkbd, false); |
316 | input_unregister_device(sunkbd->dev); | 336 | input_unregister_device(sunkbd->dev); |
317 | serio_close(serio); | 337 | serio_close(serio); |
318 | serio_set_drvdata(serio, NULL); | 338 | serio_set_drvdata(serio, NULL); |
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 677276b12020..42cb3faf7336 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define KB_DISCHARGE_DELAY 10 | 31 | #define KB_DISCHARGE_DELAY 10 |
32 | #define KB_ACTIVATE_DELAY 10 | 32 | #define KB_ACTIVATE_DELAY 10 |
33 | 33 | ||
34 | static unsigned int tosakbd_keycode[NR_SCANCODES] = { | 34 | static unsigned short tosakbd_keycode[NR_SCANCODES] = { |
35 | 0, | 35 | 0, |
36 | 0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P, | 36 | 0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P, |
37 | 0, 0, 0, 0, 0, 0, 0, 0, | 37 | 0, 0, 0, 0, 0, 0, 0, 0, |
@@ -50,9 +50,9 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_ | |||
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct tosakbd { | 52 | struct tosakbd { |
53 | unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; | 53 | unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)]; |
54 | struct input_dev *input; | 54 | struct input_dev *input; |
55 | int suspended; | 55 | bool suspended; |
56 | spinlock_t lock; /* protect kbd scanning */ | 56 | spinlock_t lock; /* protect kbd scanning */ |
57 | struct timer_list timer; | 57 | struct timer_list timer; |
58 | }; | 58 | }; |
@@ -215,7 +215,7 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) | |||
215 | unsigned long flags; | 215 | unsigned long flags; |
216 | 216 | ||
217 | spin_lock_irqsave(&tosakbd->lock, flags); | 217 | spin_lock_irqsave(&tosakbd->lock, flags); |
218 | tosakbd->suspended = 1; | 218 | tosakbd->suspended = true; |
219 | spin_unlock_irqrestore(&tosakbd->lock, flags); | 219 | spin_unlock_irqrestore(&tosakbd->lock, flags); |
220 | 220 | ||
221 | del_timer_sync(&tosakbd->timer); | 221 | del_timer_sync(&tosakbd->timer); |
@@ -227,7 +227,7 @@ static int tosakbd_resume(struct platform_device *dev) | |||
227 | { | 227 | { |
228 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | 228 | struct tosakbd *tosakbd = platform_get_drvdata(dev); |
229 | 229 | ||
230 | tosakbd->suspended = 0; | 230 | tosakbd->suspended = false; |
231 | tosakbd_scankeyboard(dev); | 231 | tosakbd_scankeyboard(dev); |
232 | 232 | ||
233 | return 0; | 233 | return 0; |
@@ -277,14 +277,14 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) { | |||
277 | 277 | ||
278 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 278 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
279 | input_dev->keycode = tosakbd->keycode; | 279 | input_dev->keycode = tosakbd->keycode; |
280 | input_dev->keycodesize = sizeof(unsigned int); | 280 | input_dev->keycodesize = sizeof(tosakbd->keycode[0]); |
281 | input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode); | 281 | input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode); |
282 | 282 | ||
283 | memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode)); | 283 | memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode)); |
284 | 284 | ||
285 | for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++) | 285 | for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++) |
286 | __set_bit(tosakbd->keycode[i], input_dev->keybit); | 286 | __set_bit(tosakbd->keycode[i], input_dev->keybit); |
287 | clear_bit(0, input_dev->keybit); | 287 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
288 | 288 | ||
289 | /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ | 289 | /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ |
290 | for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { | 290 | for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) { |
@@ -344,7 +344,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) { | |||
344 | " direction for GPIO %d, error %d\n", | 344 | " direction for GPIO %d, error %d\n", |
345 | gpio, error); | 345 | gpio, error); |
346 | gpio_free(gpio); | 346 | gpio_free(gpio); |
347 | goto fail; | 347 | goto fail2; |
348 | } | 348 | } |
349 | 349 | ||
350 | } | 350 | } |
@@ -353,7 +353,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) { | |||
353 | if (error) { | 353 | if (error) { |
354 | printk(KERN_ERR "tosakbd: Unable to register input device, " | 354 | printk(KERN_ERR "tosakbd: Unable to register input device, " |
355 | "error: %d\n", error); | 355 | "error: %d\n", error); |
356 | goto fail; | 356 | goto fail2; |
357 | } | 357 | } |
358 | 358 | ||
359 | printk(KERN_INFO "input: Tosa Keyboard Registered\n"); | 359 | printk(KERN_INFO "input: Tosa Keyboard Registered\n"); |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c new file mode 100644 index 000000000000..9a2977c21696 --- /dev/null +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * twl4030_keypad.c - driver for 8x8 keypad controller in twl4030 chips | ||
3 | * | ||
4 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2008 Nokia Corporation | ||
6 | * | ||
7 | * Code re-written for 2430SDP by: | ||
8 | * Syed Mohammed Khasim <x0khasim@ti.com> | ||
9 | * | ||
10 | * Initial Code: | ||
11 | * Manjunatha G K <manjugk@ti.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/input.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/i2c/twl4030.h> | ||
35 | |||
36 | |||
37 | /* | ||
38 | * The TWL4030 family chips include a keypad controller that supports | ||
39 | * up to an 8x8 switch matrix. The controller can issue system wakeup | ||
40 | * events, since it uses only the always-on 32KiHz oscillator, and has | ||
41 | * an internal state machine that decodes pressed keys, including | ||
42 | * multi-key combinations. | ||
43 | * | ||
44 | * This driver lets boards define what keycodes they wish to report for | ||
45 | * which scancodes, as part of the "struct twl4030_keypad_data" used in | ||
46 | * the probe() routine. | ||
47 | * | ||
48 | * See the TPS65950 documentation; that's the general availability | ||
49 | * version of the TWL5030 second generation part. | ||
50 | */ | ||
51 | #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ | ||
52 | #define TWL4030_MAX_COLS 8 | ||
53 | #define TWL4030_ROW_SHIFT 3 | ||
54 | #define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) | ||
55 | |||
56 | struct twl4030_keypad { | ||
57 | unsigned short keymap[TWL4030_KEYMAP_SIZE]; | ||
58 | u16 kp_state[TWL4030_MAX_ROWS]; | ||
59 | unsigned n_rows; | ||
60 | unsigned n_cols; | ||
61 | unsigned irq; | ||
62 | |||
63 | struct device *dbg_dev; | ||
64 | struct input_dev *input; | ||
65 | }; | ||
66 | |||
67 | /*----------------------------------------------------------------------*/ | ||
68 | |||
69 | /* arbitrary prescaler value 0..7 */ | ||
70 | #define PTV_PRESCALER 4 | ||
71 | |||
72 | /* Register Offsets */ | ||
73 | #define KEYP_CTRL 0x00 | ||
74 | #define KEYP_DEB 0x01 | ||
75 | #define KEYP_LONG_KEY 0x02 | ||
76 | #define KEYP_LK_PTV 0x03 | ||
77 | #define KEYP_TIMEOUT_L 0x04 | ||
78 | #define KEYP_TIMEOUT_H 0x05 | ||
79 | #define KEYP_KBC 0x06 | ||
80 | #define KEYP_KBR 0x07 | ||
81 | #define KEYP_SMS 0x08 | ||
82 | #define KEYP_FULL_CODE_7_0 0x09 /* row 0 column status */ | ||
83 | #define KEYP_FULL_CODE_15_8 0x0a /* ... row 1 ... */ | ||
84 | #define KEYP_FULL_CODE_23_16 0x0b | ||
85 | #define KEYP_FULL_CODE_31_24 0x0c | ||
86 | #define KEYP_FULL_CODE_39_32 0x0d | ||
87 | #define KEYP_FULL_CODE_47_40 0x0e | ||
88 | #define KEYP_FULL_CODE_55_48 0x0f | ||
89 | #define KEYP_FULL_CODE_63_56 0x10 | ||
90 | #define KEYP_ISR1 0x11 | ||
91 | #define KEYP_IMR1 0x12 | ||
92 | #define KEYP_ISR2 0x13 | ||
93 | #define KEYP_IMR2 0x14 | ||
94 | #define KEYP_SIR 0x15 | ||
95 | #define KEYP_EDR 0x16 /* edge triggers */ | ||
96 | #define KEYP_SIH_CTRL 0x17 | ||
97 | |||
98 | /* KEYP_CTRL_REG Fields */ | ||
99 | #define KEYP_CTRL_SOFT_NRST BIT(0) | ||
100 | #define KEYP_CTRL_SOFTMODEN BIT(1) | ||
101 | #define KEYP_CTRL_LK_EN BIT(2) | ||
102 | #define KEYP_CTRL_TOE_EN BIT(3) | ||
103 | #define KEYP_CTRL_TOLE_EN BIT(4) | ||
104 | #define KEYP_CTRL_RP_EN BIT(5) | ||
105 | #define KEYP_CTRL_KBD_ON BIT(6) | ||
106 | |||
107 | /* KEYP_DEB, KEYP_LONG_KEY, KEYP_TIMEOUT_x*/ | ||
108 | #define KEYP_PERIOD_US(t, prescale) ((t) / (31 << (prescale + 1)) - 1) | ||
109 | |||
110 | /* KEYP_LK_PTV_REG Fields */ | ||
111 | #define KEYP_LK_PTV_PTV_SHIFT 5 | ||
112 | |||
113 | /* KEYP_{IMR,ISR,SIR} Fields */ | ||
114 | #define KEYP_IMR1_MIS BIT(3) | ||
115 | #define KEYP_IMR1_TO BIT(2) | ||
116 | #define KEYP_IMR1_LK BIT(1) | ||
117 | #define KEYP_IMR1_KP BIT(0) | ||
118 | |||
119 | /* KEYP_EDR Fields */ | ||
120 | #define KEYP_EDR_KP_FALLING 0x01 | ||
121 | #define KEYP_EDR_KP_RISING 0x02 | ||
122 | #define KEYP_EDR_KP_BOTH 0x03 | ||
123 | #define KEYP_EDR_LK_FALLING 0x04 | ||
124 | #define KEYP_EDR_LK_RISING 0x08 | ||
125 | #define KEYP_EDR_TO_FALLING 0x10 | ||
126 | #define KEYP_EDR_TO_RISING 0x20 | ||
127 | #define KEYP_EDR_MIS_FALLING 0x40 | ||
128 | #define KEYP_EDR_MIS_RISING 0x80 | ||
129 | |||
130 | |||
131 | /*----------------------------------------------------------------------*/ | ||
132 | |||
133 | static int twl4030_kpread(struct twl4030_keypad *kp, | ||
134 | u8 *data, u32 reg, u8 num_bytes) | ||
135 | { | ||
136 | int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes); | ||
137 | |||
138 | if (ret < 0) | ||
139 | dev_warn(kp->dbg_dev, | ||
140 | "Couldn't read TWL4030: %X - ret %d[%x]\n", | ||
141 | reg, ret, ret); | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg) | ||
147 | { | ||
148 | int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg); | ||
149 | |||
150 | if (ret < 0) | ||
151 | dev_warn(kp->dbg_dev, | ||
152 | "Could not write TWL4030: %X - ret %d[%x]\n", | ||
153 | reg, ret, ret); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static inline u16 twl4030_col_xlate(struct twl4030_keypad *kp, u8 col) | ||
159 | { | ||
160 | /* If all bits in a row are active for all coloumns then | ||
161 | * we have that row line connected to gnd. Mark this | ||
162 | * key on as if it was on matrix position n_cols (ie | ||
163 | * one higher than the size of the matrix). | ||
164 | */ | ||
165 | if (col == 0xFF) | ||
166 | return 1 << kp->n_cols; | ||
167 | else | ||
168 | return col & ((1 << kp->n_cols) - 1); | ||
169 | } | ||
170 | |||
171 | static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) | ||
172 | { | ||
173 | u8 new_state[TWL4030_MAX_ROWS]; | ||
174 | int row; | ||
175 | int ret = twl4030_kpread(kp, new_state, | ||
176 | KEYP_FULL_CODE_7_0, kp->n_rows); | ||
177 | if (ret >= 0) | ||
178 | for (row = 0; row < kp->n_rows; row++) | ||
179 | state[row] = twl4030_col_xlate(kp, new_state[row]); | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) | ||
185 | { | ||
186 | int i; | ||
187 | u16 check = 0; | ||
188 | |||
189 | for (i = 0; i < kp->n_rows; i++) { | ||
190 | u16 col = key_state[i]; | ||
191 | |||
192 | if ((col & check) && hweight16(col) > 1) | ||
193 | return 1; | ||
194 | |||
195 | check |= col; | ||
196 | } | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) | ||
202 | { | ||
203 | struct input_dev *input = kp->input; | ||
204 | u16 new_state[TWL4030_MAX_ROWS]; | ||
205 | int col, row; | ||
206 | |||
207 | if (release_all) | ||
208 | memset(new_state, 0, sizeof(new_state)); | ||
209 | else { | ||
210 | /* check for any changes */ | ||
211 | int ret = twl4030_read_kp_matrix_state(kp, new_state); | ||
212 | |||
213 | if (ret < 0) /* panic ... */ | ||
214 | return; | ||
215 | |||
216 | if (twl4030_is_in_ghost_state(kp, new_state)) | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | /* check for changes and print those */ | ||
221 | for (row = 0; row < kp->n_rows; row++) { | ||
222 | int changed = new_state[row] ^ kp->kp_state[row]; | ||
223 | |||
224 | if (!changed) | ||
225 | continue; | ||
226 | |||
227 | for (col = 0; col < kp->n_cols; col++) { | ||
228 | int code; | ||
229 | |||
230 | if (!(changed & (1 << col))) | ||
231 | continue; | ||
232 | |||
233 | dev_dbg(kp->dbg_dev, "key [%d:%d] %s\n", row, col, | ||
234 | (new_state[row] & (1 << col)) ? | ||
235 | "press" : "release"); | ||
236 | |||
237 | code = MATRIX_SCAN_CODE(row, col, TWL4030_ROW_SHIFT); | ||
238 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
239 | input_report_key(input, kp->keymap[code], | ||
240 | new_state[row] & (1 << col)); | ||
241 | } | ||
242 | kp->kp_state[row] = new_state[row]; | ||
243 | } | ||
244 | input_sync(input); | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * Keypad interrupt handler | ||
249 | */ | ||
250 | static irqreturn_t do_kp_irq(int irq, void *_kp) | ||
251 | { | ||
252 | struct twl4030_keypad *kp = _kp; | ||
253 | u8 reg; | ||
254 | int ret; | ||
255 | |||
256 | #ifdef CONFIG_LOCKDEP | ||
257 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
258 | * we don't want and can't tolerate. Although it might be | ||
259 | * friendlier not to borrow this thread context... | ||
260 | */ | ||
261 | local_irq_enable(); | ||
262 | #endif | ||
263 | |||
264 | /* Read & Clear TWL4030 pending interrupt */ | ||
265 | ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); | ||
266 | |||
267 | /* Release all keys if I2C has gone bad or | ||
268 | * the KEYP has gone to idle state */ | ||
269 | if (ret >= 0 && (reg & KEYP_IMR1_KP)) | ||
270 | twl4030_kp_scan(kp, false); | ||
271 | else | ||
272 | twl4030_kp_scan(kp, true); | ||
273 | |||
274 | return IRQ_HANDLED; | ||
275 | } | ||
276 | |||
277 | static int __devinit twl4030_kp_program(struct twl4030_keypad *kp) | ||
278 | { | ||
279 | u8 reg; | ||
280 | int i; | ||
281 | |||
282 | /* Enable controller, with hardware decoding but not autorepeat */ | ||
283 | reg = KEYP_CTRL_SOFT_NRST | KEYP_CTRL_SOFTMODEN | ||
284 | | KEYP_CTRL_TOE_EN | KEYP_CTRL_KBD_ON; | ||
285 | if (twl4030_kpwrite_u8(kp, reg, KEYP_CTRL) < 0) | ||
286 | return -EIO; | ||
287 | |||
288 | /* NOTE: we could use sih_setup() here to package keypad | ||
289 | * event sources as four different IRQs ... but we don't. | ||
290 | */ | ||
291 | |||
292 | /* Enable TO rising and KP rising and falling edge detection */ | ||
293 | reg = KEYP_EDR_KP_BOTH | KEYP_EDR_TO_RISING; | ||
294 | if (twl4030_kpwrite_u8(kp, reg, KEYP_EDR) < 0) | ||
295 | return -EIO; | ||
296 | |||
297 | /* Set PTV prescaler Field */ | ||
298 | reg = (PTV_PRESCALER << KEYP_LK_PTV_PTV_SHIFT); | ||
299 | if (twl4030_kpwrite_u8(kp, reg, KEYP_LK_PTV) < 0) | ||
300 | return -EIO; | ||
301 | |||
302 | /* Set key debounce time to 20 ms */ | ||
303 | i = KEYP_PERIOD_US(20000, PTV_PRESCALER); | ||
304 | if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0) | ||
305 | return -EIO; | ||
306 | |||
307 | /* Set timeout period to 100 ms */ | ||
308 | i = KEYP_PERIOD_US(200000, PTV_PRESCALER); | ||
309 | if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0) | ||
310 | return -EIO; | ||
311 | |||
312 | if (twl4030_kpwrite_u8(kp, (i >> 8), KEYP_TIMEOUT_H) < 0) | ||
313 | return -EIO; | ||
314 | |||
315 | /* | ||
316 | * Enable Clear-on-Read; disable remembering events that fire | ||
317 | * after the IRQ but before our handler acks (reads) them, | ||
318 | */ | ||
319 | reg = TWL4030_SIH_CTRL_COR_MASK | TWL4030_SIH_CTRL_PENDDIS_MASK; | ||
320 | if (twl4030_kpwrite_u8(kp, reg, KEYP_SIH_CTRL) < 0) | ||
321 | return -EIO; | ||
322 | |||
323 | /* initialize key state; irqs update it from here on */ | ||
324 | if (twl4030_read_kp_matrix_state(kp, kp->kp_state) < 0) | ||
325 | return -EIO; | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Registers keypad device with input subsystem | ||
332 | * and configures TWL4030 keypad registers | ||
333 | */ | ||
334 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) | ||
335 | { | ||
336 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; | ||
337 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | ||
338 | struct twl4030_keypad *kp; | ||
339 | struct input_dev *input; | ||
340 | u8 reg; | ||
341 | int error; | ||
342 | |||
343 | if (!pdata || !pdata->rows || !pdata->cols || | ||
344 | pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { | ||
345 | dev_err(&pdev->dev, "Invalid platform_data\n"); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | ||
350 | input = input_allocate_device(); | ||
351 | if (!kp || !input) { | ||
352 | error = -ENOMEM; | ||
353 | goto err1; | ||
354 | } | ||
355 | |||
356 | /* Get the debug Device */ | ||
357 | kp->dbg_dev = &pdev->dev; | ||
358 | kp->input = input; | ||
359 | |||
360 | kp->n_rows = pdata->rows; | ||
361 | kp->n_cols = pdata->cols; | ||
362 | kp->irq = platform_get_irq(pdev, 0); | ||
363 | |||
364 | /* setup input device */ | ||
365 | __set_bit(EV_KEY, input->evbit); | ||
366 | |||
367 | /* Enable auto repeat feature of Linux input subsystem */ | ||
368 | if (pdata->rep) | ||
369 | __set_bit(EV_REP, input->evbit); | ||
370 | |||
371 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
372 | |||
373 | input->name = "TWL4030 Keypad"; | ||
374 | input->phys = "twl4030_keypad/input0"; | ||
375 | input->dev.parent = &pdev->dev; | ||
376 | |||
377 | input->id.bustype = BUS_HOST; | ||
378 | input->id.vendor = 0x0001; | ||
379 | input->id.product = 0x0001; | ||
380 | input->id.version = 0x0003; | ||
381 | |||
382 | input->keycode = kp->keymap; | ||
383 | input->keycodesize = sizeof(kp->keymap[0]); | ||
384 | input->keycodemax = ARRAY_SIZE(kp->keymap); | ||
385 | |||
386 | matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT, | ||
387 | input->keycode, input->keybit); | ||
388 | |||
389 | error = input_register_device(input); | ||
390 | if (error) { | ||
391 | dev_err(kp->dbg_dev, | ||
392 | "Unable to register twl4030 keypad device\n"); | ||
393 | goto err1; | ||
394 | } | ||
395 | |||
396 | error = twl4030_kp_program(kp); | ||
397 | if (error) | ||
398 | goto err2; | ||
399 | |||
400 | /* | ||
401 | * This ISR will always execute in kernel thread context because of | ||
402 | * the need to access the TWL4030 over the I2C bus. | ||
403 | * | ||
404 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... | ||
405 | */ | ||
406 | error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp); | ||
407 | if (error) { | ||
408 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | ||
409 | kp->irq); | ||
410 | goto err3; | ||
411 | } | ||
412 | |||
413 | /* Enable KP and TO interrupts now. */ | ||
414 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); | ||
415 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { | ||
416 | error = -EIO; | ||
417 | goto err4; | ||
418 | } | ||
419 | |||
420 | platform_set_drvdata(pdev, kp); | ||
421 | return 0; | ||
422 | |||
423 | err4: | ||
424 | /* mask all events - we don't care about the result */ | ||
425 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); | ||
426 | err3: | ||
427 | free_irq(kp->irq, NULL); | ||
428 | err2: | ||
429 | input_unregister_device(input); | ||
430 | input = NULL; | ||
431 | err1: | ||
432 | input_free_device(input); | ||
433 | kfree(kp); | ||
434 | return error; | ||
435 | } | ||
436 | |||
437 | static int __devexit twl4030_kp_remove(struct platform_device *pdev) | ||
438 | { | ||
439 | struct twl4030_keypad *kp = platform_get_drvdata(pdev); | ||
440 | |||
441 | free_irq(kp->irq, kp); | ||
442 | input_unregister_device(kp->input); | ||
443 | platform_set_drvdata(pdev, NULL); | ||
444 | kfree(kp); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * NOTE: twl4030 are multi-function devices connected via I2C. | ||
451 | * So this device is a child of an I2C parent, thus it needs to | ||
452 | * support unplug/replug (which most platform devices don't). | ||
453 | */ | ||
454 | |||
455 | static struct platform_driver twl4030_kp_driver = { | ||
456 | .probe = twl4030_kp_probe, | ||
457 | .remove = __devexit_p(twl4030_kp_remove), | ||
458 | .driver = { | ||
459 | .name = "twl4030_keypad", | ||
460 | .owner = THIS_MODULE, | ||
461 | }, | ||
462 | }; | ||
463 | |||
464 | static int __init twl4030_kp_init(void) | ||
465 | { | ||
466 | return platform_driver_register(&twl4030_kp_driver); | ||
467 | } | ||
468 | module_init(twl4030_kp_init); | ||
469 | |||
470 | static void __exit twl4030_kp_exit(void) | ||
471 | { | ||
472 | platform_driver_unregister(&twl4030_kp_driver); | ||
473 | } | ||
474 | module_exit(twl4030_kp_exit); | ||
475 | |||
476 | MODULE_AUTHOR("Texas Instruments"); | ||
477 | MODULE_DESCRIPTION("TWL4030 Keypad Driver"); | ||
478 | MODULE_LICENSE("GPL"); | ||
479 | MODULE_ALIAS("platform:twl4030_keypad"); | ||
480 | |||
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c new file mode 100644 index 000000000000..6032def03707 --- /dev/null +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Nuvoton technology corporation. | ||
3 | * | ||
4 | * Wan ZongShun <mcuos.com@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation;version 2 of the License. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/input.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | #include <mach/w90p910_keypad.h> | ||
24 | |||
25 | /* Keypad Interface Control Registers */ | ||
26 | #define KPI_CONF 0x00 | ||
27 | #define KPI_3KCONF 0x04 | ||
28 | #define KPI_LPCONF 0x08 | ||
29 | #define KPI_STATUS 0x0C | ||
30 | |||
31 | #define IS1KEY (0x01 << 16) | ||
32 | #define INTTR (0x01 << 21) | ||
33 | #define KEY0R (0x0f << 3) | ||
34 | #define KEY0C 0x07 | ||
35 | #define DEBOUNCE_BIT 0x08 | ||
36 | #define KSIZE0 (0x01 << 16) | ||
37 | #define KSIZE1 (0x01 << 17) | ||
38 | #define KPSEL (0x01 << 19) | ||
39 | #define ENKP (0x01 << 18) | ||
40 | |||
41 | #define KGET_RAW(n) (((n) & KEY0R) >> 3) | ||
42 | #define KGET_COLUMN(n) ((n) & KEY0C) | ||
43 | |||
44 | #define W90P910_MAX_KEY_NUM (8 * 8) | ||
45 | #define W90P910_ROW_SHIFT 3 | ||
46 | |||
47 | struct w90p910_keypad { | ||
48 | const struct w90p910_keypad_platform_data *pdata; | ||
49 | struct clk *clk; | ||
50 | struct input_dev *input_dev; | ||
51 | void __iomem *mmio_base; | ||
52 | int irq; | ||
53 | unsigned short keymap[W90P910_MAX_KEY_NUM]; | ||
54 | }; | ||
55 | |||
56 | static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, | ||
57 | unsigned int status) | ||
58 | { | ||
59 | struct input_dev *input_dev = keypad->input_dev; | ||
60 | unsigned int row = KGET_RAW(status); | ||
61 | unsigned int col = KGET_COLUMN(status); | ||
62 | unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT); | ||
63 | unsigned int key = keypad->keymap[code]; | ||
64 | |||
65 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
66 | input_report_key(input_dev, key, 1); | ||
67 | input_sync(input_dev); | ||
68 | |||
69 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
70 | input_report_key(input_dev, key, 0); | ||
71 | input_sync(input_dev); | ||
72 | } | ||
73 | |||
74 | static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id) | ||
75 | { | ||
76 | struct w90p910_keypad *keypad = dev_id; | ||
77 | unsigned int kstatus, val; | ||
78 | |||
79 | kstatus = __raw_readl(keypad->mmio_base + KPI_STATUS); | ||
80 | |||
81 | val = INTTR | IS1KEY; | ||
82 | |||
83 | if (kstatus & val) | ||
84 | w90p910_keypad_scan_matrix(keypad, kstatus); | ||
85 | |||
86 | return IRQ_HANDLED; | ||
87 | } | ||
88 | |||
89 | static int w90p910_keypad_open(struct input_dev *dev) | ||
90 | { | ||
91 | struct w90p910_keypad *keypad = input_get_drvdata(dev); | ||
92 | const struct w90p910_keypad_platform_data *pdata = keypad->pdata; | ||
93 | unsigned int val, config; | ||
94 | |||
95 | /* Enable unit clock */ | ||
96 | clk_enable(keypad->clk); | ||
97 | |||
98 | val = __raw_readl(keypad->mmio_base + KPI_CONF); | ||
99 | val |= (KPSEL | ENKP); | ||
100 | val &= ~(KSIZE0 | KSIZE1); | ||
101 | |||
102 | config = pdata->prescale | (pdata->debounce << DEBOUNCE_BIT); | ||
103 | |||
104 | val |= config; | ||
105 | |||
106 | __raw_writel(val, keypad->mmio_base + KPI_CONF); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static void w90p910_keypad_close(struct input_dev *dev) | ||
112 | { | ||
113 | struct w90p910_keypad *keypad = input_get_drvdata(dev); | ||
114 | |||
115 | /* Disable clock unit */ | ||
116 | clk_disable(keypad->clk); | ||
117 | } | ||
118 | |||
119 | static int __devinit w90p910_keypad_probe(struct platform_device *pdev) | ||
120 | { | ||
121 | const struct w90p910_keypad_platform_data *pdata = | ||
122 | pdev->dev.platform_data; | ||
123 | const struct matrix_keymap_data *keymap_data; | ||
124 | struct w90p910_keypad *keypad; | ||
125 | struct input_dev *input_dev; | ||
126 | struct resource *res; | ||
127 | int irq; | ||
128 | int error; | ||
129 | |||
130 | if (!pdata) { | ||
131 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | keymap_data = pdata->keymap_data; | ||
136 | |||
137 | irq = platform_get_irq(pdev, 0); | ||
138 | if (irq < 0) { | ||
139 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
140 | return -ENXIO; | ||
141 | } | ||
142 | |||
143 | keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); | ||
144 | input_dev = input_allocate_device(); | ||
145 | if (!keypad || !input_dev) { | ||
146 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
147 | error = -ENOMEM; | ||
148 | goto failed_free; | ||
149 | } | ||
150 | |||
151 | keypad->pdata = pdata; | ||
152 | keypad->input_dev = input_dev; | ||
153 | keypad->irq = irq; | ||
154 | |||
155 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
156 | if (res == NULL) { | ||
157 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
158 | error = -ENXIO; | ||
159 | goto failed_free; | ||
160 | } | ||
161 | |||
162 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
163 | if (res == NULL) { | ||
164 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
165 | error = -EBUSY; | ||
166 | goto failed_free; | ||
167 | } | ||
168 | |||
169 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
170 | if (keypad->mmio_base == NULL) { | ||
171 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
172 | error = -ENXIO; | ||
173 | goto failed_free_res; | ||
174 | } | ||
175 | |||
176 | keypad->clk = clk_get(&pdev->dev, NULL); | ||
177 | if (IS_ERR(keypad->clk)) { | ||
178 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
179 | error = PTR_ERR(keypad->clk); | ||
180 | goto failed_free_io; | ||
181 | } | ||
182 | |||
183 | /* set multi-function pin for w90p910 kpi. */ | ||
184 | mfp_set_groupi(&pdev->dev); | ||
185 | |||
186 | input_dev->name = pdev->name; | ||
187 | input_dev->id.bustype = BUS_HOST; | ||
188 | input_dev->open = w90p910_keypad_open; | ||
189 | input_dev->close = w90p910_keypad_close; | ||
190 | input_dev->dev.parent = &pdev->dev; | ||
191 | |||
192 | input_dev->keycode = keypad->keymap; | ||
193 | input_dev->keycodesize = sizeof(keypad->keymap[0]); | ||
194 | input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
195 | |||
196 | input_set_drvdata(input_dev, keypad); | ||
197 | |||
198 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
199 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
200 | |||
201 | matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT, | ||
202 | input_dev->keycode, input_dev->keybit); | ||
203 | |||
204 | error = request_irq(keypad->irq, w90p910_keypad_irq_handler, | ||
205 | IRQF_DISABLED, pdev->name, keypad); | ||
206 | if (error) { | ||
207 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
208 | goto failed_put_clk; | ||
209 | } | ||
210 | |||
211 | /* Register the input device */ | ||
212 | error = input_register_device(input_dev); | ||
213 | if (error) { | ||
214 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
215 | goto failed_free_irq; | ||
216 | } | ||
217 | |||
218 | platform_set_drvdata(pdev, keypad); | ||
219 | return 0; | ||
220 | |||
221 | failed_free_irq: | ||
222 | free_irq(irq, pdev); | ||
223 | failed_put_clk: | ||
224 | clk_put(keypad->clk); | ||
225 | failed_free_io: | ||
226 | iounmap(keypad->mmio_base); | ||
227 | failed_free_res: | ||
228 | release_mem_region(res->start, resource_size(res)); | ||
229 | failed_free: | ||
230 | input_free_device(input_dev); | ||
231 | kfree(keypad); | ||
232 | return error; | ||
233 | } | ||
234 | |||
235 | static int __devexit w90p910_keypad_remove(struct platform_device *pdev) | ||
236 | { | ||
237 | struct w90p910_keypad *keypad = platform_get_drvdata(pdev); | ||
238 | struct resource *res; | ||
239 | |||
240 | free_irq(keypad->irq, pdev); | ||
241 | |||
242 | clk_put(keypad->clk); | ||
243 | |||
244 | input_unregister_device(keypad->input_dev); | ||
245 | |||
246 | iounmap(keypad->mmio_base); | ||
247 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
248 | release_mem_region(res->start, resource_size(res)); | ||
249 | |||
250 | platform_set_drvdata(pdev, NULL); | ||
251 | kfree(keypad); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static struct platform_driver w90p910_keypad_driver = { | ||
257 | .probe = w90p910_keypad_probe, | ||
258 | .remove = __devexit_p(w90p910_keypad_remove), | ||
259 | .driver = { | ||
260 | .name = "nuc900-keypad", | ||
261 | .owner = THIS_MODULE, | ||
262 | }, | ||
263 | }; | ||
264 | |||
265 | static int __init w90p910_keypad_init(void) | ||
266 | { | ||
267 | return platform_driver_register(&w90p910_keypad_driver); | ||
268 | } | ||
269 | |||
270 | static void __exit w90p910_keypad_exit(void) | ||
271 | { | ||
272 | platform_driver_unregister(&w90p910_keypad_driver); | ||
273 | } | ||
274 | |||
275 | module_init(w90p910_keypad_init); | ||
276 | module_exit(w90p910_keypad_exit); | ||
277 | |||
278 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
279 | MODULE_DESCRIPTION("w90p910 keypad driver"); | ||
280 | MODULE_LICENSE("GPL"); | ||
281 | MODULE_ALIAS("platform:nuc900-keypad"); | ||