Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: hid-sensor-rotation: 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 <xiang.ye@intel.com>
Link: https://lore.kernel.org/r/20210105093515.19135-7-xiang.ye@intel.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Ye Xiang and committed by
Jonathan Cameron
4a3582c8 04fe70d1

+26 -20
+26 -20
drivers/iio/orientation/hid-sensor-rotation.c
··· 20 20 struct hid_sensor_hub_callbacks callbacks; 21 21 struct hid_sensor_common common_attributes; 22 22 struct hid_sensor_hub_attribute_info quaternion; 23 - u32 sampled_vals[4]; 23 + struct { 24 + u32 sampled_vals[4] __aligned(16); 25 + u64 timestamp __aligned(8); 26 + } scan; 24 27 int scale_pre_decml; 25 28 int scale_post_decml; 26 29 int scale_precision; 27 30 int value_offset; 31 + s64 timestamp; 28 32 }; 29 33 30 34 /* Channel definitions */ ··· 41 37 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | 42 38 BIT(IIO_CHAN_INFO_OFFSET) | 43 39 BIT(IIO_CHAN_INFO_SCALE) | 44 - BIT(IIO_CHAN_INFO_HYSTERESIS) 45 - } 40 + BIT(IIO_CHAN_INFO_HYSTERESIS), 41 + .scan_index = 0 42 + }, 43 + IIO_CHAN_SOFT_TIMESTAMP(1) 46 44 }; 47 45 48 46 /* Adjust channel real bits based on report descriptor */ ··· 76 70 case IIO_CHAN_INFO_RAW: 77 71 if (size >= 4) { 78 72 for (i = 0; i < 4; ++i) 79 - vals[i] = rot_state->sampled_vals[i]; 73 + vals[i] = rot_state->scan.sampled_vals[i]; 80 74 ret_type = IIO_VAL_INT_MULTIPLE; 81 75 *val_len = 4; 82 76 } else ··· 138 132 .write_raw = &dev_rot_write_raw, 139 133 }; 140 134 141 - /* Function to push data to buffer */ 142 - static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) 143 - { 144 - dev_dbg(&indio_dev->dev, "hid_sensor_push_data >>\n"); 145 - iio_push_to_buffers(indio_dev, (u8 *)data); 146 - dev_dbg(&indio_dev->dev, "hid_sensor_push_data <<\n"); 147 - 148 - } 149 - 150 135 /* Callback handler to send event after all samples are received and captured */ 151 136 static int dev_rot_proc_event(struct hid_sensor_hub_device *hsdev, 152 137 unsigned usage_id, ··· 147 150 struct dev_rot_state *rot_state = iio_priv(indio_dev); 148 151 149 152 dev_dbg(&indio_dev->dev, "dev_rot_proc_event\n"); 150 - if (atomic_read(&rot_state->common_attributes.data_ready)) 151 - hid_sensor_push_data(indio_dev, 152 - (u8 *)rot_state->sampled_vals, 153 - sizeof(rot_state->sampled_vals)); 153 + if (atomic_read(&rot_state->common_attributes.data_ready)) { 154 + if (!rot_state->timestamp) 155 + rot_state->timestamp = iio_get_time_ns(indio_dev); 156 + 157 + iio_push_to_buffers_with_timestamp(indio_dev, &rot_state->scan, 158 + rot_state->timestamp); 159 + 160 + rot_state->timestamp = 0; 161 + } 154 162 155 163 return 0; 156 164 } ··· 170 168 struct dev_rot_state *rot_state = iio_priv(indio_dev); 171 169 172 170 if (usage_id == HID_USAGE_SENSOR_ORIENT_QUATERNION) { 173 - memcpy(rot_state->sampled_vals, raw_data, 174 - sizeof(rot_state->sampled_vals)); 171 + memcpy(&rot_state->scan.sampled_vals, raw_data, 172 + sizeof(rot_state->scan.sampled_vals)); 173 + 175 174 dev_dbg(&indio_dev->dev, "Recd Quat len:%zu::%zu\n", raw_len, 176 - sizeof(rot_state->sampled_vals)); 175 + sizeof(rot_state->scan.sampled_vals)); 176 + } else if (usage_id == HID_USAGE_SENSOR_TIME_TIMESTAMP) { 177 + rot_state->timestamp = hid_sensor_convert_timestamp(&rot_state->common_attributes, 178 + *(s64 *)raw_data); 177 179 } 178 180 179 181 return 0;