blob: 0fe27baf5e723038110cafaa56e69646bcc27526 [file] [log] [blame]
Bryan Wu31a62962010-03-21 23:23:24 -07001/*
Barry Song6c04d7b2010-03-21 23:23:29 -07002 * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
Bryan Wu31a62962010-03-21 23:23:24 -07003 *
4 * Copyright 2009 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/device.h>
10#include <linux/init.h>
11#include <linux/input.h>
12#include <linux/interrupt.h>
13#include <linux/slab.h>
14#include <linux/input/ad714x.h>
15#include "ad714x.h"
16
17#define AD714X_PWR_CTRL 0x0
18#define AD714X_STG_CAL_EN_REG 0x1
19#define AD714X_AMB_COMP_CTRL0_REG 0x2
20#define AD714X_PARTID_REG 0x17
Bryan Wu31a62962010-03-21 23:23:24 -070021#define AD7142_PARTID 0xE620
Barry Song6c04d7b2010-03-21 23:23:29 -070022#define AD7143_PARTID 0xE630
23#define AD7147_PARTID 0x1470
24#define AD7148_PARTID 0x1480
Bryan Wu31a62962010-03-21 23:23:24 -070025#define AD714X_STAGECFG_REG 0x80
26#define AD714X_SYSCFG_REG 0x0
27
28#define STG_LOW_INT_EN_REG 0x5
29#define STG_HIGH_INT_EN_REG 0x6
30#define STG_COM_INT_EN_REG 0x7
31#define STG_LOW_INT_STA_REG 0x8
32#define STG_HIGH_INT_STA_REG 0x9
33#define STG_COM_INT_STA_REG 0xA
34
35#define CDC_RESULT_S0 0xB
36#define CDC_RESULT_S1 0xC
37#define CDC_RESULT_S2 0xD
38#define CDC_RESULT_S3 0xE
39#define CDC_RESULT_S4 0xF
40#define CDC_RESULT_S5 0x10
41#define CDC_RESULT_S6 0x11
42#define CDC_RESULT_S7 0x12
43#define CDC_RESULT_S8 0x13
44#define CDC_RESULT_S9 0x14
45#define CDC_RESULT_S10 0x15
46#define CDC_RESULT_S11 0x16
47
48#define STAGE0_AMBIENT 0xF1
49#define STAGE1_AMBIENT 0x115
50#define STAGE2_AMBIENT 0x139
51#define STAGE3_AMBIENT 0x15D
52#define STAGE4_AMBIENT 0x181
53#define STAGE5_AMBIENT 0x1A5
54#define STAGE6_AMBIENT 0x1C9
55#define STAGE7_AMBIENT 0x1ED
56#define STAGE8_AMBIENT 0x211
57#define STAGE9_AMBIENT 0x234
58#define STAGE10_AMBIENT 0x259
59#define STAGE11_AMBIENT 0x27D
60
61#define PER_STAGE_REG_NUM 36
62#define STAGE_NUM 12
63#define STAGE_CFGREG_NUM 8
64#define SYS_CFGREG_NUM 8
65
66/*
67 * driver information which will be used to maintain the software flow
68 */
69enum ad714x_device_state { IDLE, JITTER, ACTIVE, SPACE };
70
71struct ad714x_slider_drv {
72 int highest_stage;
73 int abs_pos;
74 int flt_pos;
75 enum ad714x_device_state state;
76 struct input_dev *input;
77};
78
79struct ad714x_wheel_drv {
80 int abs_pos;
81 int flt_pos;
82 int pre_mean_value;
83 int pre_highest_stage;
84 int pre_mean_value_no_offset;
85 int mean_value;
86 int mean_value_no_offset;
87 int pos_offset;
88 int pos_ratio;
89 int highest_stage;
90 enum ad714x_device_state state;
91 struct input_dev *input;
92};
93
94struct ad714x_touchpad_drv {
95 int x_highest_stage;
96 int x_flt_pos;
97 int x_abs_pos;
98 int y_highest_stage;
99 int y_flt_pos;
100 int y_abs_pos;
101 int left_ep;
102 int left_ep_val;
103 int right_ep;
104 int right_ep_val;
105 int top_ep;
106 int top_ep_val;
107 int bottom_ep;
108 int bottom_ep_val;
109 enum ad714x_device_state state;
110 struct input_dev *input;
111};
112
113struct ad714x_button_drv {
114 enum ad714x_device_state state;
115 /*
116 * Unlike slider/wheel/touchpad, all buttons point to
117 * same input_dev instance
118 */
119 struct input_dev *input;
120};
121
122struct ad714x_driver_data {
123 struct ad714x_slider_drv *slider;
124 struct ad714x_wheel_drv *wheel;
125 struct ad714x_touchpad_drv *touchpad;
126 struct ad714x_button_drv *button;
127};
128
129/*
130 * information to integrate all things which will be private data
131 * of spi/i2c device
132 */
133struct ad714x_chip {
134 unsigned short h_state;
135 unsigned short l_state;
136 unsigned short c_state;
137 unsigned short adc_reg[STAGE_NUM];
138 unsigned short amb_reg[STAGE_NUM];
139 unsigned short sensor_val[STAGE_NUM];
140
141 struct ad714x_platform_data *hw;
142 struct ad714x_driver_data *sw;
143
144 int irq;
145 struct device *dev;
146 ad714x_read_t read;
147 ad714x_write_t write;
148
149 struct mutex mutex;
150
151 unsigned product;
152 unsigned version;
153};
154
155static void ad714x_use_com_int(struct ad714x_chip *ad714x,
156 int start_stage, int end_stage)
157{
158 unsigned short data;
159 unsigned short mask;
160
161 mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage);
162
163 ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
164 data |= 1 << start_stage;
165 ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
166
167 ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
168 data &= ~mask;
169 ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
170}
171
172static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
173 int start_stage, int end_stage)
174{
175 unsigned short data;
176 unsigned short mask;
177
178 mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage);
179
180 ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
181 data &= ~(1 << start_stage);
182 ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
183
184 ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
185 data |= mask;
186 ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
187}
188
189static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
190 int start_stage, int end_stage)
191{
192 int max_res = 0;
193 int max_idx = 0;
194 int i;
195
196 for (i = start_stage; i <= end_stage; i++) {
197 if (ad714x->sensor_val[i] > max_res) {
198 max_res = ad714x->sensor_val[i];
199 max_idx = i;
200 }
201 }
202
203 return max_idx;
204}
205
206static int ad714x_cal_abs_pos(struct ad714x_chip *ad714x,
207 int start_stage, int end_stage,
208 int highest_stage, int max_coord)
209{
210 int a_param, b_param;
211
212 if (highest_stage == start_stage) {
213 a_param = ad714x->sensor_val[start_stage + 1];
214 b_param = ad714x->sensor_val[start_stage] +
215 ad714x->sensor_val[start_stage + 1];
216 } else if (highest_stage == end_stage) {
217 a_param = ad714x->sensor_val[end_stage] *
218 (end_stage - start_stage) +
219 ad714x->sensor_val[end_stage - 1] *
220 (end_stage - start_stage - 1);
221 b_param = ad714x->sensor_val[end_stage] +
222 ad714x->sensor_val[end_stage - 1];
223 } else {
224 a_param = ad714x->sensor_val[highest_stage] *
225 (highest_stage - start_stage) +
226 ad714x->sensor_val[highest_stage - 1] *
227 (highest_stage - start_stage - 1) +
228 ad714x->sensor_val[highest_stage + 1] *
229 (highest_stage - start_stage + 1);
230 b_param = ad714x->sensor_val[highest_stage] +
231 ad714x->sensor_val[highest_stage - 1] +
232 ad714x->sensor_val[highest_stage + 1];
233 }
234
235 return (max_coord / (end_stage - start_stage)) * a_param / b_param;
236}
237
238/*
239 * One button can connect to multi positive and negative of CDCs
240 * Multi-buttons can connect to same positive/negative of one CDC
241 */
242static void ad714x_button_state_machine(struct ad714x_chip *ad714x, int idx)
243{
244 struct ad714x_button_plat *hw = &ad714x->hw->button[idx];
245 struct ad714x_button_drv *sw = &ad714x->sw->button[idx];
246
247 switch (sw->state) {
248 case IDLE:
249 if (((ad714x->h_state & hw->h_mask) == hw->h_mask) &&
250 ((ad714x->l_state & hw->l_mask) == hw->l_mask)) {
251 dev_dbg(ad714x->dev, "button %d touched\n", idx);
252 input_report_key(sw->input, hw->keycode, 1);
253 input_sync(sw->input);
254 sw->state = ACTIVE;
255 }
256 break;
257
258 case ACTIVE:
259 if (((ad714x->h_state & hw->h_mask) != hw->h_mask) ||
260 ((ad714x->l_state & hw->l_mask) != hw->l_mask)) {
261 dev_dbg(ad714x->dev, "button %d released\n", idx);
262 input_report_key(sw->input, hw->keycode, 0);
263 input_sync(sw->input);
264 sw->state = IDLE;
265 }
266 break;
267
268 default:
269 break;
270 }
271}
272
273/*
274 * The response of a sensor is defined by the absolute number of codes
275 * between the current CDC value and the ambient value.
276 */
277static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
278{
279 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
280 int i;
281
282 for (i = hw->start_stage; i <= hw->end_stage; i++) {
283 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
284 &ad714x->adc_reg[i]);
285 ad714x->read(ad714x->dev,
286 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
287 &ad714x->amb_reg[i]);
288
289 ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] -
290 ad714x->amb_reg[i]);
291 }
292}
293
294static void ad714x_slider_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
295{
296 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
297 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
298
299 sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
300 hw->end_stage);
301
302 dev_dbg(ad714x->dev, "slider %d highest_stage:%d\n", idx,
303 sw->highest_stage);
304}
305
306/*
307 * The formulae are very straight forward. It uses the sensor with the
308 * highest response and the 2 adjacent ones.
309 * When Sensor 0 has the highest response, only sensor 0 and sensor 1
310 * are used in the calculations. Similarly when the last sensor has the
311 * highest response, only the last sensor and the second last sensors
312 * are used in the calculations.
313 *
314 * For i= idx_of_peak_Sensor-1 to i= idx_of_peak_Sensor+1
315 * v += Sensor response(i)*i
316 * w += Sensor response(i)
317 * POS=(Number_of_Positions_Wanted/(Number_of_Sensors_Used-1)) *(v/w)
318 */
319static void ad714x_slider_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
320{
321 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
322 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
323
324 sw->abs_pos = ad714x_cal_abs_pos(ad714x, hw->start_stage, hw->end_stage,
325 sw->highest_stage, hw->max_coord);
326
327 dev_dbg(ad714x->dev, "slider %d absolute position:%d\n", idx,
328 sw->abs_pos);
329}
330
331/*
332 * To minimise the Impact of the noise on the algorithm, ADI developed a
333 * routine that filters the CDC results after they have been read by the
334 * host processor.
335 * The filter used is an Infinite Input Response(IIR) filter implemented
336 * in firmware and attenuates the noise on the CDC results after they've
337 * been read by the host processor.
338 * Filtered_CDC_result = (Filtered_CDC_result * (10 - Coefficient) +
339 * Latest_CDC_result * Coefficient)/10
340 */
341static void ad714x_slider_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
342{
343 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
344
345 sw->flt_pos = (sw->flt_pos * (10 - 4) +
346 sw->abs_pos * 4)/10;
347
348 dev_dbg(ad714x->dev, "slider %d filter position:%d\n", idx,
349 sw->flt_pos);
350}
351
352static void ad714x_slider_use_com_int(struct ad714x_chip *ad714x, int idx)
353{
354 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
355
356 ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
357}
358
359static void ad714x_slider_use_thr_int(struct ad714x_chip *ad714x, int idx)
360{
361 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
362
363 ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
364}
365
366static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx)
367{
368 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
369 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
370 unsigned short h_state, c_state;
371 unsigned short mask;
372
373 mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
374
375 h_state = ad714x->h_state & mask;
376 c_state = ad714x->c_state & mask;
377
378 switch (sw->state) {
379 case IDLE:
380 if (h_state) {
381 sw->state = JITTER;
382 /* In End of Conversion interrupt mode, the AD714X
383 * continuously generates hardware interrupts.
384 */
385 ad714x_slider_use_com_int(ad714x, idx);
386 dev_dbg(ad714x->dev, "slider %d touched\n", idx);
387 }
388 break;
389
390 case JITTER:
391 if (c_state == mask) {
392 ad714x_slider_cal_sensor_val(ad714x, idx);
393 ad714x_slider_cal_highest_stage(ad714x, idx);
394 ad714x_slider_cal_abs_pos(ad714x, idx);
395 sw->flt_pos = sw->abs_pos;
396 sw->state = ACTIVE;
397 }
398 break;
399
400 case ACTIVE:
401 if (c_state == mask) {
402 if (h_state) {
403 ad714x_slider_cal_sensor_val(ad714x, idx);
404 ad714x_slider_cal_highest_stage(ad714x, idx);
405 ad714x_slider_cal_abs_pos(ad714x, idx);
406 ad714x_slider_cal_flt_pos(ad714x, idx);
407
408 input_report_abs(sw->input, ABS_X, sw->flt_pos);
409 input_report_key(sw->input, BTN_TOUCH, 1);
410 } else {
411 /* When the user lifts off the sensor, configure
412 * the AD714X back to threshold interrupt mode.
413 */
414 ad714x_slider_use_thr_int(ad714x, idx);
415 sw->state = IDLE;
416 input_report_key(sw->input, BTN_TOUCH, 0);
417 dev_dbg(ad714x->dev, "slider %d released\n",
418 idx);
419 }
420 input_sync(sw->input);
421 }
422 break;
423
424 default:
425 break;
426 }
427}
428
429/*
430 * When the scroll wheel is activated, we compute the absolute position based
431 * on the sensor values. To calculate the position, we first determine the
432 * sensor that has the greatest response among the 8 sensors that constitutes
433 * the scrollwheel. Then we determined the 2 sensors on either sides of the
434 * sensor with the highest response and we apply weights to these sensors.
435 */
436static void ad714x_wheel_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
437{
438 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
439 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
440
441 sw->pre_highest_stage = sw->highest_stage;
442 sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
443 hw->end_stage);
444
445 dev_dbg(ad714x->dev, "wheel %d highest_stage:%d\n", idx,
446 sw->highest_stage);
447}
448
449static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
450{
451 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
452 int i;
453
454 for (i = hw->start_stage; i <= hw->end_stage; i++) {
455 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
456 &ad714x->adc_reg[i]);
457 ad714x->read(ad714x->dev,
458 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
459 &ad714x->amb_reg[i]);
460 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
461 ad714x->sensor_val[i] = ad714x->adc_reg[i] -
462 ad714x->amb_reg[i];
463 else
464 ad714x->sensor_val[i] = 0;
465 }
466}
467
468/*
469 * When the scroll wheel is activated, we compute the absolute position based
470 * on the sensor values. To calculate the position, we first determine the
471 * sensor that has the greatest response among the 8 sensors that constitutes
472 * the scrollwheel. Then we determined the 2 sensors on either sides of the
473 * sensor with the highest response and we apply weights to these sensors. The
474 * result of this computation gives us the mean value which defined by the
475 * following formula:
476 * For i= second_before_highest_stage to i= second_after_highest_stage
477 * v += Sensor response(i)*WEIGHT*(i+3)
478 * w += Sensor response(i)
479 * Mean_Value=v/w
480 * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio
481 */
482
483#define WEIGHT_FACTOR 30
484/* This constant prevents the "PositionOffset" from reaching a big value */
485#define OFFSET_POSITION_CLAMP 120
486static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
487{
488 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
489 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
490 int stage_num = hw->end_stage - hw->start_stage + 1;
491 int second_before, first_before, highest, first_after, second_after;
492 int a_param, b_param;
493
494 /* Calculate Mean value */
495
496 second_before = (sw->highest_stage + stage_num - 2) % stage_num;
497 first_before = (sw->highest_stage + stage_num - 1) % stage_num;
498 highest = sw->highest_stage;
499 first_after = (sw->highest_stage + stage_num + 1) % stage_num;
500 second_after = (sw->highest_stage + stage_num + 2) % stage_num;
501
502 if (((sw->highest_stage - hw->start_stage) > 1) &&
503 ((hw->end_stage - sw->highest_stage) > 1)) {
504 a_param = ad714x->sensor_val[second_before] *
505 (second_before - hw->start_stage + 3) +
506 ad714x->sensor_val[first_before] *
507 (second_before - hw->start_stage + 3) +
508 ad714x->sensor_val[highest] *
509 (second_before - hw->start_stage + 3) +
510 ad714x->sensor_val[first_after] *
511 (first_after - hw->start_stage + 3) +
512 ad714x->sensor_val[second_after] *
513 (second_after - hw->start_stage + 3);
514 } else {
515 a_param = ad714x->sensor_val[second_before] *
516 (second_before - hw->start_stage + 1) +
517 ad714x->sensor_val[first_before] *
518 (second_before - hw->start_stage + 2) +
519 ad714x->sensor_val[highest] *
520 (second_before - hw->start_stage + 3) +
521 ad714x->sensor_val[first_after] *
522 (first_after - hw->start_stage + 4) +
523 ad714x->sensor_val[second_after] *
524 (second_after - hw->start_stage + 5);
525 }
526 a_param *= WEIGHT_FACTOR;
527
528 b_param = ad714x->sensor_val[second_before] +
529 ad714x->sensor_val[first_before] +
530 ad714x->sensor_val[highest] +
531 ad714x->sensor_val[first_after] +
532 ad714x->sensor_val[second_after];
533
534 sw->pre_mean_value = sw->mean_value;
535 sw->mean_value = a_param / b_param;
536
537 /* Calculate the offset */
538
539 if ((sw->pre_highest_stage == hw->end_stage) &&
540 (sw->highest_stage == hw->start_stage))
541 sw->pos_offset = sw->mean_value;
542 else if ((sw->pre_highest_stage == hw->start_stage) &&
543 (sw->highest_stage == hw->end_stage))
544 sw->pos_offset = sw->pre_mean_value;
545
546 if (sw->pos_offset > OFFSET_POSITION_CLAMP)
547 sw->pos_offset = OFFSET_POSITION_CLAMP;
548
549 /* Calculate the mean value without the offset */
550
551 sw->pre_mean_value_no_offset = sw->mean_value_no_offset;
552 sw->mean_value_no_offset = sw->mean_value - sw->pos_offset;
553 if (sw->mean_value_no_offset < 0)
554 sw->mean_value_no_offset = 0;
555
556 /* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */
557
558 if ((sw->pre_highest_stage == hw->end_stage) &&
559 (sw->highest_stage == hw->start_stage))
560 sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) /
561 hw->max_coord;
562 else if ((sw->pre_highest_stage == hw->start_stage) &&
563 (sw->highest_stage == hw->end_stage))
564 sw->pos_ratio = (sw->mean_value_no_offset * 100) /
565 hw->max_coord;
566 sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio;
567 if (sw->abs_pos > hw->max_coord)
568 sw->abs_pos = hw->max_coord;
569}
570
571static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
572{
573 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
574 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
575 if (((sw->pre_highest_stage == hw->end_stage) &&
576 (sw->highest_stage == hw->start_stage)) ||
577 ((sw->pre_highest_stage == hw->start_stage) &&
578 (sw->highest_stage == hw->end_stage)))
579 sw->flt_pos = sw->abs_pos;
580 else
581 sw->flt_pos = ((sw->flt_pos * 30) + (sw->abs_pos * 71)) / 100;
582
583 if (sw->flt_pos > hw->max_coord)
584 sw->flt_pos = hw->max_coord;
585}
586
587static void ad714x_wheel_use_com_int(struct ad714x_chip *ad714x, int idx)
588{
589 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
590
591 ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
592}
593
594static void ad714x_wheel_use_thr_int(struct ad714x_chip *ad714x, int idx)
595{
596 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
597
598 ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
599}
600
601static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx)
602{
603 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
604 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
605 unsigned short h_state, c_state;
606 unsigned short mask;
607
608 mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
609
610 h_state = ad714x->h_state & mask;
611 c_state = ad714x->c_state & mask;
612
613 switch (sw->state) {
614 case IDLE:
615 if (h_state) {
616 sw->state = JITTER;
617 /* In End of Conversion interrupt mode, the AD714X
618 * continuously generates hardware interrupts.
619 */
620 ad714x_wheel_use_com_int(ad714x, idx);
621 dev_dbg(ad714x->dev, "wheel %d touched\n", idx);
622 }
623 break;
624
625 case JITTER:
626 if (c_state == mask) {
627 ad714x_wheel_cal_sensor_val(ad714x, idx);
628 ad714x_wheel_cal_highest_stage(ad714x, idx);
629 ad714x_wheel_cal_abs_pos(ad714x, idx);
630 sw->flt_pos = sw->abs_pos;
631 sw->state = ACTIVE;
632 }
633 break;
634
635 case ACTIVE:
636 if (c_state == mask) {
637 if (h_state) {
638 ad714x_wheel_cal_sensor_val(ad714x, idx);
639 ad714x_wheel_cal_highest_stage(ad714x, idx);
640 ad714x_wheel_cal_abs_pos(ad714x, idx);
641 ad714x_wheel_cal_flt_pos(ad714x, idx);
642
643 input_report_abs(sw->input, ABS_WHEEL,
644 sw->abs_pos);
645 input_report_key(sw->input, BTN_TOUCH, 1);
646 } else {
647 /* When the user lifts off the sensor, configure
648 * the AD714X back to threshold interrupt mode.
649 */
650 ad714x_wheel_use_thr_int(ad714x, idx);
651 sw->state = IDLE;
652 input_report_key(sw->input, BTN_TOUCH, 0);
653
654 dev_dbg(ad714x->dev, "wheel %d released\n",
655 idx);
656 }
657 input_sync(sw->input);
658 }
659 break;
660
661 default:
662 break;
663 }
664}
665
666static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
667{
668 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
669 int i;
670
671 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
672 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
673 &ad714x->adc_reg[i]);
674 ad714x->read(ad714x->dev,
675 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
676 &ad714x->amb_reg[i]);
677 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
678 ad714x->sensor_val[i] = ad714x->adc_reg[i] -
679 ad714x->amb_reg[i];
680 else
681 ad714x->sensor_val[i] = 0;
682 }
683}
684
685static void touchpad_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
686{
687 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
688 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
689
690 sw->x_highest_stage = ad714x_cal_highest_stage(ad714x,
691 hw->x_start_stage, hw->x_end_stage);
692 sw->y_highest_stage = ad714x_cal_highest_stage(ad714x,
693 hw->y_start_stage, hw->y_end_stage);
694
695 dev_dbg(ad714x->dev,
696 "touchpad %d x_highest_stage:%d, y_highest_stage:%d\n",
697 idx, sw->x_highest_stage, sw->y_highest_stage);
698}
699
700/*
701 * If 2 fingers are touching the sensor then 2 peaks can be observed in the
702 * distribution.
703 * The arithmetic doesn't support to get absolute coordinates for multi-touch
704 * yet.
705 */
706static int touchpad_check_second_peak(struct ad714x_chip *ad714x, int idx)
707{
708 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
709 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
710 int i;
711
712 for (i = hw->x_start_stage; i < sw->x_highest_stage; i++) {
713 if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
714 > (ad714x->sensor_val[i + 1] / 10))
715 return 1;
716 }
717
718 for (i = sw->x_highest_stage; i < hw->x_end_stage; i++) {
719 if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
720 > (ad714x->sensor_val[i] / 10))
721 return 1;
722 }
723
724 for (i = hw->y_start_stage; i < sw->y_highest_stage; i++) {
725 if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
726 > (ad714x->sensor_val[i + 1] / 10))
727 return 1;
728 }
729
730 for (i = sw->y_highest_stage; i < hw->y_end_stage; i++) {
731 if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
732 > (ad714x->sensor_val[i] / 10))
733 return 1;
734 }
735
736 return 0;
737}
738
739/*
740 * If only one finger is used to activate the touch pad then only 1 peak will be
741 * registered in the distribution. This peak and the 2 adjacent sensors will be
742 * used in the calculation of the absolute position. This will prevent hand
743 * shadows to affect the absolute position calculation.
744 */
745static void touchpad_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
746{
747 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
748 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
749
750 sw->x_abs_pos = ad714x_cal_abs_pos(ad714x, hw->x_start_stage,
751 hw->x_end_stage, sw->x_highest_stage, hw->x_max_coord);
752 sw->y_abs_pos = ad714x_cal_abs_pos(ad714x, hw->y_start_stage,
753 hw->y_end_stage, sw->y_highest_stage, hw->y_max_coord);
754
755 dev_dbg(ad714x->dev, "touchpad %d absolute position:(%d, %d)\n", idx,
756 sw->x_abs_pos, sw->y_abs_pos);
757}
758
759static void touchpad_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
760{
761 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
762
763 sw->x_flt_pos = (sw->x_flt_pos * (10 - 4) +
764 sw->x_abs_pos * 4)/10;
765 sw->y_flt_pos = (sw->y_flt_pos * (10 - 4) +
766 sw->y_abs_pos * 4)/10;
767
768 dev_dbg(ad714x->dev, "touchpad %d filter position:(%d, %d)\n",
769 idx, sw->x_flt_pos, sw->y_flt_pos);
770}
771
772/*
773 * To prevent distortion from showing in the absolute position, it is
774 * necessary to detect the end points. When endpoints are detected, the
775 * driver stops updating the status variables with absolute positions.
776 * End points are detected on the 4 edges of the touchpad sensor. The
777 * method to detect them is the same for all 4.
778 * To detect the end points, the firmware computes the difference in
779 * percent between the sensor on the edge and the adjacent one. The
780 * difference is calculated in percent in order to make the end point
781 * detection independent of the pressure.
782 */
783
784#define LEFT_END_POINT_DETECTION_LEVEL 550
785#define RIGHT_END_POINT_DETECTION_LEVEL 750
786#define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL 850
787#define TOP_END_POINT_DETECTION_LEVEL 550
788#define BOTTOM_END_POINT_DETECTION_LEVEL 950
789#define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL 700
790static int touchpad_check_endpoint(struct ad714x_chip *ad714x, int idx)
791{
792 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
793 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
794 int percent_sensor_diff;
795
796 /* left endpoint detect */
797 percent_sensor_diff = (ad714x->sensor_val[hw->x_start_stage] -
798 ad714x->sensor_val[hw->x_start_stage + 1]) * 100 /
799 ad714x->sensor_val[hw->x_start_stage + 1];
800 if (!sw->left_ep) {
801 if (percent_sensor_diff >= LEFT_END_POINT_DETECTION_LEVEL) {
802 sw->left_ep = 1;
803 sw->left_ep_val =
804 ad714x->sensor_val[hw->x_start_stage + 1];
805 }
806 } else {
807 if ((percent_sensor_diff < LEFT_END_POINT_DETECTION_LEVEL) &&
808 (ad714x->sensor_val[hw->x_start_stage + 1] >
809 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->left_ep_val))
810 sw->left_ep = 0;
811 }
812
813 /* right endpoint detect */
814 percent_sensor_diff = (ad714x->sensor_val[hw->x_end_stage] -
815 ad714x->sensor_val[hw->x_end_stage - 1]) * 100 /
816 ad714x->sensor_val[hw->x_end_stage - 1];
817 if (!sw->right_ep) {
818 if (percent_sensor_diff >= RIGHT_END_POINT_DETECTION_LEVEL) {
819 sw->right_ep = 1;
820 sw->right_ep_val =
821 ad714x->sensor_val[hw->x_end_stage - 1];
822 }
823 } else {
824 if ((percent_sensor_diff < RIGHT_END_POINT_DETECTION_LEVEL) &&
825 (ad714x->sensor_val[hw->x_end_stage - 1] >
826 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->right_ep_val))
827 sw->right_ep = 0;
828 }
829
830 /* top endpoint detect */
831 percent_sensor_diff = (ad714x->sensor_val[hw->y_start_stage] -
832 ad714x->sensor_val[hw->y_start_stage + 1]) * 100 /
833 ad714x->sensor_val[hw->y_start_stage + 1];
834 if (!sw->top_ep) {
835 if (percent_sensor_diff >= TOP_END_POINT_DETECTION_LEVEL) {
836 sw->top_ep = 1;
837 sw->top_ep_val =
838 ad714x->sensor_val[hw->y_start_stage + 1];
839 }
840 } else {
841 if ((percent_sensor_diff < TOP_END_POINT_DETECTION_LEVEL) &&
842 (ad714x->sensor_val[hw->y_start_stage + 1] >
843 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->top_ep_val))
844 sw->top_ep = 0;
845 }
846
847 /* bottom endpoint detect */
848 percent_sensor_diff = (ad714x->sensor_val[hw->y_end_stage] -
849 ad714x->sensor_val[hw->y_end_stage - 1]) * 100 /
850 ad714x->sensor_val[hw->y_end_stage - 1];
851 if (!sw->bottom_ep) {
852 if (percent_sensor_diff >= BOTTOM_END_POINT_DETECTION_LEVEL) {
853 sw->bottom_ep = 1;
854 sw->bottom_ep_val =
855 ad714x->sensor_val[hw->y_end_stage - 1];
856 }
857 } else {
858 if ((percent_sensor_diff < BOTTOM_END_POINT_DETECTION_LEVEL) &&
859 (ad714x->sensor_val[hw->y_end_stage - 1] >
860 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->bottom_ep_val))
861 sw->bottom_ep = 0;
862 }
863
864 return sw->left_ep || sw->right_ep || sw->top_ep || sw->bottom_ep;
865}
866
867static void touchpad_use_com_int(struct ad714x_chip *ad714x, int idx)
868{
869 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
870
871 ad714x_use_com_int(ad714x, hw->x_start_stage, hw->x_end_stage);
872}
873
874static void touchpad_use_thr_int(struct ad714x_chip *ad714x, int idx)
875{
876 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
877
878 ad714x_use_thr_int(ad714x, hw->x_start_stage, hw->x_end_stage);
879 ad714x_use_thr_int(ad714x, hw->y_start_stage, hw->y_end_stage);
880}
881
882static void ad714x_touchpad_state_machine(struct ad714x_chip *ad714x, int idx)
883{
884 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
885 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
886 unsigned short h_state, c_state;
887 unsigned short mask;
888
889 mask = (((1 << (hw->x_end_stage + 1)) - 1) -
890 ((1 << hw->x_start_stage) - 1)) +
891 (((1 << (hw->y_end_stage + 1)) - 1) -
892 ((1 << hw->y_start_stage) - 1));
893
894 h_state = ad714x->h_state & mask;
895 c_state = ad714x->c_state & mask;
896
897 switch (sw->state) {
898 case IDLE:
899 if (h_state) {
900 sw->state = JITTER;
901 /* In End of Conversion interrupt mode, the AD714X
902 * continuously generates hardware interrupts.
903 */
904 touchpad_use_com_int(ad714x, idx);
905 dev_dbg(ad714x->dev, "touchpad %d touched\n", idx);
906 }
907 break;
908
909 case JITTER:
910 if (c_state == mask) {
911 touchpad_cal_sensor_val(ad714x, idx);
912 touchpad_cal_highest_stage(ad714x, idx);
913 if ((!touchpad_check_second_peak(ad714x, idx)) &&
914 (!touchpad_check_endpoint(ad714x, idx))) {
915 dev_dbg(ad714x->dev,
916 "touchpad%d, 2 fingers or endpoint\n",
917 idx);
918 touchpad_cal_abs_pos(ad714x, idx);
919 sw->x_flt_pos = sw->x_abs_pos;
920 sw->y_flt_pos = sw->y_abs_pos;
921 sw->state = ACTIVE;
922 }
923 }
924 break;
925
926 case ACTIVE:
927 if (c_state == mask) {
928 if (h_state) {
929 touchpad_cal_sensor_val(ad714x, idx);
930 touchpad_cal_highest_stage(ad714x, idx);
931 if ((!touchpad_check_second_peak(ad714x, idx))
932 && (!touchpad_check_endpoint(ad714x, idx))) {
933 touchpad_cal_abs_pos(ad714x, idx);
934 touchpad_cal_flt_pos(ad714x, idx);
935 input_report_abs(sw->input, ABS_X,
936 sw->x_flt_pos);
937 input_report_abs(sw->input, ABS_Y,
938 sw->y_flt_pos);
939 input_report_key(sw->input, BTN_TOUCH,
940 1);
941 }
942 } else {
943 /* When the user lifts off the sensor, configure
944 * the AD714X back to threshold interrupt mode.
945 */
946 touchpad_use_thr_int(ad714x, idx);
947 sw->state = IDLE;
948 input_report_key(sw->input, BTN_TOUCH, 0);
949 dev_dbg(ad714x->dev, "touchpad %d released\n",
950 idx);
951 }
952 input_sync(sw->input);
953 }
954 break;
955
956 default:
957 break;
958 }
959}
960
961static int ad714x_hw_detect(struct ad714x_chip *ad714x)
962{
963 unsigned short data;
964
965 ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data);
966 switch (data & 0xFFF0) {
Bryan Wu31a62962010-03-21 23:23:24 -0700967 case AD7142_PARTID:
968 ad714x->product = 0x7142;
969 ad714x->version = data & 0xF;
970 dev_info(ad714x->dev, "found AD7142 captouch, rev:%d\n",
971 ad714x->version);
972 return 0;
973
Barry Song6c04d7b2010-03-21 23:23:29 -0700974 case AD7143_PARTID:
975 ad714x->product = 0x7143;
976 ad714x->version = data & 0xF;
977 dev_info(ad714x->dev, "found AD7143 captouch, rev:%d\n",
978 ad714x->version);
979 return 0;
980
981 case AD7147_PARTID:
982 ad714x->product = 0x7147;
983 ad714x->version = data & 0xF;
984 dev_info(ad714x->dev, "found AD7147(A) captouch, rev:%d\n",
985 ad714x->version);
986 return 0;
987
988 case AD7148_PARTID:
989 ad714x->product = 0x7148;
990 ad714x->version = data & 0xF;
991 dev_info(ad714x->dev, "found AD7148 captouch, rev:%d\n",
992 ad714x->version);
993 return 0;
994
Bryan Wu31a62962010-03-21 23:23:24 -0700995 default:
996 dev_err(ad714x->dev,
997 "fail to detect AD714X captouch, read ID is %04x\n",
998 data);
999 return -ENODEV;
1000 }
1001}
1002
1003static void ad714x_hw_init(struct ad714x_chip *ad714x)
1004{
1005 int i, j;
1006 unsigned short reg_base;
1007 unsigned short data;
1008
1009 /* configuration CDC and interrupts */
1010
1011 for (i = 0; i < STAGE_NUM; i++) {
1012 reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
1013 for (j = 0; j < STAGE_CFGREG_NUM; j++)
1014 ad714x->write(ad714x->dev, reg_base + j,
1015 ad714x->hw->stage_cfg_reg[i][j]);
1016 }
1017
1018 for (i = 0; i < SYS_CFGREG_NUM; i++)
1019 ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i,
1020 ad714x->hw->sys_cfg_reg[i]);
1021 for (i = 0; i < SYS_CFGREG_NUM; i++)
1022 ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i,
1023 &data);
1024
1025 ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF);
1026
1027 /* clear all interrupts */
1028 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
1029 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
1030 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
1031}
1032
1033static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
1034{
1035 struct ad714x_chip *ad714x = data;
1036 int i;
1037
1038 mutex_lock(&ad714x->mutex);
1039
1040 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
1041 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
1042 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
1043
1044 for (i = 0; i < ad714x->hw->button_num; i++)
1045 ad714x_button_state_machine(ad714x, i);
1046 for (i = 0; i < ad714x->hw->slider_num; i++)
1047 ad714x_slider_state_machine(ad714x, i);
1048 for (i = 0; i < ad714x->hw->wheel_num; i++)
1049 ad714x_wheel_state_machine(ad714x, i);
1050 for (i = 0; i < ad714x->hw->touchpad_num; i++)
1051 ad714x_touchpad_state_machine(ad714x, i);
1052
1053 mutex_unlock(&ad714x->mutex);
1054
1055 return IRQ_HANDLED;
1056}
1057
1058#define MAX_DEVICE_NUM 8
1059struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq,
1060 ad714x_read_t read, ad714x_write_t write)
1061{
1062 int i, alloc_idx;
1063 int error;
1064 struct input_dev *input[MAX_DEVICE_NUM];
1065
1066 struct ad714x_platform_data *plat_data = dev->platform_data;
1067 struct ad714x_chip *ad714x;
1068 void *drv_mem;
1069
1070 struct ad714x_button_drv *bt_drv;
1071 struct ad714x_slider_drv *sd_drv;
1072 struct ad714x_wheel_drv *wl_drv;
1073 struct ad714x_touchpad_drv *tp_drv;
1074
1075
1076 if (irq <= 0) {
1077 dev_err(dev, "IRQ not configured!\n");
1078 error = -EINVAL;
1079 goto err_out;
1080 }
1081
1082 if (dev->platform_data == NULL) {
1083 dev_err(dev, "platform data for ad714x doesn't exist\n");
1084 error = -EINVAL;
1085 goto err_out;
1086 }
1087
1088 ad714x = kzalloc(sizeof(*ad714x) + sizeof(*ad714x->sw) +
1089 sizeof(*sd_drv) * plat_data->slider_num +
1090 sizeof(*wl_drv) * plat_data->wheel_num +
1091 sizeof(*tp_drv) * plat_data->touchpad_num +
1092 sizeof(*bt_drv) * plat_data->button_num, GFP_KERNEL);
1093 if (!ad714x) {
1094 error = -ENOMEM;
1095 goto err_out;
1096 }
1097
1098 ad714x->hw = plat_data;
1099
1100 drv_mem = ad714x + 1;
1101 ad714x->sw = drv_mem;
1102 drv_mem += sizeof(*ad714x->sw);
1103 ad714x->sw->slider = sd_drv = drv_mem;
1104 drv_mem += sizeof(*sd_drv) * ad714x->hw->slider_num;
1105 ad714x->sw->wheel = wl_drv = drv_mem;
1106 drv_mem += sizeof(*wl_drv) * ad714x->hw->wheel_num;
1107 ad714x->sw->touchpad = tp_drv = drv_mem;
1108 drv_mem += sizeof(*tp_drv) * ad714x->hw->touchpad_num;
1109 ad714x->sw->button = bt_drv = drv_mem;
1110 drv_mem += sizeof(*bt_drv) * ad714x->hw->button_num;
1111
1112 ad714x->read = read;
1113 ad714x->write = write;
1114 ad714x->irq = irq;
1115 ad714x->dev = dev;
1116
1117 error = ad714x_hw_detect(ad714x);
1118 if (error)
1119 goto err_free_mem;
1120
1121 /* initilize and request sw/hw resources */
1122
1123 ad714x_hw_init(ad714x);
1124 mutex_init(&ad714x->mutex);
1125
1126 /*
1127 * Allocate and register AD714X input device
1128 */
1129 alloc_idx = 0;
1130
1131 /* a slider uses one input_dev instance */
1132 if (ad714x->hw->slider_num > 0) {
1133 struct ad714x_slider_plat *sd_plat = ad714x->hw->slider;
1134
1135 for (i = 0; i < ad714x->hw->slider_num; i++) {
1136 sd_drv[i].input = input[alloc_idx] = input_allocate_device();
1137 if (!input[alloc_idx]) {
1138 error = -ENOMEM;
1139 goto err_free_dev;
1140 }
1141
1142 __set_bit(EV_ABS, input[alloc_idx]->evbit);
1143 __set_bit(EV_KEY, input[alloc_idx]->evbit);
1144 __set_bit(ABS_X, input[alloc_idx]->absbit);
1145 __set_bit(BTN_TOUCH, input[alloc_idx]->keybit);
1146 input_set_abs_params(input[alloc_idx],
1147 ABS_X, 0, sd_plat->max_coord, 0, 0);
1148
1149 input[alloc_idx]->id.bustype = bus_type;
1150 input[alloc_idx]->id.product = ad714x->product;
1151 input[alloc_idx]->id.version = ad714x->version;
1152
1153 error = input_register_device(input[alloc_idx]);
1154 if (error)
1155 goto err_free_dev;
1156
1157 alloc_idx++;
1158 }
1159 }
1160
1161 /* a wheel uses one input_dev instance */
1162 if (ad714x->hw->wheel_num > 0) {
1163 struct ad714x_wheel_plat *wl_plat = ad714x->hw->wheel;
1164
1165 for (i = 0; i < ad714x->hw->wheel_num; i++) {
1166 wl_drv[i].input = input[alloc_idx] = input_allocate_device();
1167 if (!input[alloc_idx]) {
1168 error = -ENOMEM;
1169 goto err_free_dev;
1170 }
1171
1172 __set_bit(EV_KEY, input[alloc_idx]->evbit);
1173 __set_bit(EV_ABS, input[alloc_idx]->evbit);
1174 __set_bit(ABS_WHEEL, input[alloc_idx]->absbit);
1175 __set_bit(BTN_TOUCH, input[alloc_idx]->keybit);
1176 input_set_abs_params(input[alloc_idx],
1177 ABS_WHEEL, 0, wl_plat->max_coord, 0, 0);
1178
1179 input[alloc_idx]->id.bustype = bus_type;
1180 input[alloc_idx]->id.product = ad714x->product;
1181 input[alloc_idx]->id.version = ad714x->version;
1182
1183 error = input_register_device(input[alloc_idx]);
1184 if (error)
1185 goto err_free_dev;
1186
1187 alloc_idx++;
1188 }
1189 }
1190
1191 /* a touchpad uses one input_dev instance */
1192 if (ad714x->hw->touchpad_num > 0) {
1193 struct ad714x_touchpad_plat *tp_plat = ad714x->hw->touchpad;
1194
1195 for (i = 0; i < ad714x->hw->touchpad_num; i++) {
1196 tp_drv[i].input = input[alloc_idx] = input_allocate_device();
1197 if (!input[alloc_idx]) {
1198 error = -ENOMEM;
1199 goto err_free_dev;
1200 }
1201
1202 __set_bit(EV_ABS, input[alloc_idx]->evbit);
1203 __set_bit(EV_KEY, input[alloc_idx]->evbit);
1204 __set_bit(ABS_X, input[alloc_idx]->absbit);
1205 __set_bit(ABS_Y, input[alloc_idx]->absbit);
1206 __set_bit(BTN_TOUCH, input[alloc_idx]->keybit);
1207 input_set_abs_params(input[alloc_idx],
1208 ABS_X, 0, tp_plat->x_max_coord, 0, 0);
1209 input_set_abs_params(input[alloc_idx],
1210 ABS_Y, 0, tp_plat->y_max_coord, 0, 0);
1211
1212 input[alloc_idx]->id.bustype = bus_type;
1213 input[alloc_idx]->id.product = ad714x->product;
1214 input[alloc_idx]->id.version = ad714x->version;
1215
1216 error = input_register_device(input[alloc_idx]);
1217 if (error)
1218 goto err_free_dev;
1219
1220 alloc_idx++;
1221 }
1222 }
1223
1224 /* all buttons use one input node */
1225 if (ad714x->hw->button_num > 0) {
1226 struct ad714x_button_plat *bt_plat = ad714x->hw->button;
1227
1228 input[alloc_idx] = input_allocate_device();
1229 if (!input[alloc_idx]) {
1230 error = -ENOMEM;
1231 goto err_free_dev;
1232 }
1233
1234 __set_bit(EV_KEY, input[alloc_idx]->evbit);
1235 for (i = 0; i < ad714x->hw->button_num; i++) {
1236 bt_drv[i].input = input[alloc_idx];
1237 __set_bit(bt_plat[i].keycode, input[alloc_idx]->keybit);
1238 }
1239
1240 input[alloc_idx]->id.bustype = bus_type;
1241 input[alloc_idx]->id.product = ad714x->product;
1242 input[alloc_idx]->id.version = ad714x->version;
1243
1244 error = input_register_device(input[alloc_idx]);
1245 if (error)
1246 goto err_free_dev;
1247
1248 alloc_idx++;
1249 }
1250
1251 error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread,
1252 IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x);
1253 if (error) {
1254 dev_err(dev, "can't allocate irq %d\n", ad714x->irq);
1255 goto err_unreg_dev;
1256 }
1257
1258 return ad714x;
1259
1260 err_free_dev:
1261 dev_err(dev, "failed to setup AD714x input device %i\n", alloc_idx);
1262 input_free_device(input[alloc_idx]);
1263 err_unreg_dev:
1264 while (--alloc_idx >= 0)
1265 input_unregister_device(input[alloc_idx]);
1266 err_free_mem:
1267 kfree(ad714x);
1268 err_out:
1269 return ERR_PTR(error);
1270}
1271EXPORT_SYMBOL(ad714x_probe);
1272
1273void ad714x_remove(struct ad714x_chip *ad714x)
1274{
1275 struct ad714x_platform_data *hw = ad714x->hw;
1276 struct ad714x_driver_data *sw = ad714x->sw;
1277 int i;
1278
1279 free_irq(ad714x->irq, ad714x);
1280
1281 /* unregister and free all input devices */
1282
1283 for (i = 0; i < hw->slider_num; i++)
1284 input_unregister_device(sw->slider[i].input);
1285
1286 for (i = 0; i < hw->wheel_num; i++)
1287 input_unregister_device(sw->wheel[i].input);
1288
1289 for (i = 0; i < hw->touchpad_num; i++)
1290 input_unregister_device(sw->touchpad[i].input);
1291
1292 if (hw->button_num)
1293 input_unregister_device(sw->button[0].input);
1294
1295 kfree(ad714x);
1296}
1297EXPORT_SYMBOL(ad714x_remove);
1298
1299#ifdef CONFIG_PM
1300int ad714x_disable(struct ad714x_chip *ad714x)
1301{
1302 unsigned short data;
1303
1304 dev_dbg(ad714x->dev, "%s enter\n", __func__);
1305
1306 mutex_lock(&ad714x->mutex);
1307
1308 data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
1309 ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data);
1310
1311 mutex_unlock(&ad714x->mutex);
1312
1313 return 0;
1314}
1315EXPORT_SYMBOL(ad714x_disable);
1316
1317int ad714x_enable(struct ad714x_chip *ad714x)
1318{
1319 unsigned short data;
1320
1321 dev_dbg(ad714x->dev, "%s enter\n", __func__);
1322
1323 mutex_lock(&ad714x->mutex);
1324
1325 /* resume to non-shutdown mode */
1326
1327 ad714x->write(ad714x->dev, AD714X_PWR_CTRL,
1328 ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
1329
1330 /* make sure the interrupt output line is not low level after resume,
1331 * otherwise we will get no chance to enter falling-edge irq again
1332 */
1333
1334 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
1335 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
1336 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
1337
1338 mutex_unlock(&ad714x->mutex);
1339
1340 return 0;
1341}
1342EXPORT_SYMBOL(ad714x_enable);
1343#endif
1344
1345MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor Driver");
1346MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
1347MODULE_LICENSE("GPL");