]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Input: goodix-berlin - add sysfs interface for reading and writing touch IC registers
authorCharles Wang <charles.goodix@gmail.com>
Wed, 15 May 2024 23:20:28 +0000 (16:20 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 19 Jul 2024 21:57:17 +0000 (14:57 -0700)
Export a sysfs interface that would allow reading and writing touchscreen
IC registers. With this interface many things can be done in usersapce
such as firmware updates. An example tool that utilizes this interface
for performing firmware updates can be found at [1].

[1] https://github.com/goodix/fwupdate_for_berlin_linux

Signed-off-by: Charles Wang <charles.goodix@gmail.com>
Link: https://lore.kernel.org/r/20240514115135.21410-1-charles.goodix@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/goodix_berlin.h
drivers/input/touchscreen/goodix_berlin_core.c
drivers/input/touchscreen/goodix_berlin_i2c.c
drivers/input/touchscreen/goodix_berlin_spi.c

index 1fd77eb69c9a6c0b0c6b2b1e238a35f16d719590..38b6f9ddbdefcee521458b9499957cf924fe1ef6 100644 (file)
@@ -20,5 +20,6 @@ int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
                        struct regmap *regmap);
 
 extern const struct dev_pm_ops goodix_berlin_pm_ops;
+extern const struct attribute_group *goodix_berlin_groups[];
 
 #endif
index e7b41a926ef885f301b15d816e352ad1480fc2fd..0bfca897ce5af16c8b834ba6e3ce99959e5c9950 100644 (file)
@@ -672,6 +672,49 @@ static void goodix_berlin_power_off_act(void *data)
        goodix_berlin_power_off(cd);
 }
 
+static ssize_t registers_read(struct file *filp, struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t off, size_t count)
+{
+       struct device *dev = kobj_to_dev(kobj);
+       struct goodix_berlin_core *cd = dev_get_drvdata(dev);
+       int error;
+
+       error = regmap_raw_read(cd->regmap, off, buf, count);
+
+       return error ? error : count;
+}
+
+static ssize_t registers_write(struct file *filp, struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
+{
+       struct device *dev = kobj_to_dev(kobj);
+       struct goodix_berlin_core *cd = dev_get_drvdata(dev);
+       int error;
+
+       error = regmap_raw_write(cd->regmap, off, buf, count);
+
+       return error ? error : count;
+}
+
+static BIN_ATTR_ADMIN_RW(registers, 0);
+
+static struct bin_attribute *goodix_berlin_bin_attrs[] = {
+       &bin_attr_registers,
+       NULL,
+};
+
+static const struct attribute_group goodix_berlin_attr_group = {
+       .bin_attrs = goodix_berlin_bin_attrs,
+};
+
+const struct attribute_group *goodix_berlin_groups[] = {
+       &goodix_berlin_attr_group,
+       NULL,
+};
+EXPORT_SYMBOL_GPL(goodix_berlin_groups);
+
 int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
                        struct regmap *regmap)
 {
index 2e7098078838f57d365464513af29def3adb7857..ad7a60d943388f7ccb509d6dd25cceb7cd1fee56 100644 (file)
@@ -64,6 +64,7 @@ static struct i2c_driver goodix_berlin_i2c_driver = {
                .name = "goodix-berlin-i2c",
                .of_match_table = goodix_berlin_i2c_of_match,
                .pm = pm_sleep_ptr(&goodix_berlin_pm_ops),
+               .dev_groups = goodix_berlin_groups,
        },
        .probe = goodix_berlin_i2c_probe,
        .id_table = goodix_berlin_i2c_id,
index 82774a4129563af6c4f4ac3d82e89fc3cc7e752e..a2d80e84391ba63cd2703de41ed8a0053763edd6 100644 (file)
@@ -169,6 +169,7 @@ static struct spi_driver goodix_berlin_spi_driver = {
                .name = "goodix-berlin-spi",
                .of_match_table = goodix_berlin_spi_of_match,
                .pm = pm_sleep_ptr(&goodix_berlin_pm_ops),
+               .dev_groups = goodix_berlin_groups,
        },
        .probe = goodix_berlin_spi_probe,
        .id_table = goodix_berlin_spi_ids,