2019-05-30 06:57:49 +07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2012-09-05 19:56:00 +07:00
|
|
|
/*
|
|
|
|
* HID Sensors Driver
|
|
|
|
* Copyright (c) 2012, Intel Corporation.
|
|
|
|
*/
|
|
|
|
#ifndef _HID_SENSORS_HUB_H
|
|
|
|
#define _HID_SENSORS_HUB_H
|
|
|
|
|
|
|
|
#include <linux/hid.h>
|
|
|
|
#include <linux/hid-sensor-ids.h>
|
2013-10-31 05:48:00 +07:00
|
|
|
#include <linux/iio/iio.h>
|
|
|
|
#include <linux/iio/trigger.h>
|
2012-09-05 19:56:00 +07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct hid_sensor_hub_attribute_info - Attribute info
|
|
|
|
* @usage_id: Parent usage id of a physical device.
|
|
|
|
* @attrib_id: Attribute id for this attribute.
|
|
|
|
* @report_id: Report id in which this information resides.
|
|
|
|
* @index: Field index in the report.
|
|
|
|
* @units: Measurment unit for this attribute.
|
|
|
|
* @unit_expo: Exponent used in the data.
|
|
|
|
* @size: Size in bytes for data size.
|
2015-01-08 01:14:43 +07:00
|
|
|
* @logical_minimum: Logical minimum value for this attribute.
|
|
|
|
* @logical_maximum: Logical maximum value for this attribute.
|
2012-09-05 19:56:00 +07:00
|
|
|
*/
|
|
|
|
struct hid_sensor_hub_attribute_info {
|
|
|
|
u32 usage_id;
|
|
|
|
u32 attrib_id;
|
|
|
|
s32 report_id;
|
|
|
|
s32 index;
|
|
|
|
s32 units;
|
|
|
|
s32 unit_expo;
|
|
|
|
s32 size;
|
2013-11-28 05:19:00 +07:00
|
|
|
s32 logical_minimum;
|
|
|
|
s32 logical_maximum;
|
2012-09-05 19:56:00 +07:00
|
|
|
};
|
|
|
|
|
2015-02-20 06:31:25 +07:00
|
|
|
/**
|
|
|
|
* struct sensor_hub_pending - Synchronous read pending information
|
|
|
|
* @status: Pending status true/false.
|
|
|
|
* @ready: Completion synchronization data.
|
|
|
|
* @usage_id: Usage id for physical device, E.g. Gyro usage id.
|
|
|
|
* @attr_usage_id: Usage Id of a field, E.g. X-AXIS for a gyro.
|
|
|
|
* @raw_size: Response size for a read request.
|
|
|
|
* @raw_data: Place holder for received response.
|
|
|
|
*/
|
|
|
|
struct sensor_hub_pending {
|
|
|
|
bool status;
|
|
|
|
struct completion ready;
|
|
|
|
u32 usage_id;
|
|
|
|
u32 attr_usage_id;
|
|
|
|
int raw_size;
|
|
|
|
u8 *raw_data;
|
|
|
|
};
|
|
|
|
|
2012-09-05 19:56:00 +07:00
|
|
|
/**
|
|
|
|
* struct hid_sensor_hub_device - Stores the hub instance data
|
|
|
|
* @hdev: Stores the hid instance.
|
|
|
|
* @vendor_id: Vendor id of hub device.
|
|
|
|
* @product_id: Product id of hub device.
|
2015-02-20 06:31:25 +07:00
|
|
|
* @usage: Usage id for this hub device instance.
|
HID: hid-sensor-hub: Processing for duplicate physical ids
In HID sensor hub, HID physical ids are used to represent different sensors.
For example physical id of 0x73 in usage page = 0x20, represents an
accelerometer. The HID sensor hub driver uses this physical ids to create
platform devices using MFD. There is 1:1 correspondence between an phy id and a
client driver.
But in some cases these physical ids are reused. There is a phy id 0xe1, which
specifies a custom sensor, which can exist multiple times to represent various
custom sensors. In this case there can be multiple instances of client MFD
drivers, processing specific custom sensor. In this case when client driver
looks for report id or a field index, it should still get the report id
specific to its own type. This is also true for reports, they should be
directed towards correct instance. This change introduce a way to parse and
tie physical devices to their correct instance.
Summary of changes:
- To get physical ids, use collections. If a collection of type=physical
exist then use usage id as in the name of platform device name
- As part of the platform data, we assign a hdsev instance, which has
start and end of collection indexes. Using these indexes attributes
can be tied to correct MFD client instances
- When a report is received, call callback with correct hsdev instance.
In this way using its private data stored as part of its registry, it
can distinguish different sensors even when they have same physical and
logical ids.
This patch is co-authored with Archana Patni <archna.patni@intel.com>.
Reported-by: Archana Patni <archana.patni@intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Archana Patni <archana.patni@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2014-02-01 03:04:10 +07:00
|
|
|
* @start_collection_index: Starting index for a phy type collection
|
|
|
|
* @end_collection_index: Last index for a phy type collection
|
2015-05-08 04:26:34 +07:00
|
|
|
* @mutex_ptr: synchronizing mutex pointer.
|
2015-02-20 06:31:25 +07:00
|
|
|
* @pending: Holds information of pending sync read request.
|
2012-09-05 19:56:00 +07:00
|
|
|
*/
|
|
|
|
struct hid_sensor_hub_device {
|
|
|
|
struct hid_device *hdev;
|
|
|
|
u32 vendor_id;
|
|
|
|
u32 product_id;
|
2015-02-20 06:31:25 +07:00
|
|
|
u32 usage;
|
HID: hid-sensor-hub: Processing for duplicate physical ids
In HID sensor hub, HID physical ids are used to represent different sensors.
For example physical id of 0x73 in usage page = 0x20, represents an
accelerometer. The HID sensor hub driver uses this physical ids to create
platform devices using MFD. There is 1:1 correspondence between an phy id and a
client driver.
But in some cases these physical ids are reused. There is a phy id 0xe1, which
specifies a custom sensor, which can exist multiple times to represent various
custom sensors. In this case there can be multiple instances of client MFD
drivers, processing specific custom sensor. In this case when client driver
looks for report id or a field index, it should still get the report id
specific to its own type. This is also true for reports, they should be
directed towards correct instance. This change introduce a way to parse and
tie physical devices to their correct instance.
Summary of changes:
- To get physical ids, use collections. If a collection of type=physical
exist then use usage id as in the name of platform device name
- As part of the platform data, we assign a hdsev instance, which has
start and end of collection indexes. Using these indexes attributes
can be tied to correct MFD client instances
- When a report is received, call callback with correct hsdev instance.
In this way using its private data stored as part of its registry, it
can distinguish different sensors even when they have same physical and
logical ids.
This patch is co-authored with Archana Patni <archna.patni@intel.com>.
Reported-by: Archana Patni <archana.patni@intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Archana Patni <archana.patni@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2014-02-01 03:04:10 +07:00
|
|
|
int start_collection_index;
|
|
|
|
int end_collection_index;
|
2015-05-08 04:26:34 +07:00
|
|
|
struct mutex *mutex_ptr;
|
2015-02-20 06:31:25 +07:00
|
|
|
struct sensor_hub_pending pending;
|
2012-09-05 19:56:00 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct hid_sensor_hub_callbacks - Client callback functions
|
|
|
|
* @pdev: Platform device instance of the client driver.
|
|
|
|
* @suspend: Suspend callback.
|
|
|
|
* @resume: Resume callback.
|
|
|
|
* @capture_sample: Callback to get a sample.
|
|
|
|
* @send_event: Send notification to indicate all samples are
|
|
|
|
* captured, process and send event
|
|
|
|
*/
|
|
|
|
struct hid_sensor_hub_callbacks {
|
|
|
|
struct platform_device *pdev;
|
|
|
|
int (*suspend)(struct hid_sensor_hub_device *hsdev, void *priv);
|
|
|
|
int (*resume)(struct hid_sensor_hub_device *hsdev, void *priv);
|
|
|
|
int (*capture_sample)(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u32 usage_id, size_t raw_len, char *raw_data,
|
|
|
|
void *priv);
|
|
|
|
int (*send_event)(struct hid_sensor_hub_device *hsdev, u32 usage_id,
|
|
|
|
void *priv);
|
|
|
|
};
|
|
|
|
|
2013-09-19 00:13:00 +07:00
|
|
|
/**
|
|
|
|
* sensor_hub_device_open() - Open hub device
|
|
|
|
* @hsdev: Hub device instance.
|
|
|
|
*
|
|
|
|
* Used to open hid device for sensor hub.
|
|
|
|
*/
|
|
|
|
int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_device_clode() - Close hub device
|
|
|
|
* @hsdev: Hub device instance.
|
|
|
|
*
|
|
|
|
* Used to clode hid device for sensor hub.
|
|
|
|
*/
|
|
|
|
void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev);
|
|
|
|
|
2012-09-05 19:56:00 +07:00
|
|
|
/* Registration functions */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_register_callback() - Register client callbacks
|
|
|
|
* @hsdev: Hub device instance.
|
|
|
|
* @usage_id: Usage id of the client (E.g. 0x200076 for Gyro).
|
|
|
|
* @usage_callback: Callback function storage
|
|
|
|
*
|
|
|
|
* Used to register callbacks by client processing drivers. Sensor
|
|
|
|
* hub core driver will call these callbacks to offload processing
|
|
|
|
* of data streams and notifications.
|
|
|
|
*/
|
|
|
|
int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u32 usage_id,
|
|
|
|
struct hid_sensor_hub_callbacks *usage_callback);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_remove_callback() - Remove client callbacks
|
|
|
|
* @hsdev: Hub device instance.
|
|
|
|
* @usage_id: Usage id of the client (E.g. 0x200076 for Gyro).
|
|
|
|
*
|
|
|
|
* If there is a callback registred, this call will remove that
|
|
|
|
* callbacks, so that it will stop data and event notifications.
|
|
|
|
*/
|
|
|
|
int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u32 usage_id);
|
|
|
|
|
|
|
|
|
|
|
|
/* Hid sensor hub core interfaces */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_input_get_attribute_info() - Get an attribute information
|
|
|
|
* @hsdev: Hub device instance.
|
|
|
|
* @type: Type of this attribute, input/output/feature
|
|
|
|
* @usage_id: Attribute usage id of parent physical device as per spec
|
|
|
|
* @attr_usage_id: Attribute usage id as per spec
|
|
|
|
* @info: return information about attribute after parsing report
|
|
|
|
*
|
|
|
|
* Parses report and returns the attribute information such as report id,
|
|
|
|
* field index, units and exponet etc.
|
|
|
|
*/
|
|
|
|
int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u8 type,
|
|
|
|
u32 usage_id, u32 attr_usage_id,
|
|
|
|
struct hid_sensor_hub_attribute_info *info);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_input_attr_get_raw_value() - Synchronous read request
|
2015-01-08 01:14:43 +07:00
|
|
|
* @hsdev: Hub device instance.
|
2012-09-05 19:56:00 +07:00
|
|
|
* @usage_id: Attribute usage id of parent physical device as per spec
|
|
|
|
* @attr_usage_id: Attribute usage id as per spec
|
|
|
|
* @report_id: Report id to look for
|
2015-02-20 06:33:56 +07:00
|
|
|
* @flag: Synchronous or asynchronous read
|
2018-10-31 21:20:05 +07:00
|
|
|
* @is_signed: If true then fields < 32 bits will be sign-extended
|
2012-09-05 19:56:00 +07:00
|
|
|
*
|
2015-02-20 06:33:56 +07:00
|
|
|
* Issues a synchronous or asynchronous read request for an input attribute.
|
|
|
|
* Returns data upto 32 bits.
|
2012-09-05 19:56:00 +07:00
|
|
|
*/
|
|
|
|
|
2015-02-20 06:33:56 +07:00
|
|
|
enum sensor_hub_read_flags {
|
|
|
|
SENSOR_HUB_SYNC,
|
|
|
|
SENSOR_HUB_ASYNC,
|
|
|
|
};
|
|
|
|
|
2012-09-05 19:56:00 +07:00
|
|
|
int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
|
2015-02-20 06:33:56 +07:00
|
|
|
u32 usage_id,
|
|
|
|
u32 attr_usage_id, u32 report_id,
|
2018-10-31 21:20:05 +07:00
|
|
|
enum sensor_hub_read_flags flag,
|
|
|
|
bool is_signed
|
2015-02-20 06:33:56 +07:00
|
|
|
);
|
|
|
|
|
2012-09-05 19:56:00 +07:00
|
|
|
/**
|
|
|
|
* sensor_hub_set_feature() - Feature set request
|
2015-01-08 01:14:43 +07:00
|
|
|
* @hsdev: Hub device instance.
|
2012-09-05 19:56:00 +07:00
|
|
|
* @report_id: Report id to look for
|
|
|
|
* @field_index: Field index inside a report
|
2015-02-20 06:35:26 +07:00
|
|
|
* @buffer_size: size of the buffer
|
|
|
|
* @buffer: buffer to use in the feature set
|
2012-09-05 19:56:00 +07:00
|
|
|
*
|
|
|
|
* Used to set a field in feature report. For example this can set polling
|
|
|
|
* interval, sensitivity, activate/deactivate state.
|
|
|
|
*/
|
|
|
|
int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
|
2015-02-20 06:35:26 +07:00
|
|
|
u32 field_index, int buffer_size, void *buffer);
|
2012-09-05 19:56:00 +07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* sensor_hub_get_feature() - Feature get request
|
2015-01-08 01:14:43 +07:00
|
|
|
* @hsdev: Hub device instance.
|
2012-09-05 19:56:00 +07:00
|
|
|
* @report_id: Report id to look for
|
|
|
|
* @field_index: Field index inside a report
|
2015-02-20 06:35:25 +07:00
|
|
|
* @buffer_size: size of the buffer
|
|
|
|
* @buffer: buffer to copy output
|
2012-09-05 19:56:00 +07:00
|
|
|
*
|
|
|
|
* Used to get a field in feature report. For example this can get polling
|
2015-02-20 06:35:25 +07:00
|
|
|
* interval, sensitivity, activate/deactivate state. On success it returns
|
|
|
|
* number of bytes copied to buffer. On failure, it returns value < 0.
|
2012-09-05 19:56:00 +07:00
|
|
|
*/
|
|
|
|
int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
|
2015-02-20 06:35:25 +07:00
|
|
|
u32 field_index, int buffer_size, void *buffer);
|
2012-12-15 19:45:00 +07:00
|
|
|
|
|
|
|
/* hid-sensor-attributes */
|
|
|
|
|
|
|
|
/* Common hid sensor iio structure */
|
2012-12-15 19:45:00 +07:00
|
|
|
struct hid_sensor_common {
|
2012-12-15 19:45:00 +07:00
|
|
|
struct hid_sensor_hub_device *hsdev;
|
|
|
|
struct platform_device *pdev;
|
|
|
|
unsigned usage_id;
|
2014-04-19 06:22:00 +07:00
|
|
|
atomic_t data_ready;
|
2015-06-02 06:36:27 +07:00
|
|
|
atomic_t user_requested_state;
|
2017-10-11 23:35:01 +07:00
|
|
|
atomic_t runtime_pm_enable;
|
2017-04-08 07:13:17 +07:00
|
|
|
int poll_interval;
|
|
|
|
int raw_hystersis;
|
2017-04-08 09:22:06 +07:00
|
|
|
int latency_ms;
|
2013-10-31 05:48:00 +07:00
|
|
|
struct iio_trigger *trigger;
|
2016-11-29 05:41:16 +07:00
|
|
|
int timestamp_ns_scale;
|
2012-12-15 19:45:00 +07:00
|
|
|
struct hid_sensor_hub_attribute_info poll;
|
|
|
|
struct hid_sensor_hub_attribute_info report_state;
|
|
|
|
struct hid_sensor_hub_attribute_info power_state;
|
|
|
|
struct hid_sensor_hub_attribute_info sensitivity;
|
2017-04-08 09:22:06 +07:00
|
|
|
struct hid_sensor_hub_attribute_info report_latency;
|
2016-08-16 02:12:47 +07:00
|
|
|
struct work_struct work;
|
2012-12-15 19:45:00 +07:00
|
|
|
};
|
|
|
|
|
2013-08-14 15:07:08 +07:00
|
|
|
/* Convert from hid unit expo to regular exponent */
|
2012-12-15 19:45:00 +07:00
|
|
|
static inline int hid_sensor_convert_exponent(int unit_expo)
|
|
|
|
{
|
|
|
|
if (unit_expo < 0x08)
|
|
|
|
return unit_expo;
|
|
|
|
else if (unit_expo <= 0x0f)
|
|
|
|
return -(0x0f-unit_expo+1);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u32 usage_id,
|
2012-12-15 19:45:00 +07:00
|
|
|
struct hid_sensor_common *st);
|
|
|
|
int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
|
2012-12-15 19:45:00 +07:00
|
|
|
int val1, int val2);
|
2012-12-15 19:45:00 +07:00
|
|
|
int hid_sensor_read_raw_hyst_value(struct hid_sensor_common *st,
|
2012-12-15 19:45:00 +07:00
|
|
|
int *val1, int *val2);
|
2012-12-15 19:45:00 +07:00
|
|
|
int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
|
2012-12-15 19:45:00 +07:00
|
|
|
int val1, int val2);
|
2012-12-15 19:45:00 +07:00
|
|
|
int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st,
|
2012-12-15 19:45:00 +07:00
|
|
|
int *val1, int *val2);
|
|
|
|
|
2014-01-24 09:50:21 +07:00
|
|
|
int hid_sensor_get_usage_index(struct hid_sensor_hub_device *hsdev,
|
|
|
|
u32 report_id, int field_index, u32 usage_id);
|
|
|
|
|
2014-04-19 06:22:00 +07:00
|
|
|
int hid_sensor_format_scale(u32 usage_id,
|
|
|
|
struct hid_sensor_hub_attribute_info *attr_info,
|
|
|
|
int *val0, int *val1);
|
|
|
|
|
2014-04-19 06:22:00 +07:00
|
|
|
s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
|
|
|
|
|
2016-11-29 05:41:16 +07:00
|
|
|
int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st,
|
|
|
|
int64_t raw_value);
|
2017-04-08 09:22:06 +07:00
|
|
|
bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st);
|
|
|
|
int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency);
|
|
|
|
int hid_sensor_get_report_latency(struct hid_sensor_common *st);
|
2016-11-29 05:41:16 +07:00
|
|
|
|
2012-09-05 19:56:00 +07:00
|
|
|
#endif
|