diff options
Diffstat (limited to 'drivers/iio/orientation/hid-sensor-incl-3d.c')
| -rw-r--r-- | drivers/iio/orientation/hid-sensor-incl-3d.c | 91 |
1 files changed, 45 insertions, 46 deletions
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c index 6aac8bea233a..4e23a598a3fb 100644 --- a/drivers/iio/orientation/hid-sensor-incl-3d.c +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c @@ -7,13 +7,10 @@ #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 "../common/hid-sensors/hid-sensor-trigger.h" @@ -24,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]; + aligned_s64 timestamp; + } 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] = { @@ -41,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[] = { { @@ -73,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 */ @@ -178,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, @@ -194,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; } @@ -214,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; @@ -280,28 +293,17 @@ 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; } /* Function to initialize the processing for usage id */ static int hid_incl_3d_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret; static char *name = "incli_3d"; struct iio_dev *indio_dev; struct incl_3d_state *incl_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct incl_3d_state)); @@ -316,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; @@ -335,11 +339,10 @@ 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; @@ -350,7 +353,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev) &incl_state->common_attributes); if (ret) { dev_err(&pdev->dev, "trigger setup failed\n"); - goto error_free_dev_mem; + return ret; } ret = iio_device_register(indio_dev); @@ -376,24 +379,19 @@ error_iio_unreg: iio_device_unregister(indio_dev); error_remove_trigger: hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); -error_free_dev_mem: - kfree(indio_dev->channels); return ret; } /* Function to deinitialize the processing for usage id */ -static int hid_incl_3d_remove(struct platform_device *pdev) +static void hid_incl_3d_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct incl_3d_state *incl_state = iio_priv(indio_dev); sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D); iio_device_unregister(indio_dev); hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes); - kfree(indio_dev->channels); - - return 0; } static const struct platform_device_id hid_incl_3d_ids[] = { @@ -401,7 +399,7 @@ static const struct platform_device_id hid_incl_3d_ids[] = { /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ .name = "HID-SENSOR-200086", }, - { /* sentinel */ } + { } }; MODULE_DEVICE_TABLE(platform, hid_incl_3d_ids); @@ -419,3 +417,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"); |
