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 @@ -/* STMicroelectronics STMPE811 Touchscreen Driver +/* + * STMicroelectronics STMPE811 Touchscreen Driver * * (C) 2010 Luotao Fu <l.fu@pengutronix.de> * All rights reserved. @@ -16,6 +17,7 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/input.h> #include <linux/slab.h> @@ -166,7 +168,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data) return IRQ_HANDLED; } -static int __devinit stmpe_init_hw(struct stmpe_touch *ts) +static int stmpe_init_hw(struct stmpe_touch *ts) { int ret; u8 adc_ctrl1, adc_ctrl1_mask, tsc_cfg, tsc_cfg_mask; @@ -261,41 +263,18 @@ static void stmpe_ts_close(struct input_dev *dev) STMPE_TSC_CTRL_TSC_EN, 0); } -static int __devinit stmpe_input_probe(struct platform_device *pdev) +static void stmpe_ts_get_platform_info(struct platform_device *pdev, + struct stmpe_touch *ts) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); - struct stmpe_platform_data *pdata = stmpe->pdata; - struct stmpe_touch *ts; - struct input_dev *idev; + struct device_node *np = pdev->dev.of_node; struct stmpe_ts_platform_data *ts_pdata = NULL; - int ret; - int ts_irq; - - ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); - if (ts_irq < 0) - return ts_irq; - - ts = kzalloc(sizeof(*ts), GFP_KERNEL); - if (!ts) { - ret = -ENOMEM; - goto err_out; - } - idev = input_allocate_device(); - if (!idev) { - ret = -ENOMEM; - goto err_free_ts; - } - - platform_set_drvdata(pdev, ts); ts->stmpe = stmpe; - ts->idev = idev; - ts->dev = &pdev->dev; - if (pdata) - ts_pdata = pdata->ts; + if (stmpe->pdata && stmpe->pdata->ts) { + ts_pdata = stmpe->pdata->ts; - if (ts_pdata) { ts->sample_time = ts_pdata->sample_time; ts->mod_12b = ts_pdata->mod_12b; ts->ref_sel = ts_pdata->ref_sel; @@ -305,22 +284,71 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) ts->settling = ts_pdata->settling; ts->fraction_z = ts_pdata->fraction_z; ts->i_drive = ts_pdata->i_drive; + } else if (np) { + u32 val; + + if (!of_property_read_u32(np, "st,sample-time", &val)) + ts->sample_time = val; + if (!of_property_read_u32(np, "st,mod-12b", &val)) + ts->mod_12b = val; + if (!of_property_read_u32(np, "st,ref-sel", &val)) + ts->ref_sel = val; + if (!of_property_read_u32(np, "st,adc-freq", &val)) + ts->adc_freq = val; + if (!of_property_read_u32(np, "st,ave-ctrl", &val)) + ts->ave_ctrl = val; + if (!of_property_read_u32(np, "st,touch-det-delay", &val)) + ts->touch_det_delay = val; + if (!of_property_read_u32(np, "st,settling", &val)) + ts->settling = val; + if (!of_property_read_u32(np, "st,fraction-z", &val)) + ts->fraction_z = val; + if (!of_property_read_u32(np, "st,i-drive", &val)) + ts->i_drive = val; } +} + +static int stmpe_input_probe(struct platform_device *pdev) +{ + struct stmpe_touch *ts; + struct input_dev *idev; + int error; + int ts_irq; + + ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); + if (ts_irq < 0) + return ts_irq; + + ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + idev = devm_input_allocate_device(&pdev->dev); + if (!idev) + return -ENOMEM; + + platform_set_drvdata(pdev, ts); + ts->idev = idev; + ts->dev = &pdev->dev; + + stmpe_ts_get_platform_info(pdev, ts); INIT_DELAYED_WORK(&ts->work, stmpe_work); - ret = request_threaded_irq(ts_irq, NULL, stmpe_ts_handler, - IRQF_ONESHOT, STMPE_TS_NAME, ts); - if (ret) { + error = devm_request_threaded_irq(&pdev->dev, ts_irq, + NULL, stmpe_ts_handler, + IRQF_ONESHOT, STMPE_TS_NAME, ts); + if (error) { dev_err(&pdev->dev, "Failed to request IRQ %d\n", ts_irq); - goto err_free_input; + return error; } - ret = stmpe_init_hw(ts); - if (ret) - goto err_free_irq; + error = stmpe_init_hw(ts); + if (error) + return error; idev->name = STMPE_TS_NAME; + idev->phys = STMPE_TS_NAME"/input0"; idev->id.bustype = BUS_I2C; idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); @@ -334,40 +362,21 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) input_set_abs_params(idev, ABS_Y, 0, XY_MASK, 0, 0); input_set_abs_params(idev, ABS_PRESSURE, 0x0, 0xff, 0, 0); - ret = input_register_device(idev); - if (ret) { + error = input_register_device(idev); + if (error) { dev_err(&pdev->dev, "Could not register input device\n"); - goto err_free_irq; + return error; } - return ret; - -err_free_irq: - free_irq(ts_irq, ts); -err_free_input: - input_free_device(idev); - platform_set_drvdata(pdev, NULL); -err_free_ts: - kfree(ts); -err_out: - return ret; + return 0; } -static int __devexit stmpe_ts_remove(struct platform_device *pdev) +static int stmpe_ts_remove(struct platform_device *pdev) { struct stmpe_touch *ts = platform_get_drvdata(pdev); - unsigned int ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); stmpe_disable(ts->stmpe, STMPE_BLOCK_TOUCHSCREEN); - free_irq(ts_irq, ts); - - platform_set_drvdata(pdev, NULL); - - input_unregister_device(ts->idev); - - kfree(ts); - return 0; } @@ -377,7 +386,7 @@ static struct platform_driver stmpe_ts_driver = { .owner = THIS_MODULE, }, .probe = stmpe_input_probe, - .remove = __devexit_p(stmpe_ts_remove), + .remove = stmpe_ts_remove, }; module_platform_driver(stmpe_ts_driver); |