From a6bea3d5fe6ff483199da4badce159e2ed78bfa7 Mon Sep 17 00:00:00 2001 From: Ye Xiang Date: Tue, 5 Jan 2021 17:35:13 +0800 Subject: [PATCH] iio: hid-sensor-magn-3d: Add timestamp channel 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 Link: https://lore.kernel.org/r/20210105093515.19135-5-xiang.ye@intel.com Signed-off-by: Jonathan Cameron --- 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 97642ebd9168..fa48044b7f5b 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, }; /* Channel definitions */ @@ -124,7 +127,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 */ @@ -273,13 +277,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, @@ -289,8 +286,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; } @@ -321,6 +325,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; } @@ -386,9 +395,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"); @@ -404,11 +414,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)++; } }