Commit 07176b988ebb20f46a317a60ee1d983fe1630203
Exists in
master
and in
20 other branches
Merge branch 'next' into for-linus
Merge first round of changes for 3.12 merge window.
Showing 33 changed files Side-by-side Diff
- Documentation/devicetree/bindings/input/input-reset.txt
- Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
- MAINTAINERS
- drivers/input/joystick/as5011.c
- drivers/input/joystick/maplecontrol.c
- drivers/input/keyboard/imx_keypad.c
- drivers/input/keyboard/max7359_keypad.c
- drivers/input/keyboard/nspire-keypad.c
- drivers/input/keyboard/omap4-keypad.c
- drivers/input/keyboard/qt1070.c
- drivers/input/keyboard/spear-keyboard.c
- drivers/input/keyboard/tegra-kbc.c
- drivers/input/misc/Kconfig
- drivers/input/misc/Makefile
- drivers/input/misc/ideapad_slidebar.c
- drivers/input/misc/pwm-beeper.c
- drivers/input/misc/twl6040-vibra.c
- drivers/input/misc/wistron_btns.c
- drivers/input/mouse/lifebook.c
- drivers/input/mouse/synaptics.c
- drivers/input/serio/arc_ps2.c
- drivers/input/serio/i8042.h
- drivers/input/serio/olpc_apsp.c
- drivers/input/tablet/wacom_sys.c
- drivers/input/tablet/wacom_wac.c
- drivers/input/touchscreen/cy8ctmg110_ts.c
- drivers/input/touchscreen/cyttsp4_core.c
- drivers/input/touchscreen/eeti_ts.c
- drivers/input/touchscreen/htcpen.c
- drivers/input/touchscreen/max11801_ts.c
- drivers/tty/sysrq.c
- include/linux/i8042.h
- include/uapi/linux/input.h
Documentation/devicetree/bindings/input/input-reset.txt
1 | +Input: sysrq reset sequence | |
2 | + | |
3 | +A simple binding to represent a set of keys as described in | |
4 | +include/uapi/linux/input.h. This is to communicate a sequence of keys to the | |
5 | +sysrq driver. Upon holding the keys for a specified amount of time (if | |
6 | +specified) the system is sync'ed and reset. | |
7 | + | |
8 | +Key sequences are global to the system but all the keys in a set must be coming | |
9 | +from the same input device. | |
10 | + | |
11 | +The /chosen node should contain a 'linux,sysrq-reset-seq' child node to define | |
12 | +a set of keys. | |
13 | + | |
14 | +Required property: | |
15 | +sysrq-reset-seq: array of Linux keycodes, one keycode per cell. | |
16 | + | |
17 | +Optional property: | |
18 | +timeout-ms: duration keys must be pressed together in milliseconds before | |
19 | +generating a sysrq. If omitted the system is rebooted immediately when a valid | |
20 | +sequence has been recognized. | |
21 | + | |
22 | +Example: | |
23 | + | |
24 | + chosen { | |
25 | + linux,sysrq-reset-seq { | |
26 | + keyset = <0x03 | |
27 | + 0x04 | |
28 | + 0x0a>; | |
29 | + timeout-ms = <3000>; | |
30 | + }; | |
31 | + }; | |
32 | + | |
33 | +Would represent KEY_2, KEY_3 and KEY_9. |
Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
MAINTAINERS
... | ... | @@ -2411,9 +2411,9 @@ |
2411 | 2411 | F: drivers/media/common/cypress_firmware* |
2412 | 2412 | |
2413 | 2413 | CYTTSP TOUCHSCREEN DRIVER |
2414 | -M: Javier Martinez Canillas <javier@dowhile0.org> | |
2414 | +M: Ferruh Yigit <fery@cypress.com> | |
2415 | 2415 | L: linux-input@vger.kernel.org |
2416 | -S: Maintained | |
2416 | +S: Supported | |
2417 | 2417 | F: drivers/input/touchscreen/cyttsp* |
2418 | 2418 | F: include/linux/input/cyttsp.h |
2419 | 2419 | |
... | ... | @@ -4037,6 +4037,13 @@ |
4037 | 4037 | W: http://launchpad.net/ideapad-laptop |
4038 | 4038 | S: Maintained |
4039 | 4039 | F: drivers/platform/x86/ideapad-laptop.c |
4040 | + | |
4041 | +IDEAPAD LAPTOP SLIDEBAR DRIVER | |
4042 | +M: Andrey Moiseev <o2g.org.ru@gmail.com> | |
4043 | +L: linux-input@vger.kernel.org | |
4044 | +W: https://github.com/o2genum/ideapad-slidebar | |
4045 | +S: Maintained | |
4046 | +F: drivers/input/misc/ideapad_slidebar.c | |
4040 | 4047 | |
4041 | 4048 | IDE/ATAPI DRIVERS |
4042 | 4049 | M: Borislav Petkov <bp@alien8.de> |
drivers/input/joystick/as5011.c
... | ... | @@ -234,7 +234,7 @@ |
234 | 234 | int irq; |
235 | 235 | int error; |
236 | 236 | |
237 | - plat_data = client->dev.platform_data; | |
237 | + plat_data = dev_get_platdata(&client->dev); | |
238 | 238 | if (!plat_data) |
239 | 239 | return -EINVAL; |
240 | 240 | |
... | ... | @@ -288,6 +288,7 @@ |
288 | 288 | if (irq < 0) { |
289 | 289 | dev_err(&client->dev, |
290 | 290 | "Failed to get irq number for button gpio\n"); |
291 | + error = irq; | |
291 | 292 | goto err_free_button_gpio; |
292 | 293 | } |
293 | 294 |
drivers/input/joystick/maplecontrol.c
... | ... | @@ -61,7 +61,7 @@ |
61 | 61 | |
62 | 62 | static int dc_pad_open(struct input_dev *dev) |
63 | 63 | { |
64 | - struct dc_pad *pad = dev->dev.platform_data; | |
64 | + struct dc_pad *pad = dev_get_platdata(&dev->dev); | |
65 | 65 | |
66 | 66 | maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/20, |
67 | 67 | MAPLE_FUNC_CONTROLLER); |
... | ... | @@ -71,7 +71,7 @@ |
71 | 71 | |
72 | 72 | static void dc_pad_close(struct input_dev *dev) |
73 | 73 | { |
74 | - struct dc_pad *pad = dev->dev.platform_data; | |
74 | + struct dc_pad *pad = dev_get_platdata(&dev->dev); | |
75 | 75 | |
76 | 76 | maple_getcond_callback(pad->mdev, dc_pad_callback, 0, |
77 | 77 | MAPLE_FUNC_CONTROLLER); |
drivers/input/keyboard/imx_keypad.c
... | ... | @@ -442,12 +442,6 @@ |
442 | 442 | return -EINVAL; |
443 | 443 | } |
444 | 444 | |
445 | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
446 | - if (res == NULL) { | |
447 | - dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); | |
448 | - return -EINVAL; | |
449 | - } | |
450 | - | |
451 | 445 | input_dev = devm_input_allocate_device(&pdev->dev); |
452 | 446 | if (!input_dev) { |
453 | 447 | dev_err(&pdev->dev, "failed to allocate the input device\n"); |
... | ... | @@ -468,6 +462,7 @@ |
468 | 462 | setup_timer(&keypad->check_matrix_timer, |
469 | 463 | imx_keypad_check_for_events, (unsigned long) keypad); |
470 | 464 | |
465 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
471 | 466 | keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res); |
472 | 467 | if (IS_ERR(keypad->mmio_base)) |
473 | 468 | return PTR_ERR(keypad->mmio_base); |
drivers/input/keyboard/max7359_keypad.c
drivers/input/keyboard/nspire-keypad.c
... | ... | @@ -171,12 +171,6 @@ |
171 | 171 | return -EINVAL; |
172 | 172 | } |
173 | 173 | |
174 | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
175 | - if (!res) { | |
176 | - dev_err(&pdev->dev, "missing platform resources\n"); | |
177 | - return -EINVAL; | |
178 | - } | |
179 | - | |
180 | 174 | keypad = devm_kzalloc(&pdev->dev, sizeof(struct nspire_keypad), |
181 | 175 | GFP_KERNEL); |
182 | 176 | if (!keypad) { |
... | ... | @@ -208,6 +202,7 @@ |
208 | 202 | return PTR_ERR(keypad->clk); |
209 | 203 | } |
210 | 204 | |
205 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
211 | 206 | keypad->reg_base = devm_ioremap_resource(&pdev->dev, res); |
212 | 207 | if (IS_ERR(keypad->reg_base)) |
213 | 208 | return PTR_ERR(keypad->reg_base); |
drivers/input/keyboard/omap4-keypad.c
... | ... | @@ -53,22 +53,18 @@ |
53 | 53 | #define OMAP4_KBD_FULLCODE63_32 0x48 |
54 | 54 | |
55 | 55 | /* OMAP4 bit definitions */ |
56 | -#define OMAP4_DEF_IRQENABLE_EVENTEN (1 << 0) | |
57 | -#define OMAP4_DEF_IRQENABLE_LONGKEY (1 << 1) | |
58 | -#define OMAP4_DEF_IRQENABLE_TIMEOUTEN (1 << 2) | |
59 | -#define OMAP4_DEF_WUP_EVENT_ENA (1 << 0) | |
60 | -#define OMAP4_DEF_WUP_LONG_KEY_ENA (1 << 1) | |
61 | -#define OMAP4_DEF_CTRL_NOSOFTMODE (1 << 1) | |
62 | -#define OMAP4_DEF_CTRLPTVVALUE (1 << 2) | |
63 | -#define OMAP4_DEF_CTRLPTV (1 << 1) | |
56 | +#define OMAP4_DEF_IRQENABLE_EVENTEN BIT(0) | |
57 | +#define OMAP4_DEF_IRQENABLE_LONGKEY BIT(1) | |
58 | +#define OMAP4_DEF_WUP_EVENT_ENA BIT(0) | |
59 | +#define OMAP4_DEF_WUP_LONG_KEY_ENA BIT(1) | |
60 | +#define OMAP4_DEF_CTRL_NOSOFTMODE BIT(1) | |
61 | +#define OMAP4_DEF_CTRL_PTV_SHIFT 2 | |
64 | 62 | |
65 | 63 | /* OMAP4 values */ |
66 | -#define OMAP4_VAL_IRQDISABLE 0x00 | |
67 | -#define OMAP4_VAL_DEBOUNCINGTIME 0x07 | |
68 | -#define OMAP4_VAL_FUNCTIONALCFG 0x1E | |
64 | +#define OMAP4_VAL_IRQDISABLE 0x0 | |
65 | +#define OMAP4_VAL_DEBOUNCINGTIME 0x7 | |
66 | +#define OMAP4_VAL_PVT 0x7 | |
69 | 67 | |
70 | -#define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | |
71 | - | |
72 | 68 | enum { |
73 | 69 | KBD_REVISION_OMAP4 = 0, |
74 | 70 | KBD_REVISION_OMAP5, |
... | ... | @@ -78,6 +74,7 @@ |
78 | 74 | struct input_dev *input; |
79 | 75 | |
80 | 76 | void __iomem *base; |
77 | + bool irq_wake_enabled; | |
81 | 78 | unsigned int irq; |
82 | 79 | |
83 | 80 | unsigned int rows; |
84 | 81 | |
85 | 82 | |
... | ... | @@ -116,19 +113,29 @@ |
116 | 113 | } |
117 | 114 | |
118 | 115 | |
119 | -/* Interrupt handler */ | |
120 | -static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |
116 | +/* Interrupt handlers */ | |
117 | +static irqreturn_t omap4_keypad_irq_handler(int irq, void *dev_id) | |
121 | 118 | { |
122 | 119 | struct omap4_keypad *keypad_data = dev_id; |
120 | + | |
121 | + if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) { | |
122 | + /* Disable interrupts */ | |
123 | + kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | |
124 | + OMAP4_VAL_IRQDISABLE); | |
125 | + return IRQ_WAKE_THREAD; | |
126 | + } | |
127 | + | |
128 | + return IRQ_NONE; | |
129 | +} | |
130 | + | |
131 | +static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) | |
132 | +{ | |
133 | + struct omap4_keypad *keypad_data = dev_id; | |
123 | 134 | struct input_dev *input_dev = keypad_data->input; |
124 | 135 | unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; |
125 | 136 | unsigned int col, row, code, changed; |
126 | 137 | u32 *new_state = (u32 *) key_state; |
127 | 138 | |
128 | - /* Disable interrupts */ | |
129 | - kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | |
130 | - OMAP4_VAL_IRQDISABLE); | |
131 | - | |
132 | 139 | *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); |
133 | 140 | *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); |
134 | 141 | |
135 | 142 | |
136 | 143 | |
... | ... | @@ -175,11 +182,13 @@ |
175 | 182 | disable_irq(keypad_data->irq); |
176 | 183 | |
177 | 184 | kbd_writel(keypad_data, OMAP4_KBD_CTRL, |
178 | - OMAP4_VAL_FUNCTIONALCFG); | |
185 | + OMAP4_DEF_CTRL_NOSOFTMODE | | |
186 | + (OMAP4_VAL_PVT << OMAP4_DEF_CTRL_PTV_SHIFT)); | |
179 | 187 | kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, |
180 | 188 | OMAP4_VAL_DEBOUNCINGTIME); |
189 | + /* clear pending interrupts */ | |
181 | 190 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
182 | - OMAP4_VAL_IRQDISABLE); | |
191 | + kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); | |
183 | 192 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
184 | 193 | OMAP4_DEF_IRQENABLE_EVENTEN | |
185 | 194 | OMAP4_DEF_IRQENABLE_LONGKEY); |
186 | 195 | |
... | ... | @@ -363,14 +372,15 @@ |
363 | 372 | goto err_free_keymap; |
364 | 373 | } |
365 | 374 | |
366 | - error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | |
367 | - IRQF_TRIGGER_RISING, | |
368 | - "omap4-keypad", keypad_data); | |
375 | + error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, | |
376 | + omap4_keypad_irq_thread_fn, 0, | |
377 | + "omap4-keypad", keypad_data); | |
369 | 378 | if (error) { |
370 | 379 | dev_err(&pdev->dev, "failed to register interrupt\n"); |
371 | 380 | goto err_free_input; |
372 | 381 | } |
373 | 382 | |
383 | + device_init_wakeup(&pdev->dev, true); | |
374 | 384 | pm_runtime_put_sync(&pdev->dev); |
375 | 385 | |
376 | 386 | error = input_register_device(keypad_data->input); |
... | ... | @@ -384,6 +394,7 @@ |
384 | 394 | |
385 | 395 | err_pm_disable: |
386 | 396 | pm_runtime_disable(&pdev->dev); |
397 | + device_init_wakeup(&pdev->dev, false); | |
387 | 398 | free_irq(keypad_data->irq, keypad_data); |
388 | 399 | err_free_keymap: |
389 | 400 | kfree(keypad_data->keymap); |
... | ... | @@ -409,6 +420,8 @@ |
409 | 420 | |
410 | 421 | pm_runtime_disable(&pdev->dev); |
411 | 422 | |
423 | + device_init_wakeup(&pdev->dev, false); | |
424 | + | |
412 | 425 | input_unregister_device(keypad_data->input); |
413 | 426 | |
414 | 427 | iounmap(keypad_data->base); |
415 | 428 | |
... | ... | @@ -430,12 +443,46 @@ |
430 | 443 | MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); |
431 | 444 | #endif |
432 | 445 | |
446 | +#ifdef CONFIG_PM_SLEEP | |
447 | +static int omap4_keypad_suspend(struct device *dev) | |
448 | +{ | |
449 | + struct platform_device *pdev = to_platform_device(dev); | |
450 | + struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | |
451 | + int error; | |
452 | + | |
453 | + if (device_may_wakeup(&pdev->dev)) { | |
454 | + error = enable_irq_wake(keypad_data->irq); | |
455 | + if (!error) | |
456 | + keypad_data->irq_wake_enabled = true; | |
457 | + } | |
458 | + | |
459 | + return 0; | |
460 | +} | |
461 | + | |
462 | +static int omap4_keypad_resume(struct device *dev) | |
463 | +{ | |
464 | + struct platform_device *pdev = to_platform_device(dev); | |
465 | + struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | |
466 | + | |
467 | + if (device_may_wakeup(&pdev->dev) && keypad_data->irq_wake_enabled) { | |
468 | + disable_irq_wake(keypad_data->irq); | |
469 | + keypad_data->irq_wake_enabled = false; | |
470 | + } | |
471 | + | |
472 | + return 0; | |
473 | +} | |
474 | +#endif | |
475 | + | |
476 | +static SIMPLE_DEV_PM_OPS(omap4_keypad_pm_ops, | |
477 | + omap4_keypad_suspend, omap4_keypad_resume); | |
478 | + | |
433 | 479 | static struct platform_driver omap4_keypad_driver = { |
434 | 480 | .probe = omap4_keypad_probe, |
435 | 481 | .remove = omap4_keypad_remove, |
436 | 482 | .driver = { |
437 | 483 | .name = "omap4-keypad", |
438 | 484 | .owner = THIS_MODULE, |
485 | + .pm = &omap4_keypad_pm_ops, | |
439 | 486 | .of_match_table = of_match_ptr(omap_keypad_dt_match), |
440 | 487 | }, |
441 | 488 | }; |
drivers/input/keyboard/qt1070.c
... | ... | @@ -243,6 +243,32 @@ |
243 | 243 | return 0; |
244 | 244 | } |
245 | 245 | |
246 | +#ifdef CONFIG_PM_SLEEP | |
247 | +static int qt1070_suspend(struct device *dev) | |
248 | +{ | |
249 | + struct i2c_client *client = to_i2c_client(dev); | |
250 | + struct qt1070_data *data = i2c_get_clientdata(client); | |
251 | + | |
252 | + if (device_may_wakeup(dev)) | |
253 | + enable_irq_wake(data->irq); | |
254 | + | |
255 | + return 0; | |
256 | +} | |
257 | + | |
258 | +static int qt1070_resume(struct device *dev) | |
259 | +{ | |
260 | + struct i2c_client *client = to_i2c_client(dev); | |
261 | + struct qt1070_data *data = i2c_get_clientdata(client); | |
262 | + | |
263 | + if (device_may_wakeup(dev)) | |
264 | + disable_irq_wake(data->irq); | |
265 | + | |
266 | + return 0; | |
267 | +} | |
268 | +#endif | |
269 | + | |
270 | +static SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume); | |
271 | + | |
246 | 272 | static const struct i2c_device_id qt1070_id[] = { |
247 | 273 | { "qt1070", 0 }, |
248 | 274 | { }, |
... | ... | @@ -253,6 +279,7 @@ |
253 | 279 | .driver = { |
254 | 280 | .name = "qt1070", |
255 | 281 | .owner = THIS_MODULE, |
282 | + .pm = &qt1070_pm_ops, | |
256 | 283 | }, |
257 | 284 | .id_table = qt1070_id, |
258 | 285 | .probe = qt1070_probe, |
drivers/input/keyboard/spear-keyboard.c
... | ... | @@ -191,12 +191,6 @@ |
191 | 191 | int irq; |
192 | 192 | int error; |
193 | 193 | |
194 | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
195 | - if (!res) { | |
196 | - dev_err(&pdev->dev, "no keyboard resource defined\n"); | |
197 | - return -EBUSY; | |
198 | - } | |
199 | - | |
200 | 194 | irq = platform_get_irq(pdev, 0); |
201 | 195 | if (irq < 0) { |
202 | 196 | dev_err(&pdev->dev, "not able to get irq for the device\n"); |
... | ... | @@ -228,6 +222,7 @@ |
228 | 222 | kbd->suspended_rate = pdata->suspended_rate; |
229 | 223 | } |
230 | 224 | |
225 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
231 | 226 | kbd->io_base = devm_ioremap_resource(&pdev->dev, res); |
232 | 227 | if (IS_ERR(kbd->io_base)) |
233 | 228 | return PTR_ERR(kbd->io_base); |
drivers/input/keyboard/tegra-kbc.c
... | ... | @@ -638,12 +638,6 @@ |
638 | 638 | if (!tegra_kbc_check_pin_cfg(kbc, &num_rows)) |
639 | 639 | return -EINVAL; |
640 | 640 | |
641 | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
642 | - if (!res) { | |
643 | - dev_err(&pdev->dev, "failed to get I/O memory\n"); | |
644 | - return -ENXIO; | |
645 | - } | |
646 | - | |
647 | 641 | kbc->irq = platform_get_irq(pdev, 0); |
648 | 642 | if (kbc->irq < 0) { |
649 | 643 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); |
... | ... | @@ -658,6 +652,7 @@ |
658 | 652 | |
659 | 653 | setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc); |
660 | 654 | |
655 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
661 | 656 | kbc->mmio = devm_ioremap_resource(&pdev->dev, res); |
662 | 657 | if (IS_ERR(kbc->mmio)) |
663 | 658 | return PTR_ERR(kbc->mmio); |
drivers/input/misc/Kconfig
... | ... | @@ -647,5 +647,15 @@ |
647 | 647 | |
648 | 648 | If unsure, say N. |
649 | 649 | |
650 | +config INPUT_IDEAPAD_SLIDEBAR | |
651 | + tristate "IdeaPad Laptop Slidebar" | |
652 | + depends on INPUT | |
653 | + depends on SERIO_I8042 | |
654 | + help | |
655 | + Say Y here if you have an IdeaPad laptop with a slidebar. | |
656 | + | |
657 | + To compile this driver as a module, choose M here: the | |
658 | + module will be called ideapad_slidebar. | |
659 | + | |
650 | 660 | endif |
drivers/input/misc/Makefile
drivers/input/misc/ideapad_slidebar.c
1 | +/* | |
2 | + * Input driver for slidebars on some Lenovo IdeaPad laptops | |
3 | + * | |
4 | + * Copyright (C) 2013 Andrey Moiseev <o2g.org.ru@gmail.com> | |
5 | + * | |
6 | + * Reverse-engineered from Lenovo SlideNav software (SBarHook.dll). | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify it | |
9 | + * under the terms of the GNU General Public License as published by the Free | |
10 | + * Software Foundation; either version 2 of the License, or (at your option) | |
11 | + * any later version. | |
12 | + * | |
13 | + * Trademarks are the property of their respective owners. | |
14 | + */ | |
15 | + | |
16 | +/* | |
17 | + * Currently tested and works on: | |
18 | + * Lenovo IdeaPad Y550 | |
19 | + * Lenovo IdeaPad Y550P | |
20 | + * | |
21 | + * Other models can be added easily. To test, | |
22 | + * load with 'force' parameter set 'true'. | |
23 | + * | |
24 | + * LEDs blinking and input mode are managed via sysfs, | |
25 | + * (hex, unsigned byte value): | |
26 | + * /sys/devices/platform/ideapad_slidebar/slidebar_mode | |
27 | + * | |
28 | + * The value is in byte range, however, I only figured out | |
29 | + * how bits 0b10011001 work. Some other bits, probably, | |
30 | + * are meaningfull too. | |
31 | + * | |
32 | + * Possible states: | |
33 | + * | |
34 | + * STD_INT, ONMOV_INT, OFF_INT, LAST_POLL, OFF_POLL | |
35 | + * | |
36 | + * Meaning: | |
37 | + * released touched | |
38 | + * STD 'heartbeat' lights follow the finger | |
39 | + * ONMOV no lights lights follow the finger | |
40 | + * LAST at last pos lights follow the finger | |
41 | + * OFF no lights no lights | |
42 | + * | |
43 | + * INT all input events are generated, interrupts are used | |
44 | + * POLL no input events by default, to get them, | |
45 | + * send 0b10000000 (read below) | |
46 | + * | |
47 | + * Commands: write | |
48 | + * | |
49 | + * All | 0b01001 -> STD_INT | |
50 | + * possible | 0b10001 -> ONMOV_INT | |
51 | + * states | 0b01000 -> OFF_INT | |
52 | + * | |
53 | + * | 0b0 -> LAST_POLL | |
54 | + * STD_INT or ONMOV_INT | | |
55 | + * | 0b1 -> STD_INT | |
56 | + * | |
57 | + * | 0b0 -> OFF_POLL | |
58 | + * OFF_INT or OFF_POLL | | |
59 | + * | 0b1 -> OFF_INT | |
60 | + * | |
61 | + * Any state | 0b10000000 -> if the slidebar has updated data, | |
62 | + * produce one input event (last position), | |
63 | + * switch to respective POLL mode | |
64 | + * (like 0x0), if not in POLL mode yet. | |
65 | + * | |
66 | + * Get current state: read | |
67 | + * | |
68 | + * masked by 0x11 read value means: | |
69 | + * | |
70 | + * 0x00 LAST | |
71 | + * 0x01 STD | |
72 | + * 0x10 OFF | |
73 | + * 0x11 ONMOV | |
74 | + */ | |
75 | + | |
76 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
77 | + | |
78 | +#include <linux/module.h> | |
79 | +#include <linux/kernel.h> | |
80 | +#include <linux/dmi.h> | |
81 | +#include <linux/spinlock.h> | |
82 | +#include <linux/platform_device.h> | |
83 | +#include <linux/input.h> | |
84 | +#include <linux/io.h> | |
85 | +#include <linux/ioport.h> | |
86 | +#include <linux/i8042.h> | |
87 | +#include <linux/serio.h> | |
88 | + | |
89 | +#define IDEAPAD_BASE 0xff29 | |
90 | + | |
91 | +static bool force; | |
92 | +module_param(force, bool, 0); | |
93 | +MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | |
94 | + | |
95 | +static DEFINE_SPINLOCK(io_lock); | |
96 | + | |
97 | +static struct input_dev *slidebar_input_dev; | |
98 | +static struct platform_device *slidebar_platform_dev; | |
99 | + | |
100 | +static u8 slidebar_pos_get(void) | |
101 | +{ | |
102 | + u8 res; | |
103 | + unsigned long flags; | |
104 | + | |
105 | + spin_lock_irqsave(&io_lock, flags); | |
106 | + outb(0xf4, 0xff29); | |
107 | + outb(0xbf, 0xff2a); | |
108 | + res = inb(0xff2b); | |
109 | + spin_unlock_irqrestore(&io_lock, flags); | |
110 | + | |
111 | + return res; | |
112 | +} | |
113 | + | |
114 | +static u8 slidebar_mode_get(void) | |
115 | +{ | |
116 | + u8 res; | |
117 | + unsigned long flags; | |
118 | + | |
119 | + spin_lock_irqsave(&io_lock, flags); | |
120 | + outb(0xf7, 0xff29); | |
121 | + outb(0x8b, 0xff2a); | |
122 | + res = inb(0xff2b); | |
123 | + spin_unlock_irqrestore(&io_lock, flags); | |
124 | + | |
125 | + return res; | |
126 | +} | |
127 | + | |
128 | +static void slidebar_mode_set(u8 mode) | |
129 | +{ | |
130 | + unsigned long flags; | |
131 | + | |
132 | + spin_lock_irqsave(&io_lock, flags); | |
133 | + outb(0xf7, 0xff29); | |
134 | + outb(0x8b, 0xff2a); | |
135 | + outb(mode, 0xff2b); | |
136 | + spin_unlock_irqrestore(&io_lock, flags); | |
137 | +} | |
138 | + | |
139 | +static bool slidebar_i8042_filter(unsigned char data, unsigned char str, | |
140 | + struct serio *port) | |
141 | +{ | |
142 | + static bool extended = false; | |
143 | + | |
144 | + /* We are only interested in data coming form KBC port */ | |
145 | + if (str & I8042_STR_AUXDATA) | |
146 | + return false; | |
147 | + | |
148 | + /* Scancodes: e03b on move, e0bb on release. */ | |
149 | + if (data == 0xe0) { | |
150 | + extended = true; | |
151 | + return true; | |
152 | + } | |
153 | + | |
154 | + if (!extended) | |
155 | + return false; | |
156 | + | |
157 | + extended = false; | |
158 | + | |
159 | + if (likely((data & 0x7f) != 0x3b)) { | |
160 | + serio_interrupt(port, 0xe0, 0); | |
161 | + return false; | |
162 | + } | |
163 | + | |
164 | + if (data & 0x80) { | |
165 | + input_report_key(slidebar_input_dev, BTN_TOUCH, 0); | |
166 | + } else { | |
167 | + input_report_key(slidebar_input_dev, BTN_TOUCH, 1); | |
168 | + input_report_abs(slidebar_input_dev, ABS_X, slidebar_pos_get()); | |
169 | + } | |
170 | + input_sync(slidebar_input_dev); | |
171 | + | |
172 | + return true; | |
173 | +} | |
174 | + | |
175 | +static ssize_t show_slidebar_mode(struct device *dev, | |
176 | + struct device_attribute *attr, | |
177 | + char *buf) | |
178 | +{ | |
179 | + return sprintf(buf, "%x\n", slidebar_mode_get()); | |
180 | +} | |
181 | + | |
182 | +static ssize_t store_slidebar_mode(struct device *dev, | |
183 | + struct device_attribute *attr, | |
184 | + const char *buf, size_t count) | |
185 | +{ | |
186 | + u8 mode; | |
187 | + int error; | |
188 | + | |
189 | + error = kstrtou8(buf, 0, &mode); | |
190 | + if (error) | |
191 | + return error; | |
192 | + | |
193 | + slidebar_mode_set(mode); | |
194 | + | |
195 | + return count; | |
196 | +} | |
197 | + | |
198 | +static DEVICE_ATTR(slidebar_mode, S_IWUSR | S_IRUGO, | |
199 | + show_slidebar_mode, store_slidebar_mode); | |
200 | + | |
201 | +static struct attribute *ideapad_attrs[] = { | |
202 | + &dev_attr_slidebar_mode.attr, | |
203 | + NULL | |
204 | +}; | |
205 | + | |
206 | +static struct attribute_group ideapad_attr_group = { | |
207 | + .attrs = ideapad_attrs | |
208 | +}; | |
209 | + | |
210 | +static const struct attribute_group *ideapad_attr_groups[] = { | |
211 | + &ideapad_attr_group, | |
212 | + NULL | |
213 | +}; | |
214 | + | |
215 | +static int __init ideapad_probe(struct platform_device* pdev) | |
216 | +{ | |
217 | + int err; | |
218 | + | |
219 | + if (!request_region(IDEAPAD_BASE, 3, "ideapad_slidebar")) { | |
220 | + dev_err(&pdev->dev, "IO ports are busy\n"); | |
221 | + return -EBUSY; | |
222 | + } | |
223 | + | |
224 | + slidebar_input_dev = input_allocate_device(); | |
225 | + if (!slidebar_input_dev) { | |
226 | + dev_err(&pdev->dev, "Failed to allocate input device\n"); | |
227 | + err = -ENOMEM; | |
228 | + goto err_release_ports; | |
229 | + } | |
230 | + | |
231 | + slidebar_input_dev->name = "IdeaPad Slidebar"; | |
232 | + slidebar_input_dev->id.bustype = BUS_HOST; | |
233 | + slidebar_input_dev->dev.parent = &pdev->dev; | |
234 | + input_set_capability(slidebar_input_dev, EV_KEY, BTN_TOUCH); | |
235 | + input_set_capability(slidebar_input_dev, EV_ABS, ABS_X); | |
236 | + input_set_abs_params(slidebar_input_dev, ABS_X, 0, 0xff, 0, 0); | |
237 | + | |
238 | + err = i8042_install_filter(slidebar_i8042_filter); | |
239 | + if (err) { | |
240 | + dev_err(&pdev->dev, | |
241 | + "Failed to install i8042 filter: %d\n", err); | |
242 | + goto err_free_dev; | |
243 | + } | |
244 | + | |
245 | + err = input_register_device(slidebar_input_dev); | |
246 | + if (err) { | |
247 | + dev_err(&pdev->dev, | |
248 | + "Failed to register input device: %d\n", err); | |
249 | + goto err_remove_filter; | |
250 | + } | |
251 | + | |
252 | + return 0; | |
253 | + | |
254 | +err_remove_filter: | |
255 | + i8042_remove_filter(slidebar_i8042_filter); | |
256 | +err_free_dev: | |
257 | + input_free_device(slidebar_input_dev); | |
258 | +err_release_ports: | |
259 | + release_region(IDEAPAD_BASE, 3); | |
260 | + return err; | |
261 | +} | |
262 | + | |
263 | +static int ideapad_remove(struct platform_device *pdev) | |
264 | +{ | |
265 | + i8042_remove_filter(slidebar_i8042_filter); | |
266 | + input_unregister_device(slidebar_input_dev); | |
267 | + release_region(IDEAPAD_BASE, 3); | |
268 | + | |
269 | + return 0; | |
270 | +} | |
271 | + | |
272 | +static struct platform_driver slidebar_drv = { | |
273 | + .driver = { | |
274 | + .name = "ideapad_slidebar", | |
275 | + .owner = THIS_MODULE, | |
276 | + }, | |
277 | + .remove = ideapad_remove, | |
278 | +}; | |
279 | + | |
280 | +static int __init ideapad_dmi_check(const struct dmi_system_id *id) | |
281 | +{ | |
282 | + pr_info("Laptop model '%s'\n", id->ident); | |
283 | + return 1; | |
284 | +} | |
285 | + | |
286 | +static const struct dmi_system_id ideapad_dmi[] __initconst = { | |
287 | + { | |
288 | + .ident = "Lenovo IdeaPad Y550", | |
289 | + .matches = { | |
290 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
291 | + DMI_MATCH(DMI_PRODUCT_NAME, "20017"), | |
292 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Y550") | |
293 | + }, | |
294 | + .callback = ideapad_dmi_check | |
295 | + }, | |
296 | + { | |
297 | + .ident = "Lenovo IdeaPad Y550P", | |
298 | + .matches = { | |
299 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
300 | + DMI_MATCH(DMI_PRODUCT_NAME, "20035"), | |
301 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Y550P") | |
302 | + }, | |
303 | + .callback = ideapad_dmi_check | |
304 | + }, | |
305 | + { NULL, } | |
306 | +}; | |
307 | +MODULE_DEVICE_TABLE(dmi, ideapad_dmi); | |
308 | + | |
309 | +static int __init slidebar_init(void) | |
310 | +{ | |
311 | + int err; | |
312 | + | |
313 | + if (!force && !dmi_check_system(ideapad_dmi)) { | |
314 | + pr_err("DMI does not match\n"); | |
315 | + return -ENODEV; | |
316 | + } | |
317 | + | |
318 | + slidebar_platform_dev = platform_device_alloc("ideapad_slidebar", -1); | |
319 | + if (!slidebar_platform_dev) { | |
320 | + pr_err("Not enough memory\n"); | |
321 | + return -ENOMEM; | |
322 | + } | |
323 | + | |
324 | + slidebar_platform_dev->dev.groups = ideapad_attr_groups; | |
325 | + | |
326 | + err = platform_device_add(slidebar_platform_dev); | |
327 | + if (err) { | |
328 | + pr_err("Failed to register platform device\n"); | |
329 | + goto err_free_dev; | |
330 | + } | |
331 | + | |
332 | + err = platform_driver_probe(&slidebar_drv, ideapad_probe); | |
333 | + if (err) { | |
334 | + pr_err("Failed to register platform driver\n"); | |
335 | + goto err_delete_dev; | |
336 | + } | |
337 | + | |
338 | + return 0; | |
339 | + | |
340 | +err_delete_dev: | |
341 | + platform_device_del(slidebar_platform_dev); | |
342 | +err_free_dev: | |
343 | + platform_device_put(slidebar_platform_dev); | |
344 | + return err; | |
345 | +} | |
346 | + | |
347 | +static void __exit slidebar_exit(void) | |
348 | +{ | |
349 | + platform_device_unregister(slidebar_platform_dev); | |
350 | + platform_driver_unregister(&slidebar_drv); | |
351 | +} | |
352 | + | |
353 | +module_init(slidebar_init); | |
354 | +module_exit(slidebar_exit); | |
355 | + | |
356 | +MODULE_AUTHOR("Andrey Moiseev <o2g.org.ru@gmail.com>"); | |
357 | +MODULE_DESCRIPTION("Slidebar input support for some Lenovo IdeaPad laptops"); | |
358 | +MODULE_LICENSE("GPL"); |
drivers/input/misc/pwm-beeper.c
drivers/input/misc/twl6040-vibra.c
... | ... | @@ -257,7 +257,6 @@ |
257 | 257 | |
258 | 258 | static int twl6040_vibra_probe(struct platform_device *pdev) |
259 | 259 | { |
260 | - struct twl6040_vibra_data *pdata = pdev->dev.platform_data; | |
261 | 260 | struct device *twl6040_core_dev = pdev->dev.parent; |
262 | 261 | struct device_node *twl6040_core_node = NULL; |
263 | 262 | struct vibra_info *info; |
... | ... | @@ -270,8 +269,8 @@ |
270 | 269 | "vibra"); |
271 | 270 | #endif |
272 | 271 | |
273 | - if (!pdata && !twl6040_core_node) { | |
274 | - dev_err(&pdev->dev, "platform_data not available\n"); | |
272 | + if (!twl6040_core_node) { | |
273 | + dev_err(&pdev->dev, "parent of node is missing?\n"); | |
275 | 274 | return -EINVAL; |
276 | 275 | } |
277 | 276 | |
278 | 277 | |
... | ... | @@ -284,28 +283,18 @@ |
284 | 283 | info->dev = &pdev->dev; |
285 | 284 | |
286 | 285 | info->twl6040 = dev_get_drvdata(pdev->dev.parent); |
287 | - if (pdata) { | |
288 | - info->vibldrv_res = pdata->vibldrv_res; | |
289 | - info->vibrdrv_res = pdata->vibrdrv_res; | |
290 | - info->viblmotor_res = pdata->viblmotor_res; | |
291 | - info->vibrmotor_res = pdata->vibrmotor_res; | |
292 | - vddvibl_uV = pdata->vddvibl_uV; | |
293 | - vddvibr_uV = pdata->vddvibr_uV; | |
294 | - } else { | |
295 | - of_property_read_u32(twl6040_core_node, "ti,vibldrv-res", | |
296 | - &info->vibldrv_res); | |
297 | - of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res", | |
298 | - &info->vibrdrv_res); | |
299 | - of_property_read_u32(twl6040_core_node, "ti,viblmotor-res", | |
300 | - &info->viblmotor_res); | |
301 | - of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res", | |
302 | - &info->vibrmotor_res); | |
303 | - of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", | |
304 | - &vddvibl_uV); | |
305 | - of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", | |
306 | - &vddvibr_uV); | |
307 | - } | |
308 | 286 | |
287 | + of_property_read_u32(twl6040_core_node, "ti,vibldrv-res", | |
288 | + &info->vibldrv_res); | |
289 | + of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res", | |
290 | + &info->vibrdrv_res); | |
291 | + of_property_read_u32(twl6040_core_node, "ti,viblmotor-res", | |
292 | + &info->viblmotor_res); | |
293 | + of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res", | |
294 | + &info->vibrmotor_res); | |
295 | + of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", &vddvibl_uV); | |
296 | + of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", &vddvibr_uV); | |
297 | + | |
309 | 298 | if ((!info->vibldrv_res && !info->viblmotor_res) || |
310 | 299 | (!info->vibrdrv_res && !info->vibrmotor_res)) { |
311 | 300 | dev_err(info->dev, "invalid vibra driver/motor resistance\n"); |
... | ... | @@ -334,8 +323,8 @@ |
334 | 323 | * When booted with Device tree the regulators are attached to the |
335 | 324 | * parent device (twl6040 MFD core) |
336 | 325 | */ |
337 | - ret = regulator_bulk_get(pdata ? info->dev : twl6040_core_dev, | |
338 | - ARRAY_SIZE(info->supplies), info->supplies); | |
326 | + ret = regulator_bulk_get(twl6040_core_dev, ARRAY_SIZE(info->supplies), | |
327 | + info->supplies); | |
339 | 328 | if (ret) { |
340 | 329 | dev_err(info->dev, "couldn't get regulators %d\n", ret); |
341 | 330 | return ret; |
drivers/input/misc/wistron_btns.c
... | ... | @@ -46,7 +46,6 @@ |
46 | 46 | MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); |
47 | 47 | MODULE_DESCRIPTION("Wistron laptop button driver"); |
48 | 48 | MODULE_LICENSE("GPL v2"); |
49 | -MODULE_VERSION("0.3"); | |
50 | 49 | |
51 | 50 | static bool force; /* = 0; */ |
52 | 51 | module_param(force, bool, 0); |
... | ... | @@ -563,7 +562,7 @@ |
563 | 562 | { KE_KEY, 0x36, {KEY_WWW} }, |
564 | 563 | { KE_WIFI, 0x30 }, |
565 | 564 | { KE_BLUETOOTH, 0x44 }, |
566 | - { KE_END, FE_UNTESTED } | |
565 | + { KE_END, 0 } | |
567 | 566 | }; |
568 | 567 | |
569 | 568 | static struct key_entry keymap_wistron_generic[] __initdata = { |
... | ... | @@ -635,7 +634,7 @@ |
635 | 634 | * a list of buttons and their key codes (reported when loading this module |
636 | 635 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. |
637 | 636 | */ |
638 | -static const struct dmi_system_id __initconst dmi_ids[] = { | |
637 | +static const struct dmi_system_id dmi_ids[] __initconst = { | |
639 | 638 | { |
640 | 639 | /* Fujitsu-Siemens Amilo Pro V2000 */ |
641 | 640 | .callback = dmi_matched, |
... | ... | @@ -972,6 +971,7 @@ |
972 | 971 | }, |
973 | 972 | { NULL, } |
974 | 973 | }; |
974 | +MODULE_DEVICE_TABLE(dmi, dmi_ids); | |
975 | 975 | |
976 | 976 | /* Copy the good keymap, as the original ones are free'd */ |
977 | 977 | static int __init copy_keymap(void) |
drivers/input/mouse/lifebook.c
drivers/input/mouse/synaptics.c
... | ... | @@ -1433,7 +1433,7 @@ |
1433 | 1433 | |
1434 | 1434 | static bool impaired_toshiba_kbc; |
1435 | 1435 | |
1436 | -static const struct dmi_system_id __initconst toshiba_dmi_table[] = { | |
1436 | +static const struct dmi_system_id toshiba_dmi_table[] __initconst = { | |
1437 | 1437 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) |
1438 | 1438 | { |
1439 | 1439 | /* Toshiba Satellite */ |
... | ... | @@ -1472,7 +1472,7 @@ |
1472 | 1472 | |
1473 | 1473 | static bool broken_olpc_ec; |
1474 | 1474 | |
1475 | -static const struct dmi_system_id __initconst olpc_dmi_table[] = { | |
1475 | +static const struct dmi_system_id olpc_dmi_table[] __initconst = { | |
1476 | 1476 | #if defined(CONFIG_DMI) && defined(CONFIG_OLPC) |
1477 | 1477 | { |
1478 | 1478 | /* OLPC XO-1 or XO-1.5 */ |
drivers/input/serio/arc_ps2.c
... | ... | @@ -189,12 +189,6 @@ |
189 | 189 | int irq; |
190 | 190 | int error, id, i; |
191 | 191 | |
192 | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
193 | - if (!res) { | |
194 | - dev_err(&pdev->dev, "no IO memory defined\n"); | |
195 | - return -EINVAL; | |
196 | - } | |
197 | - | |
198 | 192 | irq = platform_get_irq_byname(pdev, "arc_ps2_irq"); |
199 | 193 | if (irq < 0) { |
200 | 194 | dev_err(&pdev->dev, "no IRQ defined\n"); |
... | ... | @@ -208,6 +202,7 @@ |
208 | 202 | return -ENOMEM; |
209 | 203 | } |
210 | 204 | |
205 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
211 | 206 | arc_ps2->addr = devm_ioremap_resource(&pdev->dev, res); |
212 | 207 | if (IS_ERR(arc_ps2->addr)) |
213 | 208 | return PTR_ERR(arc_ps2->addr); |
drivers/input/serio/i8042.h
... | ... | @@ -41,30 +41,6 @@ |
41 | 41 | #define I8042_CTL_TIMEOUT 10000 |
42 | 42 | |
43 | 43 | /* |
44 | - * Status register bits. | |
45 | - */ | |
46 | - | |
47 | -#define I8042_STR_PARITY 0x80 | |
48 | -#define I8042_STR_TIMEOUT 0x40 | |
49 | -#define I8042_STR_AUXDATA 0x20 | |
50 | -#define I8042_STR_KEYLOCK 0x10 | |
51 | -#define I8042_STR_CMDDAT 0x08 | |
52 | -#define I8042_STR_MUXERR 0x04 | |
53 | -#define I8042_STR_IBF 0x02 | |
54 | -#define I8042_STR_OBF 0x01 | |
55 | - | |
56 | -/* | |
57 | - * Control register bits. | |
58 | - */ | |
59 | - | |
60 | -#define I8042_CTR_KBDINT 0x01 | |
61 | -#define I8042_CTR_AUXINT 0x02 | |
62 | -#define I8042_CTR_IGNKEYLOCK 0x08 | |
63 | -#define I8042_CTR_KBDDIS 0x10 | |
64 | -#define I8042_CTR_AUXDIS 0x20 | |
65 | -#define I8042_CTR_XLATE 0x40 | |
66 | - | |
67 | -/* | |
68 | 44 | * Return codes. |
69 | 45 | */ |
70 | 46 |
drivers/input/serio/olpc_apsp.c
... | ... | @@ -183,9 +183,6 @@ |
183 | 183 | |
184 | 184 | np = pdev->dev.of_node; |
185 | 185 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
186 | - if (!res) | |
187 | - return -ENOENT; | |
188 | - | |
189 | 186 | priv->base = devm_ioremap_resource(&pdev->dev, res); |
190 | 187 | if (IS_ERR(priv->base)) { |
191 | 188 | dev_err(&pdev->dev, "Failed to map WTM registers\n"); |
drivers/input/tablet/wacom_sys.c
... | ... | @@ -221,39 +221,6 @@ |
221 | 221 | return logical_extents / physical_extents; |
222 | 222 | } |
223 | 223 | |
224 | -/* | |
225 | - * The physical dimension specified by the HID descriptor is likely not in | |
226 | - * the "100th of a mm" units expected by wacom_calculate_touch_res. This | |
227 | - * function adjusts the value of [xy]_phy based on the unit and exponent | |
228 | - * provided by the HID descriptor. If an error occurs durring conversion | |
229 | - * (e.g. from the unit being left unspecified) [xy]_phy is not modified. | |
230 | - */ | |
231 | -static void wacom_fix_phy_from_hid(struct wacom_features *features) | |
232 | -{ | |
233 | - int xres = wacom_calc_hid_res(features->x_max, features->x_phy, | |
234 | - features->unit, features->unitExpo); | |
235 | - int yres = wacom_calc_hid_res(features->y_max, features->y_phy, | |
236 | - features->unit, features->unitExpo); | |
237 | - | |
238 | - if (xres > 0 && yres > 0) { | |
239 | - features->x_phy = (100 * features->x_max) / xres; | |
240 | - features->y_phy = (100 * features->y_max) / yres; | |
241 | - } | |
242 | -} | |
243 | - | |
244 | -/* | |
245 | - * Static values for max X/Y and resolution of Pen interface is stored in | |
246 | - * features. This mean physical size of active area can be computed. | |
247 | - * This is useful to do when Pen and Touch have same active area of tablet. | |
248 | - * This means for Touch device, we only need to find max X/Y value and we | |
249 | - * have enough information to compute resolution of touch. | |
250 | - */ | |
251 | -static void wacom_set_phy_from_res(struct wacom_features *features) | |
252 | -{ | |
253 | - features->x_phy = (features->x_max * 100) / features->x_resolution; | |
254 | - features->y_phy = (features->y_max * 100) / features->y_resolution; | |
255 | -} | |
256 | - | |
257 | 224 | static int wacom_parse_logical_collection(unsigned char *report, |
258 | 225 | struct wacom_features *features) |
259 | 226 | { |
... | ... | @@ -265,8 +232,6 @@ |
265 | 232 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
266 | 233 | features->device_type = BTN_TOOL_FINGER; |
267 | 234 | |
268 | - wacom_set_phy_from_res(features); | |
269 | - | |
270 | 235 | features->x_max = features->y_max = |
271 | 236 | get_unaligned_le16(&report[10]); |
272 | 237 | |
... | ... | @@ -640,9 +605,6 @@ |
640 | 605 | } |
641 | 606 | } |
642 | 607 | error = wacom_parse_hid(intf, hid_desc, features); |
643 | - if (error) | |
644 | - goto out; | |
645 | - wacom_fix_phy_from_hid(features); | |
646 | 608 | |
647 | 609 | out: |
648 | 610 | return error; |
... | ... | @@ -1228,7 +1190,6 @@ |
1228 | 1190 | *((struct wacom_features *)id->driver_info); |
1229 | 1191 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; |
1230 | 1192 | wacom_wac2->features.device_type = BTN_TOOL_FINGER; |
1231 | - wacom_set_phy_from_res(&wacom_wac2->features); | |
1232 | 1193 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; |
1233 | 1194 | error = wacom_register_input(wacom2); |
1234 | 1195 | if (error) |
... | ... | @@ -1251,6 +1212,33 @@ |
1251 | 1212 | return; |
1252 | 1213 | } |
1253 | 1214 | |
1215 | +/* | |
1216 | + * Not all devices report physical dimensions from HID. | |
1217 | + * Compute the default from hardcoded logical dimension | |
1218 | + * and resolution before driver overwrites them. | |
1219 | + */ | |
1220 | +static void wacom_set_default_phy(struct wacom_features *features) | |
1221 | +{ | |
1222 | + if (features->x_resolution) { | |
1223 | + features->x_phy = (features->x_max * 100) / | |
1224 | + features->x_resolution; | |
1225 | + features->y_phy = (features->y_max * 100) / | |
1226 | + features->y_resolution; | |
1227 | + } | |
1228 | +} | |
1229 | + | |
1230 | +static void wacom_calculate_res(struct wacom_features *features) | |
1231 | +{ | |
1232 | + features->x_resolution = wacom_calc_hid_res(features->x_max, | |
1233 | + features->x_phy, | |
1234 | + features->unit, | |
1235 | + features->unitExpo); | |
1236 | + features->y_resolution = wacom_calc_hid_res(features->y_max, | |
1237 | + features->y_phy, | |
1238 | + features->unit, | |
1239 | + features->unitExpo); | |
1240 | +} | |
1241 | + | |
1254 | 1242 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
1255 | 1243 | { |
1256 | 1244 | struct usb_device *dev = interface_to_usbdev(intf); |
... | ... | @@ -1297,6 +1285,9 @@ |
1297 | 1285 | |
1298 | 1286 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
1299 | 1287 | |
1288 | + /* set the default size in case we do not get them from hid */ | |
1289 | + wacom_set_default_phy(features); | |
1290 | + | |
1300 | 1291 | /* Retrieve the physical and logical size for touch devices */ |
1301 | 1292 | error = wacom_retrieve_hid_descriptor(intf, features); |
1302 | 1293 | if (error) |
... | ... | @@ -1312,8 +1303,6 @@ |
1312 | 1303 | features->device_type = BTN_TOOL_FINGER; |
1313 | 1304 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
1314 | 1305 | |
1315 | - wacom_set_phy_from_res(features); | |
1316 | - | |
1317 | 1306 | features->x_max = 4096; |
1318 | 1307 | features->y_max = 4096; |
1319 | 1308 | } else { |
... | ... | @@ -1323,6 +1312,13 @@ |
1323 | 1312 | |
1324 | 1313 | wacom_setup_device_quirks(features); |
1325 | 1314 | |
1315 | + /* set unit to "100th of a mm" for devices not reported by HID */ | |
1316 | + if (!features->unit) { | |
1317 | + features->unit = 0x11; | |
1318 | + features->unitExpo = 16 - 3; | |
1319 | + } | |
1320 | + wacom_calculate_res(features); | |
1321 | + | |
1326 | 1322 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
1327 | 1323 | |
1328 | 1324 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
... | ... | @@ -1334,7 +1330,6 @@ |
1334 | 1330 | " Pen" : " Finger", |
1335 | 1331 | sizeof(wacom_wac->name)); |
1336 | 1332 | |
1337 | - | |
1338 | 1333 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); |
1339 | 1334 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) |
1340 | 1335 | other_dev = dev; |
1341 | 1336 | |
... | ... | @@ -1366,8 +1361,10 @@ |
1366 | 1361 | usb_set_intfdata(intf, wacom); |
1367 | 1362 | |
1368 | 1363 | if (features->quirks & WACOM_QUIRK_MONITOR) { |
1369 | - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) | |
1364 | + if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | |
1365 | + error = -EIO; | |
1370 | 1366 | goto fail5; |
1367 | + } | |
1371 | 1368 | } |
1372 | 1369 | |
1373 | 1370 | return 0; |
... | ... | @@ -1422,8 +1419,8 @@ |
1422 | 1419 | wacom_query_tablet_data(intf, features); |
1423 | 1420 | wacom_led_control(wacom); |
1424 | 1421 | |
1425 | - if ((wacom->open || features->quirks & WACOM_QUIRK_MONITOR) | |
1426 | - && usb_submit_urb(wacom->irq, GFP_NOIO) < 0) | |
1422 | + if ((wacom->open || (features->quirks & WACOM_QUIRK_MONITOR)) && | |
1423 | + usb_submit_urb(wacom->irq, GFP_NOIO) < 0) | |
1427 | 1424 | rv = -EIO; |
1428 | 1425 | |
1429 | 1426 | mutex_unlock(&wacom->lock); |
drivers/input/tablet/wacom_wac.c
... | ... | @@ -1445,13 +1445,6 @@ |
1445 | 1445 | } |
1446 | 1446 | } |
1447 | 1447 | |
1448 | -static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | |
1449 | - unsigned int physical_max) | |
1450 | -{ | |
1451 | - /* Touch physical dimensions are in 100th of mm */ | |
1452 | - return (logical_max * 100) / physical_max; | |
1453 | -} | |
1454 | - | |
1455 | 1448 | static void wacom_abs_set_axis(struct input_dev *input_dev, |
1456 | 1449 | struct wacom_wac *wacom_wac) |
1457 | 1450 | { |
1458 | 1451 | |
... | ... | @@ -1475,11 +1468,9 @@ |
1475 | 1468 | input_set_abs_params(input_dev, ABS_Y, 0, |
1476 | 1469 | features->y_max, features->y_fuzz, 0); |
1477 | 1470 | input_abs_set_res(input_dev, ABS_X, |
1478 | - wacom_calculate_touch_res(features->x_max, | |
1479 | - features->x_phy)); | |
1471 | + features->x_resolution); | |
1480 | 1472 | input_abs_set_res(input_dev, ABS_Y, |
1481 | - wacom_calculate_touch_res(features->y_max, | |
1482 | - features->y_phy)); | |
1473 | + features->y_resolution); | |
1483 | 1474 | } |
1484 | 1475 | |
1485 | 1476 | if (features->touch_max > 1) { |
1486 | 1477 | |
... | ... | @@ -1488,11 +1479,9 @@ |
1488 | 1479 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, |
1489 | 1480 | features->y_max, features->y_fuzz, 0); |
1490 | 1481 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, |
1491 | - wacom_calculate_touch_res(features->x_max, | |
1492 | - features->x_phy)); | |
1482 | + features->x_resolution); | |
1493 | 1483 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, |
1494 | - wacom_calculate_touch_res(features->y_max, | |
1495 | - features->y_phy)); | |
1484 | + features->y_resolution); | |
1496 | 1485 | } |
1497 | 1486 | } |
1498 | 1487 | } |
drivers/input/touchscreen/cy8ctmg110_ts.c
... | ... | @@ -291,7 +291,7 @@ |
291 | 291 | return err; |
292 | 292 | } |
293 | 293 | |
294 | -#ifdef CONFIG_PM | |
294 | +#ifdef CONFIG_PM_SLEEP | |
295 | 295 | static int cy8ctmg110_suspend(struct device *dev) |
296 | 296 | { |
297 | 297 | struct i2c_client *client = to_i2c_client(dev); |
298 | 298 | |
... | ... | @@ -319,9 +319,9 @@ |
319 | 319 | } |
320 | 320 | return 0; |
321 | 321 | } |
322 | +#endif | |
322 | 323 | |
323 | 324 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); |
324 | -#endif | |
325 | 325 | |
326 | 326 | static int cy8ctmg110_remove(struct i2c_client *client) |
327 | 327 | { |
328 | 328 | |
... | ... | @@ -351,9 +351,7 @@ |
351 | 351 | .driver = { |
352 | 352 | .owner = THIS_MODULE, |
353 | 353 | .name = CY8CTMG110_DRIVER_NAME, |
354 | -#ifdef CONFIG_PM | |
355 | 354 | .pm = &cy8ctmg110_pm, |
356 | -#endif | |
357 | 355 | }, |
358 | 356 | .id_table = cy8ctmg110_idtable, |
359 | 357 | .probe = cy8ctmg110_probe, |
drivers/input/touchscreen/cyttsp4_core.c
... | ... | @@ -1246,9 +1246,6 @@ |
1246 | 1246 | |
1247 | 1247 | dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__); |
1248 | 1248 | |
1249 | - if (!cd) | |
1250 | - return; | |
1251 | - | |
1252 | 1249 | if (!work_pending(&cd->watchdog_work)) |
1253 | 1250 | schedule_work(&cd->watchdog_work); |
1254 | 1251 | |
... | ... | @@ -1552,106 +1549,6 @@ |
1552 | 1549 | return rc; |
1553 | 1550 | } |
1554 | 1551 | |
1555 | -static int cyttsp4_core_sleep(struct cyttsp4 *cd) | |
1556 | -{ | |
1557 | - int rc; | |
1558 | - | |
1559 | - rc = cyttsp4_request_exclusive(cd, cd->dev, | |
1560 | - CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT); | |
1561 | - if (rc < 0) { | |
1562 | - dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | |
1563 | - __func__, cd->exclusive_dev, cd->dev); | |
1564 | - return 0; | |
1565 | - } | |
1566 | - | |
1567 | - rc = cyttsp4_core_sleep_(cd); | |
1568 | - | |
1569 | - if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | |
1570 | - dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | |
1571 | - else | |
1572 | - dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | |
1573 | - | |
1574 | - return rc; | |
1575 | -} | |
1576 | - | |
1577 | -static int cyttsp4_core_wake_(struct cyttsp4 *cd) | |
1578 | -{ | |
1579 | - struct device *dev = cd->dev; | |
1580 | - int rc; | |
1581 | - u8 mode; | |
1582 | - int t; | |
1583 | - | |
1584 | - /* Already woken? */ | |
1585 | - mutex_lock(&cd->system_lock); | |
1586 | - if (cd->sleep_state == SS_SLEEP_OFF) { | |
1587 | - mutex_unlock(&cd->system_lock); | |
1588 | - return 0; | |
1589 | - } | |
1590 | - cd->int_status &= ~CY_INT_IGNORE; | |
1591 | - cd->int_status |= CY_INT_AWAKE; | |
1592 | - cd->sleep_state = SS_WAKING; | |
1593 | - | |
1594 | - if (cd->cpdata->power) { | |
1595 | - dev_dbg(dev, "%s: Power up HW\n", __func__); | |
1596 | - rc = cd->cpdata->power(cd->cpdata, 1, dev, &cd->ignore_irq); | |
1597 | - } else { | |
1598 | - dev_dbg(dev, "%s: No power function\n", __func__); | |
1599 | - rc = -ENOSYS; | |
1600 | - } | |
1601 | - if (rc < 0) { | |
1602 | - dev_err(dev, "%s: HW Power up fails r=%d\n", | |
1603 | - __func__, rc); | |
1604 | - | |
1605 | - /* Initiate a read transaction to wake up */ | |
1606 | - cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode); | |
1607 | - } else | |
1608 | - dev_vdbg(cd->dev, "%s: HW power up succeeds\n", | |
1609 | - __func__); | |
1610 | - mutex_unlock(&cd->system_lock); | |
1611 | - | |
1612 | - t = wait_event_timeout(cd->wait_q, | |
1613 | - (cd->int_status & CY_INT_AWAKE) == 0, | |
1614 | - msecs_to_jiffies(CY_CORE_WAKEUP_TIMEOUT)); | |
1615 | - if (IS_TMO(t)) { | |
1616 | - dev_err(dev, "%s: TMO waiting for wakeup\n", __func__); | |
1617 | - mutex_lock(&cd->system_lock); | |
1618 | - cd->int_status &= ~CY_INT_AWAKE; | |
1619 | - /* Try starting up */ | |
1620 | - cyttsp4_queue_startup_(cd); | |
1621 | - mutex_unlock(&cd->system_lock); | |
1622 | - } | |
1623 | - | |
1624 | - mutex_lock(&cd->system_lock); | |
1625 | - cd->sleep_state = SS_SLEEP_OFF; | |
1626 | - mutex_unlock(&cd->system_lock); | |
1627 | - | |
1628 | - cyttsp4_start_wd_timer(cd); | |
1629 | - | |
1630 | - return 0; | |
1631 | -} | |
1632 | - | |
1633 | -static int cyttsp4_core_wake(struct cyttsp4 *cd) | |
1634 | -{ | |
1635 | - int rc; | |
1636 | - | |
1637 | - rc = cyttsp4_request_exclusive(cd, cd->dev, | |
1638 | - CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT); | |
1639 | - if (rc < 0) { | |
1640 | - dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | |
1641 | - __func__, cd->exclusive_dev, cd->dev); | |
1642 | - return 0; | |
1643 | - } | |
1644 | - | |
1645 | - rc = cyttsp4_core_wake_(cd); | |
1646 | - | |
1647 | - if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | |
1648 | - dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | |
1649 | - else | |
1650 | - dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | |
1651 | - | |
1652 | - return rc; | |
1653 | -} | |
1654 | - | |
1655 | 1552 | static int cyttsp4_startup_(struct cyttsp4 *cd) |
1656 | 1553 | { |
1657 | 1554 | int retry = CY_CORE_STARTUP_RETRY_COUNT; |
... | ... | @@ -1821,6 +1718,106 @@ |
1821 | 1718 | } |
1822 | 1719 | |
1823 | 1720 | #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) |
1721 | +static int cyttsp4_core_sleep(struct cyttsp4 *cd) | |
1722 | +{ | |
1723 | + int rc; | |
1724 | + | |
1725 | + rc = cyttsp4_request_exclusive(cd, cd->dev, | |
1726 | + CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT); | |
1727 | + if (rc < 0) { | |
1728 | + dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | |
1729 | + __func__, cd->exclusive_dev, cd->dev); | |
1730 | + return 0; | |
1731 | + } | |
1732 | + | |
1733 | + rc = cyttsp4_core_sleep_(cd); | |
1734 | + | |
1735 | + if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | |
1736 | + dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | |
1737 | + else | |
1738 | + dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | |
1739 | + | |
1740 | + return rc; | |
1741 | +} | |
1742 | + | |
1743 | +static int cyttsp4_core_wake_(struct cyttsp4 *cd) | |
1744 | +{ | |
1745 | + struct device *dev = cd->dev; | |
1746 | + int rc; | |
1747 | + u8 mode; | |
1748 | + int t; | |
1749 | + | |
1750 | + /* Already woken? */ | |
1751 | + mutex_lock(&cd->system_lock); | |
1752 | + if (cd->sleep_state == SS_SLEEP_OFF) { | |
1753 | + mutex_unlock(&cd->system_lock); | |
1754 | + return 0; | |
1755 | + } | |
1756 | + cd->int_status &= ~CY_INT_IGNORE; | |
1757 | + cd->int_status |= CY_INT_AWAKE; | |
1758 | + cd->sleep_state = SS_WAKING; | |
1759 | + | |
1760 | + if (cd->cpdata->power) { | |
1761 | + dev_dbg(dev, "%s: Power up HW\n", __func__); | |
1762 | + rc = cd->cpdata->power(cd->cpdata, 1, dev, &cd->ignore_irq); | |
1763 | + } else { | |
1764 | + dev_dbg(dev, "%s: No power function\n", __func__); | |
1765 | + rc = -ENOSYS; | |
1766 | + } | |
1767 | + if (rc < 0) { | |
1768 | + dev_err(dev, "%s: HW Power up fails r=%d\n", | |
1769 | + __func__, rc); | |
1770 | + | |
1771 | + /* Initiate a read transaction to wake up */ | |
1772 | + cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode); | |
1773 | + } else | |
1774 | + dev_vdbg(cd->dev, "%s: HW power up succeeds\n", | |
1775 | + __func__); | |
1776 | + mutex_unlock(&cd->system_lock); | |
1777 | + | |
1778 | + t = wait_event_timeout(cd->wait_q, | |
1779 | + (cd->int_status & CY_INT_AWAKE) == 0, | |
1780 | + msecs_to_jiffies(CY_CORE_WAKEUP_TIMEOUT)); | |
1781 | + if (IS_TMO(t)) { | |
1782 | + dev_err(dev, "%s: TMO waiting for wakeup\n", __func__); | |
1783 | + mutex_lock(&cd->system_lock); | |
1784 | + cd->int_status &= ~CY_INT_AWAKE; | |
1785 | + /* Try starting up */ | |
1786 | + cyttsp4_queue_startup_(cd); | |
1787 | + mutex_unlock(&cd->system_lock); | |
1788 | + } | |
1789 | + | |
1790 | + mutex_lock(&cd->system_lock); | |
1791 | + cd->sleep_state = SS_SLEEP_OFF; | |
1792 | + mutex_unlock(&cd->system_lock); | |
1793 | + | |
1794 | + cyttsp4_start_wd_timer(cd); | |
1795 | + | |
1796 | + return 0; | |
1797 | +} | |
1798 | + | |
1799 | +static int cyttsp4_core_wake(struct cyttsp4 *cd) | |
1800 | +{ | |
1801 | + int rc; | |
1802 | + | |
1803 | + rc = cyttsp4_request_exclusive(cd, cd->dev, | |
1804 | + CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT); | |
1805 | + if (rc < 0) { | |
1806 | + dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n", | |
1807 | + __func__, cd->exclusive_dev, cd->dev); | |
1808 | + return 0; | |
1809 | + } | |
1810 | + | |
1811 | + rc = cyttsp4_core_wake_(cd); | |
1812 | + | |
1813 | + if (cyttsp4_release_exclusive(cd, cd->dev) < 0) | |
1814 | + dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); | |
1815 | + else | |
1816 | + dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__); | |
1817 | + | |
1818 | + return rc; | |
1819 | +} | |
1820 | + | |
1824 | 1821 | static int cyttsp4_core_suspend(struct device *dev) |
1825 | 1822 | { |
1826 | 1823 | struct cyttsp4 *cd = dev_get_drvdata(dev); |
drivers/input/touchscreen/eeti_ts.c
... | ... | @@ -264,7 +264,7 @@ |
264 | 264 | return 0; |
265 | 265 | } |
266 | 266 | |
267 | -#ifdef CONFIG_PM | |
267 | +#ifdef CONFIG_PM_SLEEP | |
268 | 268 | static int eeti_ts_suspend(struct device *dev) |
269 | 269 | { |
270 | 270 | struct i2c_client *client = to_i2c_client(dev); |
271 | 271 | |
... | ... | @@ -302,9 +302,9 @@ |
302 | 302 | |
303 | 303 | return 0; |
304 | 304 | } |
305 | +#endif | |
305 | 306 | |
306 | 307 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
307 | -#endif | |
308 | 308 | |
309 | 309 | static const struct i2c_device_id eeti_ts_id[] = { |
310 | 310 | { "eeti_ts", 0 }, |
311 | 311 | |
... | ... | @@ -315,9 +315,7 @@ |
315 | 315 | static struct i2c_driver eeti_ts_driver = { |
316 | 316 | .driver = { |
317 | 317 | .name = "eeti_ts", |
318 | -#ifdef CONFIG_PM | |
319 | 318 | .pm = &eeti_ts_pm, |
320 | -#endif | |
321 | 319 | }, |
322 | 320 | .probe = eeti_ts_probe, |
323 | 321 | .remove = eeti_ts_remove, |
drivers/input/touchscreen/htcpen.c
drivers/input/touchscreen/max11801_ts.c
... | ... | @@ -181,12 +181,11 @@ |
181 | 181 | struct input_dev *input_dev; |
182 | 182 | int error; |
183 | 183 | |
184 | - data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); | |
185 | - input_dev = input_allocate_device(); | |
184 | + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | |
185 | + input_dev = devm_input_allocate_device(&client->dev); | |
186 | 186 | if (!data || !input_dev) { |
187 | 187 | dev_err(&client->dev, "Failed to allocate memory\n"); |
188 | - error = -ENOMEM; | |
189 | - goto err_free_mem; | |
188 | + return -ENOMEM; | |
190 | 189 | } |
191 | 190 | |
192 | 191 | data->client = client; |
193 | 192 | |
194 | 193 | |
195 | 194 | |
196 | 195 | |
... | ... | @@ -205,40 +204,23 @@ |
205 | 204 | |
206 | 205 | max11801_ts_phy_init(data); |
207 | 206 | |
208 | - error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, | |
209 | - IRQF_TRIGGER_LOW | IRQF_ONESHOT, | |
210 | - "max11801_ts", data); | |
207 | + error = devm_request_threaded_irq(&client->dev, client->irq, NULL, | |
208 | + max11801_ts_interrupt, | |
209 | + IRQF_TRIGGER_LOW | IRQF_ONESHOT, | |
210 | + "max11801_ts", data); | |
211 | 211 | if (error) { |
212 | 212 | dev_err(&client->dev, "Failed to register interrupt\n"); |
213 | - goto err_free_mem; | |
213 | + return error; | |
214 | 214 | } |
215 | 215 | |
216 | 216 | error = input_register_device(data->input_dev); |
217 | 217 | if (error) |
218 | - goto err_free_irq; | |
218 | + return error; | |
219 | 219 | |
220 | 220 | i2c_set_clientdata(client, data); |
221 | 221 | return 0; |
222 | - | |
223 | -err_free_irq: | |
224 | - free_irq(client->irq, data); | |
225 | -err_free_mem: | |
226 | - input_free_device(input_dev); | |
227 | - kfree(data); | |
228 | - return error; | |
229 | 222 | } |
230 | 223 | |
231 | -static int max11801_ts_remove(struct i2c_client *client) | |
232 | -{ | |
233 | - struct max11801_data *data = i2c_get_clientdata(client); | |
234 | - | |
235 | - free_irq(client->irq, data); | |
236 | - input_unregister_device(data->input_dev); | |
237 | - kfree(data); | |
238 | - | |
239 | - return 0; | |
240 | -} | |
241 | - | |
242 | 224 | static const struct i2c_device_id max11801_ts_id[] = { |
243 | 225 | {"max11801", 0}, |
244 | 226 | { } |
... | ... | @@ -252,7 +234,6 @@ |
252 | 234 | }, |
253 | 235 | .id_table = max11801_ts_id, |
254 | 236 | .probe = max11801_ts_probe, |
255 | - .remove = max11801_ts_remove, | |
256 | 237 | }; |
257 | 238 | |
258 | 239 | module_i2c_driver(max11801_ts_driver); |
drivers/tty/sysrq.c
... | ... | @@ -45,6 +45,7 @@ |
45 | 45 | #include <linux/moduleparam.h> |
46 | 46 | #include <linux/jiffies.h> |
47 | 47 | #include <linux/syscalls.h> |
48 | +#include <linux/of.h> | |
48 | 49 | |
49 | 50 | #include <asm/ptrace.h> |
50 | 51 | #include <asm/irq_regs.h> |
... | ... | @@ -681,6 +682,40 @@ |
681 | 682 | } |
682 | 683 | } |
683 | 684 | |
685 | +#ifdef CONFIG_OF | |
686 | +static void sysrq_of_get_keyreset_config(void) | |
687 | +{ | |
688 | + u32 key; | |
689 | + struct device_node *np; | |
690 | + struct property *prop; | |
691 | + const __be32 *p; | |
692 | + | |
693 | + np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq"); | |
694 | + if (!np) { | |
695 | + pr_debug("No sysrq node found"); | |
696 | + return; | |
697 | + } | |
698 | + | |
699 | + /* Reset in case a __weak definition was present */ | |
700 | + sysrq_reset_seq_len = 0; | |
701 | + | |
702 | + of_property_for_each_u32(np, "keyset", prop, p, key) { | |
703 | + if (key == KEY_RESERVED || key > KEY_MAX || | |
704 | + sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX) | |
705 | + break; | |
706 | + | |
707 | + sysrq_reset_seq[sysrq_reset_seq_len++] = (unsigned short)key; | |
708 | + } | |
709 | + | |
710 | + /* Get reset timeout if any. */ | |
711 | + of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms); | |
712 | +} | |
713 | +#else | |
714 | +static void sysrq_of_get_keyreset_config(void) | |
715 | +{ | |
716 | +} | |
717 | +#endif | |
718 | + | |
684 | 719 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) |
685 | 720 | { |
686 | 721 | struct sysrq_state *sysrq = |
... | ... | @@ -914,6 +949,7 @@ |
914 | 949 | int error; |
915 | 950 | int i; |
916 | 951 | |
952 | + /* First check if a __weak interface was instantiated. */ | |
917 | 953 | for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) { |
918 | 954 | key = platform_sysrq_reset_seq[i]; |
919 | 955 | if (key == KEY_RESERVED || key > KEY_MAX) |
... | ... | @@ -921,6 +957,12 @@ |
921 | 957 | |
922 | 958 | sysrq_reset_seq[sysrq_reset_seq_len++] = key; |
923 | 959 | } |
960 | + | |
961 | + /* | |
962 | + * DT configuration takes precedence over anything that would | |
963 | + * have been defined via the __weak interface. | |
964 | + */ | |
965 | + sysrq_of_get_keyreset_config(); | |
924 | 966 | |
925 | 967 | error = input_register_handler(&sysrq_handler); |
926 | 968 | if (error) |
include/linux/i8042.h
... | ... | @@ -31,6 +31,30 @@ |
31 | 31 | #define I8042_CMD_MUX_PFX 0x0090 |
32 | 32 | #define I8042_CMD_MUX_SEND 0x1090 |
33 | 33 | |
34 | +/* | |
35 | + * Status register bits. | |
36 | + */ | |
37 | + | |
38 | +#define I8042_STR_PARITY 0x80 | |
39 | +#define I8042_STR_TIMEOUT 0x40 | |
40 | +#define I8042_STR_AUXDATA 0x20 | |
41 | +#define I8042_STR_KEYLOCK 0x10 | |
42 | +#define I8042_STR_CMDDAT 0x08 | |
43 | +#define I8042_STR_MUXERR 0x04 | |
44 | +#define I8042_STR_IBF 0x02 | |
45 | +#define I8042_STR_OBF 0x01 | |
46 | + | |
47 | +/* | |
48 | + * Control register bits. | |
49 | + */ | |
50 | + | |
51 | +#define I8042_CTR_KBDINT 0x01 | |
52 | +#define I8042_CTR_AUXINT 0x02 | |
53 | +#define I8042_CTR_IGNKEYLOCK 0x08 | |
54 | +#define I8042_CTR_KBDDIS 0x10 | |
55 | +#define I8042_CTR_AUXDIS 0x20 | |
56 | +#define I8042_CTR_XLATE 0x40 | |
57 | + | |
34 | 58 | struct serio; |
35 | 59 | |
36 | 60 | #if defined(CONFIG_SERIO_I8042) || defined(CONFIG_SERIO_I8042_MODULE) |