#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>
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;
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,
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;
}
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;
*/
#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
u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
u16 productinfo;
u32 firmware_id;
+ u32 package_id;
};
/* F01 device status bits */
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)
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);
},
.func = 0x01,
.probe = rmi_f01_probe,
+ .remove = rmi_f01_remove,
.config = rmi_f01_config,
.attention = rmi_f01_attention,
.suspend = rmi_f01_suspend,