1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
5 * Copyright 2009-2011 Analog Devices Inc.
8 #include <linux/device.h>
9 #include <linux/input.h>
10 #include <linux/interrupt.h>
11 #include <linux/slab.h>
12 #include <linux/input/ad714x.h>
13 #include <linux/module.h>
16 #define AD714X_PWR_CTRL 0x0
17 #define AD714X_STG_CAL_EN_REG 0x1
18 #define AD714X_AMB_COMP_CTRL0_REG 0x2
19 #define AD714X_PARTID_REG 0x17
20 #define AD7142_PARTID 0xE620
21 #define AD7143_PARTID 0xE630
22 #define AD7147_PARTID 0x1470
23 #define AD7148_PARTID 0x1480
24 #define AD714X_STAGECFG_REG 0x80
25 #define AD714X_SYSCFG_REG 0x0
27 #define STG_LOW_INT_EN_REG 0x5
28 #define STG_HIGH_INT_EN_REG 0x6
29 #define STG_COM_INT_EN_REG 0x7
30 #define STG_LOW_INT_STA_REG 0x8
31 #define STG_HIGH_INT_STA_REG 0x9
32 #define STG_COM_INT_STA_REG 0xA
34 #define CDC_RESULT_S0 0xB
35 #define CDC_RESULT_S1 0xC
36 #define CDC_RESULT_S2 0xD
37 #define CDC_RESULT_S3 0xE
38 #define CDC_RESULT_S4 0xF
39 #define CDC_RESULT_S5 0x10
40 #define CDC_RESULT_S6 0x11
41 #define CDC_RESULT_S7 0x12
42 #define CDC_RESULT_S8 0x13
43 #define CDC_RESULT_S9 0x14
44 #define CDC_RESULT_S10 0x15
45 #define CDC_RESULT_S11 0x16
47 #define STAGE0_AMBIENT 0xF1
48 #define STAGE1_AMBIENT 0x115
49 #define STAGE2_AMBIENT 0x139
50 #define STAGE3_AMBIENT 0x15D
51 #define STAGE4_AMBIENT 0x181
52 #define STAGE5_AMBIENT 0x1A5
53 #define STAGE6_AMBIENT 0x1C9
54 #define STAGE7_AMBIENT 0x1ED
55 #define STAGE8_AMBIENT 0x211
56 #define STAGE9_AMBIENT 0x234
57 #define STAGE10_AMBIENT 0x259
58 #define STAGE11_AMBIENT 0x27D
60 #define PER_STAGE_REG_NUM 36
61 #define STAGE_CFGREG_NUM 8
62 #define SYS_CFGREG_NUM 8
65 * driver information which will be used to maintain the software flow
67 enum ad714x_device_state
{ IDLE
, JITTER
, ACTIVE
, SPACE
};
69 struct ad714x_slider_drv
{
73 enum ad714x_device_state state
;
74 struct input_dev
*input
;
77 struct ad714x_wheel_drv
{
80 int pre_highest_stage
;
82 enum ad714x_device_state state
;
83 struct input_dev
*input
;
86 struct ad714x_touchpad_drv
{
101 enum ad714x_device_state state
;
102 struct input_dev
*input
;
105 struct ad714x_button_drv
{
106 enum ad714x_device_state state
;
108 * Unlike slider/wheel/touchpad, all buttons point to
109 * same input_dev instance
111 struct input_dev
*input
;
114 struct ad714x_driver_data
{
115 struct ad714x_slider_drv
*slider
;
116 struct ad714x_wheel_drv
*wheel
;
117 struct ad714x_touchpad_drv
*touchpad
;
118 struct ad714x_button_drv
*button
;
122 * information to integrate all things which will be private data
126 static void ad714x_use_com_int(struct ad714x_chip
*ad714x
,
127 int start_stage
, int end_stage
)
132 mask
= ((1 << (end_stage
+ 1)) - 1) - ((1 << start_stage
) - 1);
134 ad714x
->read(ad714x
, STG_COM_INT_EN_REG
, &data
, 1);
135 data
|= 1 << end_stage
;
136 ad714x
->write(ad714x
, STG_COM_INT_EN_REG
, data
);
138 ad714x
->read(ad714x
, STG_HIGH_INT_EN_REG
, &data
, 1);
140 ad714x
->write(ad714x
, STG_HIGH_INT_EN_REG
, data
);
143 static void ad714x_use_thr_int(struct ad714x_chip
*ad714x
,
144 int start_stage
, int end_stage
)
149 mask
= ((1 << (end_stage
+ 1)) - 1) - ((1 << start_stage
) - 1);
151 ad714x
->read(ad714x
, STG_COM_INT_EN_REG
, &data
, 1);
152 data
&= ~(1 << end_stage
);
153 ad714x
->write(ad714x
, STG_COM_INT_EN_REG
, data
);
155 ad714x
->read(ad714x
, STG_HIGH_INT_EN_REG
, &data
, 1);
157 ad714x
->write(ad714x
, STG_HIGH_INT_EN_REG
, data
);
160 static int ad714x_cal_highest_stage(struct ad714x_chip
*ad714x
,
161 int start_stage
, int end_stage
)
167 for (i
= start_stage
; i
<= end_stage
; i
++) {
168 if (ad714x
->sensor_val
[i
] > max_res
) {
169 max_res
= ad714x
->sensor_val
[i
];
177 static int ad714x_cal_abs_pos(struct ad714x_chip
*ad714x
,
178 int start_stage
, int end_stage
,
179 int highest_stage
, int max_coord
)
181 int a_param
, b_param
;
183 if (highest_stage
== start_stage
) {
184 a_param
= ad714x
->sensor_val
[start_stage
+ 1];
185 b_param
= ad714x
->sensor_val
[start_stage
] +
186 ad714x
->sensor_val
[start_stage
+ 1];
187 } else if (highest_stage
== end_stage
) {
188 a_param
= ad714x
->sensor_val
[end_stage
] *
189 (end_stage
- start_stage
) +
190 ad714x
->sensor_val
[end_stage
- 1] *
191 (end_stage
- start_stage
- 1);
192 b_param
= ad714x
->sensor_val
[end_stage
] +
193 ad714x
->sensor_val
[end_stage
- 1];
195 a_param
= ad714x
->sensor_val
[highest_stage
] *
196 (highest_stage
- start_stage
) +
197 ad714x
->sensor_val
[highest_stage
- 1] *
198 (highest_stage
- start_stage
- 1) +
199 ad714x
->sensor_val
[highest_stage
+ 1] *
200 (highest_stage
- start_stage
+ 1);
201 b_param
= ad714x
->sensor_val
[highest_stage
] +
202 ad714x
->sensor_val
[highest_stage
- 1] +
203 ad714x
->sensor_val
[highest_stage
+ 1];
206 return (max_coord
/ (end_stage
- start_stage
)) * a_param
/ b_param
;
210 * One button can connect to multi positive and negative of CDCs
211 * Multi-buttons can connect to same positive/negative of one CDC
213 static void ad714x_button_state_machine(struct ad714x_chip
*ad714x
, int idx
)
215 struct ad714x_button_plat
*hw
= &ad714x
->hw
->button
[idx
];
216 struct ad714x_button_drv
*sw
= &ad714x
->sw
->button
[idx
];
220 if (((ad714x
->h_state
& hw
->h_mask
) == hw
->h_mask
) &&
221 ((ad714x
->l_state
& hw
->l_mask
) == hw
->l_mask
)) {
222 dev_dbg(ad714x
->dev
, "button %d touched\n", idx
);
223 input_report_key(sw
->input
, hw
->keycode
, 1);
224 input_sync(sw
->input
);
230 if (((ad714x
->h_state
& hw
->h_mask
) != hw
->h_mask
) ||
231 ((ad714x
->l_state
& hw
->l_mask
) != hw
->l_mask
)) {
232 dev_dbg(ad714x
->dev
, "button %d released\n", idx
);
233 input_report_key(sw
->input
, hw
->keycode
, 0);
234 input_sync(sw
->input
);
245 * The response of a sensor is defined by the absolute number of codes
246 * between the current CDC value and the ambient value.
248 static void ad714x_slider_cal_sensor_val(struct ad714x_chip
*ad714x
, int idx
)
250 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
253 ad714x
->read(ad714x
, CDC_RESULT_S0
+ hw
->start_stage
,
254 &ad714x
->adc_reg
[hw
->start_stage
],
255 hw
->end_stage
- hw
->start_stage
+ 1);
257 for (i
= hw
->start_stage
; i
<= hw
->end_stage
; i
++) {
258 ad714x
->read(ad714x
, STAGE0_AMBIENT
+ i
* PER_STAGE_REG_NUM
,
259 &ad714x
->amb_reg
[i
], 1);
261 ad714x
->sensor_val
[i
] =
262 abs(ad714x
->adc_reg
[i
] - ad714x
->amb_reg
[i
]);
266 static void ad714x_slider_cal_highest_stage(struct ad714x_chip
*ad714x
, int idx
)
268 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
269 struct ad714x_slider_drv
*sw
= &ad714x
->sw
->slider
[idx
];
271 sw
->highest_stage
= ad714x_cal_highest_stage(ad714x
, hw
->start_stage
,
274 dev_dbg(ad714x
->dev
, "slider %d highest_stage:%d\n", idx
,
279 * The formulae are very straight forward. It uses the sensor with the
280 * highest response and the 2 adjacent ones.
281 * When Sensor 0 has the highest response, only sensor 0 and sensor 1
282 * are used in the calculations. Similarly when the last sensor has the
283 * highest response, only the last sensor and the second last sensors
284 * are used in the calculations.
286 * For i= idx_of_peak_Sensor-1 to i= idx_of_peak_Sensor+1
287 * v += Sensor response(i)*i
288 * w += Sensor response(i)
289 * POS=(Number_of_Positions_Wanted/(Number_of_Sensors_Used-1)) *(v/w)
291 static void ad714x_slider_cal_abs_pos(struct ad714x_chip
*ad714x
, int idx
)
293 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
294 struct ad714x_slider_drv
*sw
= &ad714x
->sw
->slider
[idx
];
296 sw
->abs_pos
= ad714x_cal_abs_pos(ad714x
, hw
->start_stage
, hw
->end_stage
,
297 sw
->highest_stage
, hw
->max_coord
);
299 dev_dbg(ad714x
->dev
, "slider %d absolute position:%d\n", idx
,
304 * To minimise the Impact of the noise on the algorithm, ADI developed a
305 * routine that filters the CDC results after they have been read by the
307 * The filter used is an Infinite Input Response(IIR) filter implemented
308 * in firmware and attenuates the noise on the CDC results after they've
309 * been read by the host processor.
310 * Filtered_CDC_result = (Filtered_CDC_result * (10 - Coefficient) +
311 * Latest_CDC_result * Coefficient)/10
313 static void ad714x_slider_cal_flt_pos(struct ad714x_chip
*ad714x
, int idx
)
315 struct ad714x_slider_drv
*sw
= &ad714x
->sw
->slider
[idx
];
317 sw
->flt_pos
= (sw
->flt_pos
* (10 - 4) +
320 dev_dbg(ad714x
->dev
, "slider %d filter position:%d\n", idx
,
324 static void ad714x_slider_use_com_int(struct ad714x_chip
*ad714x
, int idx
)
326 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
328 ad714x_use_com_int(ad714x
, hw
->start_stage
, hw
->end_stage
);
331 static void ad714x_slider_use_thr_int(struct ad714x_chip
*ad714x
, int idx
)
333 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
335 ad714x_use_thr_int(ad714x
, hw
->start_stage
, hw
->end_stage
);
338 static void ad714x_slider_state_machine(struct ad714x_chip
*ad714x
, int idx
)
340 struct ad714x_slider_plat
*hw
= &ad714x
->hw
->slider
[idx
];
341 struct ad714x_slider_drv
*sw
= &ad714x
->sw
->slider
[idx
];
342 unsigned short h_state
, c_state
;
345 mask
= ((1 << (hw
->end_stage
+ 1)) - 1) - ((1 << hw
->start_stage
) - 1);
347 h_state
= ad714x
->h_state
& mask
;
348 c_state
= ad714x
->c_state
& mask
;
354 /* In End of Conversion interrupt mode, the AD714X
355 * continuously generates hardware interrupts.
357 ad714x_slider_use_com_int(ad714x
, idx
);
358 dev_dbg(ad714x
->dev
, "slider %d touched\n", idx
);
363 if (c_state
== mask
) {
364 ad714x_slider_cal_sensor_val(ad714x
, idx
);
365 ad714x_slider_cal_highest_stage(ad714x
, idx
);
366 ad714x_slider_cal_abs_pos(ad714x
, idx
);
367 sw
->flt_pos
= sw
->abs_pos
;
373 if (c_state
== mask
) {
375 ad714x_slider_cal_sensor_val(ad714x
, idx
);
376 ad714x_slider_cal_highest_stage(ad714x
, idx
);
377 ad714x_slider_cal_abs_pos(ad714x
, idx
);
378 ad714x_slider_cal_flt_pos(ad714x
, idx
);
379 input_report_abs(sw
->input
, ABS_X
, sw
->flt_pos
);
380 input_report_key(sw
->input
, BTN_TOUCH
, 1);
382 /* When the user lifts off the sensor, configure
383 * the AD714X back to threshold interrupt mode.
385 ad714x_slider_use_thr_int(ad714x
, idx
);
387 input_report_key(sw
->input
, BTN_TOUCH
, 0);
388 dev_dbg(ad714x
->dev
, "slider %d released\n",
391 input_sync(sw
->input
);
401 * When the scroll wheel is activated, we compute the absolute position based
402 * on the sensor values. To calculate the position, we first determine the
403 * sensor that has the greatest response among the 8 sensors that constitutes
404 * the scrollwheel. Then we determined the 2 sensors on either sides of the
405 * sensor with the highest response and we apply weights to these sensors.
407 static void ad714x_wheel_cal_highest_stage(struct ad714x_chip
*ad714x
, int idx
)
409 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
410 struct ad714x_wheel_drv
*sw
= &ad714x
->sw
->wheel
[idx
];
412 sw
->pre_highest_stage
= sw
->highest_stage
;
413 sw
->highest_stage
= ad714x_cal_highest_stage(ad714x
, hw
->start_stage
,
416 dev_dbg(ad714x
->dev
, "wheel %d highest_stage:%d\n", idx
,
420 static void ad714x_wheel_cal_sensor_val(struct ad714x_chip
*ad714x
, int idx
)
422 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
425 ad714x
->read(ad714x
, CDC_RESULT_S0
+ hw
->start_stage
,
426 &ad714x
->adc_reg
[hw
->start_stage
],
427 hw
->end_stage
- hw
->start_stage
+ 1);
429 for (i
= hw
->start_stage
; i
<= hw
->end_stage
; i
++) {
430 ad714x
->read(ad714x
, STAGE0_AMBIENT
+ i
* PER_STAGE_REG_NUM
,
431 &ad714x
->amb_reg
[i
], 1);
432 if (ad714x
->adc_reg
[i
] > ad714x
->amb_reg
[i
])
433 ad714x
->sensor_val
[i
] =
434 ad714x
->adc_reg
[i
] - ad714x
->amb_reg
[i
];
436 ad714x
->sensor_val
[i
] = 0;
441 * When the scroll wheel is activated, we compute the absolute position based
442 * on the sensor values. To calculate the position, we first determine the
443 * sensor that has the greatest response among the sensors that constitutes
444 * the scrollwheel. Then we determined the sensors on either sides of the
445 * sensor with the highest response and we apply weights to these sensors. The
446 * result of this computation gives us the mean value.
449 static void ad714x_wheel_cal_abs_pos(struct ad714x_chip
*ad714x
, int idx
)
451 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
452 struct ad714x_wheel_drv
*sw
= &ad714x
->sw
->wheel
[idx
];
453 int stage_num
= hw
->end_stage
- hw
->start_stage
+ 1;
454 int first_before
, highest
, first_after
;
455 int a_param
, b_param
;
457 first_before
= (sw
->highest_stage
+ stage_num
- 1) % stage_num
;
458 highest
= sw
->highest_stage
;
459 first_after
= (sw
->highest_stage
+ stage_num
+ 1) % stage_num
;
461 a_param
= ad714x
->sensor_val
[highest
] *
462 (highest
- hw
->start_stage
) +
463 ad714x
->sensor_val
[first_before
] *
464 (highest
- hw
->start_stage
- 1) +
465 ad714x
->sensor_val
[first_after
] *
466 (highest
- hw
->start_stage
+ 1);
467 b_param
= ad714x
->sensor_val
[highest
] +
468 ad714x
->sensor_val
[first_before
] +
469 ad714x
->sensor_val
[first_after
];
471 sw
->abs_pos
= ((hw
->max_coord
/ (hw
->end_stage
- hw
->start_stage
)) *
474 if (sw
->abs_pos
> hw
->max_coord
)
475 sw
->abs_pos
= hw
->max_coord
;
476 else if (sw
->abs_pos
< 0)
480 static void ad714x_wheel_cal_flt_pos(struct ad714x_chip
*ad714x
, int idx
)
482 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
483 struct ad714x_wheel_drv
*sw
= &ad714x
->sw
->wheel
[idx
];
484 if (((sw
->pre_highest_stage
== hw
->end_stage
) &&
485 (sw
->highest_stage
== hw
->start_stage
)) ||
486 ((sw
->pre_highest_stage
== hw
->start_stage
) &&
487 (sw
->highest_stage
== hw
->end_stage
)))
488 sw
->flt_pos
= sw
->abs_pos
;
490 sw
->flt_pos
= ((sw
->flt_pos
* 30) + (sw
->abs_pos
* 71)) / 100;
492 if (sw
->flt_pos
> hw
->max_coord
)
493 sw
->flt_pos
= hw
->max_coord
;
496 static void ad714x_wheel_use_com_int(struct ad714x_chip
*ad714x
, int idx
)
498 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
500 ad714x_use_com_int(ad714x
, hw
->start_stage
, hw
->end_stage
);
503 static void ad714x_wheel_use_thr_int(struct ad714x_chip
*ad714x
, int idx
)
505 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
507 ad714x_use_thr_int(ad714x
, hw
->start_stage
, hw
->end_stage
);
510 static void ad714x_wheel_state_machine(struct ad714x_chip
*ad714x
, int idx
)
512 struct ad714x_wheel_plat
*hw
= &ad714x
->hw
->wheel
[idx
];
513 struct ad714x_wheel_drv
*sw
= &ad714x
->sw
->wheel
[idx
];
514 unsigned short h_state
, c_state
;
517 mask
= ((1 << (hw
->end_stage
+ 1)) - 1) - ((1 << hw
->start_stage
) - 1);
519 h_state
= ad714x
->h_state
& mask
;
520 c_state
= ad714x
->c_state
& mask
;
526 /* In End of Conversion interrupt mode, the AD714X
527 * continuously generates hardware interrupts.
529 ad714x_wheel_use_com_int(ad714x
, idx
);
530 dev_dbg(ad714x
->dev
, "wheel %d touched\n", idx
);
535 if (c_state
== mask
) {
536 ad714x_wheel_cal_sensor_val(ad714x
, idx
);
537 ad714x_wheel_cal_highest_stage(ad714x
, idx
);
538 ad714x_wheel_cal_abs_pos(ad714x
, idx
);
539 sw
->flt_pos
= sw
->abs_pos
;
545 if (c_state
== mask
) {
547 ad714x_wheel_cal_sensor_val(ad714x
, idx
);
548 ad714x_wheel_cal_highest_stage(ad714x
, idx
);
549 ad714x_wheel_cal_abs_pos(ad714x
, idx
);
550 ad714x_wheel_cal_flt_pos(ad714x
, idx
);
551 input_report_abs(sw
->input
, ABS_WHEEL
,
553 input_report_key(sw
->input
, BTN_TOUCH
, 1);
555 /* When the user lifts off the sensor, configure
556 * the AD714X back to threshold interrupt mode.
558 ad714x_wheel_use_thr_int(ad714x
, idx
);
560 input_report_key(sw
->input
, BTN_TOUCH
, 0);
562 dev_dbg(ad714x
->dev
, "wheel %d released\n",
565 input_sync(sw
->input
);
574 static void touchpad_cal_sensor_val(struct ad714x_chip
*ad714x
, int idx
)
576 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
579 ad714x
->read(ad714x
, CDC_RESULT_S0
+ hw
->x_start_stage
,
580 &ad714x
->adc_reg
[hw
->x_start_stage
],
581 hw
->x_end_stage
- hw
->x_start_stage
+ 1);
583 for (i
= hw
->x_start_stage
; i
<= hw
->x_end_stage
; i
++) {
584 ad714x
->read(ad714x
, STAGE0_AMBIENT
+ i
* PER_STAGE_REG_NUM
,
585 &ad714x
->amb_reg
[i
], 1);
586 if (ad714x
->adc_reg
[i
] > ad714x
->amb_reg
[i
])
587 ad714x
->sensor_val
[i
] =
588 ad714x
->adc_reg
[i
] - ad714x
->amb_reg
[i
];
590 ad714x
->sensor_val
[i
] = 0;
594 static void touchpad_cal_highest_stage(struct ad714x_chip
*ad714x
, int idx
)
596 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
597 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
599 sw
->x_highest_stage
= ad714x_cal_highest_stage(ad714x
,
600 hw
->x_start_stage
, hw
->x_end_stage
);
601 sw
->y_highest_stage
= ad714x_cal_highest_stage(ad714x
,
602 hw
->y_start_stage
, hw
->y_end_stage
);
605 "touchpad %d x_highest_stage:%d, y_highest_stage:%d\n",
606 idx
, sw
->x_highest_stage
, sw
->y_highest_stage
);
610 * If 2 fingers are touching the sensor then 2 peaks can be observed in the
612 * The arithmetic doesn't support to get absolute coordinates for multi-touch
615 static int touchpad_check_second_peak(struct ad714x_chip
*ad714x
, int idx
)
617 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
618 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
621 for (i
= hw
->x_start_stage
; i
< sw
->x_highest_stage
; i
++) {
622 if ((ad714x
->sensor_val
[i
] - ad714x
->sensor_val
[i
+ 1])
623 > (ad714x
->sensor_val
[i
+ 1] / 10))
627 for (i
= sw
->x_highest_stage
; i
< hw
->x_end_stage
; i
++) {
628 if ((ad714x
->sensor_val
[i
+ 1] - ad714x
->sensor_val
[i
])
629 > (ad714x
->sensor_val
[i
] / 10))
633 for (i
= hw
->y_start_stage
; i
< sw
->y_highest_stage
; i
++) {
634 if ((ad714x
->sensor_val
[i
] - ad714x
->sensor_val
[i
+ 1])
635 > (ad714x
->sensor_val
[i
+ 1] / 10))
639 for (i
= sw
->y_highest_stage
; i
< hw
->y_end_stage
; i
++) {
640 if ((ad714x
->sensor_val
[i
+ 1] - ad714x
->sensor_val
[i
])
641 > (ad714x
->sensor_val
[i
] / 10))
649 * If only one finger is used to activate the touch pad then only 1 peak will be
650 * registered in the distribution. This peak and the 2 adjacent sensors will be
651 * used in the calculation of the absolute position. This will prevent hand
652 * shadows to affect the absolute position calculation.
654 static void touchpad_cal_abs_pos(struct ad714x_chip
*ad714x
, int idx
)
656 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
657 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
659 sw
->x_abs_pos
= ad714x_cal_abs_pos(ad714x
, hw
->x_start_stage
,
660 hw
->x_end_stage
, sw
->x_highest_stage
, hw
->x_max_coord
);
661 sw
->y_abs_pos
= ad714x_cal_abs_pos(ad714x
, hw
->y_start_stage
,
662 hw
->y_end_stage
, sw
->y_highest_stage
, hw
->y_max_coord
);
664 dev_dbg(ad714x
->dev
, "touchpad %d absolute position:(%d, %d)\n", idx
,
665 sw
->x_abs_pos
, sw
->y_abs_pos
);
668 static void touchpad_cal_flt_pos(struct ad714x_chip
*ad714x
, int idx
)
670 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
672 sw
->x_flt_pos
= (sw
->x_flt_pos
* (10 - 4) +
673 sw
->x_abs_pos
* 4)/10;
674 sw
->y_flt_pos
= (sw
->y_flt_pos
* (10 - 4) +
675 sw
->y_abs_pos
* 4)/10;
677 dev_dbg(ad714x
->dev
, "touchpad %d filter position:(%d, %d)\n",
678 idx
, sw
->x_flt_pos
, sw
->y_flt_pos
);
682 * To prevent distortion from showing in the absolute position, it is
683 * necessary to detect the end points. When endpoints are detected, the
684 * driver stops updating the status variables with absolute positions.
685 * End points are detected on the 4 edges of the touchpad sensor. The
686 * method to detect them is the same for all 4.
687 * To detect the end points, the firmware computes the difference in
688 * percent between the sensor on the edge and the adjacent one. The
689 * difference is calculated in percent in order to make the end point
690 * detection independent of the pressure.
693 #define LEFT_END_POINT_DETECTION_LEVEL 550
694 #define RIGHT_END_POINT_DETECTION_LEVEL 750
695 #define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL 850
696 #define TOP_END_POINT_DETECTION_LEVEL 550
697 #define BOTTOM_END_POINT_DETECTION_LEVEL 950
698 #define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL 700
699 static int touchpad_check_endpoint(struct ad714x_chip
*ad714x
, int idx
)
701 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
702 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
703 int percent_sensor_diff
;
705 /* left endpoint detect */
706 percent_sensor_diff
= (ad714x
->sensor_val
[hw
->x_start_stage
] -
707 ad714x
->sensor_val
[hw
->x_start_stage
+ 1]) * 100 /
708 ad714x
->sensor_val
[hw
->x_start_stage
+ 1];
710 if (percent_sensor_diff
>= LEFT_END_POINT_DETECTION_LEVEL
) {
713 ad714x
->sensor_val
[hw
->x_start_stage
+ 1];
716 if ((percent_sensor_diff
< LEFT_END_POINT_DETECTION_LEVEL
) &&
717 (ad714x
->sensor_val
[hw
->x_start_stage
+ 1] >
718 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL
+ sw
->left_ep_val
))
722 /* right endpoint detect */
723 percent_sensor_diff
= (ad714x
->sensor_val
[hw
->x_end_stage
] -
724 ad714x
->sensor_val
[hw
->x_end_stage
- 1]) * 100 /
725 ad714x
->sensor_val
[hw
->x_end_stage
- 1];
727 if (percent_sensor_diff
>= RIGHT_END_POINT_DETECTION_LEVEL
) {
730 ad714x
->sensor_val
[hw
->x_end_stage
- 1];
733 if ((percent_sensor_diff
< RIGHT_END_POINT_DETECTION_LEVEL
) &&
734 (ad714x
->sensor_val
[hw
->x_end_stage
- 1] >
735 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL
+ sw
->right_ep_val
))
739 /* top endpoint detect */
740 percent_sensor_diff
= (ad714x
->sensor_val
[hw
->y_start_stage
] -
741 ad714x
->sensor_val
[hw
->y_start_stage
+ 1]) * 100 /
742 ad714x
->sensor_val
[hw
->y_start_stage
+ 1];
744 if (percent_sensor_diff
>= TOP_END_POINT_DETECTION_LEVEL
) {
747 ad714x
->sensor_val
[hw
->y_start_stage
+ 1];
750 if ((percent_sensor_diff
< TOP_END_POINT_DETECTION_LEVEL
) &&
751 (ad714x
->sensor_val
[hw
->y_start_stage
+ 1] >
752 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL
+ sw
->top_ep_val
))
756 /* bottom endpoint detect */
757 percent_sensor_diff
= (ad714x
->sensor_val
[hw
->y_end_stage
] -
758 ad714x
->sensor_val
[hw
->y_end_stage
- 1]) * 100 /
759 ad714x
->sensor_val
[hw
->y_end_stage
- 1];
760 if (!sw
->bottom_ep
) {
761 if (percent_sensor_diff
>= BOTTOM_END_POINT_DETECTION_LEVEL
) {
764 ad714x
->sensor_val
[hw
->y_end_stage
- 1];
767 if ((percent_sensor_diff
< BOTTOM_END_POINT_DETECTION_LEVEL
) &&
768 (ad714x
->sensor_val
[hw
->y_end_stage
- 1] >
769 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL
+ sw
->bottom_ep_val
))
773 return sw
->left_ep
|| sw
->right_ep
|| sw
->top_ep
|| sw
->bottom_ep
;
776 static void touchpad_use_com_int(struct ad714x_chip
*ad714x
, int idx
)
778 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
780 ad714x_use_com_int(ad714x
, hw
->x_start_stage
, hw
->x_end_stage
);
783 static void touchpad_use_thr_int(struct ad714x_chip
*ad714x
, int idx
)
785 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
787 ad714x_use_thr_int(ad714x
, hw
->x_start_stage
, hw
->x_end_stage
);
788 ad714x_use_thr_int(ad714x
, hw
->y_start_stage
, hw
->y_end_stage
);
791 static void ad714x_touchpad_state_machine(struct ad714x_chip
*ad714x
, int idx
)
793 struct ad714x_touchpad_plat
*hw
= &ad714x
->hw
->touchpad
[idx
];
794 struct ad714x_touchpad_drv
*sw
= &ad714x
->sw
->touchpad
[idx
];
795 unsigned short h_state
, c_state
;
798 mask
= (((1 << (hw
->x_end_stage
+ 1)) - 1) -
799 ((1 << hw
->x_start_stage
) - 1)) +
800 (((1 << (hw
->y_end_stage
+ 1)) - 1) -
801 ((1 << hw
->y_start_stage
) - 1));
803 h_state
= ad714x
->h_state
& mask
;
804 c_state
= ad714x
->c_state
& mask
;
810 /* In End of Conversion interrupt mode, the AD714X
811 * continuously generates hardware interrupts.
813 touchpad_use_com_int(ad714x
, idx
);
814 dev_dbg(ad714x
->dev
, "touchpad %d touched\n", idx
);
819 if (c_state
== mask
) {
820 touchpad_cal_sensor_val(ad714x
, idx
);
821 touchpad_cal_highest_stage(ad714x
, idx
);
822 if ((!touchpad_check_second_peak(ad714x
, idx
)) &&
823 (!touchpad_check_endpoint(ad714x
, idx
))) {
825 "touchpad%d, 2 fingers or endpoint\n",
827 touchpad_cal_abs_pos(ad714x
, idx
);
828 sw
->x_flt_pos
= sw
->x_abs_pos
;
829 sw
->y_flt_pos
= sw
->y_abs_pos
;
836 if (c_state
== mask
) {
838 touchpad_cal_sensor_val(ad714x
, idx
);
839 touchpad_cal_highest_stage(ad714x
, idx
);
840 if ((!touchpad_check_second_peak(ad714x
, idx
))
841 && (!touchpad_check_endpoint(ad714x
, idx
))) {
842 touchpad_cal_abs_pos(ad714x
, idx
);
843 touchpad_cal_flt_pos(ad714x
, idx
);
844 input_report_abs(sw
->input
, ABS_X
,
846 input_report_abs(sw
->input
, ABS_Y
,
848 input_report_key(sw
->input
, BTN_TOUCH
,
852 /* When the user lifts off the sensor, configure
853 * the AD714X back to threshold interrupt mode.
855 touchpad_use_thr_int(ad714x
, idx
);
857 input_report_key(sw
->input
, BTN_TOUCH
, 0);
858 dev_dbg(ad714x
->dev
, "touchpad %d released\n",
861 input_sync(sw
->input
);
870 static int ad714x_hw_detect(struct ad714x_chip
*ad714x
)
874 ad714x
->read(ad714x
, AD714X_PARTID_REG
, &data
, 1);
875 switch (data
& 0xFFF0) {
877 ad714x
->product
= 0x7142;
878 ad714x
->version
= data
& 0xF;
879 dev_info(ad714x
->dev
, "found AD7142 captouch, rev:%d\n",
884 ad714x
->product
= 0x7143;
885 ad714x
->version
= data
& 0xF;
886 dev_info(ad714x
->dev
, "found AD7143 captouch, rev:%d\n",
891 ad714x
->product
= 0x7147;
892 ad714x
->version
= data
& 0xF;
893 dev_info(ad714x
->dev
, "found AD7147(A) captouch, rev:%d\n",
898 ad714x
->product
= 0x7148;
899 ad714x
->version
= data
& 0xF;
900 dev_info(ad714x
->dev
, "found AD7148 captouch, rev:%d\n",
906 "fail to detect AD714X captouch, read ID is %04x\n",
912 static void ad714x_hw_init(struct ad714x_chip
*ad714x
)
915 unsigned short reg_base
;
918 /* configuration CDC and interrupts */
920 for (i
= 0; i
< STAGE_NUM
; i
++) {
921 reg_base
= AD714X_STAGECFG_REG
+ i
* STAGE_CFGREG_NUM
;
922 for (j
= 0; j
< STAGE_CFGREG_NUM
; j
++)
923 ad714x
->write(ad714x
, reg_base
+ j
,
924 ad714x
->hw
->stage_cfg_reg
[i
][j
]);
927 for (i
= 0; i
< SYS_CFGREG_NUM
; i
++)
928 ad714x
->write(ad714x
, AD714X_SYSCFG_REG
+ i
,
929 ad714x
->hw
->sys_cfg_reg
[i
]);
930 for (i
= 0; i
< SYS_CFGREG_NUM
; i
++)
931 ad714x
->read(ad714x
, AD714X_SYSCFG_REG
+ i
, &data
, 1);
933 ad714x
->write(ad714x
, AD714X_STG_CAL_EN_REG
, 0xFFF);
935 /* clear all interrupts */
936 ad714x
->read(ad714x
, STG_LOW_INT_STA_REG
, &ad714x
->l_state
, 3);
939 static irqreturn_t
ad714x_interrupt_thread(int irq
, void *data
)
941 struct ad714x_chip
*ad714x
= data
;
944 mutex_lock(&ad714x
->mutex
);
946 ad714x
->read(ad714x
, STG_LOW_INT_STA_REG
, &ad714x
->l_state
, 3);
948 for (i
= 0; i
< ad714x
->hw
->button_num
; i
++)
949 ad714x_button_state_machine(ad714x
, i
);
950 for (i
= 0; i
< ad714x
->hw
->slider_num
; i
++)
951 ad714x_slider_state_machine(ad714x
, i
);
952 for (i
= 0; i
< ad714x
->hw
->wheel_num
; i
++)
953 ad714x_wheel_state_machine(ad714x
, i
);
954 for (i
= 0; i
< ad714x
->hw
->touchpad_num
; i
++)
955 ad714x_touchpad_state_machine(ad714x
, i
);
957 mutex_unlock(&ad714x
->mutex
);
962 struct ad714x_chip
*ad714x_probe(struct device
*dev
, u16 bus_type
, int irq
,
963 ad714x_read_t read
, ad714x_write_t write
)
967 struct input_dev
*input
;
969 struct ad714x_platform_data
*plat_data
= dev_get_platdata(dev
);
970 struct ad714x_chip
*ad714x
;
972 unsigned long irqflags
;
974 struct ad714x_button_drv
*bt_drv
;
975 struct ad714x_slider_drv
*sd_drv
;
976 struct ad714x_wheel_drv
*wl_drv
;
977 struct ad714x_touchpad_drv
*tp_drv
;
981 dev_err(dev
, "IRQ not configured!\n");
983 return ERR_PTR(error
);
986 if (dev_get_platdata(dev
) == NULL
) {
987 dev_err(dev
, "platform data for ad714x doesn't exist\n");
989 return ERR_PTR(error
);
992 ad714x
= devm_kzalloc(dev
, sizeof(*ad714x
) + sizeof(*ad714x
->sw
) +
993 sizeof(*sd_drv
) * plat_data
->slider_num
+
994 sizeof(*wl_drv
) * plat_data
->wheel_num
+
995 sizeof(*tp_drv
) * plat_data
->touchpad_num
+
996 sizeof(*bt_drv
) * plat_data
->button_num
,
1000 return ERR_PTR(error
);
1002 ad714x
->hw
= plat_data
;
1004 drv_mem
= ad714x
+ 1;
1005 ad714x
->sw
= drv_mem
;
1006 drv_mem
+= sizeof(*ad714x
->sw
);
1007 ad714x
->sw
->slider
= sd_drv
= drv_mem
;
1008 drv_mem
+= sizeof(*sd_drv
) * ad714x
->hw
->slider_num
;
1009 ad714x
->sw
->wheel
= wl_drv
= drv_mem
;
1010 drv_mem
+= sizeof(*wl_drv
) * ad714x
->hw
->wheel_num
;
1011 ad714x
->sw
->touchpad
= tp_drv
= drv_mem
;
1012 drv_mem
+= sizeof(*tp_drv
) * ad714x
->hw
->touchpad_num
;
1013 ad714x
->sw
->button
= bt_drv
= drv_mem
;
1014 drv_mem
+= sizeof(*bt_drv
) * ad714x
->hw
->button_num
;
1016 ad714x
->read
= read
;
1017 ad714x
->write
= write
;
1021 error
= ad714x_hw_detect(ad714x
);
1023 return ERR_PTR(error
);
1025 /* initialize and request sw/hw resources */
1027 ad714x_hw_init(ad714x
);
1028 mutex_init(&ad714x
->mutex
);
1030 /* a slider uses one input_dev instance */
1031 if (ad714x
->hw
->slider_num
> 0) {
1032 struct ad714x_slider_plat
*sd_plat
= ad714x
->hw
->slider
;
1034 for (i
= 0; i
< ad714x
->hw
->slider_num
; i
++) {
1035 input
= devm_input_allocate_device(dev
);
1037 return ERR_PTR(-ENOMEM
);
1039 __set_bit(EV_ABS
, input
->evbit
);
1040 __set_bit(EV_KEY
, input
->evbit
);
1041 __set_bit(ABS_X
, input
->absbit
);
1042 __set_bit(BTN_TOUCH
, input
->keybit
);
1043 input_set_abs_params(input
,
1044 ABS_X
, 0, sd_plat
->max_coord
, 0, 0);
1046 input
->id
.bustype
= bus_type
;
1047 input
->id
.product
= ad714x
->product
;
1048 input
->id
.version
= ad714x
->version
;
1049 input
->name
= "ad714x_captouch_slider";
1050 input
->dev
.parent
= dev
;
1052 error
= input_register_device(input
);
1054 return ERR_PTR(error
);
1056 sd_drv
[i
].input
= input
;
1060 /* a wheel uses one input_dev instance */
1061 if (ad714x
->hw
->wheel_num
> 0) {
1062 struct ad714x_wheel_plat
*wl_plat
= ad714x
->hw
->wheel
;
1064 for (i
= 0; i
< ad714x
->hw
->wheel_num
; i
++) {
1065 input
= devm_input_allocate_device(dev
);
1067 return ERR_PTR(-ENOMEM
);
1069 __set_bit(EV_KEY
, input
->evbit
);
1070 __set_bit(EV_ABS
, input
->evbit
);
1071 __set_bit(ABS_WHEEL
, input
->absbit
);
1072 __set_bit(BTN_TOUCH
, input
->keybit
);
1073 input_set_abs_params(input
,
1074 ABS_WHEEL
, 0, wl_plat
->max_coord
, 0, 0);
1076 input
->id
.bustype
= bus_type
;
1077 input
->id
.product
= ad714x
->product
;
1078 input
->id
.version
= ad714x
->version
;
1079 input
->name
= "ad714x_captouch_wheel";
1080 input
->dev
.parent
= dev
;
1082 error
= input_register_device(input
);
1084 return ERR_PTR(error
);
1086 wl_drv
[i
].input
= input
;
1090 /* a touchpad uses one input_dev instance */
1091 if (ad714x
->hw
->touchpad_num
> 0) {
1092 struct ad714x_touchpad_plat
*tp_plat
= ad714x
->hw
->touchpad
;
1094 for (i
= 0; i
< ad714x
->hw
->touchpad_num
; i
++) {
1095 input
= devm_input_allocate_device(dev
);
1097 return ERR_PTR(-ENOMEM
);
1099 __set_bit(EV_ABS
, input
->evbit
);
1100 __set_bit(EV_KEY
, input
->evbit
);
1101 __set_bit(ABS_X
, input
->absbit
);
1102 __set_bit(ABS_Y
, input
->absbit
);
1103 __set_bit(BTN_TOUCH
, input
->keybit
);
1104 input_set_abs_params(input
,
1105 ABS_X
, 0, tp_plat
->x_max_coord
, 0, 0);
1106 input_set_abs_params(input
,
1107 ABS_Y
, 0, tp_plat
->y_max_coord
, 0, 0);
1109 input
->id
.bustype
= bus_type
;
1110 input
->id
.product
= ad714x
->product
;
1111 input
->id
.version
= ad714x
->version
;
1112 input
->name
= "ad714x_captouch_pad";
1113 input
->dev
.parent
= dev
;
1115 error
= input_register_device(input
);
1117 return ERR_PTR(error
);
1119 tp_drv
[i
].input
= input
;
1123 /* all buttons use one input node */
1124 if (ad714x
->hw
->button_num
> 0) {
1125 struct ad714x_button_plat
*bt_plat
= ad714x
->hw
->button
;
1127 input
= devm_input_allocate_device(dev
);
1130 return ERR_PTR(error
);
1133 __set_bit(EV_KEY
, input
->evbit
);
1134 for (i
= 0; i
< ad714x
->hw
->button_num
; i
++) {
1135 bt_drv
[i
].input
= input
;
1136 __set_bit(bt_plat
[i
].keycode
, input
->keybit
);
1139 input
->id
.bustype
= bus_type
;
1140 input
->id
.product
= ad714x
->product
;
1141 input
->id
.version
= ad714x
->version
;
1142 input
->name
= "ad714x_captouch_button";
1143 input
->dev
.parent
= dev
;
1145 error
= input_register_device(input
);
1147 return ERR_PTR(error
);
1150 irqflags
= plat_data
->irqflags
?: IRQF_TRIGGER_FALLING
;
1151 irqflags
|= IRQF_ONESHOT
;
1153 error
= devm_request_threaded_irq(dev
, ad714x
->irq
, NULL
,
1154 ad714x_interrupt_thread
,
1155 irqflags
, "ad714x_captouch", ad714x
);
1157 dev_err(dev
, "can't allocate irq %d\n", ad714x
->irq
);
1158 return ERR_PTR(error
);
1163 EXPORT_SYMBOL(ad714x_probe
);
1166 int ad714x_disable(struct ad714x_chip
*ad714x
)
1168 unsigned short data
;
1170 dev_dbg(ad714x
->dev
, "%s enter\n", __func__
);
1172 mutex_lock(&ad714x
->mutex
);
1174 data
= ad714x
->hw
->sys_cfg_reg
[AD714X_PWR_CTRL
] | 0x3;
1175 ad714x
->write(ad714x
, AD714X_PWR_CTRL
, data
);
1177 mutex_unlock(&ad714x
->mutex
);
1181 EXPORT_SYMBOL(ad714x_disable
);
1183 int ad714x_enable(struct ad714x_chip
*ad714x
)
1185 dev_dbg(ad714x
->dev
, "%s enter\n", __func__
);
1187 mutex_lock(&ad714x
->mutex
);
1189 /* resume to non-shutdown mode */
1191 ad714x
->write(ad714x
, AD714X_PWR_CTRL
,
1192 ad714x
->hw
->sys_cfg_reg
[AD714X_PWR_CTRL
]);
1194 /* make sure the interrupt output line is not low level after resume,
1195 * otherwise we will get no chance to enter falling-edge irq again
1198 ad714x
->read(ad714x
, STG_LOW_INT_STA_REG
, &ad714x
->l_state
, 3);
1200 mutex_unlock(&ad714x
->mutex
);
1204 EXPORT_SYMBOL(ad714x_enable
);
1207 MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor Driver");
1208 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
1209 MODULE_LICENSE("GPL");