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