Merge "[Bugfix][ZXW-161] Modify the default system time configuration."
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
index 2ba0f08..44be59c 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
@@ -187,6 +187,7 @@
         liblynq-qser-network \
         liblynq-qser-gnss \
         liblynq-qser-fota \
+        liblynq-qser-audio \
         libpoweralarm \
         liblynq-systime \
         liblynq-autosuspend \
@@ -275,6 +276,7 @@
         lynq-gpio-demo \
         lynq-irq-demo \
         lynq-gnss-update \
+        lynq-audio-demo \
         "
 
 zxic_app_open += "${@bb.utils.contains('CONFIG_TEL_API_SUPPORT', 'RIL', 'rild', '', d)}"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-audio/liblynq-qser-audio.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-audio/liblynq-qser-audio.bb
new file mode 100755
index 0000000..59d21db
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-audio/liblynq-qser-audio.bb
@@ -0,0 +1,58 @@
+#inherit externalsrc package
+
+DESCRIPTION = "liblynq-qser-audio.so "
+SECTION = "base"
+#LICENSE = "Mobiletek""
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=4f60c98fa94e02f659ef5939f67fa8ae"
+DEPENDS += "bootchart  liblynq-log libupi-ab openssl libmedia"
+
+#inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-qser-audio/"
+
+FILESEXTRAPATHS_prepend :="${TOPDIR}/../src/lynq/lib/:"
+SRC_URI = " \
+          file://liblynq-qser-audio \
+          "
+
+SRC-DIR = "${S}/../liblynq-qser-audio"
+TARGET_CC_ARCH += "${LDFLAGS}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+
+#Parameters passed to do_compile()
+
+FILES_${PN} = "${base_libdir}/*.so "
+
+
+FILES_${PN}-dev = "/test \
+                   ${includedir}"
+
+FILES_${PN}-doc = "/doc"
+
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+                  ${base_libdir}/.debug \
+                  ${base_sbindir}/.debug"
+
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu"
+}
+
+do_install () {
+    oe_runmake install -C ${SRC-DIR} ROOT=${D}
+	
+    if [ -d "${WORKONSRC}" ] ; then
+        install -d ${D}${includedir}/
+        cp -af ${SRC-DIR}/include/ ${D}${includedir}/
+    fi 
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/LICENSE b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/LICENSE
new file mode 100755
index 0000000..cb88533
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("Mobiletek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to Mobiletek Inc. and/or its licensors. Without
+the prior written permission of Mobiletek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of Mobiletek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+Mobiletek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("Mobiletek SOFTWARE")
+RECEIVED FROM Mobiletek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. Mobiletek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES Mobiletek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE Mobiletek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN Mobiletek
+SOFTWARE. Mobiletek SHALL ALSO NOT BE RESPONSIBLE FOR ANY Mobiletek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND Mobiletek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE Mobiletek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT Mobiletek'S OPTION, TO REVISE OR REPLACE THE
+Mobiletek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO Mobiletek FOR SUCH Mobiletek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/lynq-audio-demo.cpp b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/lynq-audio-demo.cpp
new file mode 100755
index 0000000..eb557f6
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/lynq-audio-demo.cpp
@@ -0,0 +1,138 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <include/lynq-qser-audio.h>
+
+extern sc_audio_handle_t playback_handle;
+
+void player_cmd_proc(char *cmdstr)
+{
+    if (strcmp(cmdstr, "P\n") == 0)
+    {
+        qser_AudPlayer_Pause(playback_handle);
+    }
+    else if (strcmp(cmdstr, "R\n") == 0)
+    {
+        qser_AudPlayer_Resume(playback_handle);
+    }
+    else if (strcmp(cmdstr, "T\n") == 0)
+    {
+        qser_AudPlayer_Stop(playback_handle);
+    }
+    else
+    {
+        printf("Unknown command: %s", cmdstr);
+    }
+}
+
+void capture_cmd_proc(char *cmdstr)
+{
+    if (strcmp(cmdstr, "P\n") == 0)
+    {
+        qser_AudRecorder_Pause();
+    }
+    else if (strcmp(cmdstr, "R\n") == 0)
+    {
+        qser_AudRecorder_Resume();
+    }
+    else if (strcmp(cmdstr, "T\n") == 0)
+    {
+        qser_AudRecorder_Stop();
+    }
+    else
+    {
+        printf("Unknown command: %s", cmdstr);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    if (argc < 3)
+    {
+        printf("Usage: %s <play|recd> <file>\n", argv[0]);
+        return 1;
+    }
+
+    const char *action = argv[1];
+    const char *file = argv[2];
+
+    int g_audio_owner_id = 0;
+    char player_device[] = "device1";
+    char recorder_device[] = "device2";
+    char cmdstr[256];
+
+    _cb_onPlayer cb_fun = [](int result)
+    {
+        if (result == 0)
+        {
+            printf("Audio recorder opened successfully.\n");
+        }
+        else
+        {
+            printf("Failed to open audio recorder, error code: %d\n", result);
+        }
+    };
+
+    if (strcmp(action, "play") == 0)
+    {
+        int player_open_result = qser_AudPlayer_Open(player_device, cb_fun);
+        if (player_open_result != 0)
+        {
+            printf("Failed to open audio player.\n");
+            return 1;
+        }
+
+        qser_AudPlayer_PlayFrmFile(g_audio_owner_id, file, 0);
+
+        while (1)
+        {
+            printf("Please input a player command (P/R/T/exit) :\n");
+            if (fgets(cmdstr, sizeof(cmdstr), stdin) != NULL)
+            {
+                if (strcmp(cmdstr, "exit\n") == 0)
+                {
+                    qser_AudPlayer_Close(playback_handle);
+                    break;
+                }
+                player_cmd_proc(cmdstr);
+            }
+        }
+
+        qser_AudPlayer_Close(playback_handle);
+    }
+    else if (strcmp(action, "recd") == 0)
+    {
+        int recorder_open_result = qser_AudRecorder_Open(recorder_device, cb_fun);
+        if (recorder_open_result != 0) {
+            printf("Failed to open audio recorder.\n");
+            return 1;
+        }
+
+        qser_AudRecorder_StartRecord(g_audio_owner_id, file, 0);
+
+        while (1)
+        {
+            printf("Please input a player command (P/R/T/exit) :\n");
+            if (fgets(cmdstr, sizeof(cmdstr), stdin) != NULL)
+            {
+                if (strcmp(cmdstr, "exit\n") == 0)
+                {
+                    qser_AudRecorder_Close();
+                    break;
+                }
+                capture_cmd_proc(cmdstr);
+            }
+        }
+        qser_AudRecorder_Close();
+    }
+    else
+    {
+        printf("Unknown action: %s\n", action);
+        return 1;
+    }
+
+    qser_Audio_Deinit();
+
+    return 0;
+}
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/makefile b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/makefile
new file mode 100755
index 0000000..c37eeaa
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/files/makefile
@@ -0,0 +1,51 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fpermissive \
+
+ifeq ($(strip $(TARGET_PLATFORM)), T106)
+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1 -DHAVE_ENDIAN_H -DHAVE_PTHREADS -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP -DHAVE_STRLCPY -DHAVE_PRCTL -DHAVE_MEMSET16 -DHAVE_MEMSET32 -DANDROID_SMP=0
+endif
+
+LOCAL_CFLAGS += -Werror=format-security
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir),)
+
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include/ \
+  -I$(ROOT)$(includedir)/ \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -lpthread \
+    -llynq-qser-audio \
+
+SOURCES = lynq-audio-demo.cpp
+
+EXECUTABLE = lynq-audio-demo
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+all: $(EXECUTABLE) 
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
+	$(RM) $(OBJECTS_TOOL) $(EXECUTABLE)
+
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/lynq-audio-demo.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/lynq-audio-demo.bb
new file mode 100644
index 0000000..2260b19
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/lynq-audio-demo/lynq-audio-demo.bb
@@ -0,0 +1,31 @@
+#inherit externalsrc package
+#inherit externalsrc package systemd
+DESCRIPTION = "lynq-audio-demo"
+LICENSE = "CLOSED"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b1e07e8d88e26263e71d3a9e2aa9a2ff"
+SRC_URI = "file://lynq-audio-demo.cpp \
+           file://makefile \
+"
+DEPENDS += "liblynq-qser-audio"
+
+SRC-DIR = "${S}/../lynq-audio-demo"
+FILES_${PN} += "${bindir}/"
+TARGET_CC_ARCH += "${LDFLAGS}"
+SYSTEMD_PACKAGES = "${PN}"
+S = "${WORKDIR}"
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+	if test "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" || test "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4"; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -mhard-float"
+	else
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST}"
+	fi
+}
+
+
+do_install() {
+
+	install -d ${D}${bindir}/
+	install -m 0755 ${S}/lynq-audio-demo ${D}${bindir}/
+}
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE
new file mode 100644
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h
new file mode 100644
index 0000000..cc37b2e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h
@@ -0,0 +1,45 @@
+/*******************************************************
+* 
+* @brief: Add audio api
+* @details:  add liblynq-qser-audio api
+* @author:   yu.dong
+* @date:     2023.9.28
+* @version:  V1.0
+* @copyright:Copyright (c) MobileTek
+*
+*********************************************/
+#ifndef LYNQ_QSER_AUDIO
+#define LYNQ_QSER_AUDIO
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sc_audio.h"
+
+sc_audio_handle_t playback_handle = SC_AUDIO_INVALID_HANDLE;
+sc_audio_handle_t capture_handle = SC_AUDIO_INVALID_HANDLE;
+
+typedef void (*_cb_onPlayer)(int);
+
+int qser_AudPlayer_Open(char* device, _cb_onPlayer cb_fun);
+int qser_AudPlayer_PlayFrmFile(int hdl, const char *fd, int offset);
+int qser_AudPlayer_Pause(int hdl);
+int qser_AudPlayer_Resume(int hdl);
+void qser_AudPlayer_Stop(int hdl);
+void qser_AudPlayer_Close(int hdl);
+
+int qser_AudRecorder_Open(char* device, _cb_onPlayer cb_fun);
+int qser_AudRecorder_StartRecord(int hdl, const char *fd, int offset);
+int qser_AudRecorder_Pause(void);
+int qser_AudRecorder_Resume(void);
+void qser_AudRecorder_Stop(void);
+void qser_AudRecorder_Close(void);
+
+void qser_Audio_Deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp
new file mode 100644
index 0000000..70b4e43
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp
@@ -0,0 +1,546 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "liblog/lynq_deflog.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sc_audio.h"
+#include "lynq-qser-audio.h"
+
+#define AUDIO_INIT_MAX_TRY_CNT 100
+
+#define SC_AUDIO_BE_DAI_MIN -1
+#define SC_AUDIO_STREAM_FORMAT_INVALID 0
+
+/********************************************************************
+* @brief: _cb_onPlayer, typedef for a callback function that is called
+          when an audio operation is performed
+* @param int [IN]: The result of the audio operation, 0 if successful, non-zero if failed
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+typedef void (*_cb_onPlayer)(int);
+
+/********************************************************************
+* @brief: playback_state_cb, callback function that is called when the audio playback state changes
+* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
+* @param params [IN]: void*, parameters for the callback function
+* @param state [IN]: sc_audio_playback_state_e, the current state of audio playback
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int playback_state_cb (sc_audio_handle_t handle, void *params, sc_audio_playback_state_e state)
+{
+    LYINFLOG("playback_state_cb handle:0x%lx state:%d\n", handle, state);
+    return 0;
+}
+
+/********************************************************************
+* @brief: capture_state_cb, callback function that is called when the audio capture state changes
+* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
+* @param params [IN]: void*, parameters for the callback function
+* @param state [IN]: sc_audio_capture_state_e, the current state of audio capture
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int capture_state_cb (sc_audio_handle_t handle, void *params, sc_audio_capture_state_e state)
+{
+    LYINFLOG("capture_state_cb handle:0x%lx state:%d\n", handle, state);
+
+    return 0;
+}
+
+/********************************************************************
+* @brief: get_device_enum, function to convert a device string to its corresponding enum
+* @param device [IN]: const char*, the name of the device
+* @return : sc_audio_fe_pcm_dev_e, the enum corresponding to the device name
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+sc_audio_fe_pcm_dev_e get_device_enum(const char* device)
+{
+    if (strcmp(device, "device1") == 0)
+    {
+        return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1;
+    }
+    else if (strcmp(device, "device2") == 0)
+    {
+        return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2;
+    }
+    else
+    {
+        return SC_AUDIO_INVALID_HANDLE;
+    }
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Open, open the audio device for playback
+* @param device [IN]: char* device, the audio device to be opened for playback
+* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Open(char* device, _cb_onPlayer cb_fun)
+{
+    int ret = SC_ERR_SUCCESS;
+    int retry_cnt = 0;
+    int audio_is_init = 0;
+
+    sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
+
+    while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
+    {
+        ret = sc_audio_init();
+        if (SC_ERR_NOT_READY == ret)
+        {
+            LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
+            usleep(200 * 1000);
+            retry_cnt++;
+        }
+        else if (SC_ERR_SUCCESS == ret)
+        {
+            LYINFLOG("Success to initialize audio service\n");
+            audio_is_init = 1;
+            break;
+        }
+        else
+        {
+            LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
+            break;
+        }
+    }
+    if (1 != audio_is_init)
+    {
+        LYINFLOG("Failed to initialize audio service\n");
+        if (cb_fun != NULL)
+        {
+            cb_fun(-1);
+        }
+        return -1;
+    }
+
+    sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
+    if (SC_AUDIO_INVALID_HANDLE == device_handle)
+    {
+        LYINFLOG("Failed to open device: %s\n", device);
+        if (cb_fun != NULL)
+        {
+            cb_fun(-1);
+        }
+        return -1;
+    }
+
+    if (cb_fun != NULL)
+    {
+        cb_fun(0);
+    }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_PlayFrmFile, play audio from file
+* @param hdl [IN]: int, handle for the audio device or stream
+* @param fd [IN]: const char*, file descriptor of the audio file
+* @param offset [IN]: int, offset in the audio file
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_PlayFrmFile(int hdl, const char *fd, int offset)
+{
+    int error_line;
+    sc_audio_pcm_config_t pcm_config;
+    int ret = 0;
+    sc_audio_owner_id owner_id = hdl;
+
+    if(NULL== fd || 0 == strlen(fd))
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    playback_handle = sc_audio_playback_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2,SC_AUDIO_FE_PCM_DEV_MIN,owner_id);
+    if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    if(strlen(fd))
+    {
+        ret = sc_audio_playback_file_prepare(playback_handle, fd, NULL, playback_state_cb, NULL);
+        if (SC_ERR_SUCCESS != ret)
+        {
+            error_line = __LINE__;
+            goto exit;
+        }
+    }
+
+    ret = sc_audio_playback_play(playback_handle);
+    if (SC_ERR_SUCCESS != ret)
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    return 0;
+exit:
+    LYINFLOG("qser_AudPlayer_PlayFrmFile error_line=%d\n",error_line);
+    return -1;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Pause, pause the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Pause(int hdl)
+{
+    if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+    {
+        LYINFLOG("qser_AudPlayer_Pause handle is invalid.\n");
+        return -1;
+    }
+    if( sc_audio_playback_pause(playback_handle))
+    {
+	LYINFLOG("qser_AudPlayer_Pause sc_audio_playback_pause fail.\n");
+        return -1;
+    }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Resume, resume the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Resume(int hdl)
+{
+    if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+    {
+        LYINFLOG("qser_AudPlayer_Resume handle is invalid.\n");
+        return -1;
+    }
+    if( sc_audio_playback_resume(playback_handle))
+    {
+        LYINFLOG("qser_AudPlayer_Resume sc_audio_playback_resume fail.\n");
+        return -1;
+   }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Stop, stop the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudPlayer_Stop(int hdl)
+{
+    if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+    {
+	LYINFLOG("qser_AudPlayer_Stop handle is invalid.\n");
+	return;
+    }
+
+    if( sc_audio_playback_stop(playback_handle))
+    {
+        LYINFLOG("qser_AudPlayer_Stop sc_audio_playback_stop fail.\n");
+        return;
+    }
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Close, close the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudPlayer_Close(int hdl)
+{
+    if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+    {
+        LYINFLOG("qser_AudPlayer_Close handle is invalid.\n");
+        return;
+    }
+    if( sc_audio_playback_stop(playback_handle))
+    {
+        LYINFLOG("qser_AudPlayer_Close sc_audio_playback_stop fail.\n");
+        return;
+    }
+    if( sc_audio_playback_close(playback_handle))
+    {
+        LYINFLOG("qser_AudPlayer_Close sc_audio_playback_close fail.\n");
+        return;
+    }
+
+    playback_handle = SC_AUDIO_INVALID_HANDLE;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Open, open the audio device for recording
+* @param device [IN]: char* device, the audio device to be opened for recording
+* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Open(char* device, _cb_onPlayer cb_fun)
+{
+    int ret = SC_ERR_SUCCESS;
+    int retry_cnt = 0;
+    int audio_is_init = 0;
+
+    sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
+
+    while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
+    {
+        ret = sc_audio_init();
+        if (SC_ERR_NOT_READY == ret)
+        {
+            LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
+            usleep(200 * 1000);
+            retry_cnt++;
+        }
+        else if (SC_ERR_SUCCESS == ret)
+        {
+            LYINFLOG("Success to initialize audio service\n");
+            audio_is_init = 1;
+            break;
+        }
+        else
+        {
+            LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
+            break;
+        }
+    }
+    if (1 != audio_is_init)
+    {
+        LYINFLOG("Failed to initialize audio service\n");
+        if (cb_fun != NULL)
+        {
+            cb_fun(-1);
+        }
+        return -1;
+    }
+
+    sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
+    if (SC_AUDIO_INVALID_HANDLE == device_handle)
+    {
+        LYINFLOG("Failed to open device: %s\n", device);
+        if (cb_fun != NULL)
+        {
+            cb_fun(-1);
+        }
+        return -1;
+    }
+
+    if (cb_fun != NULL)
+    {
+        cb_fun(0);
+    }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_StartRecord, play a file with capture
+* @param hdl [IN]: int, handle for the audio device or stream
+* @param fd [IN]: const char*, file descriptor of the audio file
+* @param offset [IN]: int, offset in the audio file
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_StartRecord(int hdl, const char *fd, int offset)
+{
+    int error_line;
+    sc_audio_pcm_config_t pcm_config;
+    int ret = 0;
+    sc_audio_owner_id owner_id = hdl;
+
+    if(NULL== fd || 0 == strlen(fd))
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    capture_handle = sc_audio_capture_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1,SC_AUDIO_BE_DAI_MIN);
+    if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    memset(&pcm_config, 0, sizeof(sc_audio_pcm_config_t));
+
+    ret = sc_audio_capture_file_prepare(capture_handle, fd, SC_AUDIO_STREAM_FORMAT_INVALID, NULL, capture_state_cb, NULL);
+    if (SC_ERR_SUCCESS != ret)
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    ret = sc_audio_capture_record(capture_handle);
+    if (SC_ERR_SUCCESS != ret)
+    {
+        error_line = __LINE__;
+        goto exit;
+    }
+
+    return 0;
+exit:
+    LYINFLOG("qser_AudRecorder_StartRecord error_line=%d\n",error_line);
+    return -1;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Pause, pause the audio capture
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Pause(void)
+{
+    if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+    {
+        LYINFLOG("qser_AudRecorder_Pause capture_handle is invalid.\n");
+        return -1;
+    }
+    if( sc_audio_capture_pause(capture_handle))
+    {
+	LYINFLOG("qser_AudRecorder_Pause sc_audio_capture_pause fail.\n");
+	return -1;
+    }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Resume, resume the audio capture
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Resume(void)
+{
+    if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+    {
+        LYINFLOG("qser_AudRecorder_Resume capture_handle is invalid.\n");
+        return -1;
+    }
+    if( sc_audio_capture_resume(capture_handle))
+    {
+        LYINFLOG("qser_AudRecorder_Resume sc_audio_capture_resume fail.\n");
+        return -1;
+    }
+    return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Stop, stop the audio capture
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudRecorder_Stop(void)
+{
+    if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+    {
+        LYINFLOG("qser_AudRecorder_Stop capture_handle is invalid.\n");
+        return;
+    }
+    if( sc_audio_capture_stop(capture_handle))
+    {
+        LYINFLOG("qser_AudRecorder_Stop sc_audio_capture_stop fail.\n");
+        return;
+    }
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Close, close the audio capture
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudRecorder_Close(void)
+{
+    if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+    {
+        LYINFLOG("qser_AudRecorder_Close capture_handle is invalid.\n");
+        return;
+    }
+    if( sc_audio_capture_stop(capture_handle))
+    {
+        LYINFLOG("qser_AudRecorder_Close sc_audio_capture_stop fail.\n");
+        return;
+    }
+    if( sc_audio_capture_close(capture_handle))
+    {
+        LYINFLOG("qser_AudRecorder_Close sc_audio_capture_close fail.\n");
+        return;
+    }
+
+    capture_handle = SC_AUDIO_INVALID_HANDLE;
+}
+
+/********************************************************************
+* @brief: qser_Audio_Deinit, deinitialize the audio system, stop and close any active playback or capture,
+          and uninitialize the audio system
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_Audio_Deinit(void)
+{
+    if(SC_AUDIO_INVALID_HANDLE != playback_handle)
+    {
+        sc_audio_playback_stop(playback_handle);
+        sc_audio_playback_close(playback_handle);
+        playback_handle = SC_AUDIO_INVALID_HANDLE;
+    }
+
+    if(SC_AUDIO_INVALID_HANDLE != capture_handle)
+    {
+        sc_audio_capture_stop(capture_handle);
+        sc_audio_capture_close(capture_handle);
+        capture_handle = SC_AUDIO_INVALID_HANDLE;
+    }
+
+    sc_audio_uninit();
+}
+
+DEFINE_LYNQ_LIB_LOG(LYNQ_AUDIO)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile
new file mode 100644
index 0000000..cef3517
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile
@@ -0,0 +1,48 @@
+SHELL = /bin/sh

+RM = rm -f

+

+LOCAL_CFLAGS := -Wall \

+                -std=gnu++14 \

+                -g -Os \

+                -flto \

+                -fPIC \

+                -fpermissive \

+

+LOCAL_PATH   = .

+

+LOCAL_C_INCLUDES = \

+  -I. \

+  -I$(LOCAL_PATH)/include \

+  -I$(LOCAL_PATH)/ \

+  -I$(ROOT)$(includedir)/logger \

+  -I$(ROOT)$(includedir)/liblog \

+

+LOCAL_LIBS := \

+    -L. \

+    -ldl \

+    -lstdc++ \

+    -llynq-log \

+    -lmedia \

+

+SOURCES = lynq-qser-audio.cpp

+LIBRARY = liblynq-qser-audio.so

+

+OBJECTS=$(SOURCES:.cpp=.o)

+

+all: $(LIBRARY)

+

+$(LIBRARY): $(OBJECTS)

+	$(CXX) -shared -o $@ $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES)

+

+%.o : %.cpp

+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -fPIC -c $<

+

+install:

+	mkdir -p $(ROOT)$(base_libdir)/

+	install $(LIBRARY) $(ROOT)$(base_libdir)/

+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk

+

+clean:

+	$(RM) $(OBJECTS) $(LIBRARY)

+

+

diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
index dfced9c..d512dc1 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/include/mbtk_gnss_internal.h
@@ -7,7 +7,6 @@
 extern "C" {
 #endif
 
-
 /*
 GGA: GNSS 定位数据
 $GNGGA,,,,,,0,00,99.99,,,,,,*56
@@ -272,12 +271,13 @@
 
 
 
+
 static struct mopen_gnss_device_info_t mopen_gnss_device_info;
 static struct mbtk_gnss_handle_t *mbtk_gnss_handle = NULL;
 static int firmware_extren_state = 0;
 
 static char g_no_sv = 0;// 参与定位的卫星数量
-
+extern int gpio21_value;
 int mopen_gnss_get_nmea_config(uint32 h_gnss);
 int mopen_gnss_get_ant_state_info(uint32 h_gnss);
 
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
index 326f697..8884a7a 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/lynq_qser_gnss.cpp
@@ -132,7 +132,6 @@
     lynq_gnss_get_aidinfo(h_gnss);
     return 0;
 }
-
 int qser_Gnss_Start(uint32_t h_gnss)
 {
     struct mbtk_gnss_handle_t *gnss_handle = (struct mbtk_gnss_handle_t *)h_gnss;
@@ -143,10 +142,22 @@
     g_gnss_sync_done = 0;
 
     lynq_open_gps(1);
-    ret = set_baudrate(gnss_handle->dev_fd, B9600);
-    if(-1 == ret)
+    ALOGE("GNSS_VALUE: %d\n",gpio21_value);
+    if(gpio21_value == 1)
     {
-        return  -2;
+        ret = set_baudrate(gnss_handle->dev_fd, B115200);
+        if(-1 == ret)
+        {
+            return  -2;
+        }
+    }
+    else if(gpio21_value == 0)
+    {
+        ret = set_baudrate(gnss_handle->dev_fd, B9600);
+        if(-1 == ret)
+        {
+            return  -2;
+        }
     }
     return 0;
 }
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
index 7afec28..e7dba8f 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
@@ -890,14 +890,37 @@
 
     return -1;
 }
-
-#define GPS_DEV "/sys/devices/soc.0/d4000000.apb/mbtk-dev-op/gps_power"
-
+int gpio21_value = -1;
 int lynq_open_gps(int state)
 {
-    char cmd[128] = "echo '86' > /sys/class/gpio/export && cd /sys/class/gpio/gpio86";
     int ret;
+    int cn_enable = 86;
+    int eur_enable = 84;
+    int eur_boot = 15;
+    char compare_buf[256] = {0};
+    const char* compare_cmd = "echo '21' > /sys/class/gpio/export && cat /sys/class/gpio/gpio21/value";
+    exec_cmd(compare_cmd,compare_buf);
+    gpio21_value = (compare_buf[0] - '0');
+    const char*compare_cmd2 = "echo '21' > /sys/class/gpio/unexport";
+    exec_cmd(compare_cmd2,NULL);
 
+     /*this is CN GPIO*/
+    char CN_Enable[128];
+    sprintf(CN_Enable,"echo '%d' > /sys/class/gpio/export && cd /sys/class/gpio/gpio%d", cn_enable,cn_enable);
+
+     /*this is Europe GPIO*/
+    char Eur_Boot[128];
+    sprintf(Eur_Boot,"echo '%d' > /sys/class/gpio/export && cd /sys/class/gpio/gpio%d", eur_boot,eur_boot);
+    char Eur_Enable[128];
+    sprintf(Eur_Enable,"echo '%d' > /sys/class/gpio/export && cd /sys/class/gpio/gpio%d", eur_enable,eur_enable);
+
+    char CN_Enable_unexport[128];
+    sprintf(CN_Enable_unexport,"echo '%d' > /sys/class/gpio/unexport", cn_enable);
+    char Eur_Boot_unexport[128];
+    sprintf(Eur_Boot_unexport,"echo '%d' > /sys/class/gpio/unexport", eur_boot);
+    char Eur_Enable_unexport[128];
+    sprintf(Eur_Enable_unexport,"echo '%d' > /sys/class/gpio/unexport", eur_enable);
+    
     if(0 == state)
     {
         nmea_state = 0;
@@ -909,35 +932,107 @@
             }
             usleep(10000);
         }
