diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:34:29 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:34:29 -0400 |
| commit | 2c01e7bc46f10e9190818437e564f7e0db875ae9 (patch) | |
| tree | 8b06c85d69754f7df27f7fb42520f6e2ceaea907 /drivers/input/touchscreen | |
| parent | ab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (diff) | |
| parent | e644dae645e167d154c0526358940986682a72b0 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input layer updates from Dmitry Torokhov:
- a bunch of new drivers (DA9052/53 touchscreenn controller, Synaptics
Navpoint, LM8333 keypads, Wacom I2C touhscreen);
- updates to existing touchpad drivers (ALPS, Sntelic);
- Wacom driver now supports Intuos5;
- device-tree bindings in numerous drivers;
- other cleanups and fixes.
Fix annoying conflict in drivers/input/tablet/wacom_wac.c that I think
implies that the input layer device naming is broken, but let's see. I
brough it up with Dmitry.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (57 commits)
Input: matrix-keymap - fix building keymaps
Input: spear-keyboard - document DT bindings
Input: spear-keyboard - add device tree bindings
Input: matrix-keymap - wire up device tree support
Input: matrix-keymap - uninline and prepare for device tree support
Input: adp5588 - add support for gpio names
Input: omap-keypad - dynamically handle register offsets
Input: synaptics - fix compile warning
MAINTAINERS: adjust input-related patterns
Input: ALPS - switch to using input_mt_report_finger_count
Input: ALPS - add semi-MT support for v4 protocol
Input: Add Synaptics NavPoint (PXA27x SSP/SPI) driver
Input: atmel_mxt_ts - dump each message on just 1 line
Input: atmel_mxt_ts - do not read extra (checksum) byte
Input: atmel_mxt_ts - verify object size in mxt_write_object
Input: atmel_mxt_ts - only allow root to update firmware
Input: atmel_mxt_ts - use CONFIG_PM_SLEEP
Input: sentelic - report device's production serial number
Input: tl6040-vibra - Device Tree support
Input: evdev - properly handle read/write with count 0
...
Diffstat (limited to 'drivers/input/touchscreen')
21 files changed, 734 insertions, 242 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 75838d7710ce..98d263504eea 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -187,6 +187,23 @@ config TOUCHSCREEN_DA9034 | |||
| 187 | Say Y here to enable the support for the touchscreen found | 187 | Say Y here to enable the support for the touchscreen found |
| 188 | on Dialog Semiconductor DA9034 PMIC. | 188 | on Dialog Semiconductor DA9034 PMIC. |
| 189 | 189 | ||
| 190 | If unsure, say N. | ||
| 191 | |||
| 192 | To compile this driver as a module, choose M here: the | ||
| 193 | module will be called da9034-ts. | ||
| 194 | |||
| 195 | config TOUCHSCREEN_DA9052 | ||
| 196 | tristate "Dialog DA9052/DA9053 TSI" | ||
| 197 | depends on PMIC_DA9052 | ||
| 198 | help | ||
| 199 | Say Y here to support the touchscreen found on Dialog Semiconductor | ||
| 200 | DA9052-BC and DA9053-AA/Bx PMICs. | ||
| 201 | |||
| 202 | If unsure, say N. | ||
| 203 | |||
| 204 | To compile this driver as a module, choose M here: the | ||
| 205 | module will be called da9052_tsi. | ||
| 206 | |||
| 190 | config TOUCHSCREEN_DYNAPRO | 207 | config TOUCHSCREEN_DYNAPRO |
| 191 | tristate "Dynapro serial touchscreen" | 208 | tristate "Dynapro serial touchscreen" |
| 192 | select SERIO | 209 | select SERIO |
| @@ -306,6 +323,18 @@ config TOUCHSCREEN_WACOM_W8001 | |||
| 306 | To compile this driver as a module, choose M here: the | 323 | To compile this driver as a module, choose M here: the |
| 307 | module will be called wacom_w8001. | 324 | module will be called wacom_w8001. |
| 308 | 325 | ||
| 326 | config TOUCHSCREEN_WACOM_I2C | ||
| 327 | tristate "Wacom Tablet support (I2C)" | ||
| 328 | depends on I2C | ||
| 329 | help | ||
| 330 | Say Y here if you want to use the I2C version of the Wacom | ||
| 331 | Pen Tablet. | ||
| 332 | |||
| 333 | If unsure, say N. | ||
| 334 | |||
| 335 | To compile this driver as a module, choose M here: the module | ||
| 336 | will be called wacom_i2c. | ||
| 337 | |||
| 309 | config TOUCHSCREEN_LPC32XX | 338 | config TOUCHSCREEN_LPC32XX |
| 310 | tristate "LPC32XX touchscreen controller" | 339 | tristate "LPC32XX touchscreen controller" |
| 311 | depends on ARCH_LPC32XX | 340 | depends on ARCH_LPC32XX |
| @@ -635,6 +664,7 @@ config TOUCHSCREEN_USB_COMPOSITE | |||
| 635 | - Zytronic controllers | 664 | - Zytronic controllers |
| 636 | - Elo TouchSystems 2700 IntelliTouch | 665 | - Elo TouchSystems 2700 IntelliTouch |
| 637 | - EasyTouch USB Touch Controller from Data Modul | 666 | - EasyTouch USB Touch Controller from Data Modul |
| 667 | - e2i (Mimo monitors) | ||
| 638 | 668 | ||
| 639 | Have a look at <http://linux.chapter7.ch/touchkit/> for | 669 | Have a look at <http://linux.chapter7.ch/touchkit/> for |
| 640 | a usage description and the required user-space stuff. | 670 | a usage description and the required user-space stuff. |
| @@ -721,7 +751,7 @@ config TOUCHSCREEN_USB_ELO | |||
| 721 | 751 | ||
| 722 | config TOUCHSCREEN_USB_E2I | 752 | config TOUCHSCREEN_USB_E2I |
| 723 | default y | 753 | default y |
| 724 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" | 754 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" if EXPERT |
| 725 | depends on TOUCHSCREEN_USB_COMPOSITE | 755 | depends on TOUCHSCREEN_USB_COMPOSITE |
| 726 | 756 | ||
| 727 | config TOUCHSCREEN_USB_ZYTRONIC | 757 | config TOUCHSCREEN_USB_ZYTRONIC |
| @@ -744,7 +774,7 @@ config TOUCHSCREEN_USB_EASYTOUCH | |||
| 744 | bool "EasyTouch USB Touch controller device support" if EMBEDDED | 774 | bool "EasyTouch USB Touch controller device support" if EMBEDDED |
| 745 | depends on TOUCHSCREEN_USB_COMPOSITE | 775 | depends on TOUCHSCREEN_USB_COMPOSITE |
| 746 | help | 776 | help |
| 747 | Say Y here if you have a EasyTouch USB Touch controller device support. | 777 | Say Y here if you have an EasyTouch USB Touch controller. |
| 748 | If unsure, say N. | 778 | If unsure, say N. |
| 749 | 779 | ||
| 750 | config TOUCHSCREEN_TOUCHIT213 | 780 | config TOUCHSCREEN_TOUCHIT213 |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 3d5cf8cbf89c..eb8bfe1c1a46 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o | |||
| 22 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o | 22 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o |
| 23 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o | 23 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o |
| 24 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | 24 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o |
| 25 | obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o | ||
| 25 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 26 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
| 26 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o | 27 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o |
| 27 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 28 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
| @@ -59,6 +60,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o | |||
| 59 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o | 60 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o |
| 60 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 61 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
| 61 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o | 62 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o |
| 63 | obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o | ||
| 62 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o | 64 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o |
| 63 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o | 65 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o |
| 64 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 66 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 19d4ea65ea01..42e645062c20 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -236,7 +236,6 @@ struct mxt_object { | |||
| 236 | struct mxt_message { | 236 | struct mxt_message { |
| 237 | u8 reportid; | 237 | u8 reportid; |
| 238 | u8 message[7]; | 238 | u8 message[7]; |
| 239 | u8 checksum; | ||
| 240 | }; | 239 | }; |
| 241 | 240 | ||
| 242 | struct mxt_finger { | 241 | struct mxt_finger { |
| @@ -326,17 +325,12 @@ static bool mxt_object_writable(unsigned int type) | |||
| 326 | } | 325 | } |
| 327 | 326 | ||
| 328 | static void mxt_dump_message(struct device *dev, | 327 | static void mxt_dump_message(struct device *dev, |
| 329 | struct mxt_message *message) | 328 | struct mxt_message *message) |
| 330 | { | 329 | { |
| 331 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | 330 | dev_dbg(dev, "reportid: %u\tmessage: %02x %02x %02x %02x %02x %02x %02x\n", |
| 332 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | 331 | message->reportid, message->message[0], message->message[1], |
| 333 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | 332 | message->message[2], message->message[3], message->message[4], |
| 334 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | 333 | message->message[5], message->message[6]); |
| 335 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
| 336 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
| 337 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
| 338 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
| 339 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
| 340 | } | 334 | } |
| 341 | 335 | ||
| 342 | static int mxt_check_bootloader(struct i2c_client *client, | 336 | static int mxt_check_bootloader(struct i2c_client *client, |
| @@ -506,7 +500,7 @@ static int mxt_write_object(struct mxt_data *data, | |||
| 506 | u16 reg; | 500 | u16 reg; |
| 507 | 501 | ||
| 508 | object = mxt_get_object(data, type); | 502 | object = mxt_get_object(data, type); |
| 509 | if (!object) | 503 | if (!object || offset >= object->size + 1) |
| 510 | return -EINVAL; | 504 | return -EINVAL; |
| 511 | 505 | ||
| 512 | reg = object->start_address; | 506 | reg = object->start_address; |
| @@ -1049,8 +1043,8 @@ static ssize_t mxt_update_fw_store(struct device *dev, | |||
| 1049 | return count; | 1043 | return count; |
| 1050 | } | 1044 | } |
| 1051 | 1045 | ||
| 1052 | static DEVICE_ATTR(object, 0444, mxt_object_show, NULL); | 1046 | static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); |
| 1053 | static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store); | 1047 | static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store); |
| 1054 | 1048 | ||
| 1055 | static struct attribute *mxt_attrs[] = { | 1049 | static struct attribute *mxt_attrs[] = { |
| 1056 | &dev_attr_object.attr, | 1050 | &dev_attr_object.attr, |
| @@ -1201,7 +1195,7 @@ static int __devexit mxt_remove(struct i2c_client *client) | |||
| 1201 | return 0; | 1195 | return 0; |
| 1202 | } | 1196 | } |
| 1203 | 1197 | ||
| 1204 | #ifdef CONFIG_PM | 1198 | #ifdef CONFIG_PM_SLEEP |
| 1205 | static int mxt_suspend(struct device *dev) | 1199 | static int mxt_suspend(struct device *dev) |
| 1206 | { | 1200 | { |
| 1207 | struct i2c_client *client = to_i2c_client(dev); | 1201 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -1239,13 +1233,10 @@ static int mxt_resume(struct device *dev) | |||
| 1239 | 1233 | ||
| 1240 | return 0; | 1234 | return 0; |
| 1241 | } | 1235 | } |
| 1242 | |||
| 1243 | static const struct dev_pm_ops mxt_pm_ops = { | ||
| 1244 | .suspend = mxt_suspend, | ||
| 1245 | .resume = mxt_resume, | ||
| 1246 | }; | ||
| 1247 | #endif | 1236 | #endif |
| 1248 | 1237 | ||
| 1238 | static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); | ||
| 1239 | |||
| 1249 | static const struct i2c_device_id mxt_id[] = { | 1240 | static const struct i2c_device_id mxt_id[] = { |
| 1250 | { "qt602240_ts", 0 }, | 1241 | { "qt602240_ts", 0 }, |
| 1251 | { "atmel_mxt_ts", 0 }, | 1242 | { "atmel_mxt_ts", 0 }, |
| @@ -1258,9 +1249,7 @@ static struct i2c_driver mxt_driver = { | |||
| 1258 | .driver = { | 1249 | .driver = { |
| 1259 | .name = "atmel_mxt_ts", | 1250 | .name = "atmel_mxt_ts", |
| 1260 | .owner = THIS_MODULE, | 1251 | .owner = THIS_MODULE, |
| 1261 | #ifdef CONFIG_PM | ||
| 1262 | .pm = &mxt_pm_ops, | 1252 | .pm = &mxt_pm_ops, |
| 1263 | #endif | ||
| 1264 | }, | 1253 | }, |
| 1265 | .probe = mxt_probe, | 1254 | .probe = mxt_probe, |
| 1266 | .remove = __devexit_p(mxt_remove), | 1255 | .remove = __devexit_p(mxt_remove), |
diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c new file mode 100644 index 000000000000..e8df341090c0 --- /dev/null +++ b/drivers/input/touchscreen/da9052_tsi.c | |||
| @@ -0,0 +1,370 @@ | |||
| 1 | /* | ||
| 2 | * TSI driver for Dialog DA9052 | ||
| 3 | * | ||
| 4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
| 5 | * | ||
| 6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
| 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 | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/input.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | |||
| 20 | #include <linux/mfd/da9052/reg.h> | ||
| 21 | #include <linux/mfd/da9052/da9052.h> | ||
| 22 | |||
| 23 | #define TSI_PEN_DOWN_STATUS 0x40 | ||
| 24 | |||
| 25 | struct da9052_tsi { | ||
| 26 | struct da9052 *da9052; | ||
| 27 | struct input_dev *dev; | ||
| 28 | struct delayed_work ts_pen_work; | ||
| 29 | struct mutex mutex; | ||
| 30 | unsigned int irq_pendwn; | ||
| 31 | unsigned int irq_datardy; | ||
| 32 | bool stopped; | ||
| 33 | bool adc_on; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static void da9052_ts_adc_toggle(struct da9052_tsi *tsi, bool on) | ||
| 37 | { | ||
| 38 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 0, on); | ||
| 39 | tsi->adc_on = on; | ||
| 40 | } | ||
| 41 | |||
| 42 | static irqreturn_t da9052_ts_pendwn_irq(int irq, void *data) | ||
| 43 | { | ||
| 44 | struct da9052_tsi *tsi = data; | ||
| 45 | |||
| 46 | if (!tsi->stopped) { | ||
| 47 | /* Mask PEN_DOWN event and unmask TSI_READY event */ | ||
| 48 | disable_irq_nosync(tsi->irq_pendwn); | ||
| 49 | enable_irq(tsi->irq_datardy); | ||
| 50 | |||
| 51 | da9052_ts_adc_toggle(tsi, true); | ||
| 52 | |||
| 53 | schedule_delayed_work(&tsi->ts_pen_work, HZ / 50); | ||
| 54 | } | ||
| 55 | |||
| 56 | return IRQ_HANDLED; | ||
| 57 | } | ||
| 58 | |||
| 59 | static void da9052_ts_read(struct da9052_tsi *tsi) | ||
| 60 | { | ||
| 61 | struct input_dev *input = tsi->dev; | ||
| 62 | int ret; | ||
| 63 | u16 x, y, z; | ||
| 64 | u8 v; | ||
| 65 | |||
| 66 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_X_MSB_REG); | ||
| 67 | if (ret < 0) | ||
| 68 | return; | ||
| 69 | |||
| 70 | x = (u16) ret; | ||
| 71 | |||
| 72 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Y_MSB_REG); | ||
| 73 | if (ret < 0) | ||
| 74 | return; | ||
| 75 | |||
| 76 | y = (u16) ret; | ||
| 77 | |||
| 78 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Z_MSB_REG); | ||
| 79 | if (ret < 0) | ||
| 80 | return; | ||
| 81 | |||
| 82 | z = (u16) ret; | ||
| 83 | |||
| 84 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG); | ||
| 85 | if (ret < 0) | ||
| 86 | return; | ||
| 87 | |||
| 88 | v = (u8) ret; | ||
| 89 | |||
| 90 | x = ((x << 2) & 0x3fc) | (v & 0x3); | ||
| 91 | y = ((y << 2) & 0x3fc) | ((v & 0xc) >> 2); | ||
| 92 | z = ((z << 2) & 0x3fc) | ((v & 0x30) >> 4); | ||
| 93 | |||
| 94 | input_report_key(input, BTN_TOUCH, 1); | ||
| 95 | input_report_abs(input, ABS_X, x); | ||
| 96 | input_report_abs(input, ABS_Y, y); | ||
| 97 | input_report_abs(input, ABS_PRESSURE, z); | ||
| 98 | input_sync(input); | ||
| 99 | } | ||
| 100 | |||
| 101 | static irqreturn_t da9052_ts_datardy_irq(int irq, void *data) | ||
| 102 | { | ||
| 103 | struct da9052_tsi *tsi = data; | ||
| 104 | |||
| 105 | da9052_ts_read(tsi); | ||
| 106 | |||
| 107 | return IRQ_HANDLED; | ||
| 108 | } | ||
| 109 | |||
| 110 | static void da9052_ts_pen_work(struct work_struct *work) | ||
| 111 | { | ||
| 112 | struct da9052_tsi *tsi = container_of(work, struct da9052_tsi, | ||
| 113 | ts_pen_work.work); | ||
| 114 | if (!tsi->stopped) { | ||
| 115 | int ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG); | ||
| 116 | if (ret < 0 || (ret & TSI_PEN_DOWN_STATUS)) { | ||
| 117 | /* Pen is still DOWN (or read error) */ | ||
| 118 | schedule_delayed_work(&tsi->ts_pen_work, HZ / 50); | ||
| 119 | } else { | ||
| 120 | struct input_dev *input = tsi->dev; | ||
| 121 | |||
| 122 | /* Pen UP */ | ||
| 123 | da9052_ts_adc_toggle(tsi, false); | ||
| 124 | |||
| 125 | /* Report Pen UP */ | ||
| 126 | input_report_key(input, BTN_TOUCH, 0); | ||
| 127 | input_report_abs(input, ABS_PRESSURE, 0); | ||
| 128 | input_sync(input); | ||
| 129 | |||
| 130 | /* | ||
| 131 | * FIXME: Fixes the unhandled irq issue when quick | ||
| 132 | * pen down and pen up events occurs | ||
| 133 | */ | ||
| 134 | ret = da9052_reg_update(tsi->da9052, | ||
| 135 | DA9052_EVENT_B_REG, 0xC0, 0xC0); | ||
| 136 | if (ret < 0) | ||
| 137 | return; | ||
| 138 | |||
| 139 | /* Mask TSI_READY event and unmask PEN_DOWN event */ | ||
| 140 | disable_irq(tsi->irq_datardy); | ||
| 141 | enable_irq(tsi->irq_pendwn); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | static int __devinit da9052_ts_configure_gpio(struct da9052 *da9052) | ||
| 147 | { | ||
| 148 | int error; | ||
| 149 | |||
| 150 | error = da9052_reg_update(da9052, DA9052_GPIO_2_3_REG, 0x30, 0); | ||
| 151 | if (error < 0) | ||
| 152 | return error; | ||
| 153 | |||
| 154 | error = da9052_reg_update(da9052, DA9052_GPIO_4_5_REG, 0x33, 0); | ||
| 155 | if (error < 0) | ||
| 156 | return error; | ||
| 157 | |||
| 158 | error = da9052_reg_update(da9052, DA9052_GPIO_6_7_REG, 0x33, 0); | ||
| 159 | if (error < 0) | ||
| 160 | return error; | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | static int __devinit da9052_configure_tsi(struct da9052_tsi *tsi) | ||
| 166 | { | ||
| 167 | int error; | ||
| 168 | |||
| 169 | error = da9052_ts_configure_gpio(tsi->da9052); | ||
| 170 | if (error) | ||
| 171 | return error; | ||
| 172 | |||
| 173 | /* Measure TSI sample every 1ms */ | ||
| 174 | error = da9052_reg_update(tsi->da9052, DA9052_ADC_CONT_REG, | ||
| 175 | 1 << 6, 1 << 6); | ||
| 176 | if (error < 0) | ||
| 177 | return error; | ||
| 178 | |||
| 179 | /* TSI_DELAY: 3 slots, TSI_SKIP: 0 slots, TSI_MODE: XYZP */ | ||
| 180 | error = da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 0xFC, 0xC0); | ||
| 181 | if (error < 0) | ||
| 182 | return error; | ||
| 183 | |||
| 184 | /* Supply TSIRef through LD09 */ | ||
| 185 | error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x59); | ||
| 186 | if (error < 0) | ||
| 187 | return error; | ||
| 188 | |||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static int da9052_ts_input_open(struct input_dev *input_dev) | ||
| 193 | { | ||
| 194 | struct da9052_tsi *tsi = input_get_drvdata(input_dev); | ||
| 195 | |||
| 196 | tsi->stopped = false; | ||
| 197 | mb(); | ||
| 198 | |||
| 199 | /* Unmask PEN_DOWN event */ | ||
| 200 | enable_irq(tsi->irq_pendwn); | ||
| 201 | |||
| 202 | /* Enable Pen Detect Circuit */ | ||
| 203 | return da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, | ||
| 204 | 1 << 1, 1 << 1); | ||
| 205 | } | ||
| 206 | |||
| 207 | static void da9052_ts_input_close(struct input_dev *input_dev) | ||
| 208 | { | ||
| 209 | struct da9052_tsi *tsi = input_get_drvdata(input_dev); | ||
| 210 | |||
| 211 | tsi->stopped = true; | ||
| 212 | mb(); | ||
| 213 | disable_irq(tsi->irq_pendwn); | ||
| 214 | cancel_delayed_work_sync(&tsi->ts_pen_work); | ||
| 215 | |||
| 216 | if (tsi->adc_on) { | ||
| 217 | disable_irq(tsi->irq_datardy); | ||
| 218 | da9052_ts_adc_toggle(tsi, false); | ||
| 219 | |||
| 220 | /* | ||
| 221 | * If ADC was on that means that pendwn IRQ was disabled | ||
| 222 | * twice and we need to enable it to keep enable/disable | ||
| 223 | * counter balanced. IRQ is still off though. | ||
| 224 | */ | ||
| 225 | enable_irq(tsi->irq_pendwn); | ||
| 226 | } | ||
| 227 | |||
| 228 | /* Disable Pen Detect Circuit */ | ||
| 229 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0); | ||
| 230 | } | ||
| 231 | |||
| 232 | static int __devinit da9052_ts_probe(struct platform_device *pdev) | ||
| 233 | { | ||
| 234 | struct da9052 *da9052; | ||
| 235 | struct da9052_tsi *tsi; | ||
| 236 | struct input_dev *input_dev; | ||
| 237 | int irq_pendwn; | ||
| 238 | int irq_datardy; | ||
| 239 | int error; | ||
| 240 | |||
| 241 | da9052 = dev_get_drvdata(pdev->dev.parent); | ||
| 242 | if (!da9052) | ||
| 243 | return -EINVAL; | ||
| 244 | |||
| 245 | irq_pendwn = platform_get_irq_byname(pdev, "PENDWN"); | ||
| 246 | irq_datardy = platform_get_irq_byname(pdev, "TSIRDY"); | ||
| 247 | if (irq_pendwn < 0 || irq_datardy < 0) { | ||
| 248 | dev_err(da9052->dev, "Unable to determine device interrupts\n"); | ||
| 249 | return -ENXIO; | ||
| 250 | } | ||
| 251 | |||
| 252 | tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL); | ||
| 253 | input_dev = input_allocate_device(); | ||
| 254 | if (!tsi || !input_dev) { | ||
| 255 | error = -ENOMEM; | ||
| 256 | goto err_free_mem; | ||
| 257 | } | ||
| 258 | |||
| 259 | tsi->da9052 = da9052; | ||
| 260 | tsi->dev = input_dev; | ||
| 261 | tsi->irq_pendwn = da9052->irq_base + irq_pendwn; | ||
| 262 | tsi->irq_datardy = da9052->irq_base + irq_datardy; | ||
| 263 | tsi->stopped = true; | ||
| 264 | INIT_DELAYED_WORK(&tsi->ts_pen_work, da9052_ts_pen_work); | ||
| 265 | |||
| 266 | input_dev->id.version = 0x0101; | ||
| 267 | input_dev->id.vendor = 0x15B6; | ||
| 268 | input_dev->id.product = 0x9052; | ||
| 269 | input_dev->name = "Dialog DA9052 TouchScreen Driver"; | ||
| 270 | input_dev->dev.parent = &pdev->dev; | ||
| 271 | input_dev->open = da9052_ts_input_open; | ||
| 272 | input_dev->close = da9052_ts_input_close; | ||
| 273 | |||
| 274 | __set_bit(EV_ABS, input_dev->evbit); | ||
| 275 | __set_bit(EV_KEY, input_dev->evbit); | ||
| 276 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
| 277 | |||
| 278 | input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0); | ||
| 279 | input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0); | ||
| 280 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1023, 0, 0); | ||
| 281 | |||
| 282 | input_set_drvdata(input_dev, tsi); | ||
| 283 | |||
| 284 | /* Disable Pen Detect Circuit */ | ||
| 285 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0); | ||
| 286 | |||
| 287 | /* Disable ADC */ | ||
| 288 | da9052_ts_adc_toggle(tsi, false); | ||
| 289 | |||
| 290 | error = request_threaded_irq(tsi->irq_pendwn, | ||
| 291 | NULL, da9052_ts_pendwn_irq, | ||
| 292 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
| 293 | "PENDWN", tsi); | ||
| 294 | if (error) { | ||
| 295 | dev_err(tsi->da9052->dev, | ||
| 296 | "Failed to register PENDWN IRQ %d, error = %d\n", | ||
| 297 | tsi->irq_pendwn, error); | ||
| 298 | goto err_free_mem; | ||
| 299 | } | ||
| 300 | |||
| 301 | error = request_threaded_irq(tsi->irq_datardy, | ||
| 302 | NULL, da9052_ts_datardy_irq, | ||
| 303 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
| 304 | "TSIRDY", tsi); | ||
| 305 | if (error) { | ||
| 306 | dev_err(tsi->da9052->dev, | ||
| 307 | "Failed to register TSIRDY IRQ %d, error = %d\n", | ||
| 308 | tsi->irq_datardy, error); | ||
| 309 | goto err_free_pendwn_irq; | ||
| 310 | } | ||
| 311 | |||
| 312 | /* Mask PEN_DOWN and TSI_READY events */ | ||
| 313 | disable_irq(tsi->irq_pendwn); | ||
| 314 | disable_irq(tsi->irq_datardy); | ||
| 315 | |||
| 316 | error = da9052_configure_tsi(tsi); | ||
| 317 | if (error) | ||
| 318 | goto err_free_datardy_irq; | ||
| 319 | |||
| 320 | error = input_register_device(tsi->dev); | ||
| 321 | if (error) | ||
| 322 | goto err_free_datardy_irq; | ||
| 323 | |||
| 324 | platform_set_drvdata(pdev, tsi); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | |||
| 328 | err_free_datardy_irq: | ||
| 329 | free_irq(tsi->irq_datardy, tsi); | ||
| 330 | err_free_pendwn_irq: | ||
| 331 | free_irq(tsi->irq_pendwn, tsi); | ||
| 332 | err_free_mem: | ||
| 333 | kfree(tsi); | ||
| 334 | input_free_device(input_dev); | ||
| 335 | |||
| 336 | return error; | ||
| 337 | } | ||
| 338 | |||
| 339 | static int __devexit da9052_ts_remove(struct platform_device *pdev) | ||
| 340 | { | ||
| 341 | struct da9052_tsi *tsi = platform_get_drvdata(pdev); | ||
| 342 | |||
| 343 | da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); | ||
| 344 | |||
| 345 | free_irq(tsi->irq_pendwn, tsi); | ||
| 346 | free_irq(tsi->irq_datardy, tsi); | ||
| 347 | |||
| 348 | input_unregister_device(tsi->dev); | ||
| 349 | kfree(tsi); | ||
| 350 | |||
| 351 | platform_set_drvdata(pdev, NULL); | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static struct platform_driver da9052_tsi_driver = { | ||
| 357 | .probe = da9052_ts_probe, | ||
| 358 | .remove = __devexit_p(da9052_ts_remove), | ||
| 359 | .driver = { | ||
| 360 | .name = "da9052-tsi", | ||
| 361 | .owner = THIS_MODULE, | ||
| 362 | }, | ||
| 363 | }; | ||
| 364 | |||
| 365 | module_platform_driver(da9052_tsi_driver); | ||
| 366 | |||
| 367 | MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9052"); | ||
| 368 | MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>"); | ||
| 369 | MODULE_LICENSE("GPL"); | ||
| 370 | MODULE_ALIAS("platform:da9052-tsi"); | ||
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c index 455353908bdf..1809677a6513 100644 --- a/drivers/input/touchscreen/dynapro.c +++ b/drivers/input/touchscreen/dynapro.c | |||
| @@ -188,19 +188,4 @@ static struct serio_driver dynapro_drv = { | |||
| 188 | .disconnect = dynapro_disconnect, | 188 | .disconnect = dynapro_disconnect, |
| 189 | }; | 189 | }; |
| 190 | 190 | ||
| 191 | /* | 191 | module_serio_driver(dynapro_drv); |
| 192 | * The functions for inserting/removing us as a module. | ||
| 193 | */ | ||
| 194 | |||
| 195 | static int __init dynapro_init(void) | ||
| 196 | { | ||
| 197 | return serio_register_driver(&dynapro_drv); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void __exit dynapro_exit(void) | ||
| 201 | { | ||
| 202 | serio_unregister_driver(&dynapro_drv); | ||
| 203 | } | ||
| 204 | |||
| 205 | module_init(dynapro_init); | ||
| 206 | module_exit(dynapro_exit); | ||
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 486d31ba9c09..957423d1471d 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
| @@ -405,19 +405,4 @@ static struct serio_driver elo_drv = { | |||
| 405 | .disconnect = elo_disconnect, | 405 | .disconnect = elo_disconnect, |
| 406 | }; | 406 | }; |
| 407 | 407 | ||
| 408 | /* | 408 | module_serio_driver(elo_drv); |
| 409 | * The functions for inserting/removing us as a module. | ||
| 410 | */ | ||
| 411 | |||
| 412 | static int __init elo_init(void) | ||
| 413 | { | ||
| 414 | return serio_register_driver(&elo_drv); | ||
| 415 | } | ||
| 416 | |||
| 417 | static void __exit elo_exit(void) | ||
| 418 | { | ||
| 419 | serio_unregister_driver(&elo_drv); | ||
| 420 | } | ||
| 421 | |||
| 422 | module_init(elo_init); | ||
| 423 | module_exit(elo_exit); | ||
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c index 80b21800355f..10794ddbdf58 100644 --- a/drivers/input/touchscreen/fujitsu_ts.c +++ b/drivers/input/touchscreen/fujitsu_ts.c | |||
| @@ -175,15 +175,4 @@ static struct serio_driver fujitsu_drv = { | |||
| 175 | .disconnect = fujitsu_disconnect, | 175 | .disconnect = fujitsu_disconnect, |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | static int __init fujitsu_init(void) | 178 | module_serio_driver(fujitsu_drv); |
| 179 | { | ||
| 180 | return serio_register_driver(&fujitsu_drv); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void __exit fujitsu_exit(void) | ||
| 184 | { | ||
| 185 | serio_unregister_driver(&fujitsu_drv); | ||
| 186 | } | ||
| 187 | |||
| 188 | module_init(fujitsu_init); | ||
| 189 | module_exit(fujitsu_exit); | ||
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index a54f90e02ab6..41c71766bf18 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
| @@ -186,19 +186,4 @@ static struct serio_driver gunze_drv = { | |||
| 186 | .disconnect = gunze_disconnect, | 186 | .disconnect = gunze_disconnect, |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | /* | 189 | module_serio_driver(gunze_drv); |
| 190 | * The functions for inserting/removing us as a module. | ||
| 191 | */ | ||
| 192 | |||
| 193 | static int __init gunze_init(void) | ||
| 194 | { | ||
| 195 | return serio_register_driver(&gunze_drv); | ||
| 196 | } | ||
| 197 | |||
| 198 | static void __exit gunze_exit(void) | ||
| 199 | { | ||
| 200 | serio_unregister_driver(&gunze_drv); | ||
| 201 | } | ||
| 202 | |||
| 203 | module_init(gunze_init); | ||
| 204 | module_exit(gunze_exit); | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 6107e563e681..b9e8686a6f1c 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
| @@ -476,19 +476,4 @@ static struct serio_driver h3600ts_drv = { | |||
| 476 | .disconnect = h3600ts_disconnect, | 476 | .disconnect = h3600ts_disconnect, |
| 477 | }; | 477 | }; |
| 478 | 478 | ||
| 479 | /* | 479 | module_serio_driver(h3600ts_drv); |
| 480 | * The functions for inserting/removing us as a module. | ||
| 481 | */ | ||
| 482 | |||
| 483 | static int __init h3600ts_init(void) | ||
| 484 | { | ||
| 485 | return serio_register_driver(&h3600ts_drv); | ||
| 486 | } | ||
| 487 | |||
| 488 | static void __exit h3600ts_exit(void) | ||
| 489 | { | ||
| 490 | serio_unregister_driver(&h3600ts_drv); | ||
| 491 | } | ||
| 492 | |||
| 493 | module_init(h3600ts_init); | ||
| 494 | module_exit(h3600ts_exit); | ||
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c index 2da6cc31bb21..0cc47ea98acf 100644 --- a/drivers/input/touchscreen/hampshire.c +++ b/drivers/input/touchscreen/hampshire.c | |||
| @@ -187,19 +187,4 @@ static struct serio_driver hampshire_drv = { | |||
| 187 | .disconnect = hampshire_disconnect, | 187 | .disconnect = hampshire_disconnect, |
| 188 | }; | 188 | }; |
| 189 | 189 | ||
| 190 | /* | 190 | module_serio_driver(hampshire_drv); |
| 191 | * The functions for inserting/removing us as a module. | ||
| 192 | */ | ||
| 193 | |||
| 194 | static int __init hampshire_init(void) | ||
| 195 | { | ||
| 196 | return serio_register_driver(&hampshire_drv); | ||
| 197 | } | ||
| 198 | |||
| 199 | static void __exit hampshire_exit(void) | ||
| 200 | { | ||
| 201 | serio_unregister_driver(&hampshire_drv); | ||
| 202 | } | ||
| 203 | |||
| 204 | module_init(hampshire_init); | ||
| 205 | module_exit(hampshire_exit); | ||
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c index 192ade0a0fb9..a29c99c32245 100644 --- a/drivers/input/touchscreen/inexio.c +++ b/drivers/input/touchscreen/inexio.c | |||
| @@ -189,19 +189,4 @@ static struct serio_driver inexio_drv = { | |||
| 189 | .disconnect = inexio_disconnect, | 189 | .disconnect = inexio_disconnect, |
| 190 | }; | 190 | }; |
| 191 | 191 | ||
| 192 | /* | 192 | module_serio_driver(inexio_drv); |
| 193 | * The functions for inserting/removing us as a module. | ||
| 194 | */ | ||
| 195 | |||
| 196 | static int __init inexio_init(void) | ||
| 197 | { | ||
| 198 | return serio_register_driver(&inexio_drv); | ||
| 199 | } | ||
| 200 | |||
| 201 | static void __exit inexio_exit(void) | ||
| 202 | { | ||
| 203 | serio_unregister_driver(&inexio_drv); | ||
| 204 | } | ||
| 205 | |||
| 206 | module_init(inexio_init); | ||
| 207 | module_exit(inexio_exit); | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index afcd0691ec67..4c2b8ed3bf16 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/of.h> | ||
| 25 | 26 | ||
| 26 | /* | 27 | /* |
| 27 | * Touchscreen controller register offsets | 28 | * Touchscreen controller register offsets |
| @@ -383,6 +384,14 @@ static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | |||
| 383 | #define LPC32XX_TS_PM_OPS NULL | 384 | #define LPC32XX_TS_PM_OPS NULL |
| 384 | #endif | 385 | #endif |
| 385 | 386 | ||
| 387 | #ifdef CONFIG_OF | ||
| 388 | static struct of_device_id lpc32xx_tsc_of_match[] = { | ||
| 389 | { .compatible = "nxp,lpc3220-tsc", }, | ||
| 390 | { }, | ||
| 391 | }; | ||
| 392 | MODULE_DEVICE_TABLE(of, lpc32xx_tsc_of_match); | ||
| 393 | #endif | ||
| 394 | |||
| 386 | static struct platform_driver lpc32xx_ts_driver = { | 395 | static struct platform_driver lpc32xx_ts_driver = { |
| 387 | .probe = lpc32xx_ts_probe, | 396 | .probe = lpc32xx_ts_probe, |
| 388 | .remove = __devexit_p(lpc32xx_ts_remove), | 397 | .remove = __devexit_p(lpc32xx_ts_remove), |
| @@ -390,6 +399,7 @@ static struct platform_driver lpc32xx_ts_driver = { | |||
| 390 | .name = MOD_NAME, | 399 | .name = MOD_NAME, |
| 391 | .owner = THIS_MODULE, | 400 | .owner = THIS_MODULE, |
| 392 | .pm = LPC32XX_TS_PM_OPS, | 401 | .pm = LPC32XX_TS_PM_OPS, |
| 402 | .of_match_table = of_match_ptr(lpc32xx_tsc_of_match), | ||
| 393 | }, | 403 | }, |
| 394 | }; | 404 | }; |
| 395 | module_platform_driver(lpc32xx_ts_driver); | 405 | module_platform_driver(lpc32xx_ts_driver); |
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 9077228418b7..eb66b7c37c2f 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c | |||
| @@ -202,19 +202,4 @@ static struct serio_driver mtouch_drv = { | |||
| 202 | .disconnect = mtouch_disconnect, | 202 | .disconnect = mtouch_disconnect, |
| 203 | }; | 203 | }; |
| 204 | 204 | ||
| 205 | /* | 205 | module_serio_driver(mtouch_drv); |
| 206 | * The functions for inserting/removing us as a module. | ||
| 207 | */ | ||
| 208 | |||
| 209 | static int __init mtouch_init(void) | ||
| 210 | { | ||
| 211 | return serio_register_driver(&mtouch_drv); | ||
| 212 | } | ||
| 213 | |||
| 214 | static void __exit mtouch_exit(void) | ||
| 215 | { | ||
| 216 | serio_unregister_driver(&mtouch_drv); | ||
| 217 | } | ||
| 218 | |||
| 219 | module_init(mtouch_init); | ||
| 220 | module_exit(mtouch_exit); | ||
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 4c012fb2b01e..4ccde45b9da2 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
| @@ -317,19 +317,4 @@ static struct serio_driver pm_drv = { | |||
| 317 | .disconnect = pm_disconnect, | 317 | .disconnect = pm_disconnect, |
| 318 | }; | 318 | }; |
| 319 | 319 | ||
| 320 | /* | 320 | module_serio_driver(pm_drv); |
| 321 | * The functions for inserting/removing us as a module. | ||
| 322 | */ | ||
| 323 | |||
| 324 | static int __init pm_init(void) | ||
| 325 | { | ||
| 326 | return serio_register_driver(&pm_drv); | ||
| 327 | } | ||
| 328 | |||
| 329 | static void __exit pm_exit(void) | ||
| 330 | { | ||
| 331 | serio_unregister_driver(&pm_drv); | ||
| 332 | } | ||
| 333 | |||
| 334 | module_init(pm_init); | ||
| 335 | module_exit(pm_exit); | ||
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index cbbf71b22696..6cb68a1981bf 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c | |||
| @@ -218,7 +218,7 @@ static int __devexit st1232_ts_remove(struct i2c_client *client) | |||
| 218 | return 0; | 218 | return 0; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | #ifdef CONFIG_PM | 221 | #ifdef CONFIG_PM_SLEEP |
| 222 | static int st1232_ts_suspend(struct device *dev) | 222 | static int st1232_ts_suspend(struct device *dev) |
| 223 | { | 223 | { |
| 224 | struct i2c_client *client = to_i2c_client(dev); | 224 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -243,18 +243,25 @@ static int st1232_ts_resume(struct device *dev) | |||
| 243 | return 0; | 243 | return 0; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | static const struct dev_pm_ops st1232_ts_pm_ops = { | ||
| 247 | .suspend = st1232_ts_suspend, | ||
| 248 | .resume = st1232_ts_resume, | ||
| 249 | }; | ||
| 250 | #endif | 246 | #endif |
| 251 | 247 | ||
| 248 | static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, | ||
| 249 | st1232_ts_suspend, st1232_ts_resume); | ||
| 250 | |||
| 252 | static const struct i2c_device_id st1232_ts_id[] = { | 251 | static const struct i2c_device_id st1232_ts_id[] = { |
| 253 | { ST1232_TS_NAME, 0 }, | 252 | { ST1232_TS_NAME, 0 }, |
| 254 | { } | 253 | { } |
| 255 | }; | 254 | }; |
| 256 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); | 255 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); |
| 257 | 256 | ||
| 257 | #ifdef CONFIG_OF | ||
| 258 | static const struct of_device_id st1232_ts_dt_ids[] __devinitconst = { | ||
| 259 | { .compatible = "sitronix,st1232", }, | ||
| 260 | { } | ||
| 261 | }; | ||
| 262 | MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids); | ||
| 263 | #endif | ||
| 264 | |||
| 258 | static struct i2c_driver st1232_ts_driver = { | 265 | static struct i2c_driver st1232_ts_driver = { |
| 259 | .probe = st1232_ts_probe, | 266 | .probe = st1232_ts_probe, |
| 260 | .remove = __devexit_p(st1232_ts_remove), | 267 | .remove = __devexit_p(st1232_ts_remove), |
| @@ -262,9 +269,8 @@ static struct i2c_driver st1232_ts_driver = { | |||
| 262 | .driver = { | 269 | .driver = { |
| 263 | .name = ST1232_TS_NAME, | 270 | .name = ST1232_TS_NAME, |
| 264 | .owner = THIS_MODULE, | 271 | .owner = THIS_MODULE, |
| 265 | #ifdef CONFIG_PM | 272 | .of_match_table = of_match_ptr(st1232_ts_dt_ids), |
| 266 | .pm = &st1232_ts_pm_ops, | 273 | .pm = &st1232_ts_pm_ops, |
| 267 | #endif | ||
| 268 | }, | 274 | }, |
| 269 | }; | 275 | }; |
| 270 | 276 | ||
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c index d1297ba19daf..5f29e5b8e1c1 100644 --- a/drivers/input/touchscreen/touchit213.c +++ b/drivers/input/touchscreen/touchit213.c | |||
| @@ -216,19 +216,4 @@ static struct serio_driver touchit213_drv = { | |||
| 216 | .disconnect = touchit213_disconnect, | 216 | .disconnect = touchit213_disconnect, |
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | /* | 219 | module_serio_driver(touchit213_drv); |
| 220 | * The functions for inserting/removing us as a module. | ||
| 221 | */ | ||
| 222 | |||
| 223 | static int __init touchit213_init(void) | ||
| 224 | { | ||
| 225 | return serio_register_driver(&touchit213_drv); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void __exit touchit213_exit(void) | ||
| 229 | { | ||
| 230 | serio_unregister_driver(&touchit213_drv); | ||
| 231 | } | ||
| 232 | |||
| 233 | module_init(touchit213_init); | ||
| 234 | module_exit(touchit213_exit); | ||
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 3a5c142c2a78..8a2887daf194 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c | |||
| @@ -176,19 +176,4 @@ static struct serio_driver tr_drv = { | |||
| 176 | .disconnect = tr_disconnect, | 176 | .disconnect = tr_disconnect, |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | /* | 179 | module_serio_driver(tr_drv); |
| 180 | * The functions for inserting/removing us as a module. | ||
| 181 | */ | ||
| 182 | |||
| 183 | static int __init tr_init(void) | ||
| 184 | { | ||
| 185 | return serio_register_driver(&tr_drv); | ||
| 186 | } | ||
| 187 | |||
| 188 | static void __exit tr_exit(void) | ||
| 189 | { | ||
| 190 | serio_unregister_driver(&tr_drv); | ||
| 191 | } | ||
| 192 | |||
| 193 | module_init(tr_init); | ||
| 194 | module_exit(tr_exit); | ||
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 763a656a59f8..588cdcb839dd 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c | |||
| @@ -183,19 +183,4 @@ static struct serio_driver tw_drv = { | |||
| 183 | .disconnect = tw_disconnect, | 183 | .disconnect = tw_disconnect, |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | /* | 186 | module_serio_driver(tw_drv); |
| 187 | * The functions for inserting/removing us as a module. | ||
| 188 | */ | ||
| 189 | |||
| 190 | static int __init tw_init(void) | ||
| 191 | { | ||
| 192 | return serio_register_driver(&tw_drv); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void __exit tw_exit(void) | ||
| 196 | { | ||
| 197 | serio_unregister_driver(&tw_drv); | ||
| 198 | } | ||
| 199 | |||
| 200 | module_init(tw_init); | ||
| 201 | module_exit(tw_exit); | ||
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index 29d5ed4dd31c..63209aaa55f0 100644 --- a/drivers/input/touchscreen/tsc40.c +++ b/drivers/input/touchscreen/tsc40.c | |||
| @@ -167,17 +167,7 @@ static struct serio_driver tsc_drv = { | |||
| 167 | .disconnect = tsc_disconnect, | 167 | .disconnect = tsc_disconnect, |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | static int __init tsc_ser_init(void) | 170 | module_serio_driver(tsc_drv); |
| 171 | { | ||
| 172 | return serio_register_driver(&tsc_drv); | ||
| 173 | } | ||
| 174 | module_init(tsc_ser_init); | ||
| 175 | |||
| 176 | static void __exit tsc_exit(void) | ||
| 177 | { | ||
| 178 | serio_unregister_driver(&tsc_drv); | ||
| 179 | } | ||
| 180 | module_exit(tsc_exit); | ||
| 181 | 171 | ||
| 182 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); | 172 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); |
| 183 | MODULE_DESCRIPTION(DRIVER_DESC); | 173 | MODULE_DESCRIPTION(DRIVER_DESC); |
diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c new file mode 100644 index 000000000000..35572575d34a --- /dev/null +++ b/drivers/input/touchscreen/wacom_i2c.c | |||
| @@ -0,0 +1,282 @@ | |||
| 1 | /* | ||
| 2 | * Wacom Penabled Driver for I2C | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Tatsunosuke Tobita, Wacom. | ||
| 5 | * <tobita.tatsunosuke@wacom.co.jp> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it | ||
| 8 | * and/or modify it under the terms of the GNU General | ||
| 9 | * Public License as published by the Free Software | ||
| 10 | * Foundation; either version of 2 of the License, | ||
| 11 | * or (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/input.h> | ||
| 16 | #include <linux/i2c.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/irq.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <asm/unaligned.h> | ||
| 22 | |||
| 23 | #define WACOM_CMD_QUERY0 0x04 | ||
| 24 | #define WACOM_CMD_QUERY1 0x00 | ||
| 25 | #define WACOM_CMD_QUERY2 0x33 | ||
| 26 | #define WACOM_CMD_QUERY3 0x02 | ||
| 27 | #define WACOM_CMD_THROW0 0x05 | ||
| 28 | #define WACOM_CMD_THROW1 0x00 | ||
| 29 | #define WACOM_QUERY_SIZE 19 | ||
| 30 | #define WACOM_RETRY_CNT 100 | ||
| 31 | |||
| 32 | struct wacom_features { | ||
| 33 | int x_max; | ||
| 34 | int y_max; | ||
| 35 | int pressure_max; | ||
| 36 | char fw_version; | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct wacom_i2c { | ||
| 40 | struct i2c_client *client; | ||
| 41 | struct input_dev *input; | ||
| 42 | u8 data[WACOM_QUERY_SIZE]; | ||
| 43 | }; | ||
| 44 | |||
| 45 | static int wacom_query_device(struct i2c_client *client, | ||
| 46 | struct wacom_features *features) | ||
| 47 | { | ||
| 48 | int ret; | ||
| 49 | u8 cmd1[] = { WACOM_CMD_QUERY0, WACOM_CMD_QUERY1, | ||
| 50 | WACOM_CMD_QUERY2, WACOM_CMD_QUERY3 }; | ||
| 51 | u8 cmd2[] = { WACOM_CMD_THROW0, WACOM_CMD_THROW1 }; | ||
| 52 | u8 data[WACOM_QUERY_SIZE]; | ||
| 53 | struct i2c_msg msgs[] = { | ||
| 54 | { | ||
| 55 | .addr = client->addr, | ||
| 56 | .flags = 0, | ||
| 57 | .len = sizeof(cmd1), | ||
| 58 | .buf = cmd1, | ||
| 59 | }, | ||
| 60 | { | ||
| 61 | .addr = client->addr, | ||
| 62 | .flags = 0, | ||
| 63 | .len = sizeof(cmd2), | ||
| 64 | .buf = cmd2, | ||
| 65 | }, | ||
| 66 | { | ||
| 67 | .addr = client->addr, | ||
| 68 | .flags = I2C_M_RD, | ||
| 69 | .len = sizeof(data), | ||
| 70 | .buf = data, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
| 75 | if (ret < 0) | ||
| 76 | return ret; | ||
| 77 | if (ret != ARRAY_SIZE(msgs)) | ||
| 78 | return -EIO; | ||
| 79 | |||
| 80 | features->x_max = get_unaligned_le16(&data[3]); | ||
| 81 | features->y_max = get_unaligned_le16(&data[5]); | ||
| 82 | features->pressure_max = get_unaligned_le16(&data[11]); | ||
| 83 | features->fw_version = get_unaligned_le16(&data[13]); | ||
| 84 | |||
| 85 | dev_dbg(&client->dev, | ||
| 86 | "x_max:%d, y_max:%d, pressure:%d, fw:%d\n", | ||
| 87 | features->x_max, features->y_max, | ||
| 88 | features->pressure_max, features->fw_version); | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static irqreturn_t wacom_i2c_irq(int irq, void *dev_id) | ||
| 94 | { | ||
| 95 | struct wacom_i2c *wac_i2c = dev_id; | ||
| 96 | struct input_dev *input = wac_i2c->input; | ||
| 97 | u8 *data = wac_i2c->data; | ||
| 98 | unsigned int x, y, pressure; | ||
| 99 | unsigned char tsw, f1, f2, ers; | ||
| 100 | int error; | ||
| 101 | |||
| 102 | error = i2c_master_recv(wac_i2c->client, | ||
| 103 | wac_i2c->data, sizeof(wac_i2c->data)); | ||
| 104 | if (error < 0) | ||
| 105 | goto out; | ||
| 106 | |||
| 107 | tsw = data[3] & 0x01; | ||
| 108 | ers = data[3] & 0x04; | ||
| 109 | f1 = data[3] & 0x02; | ||
| 110 | f2 = data[3] & 0x10; | ||
| 111 | x = le16_to_cpup((__le16 *)&data[4]); | ||
| 112 | y = le16_to_cpup((__le16 *)&data[6]); | ||
| 113 | pressure = le16_to_cpup((__le16 *)&data[8]); | ||
| 114 | |||
| 115 | input_report_key(input, BTN_TOUCH, tsw || ers); | ||
| 116 | input_report_key(input, BTN_TOOL_PEN, tsw); | ||
| 117 | input_report_key(input, BTN_TOOL_RUBBER, ers); | ||
| 118 | input_report_key(input, BTN_STYLUS, f1); | ||
| 119 | input_report_key(input, BTN_STYLUS2, f2); | ||
| 120 | input_report_abs(input, ABS_X, x); | ||
| 121 | input_report_abs(input, ABS_Y, y); | ||
| 122 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
| 123 | input_sync(input); | ||
| 124 | |||
| 125 | out: | ||
| 126 | return IRQ_HANDLED; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int wacom_i2c_open(struct input_dev *dev) | ||
| 130 | { | ||
| 131 | struct wacom_i2c *wac_i2c = input_get_drvdata(dev); | ||
| 132 | struct i2c_client *client = wac_i2c->client; | ||
| 133 | |||
| 134 | enable_irq(client->irq); | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void wacom_i2c_close(struct input_dev *dev) | ||
| 140 | { | ||
| 141 | struct wacom_i2c *wac_i2c = input_get_drvdata(dev); | ||
| 142 | struct i2c_client *client = wac_i2c->client; | ||
| 143 | |||
| 144 | disable_irq(client->irq); | ||
| 145 | } | ||
| 146 | |||
| 147 | static int __devinit wacom_i2c_probe(struct i2c_client *client, | ||
| 148 | const struct i2c_device_id *id) | ||
| 149 | { | ||
| 150 | struct wacom_i2c *wac_i2c; | ||
| 151 | struct input_dev *input; | ||
| 152 | struct wacom_features features; | ||
| 153 | int error; | ||
| 154 | |||
| 155 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 156 | dev_err(&client->dev, "i2c_check_functionality error\n"); | ||
| 157 | return -EIO; | ||
| 158 | } | ||
| 159 | |||
| 160 | error = wacom_query_device(client, &features); | ||
| 161 | if (error) | ||
| 162 | return error; | ||
| 163 | |||
| 164 | wac_i2c = kzalloc(sizeof(*wac_i2c), GFP_KERNEL); | ||
| 165 | input = input_allocate_device(); | ||
| 166 | if (!wac_i2c || !input) { | ||
| 167 | error = -ENOMEM; | ||
| 168 | goto err_free_mem; | ||
| 169 | } | ||
| 170 | |||
| 171 | wac_i2c->client = client; | ||
| 172 | wac_i2c->input = input; | ||
| 173 | |||
| 174 | input->name = "Wacom I2C Digitizer"; | ||
| 175 | input->id.bustype = BUS_I2C; | ||
| 176 | input->id.vendor = 0x56a; | ||
| 177 | input->id.version = features.fw_version; | ||
| 178 | input->dev.parent = &client->dev; | ||
| 179 | input->open = wacom_i2c_open; | ||
| 180 | input->close = wacom_i2c_close; | ||
| 181 | |||
| 182 | input->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
| 183 | |||
| 184 | __set_bit(BTN_TOOL_PEN, input->keybit); | ||
| 185 | __set_bit(BTN_TOOL_RUBBER, input->keybit); | ||
| 186 | __set_bit(BTN_STYLUS, input->keybit); | ||
| 187 | __set_bit(BTN_STYLUS2, input->keybit); | ||
| 188 | __set_bit(BTN_TOUCH, input->keybit); | ||
| 189 | |||
| 190 | input_set_abs_params(input, ABS_X, 0, features.x_max, 0, 0); | ||
| 191 | input_set_abs_params(input, ABS_Y, 0, features.y_max, 0, 0); | ||
| 192 | input_set_abs_params(input, ABS_PRESSURE, | ||
| 193 | 0, features.pressure_max, 0, 0); | ||
| 194 | |||
| 195 | input_set_drvdata(input, wac_i2c); | ||
| 196 | |||
| 197 | error = request_threaded_irq(client->irq, NULL, wacom_i2c_irq, | ||
| 198 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
| 199 | "wacom_i2c", wac_i2c); | ||
| 200 | if (error) { | ||
| 201 | dev_err(&client->dev, | ||
| 202 | "Failed to enable IRQ, error: %d\n", error); | ||
| 203 | goto err_free_mem; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* Disable the IRQ, we'll enable it in wac_i2c_open() */ | ||
| 207 | disable_irq(client->irq); | ||
| 208 | |||
| 209 | error = input_register_device(wac_i2c->input); | ||
| 210 | if (error) { | ||
| 211 | dev_err(&client->dev, | ||
| 212 | "Failed to register input device, error: %d\n", error); | ||
| 213 | goto err_free_irq; | ||
| 214 | } | ||
| 215 | |||
| 216 | i2c_set_clientdata(client, wac_i2c); | ||
| 217 | return 0; | ||
| 218 | |||
| 219 | err_free_irq: | ||
| 220 | free_irq(client->irq, wac_i2c); | ||
| 221 | err_free_mem: | ||
| 222 | input_free_device(input); | ||
| 223 | kfree(wac_i2c); | ||
| 224 | |||
| 225 | return error; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int __devexit wacom_i2c_remove(struct i2c_client *client) | ||
| 229 | { | ||
| 230 | struct wacom_i2c *wac_i2c = i2c_get_clientdata(client); | ||
| 231 | |||
| 232 | free_irq(client->irq, wac_i2c); | ||
| 233 | input_unregister_device(wac_i2c->input); | ||
| 234 | kfree(wac_i2c); | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | #ifdef CONFIG_PM_SLEEP | ||
| 240 | static int wacom_i2c_suspend(struct device *dev) | ||
| 241 | { | ||
| 242 | struct i2c_client *client = to_i2c_client(dev); | ||
| 243 | |||
| 244 | disable_irq(client->irq); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | static int wacom_i2c_resume(struct device *dev) | ||
| 250 | { | ||
| 251 | struct i2c_client *client = to_i2c_client(dev); | ||
| 252 | |||
| 253 | enable_irq(client->irq); | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | #endif | ||
| 258 | |||
| 259 | static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); | ||
| 260 | |||
| 261 | static const struct i2c_device_id wacom_i2c_id[] = { | ||
| 262 | { "WAC_I2C_EMR", 0 }, | ||
| 263 | { }, | ||
| 264 | }; | ||
| 265 | MODULE_DEVICE_TABLE(i2c, wacom_i2c_id); | ||
| 266 | |||
| 267 | static struct i2c_driver wacom_i2c_driver = { | ||
| 268 | .driver = { | ||
| 269 | .name = "wacom_i2c", | ||
| 270 | .owner = THIS_MODULE, | ||
| 271 | .pm = &wacom_i2c_pm, | ||
| 272 | }, | ||
| 273 | |||
| 274 | .probe = wacom_i2c_probe, | ||
| 275 | .remove = __devexit_p(wacom_i2c_remove), | ||
| 276 | .id_table = wacom_i2c_id, | ||
| 277 | }; | ||
| 278 | module_i2c_driver(wacom_i2c_driver); | ||
| 279 | |||
| 280 | MODULE_AUTHOR("Tatsunosuke Tobita <tobita.tatsunosuke@wacom.co.jp>"); | ||
| 281 | MODULE_DESCRIPTION("WACOM EMR I2C Driver"); | ||
| 282 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 1569a3934ab2..8f9ad2f893b8 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
| @@ -594,15 +594,4 @@ static struct serio_driver w8001_drv = { | |||
| 594 | .disconnect = w8001_disconnect, | 594 | .disconnect = w8001_disconnect, |
| 595 | }; | 595 | }; |
| 596 | 596 | ||
| 597 | static int __init w8001_init(void) | 597 | module_serio_driver(w8001_drv); |
| 598 | { | ||
| 599 | return serio_register_driver(&w8001_drv); | ||
| 600 | } | ||
| 601 | |||
| 602 | static void __exit w8001_exit(void) | ||
| 603 | { | ||
| 604 | serio_unregister_driver(&w8001_drv); | ||
| 605 | } | ||
| 606 | |||
| 607 | module_init(w8001_init); | ||
| 608 | module_exit(w8001_exit); | ||
