Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tps6507x-ts.c
Go to the documentation of this file.
1 /*
2  * Touchscreen driver for the tps6507x chip.
3  *
4  * Copyright (c) 2009 RidgeRun ([email protected])
5  *
6  * Credits:
7  *
8  * Using code from tsc2007, MtekVision Co., Ltd.
9  *
10  * For licencing details see kernel-base/COPYING
11  *
12  * TPS65070, TPS65073, TPS650731, and TPS650732 support
13  * 10 bit touch screen interface.
14  */
15 
16 #include <linux/module.h>
17 #include <linux/workqueue.h>
18 #include <linux/slab.h>
19 #include <linux/input.h>
20 #include <linux/platform_device.h>
21 #include <linux/mfd/tps6507x.h>
23 #include <linux/delay.h>
24 
25 #define TSC_DEFAULT_POLL_PERIOD 30 /* ms */
26 #define TPS_DEFAULT_MIN_PRESSURE 0x30
27 #define MAX_10BIT ((1 << 10) - 1)
28 
29 #define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \
30  TPS6507X_ADCONFIG_START_CONVERSION | \
31  TPS6507X_ADCONFIG_INPUT_REAL_TSC)
32 #define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC)
33 
34 struct ts_event {
35  u16 x;
36  u16 y;
38 };
39 
40 struct tps6507x_ts {
42  struct device *dev;
43  char phys[32];
45  unsigned polling; /* polling is active */
46  struct ts_event tc;
47  struct tps6507x_dev *mfd;
49  unsigned pendown;
50  int irq;
52  unsigned long poll_period; /* ms */
54  int vref; /* non-zero to leave vref on */
55 };
56 
57 static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data)
58 {
59  int err;
60 
61  err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data);
62 
63  if (err)
64  return err;
65 
66  return 0;
67 }
68 
69 static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data)
70 {
71  return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data);
72 }
73 
74 static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc,
75  u8 tsc_mode, u16 *value)
76 {
77  s32 ret;
78  u8 adc_status;
79  u8 result;
80 
81  /* Route input signal to A/D converter */
82 
83  ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode);
84  if (ret) {
85  dev_err(tsc->dev, "TSC mode read failed\n");
86  goto err;
87  }
88 
89  /* Start A/D conversion */
90 
91  ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
93  if (ret) {
94  dev_err(tsc->dev, "ADC config write failed\n");
95  return ret;
96  }
97 
98  do {
99  ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG,
100  &adc_status);
101  if (ret) {
102  dev_err(tsc->dev, "ADC config read failed\n");
103  goto err;
104  }
105  } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION);
106 
107  ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result);
108  if (ret) {
109  dev_err(tsc->dev, "ADC result 2 read failed\n");
110  goto err;
111  }
112 
113  *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8;
114 
115  ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result);
116  if (ret) {
117  dev_err(tsc->dev, "ADC result 1 read failed\n");
118  goto err;
119  }
120 
121  *value |= result;
122 
123  dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value);
124 
125 err:
126  return ret;
127 }
128 
129 /* Need to call tps6507x_adc_standby() after using A/D converter for the
130  * touch screen interrupt to work properly.
131  */
132 
133 static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
134 {
135  s32 ret;
136  s32 loops = 0;
137  u8 val;
138 
139  ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
141  if (ret)
142  return ret;
143 
144  ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE,
146  if (ret)
147  return ret;
148 
149  ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
150  if (ret)
151  return ret;
152 
153  while (val & TPS6507X_REG_TSC_INT) {
154  mdelay(10);
155  ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
156  if (ret)
157  return ret;
158  loops++;
159  }
160 
161  return ret;
162 }
163 
164 static void tps6507x_ts_handler(struct work_struct *work)
165 {
166  struct tps6507x_ts *tsc = container_of(work,
167  struct tps6507x_ts, work.work);
168  struct input_dev *input_dev = tsc->input_dev;
169  int pendown;
170  int schd;
171  int poll = 0;
172  s32 ret;
173 
174  ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE,
175  &tsc->tc.pressure);
176  if (ret)
177  goto done;
178 
179  pendown = tsc->tc.pressure > tsc->min_pressure;
180 
181  if (unlikely(!pendown && tsc->pendown)) {
182  dev_dbg(tsc->dev, "UP\n");
183  input_report_key(input_dev, BTN_TOUCH, 0);
184  input_report_abs(input_dev, ABS_PRESSURE, 0);
185  input_sync(input_dev);
186  tsc->pendown = 0;
187  }
188 
189  if (pendown) {
190 
191  if (!tsc->pendown) {
192  dev_dbg(tsc->dev, "DOWN\n");
193  input_report_key(input_dev, BTN_TOUCH, 1);
194  } else
195  dev_dbg(tsc->dev, "still down\n");
196 
197  ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION,
198  &tsc->tc.x);
199  if (ret)
200  goto done;
201 
202  ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION,
203  &tsc->tc.y);
204  if (ret)
205  goto done;
206 
207  input_report_abs(input_dev, ABS_X, tsc->tc.x);
208  input_report_abs(input_dev, ABS_Y, tsc->tc.y);
209  input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure);
210  input_sync(input_dev);
211  tsc->pendown = 1;
212  poll = 1;
213  }
214 
215 done:
216  /* always poll if not using interrupts */
217  poll = 1;
218 
219  if (poll) {
220  schd = schedule_delayed_work(&tsc->work,
222  if (schd)
223  tsc->polling = 1;
224  else {
225  tsc->polling = 0;
226  dev_err(tsc->dev, "re-schedule failed");
227  }
228  } else
229  tsc->polling = 0;
230 
231  ret = tps6507x_adc_standby(tsc);
232 }
233 
234 static int tps6507x_ts_probe(struct platform_device *pdev)
235 {
236  int error;
237  struct tps6507x_ts *tsc;
238  struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
239  struct touchscreen_init_data *init_data;
240  struct input_dev *input_dev;
241  struct tps6507x_board *tps_board;
242  int schd;
243 
249  tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data;
250 
251  if (!tps_board) {
252  dev_err(tps6507x_dev->dev,
253  "Could not find tps6507x platform data\n");
254  return -EIO;
255  }
256 
262  init_data = tps_board->tps6507x_ts_init_data;
263 
264  tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL);
265  if (!tsc) {
266  dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
267  error = -ENOMEM;
268  goto err0;
269  }
270 
271  tps6507x_dev->ts = tsc;
272  tsc->mfd = tps6507x_dev;
273  tsc->dev = tps6507x_dev->dev;
274  input_dev = input_allocate_device();
275  if (!input_dev) {
276  dev_err(tsc->dev, "Failed to allocate input device.\n");
277  error = -ENOMEM;
278  goto err1;
279  }
280 
281  input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
282  input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
283 
284  input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0);
285  input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0);
286  input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0);
287 
288  input_dev->name = "TPS6507x Touchscreen";
289  input_dev->id.bustype = BUS_I2C;
290  input_dev->dev.parent = tsc->dev;
291 
292  snprintf(tsc->phys, sizeof(tsc->phys),
293  "%s/input0", dev_name(tsc->dev));
294  input_dev->phys = tsc->phys;
295 
296  dev_dbg(tsc->dev, "device: %s\n", input_dev->phys);
297 
298  input_set_drvdata(input_dev, tsc);
299 
300  tsc->input_dev = input_dev;
301 
302  INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);
303 
304  if (init_data) {
305  tsc->poll_period = init_data->poll_period;
306  tsc->vref = init_data->vref;
307  tsc->min_pressure = init_data->min_pressure;
308  input_dev->id.vendor = init_data->vendor;
309  input_dev->id.product = init_data->product;
310  input_dev->id.version = init_data->version;
311  } else {
314  }
315 
316  error = tps6507x_adc_standby(tsc);
317  if (error)
318  goto err2;
319 
320  error = input_register_device(input_dev);
321  if (error)
322  goto err2;
323 
324  schd = schedule_delayed_work(&tsc->work,
326 
327  if (schd)
328  tsc->polling = 1;
329  else {
330  tsc->polling = 0;
331  dev_err(tsc->dev, "schedule failed");
332  goto err2;
333  }
334  platform_set_drvdata(pdev, tps6507x_dev);
335 
336  return 0;
337 
338 err2:
340  input_free_device(input_dev);
341 err1:
342  kfree(tsc);
343  tps6507x_dev->ts = NULL;
344 err0:
345  return error;
346 }
347 
348 static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
349 {
350  struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
351  struct tps6507x_ts *tsc = tps6507x_dev->ts;
352  struct input_dev *input_dev = tsc->input_dev;
353 
355 
356  input_unregister_device(input_dev);
357 
358  tps6507x_dev->ts = NULL;
359  kfree(tsc);
360 
361  return 0;
362 }
363 
364 static struct platform_driver tps6507x_ts_driver = {
365  .driver = {
366  .name = "tps6507x-ts",
367  .owner = THIS_MODULE,
368  },
369  .probe = tps6507x_ts_probe,
370  .remove = __devexit_p(tps6507x_ts_remove),
371 };
372 module_platform_driver(tps6507x_ts_driver);
373 
374 MODULE_AUTHOR("Todd Fischer <[email protected]>");
375 MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
376 MODULE_LICENSE("GPL v2");
377 MODULE_ALIAS("platform:tps6507x-ts");