Input: rpi_ft5406 - add enable sysfs attribute 57/148857/8
authorKwangCheol Lee <kclee@dignsys.com>
Mon, 11 Sep 2017 05:09:08 +0000 (14:09 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 13 Sep 2017 03:04:07 +0000 (03:04 +0000)
Add enable sysfs attribute for disable/enable the touchscreen input.
This feature is required to turn the touch screen display on or off.

Change-Id: I4d5250c32cc2118f0f19a8a3cfb76ea8574f6937
Signed-off-by: KwangCheol Lee <kclee@dignsys.com>
drivers/input/touchscreen/rpi-ft5406.c

index 9d7d054..36874f5 100644 (file)
@@ -49,6 +49,8 @@ struct ft5406 {
        void __iomem           * ts_base;
        dma_addr_t               bus_addr;
        struct task_struct     * thread;
+       bool                     enable;
+       struct mutex             sysfs_mutex;
 };
 
 /* Thread to poll for touchscreen events
@@ -117,6 +119,62 @@ static int ft5406_thread(void *arg)
        return 0;
 }
 
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct ft5406 *ts = (struct ft5406 *)dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", ts->enable);
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct ft5406 *ts = (struct ft5406 *)dev_get_drvdata(dev);
+       unsigned int val;
+       int error;
+
+       error = kstrtouint(buf, 0, &val);
+       if (error)
+               return error;
+
+       mutex_lock(&ts->sysfs_mutex);
+
+       if (ts->enable == !!val)
+               goto out;
+
+       if (val) {
+               ts->thread = kthread_run(ft5406_thread, ts, "ft5406");
+               if (IS_ERR(ts->thread)) {
+                       dev_err(dev, "Failed to create kernel thread");
+                       goto out;
+               }
+       } else {
+               error = kthread_stop(ts->thread);
+               if (unlikely(error)) {
+                       dev_err(dev, "Failed to stop kernel thread");
+                       goto out;
+               }
+       }
+       ts->enable = !!val;
+
+out:
+       mutex_unlock(&ts->sysfs_mutex);
+
+       return count;
+}
+
+static DEVICE_ATTR_RW(enable);
+
+static struct attribute *rpi_ft5406_attrs[] = {
+       &dev_attr_enable.attr,
+       NULL
+};
+
+static const struct attribute_group rpi_ft5406_attr_group = {
+       .attrs = rpi_ft5406_attrs,
+};
+
 static int ft5406_probe(struct platform_device *pdev)
 {
        int err = 0;
@@ -223,17 +281,28 @@ static int ft5406_probe(struct platform_device *pdev)
                goto out;
        }
 
+       ts->enable = true;
+       mutex_init(&ts->sysfs_mutex);
+
+       err = sysfs_create_group(&dev->kobj, &rpi_ft5406_attr_group);
+       if (err) {
+               dev_err(dev, "failed to create sysfs group: %d\n", err);
+               goto out;
+       }
+
        // create thread to poll the touch events
        ts->thread = kthread_run(ft5406_thread, ts, "ft5406");
-       if(ts->thread == NULL)
+       if (IS_ERR(ts->thread))
        {
                dev_err(dev, "Failed to create kernel thread");
                err = -ENOMEM;
-               goto out;
+               goto out_sysfs;
        }
 
        return 0;
 
+out_sysfs:
+       sysfs_remove_group(&dev->kobj, &rpi_ft5406_attr_group);
 out:
        if (ts->bus_addr) {
                dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr);
@@ -257,7 +326,10 @@ static int ft5406_remove(struct platform_device *pdev)
        
        dev_info(dev, "Removing rpi-ft5406\n");
        
-       kthread_stop(ts->thread);
+       sysfs_remove_group(&dev->kobj, &rpi_ft5406_attr_group);
+
+       if (ts->enable)
+               kthread_stop(ts->thread);
 
        if (ts->bus_addr)
                dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr);