Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Weida HiTech WDT87xx TouchScreen I2C driver
0003  *
0004  * Copyright (c) 2015  Weida Hi-Tech Co., Ltd.
0005  * HN Chen <hn.chen@weidahitech.com>
0006  *
0007  * This software is licensed under the terms of the GNU General Public
0008  * License, as published by the Free Software Foundation, and
0009  * may be copied, distributed, and modified under those terms.
0010  */
0011 
0012 #include <linux/i2c.h>
0013 #include <linux/input.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/delay.h>
0016 #include <linux/irq.h>
0017 #include <linux/io.h>
0018 #include <linux/module.h>
0019 #include <linux/slab.h>
0020 #include <linux/firmware.h>
0021 #include <linux/input/mt.h>
0022 #include <linux/acpi.h>
0023 #include <asm/unaligned.h>
0024 
0025 #define WDT87XX_NAME        "wdt87xx_i2c"
0026 #define WDT87XX_FW_NAME     "wdt87xx_fw.bin"
0027 #define WDT87XX_CFG_NAME    "wdt87xx_cfg.bin"
0028 
0029 #define MODE_ACTIVE         0x01
0030 #define MODE_READY          0x02
0031 #define MODE_IDLE           0x03
0032 #define MODE_SLEEP          0x04
0033 #define MODE_STOP           0xFF
0034 
0035 #define WDT_MAX_FINGER          10
0036 #define WDT_RAW_BUF_COUNT       54
0037 #define WDT_V1_RAW_BUF_COUNT        74
0038 #define WDT_FIRMWARE_ID         0xa9e368f5
0039 
0040 #define PG_SIZE             0x1000
0041 #define MAX_RETRIES         3
0042 
0043 #define MAX_UNIT_AXIS           0x7FFF
0044 
0045 #define PKT_READ_SIZE           72
0046 #define PKT_WRITE_SIZE          80
0047 
0048 /* the finger definition of the report event */
0049 #define FINGER_EV_OFFSET_ID     0
0050 #define FINGER_EV_OFFSET_X      1
0051 #define FINGER_EV_OFFSET_Y      3
0052 #define FINGER_EV_SIZE          5
0053 
0054 #define FINGER_EV_V1_OFFSET_ID      0
0055 #define FINGER_EV_V1_OFFSET_W       1
0056 #define FINGER_EV_V1_OFFSET_P       2
0057 #define FINGER_EV_V1_OFFSET_X       3
0058 #define FINGER_EV_V1_OFFSET_Y       5
0059 #define FINGER_EV_V1_SIZE       7
0060 
0061 /* The definition of a report packet */
0062 #define TOUCH_PK_OFFSET_REPORT_ID   0
0063 #define TOUCH_PK_OFFSET_EVENT       1
0064 #define TOUCH_PK_OFFSET_SCAN_TIME   51
0065 #define TOUCH_PK_OFFSET_FNGR_NUM    53
0066 
0067 #define TOUCH_PK_V1_OFFSET_REPORT_ID    0
0068 #define TOUCH_PK_V1_OFFSET_EVENT    1
0069 #define TOUCH_PK_V1_OFFSET_SCAN_TIME    71
0070 #define TOUCH_PK_V1_OFFSET_FNGR_NUM 73
0071 
0072 /* The definition of the controller parameters */
0073 #define CTL_PARAM_OFFSET_FW_ID      0
0074 #define CTL_PARAM_OFFSET_PLAT_ID    2
0075 #define CTL_PARAM_OFFSET_XMLS_ID1   4
0076 #define CTL_PARAM_OFFSET_XMLS_ID2   6
0077 #define CTL_PARAM_OFFSET_PHY_CH_X   8
0078 #define CTL_PARAM_OFFSET_PHY_CH_Y   10
0079 #define CTL_PARAM_OFFSET_PHY_X0     12
0080 #define CTL_PARAM_OFFSET_PHY_X1     14
0081 #define CTL_PARAM_OFFSET_PHY_Y0     16
0082 #define CTL_PARAM_OFFSET_PHY_Y1     18
0083 #define CTL_PARAM_OFFSET_PHY_W      22
0084 #define CTL_PARAM_OFFSET_PHY_H      24
0085 #define CTL_PARAM_OFFSET_FACTOR     32
0086 
0087 /* The definition of the device descriptor */
0088 #define WDT_GD_DEVICE           1
0089 #define DEV_DESC_OFFSET_VID     8
0090 #define DEV_DESC_OFFSET_PID     10
0091 
0092 /* Communication commands */
0093 #define PACKET_SIZE         56
0094 #define VND_REQ_READ            0x06
0095 #define VND_READ_DATA           0x07
0096 #define VND_REQ_WRITE           0x08
0097 
0098 #define VND_CMD_START           0x00
0099 #define VND_CMD_STOP            0x01
0100 #define VND_CMD_RESET           0x09
0101 
0102 #define VND_CMD_ERASE           0x1A
0103 
0104 #define VND_GET_CHECKSUM        0x66
0105 
0106 #define VND_SET_DATA            0x83
0107 #define VND_SET_COMMAND_DATA        0x84
0108 #define VND_SET_CHECKSUM_CALC       0x86
0109 #define VND_SET_CHECKSUM_LENGTH     0x87
0110 
0111 #define VND_CMD_SFLCK           0xFC
0112 #define VND_CMD_SFUNL           0xFD
0113 
0114 #define CMD_SFLCK_KEY           0xC39B
0115 #define CMD_SFUNL_KEY           0x95DA
0116 
0117 #define STRIDX_PLATFORM_ID      0x80
0118 #define STRIDX_PARAMETERS       0x81
0119 
0120 #define CMD_BUF_SIZE            8
0121 #define PKT_BUF_SIZE            64
0122 
0123 /* The definition of the command packet */
0124 #define CMD_REPORT_ID_OFFSET        0x0
0125 #define CMD_TYPE_OFFSET         0x1
0126 #define CMD_INDEX_OFFSET        0x2
0127 #define CMD_KEY_OFFSET          0x3
0128 #define CMD_LENGTH_OFFSET       0x4
0129 #define CMD_DATA_OFFSET         0x8
0130 
0131 /* The definition of firmware chunk tags */
0132 #define FOURCC_ID_RIFF          0x46464952
0133 #define FOURCC_ID_WHIF          0x46494857
0134 #define FOURCC_ID_FRMT          0x544D5246
0135 #define FOURCC_ID_FRWR          0x52575246
0136 #define FOURCC_ID_CNFG          0x47464E43
0137 
0138 #define CHUNK_ID_FRMT           FOURCC_ID_FRMT
0139 #define CHUNK_ID_FRWR           FOURCC_ID_FRWR
0140 #define CHUNK_ID_CNFG           FOURCC_ID_CNFG
0141 
0142 #define FW_FOURCC1_OFFSET       0
0143 #define FW_SIZE_OFFSET          4
0144 #define FW_FOURCC2_OFFSET       8
0145 #define FW_PAYLOAD_OFFSET       40
0146 
0147 #define FW_CHUNK_ID_OFFSET      0
0148 #define FW_CHUNK_SIZE_OFFSET        4
0149 #define FW_CHUNK_TGT_START_OFFSET   8
0150 #define FW_CHUNK_PAYLOAD_LEN_OFFSET 12
0151 #define FW_CHUNK_SRC_START_OFFSET   16
0152 #define FW_CHUNK_VERSION_OFFSET     20
0153 #define FW_CHUNK_ATTR_OFFSET        24
0154 #define FW_CHUNK_PAYLOAD_OFFSET     32
0155 
0156 /* Controller requires minimum 300us between commands */
0157 #define WDT_COMMAND_DELAY_MS        2
0158 #define WDT_FLASH_WRITE_DELAY_MS    4
0159 #define WDT_FLASH_ERASE_DELAY_MS    200
0160 #define WDT_FW_RESET_TIME       2500
0161 
0162 struct wdt87xx_sys_param {
0163     u16 fw_id;
0164     u16 plat_id;
0165     u16 xmls_id1;
0166     u16 xmls_id2;
0167     u16 phy_ch_x;
0168     u16 phy_ch_y;
0169     u16 phy_w;
0170     u16 phy_h;
0171     u16 scaling_factor;
0172     u32 max_x;
0173     u32 max_y;
0174     u16 vendor_id;
0175     u16 product_id;
0176 };
0177 
0178 struct wdt87xx_data {
0179     struct i2c_client       *client;
0180     struct input_dev        *input;
0181     /* Mutex for fw update to prevent concurrent access */
0182     struct mutex            fw_mutex;
0183     struct wdt87xx_sys_param    param;
0184     u8              phys[32];
0185 };
0186 
0187 static int wdt87xx_i2c_xfer(struct i2c_client *client,
0188                 void *txdata, size_t txlen,
0189                 void *rxdata, size_t rxlen)
0190 {
0191     struct i2c_msg msgs[] = {
0192         {
0193             .addr   = client->addr,
0194             .flags  = 0,
0195             .len    = txlen,
0196             .buf    = txdata,
0197         },
0198         {
0199             .addr   = client->addr,
0200             .flags  = I2C_M_RD,
0201             .len    = rxlen,
0202             .buf    = rxdata,
0203         },
0204     };
0205     int error;
0206     int ret;
0207 
0208     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
0209     if (ret != ARRAY_SIZE(msgs)) {
0210         error = ret < 0 ? ret : -EIO;
0211         dev_err(&client->dev, "%s: i2c transfer failed: %d\n",
0212             __func__, error);
0213         return error;
0214     }
0215 
0216     return 0;
0217 }
0218 
0219 static int wdt87xx_get_desc(struct i2c_client *client, u8 desc_idx,
0220                 u8 *buf, size_t len)
0221 {
0222     u8 tx_buf[] = { 0x22, 0x00, 0x10, 0x0E, 0x23, 0x00 };
0223     int error;
0224 
0225     tx_buf[2] |= desc_idx & 0xF;
0226 
0227     error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
0228                  buf, len);
0229     if (error) {
0230         dev_err(&client->dev, "get desc failed: %d\n", error);
0231         return error;
0232     }
0233 
0234     if (buf[0] != len) {
0235         dev_err(&client->dev, "unexpected response to get desc: %d\n",
0236             buf[0]);
0237         return -EINVAL;
0238     }
0239 
0240     mdelay(WDT_COMMAND_DELAY_MS);
0241 
0242     return 0;
0243 }
0244 
0245 static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
0246                   u8 *buf, size_t len)
0247 {
0248     u8 tx_buf[] = { 0x22, 0x00, 0x13, 0x0E, str_idx, 0x23, 0x00 };
0249     u8 rx_buf[PKT_WRITE_SIZE];
0250     size_t rx_len = len + 2;
0251     int error;
0252 
0253     if (rx_len > sizeof(rx_buf))
0254         return -EINVAL;
0255 
0256     error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
0257                  rx_buf, rx_len);
0258     if (error) {
0259         dev_err(&client->dev, "get string failed: %d\n", error);
0260         return error;
0261     }
0262 
0263     if (rx_buf[1] != 0x03) {
0264         dev_err(&client->dev, "unexpected response to get string: %d\n",
0265             rx_buf[1]);
0266         return -EINVAL;
0267     }
0268 
0269     rx_len = min_t(size_t, len, rx_buf[0]);
0270     memcpy(buf, &rx_buf[2], rx_len);
0271 
0272     mdelay(WDT_COMMAND_DELAY_MS);
0273 
0274     return 0;
0275 }
0276 
0277 static int wdt87xx_get_feature(struct i2c_client *client,
0278                    u8 *buf, size_t buf_size)
0279 {
0280     u8 tx_buf[8];
0281     u8 rx_buf[PKT_WRITE_SIZE];
0282     size_t tx_len = 0;
0283     size_t rx_len = buf_size + 2;
0284     int error;
0285 
0286     if (rx_len > sizeof(rx_buf))
0287         return -EINVAL;
0288 
0289     /* Get feature command packet */
0290     tx_buf[tx_len++] = 0x22;
0291     tx_buf[tx_len++] = 0x00;
0292     if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
0293         tx_buf[tx_len++] = 0x30;
0294         tx_buf[tx_len++] = 0x02;
0295         tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
0296     } else {
0297         tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
0298         tx_buf[tx_len++] = 0x02;
0299     }
0300     tx_buf[tx_len++] = 0x23;
0301     tx_buf[tx_len++] = 0x00;
0302 
0303     error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
0304     if (error) {
0305         dev_err(&client->dev, "get feature failed: %d\n", error);
0306         return error;
0307     }
0308 
0309     rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
0310     memcpy(buf, &rx_buf[2], rx_len);
0311 
0312     mdelay(WDT_COMMAND_DELAY_MS);
0313 
0314     return 0;
0315 }
0316 
0317 static int wdt87xx_set_feature(struct i2c_client *client,
0318                    const u8 *buf, size_t buf_size)
0319 {
0320     u8 tx_buf[PKT_WRITE_SIZE];
0321     int tx_len = 0;
0322     int error;
0323 
0324     /* Set feature command packet */
0325     tx_buf[tx_len++] = 0x22;
0326     tx_buf[tx_len++] = 0x00;
0327     if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
0328         tx_buf[tx_len++] = 0x30;
0329         tx_buf[tx_len++] = 0x03;
0330         tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
0331     } else {
0332         tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
0333         tx_buf[tx_len++] = 0x03;
0334     }
0335     tx_buf[tx_len++] = 0x23;
0336     tx_buf[tx_len++] = 0x00;
0337     tx_buf[tx_len++] = (buf_size & 0xFF);
0338     tx_buf[tx_len++] = ((buf_size & 0xFF00) >> 8);
0339 
0340     if (tx_len + buf_size > sizeof(tx_buf))
0341         return -EINVAL;
0342 
0343     memcpy(&tx_buf[tx_len], buf, buf_size);
0344     tx_len += buf_size;
0345 
0346     error = i2c_master_send(client, tx_buf, tx_len);
0347     if (error < 0) {
0348         dev_err(&client->dev, "set feature failed: %d\n", error);
0349         return error;
0350     }
0351 
0352     mdelay(WDT_COMMAND_DELAY_MS);
0353 
0354     return 0;
0355 }
0356 
0357 static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
0358 {
0359     u8 cmd_buf[CMD_BUF_SIZE];
0360 
0361     /* Set the command packet */
0362     cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
0363     cmd_buf[CMD_TYPE_OFFSET] = VND_SET_COMMAND_DATA;
0364     put_unaligned_le16((u16)cmd, &cmd_buf[CMD_INDEX_OFFSET]);
0365 
0366     switch (cmd) {
0367     case VND_CMD_START:
0368     case VND_CMD_STOP:
0369     case VND_CMD_RESET:
0370         /* Mode selector */
0371         put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
0372         break;
0373 
0374     case VND_CMD_SFLCK:
0375         put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
0376         break;
0377 
0378     case VND_CMD_SFUNL:
0379         put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
0380         break;
0381 
0382     case VND_CMD_ERASE:
0383     case VND_SET_CHECKSUM_CALC:
0384     case VND_SET_CHECKSUM_LENGTH:
0385         put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
0386         break;
0387 
0388     default:
0389         cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
0390         dev_err(&client->dev, "Invalid command: %d\n", cmd);
0391         return -EINVAL;
0392     }
0393 
0394     return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
0395 }
0396 
0397 static int wdt87xx_sw_reset(struct i2c_client *client)
0398 {
0399     int error;
0400 
0401     dev_dbg(&client->dev, "resetting device now\n");
0402 
0403     error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
0404     if (error) {
0405         dev_err(&client->dev, "reset failed\n");
0406         return error;
0407     }
0408 
0409     /* Wait the device to be ready */
0410     msleep(WDT_FW_RESET_TIME);
0411 
0412     return 0;
0413 }
0414 
0415 static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
0416 {
0417     size_t pos = FW_PAYLOAD_OFFSET;
0418     u32 chunk_id, chunk_size;
0419 
0420     while (pos < fw->size) {
0421         chunk_id = get_unaligned_le32(fw->data +
0422                           pos + FW_CHUNK_ID_OFFSET);
0423         if (chunk_id == id)
0424             return fw->data + pos;
0425 
0426         chunk_size = get_unaligned_le32(fw->data +
0427                         pos + FW_CHUNK_SIZE_OFFSET);
0428         pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
0429     }
0430 
0431     return NULL;
0432 }
0433 
0434 static int wdt87xx_get_sysparam(struct i2c_client *client,
0435                 struct wdt87xx_sys_param *param)
0436 {
0437     u8 buf[PKT_READ_SIZE];
0438     int error;
0439 
0440     error = wdt87xx_get_desc(client, WDT_GD_DEVICE, buf, 18);
0441     if (error) {
0442         dev_err(&client->dev, "failed to get device desc\n");
0443         return error;
0444     }
0445 
0446     param->vendor_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_VID);
0447     param->product_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_PID);
0448 
0449     error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
0450     if (error) {
0451         dev_err(&client->dev, "failed to get parameters\n");
0452         return error;
0453     }
0454 
0455     param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1);
0456     param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2);
0457     param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X);
0458     param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y);
0459     param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10;
0460     param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10;
0461 
0462     /* Get the scaling factor of pixel to logical coordinate */
0463     param->scaling_factor =
0464             get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);
0465 
0466     param->max_x = MAX_UNIT_AXIS;
0467     param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
0468                      param->phy_w);
0469 
0470     error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
0471     if (error) {
0472         dev_err(&client->dev, "failed to get platform id\n");
0473         return error;
0474     }
0475 
0476     param->plat_id = buf[1];
0477 
0478     buf[0] = 0xf2;
0479     error = wdt87xx_get_feature(client, buf, 16);
0480     if (error) {
0481         dev_err(&client->dev, "failed to get firmware id\n");
0482         return error;
0483     }
0484 
0485     if (buf[0] != 0xf2) {
0486         dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
0487             buf[0]);
0488         return -EINVAL;
0489     }
0490 
0491     param->fw_id = get_unaligned_le16(&buf[1]);
0492 
0493     dev_info(&client->dev,
0494          "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
0495          param->fw_id, param->plat_id,
0496          param->xmls_id1, param->xmls_id2);
0497 
0498     return 0;
0499 }
0500 
0501 static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
0502                      const struct firmware *fw)
0503 {
0504     const void *fw_chunk;
0505     u32 data1, data2;
0506     u32 size;
0507     u8 fw_chip_id;
0508     u8 chip_id;
0509 
0510     data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET);
0511     data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET);
0512     if (data1 != FOURCC_ID_RIFF || data2 != FOURCC_ID_WHIF) {
0513         dev_err(&wdt->client->dev, "check fw tag failed\n");
0514         return -EINVAL;
0515     }
0516 
0517     size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET);
0518     if (size != fw->size) {
0519         dev_err(&wdt->client->dev,
0520             "fw size mismatch: expected %d, actual %zu\n",
0521             size, fw->size);
0522         return -EINVAL;
0523     }
0524 
0525     /*
0526      * Get the chip_id from the firmware. Make sure that it is the
0527      * right controller to do the firmware and config update.
0528      */
0529     fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
0530     if (!fw_chunk) {
0531         dev_err(&wdt->client->dev,
0532             "unable to locate firmware chunk\n");
0533         return -EINVAL;
0534     }
0535 
0536     fw_chip_id = (get_unaligned_le32(fw_chunk +
0537                      FW_CHUNK_VERSION_OFFSET) >> 12) & 0xF;
0538     chip_id = (wdt->param.fw_id >> 12) & 0xF;
0539 
0540     if (fw_chip_id != chip_id) {
0541         dev_err(&wdt->client->dev,
0542             "fw version mismatch: fw %d vs. chip %d\n",
0543             fw_chip_id, chip_id);
0544         return -ENODEV;
0545     }
0546 
0547     return 0;
0548 }
0549 
0550 static int wdt87xx_validate_fw_chunk(const void *data, int id)
0551 {
0552     if (id == CHUNK_ID_FRWR) {
0553         u32 fw_id;
0554 
0555         fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
0556         if (fw_id != WDT_FIRMWARE_ID)
0557             return -EINVAL;
0558     }
0559 
0560     return 0;
0561 }
0562 
0563 static int wdt87xx_write_data(struct i2c_client *client, const char *data,
0564                   u32 address, int length)
0565 {
0566     u16 packet_size;
0567     int count = 0;
0568     int error;
0569     u8 pkt_buf[PKT_BUF_SIZE];
0570 
0571     /* Address and length should be 4 bytes aligned */
0572     if ((address & 0x3) != 0 || (length & 0x3) != 0) {
0573         dev_err(&client->dev,
0574             "addr & len must be 4 bytes aligned %x, %x\n",
0575             address, length);
0576         return -EINVAL;
0577     }
0578 
0579     while (length) {
0580         packet_size = min(length, PACKET_SIZE);
0581 
0582         pkt_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
0583         pkt_buf[CMD_TYPE_OFFSET] = VND_SET_DATA;
0584         put_unaligned_le16(packet_size, &pkt_buf[CMD_INDEX_OFFSET]);
0585         put_unaligned_le32(address, &pkt_buf[CMD_LENGTH_OFFSET]);
0586         memcpy(&pkt_buf[CMD_DATA_OFFSET], data, packet_size);
0587 
0588         error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
0589         if (error)
0590             return error;
0591 
0592         length -= packet_size;
0593         data += packet_size;
0594         address += packet_size;
0595 
0596         /* Wait for the controller to finish the write */
0597         mdelay(WDT_FLASH_WRITE_DELAY_MS);
0598 
0599         if ((++count % 32) == 0) {
0600             /* Delay for fw to clear watch dog */
0601             msleep(20);
0602         }
0603     }
0604 
0605     return 0;
0606 }
0607 
0608 static u16 misr(u16 cur_value, u8 new_value)
0609 {
0610     u32 a, b;
0611     u32 bit0;
0612     u32 y;
0613 
0614     a = cur_value;
0615     b = new_value;
0616     bit0 = a ^ (b & 1);
0617     bit0 ^= a >> 1;
0618     bit0 ^= a >> 2;
0619     bit0 ^= a >> 4;
0620     bit0 ^= a >> 5;
0621     bit0 ^= a >> 7;
0622     bit0 ^= a >> 11;
0623     bit0 ^= a >> 15;
0624     y = (a << 1) ^ b;
0625     y = (y & ~1) | (bit0 & 1);
0626 
0627     return (u16)y;
0628 }
0629 
0630 static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
0631 {
0632     u16 checksum = 0;
0633     size_t i;
0634 
0635     for (i = 0; i < length; i++)
0636         checksum = misr(checksum, data[i]);
0637 
0638     return checksum;
0639 }
0640 
0641 static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
0642                 u32 address, int length)
0643 {
0644     int error;
0645     int time_delay;
0646     u8 pkt_buf[PKT_BUF_SIZE];
0647     u8 cmd_buf[CMD_BUF_SIZE];
0648 
0649     error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
0650     if (error) {
0651         dev_err(&client->dev, "failed to set checksum length\n");
0652         return error;
0653     }
0654 
0655     error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
0656     if (error) {
0657         dev_err(&client->dev, "failed to set checksum address\n");
0658         return error;
0659     }
0660 
0661     /* Wait the operation to complete */
0662     time_delay = DIV_ROUND_UP(length, 1024);
0663     msleep(time_delay * 30);
0664 
0665     memset(cmd_buf, 0, sizeof(cmd_buf));
0666     cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_READ;
0667     cmd_buf[CMD_TYPE_OFFSET] = VND_GET_CHECKSUM;
0668     error = wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
0669     if (error) {
0670         dev_err(&client->dev, "failed to request checksum\n");
0671         return error;
0672     }
0673 
0674     memset(pkt_buf, 0, sizeof(pkt_buf));
0675     pkt_buf[CMD_REPORT_ID_OFFSET] = VND_READ_DATA;
0676     error = wdt87xx_get_feature(client, pkt_buf, sizeof(pkt_buf));
0677     if (error) {
0678         dev_err(&client->dev, "failed to read checksum\n");
0679         return error;
0680     }
0681 
0682     *checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
0683     return 0;
0684 }
0685 
0686 static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
0687 {
0688     u32 start_addr = get_unaligned_le32(chunk + FW_CHUNK_TGT_START_OFFSET);
0689     u32 size = get_unaligned_le32(chunk + FW_CHUNK_PAYLOAD_LEN_OFFSET);
0690     const void *data = chunk + FW_CHUNK_PAYLOAD_OFFSET;
0691     int error;
0692     int err1;
0693     int page_size;
0694     int retry = 0;
0695     u16 device_checksum, firmware_checksum;
0696 
0697     dev_dbg(&client->dev, "start 4k page program\n");
0698 
0699     error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
0700     if (error) {
0701         dev_err(&client->dev, "stop report mode failed\n");
0702         return error;
0703     }
0704 
0705     error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
0706     if (error) {
0707         dev_err(&client->dev, "unlock failed\n");
0708         goto out_enable_reporting;
0709     }
0710 
0711     mdelay(10);
0712 
0713     while (size) {
0714         dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
0715             start_addr, size);
0716 
0717         page_size = min_t(u32, size, PG_SIZE);
0718         size -= page_size;
0719 
0720         for (retry = 0; retry < MAX_RETRIES; retry++) {
0721             error = wdt87xx_send_command(client, VND_CMD_ERASE,
0722                              start_addr);
0723             if (error) {
0724                 dev_err(&client->dev,
0725                     "erase failed at %#08x\n", start_addr);
0726                 break;
0727             }
0728 
0729             msleep(WDT_FLASH_ERASE_DELAY_MS);
0730 
0731             error = wdt87xx_write_data(client, data, start_addr,
0732                            page_size);
0733             if (error) {
0734                 dev_err(&client->dev,
0735                     "write failed at %#08x (%d bytes)\n",
0736                     start_addr, page_size);
0737                 break;
0738             }
0739 
0740             error = wdt87xx_get_checksum(client, &device_checksum,
0741                              start_addr, page_size);
0742             if (error) {
0743                 dev_err(&client->dev,
0744                     "failed to retrieve checksum for %#08x (len: %d)\n",
0745                     start_addr, page_size);
0746                 break;
0747             }
0748 
0749             firmware_checksum =
0750                 wdt87xx_calculate_checksum(data, page_size);
0751 
0752             if (device_checksum == firmware_checksum)
0753                 break;
0754 
0755             dev_err(&client->dev,
0756                 "checksum fail: %d vs %d, retry %d\n",
0757                 device_checksum, firmware_checksum, retry);
0758         }
0759 
0760         if (retry == MAX_RETRIES) {
0761             dev_err(&client->dev, "page write failed\n");
0762             error = -EIO;
0763             goto out_lock_device;
0764         }
0765 
0766         start_addr = start_addr + page_size;
0767         data = data + page_size;
0768     }
0769 
0770 out_lock_device:
0771     err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
0772     if (err1)
0773         dev_err(&client->dev, "lock failed\n");
0774 
0775     mdelay(10);
0776 
0777 out_enable_reporting:
0778     err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
0779     if (err1)
0780         dev_err(&client->dev, "start to report failed\n");
0781 
0782     return error ? error : err1;
0783 }
0784 
0785 static int wdt87xx_load_chunk(struct i2c_client *client,
0786                   const struct firmware *fw, u32 ck_id)
0787 {
0788     const void *chunk;
0789     int error;
0790 
0791     chunk = wdt87xx_get_fw_chunk(fw, ck_id);
0792     if (!chunk) {
0793         dev_err(&client->dev, "unable to locate chunk (type %d)\n",
0794             ck_id);
0795         return -EINVAL;
0796     }
0797 
0798     error = wdt87xx_validate_fw_chunk(chunk, ck_id);
0799     if (error) {
0800         dev_err(&client->dev, "invalid chunk (type %d): %d\n",
0801             ck_id, error);
0802         return error;
0803     }
0804 
0805     error = wdt87xx_write_firmware(client, chunk);
0806     if (error) {
0807         dev_err(&client->dev,
0808             "failed to write fw chunk (type %d): %d\n",
0809             ck_id, error);
0810         return error;
0811     }
0812 
0813     return 0;
0814 }
0815 
0816 static int wdt87xx_do_update_firmware(struct i2c_client *client,
0817                       const struct firmware *fw,
0818                       unsigned int chunk_id)
0819 {
0820     struct wdt87xx_data *wdt = i2c_get_clientdata(client);
0821     int error;
0822 
0823     error = wdt87xx_validate_firmware(wdt, fw);
0824     if (error)
0825         return error;
0826 
0827     error = mutex_lock_interruptible(&wdt->fw_mutex);
0828     if (error)
0829         return error;
0830 
0831     disable_irq(client->irq);
0832 
0833     error = wdt87xx_load_chunk(client, fw, chunk_id);
0834     if (error) {
0835         dev_err(&client->dev,
0836             "firmware load failed (type: %d): %d\n",
0837             chunk_id, error);
0838         goto out;
0839     }
0840 
0841     error = wdt87xx_sw_reset(client);
0842     if (error) {
0843         dev_err(&client->dev, "soft reset failed: %d\n", error);
0844         goto out;
0845     }
0846 
0847     /* Refresh the parameters */
0848     error = wdt87xx_get_sysparam(client, &wdt->param);
0849     if (error)
0850         dev_err(&client->dev,
0851             "failed to refresh system parameters: %d\n", error);
0852 out:
0853     enable_irq(client->irq);
0854     mutex_unlock(&wdt->fw_mutex);
0855 
0856     return error ? error : 0;
0857 }
0858 
0859 static int wdt87xx_update_firmware(struct device *dev,
0860                    const char *fw_name, unsigned int chunk_id)
0861 {
0862     struct i2c_client *client = to_i2c_client(dev);
0863     const struct firmware *fw;
0864     int error;
0865 
0866     error = request_firmware(&fw, fw_name, dev);
0867     if (error) {
0868         dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
0869             fw_name, error);
0870         return error;
0871     }
0872 
0873     error = wdt87xx_do_update_firmware(client, fw, chunk_id);
0874 
0875     release_firmware(fw);
0876 
0877     return error ? error : 0;
0878 }
0879 
0880 static ssize_t config_csum_show(struct device *dev,
0881                 struct device_attribute *attr, char *buf)
0882 {
0883     struct i2c_client *client = to_i2c_client(dev);
0884     struct wdt87xx_data *wdt = i2c_get_clientdata(client);
0885     u32 cfg_csum;
0886 
0887     cfg_csum = wdt->param.xmls_id1;
0888     cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
0889 
0890     return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
0891 }
0892 
0893 static ssize_t fw_version_show(struct device *dev,
0894                    struct device_attribute *attr, char *buf)
0895 {
0896     struct i2c_client *client = to_i2c_client(dev);
0897     struct wdt87xx_data *wdt = i2c_get_clientdata(client);
0898 
0899     return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
0900 }
0901 
0902 static ssize_t plat_id_show(struct device *dev,
0903                 struct device_attribute *attr, char *buf)
0904 {
0905     struct i2c_client *client = to_i2c_client(dev);
0906     struct wdt87xx_data *wdt = i2c_get_clientdata(client);
0907 
0908     return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
0909 }
0910 
0911 static ssize_t update_config_store(struct device *dev,
0912                    struct device_attribute *attr,
0913                    const char *buf, size_t count)
0914 {
0915     int error;
0916 
0917     error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);
0918 
0919     return error ? error : count;
0920 }
0921 
0922 static ssize_t update_fw_store(struct device *dev,
0923                    struct device_attribute *attr,
0924                    const char *buf, size_t count)
0925 {
0926     int error;
0927 
0928     error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);
0929 
0930     return error ? error : count;
0931 }
0932 
0933 static DEVICE_ATTR_RO(config_csum);
0934 static DEVICE_ATTR_RO(fw_version);
0935 static DEVICE_ATTR_RO(plat_id);
0936 static DEVICE_ATTR_WO(update_config);
0937 static DEVICE_ATTR_WO(update_fw);
0938 
0939 static struct attribute *wdt87xx_attrs[] = {
0940     &dev_attr_config_csum.attr,
0941     &dev_attr_fw_version.attr,
0942     &dev_attr_plat_id.attr,
0943     &dev_attr_update_config.attr,
0944     &dev_attr_update_fw.attr,
0945     NULL
0946 };
0947 
0948 static const struct attribute_group wdt87xx_attr_group = {
0949     .attrs = wdt87xx_attrs,
0950 };
0951 
0952 static void wdt87xx_report_contact(struct input_dev *input,
0953                    struct wdt87xx_sys_param *param,
0954                    u8 *buf)
0955 {
0956     int finger_id;
0957     u32 x, y, w;
0958     u8 p;
0959 
0960     finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
0961     if (finger_id < 0)
0962         return;
0963 
0964     /* Check if this is an active contact */
0965     if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
0966         return;
0967 
0968     w = buf[FINGER_EV_V1_OFFSET_W];
0969     w *= param->scaling_factor;
0970 
0971     p = buf[FINGER_EV_V1_OFFSET_P];
0972 
0973     x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);
0974 
0975     y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
0976     y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);
0977 
0978     /* Refuse incorrect coordinates */
0979     if (x > param->max_x || y > param->max_y)
0980         return;
0981 
0982     dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
0983         finger_id, x, y);
0984 
0985     input_mt_slot(input, finger_id);
0986     input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
0987     input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
0988     input_report_abs(input, ABS_MT_PRESSURE, p);
0989     input_report_abs(input, ABS_MT_POSITION_X, x);
0990     input_report_abs(input, ABS_MT_POSITION_Y, y);
0991 }
0992 
0993 static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
0994 {
0995     struct wdt87xx_data *wdt = dev_id;
0996     struct i2c_client *client = wdt->client;
0997     int i, fingers;
0998     int error;
0999     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");