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