diff options
Diffstat (limited to 'drivers/iio/orientation/hid-sensor-incl-3d.c')
-rw-r--r-- | drivers/iio/orientation/hid-sensor-incl-3d.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c index 00af68764cda..ba5b581d5b25 100644 --- a/drivers/iio/orientation/hid-sensor-incl-3d.c +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c @@ -7,16 +7,11 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/irq.h> +#include <linux/mod_devicetable.h> #include <linux/slab.h> -#include <linux/delay.h> #include <linux/hid-sensor-hub.h> #include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> -#include <linux/iio/trigger_consumer.h> -#include <linux/iio/triggered_buffer.h> #include "../common/hid-sensors/hid-sensor-trigger.h" enum incl_3d_channel { @@ -26,15 +21,21 @@ enum incl_3d_channel { INCLI_3D_CHANNEL_MAX, }; +#define CHANNEL_SCAN_INDEX_TIMESTAMP INCLI_3D_CHANNEL_MAX + struct incl_3d_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info incl[INCLI_3D_CHANNEL_MAX]; - u32 incl_val[INCLI_3D_CHANNEL_MAX]; + struct { + u32 incl_val[INCLI_3D_CHANNEL_MAX]; + u64 timestamp __aligned(8); + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; int value_offset; + s64 timestamp; }; static const u32 incl_3d_addresses[INCLI_3D_CHANNEL_MAX] = { @@ -43,6 +44,11 @@ static const u32 incl_3d_addresses[INCLI_3D_CHANNEL_MAX] = { HID_USAGE_SENSOR_ORIENT_TILT_Z }; +static const u32 incl_3d_sensitivity_addresses[] = { + HID_USAGE_SENSOR_DATA_ORIENTATION, + HID_USAGE_SENSOR_ORIENT_TILT, +}; + /* Channel definitions */ static const struct iio_chan_spec incl_3d_channels[] = { { @@ -75,7 +81,8 @@ static const struct iio_chan_spec incl_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, - } + }, + IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP), }; /* Adjust channel real bits based on report descriptor */ @@ -180,13 +187,6 @@ static const struct iio_info incl_3d_info = { .write_raw = &incl_3d_write_raw, }; -/* Function to push data to buffer */ -static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) -{ - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - iio_push_to_buffers(indio_dev, (u8 *)data); -} - /* Callback handler to send event after all samples are received and captured */ static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev, unsigned usage_id, @@ -196,10 +196,16 @@ static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev, struct incl_3d_state *incl_state = iio_priv(indio_dev); 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)); + if (atomic_read(&incl_state->common_attributes.data_ready)) { + if (!incl_state->timestamp) + incl_state->timestamp = iio_get_time_ns(indio_dev); + + iio_push_to_buffers_with_timestamp(indio_dev, + &incl_state->scan, + incl_state->timestamp); + + incl_state->timestamp = 0; + } return 0; } @@ -216,13 +222,18 @@ static int incl_3d_capture_sample(struct hid_sensor_hub_device *hsdev, switch (usage_id) { case HID_USAGE_SENSOR_ORIENT_TILT_X: - incl_state->incl_val[CHANNEL_SCAN_INDEX_X] = *(u32 *)raw_data; + incl_state->scan.incl_val[CHANNEL_SCAN_INDEX_X] = *(u32 *)raw_data; break; case HID_USAGE_SENSOR_ORIENT_TILT_Y: - incl_state->incl_val[CHANNEL_SCAN_INDEX_Y] = *(u32 *)raw_data; + incl_state->scan.incl_val[CHANNEL_SCAN_INDEX_Y] = *(u32 *)raw_data; break; case HID_USAGE_SENSOR_ORIENT_TILT_Z: - incl_state->incl_val[CHANNEL_SCAN_INDEX_Z] = *(u32 *)raw_data; + incl_state->scan.incl_val[CHANNEL_SCAN_INDEX_Z] = *(u32 *)raw_data; + break; + case HID_USAGE_SENSOR_TIME_TIMESTAMP: + incl_state->timestamp = + hid_sensor_convert_timestamp(&incl_state->common_attributes, + *(s64 *)raw_data); break; default: ret = -EINVAL; @@ -282,17 +293,6 @@ static int incl_3d_parse_report(struct platform_device *pdev, &st->incl[CHANNEL_SCAN_INDEX_X], &st->scale_pre_decml, &st->scale_post_decml); - /* Set Sensitivity field ids, when there is no individual modifier */ - if (st->common_attributes.sensitivity.index < 0) { - sensor_hub_input_get_attribute_info(hsdev, - HID_FEATURE_REPORT, usage_id, - HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | - HID_USAGE_SENSOR_DATA_ORIENTATION, - &st->common_attributes.sensitivity); - dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", - st->common_attributes.sensitivity.index, - st->common_attributes.sensitivity.report_id); - } return ret; } @@ -318,14 +318,16 @@ static int hid_incl_3d_probe(struct platform_device *pdev) ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D, - &incl_state->common_attributes); + &incl_state->common_attributes, + incl_3d_sensitivity_addresses, + ARRAY_SIZE(incl_3d_sensitivity_addresses)); if (ret) { dev_err(&pdev->dev, "failed to setup common attributes\n"); return ret; } - indio_dev->channels = kmemdup(incl_3d_channels, - sizeof(incl_3d_channels), GFP_KERNEL); + indio_dev->channels = devm_kmemdup(&pdev->dev, incl_3d_channels, + sizeof(incl_3d_channels), GFP_KERNEL); if (!indio_dev->channels) { dev_err(&pdev->dev, "failed to duplicate channels\n"); return -ENOMEM; @@ -337,27 +339,21 @@ static int hid_incl_3d_probe(struct platform_device *pdev) incl_state); if (ret) { dev_err(&pdev->dev, "failed to setup attributes\n"); - goto error_free_dev_mem; + return ret; } indio_dev->num_channels = ARRAY_SIZE(incl_3d_channels); - indio_dev->dev.parent = &pdev->dev; indio_dev->info = &incl_3d_info; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - NULL, NULL); - if (ret) { - dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); - goto error_free_dev_mem; - } atomic_set(&incl_state->common_attributes.data_ready, 0); + ret = hid_sensor_setup_trigger(indio_dev, name, &incl_state->common_attributes); if (ret) { dev_err(&pdev->dev, "trigger setup failed\n"); - goto error_unreg_buffer_funcs; + return ret; } ret = iio_device_register(indio_dev); @@ -382,11 +378,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev) error_iio_unreg: iio_device_unregister(indio_dev); error_remove_trigger: - hid_sensor_remove_trigger(&incl_state->common_attributes); -error_unreg_buffer_funcs: - iio_triggered_buffer_cleanup(indio_dev); -error_free_dev_mem: - kfree(indio_dev->channels); + hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); return ret; } @@ -399,9 +391,7 @@ static int hid_incl_3d_remove(struct platform_device *pdev) sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D); iio_device_unregister(indio_dev); - hid_sensor_remove_trigger(&incl_state->common_attributes); - iio_triggered_buffer_cleanup(indio_dev); - kfree(indio_dev->channels); + hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); return 0; } @@ -429,3 +419,4 @@ module_platform_driver(hid_incl_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Inclinometer 3D"); MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_HID); |