aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt41
-rw-r--r--arch/arm/mach-imx/mach-cpuimx35.c2
-rw-r--r--arch/arm/mach-imx/mach-cpuimx51sd.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c2
-rw-r--r--drivers/input/touchscreen/tsc2007.c173
-rw-r--r--include/linux/i2c/tsc2007.h6
6 files changed, 180 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
new file mode 100644
index 000000000000..ec365e172236
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
@@ -0,0 +1,41 @@
1* Texas Instruments tsc2007 touchscreen controller
2
3Required properties:
4- compatible: must be "ti,tsc2007".
5- reg: I2C address of the chip.
6- ti,x-plate-ohms: X-plate resistance in ohms.
7
8Optional properties:
9- gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
10 The penirq pin goes to low when the panel is touched.
11 (see GPIO binding[1] for more details).
12- interrupt-parent: the phandle for the gpio controller
13 (see interrupt binding[0]).
14- interrupts: (gpio) interrupt to which the chip is connected
15 (see interrupt binding[0]).
16- ti,max-rt: maximum pressure.
17- ti,fuzzx: specifies the absolute input fuzz x value.
18 If set, it will permit noise in the data up to +- the value given to the fuzz
19 parameter, that is used to filter noise from the event stream.
20- ti,fuzzy: specifies the absolute input fuzz y value.
21- ti,fuzzz: specifies the absolute input fuzz z value.
22- ti,poll-period: how much time to wait (in milliseconds) before reading again the
23 values from the tsc2007.
24
25[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
26[1]: Documentation/devicetree/bindings/gpio/gpio.txt
27
28Example:
29 &i2c1 {
30 /* ... */
31 tsc2007@49 {
32 compatible = "ti,tsc2007";
33 reg = <0x49>;
34 interrupt-parent = <&gpio4>;
35 interrupts = <0x0 0x8>;
36 gpios = <&gpio4 0 0>;
37 ti,x-plate-ohms = <180>;
38 };
39
40 /* ... */
41 };
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c
index 771362d1fbee..65e4c53e1554 100644
--- a/arch/arm/mach-imx/mach-cpuimx35.c
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -53,7 +53,7 @@ static const struct imxi2c_platform_data
53}; 53};
54 54
55#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2) 55#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)
56static int tsc2007_get_pendown_state(void) 56static int tsc2007_get_pendown_state(struct device *dev)
57{ 57{
58 return !gpio_get_value(TSC2007_IRQGPIO); 58 return !gpio_get_value(TSC2007_IRQGPIO);
59} 59}
diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index 9b5ddf5bbd33..1fba2b8e983f 100644
--- a/arch/arm/mach-imx/mach-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
@@ -121,7 +121,7 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
121 .flags = IMXUART_HAVE_RTSCTS, 121 .flags = IMXUART_HAVE_RTSCTS,
122}; 122};
123 123
124static int tsc2007_get_pendown_state(void) 124static int tsc2007_get_pendown_state(struct device *dev)
125{ 125{
126 if (mx51_revision() < IMX_CHIP_REVISION_3_0) 126 if (mx51_revision() < IMX_CHIP_REVISION_3_0)
127 return !gpio_get_value(TSC2007_IRQGPIO_REV2); 127 return !gpio_get_value(TSC2007_IRQGPIO_REV2);
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 1fa8be409771..23d7e45f9d14 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -501,7 +501,7 @@ static struct platform_device keysc_device = {
501/* TouchScreen */ 501/* TouchScreen */
502#define IRQ0 evt2irq(0x600) 502#define IRQ0 evt2irq(0x600)
503 503
504static int ts_get_pendown_state(void) 504static int ts_get_pendown_state(struct device *dev)
505{ 505{
506 int val = 0; 506 int val = 0;
507 gpio_free(GPIO_FN_INTC_IRQ0); 507 gpio_free(GPIO_FN_INTC_IRQ0);
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 0b67ba476b4c..88b150a0b8ee 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -26,6 +26,9 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/i2c/tsc2007.h> 28#include <linux/i2c/tsc2007.h>
29#include <linux/of_device.h>
30#include <linux/of.h>
31#include <linux/of_gpio.h>
29 32
30#define TSC2007_MEASURE_TEMP0 (0x0 << 4) 33#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
31#define TSC2007_MEASURE_AUX (0x2 << 4) 34#define TSC2007_MEASURE_AUX (0x2 << 4)
@@ -74,13 +77,17 @@ struct tsc2007 {
74 u16 max_rt; 77 u16 max_rt;
75 unsigned long poll_delay; 78 unsigned long poll_delay;
76 unsigned long poll_period; 79 unsigned long poll_period;
80 int fuzzx;
81 int fuzzy;
82 int fuzzz;
77 83
84 unsigned gpio;
78 int irq; 85 int irq;
79 86
80 wait_queue_head_t wait; 87 wait_queue_head_t wait;
81 bool stopped; 88 bool stopped;
82 89
83 int (*get_pendown_state)(void); 90 int (*get_pendown_state)(struct device *);
84 void (*clear_penirq)(void); 91 void (*clear_penirq)(void);
85}; 92};
86 93
@@ -161,7 +168,7 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts)
161 if (!ts->get_pendown_state) 168 if (!ts->get_pendown_state)
162 return true; 169 return true;
163 170
164 return ts->get_pendown_state(); 171 return ts->get_pendown_state(&ts->client->dev);
165} 172}
166 173
167static irqreturn_t tsc2007_soft_irq(int irq, void *handle) 174static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
@@ -178,7 +185,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
178 185
179 rt = tsc2007_calculate_pressure(ts, &tc); 186 rt = tsc2007_calculate_pressure(ts, &tc);
180 187
181 if (rt == 0 && !ts->get_pendown_state) { 188 if (!rt && !ts->get_pendown_state) {
182 /* 189 /*
183 * If pressure reported is 0 and we don't have 190 * If pressure reported is 0 and we don't have
184 * callback to check pendown state, we have to 191 * callback to check pendown state, we have to
@@ -228,7 +235,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
228{ 235{
229 struct tsc2007 *ts = handle; 236 struct tsc2007 *ts = handle;
230 237
231 if (!ts->get_pendown_state || likely(ts->get_pendown_state())) 238 if (tsc2007_is_pen_down(ts))
232 return IRQ_WAKE_THREAD; 239 return IRQ_WAKE_THREAD;
233 240
234 if (ts->clear_penirq) 241 if (ts->clear_penirq)
@@ -273,35 +280,74 @@ static void tsc2007_close(struct input_dev *input_dev)
273 tsc2007_stop(ts); 280 tsc2007_stop(ts);
274} 281}
275 282
276static int tsc2007_probe(struct i2c_client *client, 283#ifdef CONFIG_OF
277 const struct i2c_device_id *id) 284static int tsc2007_get_pendown_state_gpio(struct device *dev)
278{ 285{
279 struct tsc2007 *ts; 286 struct i2c_client *client = to_i2c_client(dev);
280 struct tsc2007_platform_data *pdata = client->dev.platform_data; 287 struct tsc2007 *ts = i2c_get_clientdata(client);
281 struct input_dev *input_dev; 288
282 int err; 289 return !gpio_get_value(ts->gpio);
290}
291
292static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
293{
294 struct device_node *np = client->dev.of_node;
295 u32 val32;
296 u64 val64;
283 297
284 if (!pdata) { 298 if (!np) {
285 dev_err(&client->dev, "platform data is required!\n"); 299 dev_err(&client->dev, "missing device tree data\n");
286 return -EINVAL; 300 return -EINVAL;
287 } 301 }
288 302
289 if (!i2c_check_functionality(client->adapter, 303 if (!of_property_read_u32(np, "ti,max-rt", &val32))
290 I2C_FUNC_SMBUS_READ_WORD_DATA)) 304 ts->max_rt = val32;
291 return -EIO; 305 else
306 ts->max_rt = MAX_12BIT;
292 307
293 ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL); 308 if (!of_property_read_u32(np, "ti,fuzzx", &val32))
294 input_dev = input_allocate_device(); 309 ts->fuzzx = val32;
295 if (!ts || !input_dev) { 310
296 err = -ENOMEM; 311 if (!of_property_read_u32(np, "ti,fuzzy", &val32))
297 goto err_free_mem; 312 ts->fuzzy = val32;
313
314 if (!of_property_read_u32(np, "ti,fuzzz", &val32))
315 ts->fuzzz = val32;
316
317 if (!of_property_read_u64(np, "ti,poll-period", &val64))
318 ts->poll_period = val64;
319 else
320 ts->poll_period = 1;
321
322 if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) {
323 ts->x_plate_ohms = val32;
324 } else {
325 dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property.");
326 return -EINVAL;
298 } 327 }
299 328
300 ts->client = client; 329 ts->gpio = of_get_gpio(np, 0);
301 ts->irq = client->irq; 330 if (gpio_is_valid(ts->gpio))
302 ts->input = input_dev; 331 ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
303 init_waitqueue_head(&ts->wait); 332 else
333 dev_warn(&client->dev,
334 "GPIO not specified in DT (of_get_gpio returned %d)\n",
335 ts->gpio);
304 336
337 return 0;
338}
339#else
340static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
341{
342 dev_err(&client->dev, "platform data is required!\n");
343 return -EINVAL;
344}
345#endif
346
347static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
348 const struct tsc2007_platform_data *pdata,
349 const struct i2c_device_id *id)
350{
305 ts->model = pdata->model; 351 ts->model = pdata->model;
306 ts->x_plate_ohms = pdata->x_plate_ohms; 352 ts->x_plate_ohms = pdata->x_plate_ohms;
307 ts->max_rt = pdata->max_rt ? : MAX_12BIT; 353 ts->max_rt = pdata->max_rt ? : MAX_12BIT;
@@ -309,13 +355,54 @@ static int tsc2007_probe(struct i2c_client *client,
309 ts->poll_period = pdata->poll_period ? : 1; 355 ts->poll_period = pdata->poll_period ? : 1;
310 ts->get_pendown_state = pdata->get_pendown_state; 356 ts->get_pendown_state = pdata->get_pendown_state;
311 ts->clear_penirq = pdata->clear_penirq; 357 ts->clear_penirq = pdata->clear_penirq;
358 ts->fuzzx = pdata->fuzzx;
359 ts->fuzzy = pdata->fuzzy;
360 ts->fuzzz = pdata->fuzzz;
312 361
313 if (pdata->x_plate_ohms == 0) { 362 if (pdata->x_plate_ohms == 0) {
314 dev_err(&client->dev, "x_plate_ohms is not set up in platform data"); 363 dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
315 err = -EINVAL; 364 return -EINVAL;
316 goto err_free_mem;
317 } 365 }
318 366
367 return 0;
368}
369
370static int tsc2007_probe(struct i2c_client *client,
371 const struct i2c_device_id *id)
372{
373 const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
374 struct tsc2007 *ts;
375 struct input_dev *input_dev;
376 int err;
377
378 if (!i2c_check_functionality(client->adapter,
379 I2C_FUNC_SMBUS_READ_WORD_DATA))
380 return -EIO;
381
382 ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
383 if (!ts)
384 return -ENOMEM;
385
386 if (pdata)
387 err = tsc2007_probe_pdev(client, ts, pdata, id);
388 else
389 err = tsc2007_probe_dt(client, ts);
390 if (err)
391 return err;
392
393 input_dev = input_allocate_device();
394 if (!input_dev) {
395 err = -ENOMEM;
396 goto err_free_input;
397 };
398
399 i2c_set_clientdata(client, ts);
400
401 ts->client = client;
402 ts->irq = client->irq;
403 ts->input = input_dev;
404 init_waitqueue_head(&ts->wait);
405
319 snprintf(ts->phys, sizeof(ts->phys), 406 snprintf(ts->phys, sizeof(ts->phys),
320 "%s/input0", dev_name(&client->dev)); 407 "%s/input0", dev_name(&client->dev));
321 408
@@ -331,19 +418,19 @@ static int tsc2007_probe(struct i2c_client *client,
331 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 418 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
332 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 419 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
333 420
334 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); 421 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
335 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); 422 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
336 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 423 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
337 pdata->fuzzz, 0); 424 ts->fuzzz, 0);
338 425
339 if (pdata->init_platform_hw) 426 if (pdata && pdata->init_platform_hw)
340 pdata->init_platform_hw(); 427 pdata->init_platform_hw();
341 428
342 err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq, 429 err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,
343 IRQF_ONESHOT, client->dev.driver->name, ts); 430 IRQF_ONESHOT, client->dev.driver->name, ts);
344 if (err < 0) { 431 if (err < 0) {
345 dev_err(&client->dev, "irq %d busy?\n", ts->irq); 432 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
346 goto err_free_mem; 433 goto err_free_input;
347 } 434 }
348 435
349 tsc2007_stop(ts); 436 tsc2007_stop(ts);
@@ -352,28 +439,25 @@ static int tsc2007_probe(struct i2c_client *client,
352 if (err) 439 if (err)
353 goto err_free_irq; 440 goto err_free_irq;
354 441
355 i2c_set_clientdata(client, ts);
356
357 return 0; 442 return 0;
358 443
359 err_free_irq: 444 err_free_irq:
360 free_irq(ts->irq, ts); 445 free_irq(ts->irq, ts);
361 if (pdata->exit_platform_hw) 446 if (pdata && pdata->exit_platform_hw)
362 pdata->exit_platform_hw(); 447 pdata->exit_platform_hw();
363 err_free_mem: 448 err_free_input:
364 input_free_device(input_dev); 449 input_free_device(input_dev);
365 kfree(ts);
366 return err; 450 return err;
367} 451}
368 452
369static int tsc2007_remove(struct i2c_client *client) 453static int tsc2007_remove(struct i2c_client *client)
370{ 454{
371 struct tsc2007 *ts = i2c_get_clientdata(client); 455 const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
372 struct tsc2007_platform_data *pdata = client->dev.platform_data; 456 struct tsc2007 *ts = i2c_get_clientdata(client);
373 457
374 free_irq(ts->irq, ts); 458 free_irq(ts->irq, ts);
375 459
376 if (pdata->exit_platform_hw) 460 if (pdata && pdata->exit_platform_hw)
377 pdata->exit_platform_hw(); 461 pdata->exit_platform_hw();
378 462
379 input_unregister_device(ts->input); 463 input_unregister_device(ts->input);
@@ -389,10 +473,19 @@ static const struct i2c_device_id tsc2007_idtable[] = {
389 473
390MODULE_DEVICE_TABLE(i2c, tsc2007_idtable); 474MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
391 475
476#ifdef CONFIG_OF
477static const struct of_device_id tsc2007_of_match[] = {
478 { .compatible = "ti,tsc2007" },
479 { /* sentinel */ }
480};
481MODULE_DEVICE_TABLE(of, tsc2007_of_match);
482#endif
483
392static struct i2c_driver tsc2007_driver = { 484static struct i2c_driver tsc2007_driver = {
393 .driver = { 485 .driver = {
394 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
395 .name = "tsc2007" 487 .name = "tsc2007",
488 .of_match_table = of_match_ptr(tsc2007_of_match),
396 }, 489 },
397 .id_table = tsc2007_idtable, 490 .id_table = tsc2007_idtable,
398 .probe = tsc2007_probe, 491 .probe = tsc2007_probe,
diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
index 506a9f7af51e..041c8e823664 100644
--- a/include/linux/i2c/tsc2007.h
+++ b/include/linux/i2c/tsc2007.h
@@ -14,9 +14,9 @@ struct tsc2007_platform_data {
14 int fuzzy; 14 int fuzzy;
15 int fuzzz; 15 int fuzzz;
16 16
17 int (*get_pendown_state)(void); 17 int (*get_pendown_state)(struct device *);
18 void (*clear_penirq)(void); /* If needed, clear 2nd level 18 /* If needed, clear 2nd level interrupt source */
19 interrupt source */ 19 void (*clear_penirq)(void);
20 int (*init_platform_hw)(void); 20 int (*init_platform_hw)(void);
21 void (*exit_platform_hw)(void); 21 void (*exit_platform_hw)(void);
22}; 22};