diff options
Diffstat (limited to 'drivers/iio/accel/hid-sensor-accel-3d.c')
| -rw-r--r-- | drivers/iio/accel/hid-sensor-accel-3d.c | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 0ec0533448bc..2ff591b3458f 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -6,13 +6,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" @@ -23,12 +20,16 @@ enum accel_3d_channel { ACCEL_3D_CHANNEL_MAX, }; +#define CHANNEL_SCAN_INDEX_TIMESTAMP ACCEL_3D_CHANNEL_MAX struct accel_3d_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; - /* Reserve for 3 channels + padding + timestamp */ - u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3]; + /* Ensure timestamp is naturally aligned */ + struct { + u32 accel_val[3]; + aligned_s64 timestamp; + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -42,6 +43,10 @@ static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = { HID_USAGE_SENSOR_ACCEL_Z_AXIS }; +static const u32 accel_3d_sensitivity_addresses[] = { + HID_USAGE_SENSOR_DATA_ACCELERATION, +}; + /* Channel definitions */ static const struct iio_chan_spec accel_3d_channels[] = { { @@ -75,7 +80,7 @@ static const struct iio_chan_spec accel_3d_channels[] = { BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, }, - IIO_CHAN_SOFT_TIMESTAMP(3) + IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP) }; /* Channel definitions */ @@ -110,7 +115,8 @@ static const struct iio_chan_spec gravity_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 */ @@ -222,7 +228,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, void *data, int len, int64_t timestamp) { dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); + iio_push_to_buffers_with_ts(indio_dev, data, len, timestamp); } /* Callback handler to send event after all samples are received and captured */ @@ -239,8 +245,8 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev, accel_state->timestamp = iio_get_time_ns(indio_dev); hid_sensor_push_data(indio_dev, - accel_state->accel_val, - sizeof(accel_state->accel_val), + &accel_state->scan, + sizeof(accel_state->scan), accel_state->timestamp); accel_state->timestamp = 0; @@ -265,7 +271,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, case HID_USAGE_SENSOR_ACCEL_Y_AXIS: case HID_USAGE_SENSOR_ACCEL_Z_AXIS: offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS; - accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] = + accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] = *(u32 *)raw_data; ret = 0; break; @@ -274,6 +280,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, hid_sensor_convert_timestamp( &accel_state->common_attributes, *(int64_t *)raw_data); + ret = 0; break; default: break; @@ -315,24 +322,13 @@ static int accel_3d_parse_report(struct platform_device *pdev, &st->accel[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_ACCELERATION, - &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_accel_3d_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; const char *name; struct iio_dev *indio_dev; @@ -340,8 +336,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev) const struct iio_chan_spec *channel_spec; int channel_size; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct accel_3d_state)); if (indio_dev == NULL) @@ -364,13 +358,17 @@ static int hid_accel_3d_probe(struct platform_device *pdev) channel_size = sizeof(gravity_channels); indio_dev->num_channels = ARRAY_SIZE(gravity_channels); } - ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage, - &accel_state->common_attributes); + ret = hid_sensor_parse_common_attributes(hsdev, + hsdev->usage, + &accel_state->common_attributes, + accel_3d_sensitivity_addresses, + ARRAY_SIZE(accel_3d_sensitivity_addresses)); if (ret) { dev_err(&pdev->dev, "failed to setup common attributes\n"); return ret; } - indio_dev->channels = kmemdup(channel_spec, channel_size, GFP_KERNEL); + indio_dev->channels = devm_kmemdup(&pdev->dev, channel_spec, + channel_size, GFP_KERNEL); if (!indio_dev->channels) { dev_err(&pdev->dev, "failed to duplicate channels\n"); @@ -381,10 +379,9 @@ static int hid_accel_3d_probe(struct platform_device *pdev) hsdev->usage, accel_state); if (ret) { dev_err(&pdev->dev, "failed to setup attributes\n"); - goto error_free_dev_mem; + return ret; } - indio_dev->dev.parent = &pdev->dev; indio_dev->info = &accel_3d_info; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; @@ -395,7 +392,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev) &accel_state->common_attributes); if (ret < 0) { dev_err(&pdev->dev, "trigger setup failed\n"); - goto error_free_dev_mem; + return ret; } ret = iio_device_register(indio_dev); @@ -420,24 +417,19 @@ error_iio_unreg: iio_device_unregister(indio_dev); error_remove_trigger: hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes); -error_free_dev_mem: - kfree(indio_dev->channels); return ret; } /* Function to deinitialize the processing for usage id */ -static int hid_accel_3d_remove(struct platform_device *pdev) +static void hid_accel_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 accel_3d_state *accel_state = iio_priv(indio_dev); sensor_hub_remove_callback(hsdev, hsdev->usage); iio_device_unregister(indio_dev); hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes); - kfree(indio_dev->channels); - - return 0; } static const struct platform_device_id hid_accel_3d_ids[] = { @@ -448,7 +440,7 @@ static const struct platform_device_id hid_accel_3d_ids[] = { { /* gravity sensor */ .name = "HID-SENSOR-20007b", }, - { /* sentinel */ } + { } }; MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids); @@ -466,3 +458,4 @@ module_platform_driver(hid_accel_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Accel 3D"); MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_HID"); |
