| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef HUB_CONNECTION_H_ |
| |
| #define HUB_CONNECTION_H_ |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <poll.h> |
| |
| #include <utils/Errors.h> |
| #include <utils/Mutex.h> |
| #include <utils/Thread.h> |
| #include <hardware_legacy/power.h> |
| |
| #include "activityeventhandler.h" |
| #include "eventnums.h" |
| #include "hubdefs.h" |
| #include "ring.h" |
| |
| #define WAKELOCK_NAME "sensorHal" |
| |
| namespace android { |
| |
| struct HubConnection : public Thread { |
| static HubConnection *getInstance(); |
| |
| status_t initCheck() const; |
| |
| enum ProximitySensorType { |
| PROXIMITY_UNKNOWN, |
| PROXIMITY_ROHM, |
| PROXIMITY_AMS, |
| }; |
| |
| // Blocks until it can return a status |
| status_t getAliveCheck(); |
| |
| virtual bool threadLoop(); |
| |
| void queueActivate(int handle, bool enable); |
| void queueSetDelay(int handle, nsecs_t delayNs); |
| void queueBatch(int handle, nsecs_t sampling_period_ns, |
| nsecs_t max_report_latency_ns); |
| void queueFlush(int handle); |
| void queueData(int handle, void *data, size_t length); |
| |
| bool isWakeEvent(int32_t sensor); |
| void releaseWakeLockIfAppropriate(); |
| ssize_t getWakeEventCount(); |
| ssize_t decrementWakeEventCount(); |
| |
| ssize_t read(sensors_event_t *ev, size_t size); |
| |
| void setActivityCallback(ActivityEventHandler *eventHandler); |
| |
| void saveSensorSettings() const; |
| |
| protected: |
| HubConnection(); |
| virtual ~HubConnection(); |
| |
| virtual void onFirstRef(); |
| |
| private: |
| typedef uint32_t rate_q10_t; // q10 means lower 10 bits are for fractions |
| |
| bool mWakelockHeld; |
| int32_t mWakeEventCount; |
| |
| void protectIfWakeEvent(int32_t sensor); |
| |
| static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) { |
| return 1024000000000ULL / period_ns; |
| } |
| |
| static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) { |
| if (frequency_q10) |
| return 1024000000000LL / frequency_q10; |
| else |
| return (nsecs_t)0; |
| } |
| |
| enum |
| { |
| CONFIG_CMD_DISABLE = 0, |
| CONFIG_CMD_ENABLE = 1, |
| CONFIG_CMD_FLUSH = 2, |
| CONFIG_CMD_CFG_DATA = 3, |
| CONFIG_CMD_CALIBRATE = 4, |
| }; |
| |
| struct ConfigCmd |
| { |
| uint32_t evtType; |
| uint64_t latency; |
| rate_q10_t rate; |
| uint8_t sensorType; |
| uint8_t cmd; |
| uint16_t flags; |
| uint8_t data[]; |
| } __attribute__((packed)); |
| |
| struct MsgCmd |
| { |
| uint32_t evtType; |
| struct HostHubRawPacket msg; |
| } __attribute__((packed)); |
| |
| struct SensorState { |
| uint64_t latency; |
| rate_q10_t rate; |
| uint8_t sensorType; |
| uint8_t alt; |
| uint8_t flushCnt; |
| bool enable; |
| }; |
| |
| struct FirstSample |
| { |
| uint8_t numSamples; |
| uint8_t numFlushes; |
| uint8_t highAccuracy : 1; |
| uint8_t biasPresent : 1; |
| uint8_t biasSample : 6; |
| uint8_t pad; |
| }; |
| |
| struct RawThreeAxisSample |
| { |
| uint32_t deltaTime; |
| int16_t ix, iy, iz; |
| } __attribute__((packed)); |
| |
| struct ThreeAxisSample |
| { |
| uint32_t deltaTime; |
| float x, y, z; |
| } __attribute__((packed)); |
| |
| struct OneAxisSample |
| { |
| uint32_t deltaTime; |
| union |
| { |
| float fdata; |
| uint32_t idata; |
| }; |
| } __attribute__((packed)); |
| |
| // The following structure should match struct HostIntfDataBuffer found in |
| // firmware/inc/hostIntf.h |
| struct nAxisEvent |
| { |
| uint32_t evtType; |
| union |
| { |
| struct |
| { |
| uint64_t referenceTime; |
| union |
| { |
| struct FirstSample firstSample; |
| struct OneAxisSample oneSamples[]; |
| struct RawThreeAxisSample rawThreeSamples[]; |
| struct ThreeAxisSample threeSamples[]; |
| }; |
| }; |
| uint8_t buffer[]; |
| }; |
| } __attribute__((packed)); |
| |
| static Mutex sInstanceLock; |
| static HubConnection *sInstance; |
| |
| // This lock is used for synchronization between the write thread (from |
| // sensorservice) and the read thread polling from the nanohub driver. |
| Mutex mLock; |
| |
| RingBuffer mRing; |
| |
| ActivityEventHandler *mActivityEventHandler; |
| |
| float mMagBias[3]; |
| uint8_t mMagAccuracy; |
| uint8_t mMagAccuracyRestore; |
| |
| float mGyroBias[3], mAccelBias[3]; |
| |
| SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1]; |
| |
| uint64_t mStepCounterOffset; |
| uint64_t mLastStepCount; |
| |
| int mFd; |
| int mInotifyPollIndex; |
| struct pollfd mPollFds[4]; |
| int mNumPollFds; |
| |
| sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor); |
| void magAccuracyUpdate(float x, float y, float z); |
| void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy); |
| void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy); |
| void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy); |
| void postOsLog(uint8_t *buf, ssize_t len); |
| ssize_t processBuf(uint8_t *buf, ssize_t len); |
| |
| void initConfigCmd(struct ConfigCmd *cmd, int handle); |
| |
| void queueDataInternal(int handle, void *data, size_t length); |
| |
| void discardInotifyEvent(); |
| void waitOnNanohubLock(); |
| |
| void initNanohubLock(); |
| |
| void restoreSensorState(); |
| void sendCalibrationOffsets(); |
| |
| // Enable SCHED_FIFO priority for main thread |
| void enableSchedFifoMode(); |
| |
| #ifdef LID_STATE_REPORTING_ENABLED |
| int mUinputFd; |
| |
| status_t initializeUinputNode(); |
| void sendFolioEvent(int32_t data); |
| #endif // LID_STATE_REPORTING_ENABLED |
| |
| #ifdef USB_MAG_BIAS_REPORTING_ENABLED |
| int mMagBiasPollIndex; |
| float mUsbMagBias; |
| |
| void queueUsbMagBias(); |
| #endif // USB_MAG_BIAS_REPORTING_ENABLED |
| |
| #ifdef DOUBLE_TOUCH_ENABLED |
| int mDoubleTouchPollIndex; |
| #endif // DOUBLE_TOUCH_ENABLED |
| |
| DISALLOW_EVIL_CONSTRUCTORS(HubConnection); |
| }; |
| |
| } // namespace android |
| |
| #endif // HUB_CONNECTION_H_ |