diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-02-06 14:17:39 -0800 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-02-06 14:17:39 -0800 |
commit | d5e6e0fa442a479e27dfb7d17aeef1260dc19b09 (patch) | |
tree | b0a3d1b6c32335b009493d79b30f8e59ed60f269 /drivers/input | |
parent | 57b8443d3e5bd046a519ff714ca31c64c7f04309 (diff) | |
parent | f32361b71ae5c81b8fb96f796ab947ba2ad17aa8 (diff) | |
download | linux-d5e6e0fa442a479e27dfb7d17aeef1260dc19b09.tar.bz2 |
Merge branch 'synaptics-rmi4' into next
Bring in latest RMI4 support in preparation to the merge window.
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/rmi4/Kconfig | 28 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_2d_sensor.c | 7 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_bus.c | 4 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 19 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.h | 3 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f01.c | 104 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f03.c | 3 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34.c | 142 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34.h | 4 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_f34v7.c | 11 |
10 files changed, 268 insertions, 57 deletions
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig index 8993983e3fe4..78a78b99ec31 100644 --- a/drivers/input/rmi4/Kconfig +++ b/drivers/input/rmi4/Kconfig @@ -9,9 +9,11 @@ config RMI4_CORE If unsure, say Y. +if RMI4_CORE + config RMI4_I2C tristate "RMI4 I2C Support" - depends on RMI4_CORE && I2C + depends on I2C help Say Y here if you want to support RMI4 devices connected to an I2C bus. @@ -20,7 +22,7 @@ config RMI4_I2C config RMI4_SPI tristate "RMI4 SPI Support" - depends on RMI4_CORE && SPI + depends on SPI help Say Y here if you want to support RMI4 devices connected to a SPI bus. @@ -29,7 +31,7 @@ config RMI4_SPI config RMI4_SMB tristate "RMI4 SMB Support" - depends on RMI4_CORE && I2C + depends on I2C help Say Y here if you want to support RMI4 devices connected to an SMB bus. @@ -40,23 +42,20 @@ config RMI4_SMB called rmi_smbus. config RMI4_F03 - bool "RMI4 Function 03 (PS2 Guest)" - depends on RMI4_CORE + bool "RMI4 Function 03 (PS2 Guest)" depends on SERIO=y || RMI4_CORE=SERIO - help - Say Y here if you want to add support for RMI4 function 03. + help + Say Y here if you want to add support for RMI4 function 03. - Function 03 provides PS2 guest support for RMI4 devices. This - includes support for TrackPoints on TouchPads. + Function 03 provides PS2 guest support for RMI4 devices. This + includes support for TrackPoints on TouchPads. config RMI4_2D_SENSOR bool - depends on RMI4_CORE config RMI4_F11 bool "RMI4 Function 11 (2D pointing)" select RMI4_2D_SENSOR - depends on RMI4_CORE help Say Y here if you want to add support for RMI4 function 11. @@ -67,7 +66,6 @@ config RMI4_F11 config RMI4_F12 bool "RMI4 Function 12 (2D pointing)" select RMI4_2D_SENSOR - depends on RMI4_CORE help Say Y here if you want to add support for RMI4 function 12. @@ -77,7 +75,6 @@ config RMI4_F12 config RMI4_F30 bool "RMI4 Function 30 (GPIO LED)" - depends on RMI4_CORE help Say Y here if you want to add support for RMI4 function 30. @@ -86,7 +83,6 @@ config RMI4_F30 config RMI4_F34 bool "RMI4 Function 34 (Device reflash)" - depends on RMI4_CORE select FW_LOADER help Say Y here if you want to add support for RMI4 function 34. @@ -97,7 +93,6 @@ config RMI4_F34 config RMI4_F54 bool "RMI4 Function 54 (Analog diagnostics)" - depends on RMI4_CORE depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m) select VIDEOBUF2_VMALLOC select RMI4_F55 @@ -109,9 +104,10 @@ config RMI4_F54 config RMI4_F55 bool "RMI4 Function 55 (Sensor tuning)" - depends on RMI4_CORE help Say Y here if you want to add support for RMI4 function 55 Function 55 provides access to the RMI4 touch sensor tuning mechanism. + +endif # RMI_CORE diff --git a/drivers/input/rmi4/rmi_2d_sensor.c b/drivers/input/rmi4/rmi_2d_sensor.c index 07007ff8e29f..8bb866c7b985 100644 --- a/drivers/input/rmi4/rmi_2d_sensor.c +++ b/drivers/input/rmi4/rmi_2d_sensor.c @@ -144,8 +144,13 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor) int input_flags = 0; if (sensor->report_abs) { - if (sensor->axis_align.swap_axes) + if (sensor->axis_align.swap_axes) { swap(sensor->max_x, sensor->max_y); + swap(sensor->axis_align.clip_x_low, + sensor->axis_align.clip_y_low); + swap(sensor->axis_align.clip_x_high, + sensor->axis_align.clip_y_high); + } sensor->min_x = sensor->axis_align.clip_x_low; if (sensor->axis_align.clip_x_high) diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c index 213e3189f74c..ae1bffe45c75 100644 --- a/drivers/input/rmi4/rmi_bus.c +++ b/drivers/input/rmi4/rmi_bus.c @@ -261,10 +261,10 @@ int __rmi_register_function_handler(struct rmi_function_handler *handler, driver->probe = rmi_function_probe; driver->remove = rmi_function_remove; - error = driver_register(&handler->driver); + error = driver_register(driver); if (error) { pr_err("driver_register() failed for %s, error: %d\n", - handler->driver.name, error); + driver->name, error); return error; } diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 11447ab1055c..2aa3cd0fe222 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -265,6 +265,19 @@ static int rmi_irq_init(struct rmi_device *rmi_dev) return 0; } +struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number) +{ + struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + struct rmi_function *entry; + + list_for_each_entry(entry, &data->function_list, node) { + if (entry->fd.function_number == number) + return entry; + } + + return NULL; +} + static int suspend_one_function(struct rmi_function *fn) { struct rmi_function_handler *fh; @@ -364,7 +377,7 @@ static void rmi_driver_set_input_name(struct rmi_device *rmi_dev, struct input_dev *input) { struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); - char *device_name = rmi_f01_get_product_ID(data->f01_container); + const char *device_name = rmi_f01_get_product_ID(data->f01_container); char *name; name = devm_kasprintf(&rmi_dev->dev, GFP_KERNEL, @@ -836,7 +849,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev, void *ctx, const struct pdt_entry *pdt) { struct device *dev = &rmi_dev->dev; - struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); + struct rmi_driver_data *data = dev_get_drvdata(dev); int *current_irq_count = ctx; struct rmi_function *fn; int i; @@ -1040,7 +1053,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) } if (data->bootloader_mode) - dev_warn(&rmi_dev->dev, "Device in bootloader mode.\n"); + dev_warn(dev, "Device in bootloader mode.\n"); data->irq_count = irq_count; data->num_of_irq_regs = (data->irq_count + 7) / 8; diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h index 24f8f764d171..6e0449cdca68 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -93,6 +93,7 @@ bool rmi_is_physical_driver(struct device_driver *); int rmi_register_physical_driver(void); void rmi_unregister_physical_driver(void); void rmi_free_function_list(struct rmi_device *rmi_dev); +struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number); int rmi_enable_sensor(struct rmi_device *rmi_dev); int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, int (*callback)(struct rmi_device *rmi_dev, void *ctx, @@ -104,7 +105,7 @@ int rmi_init_functions(struct rmi_driver_data *data); int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, const struct pdt_entry *pdt); -char *rmi_f01_get_product_ID(struct rmi_function *fn); +const char *rmi_f01_get_product_ID(struct rmi_function *fn); #ifdef CONFIG_RMI4_F34 int rmi_f34_create_sysfs(struct rmi_device *rmi_dev); diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index 18baf4ceb940..7f7e9176f7ea 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/of.h> +#include <asm/unaligned.h> #include "rmi_driver.h" #define RMI_PRODUCT_ID_LENGTH 10 @@ -54,6 +55,7 @@ struct f01_basic_properties { u8 product_id[RMI_PRODUCT_ID_LENGTH + 1]; u16 productinfo; u32 firmware_id; + u32 package_id; }; /* F01 device status bits */ @@ -220,8 +222,19 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev, has_build_id_query = !!(queries[0] & BIT(1)); } - if (has_package_id_query) + if (has_package_id_query) { + ret = rmi_read_block(rmi_dev, prod_info_addr, + queries, sizeof(__le64)); + if (ret) { + dev_err(&rmi_dev->dev, + "Failed to read package info: %d\n", + ret); + return ret; + } + + props->package_id = get_unaligned_le64(queries); prod_info_addr++; + } if (has_build_id_query) { ret = rmi_read_block(rmi_dev, prod_info_addr, queries, @@ -241,13 +254,90 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev, return 0; } -char *rmi_f01_get_product_ID(struct rmi_function *fn) +const char *rmi_f01_get_product_ID(struct rmi_function *fn) { struct f01_data *f01 = dev_get_drvdata(&fn->dev); return f01->properties.product_id; } +static ssize_t rmi_driver_manufacturer_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", + f01->properties.manufacturer_id); +} + +static DEVICE_ATTR(manufacturer_id, 0444, + rmi_driver_manufacturer_id_show, NULL); + +static ssize_t rmi_driver_dom_show(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev); + + return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.dom); +} + +static DEVICE_ATTR(date_of_manufacture, 0444, rmi_driver_dom_show, NULL); + +static ssize_t rmi_driver_product_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev); + + return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.product_id); +} + +static DEVICE_ATTR(product_id, 0444, rmi_driver_product_id_show, NULL); + +static ssize_t rmi_driver_firmware_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", f01->properties.firmware_id); +} + +static DEVICE_ATTR(firmware_id, 0444, rmi_driver_firmware_id_show, NULL); + +static ssize_t rmi_driver_package_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev); + + u32 package_id = f01->properties.package_id; + + return scnprintf(buf, PAGE_SIZE, "%04x.%04x\n", + package_id & 0xffff, (package_id >> 16) & 0xffff); +} + +static DEVICE_ATTR(package_id, 0444, rmi_driver_package_id_show, NULL); + +static struct attribute *rmi_f01_attrs[] = { + &dev_attr_manufacturer_id.attr, + &dev_attr_date_of_manufacture.attr, + &dev_attr_product_id.attr, + &dev_attr_firmware_id.attr, + &dev_attr_package_id.attr, + NULL +}; + +static struct attribute_group rmi_f01_attr_group = { + .attrs = rmi_f01_attrs, +}; + #ifdef CONFIG_OF static int rmi_f01_of_probe(struct device *dev, struct rmi_device_platform_data *pdata) @@ -480,9 +570,18 @@ static int rmi_f01_probe(struct rmi_function *fn) dev_set_drvdata(&fn->dev, f01); + error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); + if (error) + dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error); + return 0; } +static void rmi_f01_remove(struct rmi_function *fn) +{ + sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); +} + static int rmi_f01_config(struct rmi_function *fn) { struct f01_data *f01 = dev_get_drvdata(&fn->dev); @@ -622,6 +721,7 @@ struct rmi_function_handler rmi_f01_handler = { }, .func = 0x01, .probe = rmi_f01_probe, + .remove = rmi_f01_remove, .config = rmi_f01_config, .attention = rmi_f01_attention, .suspend = rmi_f01_suspend, diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index 8a7ca3e2f95e..9a1b099b72e0 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -175,9 +175,6 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) int i; int error; - if (!rmi_dev) - return -ENODEV; - if (drvdata->attn_data.data) { /* First grab the data passed by the transport device */ if (drvdata->attn_data.size < ob_len) { diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index 9774dfbab9bb..425fe140e9df 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -157,6 +157,9 @@ static int rmi_f34_write_blocks(struct f34_data *f34, const void *data, i + 1, block_count); data += f34->v5.block_size; + f34->update_progress += f34->v5.block_size; + f34->update_status = (f34->update_progress * 100) / + f34->update_size; } return 0; @@ -174,7 +177,7 @@ static int rmi_f34_write_config(struct f34_data *f34, const void *data) F34_WRITE_CONFIG_BLOCK); } -int rmi_f34_enable_flash(struct f34_data *f34) +static int rmi_f34_enable_flash(struct f34_data *f34) { return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG, F34_ENABLE_WAIT_MS, true); @@ -184,9 +187,14 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, const struct rmi_f34_firmware *syn_fw) { struct rmi_function *fn = f34->fn; + u32 image_size = le32_to_cpu(syn_fw->image_size); + u32 config_size = le32_to_cpu(syn_fw->config_size); int ret; - if (syn_fw->image_size) { + f34->update_progress = 0; + f34->update_size = image_size + config_size; + + if (image_size) { dev_info(&fn->dev, "Erasing firmware...\n"); ret = rmi_f34_command(f34, F34_ERASE_ALL, F34_ERASE_WAIT_MS, true); @@ -194,18 +202,18 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, return ret; dev_info(&fn->dev, "Writing firmware (%d bytes)...\n", - syn_fw->image_size); + image_size); ret = rmi_f34_write_firmware(f34, syn_fw->data); if (ret) return ret; } - if (syn_fw->config_size) { + if (config_size) { /* * We only need to erase config if we haven't updated * firmware. */ - if (!syn_fw->image_size) { + if (!image_size) { dev_info(&fn->dev, "Erasing config...\n"); ret = rmi_f34_command(f34, F34_ERASE_CONFIG, F34_ERASE_WAIT_MS, true); @@ -214,9 +222,8 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, } dev_info(&fn->dev, "Writing config (%d bytes)...\n", - syn_fw->config_size); - ret = rmi_f34_write_config(f34, - &syn_fw->data[syn_fw->image_size]); + config_size); + ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]); if (ret) return ret; } @@ -224,21 +231,23 @@ static int rmi_f34_flash_firmware(struct f34_data *f34, return 0; } -int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) +static int rmi_f34_update_firmware(struct f34_data *f34, + const struct firmware *fw) { - const struct rmi_f34_firmware *syn_fw; + const struct rmi_f34_firmware *syn_fw = + (const struct rmi_f34_firmware *)fw->data; + u32 image_size = le32_to_cpu(syn_fw->image_size); + u32 config_size = le32_to_cpu(syn_fw->config_size); int ret; - syn_fw = (const struct rmi_f34_firmware *)fw->data; BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) != F34_FW_IMAGE_OFFSET); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, - "FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n", - (int)fw->size, + "FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n", + fw->size, le32_to_cpu(syn_fw->checksum), - le32_to_cpu(syn_fw->image_size), - le32_to_cpu(syn_fw->config_size)); + image_size, config_size); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n", @@ -246,27 +255,25 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) (int)sizeof(syn_fw->product_id), syn_fw->product_id, syn_fw->product_info[0], syn_fw->product_info[1]); - if (syn_fw->image_size && - syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) { + if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: fw size %d, expected %d\n", - syn_fw->image_size, - f34->v5.fw_blocks * f34->v5.block_size); + image_size, f34->v5.fw_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } - if (syn_fw->config_size && - syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) { + if (config_size && + config_size != f34->v5.config_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: config size %d, expected %d\n", - syn_fw->config_size, + config_size, f34->v5.config_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } - if (syn_fw->image_size && !syn_fw->config_size) { + if (image_size && !config_size) { dev_err(&f34->fn->dev, "Bad firmware image: no config data\n"); ret = -EILSEQ; goto out; @@ -283,6 +290,63 @@ out: return ret; } +static int rmi_f34_status(struct rmi_function *fn) +{ + struct f34_data *f34 = dev_get_drvdata(&fn->dev); + + /* + * The status is the percentage complete, or once complete, + * zero for success or a negative return code. + */ + return f34->update_status; +} + +static ssize_t rmi_driver_bootloader_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct rmi_function *fn = data->f34_container; + struct f34_data *f34; + + if (fn) { + f34 = dev_get_drvdata(&fn->dev); + + if (f34->bl_version == 5) + return scnprintf(buf, PAGE_SIZE, "%c%c\n", + f34->bootloader_id[0], + f34->bootloader_id[1]); + else + return scnprintf(buf, PAGE_SIZE, "V%d.%d\n", + f34->bootloader_id[1], + f34->bootloader_id[0]); + } + + return 0; +} + +static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL); + +static ssize_t rmi_driver_configuration_id_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + struct rmi_function *fn = data->f34_container; + struct f34_data *f34; + + if (fn) { + f34 = dev_get_drvdata(&fn->dev); + + return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id); + } + + return 0; +} + +static DEVICE_ATTR(configuration_id, 0444, + rmi_driver_configuration_id_show, NULL); + static int rmi_firmware_update(struct rmi_driver_data *data, const struct firmware *fw) { @@ -346,7 +410,13 @@ static int rmi_firmware_update(struct rmi_driver_data *data, else ret = rmi_f34_update_firmware(f34, fw); - dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret); + if (ret) { + f34->update_status = ret; + dev_err(&f34->fn->dev, + "Firmware update failed, status: %d\n", ret); + } else { + dev_info(&f34->fn->dev, "Firmware update complete\n"); + } rmi_disable_irq(rmi_dev, false); @@ -377,9 +447,6 @@ static int rmi_firmware_update(struct rmi_driver_data *data, return ret; } -static int rmi_firmware_update(struct rmi_driver_data *data, - const struct firmware *fw); - static ssize_t rmi_driver_update_fw_store(struct device *dev, struct device_attribute *dattr, const char *buf, size_t count) @@ -414,8 +481,27 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev, static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store); +static ssize_t rmi_driver_update_fw_status_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct rmi_driver_data *data = dev_get_drvdata(dev); + int update_status = 0; + + if (data->f34_container) + update_status = rmi_f34_status(data->f34_container); + + return scnprintf(buf, PAGE_SIZE, "%d\n", update_status); +} + +static DEVICE_ATTR(update_fw_status, 0444, + rmi_driver_update_fw_status_show, NULL); + static struct attribute *rmi_firmware_attrs[] = { + &dev_attr_bootloader_id.attr, + &dev_attr_configuration_id.attr, &dev_attr_update_fw.attr, + &dev_attr_update_fw_status.attr, NULL }; @@ -441,8 +527,6 @@ static int rmi_f34_probe(struct rmi_function *fn) /* v5 code only supported version 0, try V7 probe */ if (version > 0) return rmi_f34v7_probe(f34); - else if (version != 0) - return -ENODEV; f34->bl_version = 5; diff --git a/drivers/input/rmi4/rmi_f34.h b/drivers/input/rmi4/rmi_f34.h index 2c21056dc375..43a91349b28d 100644 --- a/drivers/input/rmi4/rmi_f34.h +++ b/drivers/input/rmi4/rmi_f34.h @@ -301,6 +301,10 @@ struct f34_data { unsigned char bootloader_id[5]; unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1]; + int update_status; + int update_progress; + int update_size; + union { struct f34v5_data v5; struct f34v7_data v7; diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index ca31f9539d9b..56c6c39ad31e 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -588,6 +588,7 @@ static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34) u16 block_count; block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size; + f34->update_size += block_count; if (block_count != f34->v7.blkcount.ui_firmware) { dev_err(&f34->fn->dev, @@ -604,6 +605,7 @@ static int rmi_f34v7_check_ui_config_size(struct f34_data *f34) u16 block_count; block_count = f34->v7.img.ui_config.size / f34->v7.block_size; + f34->update_size += block_count; if (block_count != f34->v7.blkcount.ui_config) { dev_err(&f34->fn->dev, "UI config size mismatch\n"); @@ -618,6 +620,7 @@ static int rmi_f34v7_check_dp_config_size(struct f34_data *f34) u16 block_count; block_count = f34->v7.img.dp_config.size / f34->v7.block_size; + f34->update_size += block_count; if (block_count != f34->v7.blkcount.dp_config) { dev_err(&f34->fn->dev, "Display config size mismatch\n"); @@ -632,6 +635,8 @@ static int rmi_f34v7_check_guest_code_size(struct f34_data *f34) u16 block_count; block_count = f34->v7.img.guest_code.size / f34->v7.block_size; + f34->update_size += block_count; + if (block_count != f34->v7.blkcount.guest_code) { dev_err(&f34->fn->dev, "Guest code size mismatch\n"); return -EINVAL; @@ -645,6 +650,7 @@ static int rmi_f34v7_check_bl_config_size(struct f34_data *f34) u16 block_count; block_count = f34->v7.img.bl_config.size / f34->v7.block_size; + f34->update_size += block_count; if (block_count != f34->v7.blkcount.bl_config) { dev_err(&f34->fn->dev, "Bootloader config size mismatch\n"); @@ -881,6 +887,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34, block_ptr += (transfer * f34->v7.block_size); remaining -= transfer; + f34->update_progress += transfer; + f34->update_status = (f34->update_progress * 100) / + f34->update_size; } while (remaining); return 0; @@ -1191,6 +1200,8 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) rmi_f34v7_read_queries_bl_version(f34); f34->v7.image = fw->data; + f34->update_progress = 0; + f34->update_size = 0; ret = rmi_f34v7_parse_image_info(f34); if (ret < 0) |