From: hq_guohongtao5_tmp Date: Tue, 28 Aug 2018 06:07:22 +0000 (+0800) Subject: (CR):[kane]:kernel: add sensor class drivers X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c45e7d14de0996f9b55a7c9758871534dabd92e0;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git (CR):[kane]:kernel: add sensor class drivers add sensor class drivers for sar Change-Id: I7709ed9d502bdb09324b658ea8f167e6abad7e57 Signed-off-by: hq_guohongtao5_tmp --- diff --git a/drivers/Kconfig b/drivers/Kconfig old mode 100644 new mode 100755 index a56a1405a62e..1c4575fdf8c1 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -220,4 +220,6 @@ source "drivers/ccic/Kconfig" source "drivers/vision/Kconfig" +source "drivers/sensors/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile old mode 100644 new mode 100755 index e0d2af38bc99..03848841b933 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -199,3 +199,4 @@ obj-$(CONFIG_USBPD_CORE) += ccic/ obj-$(CONFIG_VISION_SUPPORT) += vision/ obj-$(CONFIG_USE_CCIC) += ccic/ +obj-$(CONFIG_SENSORS_CLASS) += sensors/ \ No newline at end of file diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig new file mode 100755 index 000000000000..496f7b5afb06 --- /dev/null +++ b/drivers/sensors/Kconfig @@ -0,0 +1,5 @@ +config SENSORS_CLASS + bool "Sensors Class Support" + help + This option enables the sensor sysfs class in /sys/class/sensors. + You'll need this to do anything useful with sensors. If unsure, say N. diff --git a/drivers/sensors/Makefile b/drivers/sensors/Makefile new file mode 100755 index 000000000000..fdbcb1362e04 --- /dev/null +++ b/drivers/sensors/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SENSORS_CLASS) += sensors_class.o diff --git a/drivers/sensors/sensors_class.c b/drivers/sensors/sensors_class.c new file mode 100755 index 000000000000..4e31ec6eb061 --- /dev/null +++ b/drivers/sensors/sensors_class.c @@ -0,0 +1,575 @@ +/* Copyright (c) 2013-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APPLY_MASK 0x00000001 + +#define CMD_W_L_MASK 0x00 +#define CMD_W_H_MASK 0x10 +#define CMD_W_H_L 0x10 +#define CMD_MASK 0xF +#define DATA_MASK 0xFFFF0000 +#define DATA_AXIS_SHIFT 17 +#define DATA_APPLY_SHIFT 16 +/* + * CMD_GET_PARAMS(BIT, PARA, DATA) combine high 16 bit and low 16 bit + * as one params + */ + +#define CMD_GET_PARAMS(BIT, PARA, DATA) \ + ((BIT) ? \ + ((DATA) & DATA_MASK) \ + : ((PARA) \ + | (((DATA) & DATA_MASK) >> 16))) + + +/* + * CMD_DO_CAL sensor do calibrate command, when do sensor calibrate must use + * this. + * AXIS_X,AXIS_Y,AXIS_Z write axis params to driver like accelerometer + * magnetometer,gyroscope etc. + * CMD_W_THRESHOLD_H,CMD_W_THRESHOLD_L,CMD_W_BIAS write theshold and bias + * params to proximity driver. + * CMD_W_FACTOR,CMD_W_OFFSET write factor and offset params to light + * sensor driver. + * CMD_COMPLETE when one sensor receive calibrate parameters complete, it + * must use this command to end receive the parameters and send the + * parameters to sensor. + */ + +enum { + CMD_DO_CAL = 0x0, + CMD_W_OFFSET_X, + CMD_W_OFFSET_Y, + CMD_W_OFFSET_Z, + CMD_W_THRESHOLD_H, + CMD_W_THRESHOLD_L, + CMD_W_BIAS, + CMD_W_OFFSET, + CMD_W_FACTOR, + CMD_W_RANGE, + CMD_COMPLETE, + CMD_COUNT +}; + +int cal_map[] = { + 0, + offsetof(struct cal_result_t, offset_x), + offsetof(struct cal_result_t, offset_y), + offsetof(struct cal_result_t, offset_z), + offsetof(struct cal_result_t, threshold_h), + offsetof(struct cal_result_t, threshold_l), + offsetof(struct cal_result_t, bias), + offsetof(struct cal_result_t, offset[0]), + offsetof(struct cal_result_t, offset[1]), + offsetof(struct cal_result_t, offset[2]), + offsetof(struct cal_result_t, factor), + offsetof(struct cal_result_t, range), +}; + +static struct class *sensors_class; + +DECLARE_RWSEM(sensors_list_lock); +LIST_HEAD(sensors_list); + +static ssize_t sensors_name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->name); +} + +static ssize_t sensors_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->vendor); +} + +static ssize_t sensors_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->version); +} + +static ssize_t sensors_handle_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->handle); +} + +static ssize_t sensors_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->type); +} + +static ssize_t sensors_max_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->max_delay); +} + +static ssize_t sensors_flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->flags); +} + +static ssize_t sensors_max_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->max_range); +} + +static ssize_t sensors_resolution_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->resolution); +} + +static ssize_t sensors_power_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->sensor_power); +} + +static ssize_t sensors_min_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->min_delay); +} + +static ssize_t sensors_fifo_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + sensors_cdev->fifo_reserved_event_count); +} + +static ssize_t sensors_fifo_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + sensors_cdev->fifo_max_event_count); +} + +static ssize_t sensors_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + ssize_t ret = -EINVAL; + unsigned long data = 0; + + ret = kstrtoul(buf, 10, &data); + if (ret) + return ret; + if (data > 1) { + dev_err(dev, "Invalid value of input, input=%ld\n", data); + return -EINVAL; + } + + if (sensors_cdev->sensors_enable == NULL) { + dev_err(dev, "Invalid sensor class enable handle\n"); + return -EINVAL; + } + ret = sensors_cdev->sensors_enable(sensors_cdev, data); + if (ret) + return ret; + + sensors_cdev->enabled = data; + return size; +} + + +static ssize_t sensors_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + sensors_cdev->enabled); +} + +static ssize_t sensors_delay_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + ssize_t ret = -EINVAL; + unsigned long data = 0; + + ret = kstrtoul(buf, 10, &data); + if (ret) + return ret; + /* The data unit is millisecond, the min_delay unit is microseconds. */ + if ((data * 1000) < sensors_cdev->min_delay) { + dev_err(dev, "Invalid value of delay, delay=%ld\n", data); + return -EINVAL; + } + if (sensors_cdev->sensors_poll_delay == NULL) { + dev_err(dev, "Invalid sensor class delay handle\n"); + return -EINVAL; + } + ret = sensors_cdev->sensors_poll_delay(sensors_cdev, data); + if (ret) + return ret; + + sensors_cdev->delay_msec = data; + return size; +} + +static ssize_t sensors_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + sensors_cdev->delay_msec); +} + +static ssize_t sensors_test_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + int ret; + + if (sensors_cdev->sensors_self_test == NULL) { + dev_err(dev, "Invalid sensor class self test handle\n"); + return -EINVAL; + } + + ret = sensors_cdev->sensors_self_test(sensors_cdev); + if (ret) + dev_warn(dev, "self test failed.(%d)\n", ret); + + return snprintf(buf, PAGE_SIZE, "%s\n", + ret ? "fail" : "pass"); +} + +static ssize_t sensors_max_latency_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + unsigned long latency; + int ret = -EINVAL; + + ret = kstrtoul(buf, 10, &latency); + if (ret) + return ret; + + if (latency > sensors_cdev->max_delay) { + dev_err(dev, "max_latency(%lu) is greater than max_delay(%u)\n", + latency, sensors_cdev->max_delay); + return -EINVAL; + } + + if (sensors_cdev->sensors_set_latency == NULL) { + dev_err(dev, "Invalid sensor calss set latency handle\n"); + return -EINVAL; + } + + /* Disable batching for this sensor */ + if ((latency < sensors_cdev->delay_msec) && (latency != 0)) { + dev_err(dev, "max_latency is less than delay_msec\n"); + return -EINVAL; + } + + ret = sensors_cdev->sensors_set_latency(sensors_cdev, latency); + if (ret) + return ret; + + sensors_cdev->max_latency = latency; + + return size; +} + +static ssize_t sensors_max_latency_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, + "%u\n", sensors_cdev->max_latency); +} + +static ssize_t sensors_flush_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + ssize_t ret = -EINVAL; + unsigned long data = 0; + + ret = kstrtoul(buf, 10, &data); + if (ret) + return ret; + if (data != 1) { + dev_err(dev, "Flush: Invalid value of input, input=%ld\n", + data); + return -EINVAL; + } + + if (sensors_cdev->sensors_flush == NULL) { + dev_err(dev, "Invalid sensor class flush handle\n"); + return -EINVAL; + } + ret = sensors_cdev->sensors_flush(sensors_cdev); + if (ret) + return ret; + + return size; +} + +static ssize_t sensors_flush_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, + "Flush handler %s\n", + (sensors_cdev->sensors_flush == NULL) + ? "not exist" : "exist"); +} + +static ssize_t sensors_enable_wakeup_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + ssize_t ret; + unsigned long enable; + + if (sensors_cdev->sensors_enable_wakeup == NULL) { + dev_err(dev, "Invalid sensor class enable_wakeup handle\n"); + return -EINVAL; + } + + ret = kstrtoul(buf, 10, &enable); + if (ret) + return ret; + + enable = enable ? 1 : 0; + ret = sensors_cdev->sensors_enable_wakeup(sensors_cdev, enable); + if (ret) + return ret; + + sensors_cdev->wakeup = enable; + + return size; +} + +static ssize_t sensors_enable_wakeup_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->wakeup); +} + + +static ssize_t sensors_calibrate_show(struct device *dev, + struct device_attribute *atte, char *buf) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + + if (sensors_cdev->params == NULL) { + dev_err(dev, "Invalid sensor params\n"); + return -EINVAL; + } + return snprintf(buf, PAGE_SIZE, "%s\n", sensors_cdev->params); +} + +static ssize_t sensors_calibrate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev); + ssize_t ret = -EINVAL; + long data; + int axis, apply_now; + int cmd, bit_h; + + ret = kstrtol(buf, 0, &data); + if (ret) + return ret; + dev_dbg(dev, "data = %lx\n", data); + cmd = data & CMD_MASK; + if (cmd == CMD_DO_CAL) { + if (sensors_cdev->sensors_calibrate == NULL) { + dev_err(dev, "Invalid calibrate handle\n"); + return -EINVAL; + } + /* parse the data to get the axis and apply_now value*/ + apply_now = (int)(data >> DATA_APPLY_SHIFT) & APPLY_MASK; + axis = (int)data >> DATA_AXIS_SHIFT; + dev_dbg(dev, "apply_now = %d, axis = %d\n", apply_now, axis); + ret = sensors_cdev->sensors_calibrate(sensors_cdev, + axis, apply_now); + if (ret) + return ret; + } else { + if (sensors_cdev->sensors_write_cal_params == NULL) { + dev_err(dev, + "Invalid write_cal_params handle\n"); + return -EINVAL; + } + bit_h = (data & CMD_W_H_L) >> 4; + if (cmd > CMD_DO_CAL && cmd < CMD_COMPLETE) { + char *p = (char *)(&sensors_cdev->cal_result) + + cal_map[cmd]; + *(int *)p = CMD_GET_PARAMS(bit_h, *(int *)p, data); + } else if (cmd == CMD_COMPLETE) { + ret = sensors_cdev->sensors_write_cal_params + (sensors_cdev, &sensors_cdev->cal_result); + } else { + dev_err(dev, "Invalid command\n"); + return -EINVAL; + } + } + return size; +} + +static DEVICE_ATTR(name, 0444, sensors_name_show, NULL); +static DEVICE_ATTR(vendor, 0444, sensors_vendor_show, NULL); +static DEVICE_ATTR(version, 0444, sensors_version_show, NULL); +static DEVICE_ATTR(handle, 0444, sensors_handle_show, NULL); +static DEVICE_ATTR(type, 0444, sensors_type_show, NULL); +static DEVICE_ATTR(max_range, 0444, sensors_max_range_show, NULL); +static DEVICE_ATTR(resolution, 0444, sensors_resolution_show, NULL); +static DEVICE_ATTR(sensor_power, 0444, sensors_power_show, NULL); +static DEVICE_ATTR(min_delay, 0444, sensors_min_delay_show, NULL); +static DEVICE_ATTR(fifo_reserved_event_count, 0444, sensors_fifo_event_show, + NULL); +static DEVICE_ATTR(fifo_max_event_count, 0444, sensors_fifo_max_show, NULL); +static DEVICE_ATTR(max_delay, 0444, sensors_max_delay_show, NULL); +static DEVICE_ATTR(flags, 0444, sensors_flags_show, NULL); +static DEVICE_ATTR(enable, 0664, sensors_enable_show, sensors_enable_store); +static DEVICE_ATTR(enable_wakeup, 0664, sensors_enable_wakeup_show, + sensors_enable_wakeup_store); +static DEVICE_ATTR(poll_delay, 0664, sensors_delay_show, sensors_delay_store); +static DEVICE_ATTR(self_test, 0440, sensors_test_show, NULL); +static DEVICE_ATTR(max_latency, 0660, sensors_max_latency_show, + sensors_max_latency_store); +static DEVICE_ATTR(flush, 0660, sensors_flush_show, sensors_flush_store); +static DEVICE_ATTR(calibrate, 0664, sensors_calibrate_show, + sensors_calibrate_store); + +static struct attribute *sensors_class_attrs[] = { + &dev_attr_name.attr, + &dev_attr_vendor.attr, + &dev_attr_version.attr, + &dev_attr_handle.attr, + &dev_attr_type.attr, + &dev_attr_max_range.attr, + &dev_attr_resolution.attr, + &dev_attr_sensor_power.attr, + &dev_attr_min_delay.attr, + &dev_attr_fifo_reserved_event_count.attr, + &dev_attr_fifo_max_event_count.attr, + &dev_attr_max_delay.attr, + &dev_attr_flags.attr, + &dev_attr_enable.attr, + &dev_attr_enable_wakeup.attr, + &dev_attr_poll_delay.attr, + &dev_attr_self_test.attr, + &dev_attr_max_latency.attr, + &dev_attr_flush.attr, + &dev_attr_calibrate.attr, + NULL, +}; +ATTRIBUTE_GROUPS(sensors_class); + +/** + * sensors_classdev_register - register a new object of sensors_classdev class. + * @parent: The device to register. + * @sensors_cdev: the sensors_classdev structure for this device. +*/ +int sensors_classdev_register(struct device *parent, + struct sensors_classdev *sensors_cdev) +{ + sensors_cdev->dev = device_create(sensors_class, parent, 0, + sensors_cdev, "%s", sensors_cdev->name); + if (IS_ERR(sensors_cdev->dev)) + return PTR_ERR(sensors_cdev->dev); + + down_write(&sensors_list_lock); + list_add_tail(&sensors_cdev->node, &sensors_list); + up_write(&sensors_list_lock); + + pr_debug("Registered sensors device: %s\n", + sensors_cdev->name); + return 0; +} +EXPORT_SYMBOL(sensors_classdev_register); + +/** + * sensors_classdev_unregister - unregister a object of sensors class. + * @sensors_cdev: the sensor device to unregister + * Unregister a previously registered via sensors_classdev_register object. +*/ +void sensors_classdev_unregister(struct sensors_classdev *sensors_cdev) +{ + device_unregister(sensors_cdev->dev); + down_write(&sensors_list_lock); + list_del(&sensors_cdev->node); + up_write(&sensors_list_lock); +} +EXPORT_SYMBOL(sensors_classdev_unregister); + +static int __init sensors_init(void) +{ + sensors_class = class_create(THIS_MODULE, "sensors"); + if (IS_ERR(sensors_class)) + return PTR_ERR(sensors_class); + sensors_class->dev_groups = sensors_class_groups; + return 0; +} + +static void __exit sensors_exit(void) +{ + class_destroy(sensors_class); +} + +subsys_initcall(sensors_init); +module_exit(sensors_exit); diff --git a/include/linux/sensors.h b/include/linux/sensors.h new file mode 100755 index 000000000000..c20e876efe12 --- /dev/null +++ b/include/linux/sensors.h @@ -0,0 +1,173 @@ +/* Copyright (c) 2013-2014, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_SENSORS_H_INCLUDED +#define __LINUX_SENSORS_H_INCLUDED + +#include +#include +#include + +#define SENSORS_ACCELERATION_HANDLE 0 +#define SENSORS_MAGNETIC_FIELD_HANDLE 1 +#define SENSORS_ORIENTATION_HANDLE 2 +#define SENSORS_LIGHT_HANDLE 3 +#define SENSORS_PROXIMITY_HANDLE 4 +#define SENSORS_GYROSCOPE_HANDLE 5 +#define SENSORS_PRESSURE_HANDLE 6 +#define SENSORS_CAP_PROX_PRIMARY_HANDLE 101 +#define SENSORS_CAP_PROX_SECONDARY_HANDLE 102 + +#define SENSOR_TYPE_ACCELEROMETER 1 +#define SENSOR_TYPE_GEOMAGNETIC_FIELD 2 +#define SENSOR_TYPE_MAGNETIC_FIELD SENSOR_TYPE_GEOMAGNETIC_FIELD +#define SENSOR_TYPE_ORIENTATION 3 +#define SENSOR_TYPE_GYROSCOPE 4 +#define SENSOR_TYPE_LIGHT 5 +#define SENSOR_TYPE_PRESSURE 6 +#define SENSOR_TYPE_TEMPERATURE 7 +#define SENSOR_TYPE_PROXIMITY 8 +#define SENSOR_TYPE_GRAVITY 9 +#define SENSOR_TYPE_LINEAR_ACCELERATION 10 +#define SENSOR_TYPE_ROTATION_VECTOR 11 +#define SENSOR_TYPE_RELATIVE_HUMIDITY 12 +#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13 +#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED 14 +#define SENSOR_TYPE_GAME_ROTATION_VECTOR 15 +#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED 16 +#define SENSOR_TYPE_SIGNIFICANT_MOTION 17 +#define SENSOR_TYPE_STEP_DETECTOR 18 +#define SENSOR_TYPE_STEP_COUNTER 19 +#define SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR 20 + +#define SENSOR_TYPE_DEVICE_PRIVATE_BASE 0x10000 +#define SENSOR_TYPE_CAP_PROX (SENSOR_TYPE_DEVICE_PRIVATE_BASE + 2) + +enum LIS3DH_AXIS { + AXIS_X = 0, + AXIS_Y, + AXIS_Z, + AXIS_XYZ, +}; + +enum LIS3DH_THRES { + AXIS_THRESHOLD_H = 0, + AXIS_THRESHOLD_L, + AXIS_BIAS, +}; + +#define AXIS_FACTOR 0 +#define AXIS_OFFSET 1 + + +struct cal_result_t { + union { + + struct { + int offset_x; /*axis offset of x axis*/ + int offset_y; /*axis offset of x axis*/ + int offset_z; /*axis offset of x axis*/ + }; + struct { + int threshold_h; /*proximity threshold_h*/ + int threshold_l; /*proximity threshold_l*/ + int bias; /*proximity measure data noise*/ + }; + int offset[3]; + }; + int factor; /*light sensor factor for real ligt strength*/ + int range; + struct cal_result_t *node; +}; + +/** + * struct sensors_classdev - hold the sensor general parameters and APIs + * @dev: The device to register. + * @node: The list for the all the sensor drivers. + * @name: Name of this sensor. + * @vendor: The vendor of the hardware part. + * @handle: The handle that identifies this sensors. + * @type: The sensor type. + * @max_range: The maximum range of this sensor's value in SI units. + * @resolution: The smallest difference between two values reported by + * this sensor. + * @sensor_power: The rough estimate of this sensor's power consumption + * in mA. + * @min_delay: This value depends on the trigger mode: + * continuous: minimum period allowed in microseconds + * on-change : 0 + * one-shot :-1 + * special : 0, unless otherwise noted + * @fifo_reserved_event_count: The number of events reserved for this sensor + * in the batch mode FIFO. + * @fifo_max_event_count: The maximum number of events of this sensor + * that could be batched. + * @max_delay: The slowest rate the sensor supports in millisecond. + * @flags: Should be '1' if the sensor is a wake up sensor. + * set it to '0' otherwise. + * @enabled: Store the sensor driver enable status. + * @delay_msec: Store the sensor driver delay value. The data unit is + * millisecond. + * @wakeup: Indicate if the wake up interrupt has been enabled. + * @max_latency: Max report latency in millisecond + * @sensors_enable: The handle for enable and disable sensor. + * @sensors_poll_delay: The handle for set the sensor polling delay time. + * @sensors_set_latency:Set the max report latency of the sensor. + * @sensors_flush: Flush sensor events in FIFO and report it to user space. + * @params The sensor calibrate string format params up to userspace. + * @cal_result The sensor calibrate parameters, cal_result is a struct for sensor. + */ +struct sensors_classdev { + struct device *dev; + struct list_head node; + const char *name; + const char *vendor; + int version; + int handle; + int type; + const char *max_range; + const char *resolution; + const char *sensor_power; + int min_delay; + int fifo_reserved_event_count; + int fifo_max_event_count; + int32_t max_delay; + uint32_t flags; + + unsigned int enabled; + unsigned int delay_msec; + unsigned int wakeup; + unsigned int max_latency; + char *params; + struct cal_result_t cal_result; + /* enable and disable the sensor handle*/ + int (*sensors_enable)(struct sensors_classdev *sensors_cdev, + unsigned int enabled); + int (*sensors_poll_delay)(struct sensors_classdev *sensors_cdev, + unsigned int delay_msec); + int (*sensors_self_test)(struct sensors_classdev *sensors_cdev); + int (*sensors_set_latency)(struct sensors_classdev *sensor_cdev, + unsigned int max_latency); + int (*sensors_enable_wakeup)(struct sensors_classdev *sensor_cdev, + unsigned int enable); + int (*sensors_flush)(struct sensors_classdev *sensors_cdev); + int (*sensors_calibrate)(struct sensors_classdev *sensor_cdev, + int axis, int apply_now); + int (*sensors_write_cal_params)(struct sensors_classdev + *sensor_cdev, struct cal_result_t *cal_result); +}; + +extern int sensors_classdev_register(struct device *parent, + struct sensors_classdev *sensors_cdev); +extern void sensors_classdev_unregister(struct sensors_classdev *sensors_cdev); + +#endif /* __LINUX_SENSORS_H_INCLUDED */