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