aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-03-09 02:17:32 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-03-09 02:17:32 -0500
commitce67eef6a112bb283c6db39f9195800f31f5599a (patch)
tree34f2e7fbd0b9838abba482dbb1a7db09e6fbb53c /drivers/input
parent776943fd6f104a6e8457dc95a17282e69e963666 (diff)
parent57d54889cd00db2752994b389ba714138652e60c (diff)
Merge commit 'v2.6.34-rc1' into for-linus
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input-compat.h2
-rw-r--r--drivers/input/misc/88pm860x_onkey.c155
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/atlas_btns.c2
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c236
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c4
9 files changed, 418 insertions, 5 deletions
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 47cd9eaee66a..4d8ea32e8a00 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -21,8 +21,6 @@
21 you why the ifdefs are needed? Think about it again. -AK */ 21 you why the ifdefs are needed? Think about it again. -AK */
22#ifdef CONFIG_X86_64 22#ifdef CONFIG_X86_64
23# define INPUT_COMPAT_TEST is_compat_task() 23# define INPUT_COMPAT_TEST is_compat_task()
24#elif defined(CONFIG_IA64)
25# define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
26#elif defined(CONFIG_S390) 24#elif defined(CONFIG_S390)
27# define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) 25# define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
28#elif defined(CONFIG_MIPS) 26#elif defined(CONFIG_MIPS)
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
new file mode 100644
index 000000000000..69a48e8701b9
--- /dev/null
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -0,0 +1,155 @@
1/*
2 * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver
3 *
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file "COPYING" in the main directory of this
9 * archive for more details.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c.h>
25#include <linux/input.h>
26#include <linux/interrupt.h>
27#include <linux/mfd/88pm860x.h>
28
29#define PM8607_WAKEUP 0x0b
30
31#define LONG_ONKEY_EN (1 << 1)
32#define ONKEY_STATUS (1 << 0)
33
34struct pm860x_onkey_info {
35 struct input_dev *idev;
36 struct pm860x_chip *chip;
37 struct i2c_client *i2c;
38 struct device *dev;
39 int irq;
40};
41
42/* 88PM860x gives us an interrupt when ONKEY is held */
43static irqreturn_t pm860x_onkey_handler(int irq, void *data)
44{
45 struct pm860x_onkey_info *info = data;
46 int ret;
47
48 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
49 ret &= ONKEY_STATUS;
50 input_report_key(info->idev, KEY_POWER, ret);
51 input_sync(info->idev);
52
53 /* Enable 8-second long onkey detection */
54 pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
55 return IRQ_HANDLED;
56}
57
58static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
59{
60 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
61 struct pm860x_onkey_info *info;
62 int irq, ret;
63
64 irq = platform_get_irq(pdev, 0);
65 if (irq < 0) {
66 dev_err(&pdev->dev, "No IRQ resource!\n");
67 return -EINVAL;
68 }
69
70 info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL);
71 if (!info)
72 return -ENOMEM;
73 info->chip = chip;
74 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
75 info->dev = &pdev->dev;
76 info->irq = irq + chip->irq_base;
77
78 info->idev = input_allocate_device();
79 if (!info->idev) {
80 dev_err(chip->dev, "Failed to allocate input dev\n");
81 ret = -ENOMEM;
82 goto out;
83 }
84
85 info->idev->name = "88pm860x_on";
86 info->idev->phys = "88pm860x_on/input0";
87 info->idev->id.bustype = BUS_I2C;
88 info->idev->dev.parent = &pdev->dev;
89 info->irq = irq;
90 info->idev->evbit[0] = BIT_MASK(EV_KEY);
91 info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
92
93 ret = input_register_device(info->idev);
94 if (ret) {
95 dev_err(chip->dev, "Can't register input device: %d\n", ret);
96 goto out_reg;
97 }
98
99 ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler,
100 IRQF_ONESHOT, "onkey", info);
101 if (ret < 0) {
102 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
103 info->irq, ret);
104 goto out_irq;
105 }
106
107 platform_set_drvdata(pdev, info);
108 return 0;
109
110out_irq:
111 input_unregister_device(info->idev);
112 kfree(info);
113 return ret;
114
115out_reg:
116 input_free_device(info->idev);
117out:
118 kfree(info);
119 return ret;
120}
121
122static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
123{
124 struct pm860x_onkey_info *info = platform_get_drvdata(pdev);
125
126 free_irq(info->irq, info);
127 input_unregister_device(info->idev);
128 kfree(info);
129 return 0;
130}
131
132static struct platform_driver pm860x_onkey_driver = {
133 .driver = {
134 .name = "88pm860x-onkey",
135 .owner = THIS_MODULE,
136 },
137 .probe = pm860x_onkey_probe,
138 .remove = __devexit_p(pm860x_onkey_remove),
139};
140
141static int __init pm860x_onkey_init(void)
142{
143 return platform_driver_register(&pm860x_onkey_driver);
144}
145module_init(pm860x_onkey_init);
146
147static void __exit pm860x_onkey_exit(void)
148{
149 platform_driver_unregister(&pm860x_onkey_driver);
150}
151module_exit(pm860x_onkey_exit);
152
153MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
154MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
155MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 16ec5233441c..7097bfe581d7 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC
12 12
13if INPUT_MISC 13if INPUT_MISC
14 14
15config INPUT_88PM860X_ONKEY
16 tristate "88PM860x ONKEY support"
17 depends on MFD_88PM860X
18 help
19 Support the ONKEY of Marvell 88PM860x PMICs as an input device
20 reporting power button status.
21
22 To compile this driver as a module, choose M here: the module
23 will be called 88pm860x_onkey.
24
15config INPUT_PCSPKR 25config INPUT_PCSPKR
16 tristate "PC Speaker support" 26 tristate "PC Speaker support"
17 depends on PCSPKR_PLATFORM 27 depends on PCSPKR_PLATFORM
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index a8b84854fb7b..b611615e24ad 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
7obj-$(CONFIG_INPUT_APANEL) += apanel.o 8obj-$(CONFIG_INPUT_APANEL) += apanel.o
8obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o 9obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
9obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 10obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 1b871917340a..dfaa9a045ed8 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
47 47
48static acpi_status acpi_atlas_button_handler(u32 function, 48static acpi_status acpi_atlas_button_handler(u32 function,
49 acpi_physical_address address, 49 acpi_physical_address address,
50 u32 bit_width, acpi_integer *value, 50 u32 bit_width, u64 *value,
51 void *handler_context, void *region_context) 51 void *handler_context, void *region_context)
52{ 52{
53 acpi_status status; 53 acpi_status status;
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
new file mode 100644
index 000000000000..286bb490a9f2
--- /dev/null
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -0,0 +1,236 @@
1/*
2 * Touchscreen driver for Marvell 88PM860x
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h>
15#include <linux/input.h>
16#include <linux/mfd/88pm860x.h>
17
18#define MEAS_LEN (8)
19#define ACCURATE_BIT (12)
20
21/* touch register */
22#define MEAS_EN3 (0x52)
23
24#define MEAS_TSIX_1 (0x8D)
25#define MEAS_TSIX_2 (0x8E)
26#define MEAS_TSIY_1 (0x8F)
27#define MEAS_TSIY_2 (0x90)
28#define MEAS_TSIZ1_1 (0x91)
29#define MEAS_TSIZ1_2 (0x92)
30#define MEAS_TSIZ2_1 (0x93)
31#define MEAS_TSIZ2_2 (0x94)
32
33/* bit definitions of touch */
34#define MEAS_PD_EN (1 << 3)
35#define MEAS_TSIX_EN (1 << 4)
36#define MEAS_TSIY_EN (1 << 5)
37#define MEAS_TSIZ1_EN (1 << 6)
38#define MEAS_TSIZ2_EN (1 << 7)
39
40struct pm860x_touch {
41 struct input_dev *idev;
42 struct i2c_client *i2c;
43 struct pm860x_chip *chip;
44 int irq;
45 int res_x; /* resistor of Xplate */
46};
47
48static irqreturn_t pm860x_touch_handler(int irq, void *data)
49{
50 struct pm860x_touch *touch = data;
51 struct pm860x_chip *chip = touch->chip;
52 unsigned char buf[MEAS_LEN];
53 int x, y, pen_down;
54 int z1, z2, rt = 0;
55 int ret;
56
57 ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf);
58 if (ret < 0)
59 goto out;
60
61 pen_down = buf[1] & (1 << 6);
62 x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F);
63 y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F);
64 z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F);
65 z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F);
66
67 if (pen_down) {
68 if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) {
69 rt = z2 / z1 - 1;
70 rt = (rt * touch->res_x * x) >> ACCURATE_BIT;
71 dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n",
72 z1, z2, rt);
73 }
74 input_report_abs(touch->idev, ABS_X, x);
75 input_report_abs(touch->idev, ABS_Y, y);
76 input_report_abs(touch->idev, ABS_PRESSURE, rt);
77 input_report_key(touch->idev, BTN_TOUCH, 1);
78 dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y);
79 } else {
80 input_report_abs(touch->idev, ABS_PRESSURE, 0);
81 input_report_key(touch->idev, BTN_TOUCH, 0);
82 dev_dbg(chip->dev, "pen release\n");
83 }
84 input_sync(touch->idev);
85
86out:
87 return IRQ_HANDLED;
88}
89
90static int pm860x_touch_open(struct input_dev *dev)
91{
92 struct pm860x_touch *touch = input_get_drvdata(dev);
93 int data, ret;
94
95 data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
96 | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
97 ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data);
98 if (ret < 0)
99 goto out;
100 return 0;
101out:
102 return ret;
103}
104
105static void pm860x_touch_close(struct input_dev *dev)
106{
107 struct pm860x_touch *touch = input_get_drvdata(dev);
108 int data;
109
110 data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
111 | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
112 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
113}
114
115static int __devinit pm860x_touch_probe(struct platform_device *pdev)
116{
117 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
118 struct pm860x_platform_data *pm860x_pdata = \
119 pdev->dev.parent->platform_data;
120 struct pm860x_touch_pdata *pdata = NULL;
121 struct pm860x_touch *touch;
122 int irq, ret;
123
124 irq = platform_get_irq(pdev, 0);
125 if (irq < 0) {
126 dev_err(&pdev->dev, "No IRQ resource!\n");
127 return -EINVAL;
128 }
129
130 if (!pm860x_pdata) {
131 dev_err(&pdev->dev, "platform data is missing\n");
132 return -EINVAL;
133 }
134
135 pdata = pm860x_pdata->touch;
136 if (!pdata) {
137 dev_err(&pdev->dev, "touchscreen data is missing\n");
138 return -EINVAL;
139 }
140
141 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
142 if (touch == NULL)
143 return -ENOMEM;
144 dev_set_drvdata(&pdev->dev, touch);
145
146 touch->idev = input_allocate_device();
147 if (touch->idev == NULL) {
148 dev_err(&pdev->dev, "Failed to allocate input device!\n");
149 ret = -ENOMEM;
150 goto out;
151 }
152
153 touch->idev->name = "88pm860x-touch";
154 touch->idev->phys = "88pm860x/input0";
155 touch->idev->id.bustype = BUS_I2C;
156 touch->idev->dev.parent = &pdev->dev;
157 touch->idev->open = pm860x_touch_open;
158 touch->idev->close = pm860x_touch_close;
159 touch->chip = chip;
160 touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
161 touch->irq = irq + chip->irq_base;
162 touch->res_x = pdata->res_x;
163 input_set_drvdata(touch->idev, touch);
164
165 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
166 IRQF_ONESHOT, "touch", touch);
167 if (ret < 0)
168 goto out_irq;
169
170 __set_bit(EV_ABS, touch->idev->evbit);
171 __set_bit(ABS_X, touch->idev->absbit);
172 __set_bit(ABS_Y, touch->idev->absbit);
173 __set_bit(ABS_PRESSURE, touch->idev->absbit);
174 __set_bit(EV_SYN, touch->idev->evbit);
175 __set_bit(EV_KEY, touch->idev->evbit);
176 __set_bit(BTN_TOUCH, touch->idev->keybit);
177
178 input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0);
179 input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0);
180 input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT,
181 0, 0);
182
183 ret = input_register_device(touch->idev);
184 if (ret < 0) {
185 dev_err(chip->dev, "Failed to register touch!\n");
186 goto out_rg;
187 }
188
189 platform_set_drvdata(pdev, touch);
190 return 0;
191out_rg:
192 free_irq(touch->irq, touch);
193out_irq:
194 input_free_device(touch->idev);
195out:
196 kfree(touch);
197 return ret;
198}
199
200static int __devexit pm860x_touch_remove(struct platform_device *pdev)
201{
202 struct pm860x_touch *touch = platform_get_drvdata(pdev);
203
204 input_unregister_device(touch->idev);
205 free_irq(touch->irq, touch);
206 platform_set_drvdata(pdev, NULL);
207 kfree(touch);
208 return 0;
209}
210
211static struct platform_driver pm860x_touch_driver = {
212 .driver = {
213 .name = "88pm860x-touch",
214 .owner = THIS_MODULE,
215 },
216 .probe = pm860x_touch_probe,
217 .remove = __devexit_p(pm860x_touch_remove),
218};
219
220static int __init pm860x_touch_init(void)
221{
222 return platform_driver_register(&pm860x_touch_driver);
223}
224module_init(pm860x_touch_init);
225
226static void __exit pm860x_touch_exit(void)
227{
228 platform_driver_unregister(&pm860x_touch_driver);
229}
230module_exit(pm860x_touch_exit);
231
232MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x");
233MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
234MODULE_LICENSE("GPL");
235MODULE_ALIAS("platform:88pm860x-touch");
236
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6457e060ae49..7208654a94ae 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,18 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_88PM860X
15 tristate "Marvell 88PM860x touchscreen"
16 depends on MFD_88PM860X
17 help
18 Say Y here if you have a 88PM860x PMIC and want to enable
19 support for the built-in touchscreen.
20
21 If unsure, say N.
22
23 To compile this driver as a module, choose M here: the
24 module will be called 88pm860x-ts.
25
14config TOUCHSCREEN_ADS7846 26config TOUCHSCREEN_ADS7846
15 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" 27 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
16 depends on SPI_MASTER 28 depends on SPI_MASTER
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d61a3b4def9a..7fef7d5cca23 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,7 @@
6 6
7wm97xx-ts-y := wm97xx-core.o 7wm97xx-ts-y := wm97xx-core.o
8 8
9obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
9obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o 10obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
10obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o 11obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
11obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 12obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index be115b3b65eb..be54fd639aca 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -44,7 +44,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
44{ 44{
45 struct mc13783_ts_priv *priv = data; 45 struct mc13783_ts_priv *priv = data;
46 46
47 mc13783_ackirq(priv->mc13783, irq); 47 mc13783_irq_ack(priv->mc13783, irq);
48 48
49 /* 49 /*
50 * Kick off reading coordinates. Note that if work happens already 50 * Kick off reading coordinates. Note that if work happens already
@@ -135,7 +135,7 @@ static int mc13783_ts_open(struct input_dev *dev)
135 135
136 mc13783_lock(priv->mc13783); 136 mc13783_lock(priv->mc13783);
137 137
138 mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS); 138 mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS);
139 139
140 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, 140 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
141 mc13783_ts_handler, MC13783_TS_NAME, priv); 141 mc13783_ts_handler, MC13783_TS_NAME, priv);