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