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 error;
 226        u8 val[3];
 227
 228        error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
 229        if (error) {
 230                dev_err(&client->dev, "failed to get dimensions: %d\n", error);
 231                return error;
 232        }
 233
 234        *max_x = (0x0f & val[0]) << 8 | val[1];
 235        *max_y = (0xf0 & val[0]) << 4 | val[2];
 236
 237        return 0;
 238}
 239
 240static int elan_smbus_get_resolution(struct i2c_client *client,
 241                                     u8 *hw_res_x, u8 *hw_res_y)
 242{
 243        int error;
 244        u8 val[3];
 245
 246        error = i2c_smbus_read_block_data(client,
 247                                          ETP_SMBUS_RESOLUTION_CMD, val);
 248        if (error) {
 249                dev_err(&client->dev, "failed to get resolution: %d\n", error);
 250                return error;
 251        }
 252
 253        *hw_res_x = val[1] & 0x0F;
 254        *hw_res_y = (val[1] & 0xF0) >> 4;
 255
 256        return 0;
 257}
 258
 259static int elan_smbus_get_num_traces(struct i2c_client *client,
 260                                     unsigned int *x_traces,
 261                                     unsigned int *y_traces)
 262{
 263        int error;
 264        u8 val[3];
 265
 266        error = i2c_smbus_read_block_data(client,
 267                                          ETP_SMBUS_XY_TRACENUM_CMD, val);
 268        if (error) {
 269                dev_err(&client->dev, "failed to get trace info: %d\n", error);
 270                return error;
 271        }
 272
 273        *x_traces = val[1];
 274        *y_traces = val[2];
 275
 276        return 0;
 277}
 278
 279static int elan_smbus_get_pressure_adjustment(struct i2c_client *client,
 280                                              int *adjustment)
 281{
 282        *adjustment = ETP_PRESSURE_OFFSET;
 283        return 0;
 284}
 285
 286static int elan_smbus_iap_get_mode(struct i2c_client *client,
 287                                   enum tp_mode *mode)
 288{
 289        int error;
 290        u16 constant;
 291        u8 val[3];
 292
 293        error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
 294        if (error < 0) {
 295                dev_err(&client->dev, "failed to read iap ctrol register: %d\n",
 296                        error);
 297                return error;
 298        }
 299
 300        constant = be16_to_cpup((__be16 *)val);
 301        dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant);
 302
 303        *mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE;
 304
 305        return 0;
 306}
 307
 308static int elan_smbus_iap_reset(struct i2c_client *client)
 309{
 310        int error;
 311
 312        error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD);
 313        if (error) {
 314                dev_err(&client->dev, "cannot reset IC: %d\n", error);
 315                return error;
 316        }
 317
 318        return 0;
 319}
 320
 321static int elan_smbus_set_flash_key(struct i2c_client *client)
 322{
 323        int error;
 324        u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A };
 325
 326        error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
 327                                           sizeof(cmd), cmd);
 328        if (error) {
 329                dev_err(&client->dev, "cannot set flash key: %d\n", error);
 330                return error;
 331        }
 332
 333        return 0;
 334}
 335
 336static int elan_smbus_prepare_fw_update(struct i2c_client *client)
 337{
 338        struct device *dev = &client->dev;
 339        int len;
 340        int error;
 341        enum tp_mode mode;
 342        u8 val[3];
 343        u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
 344        u16 password;
 345
 346        /* Get FW in which mode (IAP_MODE/MAIN_MODE)  */
 347        error = elan_smbus_iap_get_mode(client, &mode);
 348        if (error)
 349                return error;
 350
 351        if (mode == MAIN_MODE) {
 352
 353                /* set flash key */
 354                error = elan_smbus_set_flash_key(client);
 355                if (error)
 356                        return error;
 357
 358                /* write iap password */
 359                if (i2c_smbus_write_byte(client,
 360                                         ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) {
 361                        dev_err(dev, "cannot write iap password\n");
 362                        return -EIO;
 363                }
 364
 365                error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
 366                                                   sizeof(cmd), cmd);
 367                if (error) {
 368                        dev_err(dev, "failed to write iap password: %d\n",
 369                                error);
 370                        return error;
 371                }
 372
 373                /*
 374                 * Read back password to make sure we enabled flash
 375                 * successfully.
 376                 */
 377                len = i2c_smbus_read_block_data(client,
 378                                                ETP_SMBUS_IAP_PASSWORD_READ,
 379                                                val);
 380                if (len < sizeof(u16)) {
 381                        error = len < 0 ? len : -EIO;
 382                        dev_err(dev, "failed to read iap password: %d\n",
 383                                error);
 384                        return error;
 385                }
 386
 387                password = be16_to_cpup((__be16 *)val);
 388                if (password != ETP_SMBUS_IAP_PASSWORD) {
 389                        dev_err(dev, "wrong iap password = 0x%X\n", password);
 390                        return -EIO;
 391                }
 392
 393                /* Wait 30ms for MAIN_MODE change to IAP_MODE */
 394                msleep(30);
 395        }
 396
 397        error = elan_smbus_set_flash_key(client);
 398        if (error)
 399                return error;
 400
 401        /* Reset IC */
 402        error = elan_smbus_iap_reset(client);
 403        if (error)
 404                return error;
 405
 406        return 0;
 407}
 408
 409
 410static int elan_smbus_write_fw_block(struct i2c_client *client,
 411                                     const u8 *page, u16 checksum, int idx)
 412{
 413        struct device *dev = &client->dev;
 414        int error;
 415        u16 result;
 416        u8 val[3];
 417
 418        /*
 419         * Due to the limitation of smbus protocol limiting
 420         * transfer to 32 bytes at a time, we must split block
 421         * in 2 transfers.
 422         */
 423        error = i2c_smbus_write_block_data(client,
 424                                           ETP_SMBUS_WRITE_FW_BLOCK,
 425                                           ETP_FW_PAGE_SIZE / 2,
 426                                           page);
 427        if (error) {
 428                dev_err(dev, "Failed to write page %d (part %d): %d\n",
 429                        idx, 1, error);
 430                return error;
 431        }
 432
 433        error = i2c_smbus_write_block_data(client,
 434                                           ETP_SMBUS_WRITE_FW_BLOCK,
 435                                           ETP_FW_PAGE_SIZE / 2,
 436                                           page + ETP_FW_PAGE_SIZE / 2);
 437        if (error) {
 438                dev_err(dev, "Failed to write page %d (part %d): %d\n",
 439                        idx, 2, error);
 440                return error;
 441        }
 442
 443
 444        /* Wait for F/W to update one page ROM data. */
 445        usleep_range(8000, 10000);
 446
 447        error = i2c_smbus_read_block_data(client,
 448                                          ETP_SMBUS_IAP_CTRL_CMD, val);
 449        if (error < 0) {
 450                dev_err(dev, "Failed to read IAP write result: %d\n",
 451                        error);
 452                return error;
 453        }
 454
 455        result = be16_to_cpup((__be16 *)val);
 456        if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) {
 457                dev_err(dev, "IAP reports failed write: %04hx\n",
 458                        result);
 459                return -EIO;
 460        }
 461
 462        return 0;
 463}
 464
 465static int elan_smbus_get_report(struct i2c_client *client, u8 *report)
 466{
 467        int len;
 468
 469        len = i2c_smbus_read_block_data(client,
 470                                        ETP_SMBUS_PACKET_QUERY,
 471                                        &report[ETP_SMBUS_REPORT_OFFSET]);
 472        if (len < 0) {
 473                dev_err(&client->dev, "failed to read report data: %d\n", len);
 474                return len;
 475        }
 476
 477        if (len != ETP_SMBUS_REPORT_LEN) {
 478                dev_err(&client->dev,
 479                        "wrong report length (%d vs %d expected)\n",
 480                        len, ETP_SMBUS_REPORT_LEN);
 481                return -EIO;
 482        }
 483
 484        return 0;
 485}
 486
 487static int elan_smbus_finish_fw_update(struct i2c_client *client,
 488                                       struct completion *fw_completion)
 489{
 490        /* No special handling unlike I2C transport */
 491        return 0;
 492}
 493
 494const struct elan_transport_ops elan_smbus_ops = {
 495        .initialize             = elan_smbus_initialize,
 496        .sleep_control          = elan_smbus_sleep_control,
 497        .power_control          = elan_smbus_power_control,
 498        .set_mode               = elan_smbus_set_mode,
 499
 500        .calibrate              = elan_smbus_calibrate,
 501        .calibrate_result       = elan_smbus_calibrate_result,
 502
 503        .get_baseline_data      = elan_smbus_get_baseline_data,
 504
 505        .get_version            = elan_smbus_get_version,
 506        .get_sm_version         = elan_smbus_get_sm_version,
 507        .get_product_id         = elan_smbus_get_product_id,
 508        .get_checksum           = elan_smbus_get_checksum,
 509        .get_pressure_adjustment = elan_smbus_get_pressure_adjustment,
 510
 511        .get_max                = elan_smbus_get_max,
 512        .get_resolution         = elan_smbus_get_resolution,
 513        .get_num_traces         = elan_smbus_get_num_traces,
 514
 515        .iap_get_mode           = elan_smbus_iap_get_mode,
 516        .iap_reset              = elan_smbus_iap_reset,
 517
 518        .prepare_fw_update      = elan_smbus_prepare_fw_update,
 519        .write_fw_block         = elan_smbus_write_fw_block,
 520        .finish_fw_update       = elan_smbus_finish_fw_update,
 521
 522        .get_report             = elan_smbus_get_report,
 523};
 524