Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Chrome OS EC MEMS Sensor Hub driver.
0004  *
0005  * Copyright 2019 Google LLC
0006  */
0007 
0008 #ifndef __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H
0009 #define __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H
0010 
0011 #include <linux/ktime.h>
0012 #include <linux/mutex.h>
0013 #include <linux/notifier.h>
0014 #include <linux/platform_data/cros_ec_commands.h>
0015 
0016 struct iio_dev;
0017 
0018 /**
0019  * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information.
0020  * @sensor_num: Id of the sensor, as reported by the EC.
0021  */
0022 struct cros_ec_sensor_platform {
0023     u8 sensor_num;
0024 };
0025 
0026 /**
0027  * typedef cros_ec_sensorhub_push_data_cb_t - Callback function to send datum
0028  *                        to specific sensors.
0029  *
0030  * @indio_dev: The IIO device that will process the sample.
0031  * @data: Vector array of the ring sample.
0032  * @timestamp: Timestamp in host timespace when the sample was acquired by
0033  *             the EC.
0034  */
0035 typedef int (*cros_ec_sensorhub_push_data_cb_t)(struct iio_dev *indio_dev,
0036                         s16 *data,
0037                         s64 timestamp);
0038 
0039 struct cros_ec_sensorhub_sensor_push_data {
0040     struct iio_dev *indio_dev;
0041     cros_ec_sensorhub_push_data_cb_t push_data_cb;
0042 };
0043 
0044 enum {
0045     CROS_EC_SENSOR_LAST_TS,
0046     CROS_EC_SENSOR_NEW_TS,
0047     CROS_EC_SENSOR_ALL_TS
0048 };
0049 
0050 struct cros_ec_sensors_ring_sample {
0051     u8  sensor_id;
0052     u8  flag;
0053     s16 vector[3];
0054     s64 timestamp;
0055 } __packed;
0056 
0057 /* State used for cros_ec_ring_fix_overflow */
0058 struct cros_ec_sensors_ec_overflow_state {
0059     s64 offset;
0060     s64 last;
0061 };
0062 
0063 /* Length of the filter, how long to remember entries for */
0064 #define CROS_EC_SENSORHUB_TS_HISTORY_SIZE 64
0065 
0066 /**
0067  * struct cros_ec_sensors_ts_filter_state - Timestamp filetr state.
0068  *
0069  * @x_offset: x is EC interrupt time. x_offset its last value.
0070  * @y_offset: y is the difference between AP and EC time, y_offset its last
0071  *            value.
0072  * @x_history: The past history of x, relative to x_offset.
0073  * @y_history: The past history of y, relative to y_offset.
0074  * @m_history: rate between y and x.
0075  * @history_len: Amount of valid historic data in the arrays.
0076  * @temp_buf: Temporary buffer used when updating the filter.
0077  * @median_m: median value of m_history
0078  * @median_error: final error to apply to AP interrupt timestamp to get the
0079  *                "true timestamp" the event occurred.
0080  */
0081 struct cros_ec_sensors_ts_filter_state {
0082     s64 x_offset, y_offset;
0083     s64 x_history[CROS_EC_SENSORHUB_TS_HISTORY_SIZE];
0084     s64 y_history[CROS_EC_SENSORHUB_TS_HISTORY_SIZE];
0085     s64 m_history[CROS_EC_SENSORHUB_TS_HISTORY_SIZE];
0086     int history_len;
0087 
0088     s64 temp_buf[CROS_EC_SENSORHUB_TS_HISTORY_SIZE];
0089 
0090     s64 median_m;
0091     s64 median_error;
0092 };
0093 
0094 /* struct cros_ec_sensors_ts_batch_state - State of batch of a single sensor.
0095  *
0096  * Use to store information to batch data using median fileter information.
0097  *
0098  * @penul_ts: last but one batch timestamp (penultimate timestamp).
0099  *        Used for timestamp spreading calculations
0100  *        when a batch shows up.
0101  * @penul_len: last but one batch length.
0102  * @last_ts: Last batch timestam.
0103  * @last_len: Last batch length.
0104  * @newest_sensor_event: Last sensor timestamp.
0105  */
0106 struct cros_ec_sensors_ts_batch_state {
0107     s64 penul_ts;
0108     int penul_len;
0109     s64 last_ts;
0110     int last_len;
0111     s64 newest_sensor_event;
0112 };
0113 
0114 /*
0115  * struct cros_ec_sensorhub - Sensor Hub device data.
0116  *
0117  * @dev: Device object, mostly used for logging.
0118  * @ec: Embedded Controller where the hub is located.
0119  * @sensor_num: Number of MEMS sensors present in the EC.
0120  * @msg: Structure to send FIFO requests.
0121  * @params: Pointer to parameters in msg.
0122  * @resp: Pointer to responses in msg.
0123  * @cmd_lock : Lock for sending msg.
0124  * @notifier: Notifier to kick the FIFO interrupt.
0125  * @ring: Preprocessed ring to store events.
0126  * @fifo_timestamp: Array for event timestamp and spreading.
0127  * @fifo_info: Copy of FIFO information coming from the EC.
0128  * @fifo_size: Size of the ring.
0129  * @batch_state: Per sensor information of the last batches received.
0130  * @overflow_a: For handling timestamp overflow for a time (sensor events)
0131  * @overflow_b: For handling timestamp overflow for b time (ec interrupts)
0132  * @filter: Medium fileter structure.
0133  * @tight_timestamps: Set to truen when EC support tight timestamping:
0134  *            The timestamps reported from the EC have low jitter.
0135  *            Timestamps also come before every sample. Set either
0136  *            by feature bits coming from the EC or userspace.
0137  * @future_timestamp_count: Statistics used to compute shaved time.
0138  *              This occurs when timestamp interpolation from EC
0139  *              time to AP time accidentally puts timestamps in
0140  *              the future. These timestamps are clamped to
0141  *              `now` and these count/total_ns maintain the
0142  *              statistics for how much time was removed in a
0143  *              given period.
0144  * @future_timestamp_total_ns: Total amount of time shaved.
0145  * @push_data: Array of callback to send datums to iio sensor object.
0146  */
0147 struct cros_ec_sensorhub {
0148     struct device *dev;
0149     struct cros_ec_dev *ec;
0150     int sensor_num;
0151 
0152     struct cros_ec_command *msg;
0153     struct ec_params_motion_sense *params;
0154     struct ec_response_motion_sense *resp;
0155     struct mutex cmd_lock;  /* Lock for protecting msg structure. */
0156 
0157     struct notifier_block notifier;
0158 
0159     struct cros_ec_sensors_ring_sample *ring;
0160 
0161     ktime_t fifo_timestamp[CROS_EC_SENSOR_ALL_TS];
0162     struct ec_response_motion_sense_fifo_info *fifo_info;
0163     int fifo_size;
0164 
0165     struct cros_ec_sensors_ts_batch_state *batch_state;
0166 
0167     struct cros_ec_sensors_ec_overflow_state overflow_a;
0168     struct cros_ec_sensors_ec_overflow_state overflow_b;
0169 
0170     struct cros_ec_sensors_ts_filter_state filter;
0171 
0172     int tight_timestamps;
0173 
0174     s32 future_timestamp_count;
0175     s64 future_timestamp_total_ns;
0176 
0177     struct cros_ec_sensorhub_sensor_push_data *push_data;
0178 };
0179 
0180 int cros_ec_sensorhub_register_push_data(struct cros_ec_sensorhub *sensorhub,
0181                      u8 sensor_num,
0182                      struct iio_dev *indio_dev,
0183                      cros_ec_sensorhub_push_data_cb_t cb);
0184 
0185 void cros_ec_sensorhub_unregister_push_data(struct cros_ec_sensorhub *sensorhub,
0186                         u8 sensor_num);
0187 
0188 int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub);
0189 int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub);
0190 void cros_ec_sensorhub_ring_remove(void *arg);
0191 int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub,
0192                        bool on);
0193 
0194 #endif   /* __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H */