iio: hid-sensors: Add API to power on/off
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Fri, 18 Apr 2014 23:22:00 +0000 (00:22 +0100)
committerJonathan Cameron <jic23@kernel.org>
Mon, 5 May 2014 09:59:49 +0000 (10:59 +0100)
Added an API to allow client drivers to turn ON and OFF sensors for
quick read. Added data_read as counting varaible instead of boolean,
so that sensor is powered off only when last user released it.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/accel/hid-sensor-accel-3d.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.h
drivers/iio/gyro/hid-sensor-gyro-3d.c
drivers/iio/light/hid-sensor-als.c
drivers/iio/light/hid-sensor-prox.c
drivers/iio/magnetometer/hid-sensor-magn-3d.c
drivers/iio/orientation/hid-sensor-incl-3d.c
drivers/iio/orientation/hid-sensor-rotation.c
drivers/iio/pressure/hid-sensor-press.c
include/linux/hid-sensor-hub.h

index ca50a91752d8b0ef30fda743bb0496068e770d80..cf61c87a47e96246b80deef93a7ade77f3d13b9d 100644 (file)
@@ -201,9 +201,8 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct accel_3d_state *accel_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "accel_3d_proc_event [%d]\n",
-                               accel_state->common_attributes.data_ready);
-       if (accel_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "accel_3d_proc_event\n");
+       if (atomic_read(&accel_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                accel_state->accel_val,
                                sizeof(accel_state->accel_val));
@@ -342,7 +341,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       accel_state->common_attributes.data_ready = false;
+       atomic_set(&accel_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                        &accel_state->common_attributes);
        if (ret < 0) {
index dbefbdaf7cd10b4c25f31f33a63b7d6b37d58c03..73282cee0c81f1c025c31e2e060ae83d5aecd3ac 100644 (file)
 #include <linux/iio/sysfs.h>
 #include "hid-sensor-trigger.h"
 
-static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
-                                               bool state)
+int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 {
-       struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
        int state_val;
        int report_val;
 
        if (state) {
                if (sensor_hub_device_open(st->hsdev))
                        return -EIO;
+
+               atomic_inc(&st->data_ready);
+
                state_val = hid_sensor_get_usage_index(st->hsdev,
                        st->power_state.report_id,
                        st->power_state.index,
@@ -47,6 +48,8 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
                        st->report_state.index,
                        HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
        } else {
+               if (!atomic_dec_and_test(&st->data_ready))
+                       return 0;
                sensor_hub_device_close(st->hsdev);
                state_val = hid_sensor_get_usage_index(st->hsdev,
                        st->power_state.report_id,
@@ -57,7 +60,6 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
                        st->report_state.index,
                        HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM);
        }
-       st->data_ready = state;
 
        if (state_val >= 0) {
                state_val += st->power_state.logical_minimum;
@@ -75,6 +77,13 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
 
        return 0;
 }
+EXPORT_SYMBOL(hid_sensor_power_state);
+
+static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
+                                               bool state)
+{
+       return hid_sensor_power_state(iio_trigger_get_drvdata(trig), state);
+}
 
 void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
 {
index ca02f7811aa8c6f6a44dc8a955a064dfa1e07219..0f8e78c249d35823965293aeb4f496ee8612f503 100644 (file)
@@ -22,5 +22,6 @@
 int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
                                struct hid_sensor_common *attrb);
 void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
+int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
 
 #endif
index 53ac06040fbe355c247940be6370338d10b55cb9..392c30b8cd74e587b17c41edef56efadac97250e 100644 (file)
@@ -201,9 +201,8 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "gyro_3d_proc_event [%d]\n",
-                               gyro_state->common_attributes.data_ready);
-       if (gyro_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "gyro_3d_proc_event\n");
+       if (atomic_read(&gyro_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                gyro_state->gyro_val,
                                sizeof(gyro_state->gyro_val));
@@ -339,7 +338,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       gyro_state->common_attributes.data_ready = false;
+       atomic_set(&gyro_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                        &gyro_state->common_attributes);
        if (ret < 0) {
index 39b50be9d456d7897f725b96f3db04958af25069..e124b395f320705a53ed524ce4fe1ec21a2c48eb 100644 (file)
@@ -180,9 +180,8 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct als_state *als_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "als_proc_event [%d]\n",
-                               als_state->common_attributes.data_ready);
-       if (als_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "als_proc_event\n");
+       if (atomic_read(&als_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                &als_state->illum,
                                sizeof(als_state->illum));
@@ -305,7 +304,7 @@ static int hid_als_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       als_state->common_attributes.data_ready = false;
+       atomic_set(&als_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                &als_state->common_attributes);
        if (ret < 0) {
index 1894ab196f97dd83656ec993a5ca63a5151d7afb..07e98ec8e9f1c1d5ec040f940583e826e99f6628 100644 (file)
@@ -176,9 +176,8 @@ static int prox_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct prox_state *prox_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "prox_proc_event [%d]\n",
-                               prox_state->common_attributes.data_ready);
-       if (prox_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "prox_proc_event\n");
+       if (atomic_read(&prox_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                &prox_state->human_presence,
                                sizeof(prox_state->human_presence));
@@ -297,7 +296,7 @@ static int hid_prox_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       prox_state->common_attributes.data_ready = false;
+       atomic_set(&prox_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                &prox_state->common_attributes);
        if (ret) {
index 131ced0dcb1cfdb5a15cb3df509ed56e354d6994..54eea6a170616224d9258a217184499eec0c5573 100644 (file)
@@ -202,9 +202,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct magn_3d_state *magn_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "magn_3d_proc_event [%d]\n",
-                               magn_state->common_attributes.data_ready);
-       if (magn_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "magn_3d_proc_event\n");
+       if (atomic_read(&magn_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                magn_state->magn_val,
                                sizeof(magn_state->magn_val));
@@ -343,7 +342,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       magn_state->common_attributes.data_ready = false;
+       atomic_set(&magn_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                        &magn_state->common_attributes);
        if (ret < 0) {
index f0c465cc192a779d6ee9a752c4ff26dfd5dec9f1..bf11678dd04e393028389e9fc13a696bc6ad7f9e 100644 (file)
@@ -200,9 +200,8 @@ static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct incl_3d_state *incl_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "incl_3d_proc_event [%d]\n",
-                               incl_state->common_attributes.data_ready);
-       if (incl_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "incl_3d_proc_event\n");
+       if (atomic_read(&incl_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                (u8 *)incl_state->incl_val,
                                sizeof(incl_state->incl_val));
@@ -358,7 +357,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       incl_state->common_attributes.data_ready = false;
+       atomic_set(&incl_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                        &incl_state->common_attributes);
        if (ret) {
index 51387bbc1ce11877368acc88df3be54076dc47da..dccf848e8b0fdd7a1f8ff6bca06e40fdafe587f5 100644 (file)
@@ -145,10 +145,8 @@ static int dev_rot_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct dev_rot_state *rot_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "dev_rot_proc_event [%d]\n",
-                               rot_state->common_attributes.data_ready);
-
-       if (rot_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "dev_rot_proc_event\n");
+       if (atomic_read(&rot_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                (u8 *)rot_state->sampled_vals,
                                sizeof(rot_state->sampled_vals));
@@ -272,7 +270,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                return ret;
        }
-       rot_state->common_attributes.data_ready = false;
+       atomic_set(&rot_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                        &rot_state->common_attributes);
        if (ret) {
index ff69da4443b83df5b0c8f0cd121b403f95de5349..39df50c45dab64510bbfab247f8f96268633788c 100644 (file)
@@ -180,9 +180,8 @@ static int press_proc_event(struct hid_sensor_hub_device *hsdev,
        struct iio_dev *indio_dev = platform_get_drvdata(priv);
        struct press_state *press_state = iio_priv(indio_dev);
 
-       dev_dbg(&indio_dev->dev, "press_proc_event [%d]\n",
-                               press_state->common_attributes.data_ready);
-       if (press_state->common_attributes.data_ready)
+       dev_dbg(&indio_dev->dev, "press_proc_event\n");
+       if (atomic_read(&press_state->common_attributes.data_ready))
                hid_sensor_push_data(indio_dev,
                                &press_state->press_data,
                                sizeof(press_state->press_data));
@@ -307,7 +306,7 @@ static int hid_press_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
                goto error_free_dev_mem;
        }
-       press_state->common_attributes.data_ready = false;
+       atomic_set(&press_state->common_attributes.data_ready, 0);
        ret = hid_sensor_setup_trigger(indio_dev, name,
                                &press_state->common_attributes);
        if (ret) {
index 88d8d636a68f6e4e0bac29fd3d1e5087349183cb..51f7ccadf923c337ddb5627491a958c5e74fa610 100644 (file)
@@ -189,7 +189,7 @@ struct hid_sensor_common {
        struct hid_sensor_hub_device *hsdev;
        struct platform_device *pdev;
        unsigned usage_id;
-       bool data_ready;
+       atomic_t data_ready;
        struct iio_trigger *trigger;
        struct hid_sensor_hub_attribute_info poll;
        struct hid_sensor_hub_attribute_info report_state;