summaryrefslogtreecommitdiffstats
path: root/libsensors/akmdfs/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsensors/akmdfs/main.c')
-rw-r--r--libsensors/akmdfs/main.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/libsensors/akmdfs/main.c b/libsensors/akmdfs/main.c
new file mode 100644
index 0000000..a3df0bc
--- /dev/null
+++ b/libsensors/akmdfs/main.c
@@ -0,0 +1,293 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#include "AKFS_Common.h"
+#include "AKFS_Compass.h"
+#include "AKFS_Disp.h"
+#include "AKFS_FileIO.h"
+#include "AKFS_Measure.h"
+#include "AKFS_APIs.h"
+
+#ifndef WIN32
+#include <sched.h>
+#include <pthread.h>
+#include <linux/input.h>
+#endif
+
+#define ERROR_INITDEVICE (-1)
+#define ERROR_OPTPARSE (-2)
+#define ERROR_SELF_TEST (-3)
+#define ERROR_READ_FUSE (-4)
+#define ERROR_INIT (-5)
+#define ERROR_GETOPEN_STAT (-6)
+#define ERROR_STARTCLONE (-7)
+#define ERROR_GETCLOSE_STAT (-8)
+
+/* Global variable. See AKFS_Common.h file. */
+int g_stopRequest = 0;
+int g_opmode = 0;
+int g_dbgzone = 0;
+int g_mainQuit = AKD_FALSE;
+
+/* Static variable. */
+static pthread_t s_thread; /*!< Thread handle */
+
+/*!
+ A thread function which is raised when measurement is started.
+ @param[in] args This parameter is not used currently.
+ */
+static void* thread_main(void* args)
+{
+ AKFS_MeasureLoop();
+ return ((void*)0);
+}
+
+/*!
+ Signal handler. This should be used only in DEBUG mode.
+ @param[in] sig Event
+ */
+static void signal_handler(int sig)
+{
+ if (sig == SIGINT) {
+ ALOGE("SIGINT signal");
+ g_stopRequest = 1;
+ g_mainQuit = AKD_TRUE;
+ }
+}
+
+/*!
+ Starts new thread.
+ @return If this function succeeds, the return value is 1. Otherwise,
+ the return value is 0.
+ */
+static int startClone(void)
+{
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ g_stopRequest = 0;
+ if (pthread_create(&s_thread, &attr, thread_main, NULL) == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ This function parse the option.
+ @retval 1 Parse succeeds.
+ @retval 0 Parse failed.
+ @param[in] argc Argument count
+ @param[in] argv Argument vector
+ @param[out] layout_patno
+ */
+int OptParse(
+ int argc,
+ char* argv[],
+ AKFS_PATNO* layout_patno)
+{
+#ifdef WIN32
+ /* Static */
+#if defined(AKFS_WIN32_PAT1)
+ *layout_patno = PAT1;
+#elif defined(AKFS_WIN32_PAT2)
+ *layout_patno = PAT2;
+#elif defined(AKFS_WIN32_PAT3)
+ *layout_patno = PAT3;
+#elif defined(AKFS_WIN32_PAT4)
+ *layout_patno = PAT4;
+#elif defined(AKFS_WIN32_PAT5)
+ *layout_patno = PAT5;
+#else
+ *layout_patno = PAT1;
+#endif
+ g_opmode = OPMODE_CONSOLE;
+ /*g_opmode = 0;*/
+ g_dbgzone = AKMDATA_LOOP | AKMDATA_TEST;
+#else
+ int opt;
+ char optVal;
+
+ *layout_patno = PAT_INVALID;
+
+ while ((opt = getopt(argc, argv, "sm:z:")) != -1) {
+ switch(opt){
+ case 'm':
+ optVal = (char)(optarg[0] - '0');
+ if ((PAT1 <= optVal) && (optVal <= PAT8)) {
+ *layout_patno = (AKFS_PATNO)optVal;
+ AKMDEBUG(DBG_LEVEL2, "%s: Layout=%d\n", __FUNCTION__, optVal);
+ }
+ break;
+ case 's':
+ g_opmode |= OPMODE_CONSOLE;
+ break;
+ case 'z':
+ /* If error detected, hopefully 0 is returned. */
+ errno = 0;
+ g_dbgzone = (int)strtol(optarg, (char**)NULL, 0);
+ AKMDEBUG(DBG_LEVEL2, "%s: Dbg Zone=%d\n", __FUNCTION__, g_dbgzone);
+ break;
+ default:
+ ALOGE("%s: Invalid argument", argv[0]);
+ return 0;
+ }
+ }
+
+ /* If layout is not specified with argument, get parameter from driver */
+ if (*layout_patno == PAT_INVALID) {
+ int16_t n;
+ if (AKD_GetLayout(&n) == AKM_SUCCESS) {
+ if ((PAT1 <= n) && (n <= PAT8)) {
+ *layout_patno = (AKFS_PATNO)n;
+ }
+ }
+ }
+ /* Error */
+ if (*layout_patno == PAT_INVALID) {
+ ALOGE("No layout is specified.");
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
+void ConsoleMode(void)
+{
+ /*** Console Mode *********************************************/
+ while (AKD_TRUE) {
+ /* Select operation */
+ switch (Menu_Main()) {
+ case MODE_SelfTest:
+ AKFS_SelfTest();
+ break;
+ case MODE_Measure:
+ /* Reset flag */
+ g_stopRequest = 0;
+ /* Measurement routine */
+ AKFS_MeasureLoop();
+ break;
+
+ case MODE_Quit:
+ return;
+
+ default:
+ AKMDEBUG(DBG_LEVEL0, "Unknown operation mode.\n");
+ break;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int retValue = 0;
+ AKFS_PATNO pat;
+ uint8 regs[3];
+
+ /* Show the version info of this software. */
+ Disp_StartMessage();
+
+#if ENABLE_AKMDEBUG
+ /* Register signal handler */
+ signal(SIGINT, signal_handler);
+#endif
+
+ /* Open device driver */
+ if(AKD_InitDevice() != AKD_SUCCESS) {
+ retValue = ERROR_INITDEVICE;
+ goto MAIN_QUIT;
+ }
+
+ /* Parse command-line options */
+ /* This function calls device driver function to get layout */
+ if (OptParse(argc, argv, &pat) == 0) {
+ retValue = ERROR_OPTPARSE;
+ goto MAIN_QUIT;
+ }
+
+ /* Self Test */
+ if (g_opmode & OPMODE_FST){
+ if (AKFS_SelfTest() != AKD_SUCCESS) {
+ retValue = ERROR_SELF_TEST;
+ goto MAIN_QUIT;
+ }
+ }
+
+ /* OK, then start */
+ if (AKFS_ReadAK8975FUSEROM(regs) != AKM_SUCCESS) {
+ retValue = ERROR_READ_FUSE;
+ goto MAIN_QUIT;
+ }
+
+ /* Initialize library. */
+ if (AKFS_Init(pat, regs) != AKM_SUCCESS) {
+ retValue = ERROR_INIT;
+ goto MAIN_QUIT;
+ }
+
+ /* Start console mode */
+ if (g_opmode & OPMODE_CONSOLE) {
+ ConsoleMode();
+ goto MAIN_QUIT;
+ }
+
+ /*** Start Daemon ********************************************/
+ while (g_mainQuit == AKD_FALSE) {
+ int st = 0;
+ /* Wait until device driver is opened. */
+ if (AKD_GetOpenStatus(&st) != AKD_SUCCESS) {
+ retValue = ERROR_GETOPEN_STAT;
+ goto MAIN_QUIT;
+ }
+ if (st == 0) {
+ ALOGI("Suspended.");
+ } else {
+ ALOGI("Compass Opened.");
+ /* Reset flag */
+ g_stopRequest = 0;
+ /* Start measurement thread. */
+ if (startClone() == 0) {
+ retValue = ERROR_STARTCLONE;
+ goto MAIN_QUIT;
+ }
+
+ /* Wait until device driver is closed. */
+ if (AKD_GetCloseStatus(&st) != AKD_SUCCESS) {
+ retValue = ERROR_GETCLOSE_STAT;
+ g_mainQuit = AKD_TRUE;
+ }
+ /* Wait thread completion. */
+ g_stopRequest = 1;
+ pthread_join(s_thread, NULL);
+ ALOGI("Compass Closed.");
+ }
+ }
+
+MAIN_QUIT:
+
+ /* Release library */
+ AKFS_Release();
+ /* Close device driver. */
+ AKD_DeinitDevice();
+ /* Show the last message. */
+ Disp_EndMessage(retValue);
+
+ return retValue;
+}
+
+