From c67e48dbd5983a93e47ea118869273b70bee89bc Mon Sep 17 00:00:00 2001 From: KwangCheol Lee Date: Mon, 11 Sep 2017 14:09:08 +0900 Subject: [PATCH] Input: rpi_ft5406 - add enable sysfs attribute 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 --- drivers/input/touchscreen/rpi-ft5406.c | 79 ++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c index 719ab01..7f38fbd 100644 --- a/drivers/input/touchscreen/rpi-ft5406.c +++ b/drivers/input/touchscreen/rpi-ft5406.c @@ -53,6 +53,8 @@ struct ft5406 { void __iomem *ts_base; dma_addr_t bus_addr; struct task_struct *thread; + bool enable; + struct mutex sysfs_mutex; uint16_t max_x; uint16_t max_y; @@ -160,6 +162,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; @@ -296,16 +354,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 that polls 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); @@ -329,7 +399,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); -- 2.7.4