diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-10 16:35:57 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-10 16:35:57 -0700 |
commit | 4bcf69e57063c9b1b15df1a293c969e80a1c97e6 (patch) | |
tree | aacea8bf1ca4260d3064665ecc946ab78857b3a3 /drivers | |
parent | b7b8e3689aa0b2def48b8c6eb1df060902eb2c0a (diff) | |
parent | 9e8238020c5beba64e7ffafbb7ea0fb02fe68270 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
- an update to Elan touchpad controller driver supporting newer ICs
with enhanced precision reports and a new firmware update process
- an update to EXC3000 touch controller supporting additional parts
- assorted driver fixups
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (27 commits)
Input: exc3000 - add support to query model and fw_version
Input: exc3000 - add reset gpio support
Input: exc3000 - add EXC80H60 and EXC80H84 support
dt-bindings: touchscreen: Convert EETI EXC3000 touchscreen to json-schema
Input: sentelic - fix error return when fsp_reg_write fails
Input: alps - remove redundant assignment to variable ret
Input: ims-pcu - return error code rather than -ENOMEM
Input: elan_i2c - add ic type 0x15
Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary
Input: uinput - fix typo in function name documentation
Input: ati_remote2 - add missing newlines when printing module parameters
Input: psmouse - add a newline when printing 'proto' by sysfs
Input: synaptics-rmi4 - drop a duplicated word
Input: elan_i2c - add support for high resolution reports
Input: elan_i2c - do not constantly re-query pattern ID
Input: elan_i2c - add firmware update info for ICs 0x11, 0x13, 0x14
Input: elan_i2c - handle firmware updated on newer ICs
Input: elan_i2c - add support for different firmware page sizes
Input: elan_i2c - fix detecting IAP version on older controllers
Input: elan_i2c - handle devices with patterns above 1
...
Diffstat (limited to 'drivers')
42 files changed, 641 insertions, 235 deletions
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index a81e14148407..f699538bdac4 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -16,7 +16,7 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) if (dev->absinfo && test_bit(src, dev->absbit)) { dev->absinfo[dst] = dev->absinfo[src]; dev->absinfo[dst].fuzz = 0; - dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst); + __set_bit(dst, dev->absbit); } } diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index a7bc576eb342..434d265fa2e8 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -247,7 +247,7 @@ static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char db9_saturn_write_sub(port, type, 3, powered, 0); return data[0] = 0xe3; } - /* fall through */ + fallthrough; default: return data[0]; } @@ -267,14 +267,14 @@ static int db9_saturn_report(unsigned char id, unsigned char data[60], struct in switch (data[j]) { case 0x16: /* multi controller (analog 4 axis) */ input_report_abs(dev, db9_abs[5], data[j + 6]); - /* fall through */ + fallthrough; case 0x15: /* mission stick (analog 3 axis) */ input_report_abs(dev, db9_abs[3], data[j + 4]); input_report_abs(dev, db9_abs[4], data[j + 5]); - /* fall through */ + fallthrough; case 0x13: /* racing controller (analog 1 axis) */ input_report_abs(dev, db9_abs[2], data[j + 3]); - /* fall through */ + fallthrough; case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */ case 0x02: /* digital pad (digital 2 axis + buttons) */ input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); @@ -368,7 +368,7 @@ static void db9_timer(struct timer_list *t) input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); input_report_abs(dev2, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1); - /* fall through */ + fallthrough; case DB9_MULTI_0802: diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index e0a362be5812..88df68cc4ac6 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -485,7 +485,7 @@ static void gc_multi_process_packet(struct gc *gc) switch (pad->type) { case GC_MULTI2: input_report_key(dev, BTN_THUMB, s & data[5]); - /* fall through */ + fallthrough; case GC_MULTI: input_report_abs(dev, ABS_X, @@ -638,7 +638,7 @@ static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type, input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04); input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02); - /* fall through */ + fallthrough; case GC_PSX_NEGCON: case GC_PSX_ANALOG: @@ -872,7 +872,8 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type) case GC_SNES: for (i = 4; i < 8; i++) input_set_capability(input_dev, EV_KEY, gc_snes_btn[i]); - /* fall through */ + fallthrough; + case GC_NES: for (i = 0; i < 4; i++) input_set_capability(input_dev, EV_KEY, gc_snes_btn[i]); @@ -880,7 +881,8 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type) case GC_MULTI2: input_set_capability(input_dev, EV_KEY, BTN_THUMB); - /* fall through */ + fallthrough; + case GC_MULTI: input_set_capability(input_dev, EV_KEY, BTN_TRIGGER); /* fall through */ diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 1777e68c9f02..fac91ea14f17 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -656,16 +656,19 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) switch (i * m) { case 60: - sw->number++; /* fall through */ + sw->number++; + fallthrough; case 45: /* Ambiguous packet length */ if (j <= 40) { /* ID length less or eq 40 -> FSP */ case 43: sw->type = SW_ID_FSP; break; } - sw->number++; /* fall through */ + sw->number++; + fallthrough; case 30: - sw->number++; /* fall through */ + sw->number++; + fallthrough; case 15: sw->type = SW_ID_GP; break; @@ -681,9 +684,11 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sw->type = SW_ID_PP; break; case 66: - sw->bits = 3; /* fall through */ + sw->bits = 3; + fallthrough; case 198: - sw->length = 22; /* fall through */ + sw->length = 22; + fallthrough; case 64: sw->type = SW_ID_3DP; if (j == 160) diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index cf7cbcd0c29d..429411c6c0a8 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -146,7 +146,7 @@ static irqreturn_t spaceball_interrupt(struct serio *serio, break; } spaceball->escape = 0; - /* fall through */ + fallthrough; case 'M': case 'Q': case 'S': @@ -154,7 +154,7 @@ static irqreturn_t spaceball_interrupt(struct serio *serio, spaceball->escape = 0; data &= 0x1f; } - /* fall through */ + fallthrough; default: if (spaceball->escape) spaceball->escape = 0; @@ -220,13 +220,13 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) | BIT_MASK(BTN_B) | BIT_MASK(BTN_C) | BIT_MASK(BTN_MODE); - /* fall through */ + fallthrough; default: input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) | BIT_MASK(BTN_3) | BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7) | BIT_MASK(BTN_8); - /* fall through */ + fallthrough; case SPACEBALL_3003C: input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) | BIT_MASK(BTN_8); diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index e7d58e7f0257..eb0e9cd66bcb 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -1016,7 +1016,7 @@ static int adp5589_probe(struct i2c_client *client, switch (id->driver_data) { case ADP5585_02: kpad->support_row5 = true; - /* fall through */ + fallthrough; case ADP5585_01: kpad->is_adp5585 = true; kpad->var = &const_adp5585; diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6ec28265771d..edc613efc158 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -1241,7 +1241,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) case SERIO_8042_XL: atkbd->translated = true; - /* Fall through */ + fallthrough; case SERIO_8042: if (serio->write) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 53c9ff338dea..f2d4e4daa818 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -574,7 +574,6 @@ static int gpio_keys_setup_key(struct platform_device *pdev, IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING; break; case EV_ACT_ANY: - /* fall through */ default: /* * For other cases, we are OK letting suspend/resume diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 305f0160506a..8a36d78fed63 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -68,7 +68,7 @@ static int ati_remote2_get_channel_mask(char *buffer, { pr_debug("%s()\n", __func__); - return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); + return sprintf(buffer, "0x%04x\n", *(unsigned int *)kp->arg); } static int ati_remote2_set_mode_mask(const char *val, @@ -84,7 +84,7 @@ static int ati_remote2_get_mode_mask(char *buffer, { pr_debug("%s()\n", __func__); - return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg); + return sprintf(buffer, "0x%02x\n", *(unsigned int *)kp->arg); } static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index c09b9628ad34..e413801f0491 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c @@ -663,12 +663,8 @@ static const struct usb_device_id cm109_usb_table[] = { static void cm109_usb_cleanup(struct cm109_dev *dev) { kfree(dev->ctl_req); - if (dev->ctl_data) - usb_free_coherent(dev->udev, USB_PKT_LEN, - dev->ctl_data, dev->ctl_dma); - if (dev->irq_data) - usb_free_coherent(dev->udev, USB_PKT_LEN, - dev->irq_data, dev->irq_dma); + usb_free_coherent(dev->udev, USB_PKT_LEN, dev->ctl_data, dev->ctl_dma); + usb_free_coherent(dev->udev, USB_PKT_LEN, dev->irq_data, dev->irq_dma); usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index d8dbfc030d0f..08b9b5cdb943 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -335,7 +335,7 @@ static int ims_pcu_setup_gamepad(struct ims_pcu *pcu) err_free_mem: input_free_device(input); kfree(gamepad); - return -ENOMEM; + return error; } static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index 6699eb160a0f..a348247d3d38 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -575,8 +575,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, case IQS269_LOCAL_CAP_SIZE_GLOBAL_0pF5: engine_a |= IQS269_CHx_ENG_A_LOCAL_CAP_SIZE; - - /* fall through */ + fallthrough; case IQS269_LOCAL_CAP_SIZE_GLOBAL_ONLY: engine_b |= IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE; @@ -731,14 +730,12 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, iqs269->switches[i].code = val; iqs269->switches[i].enabled = true; } - - /* fall through */ + fallthrough; case IQS269_CHx_HALL_INACTIVE: if (iqs269->hall_enable) break; - - /* fall through */ + fallthrough; default: iqs269->keycode[i * IQS269_NUM_CH + reg] = val; @@ -1143,14 +1140,12 @@ static int iqs269_input_init(struct iqs269_private *iqs269) sw_code, state & BIT(j)); } - - /* fall through */ + fallthrough; case IQS269_CHx_HALL_INACTIVE: if (iqs269->hall_enable) continue; - - /* fall through */ + fallthrough; default: if (keycode != KEY_RESERVED) @@ -1273,14 +1268,12 @@ static int iqs269_report(struct iqs269_private *iqs269) input_report_switch(iqs269->keypad, sw_code, state & BIT(j)); - - /* fall through */ + fallthrough; case IQS269_CHx_HALL_INACTIVE: if (iqs269->hall_enable) continue; - - /* fall through */ + fallthrough; default: input_report_key(iqs269->keypad, keycode, diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index 8ceaf7db2882..81e777a04b88 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -190,7 +190,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "Failed to request direction pwm: %d", err); - /* Fall through */ + fallthrough; case -EPROBE_DEFER: return err; diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index a1bba722b234..4ff5cd2a6d8d 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c @@ -124,7 +124,7 @@ static void xenkbd_handle_mt_event(struct xenkbd_info *info, switch (mtouch->event_type) { case XENKBD_MT_EV_DOWN: input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, true); - /* fall through */ + fallthrough; case XENKBD_MT_EV_MOTION: input_report_abs(info->mtouch, ABS_MT_POSITION_X, @@ -524,7 +524,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, case XenbusStateClosed: if (dev->state == XenbusStateClosed) break; - /* fall through - Missed the backend's CLOSING state */ + fallthrough; /* Missed the backend's CLOSING state */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 34700eda0429..b067bfd2699c 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1929,7 +1929,7 @@ static int alps_monitor_mode(struct psmouse *psmouse, bool enable) static int alps_absolute_mode_v6(struct psmouse *psmouse) { u16 reg_val = 0x181; - int ret = -1; + int ret; /* enter monitor mode, to write the register */ if (alps_monitor_mode(psmouse, true)) diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 3f06e8a495d8..bfa26651c0be 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -458,7 +458,7 @@ static int atp_status_check(struct urb *urb) dev->info->datalen, dev->urb->actual_length); dev->overflow_warned = true; } - /* fall through */ + fallthrough; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c index 00e395dfc3d5..a0361f9325f8 100644 --- a/drivers/input/mouse/cyapa_gen3.c +++ b/drivers/input/mouse/cyapa_gen3.c @@ -1067,7 +1067,7 @@ static int cyapa_gen3_do_operational_check(struct cyapa *cyapa) return error; } - /* Fall through */ + fallthrough; case CYAPA_STATE_BL_IDLE: /* Try to get firmware version in bootloader mode. */ cyapa_gen3_bl_query_data(cyapa); @@ -1078,7 +1078,7 @@ static int cyapa_gen3_do_operational_check(struct cyapa *cyapa) return error; } - /* Fall through */ + fallthrough; case CYAPA_STATE_OP: /* * Reading query data before going back to the full mode diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c index 7f012bfa2658..bb3a63d1268d 100644 --- a/drivers/input/mouse/cyapa_gen5.c +++ b/drivers/input/mouse/cyapa_gen5.c @@ -2554,7 +2554,7 @@ static int cyapa_gen5_do_operational_check(struct cyapa *cyapa) } cyapa->state = CYAPA_STATE_GEN5_APP; - /* fall through */ + fallthrough; case CYAPA_STATE_GEN5_APP: /* diff --git a/drivers/input/mouse/cyapa_gen6.c b/drivers/input/mouse/cyapa_gen6.c index c1b524ab4623..7eba66fbef58 100644 --- a/drivers/input/mouse/cyapa_gen6.c +++ b/drivers/input/mouse/cyapa_gen6.c @@ -680,7 +680,7 @@ static int cyapa_gen6_operational_check(struct cyapa *cyapa) } cyapa->state = CYAPA_STATE_GEN6_APP; - /* fall through */ + fallthrough; case CYAPA_STATE_GEN6_APP: /* diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h index a9074ac9364f..c75b00c45d75 100644 --- a/drivers/input/mouse/elan_i2c.h +++ b/drivers/input/mouse/elan_i2c.h @@ -26,6 +26,8 @@ #define ETP_CALIBRATE_MAX_LEN 3 +#define ETP_FEATURE_REPORT_MK BIT(0) + /* IAP Firmware handling */ #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" @@ -33,6 +35,8 @@ #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_PAGE_SIZE_128 128 +#define ETP_FW_PAGE_SIZE_512 512 #define ETP_FW_SIGNATURE_SIZE 6 struct i2c_client; @@ -55,8 +59,9 @@ struct elan_transport_ops { int (*get_baseline_data)(struct i2c_client *client, bool max_baseliune, u8 *value); - int (*get_version)(struct i2c_client *client, bool iap, u8 *version); - int (*get_sm_version)(struct i2c_client *client, + int (*get_version)(struct i2c_client *client, u8 pattern, bool iap, + u8 *version); + int (*get_sm_version)(struct i2c_client *client, u8 pattern, u16 *ic_type, u8 *version, u8 *clickpad); int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); int (*get_product_id)(struct i2c_client *client, u16 *id); @@ -72,13 +77,18 @@ struct elan_transport_ops { int (*iap_get_mode)(struct i2c_client *client, enum tp_mode *mode); int (*iap_reset)(struct i2c_client *client); - int (*prepare_fw_update)(struct i2c_client *client); - int (*write_fw_block)(struct i2c_client *client, + int (*prepare_fw_update)(struct i2c_client *client, u16 ic_type, + u8 iap_version); + int (*write_fw_block)(struct i2c_client *client, u16 fw_page_size, const u8 *page, u16 checksum, int idx); int (*finish_fw_update)(struct i2c_client *client, struct completion *reset_done); - int (*get_report)(struct i2c_client *client, u8 *report); + int (*get_report_features)(struct i2c_client *client, u8 pattern, + unsigned int *features, + unsigned int *report_len); + int (*get_report)(struct i2c_client *client, u8 *report, + unsigned int report_len); int (*get_pressure_adjustment)(struct i2c_client *client, int *adjustment); int (*get_pattern)(struct i2c_client *client, u8 *pattern); diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 6291fb5fa015..c599e21a8478 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -50,12 +50,14 @@ #define ETP_MAX_FINGERS 5 #define ETP_FINGER_DATA_LEN 5 #define ETP_REPORT_ID 0x5D +#define ETP_REPORT_ID2 0x60 /* High precision report */ #define ETP_TP_REPORT_ID 0x5E #define ETP_REPORT_ID_OFFSET 2 #define ETP_TOUCH_INFO_OFFSET 3 #define ETP_FINGER_DATA_OFFSET 4 #define ETP_HOVER_INFO_OFFSET 30 -#define ETP_MAX_REPORT_LEN 34 +#define ETP_MK_DATA_OFFSET 33 /* For high precision reports */ +#define ETP_MAX_REPORT_LEN 39 /* The main device structure */ struct elan_tp_data { @@ -85,11 +87,14 @@ struct elan_tp_data { u8 sm_version; u8 iap_version; u16 fw_checksum; + unsigned int report_features; + unsigned int report_len; int pressure_adjustment; u8 mode; u16 ic_type; u16 fw_validpage_count; - u16 fw_signature_address; + u16 fw_page_size; + u32 fw_signature_address; bool irq_wake; @@ -100,8 +105,8 @@ struct elan_tp_data { bool middle_button; }; -static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count, - u16 *signature_address) +static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count, + u32 *signature_address, u16 *page_size) { switch (ic_type) { case 0x00: @@ -126,16 +131,37 @@ static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count, case 0x10: *validpage_count = 1024; break; + case 0x11: + *validpage_count = 1280; + break; + case 0x13: + *validpage_count = 2048; + break; + case 0x14: + case 0x15: + *validpage_count = 1024; + break; default: /* unknown ic type clear value */ *validpage_count = 0; *signature_address = 0; + *page_size = 0; return -ENXIO; } *signature_address = (*validpage_count * ETP_FW_PAGE_SIZE) - ETP_FW_SIGNATURE_SIZE; + if ((ic_type == 0x14 || ic_type == 0x15) && iap_version >= 2) { + *validpage_count /= 8; + *page_size = ETP_FW_PAGE_SIZE_512; + } else if (ic_type >= 0x0D && iap_version >= 1) { + *validpage_count /= 2; + *page_size = ETP_FW_PAGE_SIZE_128; + } else { + *page_size = ETP_FW_PAGE_SIZE; + } + return 0; } @@ -215,8 +241,13 @@ static int elan_query_product(struct elan_tp_data *data) if (error) return error; - error = data->ops->get_sm_version(data->client, &data->ic_type, - &data->sm_version, &data->clickpad); + error = data->ops->get_pattern(data->client, &data->pattern); + if (error) + return error; + + error = data->ops->get_sm_version(data->client, data->pattern, + &data->ic_type, &data->sm_version, + &data->clickpad); if (error) return error; @@ -312,9 +343,9 @@ static int elan_initialize(struct elan_tp_data *data) static int elan_query_device_info(struct elan_tp_data *data) { int error; - u16 ic_type; - error = data->ops->get_version(data->client, false, &data->fw_version); + error = data->ops->get_version(data->client, data->pattern, false, + &data->fw_version); if (error) return error; @@ -323,7 +354,8 @@ static int elan_query_device_info(struct elan_tp_data *data) if (error) return error; - error = data->ops->get_version(data->client, true, &data->iap_version); + error = data->ops->get_version(data->client, data->pattern, + true, &data->iap_version); if (error) return error; @@ -332,17 +364,16 @@ static int elan_query_device_info(struct el |