On Sun, Jun 07, 2015 at 03:34:04AM +0800, duson wrote: > In order to support multi ic type for i2c/smbus protocol, add get ic type > command and check fw vaild page count and signature address function. > > Signed-off by: Duson Lin <dusonlin@xxxxxxxxxx> Applied, thank you (but please try to convince your mailer to not use quoted printable format). > --- > drivers/input/mouse/elan_i2c.h | 5 ++-- > drivers/input/mouse/elan_i2c_core.c | 44 ++++++++++++++++++++++++++++++---- > drivers/input/mouse/elan_i2c_i2c.c | 5 +++- > drivers/input/mouse/elan_i2c_smbus.c | 6 +++-- > 4 files changed, 49 insertions(+), 11 deletions(-) > > diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h > index 6d5f8a4..ff622a1 100644 > --- a/drivers/input/mouse/elan_i2c.h > +++ b/drivers/input/mouse/elan_i2c.h > @@ -33,9 +33,7 @@ > #define ETP_FW_IAP_PAGE_ERR (1 << 5) > #define ETP_FW_IAP_INTF_ERR (1 << 4) > #define ETP_FW_PAGE_SIZE 64 > -#define ETP_FW_VAILDPAGE_COUNT 768 > #define ETP_FW_SIGNATURE_SIZE 6 > -#define ETP_FW_SIGNATURE_ADDRESS 0xBFFA > > struct i2c_client; > struct completion; > @@ -58,7 +56,8 @@ struct elan_transport_ops { > bool max_baseliune, u8 *value); > > int (*get_version)(struct i2c_client *client, bool iap, u8 *version); > - int (*get_sm_version)(struct i2c_client *client, u8 *version); > + int (*get_sm_version)(struct i2c_client *client, > + u8* ic_type, u8 *version); > int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); > int (*get_product_id)(struct i2c_client *client, u8 *id); > > diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c > index fd5068b..81e7bc9 100644 > --- a/drivers/input/mouse/elan_i2c_core.c > +++ b/drivers/input/mouse/elan_i2c_core.c > @@ -4,7 +4,7 @@ > * Copyright (c) 2013 ELAN Microelectronics Corp. > * > * Author: 林政維 (Duson Lin) <dusonlin@xxxxxxxxxx> > - * Version: 1.5.7 > + * Version: 1.5.8 > * > * Based on cyapa driver: > * copyright (c) 2011-2012 Cypress Semiconductor, Inc. > @@ -40,7 +40,7 @@ > #include "elan_i2c.h" > > #define DRIVER_NAME "elan_i2c" > -#define ELAN_DRIVER_VERSION "1.5.7" > +#define ELAN_DRIVER_VERSION "1.5.8" > #define ETP_MAX_PRESSURE 255 > #define ETP_FWIDTH_REDUCE 90 > #define ETP_FINGER_WIDTH 15 > @@ -83,6 +83,9 @@ struct elan_tp_data { > u16 fw_checksum; > int pressure_adjustment; > u8 mode; > + u8 ic_type; > + u16 fw_vaildpage_count; > + u16 fw_signature_address; > > bool irq_wake; > > @@ -91,6 +94,28 @@ struct elan_tp_data { > bool baseline_ready; > }; > > +static int elan_get_fwinfo(u8 ic_type, u16 *vaildpage_count, > + u16 *signature_address) > +{ > + > + switch(ic_type) { > + case 0x09: > + *vaildpage_count = 768; > + break; > + case 0x0D: > + *vaildpage_count = 896; > + break; > + default: > + /* unknown ic type clear value */ > + *vaildpage_count = 0; > + *signature_address = 0; > + return -ENXIO; > + } > + *signature_address = (*vaildpage_count * ETP_FW_PAGE_SIZE) > + - ETP_FW_SIGNATURE_SIZE; > + return 0; > +} > + > static int elan_enable_power(struct elan_tp_data *data) > { > int repeat = ETP_RETRY_COUNT; > @@ -221,7 +246,8 @@ static int elan_query_device_info(struct elan_tp_data *data) > if (error) > return error; > > - error = data->ops->get_sm_version(data->client, &data->sm_version); > + error = data->ops->get_sm_version(data->client, &data->ic_type, > + &data->sm_version); > if (error) > return error; > > @@ -234,6 +260,14 @@ static int elan_query_device_info(struct elan_tp_data *data) > if (error) > return error; > > + error = elan_get_fwinfo(data->ic_type, &data->fw_vaildpage_count, > + &data->fw_signature_address); > + if (error) { > + dev_err(&data->client->dev, > + "unknown ic type %d\n", data->ic_type); > + return error; > + } > + > return 0; > } > > @@ -318,7 +352,7 @@ static int __elan_update_firmware(struct elan_tp_data *data, > iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); > > boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; > - for (i = boot_page_count; i < ETP_FW_VAILDPAGE_COUNT; i++) { > + for (i = boot_page_count; i < data->fw_vaildpage_count; i++) { > u16 checksum = 0; > const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; > > @@ -454,7 +488,7 @@ static ssize_t elan_sysfs_update_fw(struct device *dev, > } > > /* Firmware file must match signature data */ > - fw_signature = &fw->data[ETP_FW_SIGNATURE_ADDRESS]; > + fw_signature = &fw->data[data->fw_signature_address]; > if (memcmp(fw_signature, signature, sizeof(signature)) != 0) { > dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n", > (int)sizeof(signature), signature, > diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c > index a0acbbf..549cdfb 100644 > --- a/drivers/input/mouse/elan_i2c_i2c.c > +++ b/drivers/input/mouse/elan_i2c_i2c.c > @@ -259,7 +259,8 @@ static int elan_i2c_get_version(struct i2c_client *client, > return 0; > } > > -static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version) > +static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *ic_type, > + u8 *version) > { > int error; > u8 val[3]; > @@ -271,9 +272,11 @@ static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version) > } > > *version = val[0]; > + *ic_type = val[1]; > return 0; > } > > + > static int elan_i2c_get_product_id(struct i2c_client *client, u8 *id) > { > int error; > diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c > index 30ab80d..c28caef 100644 > --- a/drivers/input/mouse/elan_i2c_smbus.c > +++ b/drivers/input/mouse/elan_i2c_smbus.c > @@ -165,7 +165,8 @@ static int elan_smbus_get_version(struct i2c_client *client, > return 0; > } > > -static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *version) > +static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *ic_type, > + u8 *version) > { > int error; > u8 val[3]; > @@ -177,7 +178,8 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *version) > return error; > } > > - *version = val[0]; /* XXX Why 0 and not 2 as in IAP/FW versions? */ > + *version = val[0]; > + *ic_type = val[1]; > return 0; > } -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html