Each sample has a timestamp field with this change. This timestamp may
be from the sensor hub when present or local kernel timestamp. And the
unit of timestamp is nanosecond.

Signed-off-by: Ye Xiang <xiang...@intel.com>
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 48 ++++++++++++-------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c 
b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index cacbd053b2c6..b79c8a5a98f9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -24,6 +24,7 @@ enum magn_3d_channel {
        CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
        CHANNEL_SCAN_INDEX_NORTH_MAGN,
        CHANNEL_SCAN_INDEX_NORTH_TRUE,
+       CHANNEL_SCAN_INDEX_TIMESTAMP,
        MAGN_3D_CHANNEL_MAX,
 };
 
@@ -47,6 +48,7 @@ struct magn_3d_state {
 
        struct common_attributes magn_flux_attr;
        struct common_attributes rot_attr;
+       s64 timestamp;
 };
 
 static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
@@ -57,6 +59,7 @@ static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
        HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
        HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
        HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
+       HID_USAGE_SENSOR_TIME_TIMESTAMP,
 };
 
 static const u32 magn_3d_sensitivity_addresses[] = {
@@ -132,7 +135,8 @@ static const struct iio_chan_spec magn_3d_channels[] = {
                BIT(IIO_CHAN_INFO_SCALE) |
                BIT(IIO_CHAN_INFO_SAMP_FREQ) |
                BIT(IIO_CHAN_INFO_HYSTERESIS),
-       }
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(7)
 };
 
 /* Adjust channel real bits based on report descriptor */
@@ -281,13 +285,6 @@ static const struct iio_info magn_3d_info = {
        .write_raw = &magn_3d_write_raw,
 };
 
-/* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data)
-{
-       dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, data);
-}
-
 /* Callback handler to send event after all samples are received and captured 
*/
 static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                unsigned usage_id,
@@ -297,8 +294,15 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device 
*hsdev,
        struct magn_3d_state *magn_state = iio_priv(indio_dev);
 
        dev_dbg(&indio_dev->dev, "magn_3d_proc_event\n");
-       if (atomic_read(&magn_state->magn_flux_attributes.data_ready))
-               hid_sensor_push_data(indio_dev, magn_state->iio_vals);
+       if (atomic_read(&magn_state->magn_flux_attributes.data_ready)) {
+               if (!magn_state->timestamp)
+                       magn_state->timestamp = iio_get_time_ns(indio_dev);
+
+               iio_push_to_buffers_with_timestamp(indio_dev,
+                                                  magn_state->iio_vals,
+                                                  magn_state->timestamp);
+               magn_state->timestamp = 0;
+       }
 
        return 0;
 }
@@ -329,6 +333,11 @@ static int magn_3d_capture_sample(struct 
hid_sensor_hub_device *hsdev,
                offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
                                + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
        break;
+       case HID_USAGE_SENSOR_TIME_TIMESTAMP:
+               magn_state->timestamp =
+                       
hid_sensor_convert_timestamp(&magn_state->magn_flux_attributes,
+                                                    *(s64 *)raw_data);
+               return ret;
        default:
                return -EINVAL;
        }
@@ -394,9 +403,10 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
                return -ENOMEM;
        }
 
-       st->iio_vals = devm_kcalloc(&pdev->dev, attr_count,
-                               sizeof(u32),
-                               GFP_KERNEL);
+       /* attr_count include timestamp channel, and the iio_vals should be 
aligned to 8byte */
+       st->iio_vals = devm_kcalloc(&pdev->dev,
+                                   ((attr_count + 1) % 2 + (attr_count + 1) / 
2) * 2,
+                                   sizeof(u32), GFP_KERNEL);
        if (!st->iio_vals) {
                dev_err(&pdev->dev,
                        "failed to allocate space for iio values array\n");
@@ -412,11 +422,13 @@ static int magn_3d_parse_report(struct platform_device 
*pdev,
                        (_channels[*chan_count]).scan_index = *chan_count;
                        (_channels[*chan_count]).address = i;
 
-                       /* Set magn_val_addr to iio value address */
-                       st->magn_val_addr[i] = &(st->iio_vals[*chan_count]);
-                       magn_3d_adjust_channel_bit_mask(_channels,
-                                                       *chan_count,
-                                                       st->magn[i].size);
+                       if (i != CHANNEL_SCAN_INDEX_TIMESTAMP) {
+                               /* Set magn_val_addr to iio value address */
+                               st->magn_val_addr[i] = 
&st->iio_vals[*chan_count];
+                               magn_3d_adjust_channel_bit_mask(_channels,
+                                                               *chan_count,
+                                                               
st->magn[i].size);
+                       }
                        (*chan_count)++;
                }
        }
-- 
2.17.1

Reply via email to