1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _SENSORS_H_
18#define _SENSORS_H_
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23#include <plat/taggedPtr.h>
24#include <variant/variant.h>
25#include <eventnums.h>
26#include <sensType.h>
27#include <stdbool.h>
28#include <stdint.h>
29#include "toolchain.h"
30
31// Specify the maximum number of sensors that can be registered. Allow it to be
32// overriden on a per-device basis.
33#ifndef MAX_REGISTERED_SENSORS
34#define MAX_REGISTERED_SENSORS 32
35#endif  // MAX_REGISTERED_SENSORS
36
37#define MAX_MIN_SAMPLES         3000
38
39enum NumAxis {
40    NUM_AXIS_EMBEDDED = 0,   // data = (uint32_t)evtData
41    NUM_AXIS_ONE      = 1,   // data is in struct SingleAxisDataEvent format
42    NUM_AXIS_THREE    = 3,   // data is in struct TripleAxisDataEvent format
43};
44
45struct SensorFirstSample
46{
47    uint8_t numSamples;
48    uint8_t numFlushes;
49    uint8_t biasCurrent : 1;
50    uint8_t biasPresent : 1;
51    uint8_t biasSample : 6;
52    uint8_t interrupt;
53};
54
55// NUM_AXIS_EMBEDDED data format
56union EmbeddedDataPoint {
57    uint32_t idata;
58    float fdata;
59    void *vptr;
60};
61
62// NUM_AXIS_ONE data format
63SET_PACKED_STRUCT_MODE_ON
64struct SingleAxisDataPoint {
65    union {
66        uint32_t deltaTime; //delta since last sample, for 0th sample this is firstSample
67        struct SensorFirstSample firstSample;
68    };
69    union {
70        float fdata;
71        int32_t idata;
72    };
73} ATTRIBUTE_PACKED;
74SET_PACKED_STRUCT_MODE_OFF
75
76struct SingleAxisDataEvent {
77    uint64_t referenceTime;
78    struct SingleAxisDataPoint samples[];
79};
80
81// NUM_AXIS_THREE data format
82SET_PACKED_STRUCT_MODE_ON
83struct TripleAxisDataPoint {
84    union {
85        uint32_t deltaTime; //delta since last sample, for 0th sample this is firstSample
86        struct SensorFirstSample firstSample;
87    };
88    union {
89        float x;
90        int32_t ix;
91    };
92    union {
93        float y;
94        int32_t iy;
95    };
96    union {
97        float z;
98        int32_t iz;
99    };
100} ATTRIBUTE_PACKED;
101SET_PACKED_STRUCT_MODE_OFF
102
103struct TripleAxisDataEvent {
104    uint64_t referenceTime;
105    struct TripleAxisDataPoint samples[];
106};
107
108SET_PACKED_STRUCT_MODE_ON
109struct RawTripleAxisDataPoint {
110    union {
111        uint32_t deltaTime; //delta since last sample, for 0th sample this is firstSample
112        struct SensorFirstSample firstSample;
113    };
114    int16_t ix;
115    int16_t iy;
116    int16_t iz;
117} ATTRIBUTE_PACKED;
118SET_PACKED_STRUCT_MODE_OFF
119
120struct RawTripleAxisDataEvent {
121    uint64_t referenceTime;
122    struct RawTripleAxisDataPoint samples[];
123};
124
125struct UserSensorEventHdr {  //all user sensor events start with this struct
126    TaggedPtr marshallCbk;
127};
128
129#define SENSOR_DATA_EVENT_FLUSH (void *)0xFFFFFFFF // flush for all data
130
131struct SensorRateChangeEvent {
132    uint32_t sensorHandle;
133    uint32_t newRate;
134    uint64_t newLatency;
135};
136
137struct SensorPowerEvent {
138    void *callData;
139    bool on;
140};
141
142struct SensorSetRateEvent {
143    void *callData;
144    uint32_t rate;
145    uint64_t latency;
146};
147
148struct SensorCfgDataEvent {
149    void *callData;
150    void *data;
151};
152
153struct SensorSendDirectEventEvent {
154    void *callData;
155    uint32_t tid;
156};
157
158struct SensorMarshallUserEventEvent {
159    void *callData;
160    uint32_t origEvtType;
161    void *origEvtData;
162    TaggedPtr evtFreeingInfo;
163};
164
165
166
167
168struct SensorOps {
169    bool (*sensorPower)(bool on, void *);          /* -> SENSOR_INTERNAL_EVT_POWER_STATE_CHG (success)         */
170    bool (*sensorFirmwareUpload)(void *);    /* -> SENSOR_INTERNAL_EVT_FW_STATE_CHG (rate or 0 if fail)  */
171    bool (*sensorSetRate)(uint32_t rate, uint64_t latency, void *);
172                                           /* -> SENSOR_INTERNAL_EVT_RATE_CHG (rate)                   */
173    bool (*sensorFlush)(void *); //trigger a measurement for ondemand sensors (if supported)
174    bool (*sensorTriggerOndemand)(void *);
175    bool (*sensorCalibrate)(void *);
176    bool (*sensorCfgData)(void *cfgData, void *);
177
178    bool (*sensorSendOneDirectEvt)(void *, uint32_t tid); //resend last state (if known), only for onchange-supporting sensors, to bring on a new client
179
180    // Marshall yourEvt for sending to host. Send a EVT_MARSHALLED_SENSOR_DATA event with marshalled data.
181    // Always send event, even on error, free the passed-in event using osFreeRetainedEvent
182    bool (*sensorMarshallData)(uint32_t yourEvtType, const void *yourEvtData, TaggedPtr *evtFreeingInfoP, void *);
183    bool (*sensorSelfTest)(void *);
184};
185
186enum SensorInfoFlags1 {
187    SENSOR_INFO_FLAGS1_BIAS = (1 << 0),
188    SENSOR_INFO_FLAGS1_RAW  = (1 << 1),
189
190    // Indicates that this sensor's events are for local consumption within the
191    // hub only, i.e. they should not be transmitted to the host
192    SENSOR_INFO_FLAGS1_LOCAL_ONLY = (1 << 2),
193};
194
195struct SensorInfo {
196    const char *sensorName; /* sensors.c code does not use this */
197
198    /* Specify a list of rates supported in sensorSetRate, using a 0 to mark the
199       end of the list.
200
201       If SENSOR_RATE_ONCHANGE is included in this list, then sensor events
202       should only be sent on data changes, regardless of any underlying
203       sampling rate. In this case, the sensorSendOneDirectEvt callback will be
204       invoked on each call to sensorRequest() to send new clients initial data.
205
206       If SENSOR_RATE_ONDEMAND is included in this list, then the
207       sensorTriggerOndemand callback must be implemented.
208
209       If this list contains only explicit rates in Hz, then sensorRequests with
210       SENSOR_RATE_ONCHANGE or ONDEMAND will be rejected.
211
212       If NULL, the expectation is that rate is not applicable/configurable, and
213       only SENSOR_RATE_ONCHANGE or SENSOR_RATE_ONDEMAND will be accepted, but
214       neither on-change semantics or on-demand support is implied. */
215    const uint32_t *supportedRates;
216
217    uint8_t sensorType;
218    uint8_t numAxis; /* enum NumAxis */
219    uint8_t interrupt; /* interrupt to generate to AP */
220    uint8_t flags1; /* enum SensorInfoFlags1 */
221    uint16_t minSamples; /* minimum host fifo size (in # of samples) */
222    uint8_t biasType;
223    uint8_t rawType;
224    float rawScale;
225};
226
227
228/*
229 * Sensor rate is encoded as a 32-bit integer as number of samples it can
230 * provide per 1024 seconds, allowing representations of all useful values
231 * well. This define is to be used for static values only please, as GCC
232 * will convert it into a const int at compile time. Do not use this at
233 * runtime please. A few Magic values exist at both ends of the range
234 * 0 is used as a list sentinel and high numbers for special abilities.
235 */
236#define SENSOR_RATE_ONDEMAND    0xFFFFFF00UL
237#define SENSOR_RATE_ONCHANGE    0xFFFFFF01UL
238#define SENSOR_RATE_ONESHOT     0xFFFFFF02UL
239#define SENSOR_HZ(_hz)          ((uint32_t)((_hz) * 1024.0f))
240
241/*
242 * Sensor latency is a 64-bit integer specifying the allowable delay in ns
243 * that data can be buffered.
244 */
245#define SENSOR_LATENCY_NODATA   0xFFFFFFFFFFFFFF00ULL
246
247/*
248 * sensors module api
249 */
250bool sensorsInit(void);
251
252/*
253 * Api for sensor drivers
254 */
255#define SENSOR_INTERNAL_EVT_POWER_STATE_CHG  0
256#define SENSOR_INTERNAL_EVT_FW_STATE_CHG     1
257#define SENSOR_INTERNAL_EVT_RATE_CHG         2
258
259uint32_t sensorRegister(const struct SensorInfo *si, const struct SensorOps *ops, void *callData, bool initComplete); /* returns handle, copy is not made */
260uint32_t sensorRegisterAsApp(const struct SensorInfo *si, uint32_t tid, void *callData, bool initComplete); /* returns handle, copy is not made */
261bool sensorRegisterInitComplete(uint32_t handle);
262bool sensorUnregister(uint32_t handle); /* your job to be sure it is off already */
263bool sensorSignalInternalEvt(uint32_t handle, uint32_t intEvtNum, uint32_t value1, uint64_t value2);
264
265#define sensorGetMyEventType(_sensorType) (EVT_NO_FIRST_SENSOR_EVENT + (_sensorType))
266#define sensorGetMyCfgEventType(_sensorType) (EVT_NO_SENSOR_CONFIG_EVENT + (_sensorType))
267
268
269/*
270 * api for using sensors (enum is not synced with sensor sub/unsub, this is ok since we do not expect a lot of dynamic sub/unsub)
271 */
272const struct SensorInfo* sensorFind(uint32_t sensorType, uint32_t idx, uint32_t *handleP); //enumerate all sensors of a type
273bool sensorRequest(uint32_t clientTid, uint32_t sensorHandle, uint32_t rate, uint64_t latency);
274bool sensorRequestRateChange(uint32_t clientTid, uint32_t sensorHandle, uint32_t newRate, uint64_t newLatency);
275bool sensorRelease(uint32_t clientTid, uint32_t sensorHandle);
276uint32_t sensorFreeAll(uint32_t clientTid);
277bool sensorTriggerOndemand(uint32_t clientTid, uint32_t sensorHandle);
278bool sensorFlush(uint32_t sensorHandle);
279bool sensorCalibrate(uint32_t sensorHandle);
280bool sensorSelfTest(uint32_t sensorHandle);
281bool sensorCfgData(uint32_t sensorHandle, void* cfgData);
282uint32_t sensorGetCurRate(uint32_t sensorHandle);
283uint64_t sensorGetCurLatency(uint32_t sensorHandle);
284uint32_t sensorGetReqRate(uint32_t sensorHandle);
285uint64_t sensorGetReqLatency(uint32_t sensorHandle);
286uint64_t sensorGetTime(void);
287bool sensorGetInitComplete(uint32_t sensorHandle); // DO NOT poll on this value
288bool sensorMarshallEvent(uint32_t sensorHandle, uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP);
289
290/*
291 * convenience funcs
292 */
293static inline uint64_t sensorTimerLookupCommon(const uint32_t *supportedRates, const uint64_t *timerVals, uint32_t wantedRate)
294{
295    uint32_t rate;
296
297    while ((rate = *supportedRates++) != 0) {
298        if (rate == wantedRate)
299            return *timerVals;
300        timerVals++;
301    }
302
303    return 0;
304}
305
306
307#ifdef __cplusplus
308}
309#endif
310
311#endif
312