Home | History | Annotate | Download | only in sensorhal
      1 /*
      2  * Copyright (C) 2015 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 HUB_CONNECTION_H_
     18 
     19 #define HUB_CONNECTION_H_
     20 
     21 #include <sys/types.h>
     22 #include <sys/stat.h>
     23 #include <fcntl.h>
     24 #include <poll.h>
     25 
     26 #include <utils/Errors.h>
     27 #include <utils/Mutex.h>
     28 #include <utils/Thread.h>
     29 
     30 #include "activityeventhandler.h"
     31 #include "eventnums.h"
     32 #include "hubdefs.h"
     33 #include "ring.h"
     34 
     35 namespace android {
     36 
     37 struct HubConnection : public Thread {
     38     static HubConnection *getInstance();
     39 
     40     status_t initCheck() const;
     41 
     42     enum ProximitySensorType {
     43         PROXIMITY_UNKNOWN,
     44         PROXIMITY_ROHM,
     45         PROXIMITY_AMS,
     46     };
     47 
     48     // Blocks until it can return a status
     49     status_t getAliveCheck();
     50 
     51     virtual bool threadLoop();
     52 
     53     void queueActivate(int handle, bool enable);
     54     void queueSetDelay(int handle, nsecs_t delayNs);
     55     void queueBatch(int handle, nsecs_t sampling_period_ns,
     56             nsecs_t max_report_latency_ns);
     57     void queueFlush(int handle);
     58     void queueData(int handle, void *data, size_t length);
     59 
     60     ssize_t read(sensors_event_t *ev, size_t size);
     61 
     62     void setActivityCallback(ActivityEventHandler *eventHandler);
     63 
     64     void saveSensorSettings() const;
     65 
     66 protected:
     67     HubConnection();
     68     virtual ~HubConnection();
     69 
     70     virtual void onFirstRef();
     71 
     72 private:
     73     typedef uint32_t rate_q10_t;  // q10 means lower 10 bits are for fractions
     74 
     75     static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
     76         return 1024000000000ULL / period_ns;
     77     }
     78 
     79     static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
     80         if (frequency_q10)
     81             return 1024000000000LL / frequency_q10;
     82         else
     83             return (nsecs_t)0;
     84     }
     85 
     86     enum
     87     {
     88         CONFIG_CMD_DISABLE      = 0,
     89         CONFIG_CMD_ENABLE       = 1,
     90         CONFIG_CMD_FLUSH        = 2,
     91         CONFIG_CMD_CFG_DATA     = 3,
     92         CONFIG_CMD_CALIBRATE    = 4,
     93     };
     94 
     95     struct ConfigCmd
     96     {
     97         uint32_t evtType;
     98         uint64_t latency;
     99         rate_q10_t rate;
    100         uint8_t sensorType;
    101         uint8_t cmd;
    102         uint16_t flags;
    103         uint8_t data[];
    104     } __attribute__((packed));
    105 
    106     struct MsgCmd
    107     {
    108         uint32_t evtType;
    109         struct HostHubRawPacket msg;
    110     } __attribute__((packed));
    111 
    112     struct SensorState {
    113         uint64_t latency;
    114         rate_q10_t rate;
    115         uint8_t sensorType;
    116         uint8_t alt;
    117         uint8_t flushCnt;
    118         bool enable;
    119     };
    120 
    121     struct FirstSample
    122     {
    123         uint8_t numSamples;
    124         uint8_t numFlushes;
    125         uint8_t highAccuracy : 1;
    126         uint8_t biasPresent : 1;
    127         uint8_t biasSample : 6;
    128         uint8_t pad;
    129     };
    130 
    131     struct RawThreeAxisSample
    132     {
    133         uint32_t deltaTime;
    134         int16_t ix, iy, iz;
    135     } __attribute__((packed));
    136 
    137     struct ThreeAxisSample
    138     {
    139         uint32_t deltaTime;
    140         float x, y, z;
    141     } __attribute__((packed));
    142 
    143     struct OneAxisSample
    144     {
    145         uint32_t deltaTime;
    146         union
    147         {
    148             float fdata;
    149             uint32_t idata;
    150         };
    151     } __attribute__((packed));
    152 
    153     // The following structure should match struct HostIntfDataBuffer found in
    154     // firmware/inc/hostIntf.h
    155     struct nAxisEvent
    156     {
    157         uint32_t evtType;
    158         union
    159         {
    160             struct
    161             {
    162                 uint64_t referenceTime;
    163                 union
    164                 {
    165                     struct FirstSample firstSample;
    166                     struct OneAxisSample oneSamples[];
    167                     struct RawThreeAxisSample rawThreeSamples[];
    168                     struct ThreeAxisSample threeSamples[];
    169                 };
    170             };
    171             uint8_t buffer[];
    172         };
    173     } __attribute__((packed));
    174 
    175     static Mutex sInstanceLock;
    176     static HubConnection *sInstance;
    177 
    178     // This lock is used for synchronization between the write thread (from
    179     // sensorservice) and the read thread polling from the nanohub driver.
    180     Mutex mLock;
    181 
    182     RingBuffer mRing;
    183 
    184     ActivityEventHandler *mActivityEventHandler;
    185 
    186     float mMagBias[3];
    187     uint8_t mMagAccuracy;
    188     uint8_t mMagAccuracyRestore;
    189 
    190     float mGyroBias[3], mAccelBias[3];
    191 
    192     SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];
    193 
    194     uint64_t mStepCounterOffset;
    195     uint64_t mLastStepCount;
    196 
    197     int mFd;
    198     int mInotifyPollIndex;
    199     struct pollfd mPollFds[4];
    200     int mNumPollFds;
    201 
    202     sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
    203     void magAccuracyUpdate(float x, float y, float z);
    204     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
    205     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
    206     void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
    207     void postOsLog(uint8_t *buf, ssize_t len);
    208     ssize_t processBuf(uint8_t *buf, ssize_t len);
    209 
    210     void initConfigCmd(struct ConfigCmd *cmd, int handle);
    211 
    212     void queueDataInternal(int handle, void *data, size_t length);
    213 
    214     void discardInotifyEvent();
    215     void waitOnNanohubLock();
    216 
    217     void initNanohubLock();
    218 
    219     void restoreSensorState();
    220     void sendCalibrationOffsets();
    221 
    222     // Enable SCHED_FIFO priority for main thread
    223     void enableSchedFifoMode();
    224 
    225 #ifdef LID_STATE_REPORTING_ENABLED
    226     int mUinputFd;
    227 
    228     status_t initializeUinputNode();
    229     void sendFolioEvent(int32_t data);
    230 #endif  // LID_STATE_REPORTING_ENABLED
    231 
    232 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
    233     int mMagBiasPollIndex;
    234     float mUsbMagBias;
    235 
    236     void queueUsbMagBias();
    237 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
    238 
    239 #ifdef DOUBLE_TOUCH_ENABLED
    240     int mDoubleTouchPollIndex;
    241 #endif  // DOUBLE_TOUCH_ENABLED
    242 
    243     DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
    244 };
    245 
    246 }  // namespace android
    247 
    248 #endif  // HUB_CONNECTION_H_
    249