aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2013-04-15 14:11:00 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-07-01 14:38:41 -0400
commit5705b8aca5a80141de5637ff0e23b31b26f2c5bf (patch)
tree1f71183b732935b2dbd5962bb784eee39a0b72d0
parent69e9aa99989c68763373d54076d82405d1000f46 (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.c126
-rw-r--r--include/linux/mfd/tps6507x.h1
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
40struct tps6507x_ts { 41struct 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
159static void tps6507x_ts_handler(struct work_struct *work) 158static 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
208done: 205done:
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
218static int tps6507x_ts_probe(struct platform_device *pdev) 209static 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
318err2: 294err_free_polled_dev:
319 cancel_delayed_work_sync(&tsc->work); 295 input_free_polled_device(poll_dev);
320 input_free_device(input_dev); 296err_free_mem:
321err1:
322 kfree(tsc); 297 kfree(tsc);
323 tps6507x_dev->ts = NULL;
324err0:
325 return error; 298 return error;
326} 299}
327 300
328static int tps6507x_ts_remove(struct platform_device *pdev) 301static 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 */