diff options
author | Patil, Rachna <rachna@ti.com> | 2013-01-23 22:45:10 -0500 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-06-12 12:36:30 -0400 |
commit | 0396310b0eba71595c1151ce7c8fde7a9f33f719 (patch) | |
tree | 10edb156ab7b780558722a4bffee9e410fdfcc57 /drivers/input | |
parent | af9c2fe3740fe8dac05eede8805d9aaa45972cb6 (diff) |
input: ti_am33x_tsc: Add DT support
This patch adds DT support to touch driver. It also provides a binding
document which is used by the MFD and IIO part of the device.
This patch also renames steps_to_configure to coordinate_readouts
because the original name misleads the purpose of the variable.
Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
Signed-off-by: Patil, Rachna <rachna@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/ti_am335x_tsc.c | 105 |
1 files changed, 82 insertions, 23 deletions
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 7b7de6035af7..449c0fbbe1d6 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/input/ti_am335x_tsc.h> | 27 | #include <linux/input/ti_am335x_tsc.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/of_device.h> | ||
29 | 31 | ||
30 | #include <linux/mfd/ti_am335x_tscadc.h> | 32 | #include <linux/mfd/ti_am335x_tscadc.h> |
31 | 33 | ||
@@ -47,7 +49,7 @@ struct titsc { | |||
47 | unsigned int wires; | 49 | unsigned int wires; |
48 | unsigned int x_plate_resistance; | 50 | unsigned int x_plate_resistance; |
49 | bool pen_down; | 51 | bool pen_down; |
50 | int steps_to_configure; | 52 | int coordinate_readouts; |
51 | u32 config_inp[4]; | 53 | u32 config_inp[4]; |
52 | u32 bit_xp, bit_xn, bit_yp, bit_yn; | 54 | u32 bit_xp, bit_xn, bit_yp, bit_yn; |
53 | u32 inp_xp, inp_xn, inp_yp, inp_yn; | 55 | u32 inp_xp, inp_xn, inp_yp, inp_yn; |
@@ -123,7 +125,7 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
123 | int i, total_steps; | 125 | int i, total_steps; |
124 | 126 | ||
125 | /* Configure the Step registers */ | 127 | /* Configure the Step registers */ |
126 | total_steps = 2 * ts_dev->steps_to_configure; | 128 | total_steps = 2 * ts_dev->coordinate_readouts; |
127 | 129 | ||
128 | config = STEPCONFIG_MODE_HWSYNC | | 130 | config = STEPCONFIG_MODE_HWSYNC | |
129 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; | 131 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
@@ -141,7 +143,7 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
141 | break; | 143 | break; |
142 | } | 144 | } |
143 | 145 | ||
144 | for (i = 1; i <= ts_dev->steps_to_configure; i++) { | 146 | for (i = 1; i <= ts_dev->coordinate_readouts; i++) { |
145 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 147 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
146 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 148 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
147 | } | 149 | } |
@@ -163,7 +165,7 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
163 | break; | 165 | break; |
164 | } | 166 | } |
165 | 167 | ||
166 | for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { | 168 | for (i = (ts_dev->coordinate_readouts + 1); i <= total_steps; i++) { |
167 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 169 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
168 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 170 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
169 | } | 171 | } |
@@ -218,7 +220,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev, | |||
218 | read = titsc_readl(ts_dev, REG_FIFO0); | 220 | read = titsc_readl(ts_dev, REG_FIFO0); |
219 | channel = read & 0xf0000; | 221 | channel = read & 0xf0000; |
220 | channel = channel >> 0x10; | 222 | channel = channel >> 0x10; |
221 | if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) { | 223 | if ((channel >= 0) && (channel < ts_dev->coordinate_readouts)) { |
222 | read &= 0xfff; | 224 | read &= 0xfff; |
223 | diff = abs(read - prev_val_x); | 225 | diff = abs(read - prev_val_x); |
224 | if (diff < prev_diff_x) { | 226 | if (diff < prev_diff_x) { |
@@ -231,8 +233,8 @@ static void titsc_read_coordinates(struct titsc *ts_dev, | |||
231 | read = titsc_readl(ts_dev, REG_FIFO1); | 233 | read = titsc_readl(ts_dev, REG_FIFO1); |
232 | channel = read & 0xf0000; | 234 | channel = read & 0xf0000; |
233 | channel = channel >> 0x10; | 235 | channel = channel >> 0x10; |
234 | if ((channel >= ts_dev->steps_to_configure) && | 236 | if ((channel >= ts_dev->coordinate_readouts) && |
235 | (channel < (2 * ts_dev->steps_to_configure - 1))) { | 237 | (channel < (2 * ts_dev->coordinate_readouts - 1))) { |
236 | read &= 0xfff; | 238 | read &= 0xfff; |
237 | diff = abs(read - prev_val_y); | 239 | diff = abs(read - prev_val_y); |
238 | if (diff < prev_diff_y) { | 240 | if (diff < prev_diff_y) { |
@@ -310,6 +312,59 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
310 | return IRQ_HANDLED; | 312 | return IRQ_HANDLED; |
311 | } | 313 | } |
312 | 314 | ||
315 | static int titsc_parse_dt(struct platform_device *pdev, | ||
316 | struct titsc *ts_dev) | ||
317 | { | ||
318 | struct device_node *node = pdev->dev.of_node; | ||
319 | int err; | ||
320 | |||
321 | if (!node) | ||
322 | return -EINVAL; | ||
323 | |||
324 | err = of_property_read_u32(node, "ti,wires", &ts_dev->wires); | ||
325 | if (err < 0) | ||
326 | return err; | ||
327 | switch (ts_dev->wires) { | ||
328 | case 4: | ||
329 | case 5: | ||
330 | case 8: | ||
331 | break; | ||
332 | default: | ||
333 | return -EINVAL; | ||
334 | } | ||
335 | |||
336 | err = of_property_read_u32(node, "ti,x-plate-resistance", | ||
337 | &ts_dev->x_plate_resistance); | ||
338 | if (err < 0) | ||
339 | return err; | ||
340 | |||
341 | err = of_property_read_u32(node, "ti,coordiante-readouts", | ||
342 | &ts_dev->coordinate_readouts); | ||
343 | if (err < 0) | ||
344 | return err; | ||
345 | |||
346 | return of_property_read_u32_array(node, "ti,wire-config", | ||
347 | ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp)); | ||
348 | } | ||
349 | |||
350 | static int titsc_parse_pdata(struct ti_tscadc_dev *tscadc_dev, | ||
351 | struct titsc *ts_dev) | ||
352 | { | ||
353 | struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data; | ||
354 | |||
355 | if (!pdata) | ||
356 | return -EINVAL; | ||
357 | |||
358 | ts_dev->wires = pdata->tsc_init->wires; | ||
359 | ts_dev->x_plate_resistance = | ||
360 | pdata->tsc_init->x_plate_resistance; | ||
361 | ts_dev->steps_to_configure = | ||
362 | pdata->tsc_init->steps_to_configure; | ||
363 | memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config, | ||
364 | sizeof(pdata->tsc_init->wire_config)); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
313 | /* | 368 | /* |
314 | * The functions for inserting/removing driver as a module. | 369 | * The functions for inserting/removing driver as a module. |
315 | */ | 370 | */ |
@@ -319,16 +374,8 @@ static int titsc_probe(struct platform_device *pdev) | |||
319 | struct titsc *ts_dev; | 374 | struct titsc *ts_dev; |
320 | struct input_dev *input_dev; | 375 | struct input_dev *input_dev; |
321 | struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev); | 376 | struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev); |
322 | struct mfd_tscadc_board *pdata; | ||
323 | int err; | 377 | int err; |
324 | 378 | ||
325 | pdata = tscadc_dev->dev->platform_data; | ||
326 | |||
327 | if (!pdata) { | ||
328 | dev_err(&pdev->dev, "Could not find platform data\n"); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | /* Allocate memory for device */ | 379 | /* Allocate memory for device */ |
333 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); | 380 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); |
334 | input_dev = input_allocate_device(); | 381 | input_dev = input_allocate_device(); |
@@ -342,11 +389,16 @@ static int titsc_probe(struct platform_device *pdev) | |||
342 | ts_dev->mfd_tscadc = tscadc_dev; | 389 | ts_dev->mfd_tscadc = tscadc_dev; |
343 | ts_dev->input = input_dev; | 390 | ts_dev->input = input_dev; |
344 | ts_dev->irq = tscadc_dev->irq; | 391 | ts_dev->irq = tscadc_dev->irq; |
345 | ts_dev->wires = pdata->tsc_init->wires; | 392 | |
346 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; | 393 | if (tscadc_dev->dev->platform_data) |
347 | ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; | 394 | err = titsc_parse_pdata(tscadc_dev, ts_dev); |
348 | memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config, | 395 | else |
349 | sizeof(pdata->tsc_init->wire_config)); | 396 | err = titsc_parse_dt(pdev, ts_dev); |
397 | |||
398 | if (err) { | ||
399 | dev_err(&pdev->dev, "Could not find valid DT data.\n"); | ||
400 | goto err_free_mem; | ||
401 | } | ||
350 | 402 | ||
351 | err = request_irq(ts_dev->irq, titsc_irq, | 403 | err = request_irq(ts_dev->irq, titsc_irq, |
352 | 0, pdev->dev.driver->name, ts_dev); | 404 | 0, pdev->dev.driver->name, ts_dev); |
@@ -362,7 +414,7 @@ static int titsc_probe(struct platform_device *pdev) | |||
362 | goto err_free_irq; | 414 | goto err_free_irq; |
363 | } | 415 | } |
364 | titsc_step_config(ts_dev); | 416 | titsc_step_config(ts_dev); |
365 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); | 417 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->coordinate_readouts); |
366 | 418 | ||
367 | input_dev->name = "ti-tsc"; | 419 | input_dev->name = "ti-tsc"; |
368 | input_dev->dev.parent = &pdev->dev; | 420 | input_dev->dev.parent = &pdev->dev; |
@@ -398,7 +450,7 @@ static int titsc_remove(struct platform_device *pdev) | |||
398 | free_irq(ts_dev->irq, ts_dev); | 450 | free_irq(ts_dev->irq, ts_dev); |
399 | 451 | ||
400 | /* total steps followed by the enable mask */ | 452 | /* total steps followed by the enable mask */ |
401 | steps = 2 * ts_dev->steps_to_configure + 2; | 453 | steps = 2 * ts_dev->coordinate_readouts + 2; |
402 | steps = (1 << steps) - 1; | 454 | steps = (1 << steps) - 1; |
403 | am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps); | 455 | am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps); |
404 | 456 | ||
@@ -439,7 +491,7 @@ static int titsc_resume(struct device *dev) | |||
439 | } | 491 | } |
440 | titsc_step_config(ts_dev); | 492 | titsc_step_config(ts_dev); |
441 | titsc_writel(ts_dev, REG_FIFO0THR, | 493 | titsc_writel(ts_dev, REG_FIFO0THR, |
442 | ts_dev->steps_to_configure); | 494 | ts_dev->coordinate_readouts); |
443 | return 0; | 495 | return 0; |
444 | } | 496 | } |
445 | 497 | ||
@@ -452,6 +504,12 @@ static const struct dev_pm_ops titsc_pm_ops = { | |||
452 | #define TITSC_PM_OPS NULL | 504 | #define TITSC_PM_OPS NULL |
453 | #endif | 505 | #endif |
454 | 506 | ||
507 | static const struct of_device_id ti_tsc_dt_ids[] = { | ||
508 | { .compatible = "ti,am3359-tsc", }, | ||
509 | { } | ||
510 | }; | ||
511 | MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids); | ||
512 | |||
455 | static struct platform_driver ti_tsc_driver = { | 513 | static struct platform_driver ti_tsc_driver = { |
456 | .probe = titsc_probe, | 514 | .probe = titsc_probe, |
457 | .remove = titsc_remove, | 515 | .remove = titsc_remove, |
@@ -459,6 +517,7 @@ static struct platform_driver ti_tsc_driver = { | |||
459 | .name = "tsc", | 517 | .name = "tsc", |
460 | .owner = THIS_MODULE, | 518 | .owner = THIS_MODULE, |
461 | .pm = TITSC_PM_OPS, | 519 | .pm = TITSC_PM_OPS, |
520 | .of_match_table = of_match_ptr(ti_tsc_dt_ids), | ||
462 | }, | 521 | }, |
463 | }; | 522 | }; |
464 | module_platform_driver(ti_tsc_driver); | 523 | module_platform_driver(ti_tsc_driver); |