Merge branch 'synaptics-rmi4' into next
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 6 Feb 2017 22:17:39 +0000 (14:17 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 6 Feb 2017 22:17:39 +0000 (14:17 -0800)
Bring in latest RMI4 support in preparation to the merge window.

drivers/input/rmi4/Kconfig
drivers/input/rmi4/rmi_2d_sensor.c
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_driver.c
drivers/input/rmi4/rmi_driver.h
drivers/input/rmi4/rmi_f01.c
drivers/input/rmi4/rmi_f03.c
drivers/input/rmi4/rmi_f34.c
drivers/input/rmi4/rmi_f34.h
drivers/input/rmi4/rmi_f34v7.c

index 8993983..78a78b9 100644 (file)
@@ -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
index 07007ff..8bb866c 100644 (file)
@@ -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)
index 213e318..ae1bffe 100644 (file)
@@ -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;
        }
 
index 11447ab..2aa3cd0 100644 (file)
@@ -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;
index 24f8f76..6e0449c 100644 (file)
@@ -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);
index 18baf4c..7f7e917 100644 (file)
@@ -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,
index 8a7ca3e..9a1b099 100644 (file)
@@ -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) {
index 9774dfb..425fe14 100644 (file)
@@ -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;
 
index 2c21056..43a9134 100644 (file)
@@ -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;
index ca31f95..56c6c39 100644 (file)
@@ -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)