Loading drivers/input/misc/hbtp_input.c +103 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -1408,6 +1509,7 @@ static void __exit hbtp_exit(void) platform_driver_unregister(&hbtp_pdev_driver); kfree(hbtp->sensor_data); kfree(hbtp); } Loading include/uapi/linux/hbtp_input.h +9 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,8 @@ #define HBTP_MAX_FINGER 20 #define HBTP_ABS_MT_FIRST ABS_MT_TOUCH_MAJOR #define HBTP_ABS_MT_LAST ABS_MT_TOOL_Y #define MAX_ROI_SIZE 144 #define MAX_ACCEL_SIZE 128 #define HBTP_EVENT_TYPE_DISPLAY "EVENT_TYPE=HBTP_DISPLAY" Loading @@ -20,6 +22,11 @@ struct hbtp_input_touch { __s32 orientation; }; struct hbtp_sensor_data { __s16 accelBuffer[MAX_ACCEL_SIZE]; __s16 ROI[MAX_ROI_SIZE]; }; struct hbtp_input_mt { __s32 num_touches; struct hbtp_input_touch touches[HBTP_MAX_FINGER]; Loading Loading @@ -68,6 +75,8 @@ enum hbtp_afe_power_ctrl { enum hbtp_afe_signal) #define HBTP_SET_POWER_CTRL _IOW(HBTP_INPUT_IOCTL_BASE, 206, \ enum hbtp_afe_power_ctrl) #define HBTP_SET_SENSORDATA _IOW(HBTP_INPUT_IOCTL_BASE, 207, \ struct hbtp_sensor_data) #endif /* _UAPI_HBTP_INPUT_H */ Loading
drivers/input/misc/hbtp_input.c +103 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -1408,6 +1509,7 @@ static void __exit hbtp_exit(void) platform_driver_unregister(&hbtp_pdev_driver); kfree(hbtp->sensor_data); kfree(hbtp); } Loading
include/uapi/linux/hbtp_input.h +9 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,8 @@ #define HBTP_MAX_FINGER 20 #define HBTP_ABS_MT_FIRST ABS_MT_TOUCH_MAJOR #define HBTP_ABS_MT_LAST ABS_MT_TOOL_Y #define MAX_ROI_SIZE 144 #define MAX_ACCEL_SIZE 128 #define HBTP_EVENT_TYPE_DISPLAY "EVENT_TYPE=HBTP_DISPLAY" Loading @@ -20,6 +22,11 @@ struct hbtp_input_touch { __s32 orientation; }; struct hbtp_sensor_data { __s16 accelBuffer[MAX_ACCEL_SIZE]; __s16 ROI[MAX_ROI_SIZE]; }; struct hbtp_input_mt { __s32 num_touches; struct hbtp_input_touch touches[HBTP_MAX_FINGER]; Loading Loading @@ -68,6 +75,8 @@ enum hbtp_afe_power_ctrl { enum hbtp_afe_signal) #define HBTP_SET_POWER_CTRL _IOW(HBTP_INPUT_IOCTL_BASE, 206, \ enum hbtp_afe_power_ctrl) #define HBTP_SET_SENSORDATA _IOW(HBTP_INPUT_IOCTL_BASE, 207, \ struct hbtp_sensor_data) #endif /* _UAPI_HBTP_INPUT_H */