diff options
Diffstat (limited to 'drivers/input/touchscreen/stmpe-ts.c')
-rw-r--r-- | drivers/input/touchscreen/stmpe-ts.c | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 692b685720ce..84d884b4ec3e 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* STMicroelectronics STMPE811 Touchscreen Driver | 1 | /* |
2 | * STMicroelectronics STMPE811 Touchscreen Driver | ||
2 | * | 3 | * |
3 | * (C) 2010 Luotao Fu <l.fu@pengutronix.de> | 4 | * (C) 2010 Luotao Fu <l.fu@pengutronix.de> |
4 | * All rights reserved. | 5 | * All rights reserved. |
@@ -16,6 +17,7 @@ | |||
16 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 22 | #include <linux/input.h> |
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -166,7 +168,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data) | |||
166 | return IRQ_HANDLED; | 168 | return IRQ_HANDLED; |
167 | } | 169 | } |
168 | 170 | ||
169 | static int __devinit stmpe_init_hw(struct stmpe_touch *ts) | 171 | static int stmpe_init_hw(struct stmpe_touch *ts) |
170 | { | 172 | { |
171 | int ret; | 173 | int ret; |
172 | u8 adc_ctrl1, adc_ctrl1_mask, tsc_cfg, tsc_cfg_mask; | 174 | u8 adc_ctrl1, adc_ctrl1_mask, tsc_cfg, tsc_cfg_mask; |
@@ -261,41 +263,18 @@ static void stmpe_ts_close(struct input_dev *dev) | |||
261 | STMPE_TSC_CTRL_TSC_EN, 0); | 263 | STMPE_TSC_CTRL_TSC_EN, 0); |
262 | } | 264 | } |
263 | 265 | ||
264 | static int __devinit stmpe_input_probe(struct platform_device *pdev) | 266 | static void stmpe_ts_get_platform_info(struct platform_device *pdev, |
267 | struct stmpe_touch *ts) | ||
265 | { | 268 | { |
266 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 269 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
267 | struct stmpe_platform_data *pdata = stmpe->pdata; | 270 | struct device_node *np = pdev->dev.of_node; |
268 | struct stmpe_touch *ts; | ||
269 | struct input_dev *idev; | ||
270 | struct stmpe_ts_platform_data *ts_pdata = NULL; | 271 | struct stmpe_ts_platform_data *ts_pdata = NULL; |
271 | int ret; | ||
272 | int ts_irq; | ||
273 | |||
274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | ||
275 | if (ts_irq < 0) | ||
276 | return ts_irq; | ||
277 | |||
278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
279 | if (!ts) { | ||
280 | ret = -ENOMEM; | ||
281 | goto err_out; | ||
282 | } | ||
283 | 272 | ||
284 | idev = input_allocate_device(); | ||
285 | if (!idev) { | ||
286 | ret = -ENOMEM; | ||
287 | goto err_free_ts; | ||
288 | } | ||
289 | |||
290 | platform_set_drvdata(pdev, ts); | ||
291 | ts->stmpe = stmpe; | 273 | ts->stmpe = stmpe; |
292 | ts->idev = idev; | ||
293 | ts->dev = &pdev->dev; | ||
294 | 274 | ||
295 | if (pdata) | 275 | if (stmpe->pdata && stmpe->pdata->ts) { |
296 | ts_pdata = pdata->ts; | 276 | ts_pdata = stmpe->pdata->ts; |
297 | 277 | ||
298 | if (ts_pdata) { | ||
299 | ts->sample_time = ts_pdata->sample_time; | 278 | ts->sample_time = ts_pdata->sample_time; |
300 | ts->mod_12b = ts_pdata->mod_12b; | 279 | ts->mod_12b = ts_pdata->mod_12b; |
301 | ts->ref_sel = ts_pdata->ref_sel; | 280 | ts->ref_sel = ts_pdata->ref_sel; |
@@ -305,22 +284,71 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
305 | ts->settling = ts_pdata->settling; | 284 | ts->settling = ts_pdata->settling; |
306 | ts->fraction_z = ts_pdata->fraction_z; | 285 | ts->fraction_z = ts_pdata->fraction_z; |
307 | ts->i_drive = ts_pdata->i_drive; | 286 | ts->i_drive = ts_pdata->i_drive; |
287 | } else if (np) { | ||
288 | u32 val; | ||
289 | |||
290 | if (!of_property_read_u32(np, "st,sample-time", &val)) | ||
291 | ts->sample_time = val; | ||
292 | if (!of_property_read_u32(np, "st,mod-12b", &val)) | ||
293 | ts->mod_12b = val; | ||
294 | if (!of_property_read_u32(np, "st,ref-sel", &val)) | ||
295 | ts->ref_sel = val; | ||
296 | if (!of_property_read_u32(np, "st,adc-freq", &val)) | ||
297 | ts->adc_freq = val; | ||
298 | if (!of_property_read_u32(np, "st,ave-ctrl", &val)) | ||
299 | ts->ave_ctrl = val; | ||
300 | if (!of_property_read_u32(np, "st,touch-det-delay", &val)) | ||
301 | ts->touch_det_delay = val; | ||
302 | if (!of_property_read_u32(np, "st,settling", &val)) | ||
303 | ts->settling = val; | ||
304 | if (!of_property_read_u32(np, "st,fraction-z", &val)) | ||
305 | ts->fraction_z = val; | ||
306 | if (!of_property_read_u32(np, "st,i-drive", &val)) | ||
307 | ts->i_drive = val; | ||
308 | } | 308 | } |
309 | } | ||
310 | |||
311 | static int stmpe_input_probe(struct platform_device *pdev) | ||
312 | { | ||
313 | struct stmpe_touch *ts; | ||
314 | struct input_dev *idev; | ||
315 | int error; | ||
316 | int ts_irq; | ||
317 | |||
318 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | ||
319 | if (ts_irq < 0) | ||
320 | return ts_irq; | ||
321 | |||
322 | ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); | ||
323 | if (!ts) | ||
324 | return -ENOMEM; | ||
325 | |||
326 | idev = devm_input_allocate_device(&pdev->dev); | ||
327 | if (!idev) | ||
328 | return -ENOMEM; | ||
329 | |||
330 | platform_set_drvdata(pdev, ts); | ||
331 | ts->idev = idev; | ||
332 | ts->dev = &pdev->dev; | ||
333 | |||
334 | stmpe_ts_get_platform_info(pdev, ts); | ||
309 | 335 | ||
310 | INIT_DELAYED_WORK(&ts->work, stmpe_work); | 336 | INIT_DELAYED_WORK(&ts->work, stmpe_work); |
311 | 337 | ||
312 | ret = request_threaded_irq(ts_irq, NULL, stmpe_ts_handler, | 338 | error = devm_request_threaded_irq(&pdev->dev, ts_irq, |
313 | IRQF_ONESHOT, STMPE_TS_NAME, ts); | 339 | NULL, stmpe_ts_handler, |
314 | if (ret) { | 340 | IRQF_ONESHOT, STMPE_TS_NAME, ts); |
341 | if (error) { | ||
315 | dev_err(&pdev->dev, "Failed to request IRQ %d\n", ts_irq); | 342 | dev_err(&pdev->dev, "Failed to request IRQ %d\n", ts_irq); |
316 | goto err_free_input; | 343 | return error; |
317 | } | 344 | } |
318 | 345 | ||
319 | ret = stmpe_init_hw(ts); | 346 | error = stmpe_init_hw(ts); |
320 | if (ret) | 347 | if (error) |
321 | goto err_free_irq; | 348 | return error; |
322 | 349 | ||
323 | idev->name = STMPE_TS_NAME; | 350 | idev->name = STMPE_TS_NAME; |
351 | idev->phys = STMPE_TS_NAME"/input0"; | ||
324 | idev->id.bustype = BUS_I2C; | 352 | idev->id.bustype = BUS_I2C; |
325 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 353 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
326 | idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 354 | idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
@@ -334,40 +362,21 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
334 | input_set_abs_params(idev, ABS_Y, 0, XY_MASK, 0, 0); | 362 | input_set_abs_params(idev, ABS_Y, 0, XY_MASK, 0, 0); |
335 | input_set_abs_params(idev, ABS_PRESSURE, 0x0, 0xff, 0, 0); | 363 | input_set_abs_params(idev, ABS_PRESSURE, 0x0, 0xff, 0, 0); |
336 | 364 | ||
337 | ret = input_register_device(idev); | 365 | error = input_register_device(idev); |
338 | if (ret) { | 366 | if (error) { |
339 | dev_err(&pdev->dev, "Could not register input device\n"); | 367 | dev_err(&pdev->dev, "Could not register input device\n"); |
340 | goto err_free_irq; | 368 | return error; |
341 | } | 369 | } |
342 | 370 | ||
343 | return ret; | 371 | return 0; |
344 | |||
345 | err_free_irq: | ||
346 | free_irq(ts_irq, ts); | ||
347 | err_free_input: | ||
348 | input_free_device(idev); | ||
349 | platform_set_drvdata(pdev, NULL); | ||
350 | err_free_ts: | ||
351 | kfree(ts); | ||
352 | err_out: | ||
353 | return ret; | ||
354 | } | 372 | } |
355 | 373 | ||
356 | static int __devexit stmpe_ts_remove(struct platform_device *pdev) | 374 | static int stmpe_ts_remove(struct platform_device *pdev) |
357 | { | 375 | { |
358 | struct stmpe_touch *ts = platform_get_drvdata(pdev); | 376 | struct stmpe_touch *ts = platform_get_drvdata(pdev); |
359 | unsigned int ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | ||
360 | 377 | ||
361 | stmpe_disable(ts->stmpe, STMPE_BLOCK_TOUCHSCREEN); | 378 | stmpe_disable(ts->stmpe, STMPE_BLOCK_TOUCHSCREEN); |
362 | 379 | ||
363 | free_irq(ts_irq, ts); | ||
364 | |||
365 | platform_set_drvdata(pdev, NULL); | ||
366 | |||
367 | input_unregister_device(ts->idev); | ||
368 | |||
369 | kfree(ts); | ||
370 | |||
371 | return 0; | 380 | return 0; |
372 | } | 381 | } |
373 | 382 | ||
@@ -377,7 +386,7 @@ static struct platform_driver stmpe_ts_driver = { | |||
377 | .owner = THIS_MODULE, | 386 | .owner = THIS_MODULE, |
378 | }, | 387 | }, |
379 | .probe = stmpe_input_probe, | 388 | .probe = stmpe_input_probe, |
380 | .remove = __devexit_p(stmpe_ts_remove), | 389 | .remove = stmpe_ts_remove, |
381 | }; | 390 | }; |
382 | module_platform_driver(stmpe_ts_driver); | 391 | module_platform_driver(stmpe_ts_driver); |
383 | 392 | ||