summaryrefslogtreecommitdiff
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorAlex Sarraf <asarraf@codeaurora.org>2017-02-22 12:24:20 -0800
committerAlex Sarraf <asarraf@codeaurora.org>2017-04-13 14:30:49 -0700
commit14e89235dc188bd86f550770945e9f0e93110f1b (patch)
treed8f2c9044e2a61c4b039f63a54c5c9e013692eaa /drivers/input/misc
parent9898f867d919f610016c338b39127595cc532a07 (diff)
input: misc: hbtp_input: Support for Region of Interest/sensors
Add support for sensor and Region of Interest (ROI) events. Create new ioctl to receive sensor data from userspace. Create binary sysfs entries to expose data from kernel to userspace. Change-Id: Ifa76f08eb293c3da0618c22c07e65976319ea926 Signed-off-by: Alex Sarraf <asarraf@codeaurora.org>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/hbtp_input.c104
1 files changed, 103 insertions, 1 deletions
diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c
index 1df5d8812991..6d2e7a569044 100644
--- a/drivers/input/misc/hbtp_input.c
+++ b/drivers/input/misc/hbtp_input.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -47,6 +47,8 @@ struct hbtp_data {
struct input_dev *input_dev;
s32 count;
struct mutex mutex;
+ struct mutex sensormutex;
+ struct hbtp_sensor_data *sensor_data;
bool touch_status[HBTP_MAX_FINGER];
#if defined(CONFIG_FB)
struct notifier_block fb_notif;
@@ -87,10 +89,14 @@ struct hbtp_data {
u32 power_on_delay;
u32 power_off_delay;
bool manage_pin_ctrl;
+ s16 ROI[MAX_ROI_SIZE];
+ s16 accelBuffer[MAX_ACCEL_SIZE];
};
static struct hbtp_data *hbtp;
+static struct kobject *sensor_kobject;
+
#if defined(CONFIG_FB)
static int hbtp_fb_suspend(struct hbtp_data *ts);
static int hbtp_fb_early_resume(struct hbtp_data *ts);
@@ -150,6 +156,46 @@ static int fb_notifier_callback(struct notifier_block *self,
}
#endif
+static ssize_t hbtp_sensor_roi_show(struct file *dev, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t pos,
+ size_t size) {
+ mutex_lock(&hbtp->sensormutex);
+ memcpy(buf, hbtp->ROI, size);
+ mutex_unlock(&hbtp->sensormutex);
+
+ return size;
+}
+
+static ssize_t hbtp_sensor_vib_show(struct file *dev, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t pos,
+ size_t size) {
+ mutex_lock(&hbtp->sensormutex);
+ memcpy(buf, hbtp->accelBuffer, size);
+ mutex_unlock(&hbtp->sensormutex);
+
+ return size;
+}
+
+static struct bin_attribute capdata_attr = {
+ .attr = {
+ .name = "capdata",
+ .mode = S_IRUGO,
+ },
+ .size = 1024,
+ .read = hbtp_sensor_roi_show,
+ .write = NULL,
+};
+
+static struct bin_attribute vibdata_attr = {
+ .attr = {
+ .name = "vib_data",
+ .mode = S_IRUGO,
+ },
+ .size = MAX_ACCEL_SIZE*sizeof(int16_t),
+ .read = hbtp_sensor_vib_show,
+ .write = NULL,
+};
+
static int hbtp_input_open(struct inode *inode, struct file *file)
{
mutex_lock(&hbtp->mutex);
@@ -748,6 +794,22 @@ static long hbtp_input_ioctl_handler(struct file *file, unsigned int cmd,
return -EINVAL;
}
break;
+
+ case HBTP_SET_SENSORDATA:
+ if (copy_from_user(hbtp->sensor_data, (void *)arg,
+ sizeof(struct hbtp_sensor_data))) {
+ pr_err("%s: Error copying data\n", __func__);
+ return -EFAULT;
+ }
+ mutex_lock(&hbtp->sensormutex);
+ memcpy(hbtp->ROI, hbtp->sensor_data->ROI, sizeof(hbtp->ROI));
+ memcpy(hbtp->accelBuffer, hbtp->sensor_data->accelBuffer,
+ sizeof(hbtp->accelBuffer));
+ mutex_unlock(&hbtp->sensormutex);
+
+ error = 0;
+ break;
+
default:
pr_err("%s: Unsupported ioctl command %u\n", __func__, cmd);
error = -EINVAL;
@@ -1358,7 +1420,13 @@ static int __init hbtp_init(void)
if (!hbtp)
return -ENOMEM;
+ hbtp->sensor_data = kzalloc(sizeof(struct hbtp_sensor_data),
+ GFP_KERNEL);
+ if (!hbtp->sensor_data)
+ goto err_sensordata;
+
mutex_init(&hbtp->mutex);
+ mutex_init(&hbtp->sensormutex);
error = misc_register(&hbtp_input_misc);
if (error) {
@@ -1376,6 +1444,28 @@ static int __init hbtp_init(void)
}
#endif
+ sensor_kobject = kobject_create_and_add("hbtpsensor", kernel_kobj);
+ if (!sensor_kobject) {
+ pr_err("%s: Could not create hbtpsensor kobject\n", __func__);
+ goto err_kobject_create;
+ }
+
+ error = sysfs_create_bin_file(sensor_kobject, &capdata_attr);
+ if (error < 0) {
+ pr_err("%s: hbtp capdata sysfs creation failed: %d\n", __func__,
+ error);
+ goto err_sysfs_create_capdata;
+ }
+ pr_debug("capdata sysfs creation success\n");
+
+ error = sysfs_create_bin_file(sensor_kobject, &vibdata_attr);
+ if (error < 0) {
+ pr_err("%s: vibdata sysfs creation failed: %d\n", __func__,
+ error);
+ goto err_sysfs_create_vibdata;
+ }
+ pr_debug("vibdata sysfs creation success\n");
+
error = platform_driver_register(&hbtp_pdev_driver);
if (error) {
pr_err("Failed to register platform driver: %d\n", error);
@@ -1385,12 +1475,20 @@ static int __init hbtp_init(void)
return 0;
err_platform_drv_reg:
+ sysfs_remove_bin_file(sensor_kobject, &vibdata_attr);
+err_sysfs_create_vibdata:
+ sysfs_remove_bin_file(sensor_kobject, &capdata_attr);
+err_sysfs_create_capdata:
+ kobject_put(sensor_kobject);
+err_kobject_create:
#if defined(CONFIG_FB)
fb_unregister_client(&hbtp->fb_notif);
err_fb_reg:
#endif
misc_deregister(&hbtp_input_misc);
err_misc_reg:
+ kfree(hbtp->sensor_data);
+err_sensordata:
kfree(hbtp);
return error;
@@ -1398,6 +1496,9 @@ err_misc_reg:
static void __exit hbtp_exit(void)
{
+ sysfs_remove_bin_file(sensor_kobject, &vibdata_attr);
+ sysfs_remove_bin_file(sensor_kobject, &capdata_attr);
+ kobject_put(sensor_kobject);
misc_deregister(&hbtp_input_misc);
if (hbtp->input_dev)
input_unregister_device(hbtp->input_dev);
@@ -1408,6 +1509,7 @@ static void __exit hbtp_exit(void)
platform_driver_unregister(&hbtp_pdev_driver);
+ kfree(hbtp->sensor_data);
kfree(hbtp);
}