linux/drivers/input/mouse/cyapa.c
<<
>>
Prefs
   1/*
   2 * Cypress APA trackpad with I2C interface
   3 *
   4 * Author: Dudley Du <dudl@cypress.com>
   5 * Further cleanup and restructuring by:
   6 *   Daniel Kurtz <djkurtz@chromium.org>
   7 *   Benson Leung <bleung@chromium.org>
   8 *
   9 * Copyright (C) 2011-2014 Cypress Semiconductor, Inc.
  10 * Copyright (C) 2011-2012 Google, Inc.
  11 *
  12 * This file is subject to the terms and conditions of the GNU General Public
  13 * License.  See the file COPYING in the main directory of this archive for
  14 * more details.
  15 */
  16
  17#include <linux/delay.h>
  18#include <linux/i2c.h>
  19#include <linux/input.h>
  20#include <linux/input/mt.h>
  21#include <linux/interrupt.h>
  22#include <linux/module.h>
  23#include <linux/mutex.h>
  24#include <linux/slab.h>
  25#include <linux/uaccess.h>
  26#include <linux/pm_runtime.h>
  27#include <linux/acpi.h>
  28#include "cyapa.h"
  29
  30
  31#define CYAPA_ADAPTER_FUNC_NONE   0
  32#define CYAPA_ADAPTER_FUNC_I2C    1
  33#define CYAPA_ADAPTER_FUNC_SMBUS  2
  34#define CYAPA_ADAPTER_FUNC_BOTH   3
  35
  36#define CYAPA_FW_NAME           "cyapa.bin"
  37
  38const char product_id[] = "CYTRA";
  39
  40static int cyapa_reinitialize(struct cyapa *cyapa);
  41
  42static inline bool cyapa_is_bootloader_mode(struct cyapa *cyapa)
  43{
  44        if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_BL)
  45                return true;
  46
  47        if (cyapa->gen == CYAPA_GEN3 &&
  48                cyapa->state >= CYAPA_STATE_BL_BUSY &&
  49                cyapa->state <= CYAPA_STATE_BL_ACTIVE)
  50                return true;
  51
  52        return false;
  53}
  54
  55static inline bool cyapa_is_operational_mode(struct cyapa *cyapa)
  56{
  57        if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_APP)
  58                return true;
  59
  60        if (cyapa->gen == CYAPA_GEN3 && cyapa->state == CYAPA_STATE_OP)
  61                return true;
  62
  63        return false;
  64}
  65
  66/* Returns 0 on success, else negative errno on failure. */
  67static ssize_t cyapa_i2c_read(struct cyapa *cyapa, u8 reg, size_t len,
  68                                        u8 *values)
  69{
  70        struct i2c_client *client = cyapa->client;
  71        struct i2c_msg msgs[] = {
  72                {
  73                        .addr = client->addr,
  74                        .flags = 0,
  75                        .len = 1,
  76                        .buf = &reg,
  77                },
  78                {
  79                        .addr = client->addr,
  80                        .flags = I2C_M_RD,
  81                        .len = len,
  82                        .buf = values,
  83                },
  84        };
  85        int ret;
  86
  87        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  88
  89        if (ret != ARRAY_SIZE(msgs))
  90                return ret < 0 ? ret : -EIO;
  91
  92        return 0;
  93}
  94
  95/**
  96 * cyapa_i2c_write - Execute i2c block data write operation
  97 * @cyapa: Handle to this driver
  98 * @ret: Offset of the data to written in the register map
  99 * @len: number of bytes to write
 100 * @values: Data to be written
 101 *
 102 * Return negative errno code on error; return zero when success.
 103 */
 104static int cyapa_i2c_write(struct cyapa *cyapa, u8 reg,
 105                                         size_t len, const void *values)
 106{
 107        struct i2c_client *client = cyapa->client;
 108        char buf[32];
 109        int ret;
 110
 111        if (len > sizeof(buf) - 1)
 112                return -ENOMEM;
 113
 114        buf[0] = reg;
 115        memcpy(&buf[1], values, len);
 116
 117        ret = i2c_master_send(client, buf, len + 1);
 118        if (ret != len + 1)
 119                return ret < 0 ? ret : -EIO;
 120
 121        return 0;
 122}
 123
 124static u8 cyapa_check_adapter_functionality(struct i2c_client *client)
 125{
 126        u8 ret = CYAPA_ADAPTER_FUNC_NONE;
 127
 128        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 129                ret |= CYAPA_ADAPTER_FUNC_I2C;
 130        if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 131                                     I2C_FUNC_SMBUS_BLOCK_DATA |
 132                                     I2C_FUNC_SMBUS_I2C_BLOCK))
 133                ret |= CYAPA_ADAPTER_FUNC_SMBUS;
 134        return ret;
 135}
 136
 137/*
 138 * Query device for its current operating state.
 139 */
 140static int cyapa_get_state(struct cyapa *cyapa)
 141{
 142        u8 status[BL_STATUS_SIZE];
 143        u8 cmd[32];
 144        /* The i2c address of gen4 and gen5 trackpad device must be even. */
 145        bool even_addr = ((cyapa->client->addr & 0x0001) == 0);
 146        bool smbus = false;
 147        int retries = 2;
 148        int error;
 149
 150        cyapa->state = CYAPA_STATE_NO_DEVICE;
 151
 152        /*
 153         * Get trackpad status by reading 3 registers starting from 0.
 154         * If the device is in the bootloader, this will be BL_HEAD.
 155         * If the device is in operation mode, this will be the DATA regs.
 156         *
 157         */
 158        error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE,
 159                                       status);
 160
 161        /*
 162         * On smbus systems in OP mode, the i2c_reg_read will fail with
 163         * -ETIMEDOUT.  In this case, try again using the smbus equivalent
 164         * command.  This should return a BL_HEAD indicating CYAPA_STATE_OP.
 165         */
 166        if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) {
 167                if (!even_addr)
 168                        error = cyapa_read_block(cyapa,
 169                                        CYAPA_CMD_BL_STATUS, status);
 170                smbus = true;
 171        }
 172
 173        if (error != BL_STATUS_SIZE)
 174                goto error;
 175
 176        /*
 177         * Detect trackpad protocol based on characteristic registers and bits.
 178         */
 179        do {
 180                cyapa->status[REG_OP_STATUS] = status[REG_OP_STATUS];
 181                cyapa->status[REG_BL_STATUS] = status[REG_BL_STATUS];
 182                cyapa->status[REG_BL_ERROR] = status[REG_BL_ERROR];
 183
 184                if (cyapa->gen == CYAPA_GEN_UNKNOWN ||
 185                                cyapa->gen == CYAPA_GEN3) {
 186                        error = cyapa_gen3_ops.state_parse(cyapa,
 187                                        status, BL_STATUS_SIZE);
 188                        if (!error)
 189                                goto out_detected;
 190                }
 191                if ((cyapa->gen == CYAPA_GEN_UNKNOWN ||
 192                                cyapa->gen == CYAPA_GEN5) &&
 193                        !smbus && even_addr) {
 194                        error = cyapa_gen5_ops.state_parse(cyapa,
 195                                        status, BL_STATUS_SIZE);
 196                        if (!error)
 197                                goto out_detected;
 198                }
 199
 200                /*
 201                 * Write 0x00 0x00 to trackpad device to force update its
 202                 * status, then redo the detection again.
 203                 */
 204                if (!smbus) {
 205                        cmd[0] = 0x00;
 206                        cmd[1] = 0x00;
 207                        error = cyapa_i2c_write(cyapa, 0, 2, cmd);
 208                        if (error)
 209                                goto error;
 210
 211                        msleep(50);
 212
 213                        error = cyapa_i2c_read(cyapa, BL_HEAD_OFFSET,
 214                                        BL_STATUS_SIZE, status);
 215                        if (error)
 216                                goto error;
 217                }
 218        } while (--retries > 0 && !smbus);
 219
 220        goto error;
 221
 222out_detected:
 223        if (cyapa->state <= CYAPA_STATE_BL_BUSY)
 224                return -EAGAIN;
 225        return 0;
 226
 227error:
 228        return (error < 0) ? error : -EAGAIN;
 229}
 230
 231/*
 232 * Poll device for its status in a loop, waiting up to timeout for a response.
 233 *
 234 * When the device switches state, it usually takes ~300 ms.
 235 * However, when running a new firmware image, the device must calibrate its
 236 * sensors, which can take as long as 2 seconds.
 237 *
 238 * Note: The timeout has granularity of the polling rate, which is 100 ms.
 239 *
 240 * Returns:
 241 *   0 when the device eventually responds with a valid non-busy state.
 242 *   -ETIMEDOUT if device never responds (too many -EAGAIN)
 243 *   -EAGAIN    if bootload is busy, or unknown state.
 244 *   < 0        other errors
 245 */
 246int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout)
 247{
 248        int error;
 249        int tries = timeout / 100;
 250
 251        do {
 252                error = cyapa_get_state(cyapa);
 253                if (!error && cyapa->state > CYAPA_STATE_BL_BUSY)
 254                        return 0;
 255
 256                msleep(100);
 257        } while (tries--);
 258
 259        return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error;
 260}
 261
 262/*
 263 * Check if device is operational.
 264 *
 265 * An operational device is responding, has exited bootloader, and has
 266 * firmware supported by this driver.
 267 *
 268 * Returns:
 269 *   -ENODEV no device
 270 *   -EBUSY  no device or in bootloader
 271 *   -EIO    failure while reading from device
 272 *   -ETIMEDOUT timeout failure for bus idle or bus no response
 273 *   -EAGAIN device is still in bootloader
 274 *           if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware
 275 *   -EINVAL device is in operational mode, but not supported by this driver
 276 *   0       device is supported
 277 */
 278static int cyapa_check_is_operational(struct cyapa *cyapa)
 279{
 280        int error;
 281
 282        error = cyapa_poll_state(cyapa, 4000);
 283        if (error)
 284                return error;
 285
 286        switch (cyapa->gen) {
 287        case CYAPA_GEN5:
 288                cyapa->ops = &cyapa_gen5_ops;
 289                break;
 290        case CYAPA_GEN3:
 291                cyapa->ops = &cyapa_gen3_ops;
 292                break;
 293        default:
 294                return -ENODEV;
 295        }
 296
 297        error = cyapa->ops->operational_check(cyapa);
 298        if (!error && cyapa_is_operational_mode(cyapa))
 299                cyapa->operational = true;
 300        else
 301                cyapa->operational = false;
 302
 303        return error;
 304}
 305
 306
 307/*
 308 * Returns 0 on device detected, negative errno on no device detected.
 309 * And when the device is detected and opertaional, it will be reset to
 310 * full power active mode automatically.
 311 */
 312static int cyapa_detect(struct cyapa *cyapa)
 313{
 314        struct device *dev = &cyapa->client->dev;
 315        int error;
 316
 317        error = cyapa_check_is_operational(cyapa);
 318        if (error) {
 319                if (error != -ETIMEDOUT && error != -ENODEV &&
 320                        cyapa_is_bootloader_mode(cyapa)) {
 321                        dev_warn(dev, "device detected but not operational\n");
 322                        return 0;
 323                }
 324
 325                dev_err(dev, "no device detected: %d\n", error);
 326                return error;
 327        }
 328
 329        return 0;
 330}
 331
 332static int cyapa_open(struct input_dev *input)
 333{
 334        struct cyapa *cyapa = input_get_drvdata(input);
 335        struct i2c_client *client = cyapa->client;
 336        int error;
 337
 338        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 339        if (error)
 340                return error;
 341
 342        if (cyapa->operational) {
 343                /*
 344                 * though failed to set active power mode,
 345                 * but still may be able to work in lower scan rate
 346                 * when in operational mode.
 347                 */
 348                error = cyapa->ops->set_power_mode(cyapa,
 349                                PWR_MODE_FULL_ACTIVE, 0);
 350                if (error) {
 351                        dev_warn(&client->dev,
 352                                "set active power failed: %d\n", error);
 353                        goto out;
 354                }
 355        } else {
 356                error = cyapa_reinitialize(cyapa);
 357                if (error || !cyapa->operational) {
 358                        error = error ? error : -EAGAIN;
 359                        goto out;
 360                }
 361        }
 362
 363        enable_irq(client->irq);
 364        if (!pm_runtime_enabled(&client->dev)) {
 365                pm_runtime_set_active(&client->dev);
 366                pm_runtime_enable(&client->dev);
 367        }
 368out:
 369        mutex_unlock(&cyapa->state_sync_lock);
 370        return error;
 371}
 372
 373static void cyapa_close(struct input_dev *input)
 374{
 375        struct cyapa *cyapa = input_get_drvdata(input);
 376        struct i2c_client *client = cyapa->client;
 377
 378        mutex_lock(&cyapa->state_sync_lock);
 379
 380        disable_irq(client->irq);
 381        if (pm_runtime_enabled(&client->dev))
 382                pm_runtime_disable(&client->dev);
 383        pm_runtime_set_suspended(&client->dev);
 384
 385        if (cyapa->operational)
 386                cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
 387
 388        mutex_unlock(&cyapa->state_sync_lock);
 389}
 390
 391static int cyapa_create_input_dev(struct cyapa *cyapa)
 392{
 393        struct device *dev = &cyapa->client->dev;
 394        struct input_dev *input;
 395        int error;
 396
 397        if (!cyapa->physical_size_x || !cyapa->physical_size_y)
 398                return -EINVAL;
 399
 400        input = devm_input_allocate_device(dev);
 401        if (!input) {
 402                dev_err(dev, "failed to allocate memory for input device.\n");
 403                return -ENOMEM;
 404        }
 405
 406        input->name = CYAPA_NAME;
 407        input->phys = cyapa->phys;
 408        input->id.bustype = BUS_I2C;
 409        input->id.version = 1;
 410        input->id.product = 0;  /* Means any product in eventcomm. */
 411        input->dev.parent = &cyapa->client->dev;
 412
 413        input->open = cyapa_open;
 414        input->close = cyapa_close;
 415
 416        input_set_drvdata(input, cyapa);
 417
 418        __set_bit(EV_ABS, input->evbit);
 419
 420        /* Finger position */
 421        input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0,
 422                             0);
 423        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0,
 424                             0);
 425        input_set_abs_params(input, ABS_MT_PRESSURE, 0, cyapa->max_z, 0, 0);
 426        if (cyapa->gen > CYAPA_GEN3) {
 427                input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
 428                input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
 429                /*
 430                 * Orientation is the angle between the vertical axis and
 431                 * the major axis of the contact ellipse.
 432                 * The range is -127 to 127.
 433                 * the positive direction is clockwise form the vertical axis.
 434                 * If the ellipse of contact degenerates into a circle,
 435                 * orientation is reported as 0.
 436                 *
 437                 * Also, for Gen5 trackpad the accurate of this orientation
 438                 * value is value + (-30 ~ 30).
 439                 */
 440                input_set_abs_params(input, ABS_MT_ORIENTATION,
 441                                -127, 127, 0, 0);
 442        }
 443        if (cyapa->gen >= CYAPA_GEN5) {
 444                input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
 445                input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 255, 0, 0);
 446        }
 447
 448        input_abs_set_res(input, ABS_MT_POSITION_X,
 449                          cyapa->max_abs_x / cyapa->physical_size_x);
 450        input_abs_set_res(input, ABS_MT_POSITION_Y,
 451                          cyapa->max_abs_y / cyapa->physical_size_y);
 452
 453        if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK)
 454                __set_bit(BTN_LEFT, input->keybit);
 455        if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK)
 456                __set_bit(BTN_MIDDLE, input->keybit);
 457        if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
 458                __set_bit(BTN_RIGHT, input->keybit);
 459
 460        if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK)
 461                __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 462
 463        /* Handle pointer emulation and unused slots in core */
 464        error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
 465                                    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
 466        if (error) {
 467                dev_err(dev, "failed to initialize MT slots: %d\n", error);
 468                return error;
 469        }
 470
 471        /* Register the device in input subsystem */
 472        error = input_register_device(input);
 473        if (error) {
 474                dev_err(dev, "failed to register input device: %d\n", error);
 475                return error;
 476        }
 477
 478        cyapa->input = input;
 479        return 0;
 480}
 481
 482static void cyapa_enable_irq_for_cmd(struct cyapa *cyapa)
 483{
 484        struct input_dev *input = cyapa->input;
 485
 486        if (!input || !input->users) {
 487                /*
 488                 * When input is NULL, TP must be in deep sleep mode.
 489                 * In this mode, later non-power I2C command will always failed
 490                 * if not bring it out of deep sleep mode firstly,
 491                 * so must command TP to active mode here.
 492                 */
 493                if (!input || cyapa->operational)
 494                        cyapa->ops->set_power_mode(cyapa,
 495                                PWR_MODE_FULL_ACTIVE, 0);
 496                /* Gen3 always using polling mode for command. */
 497                if (cyapa->gen >= CYAPA_GEN5)
 498                        enable_irq(cyapa->client->irq);
 499        }
 500}
 501
 502static void cyapa_disable_irq_for_cmd(struct cyapa *cyapa)
 503{
 504        struct input_dev *input = cyapa->input;
 505
 506        if (!input || !input->users) {
 507                if (cyapa->gen >= CYAPA_GEN5)
 508                        disable_irq(cyapa->client->irq);
 509                if (!input || cyapa->operational)
 510                        cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
 511        }
 512}
 513
 514/*
 515 * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time
 516 *
 517 * These are helper functions that convert to and from integer idle
 518 * times and register settings to write to the PowerMode register.
 519 * The trackpad supports between 20ms to 1000ms scan intervals.
 520 * The time will be increased in increments of 10ms from 20ms to 100ms.
 521 * From 100ms to 1000ms, time will be increased in increments of 20ms.
 522 *
 523 * When Idle_Time < 100, the format to convert Idle_Time to Idle_Command is:
 524 *   Idle_Command = Idle Time / 10;
 525 * When Idle_Time >= 100, the format to convert Idle_Time to Idle_Command is:
 526 *   Idle_Command = Idle Time / 20 + 5;
 527 */
 528u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time)
 529{
 530        u16 encoded_time;
 531
 532        sleep_time = clamp_val(sleep_time, 20, 1000);
 533        encoded_time = sleep_time < 100 ? sleep_time / 10 : sleep_time / 20 + 5;
 534        return (encoded_time << 2) & PWR_MODE_MASK;
 535}
 536
 537u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode)
 538{
 539        u8 encoded_time = pwr_mode >> 2;
 540
 541        return (encoded_time < 10) ? encoded_time * 10
 542                                   : (encoded_time - 5) * 20;
 543}
 544
 545/* 0 on driver initialize and detected successfully, negative on failure. */
 546static int cyapa_initialize(struct cyapa *cyapa)
 547{
 548        int error = 0;
 549
 550        cyapa->state = CYAPA_STATE_NO_DEVICE;
 551        cyapa->gen = CYAPA_GEN_UNKNOWN;
 552        mutex_init(&cyapa->state_sync_lock);
 553
 554        /*
 555         * Set to hard code default, they will be updated with trackpad set
 556         * default values after probe and initialized.
 557         */
 558        cyapa->suspend_power_mode = PWR_MODE_SLEEP;
 559        cyapa->suspend_sleep_time =
 560                cyapa_pwr_cmd_to_sleep_time(cyapa->suspend_power_mode);
 561
 562        /* ops.initialize() is aimed to prepare for module communications. */
 563        error = cyapa_gen3_ops.initialize(cyapa);
 564        if (!error)
 565                error = cyapa_gen5_ops.initialize(cyapa);
 566        if (error)
 567                return error;
 568
 569        error = cyapa_detect(cyapa);
 570        if (error)
 571                return error;
 572
 573        /* Power down the device until we need it. */
 574        if (cyapa->operational)
 575                cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
 576
 577        return 0;
 578}
 579
 580static int cyapa_reinitialize(struct cyapa *cyapa)
 581{
 582        struct device *dev = &cyapa->client->dev;
 583        struct input_dev *input = cyapa->input;
 584        int error;
 585
 586        if (pm_runtime_enabled(dev))
 587                pm_runtime_disable(dev);
 588
 589        /* Avoid command failures when TP was in OFF state. */
 590        if (cyapa->operational)
 591                cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
 592
 593        error = cyapa_detect(cyapa);
 594        if (error)
 595                goto out;
 596
 597        if (!input && cyapa->operational) {
 598                error = cyapa_create_input_dev(cyapa);
 599                if (error) {
 600                        dev_err(dev, "create input_dev instance failed: %d\n",
 601                                        error);
 602                        goto out;
 603                }
 604        }
 605
 606out:
 607        if (!input || !input->users) {
 608                /* Reset to power OFF state to save power when no user open. */
 609                if (cyapa->operational)
 610                        cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
 611        } else if (!error && cyapa->operational) {
 612                /*
 613                 * Make sure only enable runtime PM when device is
 614                 * in operational mode and input->users > 0.
 615                 */
 616                pm_runtime_set_active(dev);
 617                pm_runtime_enable(dev);
 618        }
 619
 620        return error;
 621}
 622
 623static irqreturn_t cyapa_irq(int irq, void *dev_id)
 624{
 625        struct cyapa *cyapa = dev_id;
 626        struct device *dev = &cyapa->client->dev;
 627
 628        pm_runtime_get_sync(dev);
 629        if (device_may_wakeup(dev))
 630                pm_wakeup_event(dev, 0);
 631
 632        /* Interrupt event maybe cuased by host command to trackpad device. */
 633        if (cyapa->ops->irq_cmd_handler(cyapa)) {
 634                /*
 635                 * Interrupt event maybe from trackpad device input reporting.
 636                 */
 637                if (!cyapa->input) {
 638                        /*
 639                         * Still in probling or in firware image
 640                         * udpating or reading.
 641                         */
 642                        cyapa->ops->sort_empty_output_data(cyapa,
 643                                        NULL, NULL, NULL);
 644                        goto out;
 645                }
 646
 647                if (!cyapa->operational || cyapa->ops->irq_handler(cyapa)) {
 648                        if (!mutex_trylock(&cyapa->state_sync_lock)) {
 649                                cyapa->ops->sort_empty_output_data(cyapa,
 650                                        NULL, NULL, NULL);
 651                                goto out;
 652                        }
 653                        cyapa_reinitialize(cyapa);
 654                        mutex_unlock(&cyapa->state_sync_lock);
 655                }
 656        }
 657
 658out:
 659        pm_runtime_mark_last_busy(dev);
 660        pm_runtime_put_sync_autosuspend(dev);
 661        return IRQ_HANDLED;
 662}
 663
 664/*
 665 **************************************************************
 666 * sysfs interface
 667 **************************************************************
 668*/
 669#ifdef CONFIG_PM_SLEEP
 670static ssize_t cyapa_show_suspend_scanrate(struct device *dev,
 671                                           struct device_attribute *attr,
 672                                           char *buf)
 673{
 674        struct cyapa *cyapa = dev_get_drvdata(dev);
 675        u8 pwr_cmd = cyapa->suspend_power_mode;
 676        u16 sleep_time;
 677        int len;
 678        int error;
 679
 680        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 681        if (error)
 682                return error;
 683
 684        pwr_cmd = cyapa->suspend_power_mode;
 685        sleep_time = cyapa->suspend_sleep_time;
 686
 687        mutex_unlock(&cyapa->state_sync_lock);
 688
 689        switch (pwr_cmd) {
 690        case PWR_MODE_BTN_ONLY:
 691                len = scnprintf(buf, PAGE_SIZE, "%s\n", BTN_ONLY_MODE_NAME);
 692                break;
 693
 694        case PWR_MODE_OFF:
 695                len = scnprintf(buf, PAGE_SIZE, "%s\n", OFF_MODE_NAME);
 696                break;
 697
 698        default:
 699                len = scnprintf(buf, PAGE_SIZE, "%u\n",
 700                                cyapa->gen == CYAPA_GEN3 ?
 701                                        cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
 702                                        sleep_time);
 703                break;
 704        }
 705
 706        return len;
 707}
 708
 709static ssize_t cyapa_update_suspend_scanrate(struct device *dev,
 710                                             struct device_attribute *attr,
 711                                             const char *buf, size_t count)
 712{
 713        struct cyapa *cyapa = dev_get_drvdata(dev);
 714        u16 sleep_time;
 715        int error;
 716
 717        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 718        if (error)
 719                return error;
 720
 721        if (sysfs_streq(buf, BTN_ONLY_MODE_NAME)) {
 722                cyapa->suspend_power_mode = PWR_MODE_BTN_ONLY;
 723        } else if (sysfs_streq(buf, OFF_MODE_NAME)) {
 724                cyapa->suspend_power_mode = PWR_MODE_OFF;
 725        } else if (!kstrtou16(buf, 10, &sleep_time)) {
 726                cyapa->suspend_sleep_time = min_t(u16, sleep_time, 1000);
 727                cyapa->suspend_power_mode =
 728                        cyapa_sleep_time_to_pwr_cmd(cyapa->suspend_sleep_time);
 729        } else {
 730                count = -EINVAL;
 731        }
 732
 733        mutex_unlock(&cyapa->state_sync_lock);
 734
 735        return count;
 736}
 737
 738static DEVICE_ATTR(suspend_scanrate_ms, S_IRUGO|S_IWUSR,
 739                   cyapa_show_suspend_scanrate,
 740                   cyapa_update_suspend_scanrate);
 741
 742static struct attribute *cyapa_power_wakeup_entries[] = {
 743        &dev_attr_suspend_scanrate_ms.attr,
 744        NULL,
 745};
 746
 747static const struct attribute_group cyapa_power_wakeup_group = {
 748        .name = power_group_name,
 749        .attrs = cyapa_power_wakeup_entries,
 750};
 751
 752static void cyapa_remove_power_wakeup_group(void *data)
 753{
 754        struct cyapa *cyapa = data;
 755
 756        sysfs_unmerge_group(&cyapa->client->dev.kobj,
 757                                &cyapa_power_wakeup_group);
 758}
 759
 760static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
 761{
 762        struct i2c_client *client = cyapa->client;
 763        struct device *dev = &client->dev;
 764        int error;
 765
 766        if (device_can_wakeup(dev)) {
 767                error = sysfs_merge_group(&client->dev.kobj,
 768                                        &cyapa_power_wakeup_group);
 769                if (error) {
 770                        dev_err(dev, "failed to add power wakeup group: %d\n",
 771                                error);
 772                        return error;
 773                }
 774
 775                error = devm_add_action(dev,
 776                                cyapa_remove_power_wakeup_group, cyapa);
 777                if (error) {
 778                        cyapa_remove_power_wakeup_group(cyapa);
 779                        dev_err(dev, "failed to add power cleanup action: %d\n",
 780                                error);
 781                        return error;
 782                }
 783        }
 784
 785        return 0;
 786}
 787#else
 788static inline int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
 789{
 790        return 0;
 791}
 792#endif /* CONFIG_PM_SLEEP */
 793
 794#ifdef CONFIG_PM
 795static ssize_t cyapa_show_rt_suspend_scanrate(struct device *dev,
 796                                              struct device_attribute *attr,
 797                                              char *buf)
 798{
 799        struct cyapa *cyapa = dev_get_drvdata(dev);
 800        u8 pwr_cmd;
 801        u16 sleep_time;
 802        int error;
 803
 804        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 805        if (error)
 806                return error;
 807
 808        pwr_cmd = cyapa->runtime_suspend_power_mode;
 809        sleep_time = cyapa->runtime_suspend_sleep_time;
 810
 811        mutex_unlock(&cyapa->state_sync_lock);
 812
 813        return scnprintf(buf, PAGE_SIZE, "%u\n",
 814                         cyapa->gen == CYAPA_GEN3 ?
 815                                cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
 816                                sleep_time);
 817}
 818
 819static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev,
 820                                                struct device_attribute *attr,
 821                                                const char *buf, size_t count)
 822{
 823        struct cyapa *cyapa = dev_get_drvdata(dev);
 824        u16 time;
 825        int error;
 826
 827        if (buf == NULL || count == 0 || kstrtou16(buf, 10, &time)) {
 828                dev_err(dev, "invalid runtime suspend scanrate ms parameter\n");
 829                return -EINVAL;
 830        }
 831
 832        /*
 833         * When the suspend scanrate is changed, pm_runtime_get to resume
 834         * a potentially suspended device, update to the new pwr_cmd
 835         * and then pm_runtime_put to suspend into the new power mode.
 836         */
 837        pm_runtime_get_sync(dev);
 838
 839        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 840        if (error)
 841                return error;
 842
 843        cyapa->runtime_suspend_sleep_time = min_t(u16, time, 1000);
 844        cyapa->runtime_suspend_power_mode =
 845                cyapa_sleep_time_to_pwr_cmd(cyapa->runtime_suspend_sleep_time);
 846
 847        mutex_unlock(&cyapa->state_sync_lock);
 848
 849        pm_runtime_put_sync_autosuspend(dev);
 850
 851        return count;
 852}
 853
 854static DEVICE_ATTR(runtime_suspend_scanrate_ms, S_IRUGO|S_IWUSR,
 855                   cyapa_show_rt_suspend_scanrate,
 856                   cyapa_update_rt_suspend_scanrate);
 857
 858static struct attribute *cyapa_power_runtime_entries[] = {
 859        &dev_attr_runtime_suspend_scanrate_ms.attr,
 860        NULL,
 861};
 862
 863static const struct attribute_group cyapa_power_runtime_group = {
 864        .name = power_group_name,
 865        .attrs = cyapa_power_runtime_entries,
 866};
 867
 868static void cyapa_remove_power_runtime_group(void *data)
 869{
 870        struct cyapa *cyapa = data;
 871
 872        sysfs_unmerge_group(&cyapa->client->dev.kobj,
 873                                &cyapa_power_runtime_group);
 874}
 875
 876static int cyapa_start_runtime(struct cyapa *cyapa)
 877{
 878        struct device *dev = &cyapa->client->dev;
 879        int error;
 880
 881        cyapa->runtime_suspend_power_mode = PWR_MODE_IDLE;
 882        cyapa->runtime_suspend_sleep_time =
 883                cyapa_pwr_cmd_to_sleep_time(cyapa->runtime_suspend_power_mode);
 884
 885        error = sysfs_merge_group(&dev->kobj, &cyapa_power_runtime_group);
 886        if (error) {
 887                dev_err(dev,
 888                        "failed to create power runtime group: %d\n", error);
 889                return error;
 890        }
 891
 892        error = devm_add_action(dev, cyapa_remove_power_runtime_group, cyapa);
 893        if (error) {
 894                cyapa_remove_power_runtime_group(cyapa);
 895                dev_err(dev,
 896                        "failed to add power runtime cleanup action: %d\n",
 897                        error);
 898                return error;
 899        }
 900
 901        /* runtime is enabled until device is operational and opened. */
 902        pm_runtime_set_suspended(dev);
 903        pm_runtime_use_autosuspend(dev);
 904        pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY);
 905
 906        return 0;
 907}
 908#else
 909static inline int cyapa_start_runtime(struct cyapa *cyapa)
 910{
 911        return 0;
 912}
 913#endif /* CONFIG_PM */
 914
 915static ssize_t cyapa_show_fm_ver(struct device *dev,
 916                                 struct device_attribute *attr, char *buf)
 917{
 918        int error;
 919        struct cyapa *cyapa = dev_get_drvdata(dev);
 920
 921        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 922        if (error)
 923                return error;
 924        error = scnprintf(buf, PAGE_SIZE, "%d.%d\n", cyapa->fw_maj_ver,
 925                         cyapa->fw_min_ver);
 926        mutex_unlock(&cyapa->state_sync_lock);
 927        return error;
 928}
 929
 930static ssize_t cyapa_show_product_id(struct device *dev,
 931                                     struct device_attribute *attr, char *buf)
 932{
 933        struct cyapa *cyapa = dev_get_drvdata(dev);
 934        int size;
 935        int error;
 936
 937        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
 938        if (error)
 939                return error;
 940        size = scnprintf(buf, PAGE_SIZE, "%s\n", cyapa->product_id);
 941        mutex_unlock(&cyapa->state_sync_lock);
 942        return size;
 943}
 944
 945static int cyapa_firmware(struct cyapa *cyapa, const char *fw_name)
 946{
 947        struct device *dev = &cyapa->client->dev;
 948        const struct firmware *fw;
 949        int error;
 950
 951        error = request_firmware(&fw, fw_name, dev);
 952        if (error) {
 953                dev_err(dev, "Could not load firmware from %s: %d\n",
 954                        fw_name, error);
 955                return error;
 956        }
 957
 958        error = cyapa->ops->check_fw(cyapa, fw);
 959        if (error) {
 960                dev_err(dev, "Invalid CYAPA firmware image: %s\n",
 961                                fw_name);
 962                goto done;
 963        }
 964
 965        /*
 966         * Resume the potentially suspended device because doing FW
 967         * update on a device not in the FULL mode has a chance to
 968         * fail.
 969         */
 970        pm_runtime_get_sync(dev);
 971
 972        /* Require IRQ support for firmware update commands. */
 973        cyapa_enable_irq_for_cmd(cyapa);
 974
 975        error = cyapa->ops->bl_enter(cyapa);
 976        if (error) {
 977                dev_err(dev, "bl_enter failed, %d\n", error);
 978                goto err_detect;
 979        }
 980
 981        error = cyapa->ops->bl_activate(cyapa);
 982        if (error) {
 983                dev_err(dev, "bl_activate failed, %d\n", error);
 984                goto err_detect;
 985        }
 986
 987        error = cyapa->ops->bl_initiate(cyapa, fw);
 988        if (error) {
 989                dev_err(dev, "bl_initiate failed, %d\n", error);
 990                goto err_detect;
 991        }
 992
 993        error = cyapa->ops->update_fw(cyapa, fw);
 994        if (error) {
 995                dev_err(dev, "update_fw failed, %d\n", error);
 996                goto err_detect;
 997        }
 998
 999err_detect:
1000        cyapa_disable_irq_for_cmd(cyapa);
1001        pm_runtime_put_noidle(dev);
1002
1003done:
1004        release_firmware(fw);
1005        return error;
1006}
1007
1008static ssize_t cyapa_update_fw_store(struct device *dev,
1009                                     struct device_attribute *attr,
1010                                     const char *buf, size_t count)
1011{
1012        struct cyapa *cyapa = dev_get_drvdata(dev);
1013        char fw_name[NAME_MAX];
1014        int ret, error;
1015
1016        if (count >= NAME_MAX) {
1017                dev_err(dev, "File name too long\n");
1018                return -EINVAL;
1019        }
1020
1021        memcpy(fw_name, buf, count);
1022        if (fw_name[count - 1] == '\n')
1023                fw_name[count - 1] = '\0';
1024        else
1025                fw_name[count] = '\0';
1026
1027        if (cyapa->input) {
1028                /*
1029                 * Force the input device to be registered after the firmware
1030                 * image is updated, so if the corresponding parameters updated
1031                 * in the new firmware image can taken effect immediately.
1032                 */
1033                input_unregister_device(cyapa->input);
1034                cyapa->input = NULL;
1035        }
1036
1037        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1038        if (error) {
1039                /*
1040                 * Whatever, do reinitialize to try to recover TP state to
1041                 * previous state just as it entered fw update entrance.
1042                 */
1043                cyapa_reinitialize(cyapa);
1044                return error;
1045        }
1046
1047        error = cyapa_firmware(cyapa, fw_name);
1048        if (error)
1049                dev_err(dev, "firmware update failed: %d\n", error);
1050        else
1051                dev_dbg(dev, "firmware update successfully done.\n");
1052
1053        /*
1054         * Redetect trackpad device states because firmware update process
1055         * will reset trackpad device into bootloader mode.
1056         */
1057        ret = cyapa_reinitialize(cyapa);
1058        if (ret) {
1059                dev_err(dev, "failed to redetect after updated: %d\n", ret);
1060                error = error ? error : ret;
1061        }
1062
1063        mutex_unlock(&cyapa->state_sync_lock);
1064
1065        return error ? error : count;
1066}
1067
1068static ssize_t cyapa_calibrate_store(struct device *dev,
1069                                     struct device_attribute *attr,
1070                                     const char *buf, size_t count)
1071{
1072        struct cyapa *cyapa = dev_get_drvdata(dev);
1073        int error;
1074
1075        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1076        if (error)
1077                return error;
1078
1079        if (cyapa->operational) {
1080                cyapa_enable_irq_for_cmd(cyapa);
1081                error = cyapa->ops->calibrate_store(dev, attr, buf, count);
1082                cyapa_disable_irq_for_cmd(cyapa);
1083        } else {
1084                error = -EBUSY;  /* Still running in bootloader mode. */
1085        }
1086
1087        mutex_unlock(&cyapa->state_sync_lock);
1088        return error < 0 ? error : count;
1089}
1090
1091static ssize_t cyapa_show_baseline(struct device *dev,
1092                                   struct device_attribute *attr, char *buf)
1093{
1094        struct cyapa *cyapa = dev_get_drvdata(dev);
1095        ssize_t error;
1096
1097        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1098        if (error)
1099                return error;
1100
1101        if (cyapa->operational) {
1102                cyapa_enable_irq_for_cmd(cyapa);
1103                error = cyapa->ops->show_baseline(dev, attr, buf);
1104                cyapa_disable_irq_for_cmd(cyapa);
1105        } else {
1106                error = -EBUSY;  /* Still running in bootloader mode. */
1107        }
1108
1109        mutex_unlock(&cyapa->state_sync_lock);
1110        return error;
1111}
1112
1113static char *cyapa_state_to_string(struct cyapa *cyapa)
1114{
1115        switch (cyapa->state) {
1116        case CYAPA_STATE_BL_BUSY:
1117                return "bootloader busy";
1118        case CYAPA_STATE_BL_IDLE:
1119                return "bootloader idle";
1120        case CYAPA_STATE_BL_ACTIVE:
1121                return "bootloader active";
1122        case CYAPA_STATE_GEN5_BL:
1123                return "bootloader";
1124        case CYAPA_STATE_OP:
1125        case CYAPA_STATE_GEN5_APP:
1126                return "operational";  /* Normal valid state. */
1127        default:
1128                return "invalid mode";
1129        }
1130}
1131
1132static ssize_t cyapa_show_mode(struct device *dev,
1133                                   struct device_attribute *attr, char *buf)
1134{
1135        struct cyapa *cyapa = dev_get_drvdata(dev);
1136        int size;
1137        int error;
1138
1139        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1140        if (error)
1141                return error;
1142
1143        size = scnprintf(buf, PAGE_SIZE, "gen%d %s\n",
1144                        cyapa->gen, cyapa_state_to_string(cyapa));
1145
1146        mutex_unlock(&cyapa->state_sync_lock);
1147        return size;
1148}
1149
1150static DEVICE_ATTR(firmware_version, S_IRUGO, cyapa_show_fm_ver, NULL);
1151static DEVICE_ATTR(product_id, S_IRUGO, cyapa_show_product_id, NULL);
1152static DEVICE_ATTR(update_fw, S_IWUSR, NULL, cyapa_update_fw_store);
1153static DEVICE_ATTR(baseline, S_IRUGO, cyapa_show_baseline, NULL);
1154static DEVICE_ATTR(calibrate, S_IWUSR, NULL, cyapa_calibrate_store);
1155static DEVICE_ATTR(mode, S_IRUGO, cyapa_show_mode, NULL);
1156
1157static struct attribute *cyapa_sysfs_entries[] = {
1158        &dev_attr_firmware_version.attr,
1159        &dev_attr_product_id.attr,
1160        &dev_attr_update_fw.attr,
1161        &dev_attr_baseline.attr,
1162        &dev_attr_calibrate.attr,
1163        &dev_attr_mode.attr,
1164        NULL,
1165};
1166
1167static const struct attribute_group cyapa_sysfs_group = {
1168        .attrs = cyapa_sysfs_entries,
1169};
1170
1171static void cyapa_remove_sysfs_group(void *data)
1172{
1173        struct cyapa *cyapa = data;
1174
1175        sysfs_remove_group(&cyapa->client->dev.kobj, &cyapa_sysfs_group);
1176}
1177
1178static int cyapa_probe(struct i2c_client *client,
1179                       const struct i2c_device_id *dev_id)
1180{
1181        struct device *dev = &client->dev;
1182        struct cyapa *cyapa;
1183        u8 adapter_func;
1184        union i2c_smbus_data dummy;
1185        int error;
1186
1187        adapter_func = cyapa_check_adapter_functionality(client);
1188        if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) {
1189                dev_err(dev, "not a supported I2C/SMBus adapter\n");
1190                return -EIO;
1191        }
1192
1193        /* Make sure there is something at this address */
1194        if (i2c_smbus_xfer(client->adapter, client->addr, 0,
1195                        I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0)
1196                return -ENODEV;
1197
1198        cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
1199        if (!cyapa)
1200                return -ENOMEM;
1201
1202        /* i2c isn't supported, use smbus */
1203        if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS)
1204                cyapa->smbus = true;
1205
1206        cyapa->client = client;
1207        i2c_set_clientdata(client, cyapa);
1208        sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr,
1209                client->addr);
1210
1211        error = cyapa_initialize(cyapa);
1212        if (error) {
1213                dev_err(dev, "failed to detect and initialize tp device.\n");
1214                return error;
1215        }
1216
1217        error = sysfs_create_group(&client->dev.kobj, &cyapa_sysfs_group);
1218        if (error) {
1219                dev_err(dev, "failed to create sysfs entries: %d\n", error);
1220                return error;
1221        }
1222
1223        error = devm_add_action(dev, cyapa_remove_sysfs_group, cyapa);
1224        if (error) {
1225                cyapa_remove_sysfs_group(cyapa);
1226                dev_err(dev, "failed to add sysfs cleanup action: %d\n", error);
1227                return error;
1228        }
1229
1230        error = cyapa_prepare_wakeup_controls(cyapa);
1231        if (error) {
1232                dev_err(dev, "failed to prepare wakeup controls: %d\n", error);
1233                return error;
1234        }
1235
1236        error = cyapa_start_runtime(cyapa);
1237        if (error) {
1238                dev_err(dev, "failed to start pm_runtime: %d\n", error);
1239                return error;
1240        }
1241
1242        error = devm_request_threaded_irq(dev, client->irq,
1243                                          NULL, cyapa_irq,
1244                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1245                                          "cyapa", cyapa);
1246        if (error) {
1247                dev_err(dev, "failed to request threaded irq: %d\n", error);
1248                return error;
1249        }
1250
1251        /* Disable IRQ until the device is opened */
1252        disable_irq(client->irq);
1253
1254        /*
1255         * Register the device in the input subsystem when it's operational.
1256         * Otherwise, keep in this driver, so it can be be recovered or updated
1257         * through the sysfs mode and update_fw interfaces by user or apps.
1258         */
1259        if (cyapa->operational) {
1260                error = cyapa_create_input_dev(cyapa);
1261                if (error) {
1262                        dev_err(dev, "create input_dev instance failed: %d\n",
1263                                        error);
1264                        return error;
1265                }
1266        }
1267
1268        return 0;
1269}
1270
1271static int __maybe_unused cyapa_suspend(struct device *dev)
1272{
1273        struct i2c_client *client = to_i2c_client(dev);
1274        struct cyapa *cyapa = i2c_get_clientdata(client);
1275        u8 power_mode;
1276        int error;
1277
1278        error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1279        if (error)
1280                return error;
1281
1282        /*
1283         * Runtime PM is enable only when device is in operational mode and
1284         * users in use, so need check it before disable it to
1285         * avoid unbalance warning.
1286         */
1287        if (pm_runtime_enabled(dev))
1288                pm_runtime_disable(dev);
1289        disable_irq(client->irq);
1290
1291        /*
1292         * Set trackpad device to idle mode if wakeup is allowed,
1293         * otherwise turn off.
1294         */
1295        if (cyapa->operational) {
1296                power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode
1297                                                    : PWR_MODE_OFF;
1298                error = cyapa->ops->set_power_mode(cyapa, power_mode,
1299                                cyapa->suspend_sleep_time);
1300                if (error)
1301                        dev_err(dev, "suspend set power mode failed: %d\n",
1302                                        error);
1303        }
1304
1305        if (device_may_wakeup(dev))
1306                cyapa->irq_wake = (enable_irq_wake(client->irq) == 0);
1307
1308        mutex_unlock(&cyapa->state_sync_lock);
1309        return 0;
1310}
1311
1312static int __maybe_unused cyapa_resume(struct device *dev)
1313{
1314        struct i2c_client *client = to_i2c_client(dev);
1315        struct cyapa *cyapa = i2c_get_clientdata(client);
1316        int error;
1317
1318        mutex_lock(&cyapa->state_sync_lock);
1319
1320        if (device_may_wakeup(dev) && cyapa->irq_wake) {
1321                disable_irq_wake(client->irq);
1322                cyapa->irq_wake = false;
1323        }
1324
1325        /* Update device states and runtime PM states. */
1326        error = cyapa_reinitialize(cyapa);
1327        if (error)
1328                dev_warn(dev, "failed to reinitialize TP device: %d\n", error);
1329
1330        enable_irq(client->irq);
1331
1332        mutex_unlock(&cyapa->state_sync_lock);
1333        return 0;
1334}
1335
1336static int __maybe_unused cyapa_runtime_suspend(struct device *dev)
1337{
1338        struct cyapa *cyapa = dev_get_drvdata(dev);
1339        int error;
1340
1341        error = cyapa->ops->set_power_mode(cyapa,
1342                        cyapa->runtime_suspend_power_mode,
1343                        cyapa->runtime_suspend_sleep_time);
1344        if (error)
1345                dev_warn(dev, "runtime suspend failed: %d\n", error);
1346
1347        return 0;
1348}
1349
1350static int __maybe_unused cyapa_runtime_resume(struct device *dev)
1351{
1352        struct cyapa *cyapa = dev_get_drvdata(dev);
1353        int error;
1354
1355        error = cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
1356        if (error)
1357                dev_warn(dev, "runtime resume failed: %d\n", error);
1358
1359        return 0;
1360}
1361
1362static const struct dev_pm_ops cyapa_pm_ops = {
1363        SET_SYSTEM_SLEEP_PM_OPS(cyapa_suspend, cyapa_resume)
1364        SET_RUNTIME_PM_OPS(cyapa_runtime_suspend, cyapa_runtime_resume, NULL)
1365};
1366
1367static const struct i2c_device_id cyapa_id_table[] = {
1368        { "cyapa", 0 },
1369        { },
1370};
1371MODULE_DEVICE_TABLE(i2c, cyapa_id_table);
1372
1373#ifdef CONFIG_ACPI
1374static const struct acpi_device_id cyapa_acpi_id[] = {
1375        { "CYAP0000", 0 },  /* Gen3 trackpad with 0x67 I2C address. */
1376        { "CYAP0001", 0 },  /* Gen5 trackpad with 0x24 I2C address. */
1377        { }
1378};
1379MODULE_DEVICE_TABLE(acpi, cyapa_acpi_id);
1380#endif
1381
1382static struct i2c_driver cyapa_driver = {
1383        .driver = {
1384                .name = "cyapa",
1385                .owner = THIS_MODULE,
1386                .pm = &cyapa_pm_ops,
1387                .acpi_match_table = ACPI_PTR(cyapa_acpi_id),
1388        },
1389
1390        .probe = cyapa_probe,
1391        .id_table = cyapa_id_table,
1392};
1393
1394module_i2c_driver(cyapa_driver);
1395
1396MODULE_DESCRIPTION("Cypress APA I2C Trackpad Driver");
1397MODULE_AUTHOR("Dudley Du <dudl@cypress.com>");
1398MODULE_LICENSE("GPL");
1399