0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/input.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/slab.h>
0012 #include <linux/input/ad714x.h>
0013 #include <linux/module.h>
0014 #include "ad714x.h"
0015
0016 #define AD714X_PWR_CTRL 0x0
0017 #define AD714X_STG_CAL_EN_REG 0x1
0018 #define AD714X_AMB_COMP_CTRL0_REG 0x2
0019 #define AD714X_PARTID_REG 0x17
0020 #define AD7142_PARTID 0xE620
0021 #define AD7143_PARTID 0xE630
0022 #define AD7147_PARTID 0x1470
0023 #define AD7148_PARTID 0x1480
0024 #define AD714X_STAGECFG_REG 0x80
0025 #define AD714X_SYSCFG_REG 0x0
0026
0027 #define STG_LOW_INT_EN_REG 0x5
0028 #define STG_HIGH_INT_EN_REG 0x6
0029 #define STG_COM_INT_EN_REG 0x7
0030 #define STG_LOW_INT_STA_REG 0x8
0031 #define STG_HIGH_INT_STA_REG 0x9
0032 #define STG_COM_INT_STA_REG 0xA
0033
0034 #define CDC_RESULT_S0 0xB
0035 #define CDC_RESULT_S1 0xC
0036 #define CDC_RESULT_S2 0xD
0037 #define CDC_RESULT_S3 0xE
0038 #define CDC_RESULT_S4 0xF
0039 #define CDC_RESULT_S5 0x10
0040 #define CDC_RESULT_S6 0x11
0041 #define CDC_RESULT_S7 0x12
0042 #define CDC_RESULT_S8 0x13
0043 #define CDC_RESULT_S9 0x14
0044 #define CDC_RESULT_S10 0x15
0045 #define CDC_RESULT_S11 0x16
0046
0047 #define STAGE0_AMBIENT 0xF1
0048 #define STAGE1_AMBIENT 0x115
0049 #define STAGE2_AMBIENT 0x139
0050 #define STAGE3_AMBIENT 0x15D
0051 #define STAGE4_AMBIENT 0x181
0052 #define STAGE5_AMBIENT 0x1A5
0053 #define STAGE6_AMBIENT 0x1C9
0054 #define STAGE7_AMBIENT 0x1ED
0055 #define STAGE8_AMBIENT 0x211
0056 #define STAGE9_AMBIENT 0x234
0057 #define STAGE10_AMBIENT 0x259
0058 #define STAGE11_AMBIENT 0x27D
0059
0060 #define PER_STAGE_REG_NUM 36
0061 #define STAGE_CFGREG_NUM 8
0062 #define SYS_CFGREG_NUM 8
0063
0064
0065
0066
0067 enum ad714x_device_state { IDLE, JITTER, ACTIVE, SPACE };
0068
0069 struct ad714x_slider_drv {
0070 int highest_stage;
0071 int abs_pos;
0072 int flt_pos;
0073 enum ad714x_device_state state;
0074 struct input_dev *input;
0075 };
0076
0077 struct ad714x_wheel_drv {
0078 int abs_pos;
0079 int flt_pos;
0080 int pre_highest_stage;
0081 int highest_stage;
0082 enum ad714x_device_state state;
0083 struct input_dev *input;
0084 };
0085
0086 struct ad714x_touchpad_drv {
0087 int x_highest_stage;
0088 int x_flt_pos;
0089 int x_abs_pos;
0090 int y_highest_stage;
0091 int y_flt_pos;
0092 int y_abs_pos;
0093 int left_ep;
0094 int left_ep_val;
0095 int right_ep;
0096 int right_ep_val;
0097 int top_ep;
0098 int top_ep_val;
0099 int bottom_ep;
0100 int bottom_ep_val;
0101 enum ad714x_device_state state;
0102 struct input_dev *input;
0103 };
0104
0105 struct ad714x_button_drv {
0106 enum ad714x_device_state state;
0107
0108
0109
0110
0111 struct input_dev *input;
0112 };
0113
0114 struct ad714x_driver_data {
0115 struct ad714x_slider_drv *slider;
0116 struct ad714x_wheel_drv *wheel;
0117 struct ad714x_touchpad_drv *touchpad;
0118 struct ad714x_button_drv *button;
0119 };
0120
0121
0122
0123
0124
0125
0126 static void ad714x_use_com_int(struct ad714x_chip *ad714x,
0127 int start_stage, int end_stage)
0128 {
0129 unsigned short data;
0130 unsigned short mask;
0131
0132 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
0133
0134 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
0135 data |= 1 << end_stage;
0136 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
0137
0138 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
0139 data &= ~mask;
0140 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
0141 }
0142
0143 static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
0144 int start_stage, int end_stage)
0145 {
0146 unsigned short data;
0147 unsigned short mask;
0148
0149 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
0150
0151 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
0152 data &= ~(1 << end_stage);
0153 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
0154
0155 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
0156 data |= mask;
0157 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
0158 }
0159
0160 static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
0161 int start_stage, int end_stage)
0162 {
0163 int max_res = 0;
0164 int max_idx = 0;
0165 int i;
0166
0167 for (i = start_stage; i <= end_stage; i++) {
0168 if (ad714x->sensor_val[i] > max_res) {
0169 max_res = ad714x->sensor_val[i];
0170 max_idx = i;
0171 }
0172 }
0173
0174 return max_idx;
0175 }
0176
0177 static int ad714x_cal_abs_pos(struct ad714x_chip *ad714x,
0178 int start_stage, int end_stage,
0179 int highest_stage, int max_coord)
0180 {
0181 int a_param, b_param;
0182
0183 if (highest_stage == start_stage) {
0184 a_param = ad714x->sensor_val[start_stage + 1];
0185 b_param = ad714x->sensor_val[start_stage] +
0186 ad714x->sensor_val[start_stage + 1];
0187 } else if (highest_stage == end_stage) {
0188 a_param = ad714x->sensor_val[end_stage] *
0189 (end_stage - start_stage) +
0190 ad714x->sensor_val[end_stage - 1] *
0191 (end_stage - start_stage - 1);
0192 b_param = ad714x->sensor_val[end_stage] +
0193 ad714x->sensor_val[end_stage - 1];
0194 } else {
0195 a_param = ad714x->sensor_val[highest_stage] *
0196 (highest_stage - start_stage) +
0197 ad714x->sensor_val[highest_stage - 1] *
0198 (highest_stage - start_stage - 1) +
0199 ad714x->sensor_val[highest_stage + 1] *
0200 (highest_stage - start_stage + 1);
0201 b_param = ad714x->sensor_val[highest_stage] +
0202 ad714x->sensor_val[highest_stage - 1] +
0203 ad714x->sensor_val[highest_stage + 1];
0204 }
0205
0206 return (max_coord / (end_stage - start_stage)) * a_param / b_param;
0207 }
0208
0209
0210
0211
0212
0213 static void ad714x_button_state_machine(struct ad714x_chip *ad714x, int idx)
0214 {
0215 struct ad714x_button_plat *hw = &ad714x->hw->button[idx];
0216 struct ad714x_button_drv *sw = &ad714x->sw->button[idx];
0217
0218 switch (sw->state) {
0219 case IDLE:
0220 if (((ad714x->h_state & hw->h_mask) == hw->h_mask) &&
0221 ((ad714x->l_state & hw->l_mask) == hw->l_mask)) {
0222 dev_dbg(ad714x->dev, "button %d touched\n", idx);
0223 input_report_key(sw->input, hw->keycode, 1);
0224 input_sync(sw->input);
0225 sw->state = ACTIVE;
0226 }
0227 break;
0228
0229 case ACTIVE:
0230 if (((ad714x->h_state & hw->h_mask) != hw->h_mask) ||
0231 ((ad714x->l_state & hw->l_mask) != hw->l_mask)) {
0232 dev_dbg(ad714x->dev, "button %d released\n", idx);
0233 input_report_key(sw->input, hw->keycode, 0);
0234 input_sync(sw->input);
0235 sw->state = IDLE;
0236 }
0237 break;
0238
0239 default:
0240 break;
0241 }
0242 }
0243
0244
0245
0246
0247
0248 static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
0249 {
0250 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0251 int i;
0252
0253 ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
0254 &ad714x->adc_reg[hw->start_stage],
0255 hw->end_stage - hw->start_stage + 1);
0256
0257 for (i = hw->start_stage; i <= hw->end_stage; i++) {
0258 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
0259 &ad714x->amb_reg[i], 1);
0260
0261 ad714x->sensor_val[i] =
0262 abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
0263 }
0264 }
0265
0266 static void ad714x_slider_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
0267 {
0268 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0269 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
0270
0271 sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
0272 hw->end_stage);
0273
0274 dev_dbg(ad714x->dev, "slider %d highest_stage:%d\n", idx,
0275 sw->highest_stage);
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 static void ad714x_slider_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
0292 {
0293 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0294 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
0295
0296 sw->abs_pos = ad714x_cal_abs_pos(ad714x, hw->start_stage, hw->end_stage,
0297 sw->highest_stage, hw->max_coord);
0298
0299 dev_dbg(ad714x->dev, "slider %d absolute position:%d\n", idx,
0300 sw->abs_pos);
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313 static void ad714x_slider_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
0314 {
0315 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
0316
0317 sw->flt_pos = (sw->flt_pos * (10 - 4) +
0318 sw->abs_pos * 4)/10;
0319
0320 dev_dbg(ad714x->dev, "slider %d filter position:%d\n", idx,
0321 sw->flt_pos);
0322 }
0323
0324 static void ad714x_slider_use_com_int(struct ad714x_chip *ad714x, int idx)
0325 {
0326 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0327
0328 ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
0329 }
0330
0331 static void ad714x_slider_use_thr_int(struct ad714x_chip *ad714x, int idx)
0332 {
0333 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0334
0335 ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
0336 }
0337
0338 static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx)
0339 {
0340 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
0341 struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
0342 unsigned short h_state, c_state;
0343 unsigned short mask;
0344
0345 mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
0346
0347 h_state = ad714x->h_state & mask;
0348 c_state = ad714x->c_state & mask;
0349
0350 switch (sw->state) {
0351 case IDLE:
0352 if (h_state) {
0353 sw->state = JITTER;
0354
0355
0356
0357 ad714x_slider_use_com_int(ad714x, idx);
0358 dev_dbg(ad714x->dev, "slider %d touched\n", idx);
0359 }
0360 break;
0361
0362 case JITTER:
0363 if (c_state == mask) {
0364 ad714x_slider_cal_sensor_val(ad714x, idx);
0365 ad714x_slider_cal_highest_stage(ad714x, idx);
0366 ad714x_slider_cal_abs_pos(ad714x, idx);
0367 sw->flt_pos = sw->abs_pos;
0368 sw->state = ACTIVE;
0369 }
0370 break;
0371
0372 case ACTIVE:
0373 if (c_state == mask) {
0374 if (h_state) {
0375 ad714x_slider_cal_sensor_val(ad714x, idx);
0376 ad714x_slider_cal_highest_stage(ad714x, idx);
0377 ad714x_slider_cal_abs_pos(ad714x, idx);
0378 ad714x_slider_cal_flt_pos(ad714x, idx);
0379 input_report_abs(sw->input, ABS_X, sw->flt_pos);
0380 input_report_key(sw->input, BTN_TOUCH, 1);
0381 } else {
0382
0383
0384
0385 ad714x_slider_use_thr_int(ad714x, idx);
0386 sw->state = IDLE;
0387 input_report_key(sw->input, BTN_TOUCH, 0);
0388 dev_dbg(ad714x->dev, "slider %d released\n",
0389 idx);
0390 }
0391 input_sync(sw->input);
0392 }
0393 break;
0394
0395 default:
0396 break;
0397 }
0398 }
0399
0400
0401
0402
0403
0404
0405
0406
0407 static void ad714x_wheel_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
0408 {
0409 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0410 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
0411
0412 sw->pre_highest_stage = sw->highest_stage;
0413 sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
0414 hw->end_stage);
0415
0416 dev_dbg(ad714x->dev, "wheel %d highest_stage:%d\n", idx,
0417 sw->highest_stage);
0418 }
0419
0420 static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
0421 {
0422 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0423 int i;
0424
0425 ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
0426 &ad714x->adc_reg[hw->start_stage],
0427 hw->end_stage - hw->start_stage + 1);
0428
0429 for (i = hw->start_stage; i <= hw->end_stage; i++) {
0430 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
0431 &ad714x->amb_reg[i], 1);
0432 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
0433 ad714x->sensor_val[i] =
0434 ad714x->adc_reg[i] - ad714x->amb_reg[i];
0435 else
0436 ad714x->sensor_val[i] = 0;
0437 }
0438 }
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
0450 {
0451 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0452 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
0453 int stage_num = hw->end_stage - hw->start_stage + 1;
0454 int first_before, highest, first_after;
0455 int a_param, b_param;
0456
0457 first_before = (sw->highest_stage + stage_num - 1) % stage_num;
0458 highest = sw->highest_stage;
0459 first_after = (sw->highest_stage + stage_num + 1) % stage_num;
0460
0461 a_param = ad714x->sensor_val[highest] *
0462 (highest - hw->start_stage) +
0463 ad714x->sensor_val[first_before] *
0464 (highest - hw->start_stage - 1) +
0465 ad714x->sensor_val[first_after] *
0466 (highest - hw->start_stage + 1);
0467 b_param = ad714x->sensor_val[highest] +
0468 ad714x->sensor_val[first_before] +
0469 ad714x->sensor_val[first_after];
0470
0471 sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) *
0472 a_param) / b_param;
0473
0474 if (sw->abs_pos > hw->max_coord)
0475 sw->abs_pos = hw->max_coord;
0476 else if (sw->abs_pos < 0)
0477 sw->abs_pos = 0;
0478 }
0479
0480 static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
0481 {
0482 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0483 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
0484 if (((sw->pre_highest_stage == hw->end_stage) &&
0485 (sw->highest_stage == hw->start_stage)) ||
0486 ((sw->pre_highest_stage == hw->start_stage) &&
0487 (sw->highest_stage == hw->end_stage)))
0488 sw->flt_pos = sw->abs_pos;
0489 else
0490 sw->flt_pos = ((sw->flt_pos * 30) + (sw->abs_pos * 71)) / 100;
0491
0492 if (sw->flt_pos > hw->max_coord)
0493 sw->flt_pos = hw->max_coord;
0494 }
0495
0496 static void ad714x_wheel_use_com_int(struct ad714x_chip *ad714x, int idx)
0497 {
0498 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0499
0500 ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
0501 }
0502
0503 static void ad714x_wheel_use_thr_int(struct ad714x_chip *ad714x, int idx)
0504 {
0505 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0506
0507 ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
0508 }
0509
0510 static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx)
0511 {
0512 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
0513 struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
0514 unsigned short h_state, c_state;
0515 unsigned short mask;
0516
0517 mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
0518
0519 h_state = ad714x->h_state & mask;
0520 c_state = ad714x->c_state & mask;
0521
0522 switch (sw->state) {
0523 case IDLE:
0524 if (h_state) {
0525 sw->state = JITTER;
0526
0527
0528
0529 ad714x_wheel_use_com_int(ad714x, idx);
0530 dev_dbg(ad714x->dev, "wheel %d touched\n", idx);
0531 }
0532 break;
0533
0534 case JITTER:
0535 if (c_state == mask) {
0536 ad714x_wheel_cal_sensor_val(ad714x, idx);
0537 ad714x_wheel_cal_highest_stage(ad714x, idx);
0538 ad714x_wheel_cal_abs_pos(ad714x, idx);
0539 sw->flt_pos = sw->abs_pos;
0540 sw->state = ACTIVE;
0541 }
0542 break;
0543
0544 case ACTIVE:
0545 if (c_state == mask) {
0546 if (h_state) {
0547 ad714x_wheel_cal_sensor_val(ad714x, idx);
0548 ad714x_wheel_cal_highest_stage(ad714x, idx);
0549 ad714x_wheel_cal_abs_pos(ad714x, idx);
0550 ad714x_wheel_cal_flt_pos(ad714x, idx);
0551 input_report_abs(sw->input, ABS_WHEEL,
0552 sw->flt_pos);
0553 input_report_key(sw->input, BTN_TOUCH, 1);
0554 } else {
0555
0556
0557
0558 ad714x_wheel_use_thr_int(ad714x, idx);
0559 sw->state = IDLE;
0560 input_report_key(sw->input, BTN_TOUCH, 0);
0561
0562 dev_dbg(ad714x->dev, "wheel %d released\n",
0563 idx);
0564 }
0565 input_sync(sw->input);
0566 }
0567 break;
0568
0569 default:
0570 break;
0571 }
0572 }
0573
0574 static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
0575 {
0576 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0577 int i;
0578
0579 ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
0580 &ad714x->adc_reg[hw->x_start_stage],
0581 hw->x_end_stage - hw->x_start_stage + 1);
0582
0583 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
0584 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
0585 &ad714x->amb_reg[i], 1);
0586 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
0587 ad714x->sensor_val[i] =
0588 ad714x->adc_reg[i] - ad714x->amb_reg[i];
0589 else
0590 ad714x->sensor_val[i] = 0;
0591 }
0592 }
0593
0594 static void touchpad_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
0595 {
0596 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0597 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0598
0599 sw->x_highest_stage = ad714x_cal_highest_stage(ad714x,
0600 hw->x_start_stage, hw->x_end_stage);
0601 sw->y_highest_stage = ad714x_cal_highest_stage(ad714x,
0602 hw->y_start_stage, hw->y_end_stage);
0603
0604 dev_dbg(ad714x->dev,
0605 "touchpad %d x_highest_stage:%d, y_highest_stage:%d\n",
0606 idx, sw->x_highest_stage, sw->y_highest_stage);
0607 }
0608
0609
0610
0611
0612
0613
0614
0615 static int touchpad_check_second_peak(struct ad714x_chip *ad714x, int idx)
0616 {
0617 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0618 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0619 int i;
0620
0621 for (i = hw->x_start_stage; i < sw->x_highest_stage; i++) {
0622 if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
0623 > (ad714x->sensor_val[i + 1] / 10))
0624 return 1;
0625 }
0626
0627 for (i = sw->x_highest_stage; i < hw->x_end_stage; i++) {
0628 if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
0629 > (ad714x->sensor_val[i] / 10))
0630 return 1;
0631 }
0632
0633 for (i = hw->y_start_stage; i < sw->y_highest_stage; i++) {
0634 if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
0635 > (ad714x->sensor_val[i + 1] / 10))
0636 return 1;
0637 }
0638
0639 for (i = sw->y_highest_stage; i < hw->y_end_stage; i++) {
0640 if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
0641 > (ad714x->sensor_val[i] / 10))
0642 return 1;
0643 }
0644
0645 return 0;
0646 }
0647
0648
0649
0650
0651
0652
0653
0654 static void touchpad_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
0655 {
0656 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0657 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0658
0659 sw->x_abs_pos = ad714x_cal_abs_pos(ad714x, hw->x_start_stage,
0660 hw->x_end_stage, sw->x_highest_stage, hw->x_max_coord);
0661 sw->y_abs_pos = ad714x_cal_abs_pos(ad714x, hw->y_start_stage,
0662 hw->y_end_stage, sw->y_highest_stage, hw->y_max_coord);
0663
0664 dev_dbg(ad714x->dev, "touchpad %d absolute position:(%d, %d)\n", idx,
0665 sw->x_abs_pos, sw->y_abs_pos);
0666 }
0667
0668 static void touchpad_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
0669 {
0670 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0671
0672 sw->x_flt_pos = (sw->x_flt_pos * (10 - 4) +
0673 sw->x_abs_pos * 4)/10;
0674 sw->y_flt_pos = (sw->y_flt_pos * (10 - 4) +
0675 sw->y_abs_pos * 4)/10;
0676
0677 dev_dbg(ad714x->dev, "touchpad %d filter position:(%d, %d)\n",
0678 idx, sw->x_flt_pos, sw->y_flt_pos);
0679 }
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693 #define LEFT_END_POINT_DETECTION_LEVEL 550
0694 #define RIGHT_END_POINT_DETECTION_LEVEL 750
0695 #define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL 850
0696 #define TOP_END_POINT_DETECTION_LEVEL 550
0697 #define BOTTOM_END_POINT_DETECTION_LEVEL 950
0698 #define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL 700
0699 static int touchpad_check_endpoint(struct ad714x_chip *ad714x, int idx)
0700 {
0701 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0702 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0703 int percent_sensor_diff;
0704
0705
0706 percent_sensor_diff = (ad714x->sensor_val[hw->x_start_stage] -
0707 ad714x->sensor_val[hw->x_start_stage + 1]) * 100 /
0708 ad714x->sensor_val[hw->x_start_stage + 1];
0709 if (!sw->left_ep) {
0710 if (percent_sensor_diff >= LEFT_END_POINT_DETECTION_LEVEL) {
0711 sw->left_ep = 1;
0712 sw->left_ep_val =
0713 ad714x->sensor_val[hw->x_start_stage + 1];
0714 }
0715 } else {
0716 if ((percent_sensor_diff < LEFT_END_POINT_DETECTION_LEVEL) &&
0717 (ad714x->sensor_val[hw->x_start_stage + 1] >
0718 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->left_ep_val))
0719 sw->left_ep = 0;
0720 }
0721
0722
0723 percent_sensor_diff = (ad714x->sensor_val[hw->x_end_stage] -
0724 ad714x->sensor_val[hw->x_end_stage - 1]) * 100 /
0725 ad714x->sensor_val[hw->x_end_stage - 1];
0726 if (!sw->right_ep) {
0727 if (percent_sensor_diff >= RIGHT_END_POINT_DETECTION_LEVEL) {
0728 sw->right_ep = 1;
0729 sw->right_ep_val =
0730 ad714x->sensor_val[hw->x_end_stage - 1];
0731 }
0732 } else {
0733 if ((percent_sensor_diff < RIGHT_END_POINT_DETECTION_LEVEL) &&
0734 (ad714x->sensor_val[hw->x_end_stage - 1] >
0735 LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->right_ep_val))
0736 sw->right_ep = 0;
0737 }
0738
0739
0740 percent_sensor_diff = (ad714x->sensor_val[hw->y_start_stage] -
0741 ad714x->sensor_val[hw->y_start_stage + 1]) * 100 /
0742 ad714x->sensor_val[hw->y_start_stage + 1];
0743 if (!sw->top_ep) {
0744 if (percent_sensor_diff >= TOP_END_POINT_DETECTION_LEVEL) {
0745 sw->top_ep = 1;
0746 sw->top_ep_val =
0747 ad714x->sensor_val[hw->y_start_stage + 1];
0748 }
0749 } else {
0750 if ((percent_sensor_diff < TOP_END_POINT_DETECTION_LEVEL) &&
0751 (ad714x->sensor_val[hw->y_start_stage + 1] >
0752 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->top_ep_val))
0753 sw->top_ep = 0;
0754 }
0755
0756
0757 percent_sensor_diff = (ad714x->sensor_val[hw->y_end_stage] -
0758 ad714x->sensor_val[hw->y_end_stage - 1]) * 100 /
0759 ad714x->sensor_val[hw->y_end_stage - 1];
0760 if (!sw->bottom_ep) {
0761 if (percent_sensor_diff >= BOTTOM_END_POINT_DETECTION_LEVEL) {
0762 sw->bottom_ep = 1;
0763 sw->bottom_ep_val =
0764 ad714x->sensor_val[hw->y_end_stage - 1];
0765 }
0766 } else {
0767 if ((percent_sensor_diff < BOTTOM_END_POINT_DETECTION_LEVEL) &&
0768 (ad714x->sensor_val[hw->y_end_stage - 1] >
0769 TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->bottom_ep_val))
0770 sw->bottom_ep = 0;
0771 }
0772
0773 return sw->left_ep || sw->right_ep || sw->top_ep || sw->bottom_ep;
0774 }
0775
0776 static void touchpad_use_com_int(struct ad714x_chip *ad714x, int idx)
0777 {
0778 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0779
0780 ad714x_use_com_int(ad714x, hw->x_start_stage, hw->x_end_stage);
0781 }
0782
0783 static void touchpad_use_thr_int(struct ad714x_chip *ad714x, int idx)
0784 {
0785 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0786
0787 ad714x_use_thr_int(ad714x, hw->x_start_stage, hw->x_end_stage);
0788 ad714x_use_thr_int(ad714x, hw->y_start_stage, hw->y_end_stage);
0789 }
0790
0791 static void ad714x_touchpad_state_machine(struct ad714x_chip *ad714x, int idx)
0792 {
0793 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
0794 struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
0795 unsigned short h_state, c_state;
0796 unsigned short mask;
0797
0798 mask = (((1 << (hw->x_end_stage + 1)) - 1) -
0799 ((1 << hw->x_start_stage) - 1)) +
0800 (((1 << (hw->y_end_stage + 1)) - 1) -
0801 ((1 << hw->y_start_stage) - 1));
0802
0803 h_state = ad714x->h_state & mask;
0804 c_state = ad714x->c_state & mask;
0805
0806 switch (sw->state) {
0807 case IDLE:
0808 if (h_state) {
0809 sw->state = JITTER;
0810
0811
0812
0813 touchpad_use_com_int(ad714x, idx);
0814 dev_dbg(ad714x->dev, "touchpad %d touched\n", idx);
0815 }
0816 break;
0817
0818 case JITTER:
0819 if (c_state == mask) {
0820 touchpad_cal_sensor_val(ad714x, idx);
0821 touchpad_cal_highest_stage(ad714x, idx);
0822 if ((!touchpad_check_second_peak(ad714x, idx)) &&
0823 (!touchpad_check_endpoint(ad714x, idx))) {
0824 dev_dbg(ad714x->dev,
0825 "touchpad%d, 2 fingers or endpoint\n",
0826 idx);
0827 touchpad_cal_abs_pos(ad714x, idx);
0828 sw->x_flt_pos = sw->x_abs_pos;
0829 sw->y_flt_pos = sw->y_abs_pos;
0830 sw->state = ACTIVE;
0831 }
0832 }
0833 break;
0834
0835 case ACTIVE:
0836 if (c_state == mask) {
0837 if (h_state) {
0838 touchpad_cal_sensor_val(ad714x, idx);
0839 touchpad_cal_highest_stage(ad714x, idx);
0840 if ((!touchpad_check_second_peak(ad714x, idx))
0841 && (!touchpad_check_endpoint(ad714x, idx))) {
0842 touchpad_cal_abs_pos(ad714x, idx);
0843 touchpad_cal_flt_pos(ad714x, idx);
0844 input_report_abs(sw->input, ABS_X,
0845 sw->x_flt_pos);
0846 input_report_abs(sw->input, ABS_Y,
0847 sw->y_flt_pos);
0848 input_report_key(sw->input, BTN_TOUCH,
0849 1);
0850 }
0851 } else {
0852
0853
0854
0855 touchpad_use_thr_int(ad714x, idx);
0856 sw->state = IDLE;
0857 input_report_key(sw->input, BTN_TOUCH, 0);
0858 dev_dbg(ad714x->dev, "touchpad %d released\n",
0859 idx);
0860 }
0861 input_sync(sw->input);
0862 }
0863 break;
0864
0865 default:
0866 break;
0867 }
0868 }
0869
0870 static int ad714x_hw_detect(struct ad714x_chip *ad714x)
0871 {
0872 unsigned short data;
0873
0874 ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
0875 switch (data & 0xFFF0) {
0876 case AD7142_PARTID:
0877 ad714x->product = 0x7142;
0878 ad714x->version = data & 0xF;
0879 dev_info(ad714x->dev, "found AD7142 captouch, rev:%d\n",
0880 ad714x->version);
0881 return 0;
0882
0883 case AD7143_PARTID:
0884 ad714x->product = 0x7143;
0885 ad714x->version = data & 0xF;
0886 dev_info(ad714x->dev, "found AD7143 captouch, rev:%d\n",
0887 ad714x->version);
0888 return 0;
0889
0890 case AD7147_PARTID:
0891 ad714x->product = 0x7147;
0892 ad714x->version = data & 0xF;
0893 dev_info(ad714x->dev, "found AD7147(A) captouch, rev:%d\n",
0894 ad714x->version);
0895 return 0;
0896
0897 case AD7148_PARTID:
0898 ad714x->product = 0x7148;
0899 ad714x->version = data & 0xF;
0900 dev_info(ad714x->dev, "found AD7148 captouch, rev:%d\n",
0901 ad714x->version);
0902 return 0;
0903
0904 default:
0905 dev_err(ad714x->dev,
0906 "fail to detect AD714X captouch, read ID is %04x\n",
0907 data);
0908 return -ENODEV;
0909 }
0910 }
0911
0912 static void ad714x_hw_init(struct ad714x_chip *ad714x)
0913 {
0914 int i, j;
0915 unsigned short reg_base;
0916 unsigned short data;
0917
0918
0919
0920 for (i = 0; i < STAGE_NUM; i++) {
0921 reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
0922 for (j = 0; j < STAGE_CFGREG_NUM; j++)
0923 ad714x->write(ad714x, reg_base + j,
0924 ad714x->hw->stage_cfg_reg[i][j]);
0925 }
0926
0927 for (i = 0; i < SYS_CFGREG_NUM; i++)
0928 ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
0929 ad714x->hw->sys_cfg_reg[i]);
0930 for (i = 0; i < SYS_CFGREG_NUM; i++)
0931 ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
0932
0933 ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
0934
0935
0936 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
0937 }
0938
0939 static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
0940 {
0941 struct ad714x_chip *ad714x = data;
0942 int i;
0943
0944 mutex_lock(&ad714x->mutex);
0945
0946 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
0947
0948 for (i = 0; i < ad714x->hw->button_num; i++)
0949 ad714x_button_state_machine(ad714x, i);
0950 for (i = 0; i < ad714x->hw->slider_num; i++)
0951 ad714x_slider_state_machine(ad714x, i);
0952 for (i = 0; i < ad714x->hw->wheel_num; i++)
0953 ad714x_wheel_state_machine(ad714x, i);
0954 for (i = 0; i < ad714x->hw->touchpad_num; i++)
0955 ad714x_touchpad_state_machine(ad714x, i);
0956
0957 mutex_unlock(&ad714x->mutex);
0958
0959 return IRQ_HANDLED;
0960 }
0961
0962 struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq,
0963 ad714x_read_t read, ad714x_write_t write)
0964 {
0965 int i;
0966 int error;
0967 struct input_dev *input;
0968
0969 struct ad714x_platform_data *plat_data = dev_get_platdata(dev);
0970 struct ad714x_chip *ad714x;
0971 void *drv_mem;
0972 unsigned long irqflags;
0973
0974 struct ad714x_button_drv *bt_drv;
0975 struct ad714x_slider_drv *sd_drv;
0976 struct ad714x_wheel_drv *wl_drv;
0977 struct ad714x_touchpad_drv *tp_drv;
0978
0979
0980 if (irq <= 0) {
0981 dev_err(dev, "IRQ not configured!\n");
0982 error = -EINVAL;
0983 return ERR_PTR(error);
0984 }
0985
0986 if (dev_get_platdata(dev) == NULL) {
0987 dev_err(dev, "platform data for ad714x doesn't exist\n");
0988 error = -EINVAL;
0989 return ERR_PTR(error);
0990 }
0991
0992 ad714x = devm_kzalloc(dev, sizeof(*ad714x) + sizeof(*ad714x->sw) +
0993 sizeof(*sd_drv) * plat_data->slider_num +
0994 sizeof(*wl_drv) * plat_data->wheel_num +
0995 sizeof(*tp_drv) * plat_data->touchpad_num +
0996 sizeof(*bt_drv) * plat_data->button_num,
0997 GFP_KERNEL);
0998 if (!ad714x) {
0999 error = -ENOMEM;
1000 return ERR_PTR(error);
1001 }
1002 ad714x->hw = plat_data;
1003
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;
1015
1016 ad714x->read = read;
1017 ad714x->write = write;
1018 ad714x->irq = irq;
1019 ad714x->dev = dev;
1020
1021 error = ad714x_hw_detect(ad714x);
1022 if (error)
1023 return ERR_PTR(error);
1024
1025
1026
1027 ad714x_hw_init(ad714x);
1028 mutex_init(&ad714x->mutex);
1029
1030
1031 if (ad714x->hw->slider_num > 0) {
1032 struct ad714x_slider_plat *sd_plat = ad714x->hw->slider;
1033
1034 for (i = 0; i < ad714x->hw->slider_num; i++) {
1035 input = devm_input_allocate_device(dev);
1036 if (!input)
1037 return ERR_PTR(-ENOMEM);
1038
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);
1045
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;
1051
1052 error = input_register_device(input);
1053 if (error)
1054 return ERR_PTR(error);
1055
1056 sd_drv[i].input = input;
1057 }
1058 }
1059
1060
1061 if (ad714x->hw->wheel_num > 0) {
1062 struct ad714x_wheel_plat *wl_plat = ad714x->hw->wheel;
1063
1064 for (i = 0; i < ad714x->hw->wheel_num; i++) {
1065 input = devm_input_allocate_device(dev);
1066 if (!input)
1067 return ERR_PTR(-ENOMEM);
1068
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);
1075
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;
1081
1082 error = input_register_device(input);
1083 if (error)
1084 return ERR_PTR(error);
1085
1086 wl_drv[i].input = input;
1087 }
1088 }
1089
1090
1091 if (ad714x->hw->touchpad_num > 0) {
1092 struct ad714x_touchpad_plat *tp_plat = ad714x->hw->touchpad;
1093
1094 for (i = 0; i < ad714x->hw->touchpad_num; i++) {
1095 input = devm_input_allocate_device(dev);
1096 if (!input)
1097 return ERR_PTR(-ENOMEM);
1098
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);
1108
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;
1114
1115 error = input_register_device(input);
1116 if (error)
1117 return ERR_PTR(error);
1118
1119 tp_drv[i].input = input;
1120 }
1121 }
1122
1123
1124 if (ad714x->hw->button_num > 0) {
1125 struct ad714x_button_plat *bt_plat = ad714x->hw->button;
1126
1127 input = devm_input_allocate_device(dev);
1128 if (!input) {
1129 error = -ENOMEM;
1130 return ERR_PTR(error);
1131 }
1132
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);
1137 }
1138
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;
1144
1145 error = input_register_device(input);
1146 if (error)
1147 return ERR_PTR(error);
1148 }
1149
1150 irqflags = plat_data->irqflags ?: IRQF_TRIGGER_FALLING;
1151 irqflags |= IRQF_ONESHOT;
1152
1153 error = devm_request_threaded_irq(dev, ad714x->irq, NULL,
1154 ad714x_interrupt_thread,
1155 irqflags, "ad714x_captouch", ad714x);
1156 if (error) {
1157 dev_err(dev, "can't allocate irq %d\n", ad714x->irq);
1158 return ERR_PTR(error);
1159 }
1160
1161 return ad714x;
1162 }
1163 EXPORT_SYMBOL(ad714x_probe);
1164
1165 #ifdef CONFIG_PM
1166 int ad714x_disable(struct ad714x_chip *ad714x)
1167 {
1168 unsigned short data;
1169
1170 dev_dbg(ad714x->dev, "%s enter\n", __func__);
1171
1172 mutex_lock(&ad714x->mutex);
1173
1174 data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
1175 ad714x->write(ad714x, AD714X_PWR_CTRL, data);
1176
1177 mutex_unlock(&ad714x->mutex);
1178
1179 return 0;
1180 }
1181 EXPORT_SYMBOL(ad714x_disable);
1182
1183 int ad714x_enable(struct ad714x_chip *ad714x)
1184 {
1185 dev_dbg(ad714x->dev, "%s enter\n", __func__);
1186
1187 mutex_lock(&ad714x->mutex);
1188
1189
1190
1191 ad714x->write(ad714x, AD714X_PWR_CTRL,
1192 ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
1193
1194
1195
1196
1197
1198 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
1199
1200 mutex_unlock(&ad714x->mutex);
1201
1202 return 0;
1203 }
1204 EXPORT_SYMBOL(ad714x_enable);
1205 #endif
1206
1207 MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor Driver");
1208 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
1209 MODULE_LICENSE("GPL");