diff options
author | KwangCheol Lee <kclee@dignsys.com> | 2017-09-11 14:09:08 +0900 |
---|---|---|
committer | Junghoon Kim <jhoon20.kim@samsung.com> | 2019-06-11 09:35:51 +0900 |
commit | ada1cac4732a9f4590ae7e4b56a4bded81ac4c0c (patch) | |
tree | c793fd970333bffcd7ce8d06fb46c91193badb30 /drivers | |
parent | 9016a87a65a36d44ffad4d2303db8bb8c201111d (diff) | |
download | linux-rpi3-ada1cac4732a9f4590ae7e4b56a4bded81ac4c0c.tar.gz linux-rpi3-ada1cac4732a9f4590ae7e4b56a4bded81ac4c0c.tar.bz2 linux-rpi3-ada1cac4732a9f4590ae7e4b56a4bded81ac4c0c.zip |
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 <kclee@dignsys.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/touchscreen/rpi-ft5406.c | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/drivers/input/touchscreen/rpi-ft5406.c b/drivers/input/touchscreen/rpi-ft5406.c index 4115b4666211..c47555f40f82 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); |