-        ret = exec_cmd(cmd,NULL);
-        if(0 != ret)
+
+        if(gpio21_value == 1)
         {
-            printf("stop fail %x\n", ret);
+            ret = exec_cmd(Eur_Boot,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+            ret = exec_cmd(Eur_Enable,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+            
         }
-        char cmd2[128] = "echo '0' > /sys/class/gpio/gpio86/value && echo '86' > /sys/class/gpio/unexport";
-        ret = exec_cmd(cmd2,NULL);
-        if(0 != ret)
+        else if(gpio21_value == 0)
         {
-            printf("stop fail %x\n", ret);
-        }   
+            ret = exec_cmd(CN_Enable,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+        }
+
+        const char* CN_Enable2 = "echo '0' > /sys/class/gpio/gpio86/value";
+        char Eur_Boot2[128];
+        sprintf(Eur_Boot2,"echo 'out' > /sys/class/gpio/gpio%d/direction && echo '0' > /sys/class/gpio/gpio%d/value",eur_boot,eur_boot);
+        char Eur_Enable2[128];
+        sprintf(Eur_Enable2,"echo 'out' > /sys/class/gpio/gpio%d/direction && echo '0' > /sys/class/gpio/gpio%d/value",eur_enable,eur_enable);
+        if(gpio21_value == 1)
+        {
+            exec_cmd(Eur_Boot2,NULL);
+            exec_cmd(Eur_Enable2,NULL);
+            exec_cmd(Eur_Boot_unexport,NULL);
+            exec_cmd(Eur_Enable_unexport,NULL);
+            
+        }
+        else if(gpio21_value == 0)
+        {
+            ret = exec_cmd(CN_Enable2,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+            ret = exec_cmd(CN_Enable_unexport,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+        }
     }
 
-    if(1 == state)
+    else if(1 == state)
     {
         nmea_state = 1;
-
-        ret = exec_cmd(cmd,NULL);
-        if(0 != ret)
+        if(gpio21_value == 1)
         {
-            printf("start fail %x\n", ret);
-            return -1;
+            ret = exec_cmd(Eur_Boot,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+            ret = exec_cmd(Eur_Enable,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
         }
-        char cmd3[128] = "echo '1' > /sys/class/gpio/gpio86/value && echo '86' > /sys/class/gpio/unexport";
-        ret = exec_cmd(cmd3,NULL);
-        if(0 != ret)
+        else if(gpio21_value == 0)
         {
-            printf("start fail %x\n", ret);
-            return -1;
+            ret = exec_cmd(CN_Enable,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+        }
+        char CN_Enable3[128] = "echo '1' > /sys/class/gpio/gpio86/value";
+        char Eur_Boot3[128];
+        sprintf(Eur_Boot3,"echo 'out' > /sys/class/gpio/gpio%d/direction && echo '1' > /sys/class/gpio/gpio%d/value",eur_boot,eur_boot);
+        char Eur_Enable3[128];
+        sprintf(Eur_Enable3,"echo 'out' > /sys/class/gpio/gpio%d/direction && echo '1' > /sys/class/gpio/gpio%d/value",eur_enable,eur_enable);
+        if(gpio21_value == 1)
+        {
+            exec_cmd(Eur_Boot3,NULL);
+            exec_cmd(Eur_Enable3,NULL);
+            exec_cmd(Eur_Boot_unexport,NULL);
+            exec_cmd(Eur_Enable_unexport,NULL);
+            
+        }
+        else if(gpio21_value == 0)
+        {
+            ret = exec_cmd(CN_Enable3,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
+            ret = exec_cmd(CN_Enable_unexport,NULL);
+            if(ret < 0)
+            {
+                return -1;
+            }
         }
     }
     return 0;
@@ -1495,9 +1590,11 @@
     {
         if(fgets(buffer, 256, pipe))
         {
+            result[0] = buffer[0];
             memset(buffer, 0, sizeof(buffer));
         }
     }
+    
     pclose(pipe);
     return 0;
 }
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
index 7a57181..29f581a 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
@@ -596,13 +596,13 @@
 
 			/* interrupts:  */		
 			interrupts = <GIC_SPI SD1_INT IRQ_TYPE_LEVEL_HIGH>,
-						<GIC_SPI SD1_DATA1_INT IRQ_TYPE_LEVEL_HIGH>,
-						<GIC_SPI EX4_INT IRQ_TYPE_LEVEL_HIGH>;
+						<GIC_SPI SD1_DATA1_INT IRQ_TYPE_LEVEL_HIGH>/*,
+						<GIC_SPI EX4_INT IRQ_TYPE_LEVEL_HIGH>*/; //jb.qi change for irq 4 fail
 			clocks = <&clkc SD1_WCLK>, <&clkc SD1_HCLK>, <&clkc SD1_CDET>;
 			clock-names = "ciu", "biu","mmc_cdet";	
 
 			//cd-gpios = <&bgpio 51 GPIO_ACTIVE_LOW>;
-			gpios = <&bgpio 51 GPIO_ACTIVE_LOW>,<&bgpio 85 GPIO_ACTIVE_LOW>;//cd ,emmc en
+			gpios = /*<&bgpio 51 GPIO_ACTIVE_LOW>,*/<&bgpio 85 GPIO_ACTIVE_LOW>;//jb.qi add for irq 4 fail
 			pinctrl-names = "mmc_pins" ,"mmc_cd_int","mmc_cd_gpio","mmc_vcc_en";
 			pinctrl-0 = <&sd1_sd1>;
 			pinctrl-1 = <&sd1_cd_int>;