root/drivers/input/touchscreen/wdt87xx_i2c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wdt87xx_i2c_xfer
  2. wdt87xx_get_desc
  3. wdt87xx_get_string
  4. wdt87xx_get_feature
  5. wdt87xx_set_feature
  6. wdt87xx_send_command
  7. wdt87xx_sw_reset
  8. wdt87xx_get_fw_chunk
  9. wdt87xx_get_sysparam
  10. wdt87xx_validate_firmware
  11. wdt87xx_validate_fw_chunk
  12. wdt87xx_write_data
  13. misr
  14. wdt87xx_calculate_checksum
  15. wdt87xx_get_checksum
  16. wdt87xx_write_firmware
  17. wdt87xx_load_chunk
  18. wdt87xx_do_update_firmware
  19. wdt87xx_update_firmware
  20. config_csum_show
  21. fw_version_show
  22. plat_id_show
  23. update_config_store
  24. update_fw_store
  25. wdt87xx_report_contact
  26. wdt87xx_ts_interrupt
  27. wdt87xx_ts_create_input_device
  28. wdt87xx_ts_probe
  29. wdt87xx_suspend
  30. wdt87xx_resume

   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 
 162 struct 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 
 178 struct 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 
 187 static 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 
 219 static 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 
 245 static 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 
 277 static 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 
 317 static 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 
 357 static 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 
 397 static 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 
 415 static 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 
 434 static 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 
 501 static 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 
 550 static 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 
 563 static 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 
 608 static 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 
 630 static 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 
 641 static 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 
 686 static 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 
 770 out_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 
 777 out_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 
 785 static 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 
 816 static 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);
 852 out:
 853         enable_irq(client->irq);
 854         mutex_unlock(&wdt->fw_mutex);
 855 
 856         return error ? error : 0;
 857 }
 858 
 859 static 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 
 880 static 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 
 893 static 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 
 902 static 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 
 911 static 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 
 922 static 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 
 933 static DEVICE_ATTR_RO(config_csum);
 934 static DEVICE_ATTR_RO(fw_version);
 935 static DEVICE_ATTR_RO(plat_id);
 936 static DEVICE_ATTR_WO(update_config);
 937 static DEVICE_ATTR_WO(update_fw);
 938 
 939 static 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 
 948 static const struct attribute_group wdt87xx_attr_group = {
 949         .attrs = wdt87xx_attrs,
 950 };
 951 
 952 static 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 
 993 static 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 
1020 irq_exit:
1021         return IRQ_HANDLED;
1022 }
1023 
1024 static 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 
1067 static 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 
1117 static 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 
1136 static 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 
1158 static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);
1159 
1160 static const struct i2c_device_id wdt87xx_dev_id[] = {
1161         { WDT87XX_NAME, 0 },
1162         { }
1163 };
1164 MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);
1165 
1166 static const struct acpi_device_id wdt87xx_acpi_id[] = {
1167         { "WDHT0001", 0 },
1168         { }
1169 };
1170 MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
1171 
1172 static 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 };
1181 module_i2c_driver(wdt87xx_driver);
1182 
1183 MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
1184 MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
1185 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */