input: sensors: add batch and flush interface for sensor class

Batch interface allow sensor events reported in batches, flush
interface is used to flush sensor FIFO. These two interface can
save device power by reduce the amount of device wakeup.
Sensor class provide generic interfaces for sensor drivers to access
by sensor HAL, drivers using sensors class should register corresponding
sensor class callback to export their interface.

Change-Id: I1307d731793dbc9a6a2b07de3b1de5188d0d8504
Signed-off-by: Bingzhe Cai <bingzhec@codeaurora.org>
This commit is contained in:
Bingzhe Cai 2014-07-14 20:02:06 +08:00
parent 202bfbb2d7
commit 316f76162e
2 changed files with 100 additions and 0 deletions

View File

@ -195,6 +195,95 @@ static ssize_t sensors_test_show(struct device *dev,
ret ? "fail" : "pass");
}
static ssize_t sensors_batch_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
unsigned int enable, mode, period_ms, timeout_ms;
int ret = -EINVAL;
ret = sscanf(buf, "enable=%u, mode=%u, period_ms=%u, timeout_ms=%u",
&enable, &mode, &period_ms, &timeout_ms);
if (ret != 4)
return -EINVAL;
if (enable && (timeout_ms == 0)) {
dev_err(dev,
"Cannot set timeout to zero while enable batch mode\n");
return -EINVAL;
}
if (enable && ((period_ms * 1000) < sensors_cdev->min_delay)) {
dev_err(dev,
"batch: invalid value of delay, delay(ms)=%u\n",
period_ms);
return -EINVAL;
}
if (sensors_cdev->sensors_batch == NULL) {
dev_err(dev, "Invalid sensor class batch handle\n");
return -EINVAL;
}
ret = sensors_cdev->sensors_batch(sensors_cdev,
enable, mode, period_ms, timeout_ms);
if (ret)
return ret;
sensors_cdev->batch_enable = enable;
sensors_cdev->batch_mode = mode;
sensors_cdev->delay_msec = period_ms;
sensors_cdev->batch_timeout_ms = timeout_ms;
return size;
}
static ssize_t sensors_batch_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
return snprintf(buf, PAGE_SIZE,
"enable=%u, mode=%u, period_ms=%u, timeout_ms=%u\n",
sensors_cdev->batch_enable,
sensors_cdev->batch_mode,
sensors_cdev->delay_msec,
sensors_cdev->batch_timeout_ms);
}
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 struct device_attribute sensors_class_attrs[] = {
__ATTR(name, 0444, sensors_name_show, NULL),
__ATTR(vendor, 0444, sensors_vendor_show, NULL),
@ -210,6 +299,8 @@ static struct device_attribute sensors_class_attrs[] = {
__ATTR(enable, 0664, sensors_enable_show, sensors_enable_store),
__ATTR(poll_delay, 0664, sensors_delay_show, sensors_delay_store),
__ATTR(self_test, 0440, sensors_test_show, NULL),
__ATTR(batch, 0660, sensors_batch_show, sensors_batch_store),
__ATTR(flush, 0660, sensors_flush_show, sensors_flush_store),
__ATTR_NULL,
};

View File

@ -90,13 +90,22 @@ struct sensors_classdev {
int fifo_reserved_event_count;
int fifo_max_event_count;
unsigned int enabled;
unsigned int batch_enable;
unsigned int batch_mode;
unsigned int delay_msec;
unsigned int batch_timeout_ms;
/* 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_batch)(struct sensors_classdev *sensor_cdev,
unsigned int enable,
unsigned int mode,
unsigned int period_ms,
unsigned int timeout_ms);
int (*sensors_flush)(struct sensors_classdev *sensors_cdev);
};
extern int sensors_classdev_register(struct device *parent,