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