linux/drivers/input/mouse/elan_i2c_smbus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Elan I2C/SMBus Touchpad driver - SMBus interface
   4 *
   5 * Copyright (c) 2013 ELAN Microelectronics Corp.
   6 *
   7 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
   8 *
   9 * Based on cyapa driver:
  10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
  11 * copyright (c) 2011-2012 Google, Inc.
  12 *
  13 * Trademarks are the property of their respective owners.
  14 */
  15
  16#include <linux/delay.h>
  17#include <linux/i2c.h>
  18#include <linux/init.h>
  19#include <linux/kernel.h>
  20
  21#include "elan_i2c.h"
  22
  23/* Elan SMbus commands */
  24#define ETP_SMBUS_IAP_CMD               0x00
  25#define ETP_SMBUS_ENABLE_TP             0x20
  26#define ETP_SMBUS_SLEEP_CMD             0x21
  27#define ETP_SMBUS_IAP_PASSWORD_WRITE    0x29
  28#define ETP_SMBUS_IAP_PASSWORD_READ     0x80
  29#define ETP_SMBUS_WRITE_FW_BLOCK        0x2A
  30#define ETP_SMBUS_IAP_RESET_CMD         0x2B
  31#define ETP_SMBUS_RANGE_CMD             0xA0
  32#define ETP_SMBUS_FW_VERSION_CMD        0xA1
  33#define ETP_SMBUS_XY_TRACENUM_CMD       0xA2
  34#define ETP_SMBUS_SM_VERSION_CMD        0xA3
  35#define ETP_SMBUS_UNIQUEID_CMD          0xA3
  36#define ETP_SMBUS_RESOLUTION_CMD        0xA4
  37#define ETP_SMBUS_HELLOPACKET_CMD       0xA7
  38#define ETP_SMBUS_PACKET_QUERY          0xA8
  39#define ETP_SMBUS_IAP_VERSION_CMD       0xAC
  40#define ETP_SMBUS_IAP_CTRL_CMD          0xAD
  41#define ETP_SMBUS_IAP_CHECKSUM_CMD      0xAE
  42#define ETP_SMBUS_FW_CHECKSUM_CMD       0xAF
  43#define ETP_SMBUS_MAX_BASELINE_CMD      0xC3
  44#define ETP_SMBUS_MIN_BASELINE_CMD      0xC4
  45#define ETP_SMBUS_CALIBRATE_QUERY       0xC5
  46
  47#define ETP_SMBUS_REPORT_LEN            32
  48#define ETP_SMBUS_REPORT_LEN2           7
  49#define ETP_SMBUS_REPORT_OFFSET         2
  50#define ETP_SMBUS_HELLOPACKET_LEN       5
  51#define ETP_SMBUS_IAP_PASSWORD          0x1234
  52#define ETP_SMBUS_IAP_MODE_ON           (1 << 6)
  53
  54static int elan_smbus_initialize(struct i2c_client *client)
  55{
  56        u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 };
  57        u8 values[I2C_SMBUS_BLOCK_MAX] = {0};
  58        int len, error;
  59
  60        /* Get hello packet */
  61        len = i2c_smbus_read_block_data(client,
  62                                        ETP_SMBUS_HELLOPACKET_CMD, values);
  63        if (len != ETP_SMBUS_HELLOPACKET_LEN) {
  64                dev_err(&client->dev, "hello packet length fail: %d\n", len);
  65                error = len < 0 ? len : -EIO;
  66                return error;
  67        }
  68
  69        /* compare hello packet */
  70        if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) {
  71                dev_err(&client->dev, "hello packet fail [%*ph]\n",
  72                        ETP_SMBUS_HELLOPACKET_LEN, values);
  73                return -ENXIO;
  74        }
  75
  76        /* enable tp */
  77        error = i2c_smbus_write_byte(client, ETP_SMBUS_ENABLE_TP);
  78        if (error) {
  79                dev_err(&client->dev, "failed to enable touchpad: %d\n", error);
  80                return error;
  81        }
  82
  83        return 0;
  84}
  85
  86static int elan_smbus_set_mode(struct i2c_client *client, u8 mode)
  87{
  88        u8 cmd[4] = { 0x00, 0x07, 0x00, mode };
  89
  90        return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
  91                                          sizeof(cmd), cmd);
  92}
  93
  94static int elan_smbus_sleep_control(struct i2c_client *client, bool sleep)
  95{
  96        if (sleep)
  97                return i2c_smbus_write_byte(client, ETP_SMBUS_SLEEP_CMD);
  98        else
  99                return 0; /* XXX should we send ETP_SMBUS_ENABLE_TP here? */
 100}
 101
 102static int elan_smbus_power_control(struct i2c_client *client, bool enable)
 103{
 104        return 0; /* A no-op */
 105}
 106
 107static int elan_smbus_calibrate(struct i2c_client *client)
 108{
 109        u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 };
 110
 111        return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
 112                                          sizeof(cmd), cmd);
 113}
 114
 115static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val)
 116{
 117        int error;
 118        u8 buf[I2C_SMBUS_BLOCK_MAX] = {0};
 119
 120        BUILD_BUG_ON(ETP_CALIBRATE_MAX_LEN > sizeof(buf));
 121
 122        error = i2c_smbus_read_block_data(client,
 123                                          ETP_SMBUS_CALIBRATE_QUERY, buf);
 124        if (error < 0)
 125                return error;
 126
 127        memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
 128        return 0;
 129}
 130
 131static int elan_smbus_get_baseline_data(struct i2c_client *client,
 132                                        bool max_baseline, u8 *value)
 133{
 134        int error;
 135        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 136
 137        error = i2c_smbus_read_block_data(client,
 138                                          max_baseline ?
 139                                                ETP_SMBUS_MAX_BASELINE_CMD :
 140                                                ETP_SMBUS_MIN_BASELINE_CMD,
 141                                          val);
 142        if (error < 0)
 143                return error;
 144
 145        *value = be16_to_cpup((__be16 *)val);
 146
 147        return 0;
 148}
 149
 150static int elan_smbus_get_version(struct i2c_client *client,
 151                                  u8 pattern, bool iap, u8 *version)
 152{
 153        int error;
 154        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 155
 156        error = i2c_smbus_read_block_data(client,
 157                                          iap ? ETP_SMBUS_IAP_VERSION_CMD :
 158                                                ETP_SMBUS_FW_VERSION_CMD,
 159                                          val);
 160        if (error < 0) {
 161                dev_err(&client->dev, "failed to get %s version: %d\n",
 162                        iap ? "IAP" : "FW", error);
 163                return error;
 164        }
 165
 166        *version = val[2];
 167        return 0;
 168}
 169
 170static int elan_smbus_get_sm_version(struct i2c_client *client, u8 pattern,
 171                                     u16 *ic_type, u8 *version, u8 *clickpad)
 172{
 173        int error;
 174        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 175
 176        error = i2c_smbus_read_block_data(client,
 177                                          ETP_SMBUS_SM_VERSION_CMD, val);
 178        if (error < 0) {
 179                dev_err(&client->dev, "failed to get SM version: %d\n", error);
 180                return error;
 181        }
 182
 183        *version = val[0];
 184        *ic_type = val[1];
 185        *clickpad = val[0] & 0x10;
 186        return 0;
 187}
 188
 189static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
 190{
 191        int error;
 192        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 193
 194        error = i2c_smbus_read_block_data(client,
 195                                          ETP_SMBUS_UNIQUEID_CMD, val);
 196        if (error < 0) {
 197                dev_err(&client->dev, "failed to get product ID: %d\n", error);
 198                return error;
 199        }
 200
 201        *id = be16_to_cpup((__be16 *)val);
 202        return 0;
 203}
 204
 205static int elan_smbus_get_checksum(struct i2c_client *client,
 206                                   bool iap, u16 *csum)
 207{
 208        int error;
 209        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 210
 211        error = i2c_smbus_read_block_data(client,
 212                                          iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
 213                                                ETP_SMBUS_IAP_CHECKSUM_CMD,
 214                                          val);
 215        if (error < 0) {
 216                dev_err(&client->dev, "failed to get %s checksum: %d\n",
 217                        iap ? "IAP" : "FW", error);
 218                return error;
 219        }
 220
 221        *csum = be16_to_cpup((__be16 *)val);
 222        return 0;
 223}
 224
 225static int elan_smbus_get_max(struct i2c_client *client,
 226                              unsigned int *max_x, unsigned int *max_y)
 227{
 228        int ret;
 229        int error;
 230        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 231
 232        ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
 233        if (ret != 3) {
 234                error = ret < 0 ? ret : -EIO;
 235                dev_err(&client->dev, "failed to get dimensions: %d\n", error);
 236                return error;
 237        }
 238
 239        *max_x = (0x0f & val[0]) << 8 | val[1];
 240        *max_y = (0xf0 & val[0]) << 4 | val[2];
 241
 242        return 0;
 243}
 244
 245static int elan_smbus_get_resolution(struct i2c_client *client,
 246                                     u8 *hw_res_x, u8 *hw_res_y)
 247{
 248        int ret;
 249        int error;
 250        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 251
 252        ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RESOLUTION_CMD, val);
 253        if (ret != 3) {
 254                error = ret < 0 ? ret : -EIO;
 255                dev_err(&client->dev, "failed to get resolution: %d\n", error);
 256                return error;
 257        }
 258
 259        *hw_res_x = val[1] & 0x0F;
 260        *hw_res_y = (val[1] & 0xF0) >> 4;
 261
 262        return 0;
 263}
 264
 265static int elan_smbus_get_num_traces(struct i2c_client *client,
 266                                     unsigned int *x_traces,
 267                                     unsigned int *y_traces)
 268{
 269        int ret;
 270        int error;
 271        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 272
 273        ret = i2c_smbus_read_block_data(client, ETP_SMBUS_XY_TRACENUM_CMD, val);
 274        if (ret != 3) {
 275                error = ret < 0 ? ret : -EIO;
 276                dev_err(&client->dev, "failed to get trace info: %d\n", error);
 277                return error;
 278        }
 279
 280        *x_traces = val[1];
 281        *y_traces = val[2];
 282
 283        return 0;
 284}
 285
 286static int elan_smbus_get_pressure_adjustment(struct i2c_client *client,
 287                                              int *adjustment)
 288{
 289        *adjustment = ETP_PRESSURE_OFFSET;
 290        return 0;
 291}
 292
 293static int elan_smbus_iap_get_mode(struct i2c_client *client,
 294                                   enum tp_mode *mode)
 295{
 296        int error;
 297        u16 constant;
 298        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 299
 300        error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
 301        if (error < 0) {
 302                dev_err(&client->dev, "failed to read iap ctrol register: %d\n",
 303                        error);
 304                return error;
 305        }
 306
 307        constant = be16_to_cpup((__be16 *)val);
 308        dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant);
 309
 310        *mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE;
 311
 312        return 0;
 313}
 314
 315static int elan_smbus_iap_reset(struct i2c_client *client)
 316{
 317        int error;
 318
 319        error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD);
 320        if (error) {
 321                dev_err(&client->dev, "cannot reset IC: %d\n", error);
 322                return error;
 323        }
 324
 325        return 0;
 326}
 327
 328static int elan_smbus_set_flash_key(struct i2c_client *client)
 329{
 330        int error;
 331        u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A };
 332
 333        error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
 334                                           sizeof(cmd), cmd);
 335        if (error) {
 336                dev_err(&client->dev, "cannot set flash key: %d\n", error);
 337                return error;
 338        }
 339
 340        return 0;
 341}
 342
 343static int elan_smbus_prepare_fw_update(struct i2c_client *client, u16 ic_type,
 344                                        u8 iap_version, u16 fw_page_size)
 345{
 346        struct device *dev = &client->dev;
 347        int len;
 348        int error;
 349        enum tp_mode mode;
 350        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 351        u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
 352        u16 password;
 353
 354        /* Get FW in which mode (IAP_MODE/MAIN_MODE)  */
 355        error = elan_smbus_iap_get_mode(client, &mode);
 356        if (error)
 357                return error;
 358
 359        if (mode == MAIN_MODE) {
 360
 361                /* set flash key */
 362                error = elan_smbus_set_flash_key(client);
 363                if (error)
 364                        return error;
 365
 366                /* write iap password */
 367                if (i2c_smbus_write_byte(client,
 368                                         ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) {
 369                        dev_err(dev, "cannot write iap password\n");
 370                        return -EIO;
 371                }
 372
 373                error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
 374                                                   sizeof(cmd), cmd);
 375                if (error) {
 376                        dev_err(dev, "failed to write iap password: %d\n",
 377                                error);
 378                        return error;
 379                }
 380
 381                /*
 382                 * Read back password to make sure we enabled flash
 383                 * successfully.
 384                 */
 385                len = i2c_smbus_read_block_data(client,
 386                                                ETP_SMBUS_IAP_PASSWORD_READ,
 387                                                val);
 388                if (len < (int)sizeof(u16)) {
 389                        error = len < 0 ? len : -EIO;
 390                        dev_err(dev, "failed to read iap password: %d\n",
 391                                error);
 392                        return error;
 393                }
 394
 395                password = be16_to_cpup((__be16 *)val);
 396                if (password != ETP_SMBUS_IAP_PASSWORD) {
 397                        dev_err(dev, "wrong iap password = 0x%X\n", password);
 398                        return -EIO;
 399                }
 400
 401                /* Wait 30ms for MAIN_MODE change to IAP_MODE */
 402                msleep(30);
 403        }
 404
 405        error = elan_smbus_set_flash_key(client);
 406        if (error)
 407                return error;
 408
 409        /* Reset IC */
 410        error = elan_smbus_iap_reset(client);
 411        if (error)
 412                return error;
 413
 414        return 0;
 415}
 416
 417
 418static int elan_smbus_write_fw_block(struct i2c_client *client, u16 fw_page_size,
 419                                     const u8 *page, u16 checksum, int idx)
 420{
 421        struct device *dev = &client->dev;
 422        int error;
 423        u16 result;
 424        u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 425
 426        /*
 427         * Due to the limitation of smbus protocol limiting
 428         * transfer to 32 bytes at a time, we must split block
 429         * in 2 transfers.
 430         */
 431        error = i2c_smbus_write_block_data(client,
 432                                           ETP_SMBUS_WRITE_FW_BLOCK,
 433                                           fw_page_size / 2,
 434                                           page);
 435        if (error) {
 436                dev_err(dev, "Failed to write page %d (part %d): %d\n",
 437                        idx, 1, error);
 438                return error;
 439        }
 440
 441        error = i2c_smbus_write_block_data(client,
 442                                           ETP_SMBUS_WRITE_FW_BLOCK,
 443                                           fw_page_size / 2,
 444                                           page + fw_page_size / 2);
 445        if (error) {
 446                dev_err(dev, "Failed to write page %d (part %d): %d\n",
 447                        idx, 2, error);
 448                return error;
 449        }
 450
 451
 452        /* Wait for F/W to update one page ROM data. */
 453        usleep_range(8000, 10000);
 454
 455        error = i2c_smbus_read_block_data(client,
 456                                          ETP_SMBUS_IAP_CTRL_CMD, val);
 457        if (error < 0) {
 458                dev_err(dev, "Failed to read IAP write result: %d\n",
 459                        error);
 460                return error;
 461        }
 462
 463        result = be16_to_cpup((__be16 *)val);
 464        if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) {
 465                dev_err(dev, "IAP reports failed write: %04hx\n",
 466                        result);
 467                return -EIO;
 468        }
 469
 470        return 0;
 471}
 472
 473static int elan_smbus_get_report_features(struct i2c_client *client, u8 pattern,
 474                                          unsigned int *features,
 475                                          unsigned int *report_len)
 476{
 477        /*
 478         * SMBus controllers with pattern 2 lack area info, as newer
 479         * high-precision packets use that space for coordinates.
 480         */
 481        *features = pattern <= 0x01 ? ETP_FEATURE_REPORT_MK : 0;
 482        *report_len = ETP_SMBUS_REPORT_LEN;
 483        return 0;
 484}
 485
 486static int elan_smbus_get_report(struct i2c_client *client,
 487                                 u8 *report, unsigned int report_len)
 488{
 489        int len;
 490
 491        BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);
 492
 493        len = i2c_smbus_read_block_data(client,
 494                                        ETP_SMBUS_PACKET_QUERY,
 495                                        &report[ETP_SMBUS_REPORT_OFFSET]);
 496        if (len < 0) {
 497                dev_err(&client->dev, "failed to read report data: %d\n", len);
 498                return len;
 499        }
 500
 501        if (report[ETP_REPORT_ID_OFFSET] == ETP_TP_REPORT_ID2)
 502                report_len = ETP_SMBUS_REPORT_LEN2;
 503
 504        if (len != report_len) {
 505                dev_err(&client->dev,
 506                        "wrong report length (%d vs %d expected)\n",
 507                        len, report_len);
 508                return -EIO;
 509        }
 510
 511        return 0;
 512}
 513
 514static int elan_smbus_finish_fw_update(struct i2c_client *client,
 515                                       struct completion *fw_completion)
 516{
 517        /* No special handling unlike I2C transport */
 518        return 0;
 519}
 520
 521static int elan_smbus_get_pattern(struct i2c_client *client, u8 *pattern)
 522{
 523        *pattern = 0;
 524        return 0;
 525}
 526
 527const struct elan_transport_ops elan_smbus_ops = {
 528        .initialize             = elan_smbus_initialize,
 529        .sleep_control          = elan_smbus_sleep_control,
 530        .power_control          = elan_smbus_power_control,
 531        .set_mode               = elan_smbus_set_mode,
 532
 533        .calibrate              = elan_smbus_calibrate,
 534        .calibrate_result       = elan_smbus_calibrate_result,
 535
 536        .get_baseline_data      = elan_smbus_get_baseline_data,
 537
 538        .get_version            = elan_smbus_get_version,
 539        .get_sm_version         = elan_smbus_get_sm_version,
 540        .get_product_id         = elan_smbus_get_product_id,
 541        .get_checksum           = elan_smbus_get_checksum,
 542        .get_pressure_adjustment = elan_smbus_get_pressure_adjustment,
 543
 544        .get_max                = elan_smbus_get_max,
 545        .get_resolution         = elan_smbus_get_resolution,
 546        .get_num_traces         = elan_smbus_get_num_traces,
 547
 548        .iap_get_mode           = elan_smbus_iap_get_mode,
 549        .iap_reset              = elan_smbus_iap_reset,
 550
 551        .prepare_fw_update      = elan_smbus_prepare_fw_update,
 552        .write_fw_block         = elan_smbus_write_fw_block,
 553        .finish_fw_update       = elan_smbus_finish_fw_update,
 554
 555        .get_report_features    = elan_smbus_get_report_features,
 556        .get_report             = elan_smbus_get_report,
 557        .get_pattern            = elan_smbus_get_pattern,
 558};
 559