diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-04-15 14:11:00 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-07-01 14:38:41 -0400 |
commit | 5705b8aca5a80141de5637ff0e23b31b26f2c5bf (patch) | |
tree | 1f71183b732935b2dbd5962bb784eee39a0b72d0 | |
parent | 69e9aa99989c68763373d54076d82405d1000f46 (diff) |
Input: tps6507x-ts - convert to polled input device infrastructure
There is no need to roll our own polling scheme when we already have
one implemented by the core.
Tested-by: Manish Badarkhe <badarkhe.manish@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/touchscreen/tps6507x-ts.c | 126 | ||||
-rw-r--r-- | include/linux/mfd/tps6507x.h | 1 |
2 files changed, 48 insertions, 79 deletions
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index d3c2967f86fb..94cde2cb1491 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/workqueue.h> | 17 | #include <linux/workqueue.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/input-polldev.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/mfd/tps6507x.h> | 22 | #include <linux/mfd/tps6507x.h> |
22 | #include <linux/input/tps6507x-ts.h> | 23 | #include <linux/input/tps6507x-ts.h> |
@@ -38,14 +39,12 @@ struct ts_event { | |||
38 | }; | 39 | }; |
39 | 40 | ||
40 | struct tps6507x_ts { | 41 | struct tps6507x_ts { |
41 | struct input_dev *input_dev; | ||
42 | struct device *dev; | 42 | struct device *dev; |
43 | struct input_polled_dev *poll_dev; | ||
44 | struct tps6507x_dev *mfd; | ||
43 | char phys[32]; | 45 | char phys[32]; |
44 | struct delayed_work work; | ||
45 | struct ts_event tc; | 46 | struct ts_event tc; |
46 | struct tps6507x_dev *mfd; | ||
47 | u16 min_pressure; | 47 | u16 min_pressure; |
48 | unsigned long poll_period; /* ms */ | ||
49 | bool pendown; | 48 | bool pendown; |
50 | }; | 49 | }; |
51 | 50 | ||
@@ -156,13 +155,11 @@ static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) | |||
156 | return ret; | 155 | return ret; |
157 | } | 156 | } |
158 | 157 | ||
159 | static void tps6507x_ts_handler(struct work_struct *work) | 158 | static void tps6507x_ts_poll(struct input_polled_dev *poll_dev) |
160 | { | 159 | { |
161 | struct tps6507x_ts *tsc = container_of(work, | 160 | struct tps6507x_ts *tsc = poll_dev->private; |
162 | struct tps6507x_ts, work.work); | 161 | struct input_dev *input_dev = poll_dev->input; |
163 | struct input_dev *input_dev = tsc->input_dev; | ||
164 | bool pendown; | 162 | bool pendown; |
165 | int schd; | ||
166 | s32 ret; | 163 | s32 ret; |
167 | 164 | ||
168 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, | 165 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, |
@@ -206,62 +203,65 @@ static void tps6507x_ts_handler(struct work_struct *work) | |||
206 | } | 203 | } |
207 | 204 | ||
208 | done: | 205 | done: |
209 | /* always poll if not using interrupts */ | 206 | tps6507x_adc_standby(tsc); |
210 | schd = schedule_delayed_work(&tsc->work, | ||
211 | msecs_to_jiffies(tsc->poll_period)); | ||
212 | if (!schd) | ||
213 | dev_err(tsc->dev, "re-schedule failed"); | ||
214 | |||
215 | ret = tps6507x_adc_standby(tsc); | ||
216 | } | 207 | } |
217 | 208 | ||
218 | static int tps6507x_ts_probe(struct platform_device *pdev) | 209 | static int tps6507x_ts_probe(struct platform_device *pdev) |
219 | { | 210 | { |
220 | int error; | ||
221 | struct tps6507x_ts *tsc; | ||
222 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 211 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
223 | struct touchscreen_init_data *init_data; | 212 | const struct tps6507x_board *tps_board; |
213 | const struct touchscreen_init_data *init_data; | ||
214 | struct tps6507x_ts *tsc; | ||
215 | struct input_polled_dev *poll_dev; | ||
224 | struct input_dev *input_dev; | 216 | struct input_dev *input_dev; |
225 | struct tps6507x_board *tps_board; | 217 | int error; |
226 | int schd; | ||
227 | 218 | ||
228 | /** | 219 | /* |
229 | * tps_board points to pmic related constants | 220 | * tps_board points to pmic related constants |
230 | * coming from the board-evm file. | 221 | * coming from the board-evm file. |
231 | */ | 222 | */ |
232 | 223 | tps_board = dev_get_platdata(tps6507x_dev->dev); | |
233 | tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; | ||
234 | |||
235 | if (!tps_board) { | 224 | if (!tps_board) { |
236 | dev_err(tps6507x_dev->dev, | 225 | dev_err(tps6507x_dev->dev, |
237 | "Could not find tps6507x platform data\n"); | 226 | "Could not find tps6507x platform data\n"); |
238 | return -EIO; | 227 | return -ENODEV; |
239 | } | 228 | } |
240 | 229 | ||
241 | /** | 230 | /* |
242 | * init_data points to array of regulator_init structures | 231 | * init_data points to array of regulator_init structures |
243 | * coming from the board-evm file. | 232 | * coming from the board-evm file. |
244 | */ | 233 | */ |
245 | |||
246 | init_data = tps_board->tps6507x_ts_init_data; | 234 | init_data = tps_board->tps6507x_ts_init_data; |
247 | 235 | ||
248 | tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); | 236 | tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); |
249 | if (!tsc) { | 237 | if (!tsc) { |
250 | dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); | 238 | dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); |
251 | error = -ENOMEM; | 239 | return -ENOMEM; |
252 | goto err0; | ||
253 | } | 240 | } |
254 | 241 | ||
255 | tps6507x_dev->ts = tsc; | ||
256 | tsc->mfd = tps6507x_dev; | 242 | tsc->mfd = tps6507x_dev; |
257 | tsc->dev = tps6507x_dev->dev; | 243 | tsc->dev = tps6507x_dev->dev; |
258 | input_dev = input_allocate_device(); | 244 | tsc->min_pressure = init_data ? |
259 | if (!input_dev) { | 245 | init_data->min_pressure : TPS_DEFAULT_MIN_PRESSURE; |
260 | dev_err(tsc->dev, "Failed to allocate input device.\n"); | 246 | |
247 | snprintf(tsc->phys, sizeof(tsc->phys), | ||
248 | "%s/input0", dev_name(tsc->dev)); | ||
249 | |||
250 | poll_dev = input_allocate_polled_device(); | ||
251 | if (!poll_dev) { | ||
252 | dev_err(tsc->dev, "Failed to allocate polled input device.\n"); | ||
261 | error = -ENOMEM; | 253 | error = -ENOMEM; |
262 | goto err1; | 254 | goto err_free_mem; |
263 | } | 255 | } |
264 | 256 | ||
257 | tsc->poll_dev = poll_dev; | ||
258 | |||
259 | poll_dev->private = tsc; | ||
260 | poll_dev->poll = tps6507x_ts_poll; | ||
261 | poll_dev->poll_interval = init_data ? | ||
262 | init_data->poll_period : TSC_DEFAULT_POLL_PERIOD; | ||
263 | |||
264 | input_dev = poll_dev->input; | ||
265 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 265 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
266 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 266 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
267 | 267 | ||
@@ -270,72 +270,42 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
270 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); | 270 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); |
271 | 271 | ||
272 | input_dev->name = "TPS6507x Touchscreen"; | 272 | input_dev->name = "TPS6507x Touchscreen"; |
273 | input_dev->id.bustype = BUS_I2C; | ||
274 | input_dev->dev.parent = tsc->dev; | ||
275 | |||
276 | snprintf(tsc->phys, sizeof(tsc->phys), | ||
277 | "%s/input0", dev_name(tsc->dev)); | ||
278 | input_dev->phys = tsc->phys; | 273 | input_dev->phys = tsc->phys; |
279 | 274 | input_dev->dev.parent = tsc->dev; | |
280 | dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); | 275 | input_dev->id.bustype = BUS_I2C; |
281 | |||
282 | input_set_drvdata(input_dev, tsc); | ||
283 | |||
284 | tsc->input_dev = input_dev; | ||
285 | |||
286 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); | ||
287 | |||
288 | if (init_data) { | 276 | if (init_data) { |
289 | tsc->poll_period = init_data->poll_period; | ||
290 | tsc->min_pressure = init_data->min_pressure; | ||
291 | input_dev->id.vendor = init_data->vendor; | 277 | input_dev->id.vendor = init_data->vendor; |
292 | input_dev->id.product = init_data->product; | 278 | input_dev->id.product = init_data->product; |
293 | input_dev->id.version = init_data->version; | 279 | input_dev->id.version = init_data->version; |
294 | } else { | ||
295 | tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; | ||
296 | tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; | ||
297 | } | 280 | } |
298 | 281 | ||
299 | error = tps6507x_adc_standby(tsc); | 282 | error = tps6507x_adc_standby(tsc); |
300 | if (error) | 283 | if (error) |
301 | goto err2; | 284 | goto err_free_polled_dev; |
302 | 285 | ||
303 | error = input_register_device(input_dev); | 286 | error = input_register_polled_device(poll_dev); |
304 | if (error) | 287 | if (error) |
305 | goto err2; | 288 | goto err_free_polled_dev; |
306 | |||
307 | schd = schedule_delayed_work(&tsc->work, | ||
308 | msecs_to_jiffies(tsc->poll_period)); | ||
309 | 289 | ||
310 | if (!schd) { | 290 | platform_set_drvdata(pdev, tsc); |
311 | dev_err(tsc->dev, "schedule failed"); | ||
312 | goto err2; | ||
313 | } | ||
314 | platform_set_drvdata(pdev, tps6507x_dev); | ||
315 | 291 | ||
316 | return 0; | 292 | return 0; |
317 | 293 | ||
318 | err2: | 294 | err_free_polled_dev: |
319 | cancel_delayed_work_sync(&tsc->work); | 295 | input_free_polled_device(poll_dev); |
320 | input_free_device(input_dev); | 296 | err_free_mem: |
321 | err1: | ||
322 | kfree(tsc); | 297 | kfree(tsc); |
323 | tps6507x_dev->ts = NULL; | ||
324 | err0: | ||
325 | return error; | 298 | return error; |
326 | } | 299 | } |
327 | 300 | ||
328 | static int tps6507x_ts_remove(struct platform_device *pdev) | 301 | static int tps6507x_ts_remove(struct platform_device *pdev) |
329 | { | 302 | { |
330 | struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); | 303 | struct tps6507x_ts *tsc = platform_get_drvdata(pdev); |
331 | struct tps6507x_ts *tsc = tps6507x_dev->ts; | 304 | struct input_polled_dev *poll_dev = tsc->poll_dev; |
332 | struct input_dev *input_dev = tsc->input_dev; | ||
333 | |||
334 | cancel_delayed_work_sync(&tsc->work); | ||
335 | 305 | ||
336 | input_unregister_device(input_dev); | 306 | input_unregister_polled_device(poll_dev); |
307 | input_free_polled_device(poll_dev); | ||
337 | 308 | ||
338 | tps6507x_dev->ts = NULL; | ||
339 | kfree(tsc); | 309 | kfree(tsc); |
340 | 310 | ||
341 | return 0; | 311 | return 0; |
diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index c923e4864f55..c2ae56933539 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h | |||
@@ -163,7 +163,6 @@ struct tps6507x_dev { | |||
163 | 163 | ||
164 | /* Client devices */ | 164 | /* Client devices */ |
165 | struct tps6507x_pmic *pmic; | 165 | struct tps6507x_pmic *pmic; |
166 | struct tps6507x_ts *ts; | ||
167 | }; | 166 | }; |
168 | 167 | ||
169 | #endif /* __LINUX_MFD_TPS6507X_H */ | 168 | #endif /* __LINUX_MFD_TPS6507X_H */ |