linux/drivers/input/touchscreen/wdt87xx_i2c.c
<<
>>
Prefs
   1/*
   2 * Weida HiTech WDT87xx TouchScreen I2C driver
   3 *
   4 * Copyright (c) 2015  Weida Hi-Tech Co., Ltd.
   5 * HN Chen <hn.chen@weidahitech.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 */
  11
  12#include <linux/i2c.h>
  13#include <linux/input.h>
  14#include <linux/interrupt.h>
  15#include <linux/delay.h>
  16#include <linux/irq.h>
  17#include <linux/io.h>
  18#include <linux/module.h>
  19#include <linux/slab.h>
  20#include <linux/firmware.h>
  21#include <linux/input/mt.h>
  22#include <linux/acpi.h>
  23#include <asm/unaligned.h>
  24
  25#define WDT87XX_NAME            "wdt87xx_i2c"
  26#define WDT87XX_FW_NAME         "wdt87xx_fw.bin"
  27#define WDT87XX_CFG_NAME        "wdt87xx_cfg.bin"
  28
  29#define MODE_ACTIVE                     0x01
  30#define MODE_READY                      0x02
  31#define MODE_IDLE                       0x03
  32#define MODE_SLEEP                      0x04
  33#define MODE_STOP                       0xFF
  34
  35#define WDT_MAX_FINGER                  10
  36#define WDT_RAW_BUF_COUNT               54
  37#define WDT_V1_RAW_BUF_COUNT            74
  38#define WDT_FIRMWARE_ID                 0xa9e368f5
  39
  40#define PG_SIZE                         0x1000
  41#define MAX_RETRIES                     3
  42
  43#define MAX_UNIT_AXIS                   0x7FFF
  44
  45#define PKT_READ_SIZE                   72
  46#define PKT_WRITE_SIZE                  80
  47
  48/* the finger definition of the report event */
  49#define FINGER_EV_OFFSET_ID             0
  50#define FINGER_EV_OFFSET_X              1
  51#define FINGER_EV_OFFSET_Y              3
  52#define FINGER_EV_SIZE                  5
  53
  54#define FINGER_EV_V1_OFFSET_ID          0
  55#define FINGER_EV_V1_OFFSET_W           1
  56#define FINGER_EV_V1_OFFSET_P           2
  57#define FINGER_EV_V1_OFFSET_X           3
  58#define FINGER_EV_V1_OFFSET_Y           5
  59#define FINGER_EV_V1_SIZE               7
  60
  61/* The definition of a report packet */
  62#define TOUCH_PK_OFFSET_REPORT_ID       0
  63#define TOUCH_PK_OFFSET_EVENT           1
  64#define TOUCH_PK_OFFSET_SCAN_TIME       51
  65#define TOUCH_PK_OFFSET_FNGR_NUM        53
  66
  67#define TOUCH_PK_V1_OFFSET_REPORT_ID    0
  68#define TOUCH_PK_V1_OFFSET_EVENT        1
  69#define TOUCH_PK_V1_OFFSET_SCAN_TIME    71
  70#define TOUCH_PK_V1_OFFSET_FNGR_NUM     73
  71
  72/* The definition of the controller parameters */
  73#define CTL_PARAM_OFFSET_FW_ID          0
  74#define CTL_PARAM_OFFSET_PLAT_ID        2
  75#define CTL_PARAM_OFFSET_XMLS_ID1       4
  76#define CTL_PARAM_OFFSET_XMLS_ID2       6
  77#define CTL_PARAM_OFFSET_PHY_CH_X       8
  78#define CTL_PARAM_OFFSET_PHY_CH_Y       10
  79#define CTL_PARAM_OFFSET_PHY_X0         12
  80#define CTL_PARAM_OFFSET_PHY_X1         14
  81#define CTL_PARAM_OFFSET_PHY_Y0         16
  82#define CTL_PARAM_OFFSET_PHY_Y1         18
  83#define CTL_PARAM_OFFSET_PHY_W          22
  84#define CTL_PARAM_OFFSET_PHY_H          24
  85#define CTL_PARAM_OFFSET_FACTOR         32
  86
  87/* The definition of the device descriptor */
  88#define WDT_GD_DEVICE                   1
  89#define DEV_DESC_OFFSET_VID             8
  90#define DEV_DESC_OFFSET_PID             10
  91
  92/* Communication commands */
  93#define PACKET_SIZE                     56
  94#define VND_REQ_READ                    0x06
  95#define VND_READ_DATA                   0x07
  96#define VND_REQ_WRITE                   0x08
  97
  98#define VND_CMD_START                   0x00
  99#define VND_CMD_STOP                    0x01
 100#define VND_CMD_RESET                   0x09
 101
 102#define VND_CMD_ERASE                   0x1A
 103
 104#define VND_GET_CHECKSUM                0x66
 105
 106#define VND_SET_DATA                    0x83
 107#define VND_SET_COMMAND_DATA            0x84
 108#define VND_SET_CHECKSUM_CALC           0x86
 109#define VND_SET_CHECKSUM_LENGTH         0x87
 110
 111#define VND_CMD_SFLCK                   0xFC
 112#define VND_CMD_SFUNL                   0xFD
 113
 114#define CMD_SFLCK_KEY                   0xC39B
 115#define CMD_SFUNL_KEY                   0x95DA
 116
 117#define STRIDX_PLATFORM_ID              0x80
 118#define STRIDX_PARAMETERS               0x81
 119
 120#define CMD_BUF_SIZE                    8
 121#define PKT_BUF_SIZE                    64
 122
 123/* The definition of the command packet */
 124#define CMD_REPORT_ID_OFFSET            0x0
 125#define CMD_TYPE_OFFSET                 0x1
 126#define CMD_INDEX_OFFSET                0x2
 127#define CMD_KEY_OFFSET                  0x3
 128#define CMD_LENGTH_OFFSET               0x4
 129#define CMD_DATA_OFFSET                 0x8
 130
 131/* The definition of firmware chunk tags */
 132#define FOURCC_ID_RIFF                  0x46464952
 133#define FOURCC_ID_WHIF                  0x46494857
 134#define FOURCC_ID_FRMT                  0x544D5246
 135#define FOURCC_ID_FRWR                  0x52575246
 136#define FOURCC_ID_CNFG                  0x47464E43
 137
 138#define CHUNK_ID_FRMT                   FOURCC_ID_FRMT
 139#define CHUNK_ID_FRWR                   FOURCC_ID_FRWR
 140#define CHUNK_ID_CNFG                   FOURCC_ID_CNFG
 141
 142#define FW_FOURCC1_OFFSET               0
 143#define FW_SIZE_OFFSET                  4
 144#define FW_FOURCC2_OFFSET               8
 145#define FW_PAYLOAD_OFFSET               40
 146
 147#define FW_CHUNK_ID_OFFSET              0
 148#define FW_CHUNK_SIZE_OFFSET            4
 149#define FW_CHUNK_TGT_START_OFFSET       8
 150#define FW_CHUNK_PAYLOAD_LEN_OFFSET     12
 151#define FW_CHUNK_SRC_START_OFFSET       16
 152#define FW_CHUNK_VERSION_OFFSET         20
 153#define FW_CHUNK_ATTR_OFFSET            24
 154#define FW_CHUNK_PAYLOAD_OFFSET         32
 155
 156/* Controller requires minimum 300us between commands */
 157#define WDT_COMMAND_DELAY_MS            2
 158#define WDT_FLASH_WRITE_DELAY_MS        4
 159#define WDT_FLASH_ERASE_DELAY_MS        200
 160#define WDT_FW_RESET_TIME               2500
 161
 162struct wdt87xx_sys_param {
 163        u16     fw_id;
 164        u16     plat_id;
 165        u16     xmls_id1;
 166        u16     xmls_id2;
 167        u16     phy_ch_x;
 168        u16     phy_ch_y;
 169        u16     phy_w;
 170        u16     phy_h;
 171        u16     scaling_factor;
 172        u32     max_x;
 173        u32     max_y;
 174        u16     vendor_id;
 175        u16     product_id;
 176};
 177
 178struct wdt87xx_data {
 179        struct i2c_client               *client;
 180        struct input_dev                *input;
 181        /* Mutex for fw update to prevent concurrent access */
 182        struct mutex                    fw_mutex;
 183        struct wdt87xx_sys_param        param;
 184        u8                              phys[32];
 185};
 186
 187static int wdt87xx_i2c_xfer(struct i2c_client *client,
 188                            void *txdata, size_t txlen,
 189                            void *rxdata, size_t rxlen)
 190{
 191        struct i2c_msg msgs[] = {
 192                {
 193                        .addr   = client->addr,
 194                        .flags  = 0,
 195                        .len    = txlen,
 196                        .buf    = txdata,
 197                },
 198                {
 199                        .addr   = client->addr,
 200                        .flags  = I2C_M_RD,
 201                        .len    = rxlen,
 202                        .buf    = rxdata,
 203                },
 204        };
 205        int error;
 206        int ret;
 207
 208        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 209        if (ret != ARRAY_SIZE(msgs)) {
 210                error = ret < 0 ? ret : -EIO;
 211                dev_err(&client->dev, "%s: i2c transfer failed: %d\n",
 212                        __func__, error);
 213                return error;
 214        }
 215
 216        return 0;
 217}
 218
 219static int wdt87xx_get_desc(struct i2c_client *client, u8 desc_idx,
 220                            u8 *buf, size_t len)
 221{
 222        u8 tx_buf[] = { 0x22, 0x00, 0x10, 0x0E, 0x23, 0x00 };
 223        int error;
 224
 225        tx_buf[2] |= desc_idx & 0xF;
 226
 227        error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
 228                                 buf, len);
 229        if (error) {
 230                dev_err(&client->dev, "get desc failed: %d\n", error);
 231                return error;
 232        }
 233
 234        if (buf[0] != len) {
 235                dev_err(&client->dev, "unexpected response to get desc: %d\n",
 236                        buf[0]);
 237                return -EINVAL;
 238        }
 239
 240        mdelay(WDT_COMMAND_DELAY_MS);
 241
 242        return 0;
 243}
 244
 245static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
 246                              u8 *buf, size_t len)
 247{
 248        u8 tx_buf[] = { 0x22, 0x00, 0x13, 0x0E, str_idx, 0x23, 0x00 };
 249        u8 rx_buf[PKT_WRITE_SIZE];
 250        size_t rx_len = len + 2;
 251        int error;
 252
 253        if (rx_len > sizeof(rx_buf))
 254                return -EINVAL;
 255
 256        error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
 257                                 rx_buf, rx_len);
 258        if (error) {
 259                dev_err(&client->dev, "get string failed: %d\n", error);
 260                return error;
 261        }
 262
 263        if (rx_buf[1] != 0x03) {
 264                dev_err(&client->dev, "unexpected response to get string: %d\n",
 265                        rx_buf[1]);
 266                return -EINVAL;
 267        }
 268
 269        rx_len = min_t(size_t, len, rx_buf[0]);
 270        memcpy(buf, &rx_buf[2], rx_len);
 271
 272        mdelay(WDT_COMMAND_DELAY_MS);
 273
 274        return 0;
 275}
 276
 277static int wdt87xx_get_feature(struct i2c_client *client,
 278                               u8 *buf, size_t buf_size)
 279{
 280        u8 tx_buf[8];
 281        u8 rx_buf[PKT_WRITE_SIZE];
 282        size_t tx_len = 0;
 283        size_t rx_len = buf_size + 2;
 284        int error;
 285
 286        if (rx_len > sizeof(rx_buf))
 287                return -EINVAL;
 288
 289        /* Get feature command packet */
 290        tx_buf[tx_len++] = 0x22;
 291        tx_buf[tx_len++] = 0x00;
 292        if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
 293                tx_buf[tx_len++] = 0x30;
 294                tx_buf[tx_len++] = 0x02;
 295                tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
 296        } else {
 297                tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
 298                tx_buf[tx_len++] = 0x02;
 299        }
 300        tx_buf[tx_len++] = 0x23;
 301        tx_buf[tx_len++] = 0x00;
 302
 303        error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
 304        if (error) {
 305                dev_err(&client->dev, "get feature failed: %d\n", error);
 306                return error;
 307        }
 308
 309        rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
 310        memcpy(buf, &rx_buf[2], rx_len);
 311
 312        mdelay(WDT_COMMAND_DELAY_MS);
 313
 314        return 0;
 315}
 316
 317static int wdt87xx_set_feature(struct i2c_client *client,
 318                               const u8 *buf, size_t buf_size)
 319{
 320        u8 tx_buf[PKT_WRITE_SIZE];
 321        int tx_len = 0;
 322        int error;
 323
 324        /* Set feature command packet */
 325        tx_buf[tx_len++] = 0x22;
 326        tx_buf[tx_len++] = 0x00;
 327        if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
 328                tx_buf[tx_len++] = 0x30;
 329                tx_buf[tx_len++] = 0x03;
 330                tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
 331        } else {
 332                tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
 333                tx_buf[tx_len++] = 0x03;
 334        }
 335        tx_buf[tx_len++] = 0x23;
 336        tx_buf[tx_len++] = 0x00;
 337        tx_buf[tx_len++] = (buf_size & 0xFF);
 338        tx_buf[tx_len++] = ((buf_size & 0xFF00) >> 8);
 339
 340        if (tx_len + buf_size > sizeof(tx_buf))
 341                return -EINVAL;
 342
 343        memcpy(&tx_buf[tx_len], buf, buf_size);
 344        tx_len += buf_size;
 345
 346        error = i2c_master_send(client, tx_buf, tx_len);
 347        if (error < 0) {
 348                dev_err(&client->dev, "set feature failed: %d\n", error);
 349                return error;
 350        }
 351
 352        mdelay(WDT_COMMAND_DELAY_MS);
 353
 354        return 0;
 355}
 356
 357static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
 358{
 359        u8 cmd_buf[CMD_BUF_SIZE];
 360
 361        /* Set the command packet */
 362        cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
 363        cmd_buf[CMD_TYPE_OFFSET] = VND_SET_COMMAND_DATA;
 364        put_unaligned_le16((u16)cmd, &cmd_buf[CMD_INDEX_OFFSET]);
 365
 366        switch (cmd) {
 367        case VND_CMD_START:
 368        case VND_CMD_STOP:
 369        case VND_CMD_RESET:
 370                /* Mode selector */
 371                put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
 372                break;
 373
 374        case VND_CMD_SFLCK:
 375                put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
 376                break;
 377
 378        case VND_CMD_SFUNL:
 379                put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
 380                break;
 381
 382        case VND_CMD_ERASE:
 383        case VND_SET_CHECKSUM_CALC:
 384        case VND_SET_CHECKSUM_LENGTH:
 385                put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
 386                break;
 387
 388        default:
 389                cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
 390                dev_err(&client->dev, "Invalid command: %d\n", cmd);
 391                return -EINVAL;
 392        }
 393
 394        return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
 395}
 396
 397static int wdt87xx_sw_reset(struct i2c_client *client)
 398{
 399        int error;
 400
 401        dev_dbg(&client->dev, "resetting device now\n");
 402
 403        error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
 404        if (error) {
 405                dev_err(&client->dev, "reset failed\n");
 406                return error;
 407        }
 408
 409        /* Wait the device to be ready */
 410        msleep(WDT_FW_RESET_TIME);
 411
 412        return 0;
 413}
 414
 415static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
 416{
 417        size_t pos = FW_PAYLOAD_OFFSET;
 418        u32 chunk_id, chunk_size;
 419
 420        while (pos < fw->size) {
 421                chunk_id = get_unaligned_le32(fw->data +
 422                                              pos + FW_CHUNK_ID_OFFSET);
 423                if (chunk_id == id)
 424                        return fw->data + pos;
 425
 426                chunk_size = get_unaligned_le32(fw->data +
 427                                                pos + FW_CHUNK_SIZE_OFFSET);
 428                pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
 429        }
 430
 431        return NULL;
 432}
 433
 434static int wdt87xx_get_sysparam(struct i2c_client *client,
 435                                struct wdt87xx_sys_param *param)
 436{
 437        u8 buf[PKT_READ_SIZE];
 438        int error;
 439
 440        error = wdt87xx_get_desc(client, WDT_GD_DEVICE, buf, 18);
 441        if (error) {
 442                dev_err(&client->dev, "failed to get device desc\n");
 443                return error;
 444        }
 445
 446        param->vendor_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_VID);
 447        param->product_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_PID);
 448
 449        error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
 450        if (error) {
 451                dev_err(&client->dev, "failed to get parameters\n");
 452                return error;
 453        }
 454
 455        param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1);
 456        param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2);
 457        param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X);
 458        param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y);
 459        param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10;
 460        param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10;
 461
 462        /* Get the scaling factor of pixel to logical coordinate */
 463        param->scaling_factor =
 464                        get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);
 465
 466        param->max_x = MAX_UNIT_AXIS;
 467        param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
 468                                         param->phy_w);
 469
 470        error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
 471        if (error) {
 472                dev_err(&client->dev, "failed to get platform id\n");
 473                return error;
 474        }
 475
 476        param->plat_id = buf[1];
 477
 478        buf[0] = 0xf2;
 479        error = wdt87xx_get_feature(client, buf, 16);
 480        if (error) {
 481                dev_err(&client->dev, "failed to get firmware id\n");
 482                return error;
 483        }
 484
 485        if (buf[0] != 0xf2) {
 486                dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
 487                        buf[0]);
 488                return -EINVAL;
 489        }
 490
 491        param->fw_id = get_unaligned_le16(&buf[1]);
 492
 493        dev_info(&client->dev,
 494                 "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
 495                 param->fw_id, param->plat_id,
 496                 param->xmls_id1, param->xmls_id2);
 497
 498        return 0;
 499}
 500
 501static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
 502                                     const struct firmware *fw)
 503{
 504        const void *fw_chunk;
 505        u32 data1, data2;
 506        u32 size;
 507        u8 fw_chip_id;
 508        u8 chip_id;
 509
 510        data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET);
 511        data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET);
 512        if (data1 != FOURCC_ID_RIFF || data2 != FOURCC_ID_WHIF) {
 513                dev_err(&wdt->client->dev, "check fw tag failed\n");
 514                return -EINVAL;
 515        }
 516
 517        size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET);
 518        if (size != fw->size) {
 519                dev_err(&wdt->client->dev,
 520                        "fw size mismatch: expected %d, actual %zu\n",
 521                        size, fw->size);
 522                return -EINVAL;
 523        }
 524
 525        /*
 526         * Get the chip_id from the firmware. Make sure that it is the
 527         * right controller to do the firmware and config update.
 528         */
 529        fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
 530        if (!fw_chunk) {
 531                dev_err(&wdt->client->dev,
 532                        "unable to locate firmware chunk\n");
 533                return -EINVAL;
 534        }
 535
 536        fw_chip_id = (get_unaligned_le32(fw_chunk +
 537                                         FW_CHUNK_VERSION_OFFSET) >> 12) & 0xF;
 538        chip_id = (wdt->param.fw_id >> 12) & 0xF;
 539
 540        if (fw_chip_id != chip_id) {
 541                dev_err(&wdt->client->dev,
 542                        "fw version mismatch: fw %d vs. chip %d\n",
 543                        fw_chip_id, chip_id);
 544                return -ENODEV;
 545        }
 546
 547        return 0;
 548}
 549
 550static int wdt87xx_validate_fw_chunk(const void *data, int id)
 551{
 552        if (id == CHUNK_ID_FRWR) {
 553                u32 fw_id;
 554
 555                fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
 556                if (fw_id != WDT_FIRMWARE_ID)
 557                        return -EINVAL;
 558        }
 559
 560        return 0;
 561}
 562
 563static int wdt87xx_write_data(struct i2c_client *client, const char *data,
 564                              u32 address, int length)
 565{
 566        u16 packet_size;
 567        int count = 0;
 568        int error;
 569        u8 pkt_buf[PKT_BUF_SIZE];
 570
 571        /* Address and length should be 4 bytes aligned */
 572        if ((address & 0x3) != 0 || (length & 0x3) != 0) {
 573                dev_err(&client->dev,
 574                        "addr & len must be 4 bytes aligned %x, %x\n",
 575                        address, length);
 576                return -EINVAL;
 577        }
 578
 579        while (length) {
 580                packet_size = min(length, PACKET_SIZE);
 581
 582                pkt_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
 583                pkt_buf[CMD_TYPE_OFFSET] = VND_SET_DATA;
 584                put_unaligned_le16(packet_size, &pkt_buf[CMD_INDEX_OFFSET]);
 585                put_unaligned_le32(address, &pkt_buf[CMD_LENGTH_OFFSET]);
 586                memcpy(&pkt_buf[CMD_DATA_OFFSET], data, packet_size);
 587
 588                error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
 589                if (error)
 590                        return error;
 591
 592                length -= packet_size;
 593                data += packet_size;
 594                address += packet_size;
 595
 596                /* Wait for the controller to finish the write */
 597                mdelay(WDT_FLASH_WRITE_DELAY_MS);
 598
 599                if ((++count % 32) == 0) {
 600                        /* Delay for fw to clear watch dog */
 601                        msleep(20);
 602                }
 603        }
 604
 605        return 0;
 606}
 607
 608static u16 misr(u16 cur_value, u8 new_value)
 609{
 610        u32 a, b;
 611        u32 bit0;
 612        u32 y;
 613
 614        a = cur_value;
 615        b = new_value;
 616        bit0 = a ^ (b & 1);
 617        bit0 ^= a >> 1;
 618        bit0 ^= a >> 2;
 619        bit0 ^= a >> 4;
 620        bit0 ^= a >> 5;
 621        bit0 ^= a >> 7;
 622        bit0 ^= a >> 11;
 623        bit0 ^= a >> 15;
 624        y = (a << 1) ^ b;
 625        y = (y & ~1) | (bit0 & 1);
 626
 627        return (u16)y;
 628}
 629
 630static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
 631{
 632        u16 checksum = 0;
 633        size_t i;
 634
 635        for (i = 0; i < length; i++)
 636                checksum = misr(checksum, data[i]);
 637
 638        return checksum;
 639}
 640
 641static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
 642                                u32 address, int length)
 643{
 644        int error;
 645        int time_delay;
 646        u8 pkt_buf[PKT_BUF_SIZE];
 647        u8 cmd_buf[CMD_BUF_SIZE];
 648
 649        error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
 650        if (error) {
 651                dev_err(&client->dev, "failed to set checksum length\n");
 652                return error;
 653        }
 654
 655        error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
 656        if (error) {
 657                dev_err(&client->dev, "failed to set checksum address\n");
 658                return error;
 659        }
 660
 661        /* Wait the operation to complete */
 662        time_delay = DIV_ROUND_UP(length, 1024);
 663        msleep(time_delay * 30);
 664
 665        memset(cmd_buf, 0, sizeof(cmd_buf));
 666        cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_READ;
 667        cmd_buf[CMD_TYPE_OFFSET] = VND_GET_CHECKSUM;
 668        error = wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
 669        if (error) {
 670                dev_err(&client->dev, "failed to request checksum\n");
 671                return error;
 672        }
 673
 674        memset(pkt_buf, 0, sizeof(pkt_buf));
 675        pkt_buf[CMD_REPORT_ID_OFFSET] = VND_READ_DATA;
 676        error = wdt87xx_get_feature(client, pkt_buf, sizeof(pkt_buf));
 677        if (error) {
 678                dev_err(&client->dev, "failed to read checksum\n");
 679                return error;
 680        }
 681
 682        *checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
 683        return 0;
 684}
 685
 686static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
 687{
 688        u32 start_addr = get_unaligned_le32(chunk + FW_CHUNK_TGT_START_OFFSET);
 689        u32 size = get_unaligned_le32(chunk + FW_CHUNK_PAYLOAD_LEN_OFFSET);
 690        const void *data = chunk + FW_CHUNK_PAYLOAD_OFFSET;
 691        int error;
 692        int err1;
 693        int page_size;
 694        int retry = 0;
 695        u16 device_checksum, firmware_checksum;
 696
 697        dev_dbg(&client->dev, "start 4k page program\n");
 698
 699        error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
 700        if (error) {
 701                dev_err(&client->dev, "stop report mode failed\n");
 702                return error;
 703        }
 704
 705        error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
 706        if (error) {
 707                dev_err(&client->dev, "unlock failed\n");
 708                goto out_enable_reporting;
 709        }
 710
 711        mdelay(10);
 712
 713        while (size) {
 714                dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
 715                        start_addr, size);
 716
 717                page_size = min_t(u32, size, PG_SIZE);
 718                size -= page_size;
 719
 720                for (retry = 0; retry < MAX_RETRIES; retry++) {
 721                        error = wdt87xx_send_command(client, VND_CMD_ERASE,
 722                                                     start_addr);
 723                        if (error) {
 724                                dev_err(&client->dev,
 725                                        "erase failed at %#08x\n", start_addr);
 726                                break;
 727                        }
 728
 729                        msleep(WDT_FLASH_ERASE_DELAY_MS);
 730
 731                        error = wdt87xx_write_data(client, data, start_addr,
 732                                                   page_size);
 733                        if (error) {
 734                                dev_err(&client->dev,
 735                                        "write failed at %#08x (%d bytes)\n",
 736                                        start_addr, page_size);
 737                                break;
 738                        }
 739
 740                        error = wdt87xx_get_checksum(client, &device_checksum,
 741                                                     start_addr, page_size);
 742                        if (error) {
 743                                dev_err(&client->dev,
 744                                        "failed to retrieve checksum for %#08x (len: %d)\n",
 745                                        start_addr, page_size);
 746                                break;
 747                        }
 748
 749                        firmware_checksum =
 750                                wdt87xx_calculate_checksum(data, page_size);
 751
 752                        if (device_checksum == firmware_checksum)
 753                                break;
 754
 755                        dev_err(&client->dev,
 756                                "checksum fail: %d vs %d, retry %d\n",
 757                                device_checksum, firmware_checksum, retry);
 758                }
 759
 760                if (retry == MAX_RETRIES) {
 761                        dev_err(&client->dev, "page write failed\n");
 762                        error = -EIO;
 763                        goto out_lock_device;
 764                }
 765
 766                start_addr = start_addr + page_size;
 767                data = data + page_size;
 768        }
 769
 770out_lock_device:
 771        err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
 772        if (err1)
 773                dev_err(&client->dev, "lock failed\n");
 774
 775        mdelay(10);
 776
 777out_enable_reporting:
 778        err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
 779        if (err1)
 780                dev_err(&client->dev, "start to report failed\n");
 781
 782        return error ? error : err1;
 783}
 784
 785static int wdt87xx_load_chunk(struct i2c_client *client,
 786                              const struct firmware *fw, u32 ck_id)
 787{
 788        const void *chunk;
 789        int error;
 790
 791        chunk = wdt87xx_get_fw_chunk(fw, ck_id);
 792        if (!chunk) {
 793                dev_err(&client->dev, "unable to locate chunk (type %d)\n",
 794                        ck_id);
 795                return -EINVAL;
 796        }
 797
 798        error = wdt87xx_validate_fw_chunk(chunk, ck_id);
 799        if (error) {
 800                dev_err(&client->dev, "invalid chunk (type %d): %d\n",
 801                        ck_id, error);
 802                return error;
 803        }
 804
 805        error = wdt87xx_write_firmware(client, chunk);
 806        if (error) {
 807                dev_err(&client->dev,
 808                        "failed to write fw chunk (type %d): %d\n",
 809                        ck_id, error);
 810                return error;
 811        }
 812
 813        return 0;
 814}
 815
 816static int wdt87xx_do_update_firmware(struct i2c_client *client,
 817                                      const struct firmware *fw,
 818                                      unsigned int chunk_id)
 819{
 820        struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 821        int error;
 822
 823        error = wdt87xx_validate_firmware(wdt, fw);
 824        if (error)
 825                return error;
 826
 827        error = mutex_lock_interruptible(&wdt->fw_mutex);
 828        if (error)
 829                return error;
 830
 831        disable_irq(client->irq);
 832
 833        error = wdt87xx_load_chunk(client, fw, chunk_id);
 834        if (error) {
 835                dev_err(&client->dev,
 836                        "firmware load failed (type: %d): %d\n",
 837                        chunk_id, error);
 838                goto out;
 839        }
 840
 841        error = wdt87xx_sw_reset(client);
 842        if (error) {
 843                dev_err(&client->dev, "soft reset failed: %d\n", error);
 844                goto out;
 845        }
 846
 847        /* Refresh the parameters */
 848        error = wdt87xx_get_sysparam(client, &wdt->param);
 849        if (error)
 850                dev_err(&client->dev,
 851                        "failed to refresh system parameters: %d\n", error);
 852out:
 853        enable_irq(client->irq);
 854        mutex_unlock(&wdt->fw_mutex);
 855
 856        return error ? error : 0;
 857}
 858
 859static int wdt87xx_update_firmware(struct device *dev,
 860                                   const char *fw_name, unsigned int chunk_id)
 861{
 862        struct i2c_client *client = to_i2c_client(dev);
 863        const struct firmware *fw;
 864        int error;
 865
 866        error = request_firmware(&fw, fw_name, dev);
 867        if (error) {
 868                dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
 869                        fw_name, error);
 870                return error;
 871        }
 872
 873        error = wdt87xx_do_update_firmware(client, fw, chunk_id);
 874
 875        release_firmware(fw);
 876
 877        return error ? error : 0;
 878}
 879
 880static ssize_t config_csum_show(struct device *dev,
 881                                struct device_attribute *attr, char *buf)
 882{
 883        struct i2c_client *client = to_i2c_client(dev);
 884        struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 885        u32 cfg_csum;
 886
 887        cfg_csum = wdt->param.xmls_id1;
 888        cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
 889
 890        return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
 891}
 892
 893static ssize_t fw_version_show(struct device *dev,
 894                               struct device_attribute *attr, char *buf)
 895{
 896        struct i2c_client *client = to_i2c_client(dev);
 897        struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 898
 899        return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
 900}
 901
 902static ssize_t plat_id_show(struct device *dev,
 903                            struct device_attribute *attr, char *buf)
 904{
 905        struct i2c_client *client = to_i2c_client(dev);
 906        struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 907
 908        return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
 909}
 910
 911static ssize_t update_config_store(struct device *dev,
 912                                   struct device_attribute *attr,
 913                                   const char *buf, size_t count)
 914{
 915        int error;
 916
 917        error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);
 918
 919        return error ? error : count;
 920}
 921
 922static ssize_t update_fw_store(struct device *dev,
 923                               struct device_attribute *attr,
 924                               const char *buf, size_t count)
 925{
 926        int error;
 927
 928        error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);
 929
 930        return error ? error : count;
 931}
 932
 933static DEVICE_ATTR_RO(config_csum);
 934static DEVICE_ATTR_RO(fw_version);
 935static DEVICE_ATTR_RO(plat_id);
 936static DEVICE_ATTR_WO(update_config);
 937static DEVICE_ATTR_WO(update_fw);
 938
 939static struct attribute *wdt87xx_attrs[] = {
 940        &dev_attr_config_csum.attr,
 941        &dev_attr_fw_version.attr,
 942        &dev_attr_plat_id.attr,
 943        &dev_attr_update_config.attr,
 944        &dev_attr_update_fw.attr,
 945        NULL
 946};
 947
 948static const struct attribute_group wdt87xx_attr_group = {
 949        .attrs = wdt87xx_attrs,
 950};
 951
 952static void wdt87xx_report_contact(struct input_dev *input,
 953                                   struct wdt87xx_sys_param *param,
 954                                   u8 *buf)
 955{
 956        int finger_id;
 957        u32 x, y, w;
 958        u8 p;
 959
 960        finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
 961        if (finger_id < 0)
 962                return;
 963
 964        /* Check if this is an active contact */
 965        if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
 966                return;
 967
 968        w = buf[FINGER_EV_V1_OFFSET_W];
 969        w *= param->scaling_factor;
 970
 971        p = buf[FINGER_EV_V1_OFFSET_P];
 972
 973        x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);
 974
 975        y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
 976        y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);
 977
 978        /* Refuse incorrect coordinates */
 979        if (x > param->max_x || y > param->max_y)
 980                return;
 981
 982        dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
 983                finger_id, x, y);
 984
 985        input_mt_slot(input, finger_id);
 986        input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
 987        input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
 988        input_report_abs(input, ABS_MT_PRESSURE, p);
 989        input_report_abs(input, ABS_MT_POSITION_X, x);
 990        input_report_abs(input, ABS_MT_POSITION_Y, y);
 991}
 992
 993static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
 994{
 995        struct wdt87xx_data *wdt = dev_id;
 996        struct i2c_client *client = wdt->client;
 997        int i, fingers;
 998        int error;
 999        u8 raw_buf[WDT_V1_RAW_BUF_COUNT] = {0};
1000
1001        error = i2c_master_recv(client, raw_buf, WDT_V1_RAW_BUF_COUNT);
1002        if (error < 0) {
1003                dev_err(&client->dev, "read v1 raw data failed: %d\n", error);
1004                goto irq_exit;
1005        }
1006
1007        fingers = raw_buf[TOUCH_PK_V1_OFFSET_FNGR_NUM];
1008        if (!fingers)
1009                goto irq_exit;
1010
1011        for (i = 0; i < WDT_MAX_FINGER; i++)
1012                wdt87xx_report_contact(wdt->input,
1013                                       &wdt->param,
1014                                       &raw_buf[TOUCH_PK_V1_OFFSET_EVENT +
1015                                                i * FINGER_EV_V1_SIZE]);
1016
1017        input_mt_sync_frame(wdt->input);
1018        input_sync(wdt->input);
1019
1020irq_exit:
1021        return IRQ_HANDLED;
1022}
1023
1024static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
1025{
1026        struct device *dev = &wdt->client->dev;
1027        struct input_dev *input;
1028        unsigned int res = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS, wdt->param.phy_w);
1029        int error;
1030
1031        input = devm_input_allocate_device(dev);
1032        if (!input) {
1033                dev_err(dev, "failed to allocate input device\n");
1034                return -ENOMEM;
1035        }
1036        wdt->input = input;
1037
1038        input->name = "WDT87xx Touchscreen";
1039        input->id.bustype = BUS_I2C;
1040        input->id.vendor = wdt->param.vendor_id;
1041        input->id.product = wdt->param.product_id;
1042        input->phys = wdt->phys;
1043
1044        input_set_abs_params(input, ABS_MT_POSITION_X, 0,
1045                             wdt->param.max_x, 0, 0);
1046        input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
1047                             wdt->param.max_y, 0, 0);
1048        input_abs_set_res(input, ABS_MT_POSITION_X, res);
1049        input_abs_set_res(input, ABS_MT_POSITION_Y, res);
1050
1051        input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
1052                             0, wdt->param.max_x, 0, 0);
1053        input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
1054
1055        input_mt_init_slots(input, WDT_MAX_FINGER,
1056                            INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
1057
1058        error = input_register_device(input);
1059        if (error) {
1060                dev_err(dev, "failed to register input device: %d\n", error);
1061                return error;
1062        }
1063
1064        return 0;
1065}
1066
1067static int wdt87xx_ts_probe(struct i2c_client *client,
1068                            const struct i2c_device_id *id)
1069{
1070        struct wdt87xx_data *wdt;
1071        int error;
1072
1073        dev_dbg(&client->dev, "adapter=%d, client irq: %d\n",
1074                client->adapter->nr, client->irq);
1075
1076        /* Check if the I2C function is ok in this adaptor */
1077        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1078                return -ENXIO;
1079
1080        wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL);
1081        if (!wdt)
1082                return -ENOMEM;
1083
1084        wdt->client = client;
1085        mutex_init(&wdt->fw_mutex);
1086        i2c_set_clientdata(client, wdt);
1087
1088        snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0",
1089                 client->adapter->nr, client->addr);
1090
1091        error = wdt87xx_get_sysparam(client, &wdt->param);
1092        if (error)
1093                return error;
1094
1095        error = wdt87xx_ts_create_input_device(wdt);
1096        if (error)
1097                return error;
1098
1099        error = devm_request_threaded_irq(&client->dev, client->irq,
1100                                          NULL, wdt87xx_ts_interrupt,
1101                                          IRQF_ONESHOT,
1102                                          client->name, wdt);
1103        if (error) {
1104                dev_err(&client->dev, "request irq failed: %d\n", error);
1105                return error;
1106        }
1107
1108        error = devm_device_add_group(&client->dev, &wdt87xx_attr_group);
1109        if (error) {
1110                dev_err(&client->dev, "create sysfs failed: %d\n", error);
1111                return error;
1112        }
1113
1114        return 0;
1115}
1116
1117static int __maybe_unused wdt87xx_suspend(struct device *dev)
1118{
1119        struct i2c_client *client = to_i2c_client(dev);
1120        int error;
1121
1122        disable_irq(client->irq);
1123
1124        error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_IDLE);
1125        if (error) {
1126                enable_irq(client->irq);
1127                dev_err(&client->dev,
1128                        "failed to stop device when suspending: %d\n",
1129                        error);
1130                return error;
1131        }
1132
1133        return 0;
1134}
1135
1136static int __maybe_unused wdt87xx_resume(struct device *dev)
1137{
1138        struct i2c_client *client = to_i2c_client(dev);
1139        int error;
1140
1141        /*
1142         * The chip may have been reset while system is resuming,
1143         * give it some time to settle.
1144         */
1145        msleep(100);
1146
1147        error = wdt87xx_send_command(client, VND_CMD_START, 0);
1148        if (error)
1149                dev_err(&client->dev,
1150                        "failed to start device when resuming: %d\n",
1151                        error);
1152
1153        enable_irq(client->irq);
1154
1155        return 0;
1156}
1157
1158static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);
1159
1160static const struct i2c_device_id wdt87xx_dev_id[] = {
1161        { WDT87XX_NAME, 0 },
1162        { }
1163};
1164MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);
1165
1166static const struct acpi_device_id wdt87xx_acpi_id[] = {
1167        { "WDHT0001", 0 },
1168        { }
1169};
1170MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
1171
1172static struct i2c_driver wdt87xx_driver = {
1173        .probe          = wdt87xx_ts_probe,
1174        .id_table       = wdt87xx_dev_id,
1175        .driver = {
1176                .name   = WDT87XX_NAME,
1177                .pm     = &wdt87xx_pm_ops,
1178                .acpi_match_table = ACPI_PTR(wdt87xx_acpi_id),
1179        },
1180};
1181module_i2c_driver(wdt87xx_driver);
1182
1183MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
1184MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
1185MODULE_LICENSE("GPL");
1186