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.

1  2 
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_driver.c
drivers/input/rmi4/rmi_f01.c

@@@ -9,6 -9,7 +9,6 @@@
  
  #include <linux/kernel.h>
  #include <linux/device.h>
 -#include <linux/kconfig.h>
  #include <linux/list.h>
  #include <linux/pm.h>
  #include <linux/rmi.h>
@@@ -55,7 -56,7 +55,7 @@@ static void rmi_release_device(struct d
        kfree(rmi_dev);
  }
  
 -static struct device_type rmi_device_type = {
 +static const struct device_type rmi_device_type = {
        .name           = "rmi4_sensor",
        .release        = rmi_release_device,
  };
@@@ -134,7 -135,7 +134,7 @@@ static void rmi_release_function(struc
        kfree(fn);
  }
  
 -static struct device_type rmi_function_type = {
 +static const struct device_type rmi_function_type = {
        .name           = "rmi4_function",
        .release        = rmi_release_function,
  };
@@@ -261,10 -262,10 +261,10 @@@ int __rmi_register_function_handler(str
        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;
        }
  
@@@ -18,6 -18,7 +18,6 @@@
  #include <linux/delay.h>
  #include <linux/fs.h>
  #include <linux/irq.h>
 -#include <linux/kconfig.h>
  #include <linux/pm.h>
  #include <linux/slab.h>
  #include <linux/of.h>
@@@ -265,6 -266,19 +265,19 @@@ static int rmi_irq_init(struct rmi_devi
        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 -378,7 +377,7 @@@ static void rmi_driver_set_input_name(s
                                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 -850,7 +849,7 @@@ static int rmi_create_function(struct r
                               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 -1054,7 +1053,7 @@@ int rmi_probe_interrupts(struct rmi_dri
        }
  
        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;
@@@ -8,10 -8,12 +8,11 @@@
   */
  
  #include <linux/kernel.h>
 -#include <linux/kconfig.h>
  #include <linux/rmi.h>
  #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 -56,7 +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 -223,19 +222,19 @@@ static int rmi_f01_read_properties(stru
                        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,
        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 -571,18 +570,18 @@@ static int rmi_f01_probe(struct rmi_fun
  
        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 -722,7 +721,7 @@@ struct rmi_function_handler rmi_f01_han
        },
        .func           = 0x01,
        .probe          = rmi_f01_probe,
+       .remove         = rmi_f01_remove,
        .config         = rmi_f01_config,
        .attention      = rmi_f01_attention,
        .suspend        = rmi_f01_suspend,