[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/connectivity/combo_tool/combo_loader/Android.mk b/src/connectivity/combo_tool/combo_loader/Android.mk
new file mode 100755
index 0000000..d0f51a2
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/Android.mk
@@ -0,0 +1,101 @@
+# Copyright Statement:
+#
+# This software/firmware and related documentation ("MediaTek Software") are
+# protected under relevant copyright laws. The information contained herein
+# is confidential and proprietary to MediaTek Inc. and/or its licensors.
+# Without the prior written permission of MediaTek inc. and/or its licensors,
+# any reproduction, modification, use or disclosure of MediaTek Software,
+# and information contained herein, in whole or in part, shall be strictly prohibited.
+#
+# MediaTek Inc. (C) 2010. All rights reserved.
+#
+# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+# AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+# SUPPLIED WITH THE MEDIATEK 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 MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+#
+# The following software/firmware and/or related documentation ("MediaTek Software")
+# have been modified by MediaTek Inc. All revisions are subject to any receiver's
+# applicable license agreements with MediaTek Inc.
+
+
+# Copyright (C) 2008 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.
+
+# Configuration
+BUILD_LOADER  := false
+BUILD_MT6582_CONSYS := false
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(MTK_COMBO_CHIP), )
+BUILD_LOADER  := true
+endif
+
+ifneq ($(filter CONSYS_6572,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifneq ($(filter CONSYS_6582,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifneq ($(filter CONSYS_6592,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifneq ($(filter CONSYS_6735,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifneq ($(filter CONSYS_6755,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifneq ($(filter CONSYS_6797,$(MTK_COMBO_CHIP)),)
+    BUILD_MT6582_CONSYS := true
+endif
+
+ifeq ($(BUILD_LOADER), true)
+$(warning build loader)
+include $(CLEAR_VARS)
+
+ifeq ($(BUILD_MT6582_CONSYS), true)
+LOCAL_CFLAGS := -DMTK_SOC_CONSYS_SUPPORT
+endif
+
+
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_SRC_FILES  := loader.c \
+                    load_fm.c \
+                    load_wifi.c \
+                    load_ant.c \
+                    loader_pwr.c
+LOCAL_MODULE := wmt_loader
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/src/connectivity/combo_tool/combo_loader/README b/src/connectivity/combo_tool/combo_loader/README
new file mode 100755
index 0000000..053fc8b
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/README
@@ -0,0 +1,19 @@
+This module serves the common part driver of connectivity
+
+WHAT IT DOES?
+=============
+This module creates one executable binary files for loading/initializing the common part driver including 
+wifi, fm, gps and BT if needed.
+
+HOW IT WAS BUILT?
+==================
+It needs the following library from AOSP:
+
+libcutils
+
+HOW TO USE IT?
+==============
+the executable binary files, wmt_loader, will be started in init.rc when boot. it will load/initialize
+to load the common part drivers(common part/wifi/fm/gps/BT) of connectivity
+
+The source code was written by MediaTek.
diff --git a/src/connectivity/combo_tool/combo_loader/load_ant.c b/src/connectivity/combo_tool/combo_loader/load_ant.c
new file mode 100755
index 0000000..53438be
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/load_ant.c
@@ -0,0 +1,105 @@
+/* Copyright Statement:
+*
+* This software/firmware and related documentation ("MediaTek Software") are
+* protected under relevant copyright laws. The information contained herein is
+* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+* the prior written permission of MediaTek inc. and/or its licensors, any
+* reproduction, modification, use or disclosure of MediaTek Software, and
+* information contained herein, in whole or in part, shall be strictly
+* prohibited.
+*
+* MediaTek Inc. (C) 2014. All rights reserved.
+*
+* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+* ON AN "AS-IS" BASIS ONLY. MEDIATEK 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 MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK 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 MEDIATEK
+* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* The following software/firmware and/or related documentation ("MediaTek
+* Software") have been modified by MediaTek Inc. All revisions are subject to
+* any receiver's applicable license agreements with MediaTek Inc.
+*/
+
+/*
+*ANT radio driver kernel module insmod file for wmt dynamic loader
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <cutils/misc.h>
+
+//For directory operation
+#include <dirent.h>
+
+#define ANT_MODULES_PATH "/system/lib/modules/mtk_stp_ant.ko"
+extern int load_ant_module(int chip_id);
+extern int init_module(void *, unsigned long, const char *);
+
+//insmod
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret = -1;
+	int retry = 10;
+
+	printf("filename(%s)\n",filename);
+
+    module = load_file(filename, &size);
+    if (!module)
+    {
+    	printf("load file fail\n");
+        return -1;
+    }
+
+	while(retry-- > 0){
+	    ret = init_module(module, size, args);
+
+		if(ret < 0)
+		{
+			printf("insmod module fail(%d)\n",ret);
+			usleep(10000);
+		}
+		else
+			break;
+
+	}
+
+    free(module);
+
+    return ret;
+}
+
+
+int load_ant_module(int chip_id)
+{
+	int ret = -1;
+	ret = insmod(ANT_MODULES_PATH, "");
+	if(ret)
+    {
+        printf("insert mtk_ant_drv.ko fail(%d)\n",ret);
+    }
+    else
+    {
+        printf("insert mtk_ant_drv.ko ok\n");
+    }
+    return ret;
+}
+
diff --git a/src/connectivity/combo_tool/combo_loader/load_fm.c b/src/connectivity/combo_tool/combo_loader/load_fm.c
new file mode 100755
index 0000000..cf5411b
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/load_fm.c
@@ -0,0 +1,67 @@
+/*
+*FM radio driver kernel module insmod file for wmt dynamic loader
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <cutils/misc.h>
+
+//For directory operation
+#include <dirent.h>
+
+#define FMR_MODULES_PATH "/system/lib/modules/mtk_fm_drv.ko"
+extern int load_fm_module(int chip_id);
+extern int init_module(void *, unsigned long, const char *);
+
+//insmod
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret = -1;
+	int retry = 10;
+
+	printf("filename(%s)\n",filename);
+
+    module = load_file(filename, &size);
+    if (!module)
+    {
+    	printf("load file fail\n");
+        return -1;
+    }
+
+	while(retry-- > 0){
+	    ret = init_module(module, size, args);
+
+		if(ret < 0)
+		{
+			printf("insmod module fail(%d)\n",ret);
+			usleep(10000);
+		}
+		else
+			break;
+
+	}
+
+    free(module);
+
+    return ret;
+}
+
+int load_fm_module(int chip_id)
+{
+    int ret=-1;
+    ret = insmod(FMR_MODULES_PATH, "");
+    if(ret)
+    {
+        printf("insert mtk_fm_drv.ko fail(%d)\n",ret);
+    }
+    else
+    {
+        printf("insert mtk_fm_drv.ko ok\n");
+    }
+    return ret;
+}
+
diff --git a/src/connectivity/combo_tool/combo_loader/load_wifi.c b/src/connectivity/combo_tool/combo_loader/load_wifi.c
new file mode 100755
index 0000000..ac040b2
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/load_wifi.c
@@ -0,0 +1,113 @@
+/*
+*WIFI driver kernel module insmod file for wmt dynamic loader
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <cutils/log.h>
+#include <cutils/misc.h>
+#include <linux/module.h>
+//For directory operation
+#include <dirent.h>
+
+extern int load_wifi_module(int chip_id);
+extern int init_module(void *, unsigned long, const char *);
+extern int delete_module(const char *, unsigned int);
+
+static char DRIVER_MODULE_PATH[50]  = "/system/lib/modules/wlan_";
+static char DRIVER_MODULE_ARG[50] = "";
+#ifndef WIFI_DRIVER_MODULE_ARG
+#define WIFI_DRIVER_MODULE_ARG          ""
+#endif
+
+//insmod
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret;
+
+    module = load_file(filename, &size);
+    if (!module)
+        return -1;
+
+    ret = init_module(module, size, args);
+
+    free(module);
+
+    return ret;
+}
+
+static int rmmod(const char *modname)
+{
+    int ret = -1;
+    int maxtry = 10;
+
+    while (maxtry-- > 0) {
+        ret = delete_module(modname, O_NONBLOCK | O_EXCL);
+        if (ret < 0 && errno == EAGAIN)
+            usleep(500000);
+        else
+            break;
+    }
+
+    if (ret != 0)
+        ALOGD("Unable to unload driver module \"%s\": %s\n",
+             modname, strerror(errno));
+    return ret;
+}
+
+int load_wifi_module(int chip_id)
+{
+    int ret=-1;
+    
+    if(chip_id == 0x6630){
+        //insert 6630 driver
+		if(0 == insmod("/system/lib/modules/mtk_wmt_wifi.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod wmt wifi module\n");
+        }else
+            printf("Fail to insmod wmt wifi module\n");	
+
+        if(0 == insmod("/system/lib/modules/wlan_mt6630.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod wlan module\n");
+        }else
+            printf("Fail to insmod wlan module\n");	 
+    }
+    else if(chip_id == 0x6628){
+        //insert 6628 driver
+        if(0 == insmod("/system/lib/modules/mtk_wmt_wifi.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod wmt wifi module\n");
+        }else
+            printf("Fail to insmod wmt wifi module\n");	
+
+        if(0 == insmod("/system/lib/modules/wlan_mt6628.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod wlan module\n");
+        }else
+            printf("Fail to insmod wlan module\n");	 
+    }
+    else if(chip_id == 0x6620){
+        //insert 6620 driver
+    }else { //for soc chip, same naming
+        //insert wmt_wifi => for temp naming
+        if(0 == insmod("/system/lib/modules/mtk_wmt_wifi_soc.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod wmt wifi module\n");
+        }else
+            printf("Fail to insmod wmt wifi module\n");	    
+
+        //insert wifi => for temp naming
+        if(0 == insmod("/system/lib/modules/wlan_mt.ko", DRIVER_MODULE_ARG)){  
+            ret = 0;
+            printf("Success to insmod the %s\n", DRIVER_MODULE_PATH);
+        }else
+            printf("Fail to insmod the %s\n", DRIVER_MODULE_PATH);	    
+    }
+    return ret;
+}
diff --git a/src/connectivity/combo_tool/combo_loader/loader.c b/src/connectivity/combo_tool/combo_loader/loader.c
new file mode 100755
index 0000000..7b639e0
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/loader.c
@@ -0,0 +1,740 @@
+
+#include "loader.h"
+#include "loader_pwr.h"
+//#include <syslog.h>
+#include <private/android_filesystem_config.h>
+#include <utils/Log.h>
+#include <string.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "wmt_loader"
+
+#define WCN_COMBO_LOADER_CHIP_ID_PROP    	"persist.mtk.wcn.combo.chipid"
+#define WCN_DRIVER_READY_PROP                    "service.wcn.driver.ready"
+#define WCN_COMBO_LOADER_DEV				"/dev/wmtdetect"
+#define WCN_COMBO_DEF_CHIPID				"0x6582"
+#define WMT_MODULES_PRE						"/system/lib/modules/"
+#define WMT_MODULES_SUFF					".ko"
+#define WMT_IOC_MAGIC        				'w'
+#define COMBO_IOCTL_GET_CHIP_ID       _IOR(WMT_IOC_MAGIC, 0, int)
+#define COMBO_IOCTL_SET_CHIP_ID       _IOW(WMT_IOC_MAGIC, 1, int)
+#define COMBO_IOCTL_EXT_CHIP_DETECT   _IOR(WMT_IOC_MAGIC, 2, int)
+#define COMBO_IOCTL_GET_SOC_CHIP_ID   _IOR(WMT_IOC_MAGIC, 3, int)
+#define COMBO_IOCTL_DO_MODULE_INIT    _IOR(WMT_IOC_MAGIC, 4, int)
+#define COMBO_IOCTL_MODULE_CLEANUP    _IOR(WMT_IOC_MAGIC, 5, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_ON   _IOR(WMT_IOC_MAGIC, 6, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF  _IOR(WMT_IOC_MAGIC, 7, int)
+#define COMBO_IOCTL_DO_SDIO_AUDOK     _IOR(WMT_IOC_MAGIC, 8, int)
+
+
+
+#define STP_WMT_MODULE_PRE_FIX "mtk_stp_wmt"
+#define STP_BT_MODULE_PRE_FIX "mtk_stp_bt"
+#define STP_GPS_MODULE_PRE_FIX "mtk_stp_gps"
+#define HIF_SDIO_MODULE_PRE_FIX "mtk_hif_sdio"
+#define STP_SDIO_MODULE_PRE_FIX "mtk_stp_sdio"
+#define STP_UART_MODULE_PRE_FIX "mtk_stp_uart"
+
+
+
+static int gLoaderFd = -1;
+
+static char DRIVER_MODULE_PATH[64]  = {0};
+static char DRIVER_MODULE_ARG[8] = "";
+static int chipid_array[] = {
+0x6620,
+0x6628,
+0x6630,
+0x6572,
+0x6582,
+0x6592,
+0x8127,
+0x6571,
+0x6752,
+0x6735,
+0x0321,
+0x0335,
+0x0337,
+0x8163,
+0x6580,
+0x6755,
+0x0326,
+0x6797,
+0x0279
+};
+static char chip_version[PROPERTY_VALUE_MAX] = {0};
+
+static int g_remove_ko_flag = 1;
+
+
+extern int init_module(void *, unsigned long, const char *);
+extern int delete_module(const char *, unsigned int);
+extern int load_fm_module(int chip_id);
+extern int load_wifi_module(int chip_id);
+extern int load_ant_module(int chip_id);
+//insmod
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret = -1;
+	int retry = 10;
+
+	ALOGI("filename(%s)\n",filename);
+
+    module = load_file(filename, &size);
+    if (!module)
+    {
+    	ALOGI("load file fail\n");
+        return -1;
+    }
+
+	while(retry-- > 0){
+	    ret = init_module(module, size, args);
+
+		if(ret < 0)
+		{
+			ALOGI("insmod module fail(%d)\n",ret);
+			usleep(30000);
+		}
+		else
+			break;
+
+	}
+
+    free(module);
+
+    return ret;
+}
+static int is_chipId_vaild(int chipid)
+{
+	int iret;
+	unsigned char i;
+	iret = -1;
+	
+	for(i = 0;i < sizeof(chipid_array)/sizeof(0x6630); i++){
+		if(chipid == chipid_array[i]){
+			ALOGI("is_chipId_vaild: %d :0x%x!\n",i,chipid);
+			iret = 0;
+			break;
+		}
+	}
+	return iret;
+}
+static int rmmod(const char *modname)
+{
+    int ret = -1;
+    int maxtry = 10;
+
+    while (maxtry-- > 0) {
+        ret = delete_module(modname, O_EXCL);//O_NONBLOCK | O_EXCL);
+        if (ret < 0 && errno == EAGAIN)
+            usleep(500000);
+        else
+            break;
+    }
+
+    if (ret != 0)
+        ALOGI("Unable to unload driver module \"%s\": %s,ret(%d)\n",
+             modname, strerror(errno),ret);
+    return ret;
+}
+
+static int insmod_by_path (char *nameBuf, char * modulePath, char *preFix, char *postFix )
+{
+	int iRet = -1;
+	int len = 0;
+	int path_len = 0;
+
+	/*no need to check, upper layer API will makesure this condition fullfill*/
+	strcat (nameBuf, modulePath);
+	strcat (nameBuf, preFix);
+	strcat (nameBuf, postFix);
+	strcat (nameBuf, WMT_MODULES_SUFF);
+
+	insmod_retry:
+	iRet = insmod(nameBuf, DRIVER_MODULE_ARG);
+	if(iRet)
+	{
+		ALOGI("insert <%s> failed, len(%d), iret(%d), retrying\n", nameBuf, sizeof(nameBuf), iRet);
+		/*break;*/
+		usleep(800000);
+		goto insmod_retry;
+	}else
+	{
+		ALOGI("insert <%s> succeed,len(%d)\n", nameBuf, len);
+		iRet = 0;
+	}
+	return 0;
+}
+
+
+static int insert_wmt_module_for_soc(int chipid, char *modulePath, char *nameBuf, int nameBufLen)
+{
+	int iRet = -1;
+	int len = 0;
+	int path_len = 0;
+	int i = 0;
+	char postFixStr[10] = {0};
+	int totalLen = 0;
+	char *soc_modulse[] = {
+		STP_WMT_MODULE_PRE_FIX,
+		STP_BT_MODULE_PRE_FIX,
+		STP_GPS_MODULE_PRE_FIX,
+	};
+
+#if 0
+	path_len = strlen(modulePath);
+	strncpy(nameBuf, modulePath,path_len);
+	ALOGI("module subpath1(%s),sublen1(%d)\n",nameBuf,path_len);
+	len = path_len;
+#endif
+
+	sprintf(postFixStr, "_%s", "soc");
+
+#if 0
+	switch (chipid)
+	{
+		case 0x6572:
+		case 0x6582:
+			strcpy(postFixStr, "_6582");
+			break;
+		case 0x6571:
+			strcpy(postFixStr, "_6592");
+		case 0x6592:
+			strcpy(postFixStr, "_6592");
+			break;
+		default:
+
+			break;
+	}
+#endif
+
+	if (NULL == modulePath || NULL == nameBuf || 0 >= nameBufLen)
+	{
+		ALOGI("invalid parameter:modulePath(%p), nameBuf(%p), nameBufLen(%d)\n", modulePath, nameBuf, nameBufLen);
+		return iRet;
+	}
+
+	for(i = 0;i < sizeof(soc_modulse)/sizeof(soc_modulse[0]);i++)
+	{
+		totalLen = sizeof (modulePath) + sizeof (soc_modulse[i]) + sizeof(postFixStr) + sizeof(WMT_MODULES_SUFF);
+		if (nameBufLen > totalLen)
+		{
+
+			memset (nameBuf, 0, nameBufLen);
+			insmod_by_path(nameBuf, modulePath, soc_modulse[i], postFixStr);
+		}
+		else
+		{
+			ALOGI("nameBuf length(%d) too short, (%d) needed\n", nameBufLen, totalLen);
+		}
+#if 0
+		len = path_len;
+		len += sprintf(nameBuf + len,"%s",soc_modulse[i]);
+		ALOGI("module subpath2(%s),sublen2(%d)\n",nameBuf,len);
+
+		len += sprintf(nameBuf + len,"%s", postFixStr);
+		ALOGI("module subpath3(%s),sublen3(%d)\n",nameBuf,len);
+
+		len += sprintf(nameBuf + len,"%s",WMT_MODULES_SUFF);
+		ALOGI("module subpath4(%s),sublen4(%d)\n",nameBuf,len);
+
+		nameBuf[len] = '\0';
+		ALOGI("module subpath5(%s),sublen5(%d)\n",nameBuf,len);
+
+		soc_retry:
+		iRet = insmod(nameBuf, DRIVER_MODULE_ARG);
+		if(iRet)
+		{
+			ALOGI("(%d):current modules(%s) insert fail,len(%d),iret(%d), retrying\n", i, nameBuf, len, iRet);
+			/*break;*/
+			usleep(300000);
+			goto soc_retry;
+		}else
+		{
+			ALOGI("(%d):current modules(%s) insert ok,len(%d)\n", i, nameBuf, len);
+		}
+#endif
+
+	}
+
+
+
+	return 0;
+}
+
+static int insert_wmt_module_for_combo(int chipid, char *modulePath, char *nameBuf, int nameBufLen)
+{
+	int iRet = -1;
+	int len = 0;
+	int path_len = 0;
+	int i = 0;
+	char postFixStr[10] = {0};
+	int totalLen = 0;
+
+	char *combo_modulse[] = {
+		HIF_SDIO_MODULE_PRE_FIX,
+		STP_WMT_MODULE_PRE_FIX,
+		STP_UART_MODULE_PRE_FIX,
+		STP_SDIO_MODULE_PRE_FIX,
+		STP_BT_MODULE_PRE_FIX,
+		STP_GPS_MODULE_PRE_FIX
+	};
+
+	if (NULL == modulePath || NULL == nameBuf || 0 >= nameBufLen)
+	{
+		ALOGI("invalid parameter:modulePath(%p), nameBuf(%p), nameBufLen(%d)\n", modulePath, nameBuf, nameBufLen);
+		return iRet;
+	}
+
+#if 0
+	path_len = strlen(modulePath);
+	strncpy(nameBuf, modulePath,path_len);
+	ALOGI("module subpath1(%s),sublen1(%d)\n",nameBuf,path_len);
+
+	len = path_len;
+#endif
+
+	switch (chipid)
+	{
+		case 0x6620:
+		case 0x6628:
+			/*strcpy(postFixStr, "_6620_28");*/
+			strcpy(postFixStr, "");
+			break;
+		case 0x6630:
+			//strcpy(postFixStr, "_6630");
+			strcpy(postFixStr, "");
+			break;
+		default:
+
+			break;
+	}
+
+	for(i = 0;i < sizeof(combo_modulse)/sizeof(combo_modulse[0]);i++)
+	{
+		totalLen = sizeof (modulePath) + sizeof (combo_modulse[i]) + sizeof(postFixStr) + sizeof(WMT_MODULES_SUFF);
+		if (nameBufLen > totalLen)
+		{
+			memset (nameBuf, 0, nameBufLen);
+			insmod_by_path(nameBuf, modulePath, combo_modulse[i], postFixStr);
+		}
+		else
+		{
+			ALOGI("nameBuf length(%d) too short, (%d) needed\n", nameBufLen, totalLen);
+		}
+#if 0
+		len = path_len;
+		len += sprintf(nameBuf + len,"%s",combo_modulse[i]);
+		ALOGI("module subpath2(%s),sublen2(%d)\n",nameBuf,len);
+
+		len += sprintf(nameBuf + len,"%s",postFixStr);
+		ALOGI("module subpath3(%s),sublen3(%d)\n",nameBuf,len);
+
+		len += sprintf(nameBuf + len,"%s",WMT_MODULES_SUFF);
+		ALOGI("module subpath4(%s),sublen4(%d)\n",nameBuf,len);
+
+		nameBuf[len] = '\0';
+		ALOGI("module subpath5(%s),sublen5(%d)\n",nameBuf,len);
+
+		combo_retry:
+		iRet = insmod(nameBuf, DRIVER_MODULE_ARG);
+		if(iRet)
+		{
+			ALOGI("(%d):current modules(%s) insert fail,len(%d),iret(%d), retrying\n", i, nameBuf, len, iRet);
+			/*break;*/
+			usleep(300000);
+			goto combo_retry;
+		}else
+		{
+			ALOGI("(%d):current modules(%s) insert ok,len(%d)\n",i, nameBuf, len);
+		}
+#endif
+	}
+
+
+	return 0;
+}
+
+
+
+/******************************************************
+arg1:
+= 0:there is already a valid chipid in peroperty or there is no external combo chip
+	chipid is just 	MT6582
+> 0:there is no valid chipid in peroperty, boot system firstly
+
+arg2: // handle combo chip (there is an external combo chip)
+= 0:insert mtk_hif_sdio.ko for detech combo chipid
+> 0:insert combo modules except mtk_hif_sdio.ko
+******************************************************/
+
+static int insert_wmt_modules(int chipid,int arg1,int arg2)
+{
+	int iRet = -1;
+
+	switch (chipid)
+	{
+		case 0x6582:
+		case 0x6572:
+		case 0x6571:
+		case 0x6592:
+		case 0x8127:
+		case 0x6752:
+		case 0x6735:
+		case 0x8163:
+		case 0x6580:
+        case 0x6755:
+        case 0x6797:
+			iRet = insert_wmt_module_for_soc(chipid, WMT_MODULES_PRE, DRIVER_MODULE_PATH, sizeof (DRIVER_MODULE_PATH));
+			break;
+		case 0x6620:
+		case 0x6628:
+		case 0x6630:
+			iRet = insert_wmt_module_for_combo(chipid, WMT_MODULES_PRE, DRIVER_MODULE_PATH, sizeof (DRIVER_MODULE_PATH));
+			break;
+		default:
+			break;
+	}
+
+	return iRet;
+}
+
+int do_kernel_module_init(int gLoaderFd, int chipId)
+{
+	int iRet = 0;
+	if (gLoaderFd < 0)
+	{
+		ALOGI("invalid gLoaderFd: %d\n", gLoaderFd);
+		return -1;
+	}
+
+	iRet = ioctl (gLoaderFd, COMBO_IOCTL_MODULE_CLEANUP, chipId);
+	if (iRet)
+	{
+		ALOGI("do WMT-DETECT module cleanup failed: %d\n", iRet);
+		return -2;
+	}
+ 	iRet = ioctl (gLoaderFd, COMBO_IOCTL_DO_MODULE_INIT, chipId);
+	if (iRet)
+	{
+		ALOGI("do kernel module init failed: %d\n", iRet);
+		return -3;
+	}
+	ALOGI("do kernel module init succeed: %d\n", iRet);
+	return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+	int iRet = -1;
+	int noextChip = -1;
+	int chipId = -1;
+	int count = 0;
+	char chipidStr[PROPERTY_VALUE_MAX] = {0};
+        char readyStr[PROPERTY_VALUE_MAX] = {0};
+	int loadFmResult = -1;
+	int loadAntResult = -1;
+	int loadWlanResult = -1;
+	int retryCounter = 1;
+	int autokRet = 0;
+	do{
+		gLoaderFd = open(WCN_COMBO_LOADER_DEV, O_RDWR | O_NOCTTY);
+		if(gLoaderFd < 0)
+		{
+			count ++;
+			ALOGI("Can't open device node(%s) count(%d)\n", WCN_COMBO_LOADER_DEV,count);
+			usleep(300000);
+		}
+		else
+			break;
+	}while(1);
+
+	//read from system property
+	iRet = property_get(WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, NULL);
+	chipId = strtoul(chipidStr, NULL, 16);
+
+	if ((0 != iRet) && (-1 != is_chipId_vaild(chipId)))
+	{
+		/*valid chipid detected*/
+		ALOGI("key:(%s)-value:(%s),chipId:0x%04x,iRet(%d)\n", WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, chipId,iRet);
+		if (0x6630 == chipId)
+		{
+			retryCounter = 10;
+			/*trigger autok process, incase last autok process is interrupted by abnormal power off or battery down*/
+			do {
+				/*power on combo chip*/
+				iRet = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_PWR_ON);
+				if (0 != iRet)
+				{
+					ALOGI("external combo chip power on failed\n");
+					noextChip = 1;
+				}
+				else
+				{
+					/*detect is there is an external combo chip*/
+					noextChip = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_DETECT,NULL);
+				}
+
+				if(noextChip)
+				{
+					 // do nothing
+					 ALOGI("no external combo chip detected\n");
+				}
+				else
+				{
+					ALOGI("external combo chip detected\n");
+
+					chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
+					ALOGI("chipid (0x%x) detected\n", chipId);
+				}
+
+
+				if(0 == noextChip)
+				{
+					autokRet = ioctl(gLoaderFd,COMBO_IOCTL_DO_SDIO_AUDOK,chipId);
+					if (0 != autokRet)
+					{
+						ALOGI("do SDIO3.0 autok failed\n");
+					}
+					else
+					{
+						ALOGI("do SDIO3.0 autok succeed\n");
+					}
+				}
+				iRet = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_PWR_OFF);
+				if (0 != iRet)
+				{
+					ALOGI("external combo chip power off failed\n");
+				}
+				else
+				{
+					ALOGI("external combo chip power off succeed\n");
+				}
+				if ((0 == noextChip) && (-1 == chipId))
+				{
+					/*extenral chip detected, but no valid chipId detected, retry*/
+					retryCounter--;
+					ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
+					usleep(500000);
+				}
+				else
+					break;
+			}while (0 < retryCounter);
+			chipId = 0x6630;
+		}
+	}
+	else
+	{
+		/*trigger external combo chip detect and chip identification process*/
+		do {
+			/*power on combo chip*/
+			iRet = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_PWR_ON);
+			if (0 != iRet)
+			{
+				ALOGI("external combo chip power on failed\n");
+				noextChip = 1;
+			}
+			else
+			{
+				/*detect is there is an external combo chip*/
+				noextChip = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_DETECT,NULL);
+			}
+
+			if(noextChip)// use soc itself
+			{
+				ALOGI("no external combo chip detected, get current soc chipid\n");
+				chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_SOC_CHIP_ID, NULL);
+				ALOGI("soc chipid (0x%x) detected\n", chipId);
+			}
+			else
+			{
+				ALOGI("external combo chip detected\n");
+
+				chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
+				ALOGI("chipid (0x%x) detected\n", chipId);
+			}
+
+			sprintf (chipidStr, "0x%04x", chipId);
+			iRet = property_set(WCN_COMBO_LOADER_CHIP_ID_PROP,chipidStr);
+			if (0 != iRet)
+			{
+				ALOGI("set property(%s) to %s failed,iRet:%d, errno:%d\n", WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, iRet, errno);
+			}
+			else
+			{
+				ALOGI("set property(%s) to %s succeed.\n", WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr);
+			}
+			if(0 == noextChip)
+			{
+				autokRet = ioctl(gLoaderFd,COMBO_IOCTL_DO_SDIO_AUDOK,chipId);
+				if (0 != autokRet)
+				{
+					ALOGI("do SDIO3.0 autok failed\n");
+				}
+				else
+				{
+					ALOGI("do SDIO3.0 autok succeed\n");
+				}
+			}
+			iRet = ioctl(gLoaderFd,COMBO_IOCTL_EXT_CHIP_PWR_OFF);
+			if (0 != iRet)
+			{
+				ALOGI("external combo chip power off failed\n");
+			}
+			else
+			{
+				ALOGI("external combo chip power off succeed\n");
+			}
+			if ((0 == noextChip) && (-1 == chipId))
+			{
+			    /*extenral chip detected, but no valid chipId detected, retry*/
+			    retryCounter--;
+			    usleep(500000);
+			    ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
+			}
+			else
+			    break;
+		}while (0 < retryCounter);
+	}
+
+	/*set chipid to kernel*/
+	ioctl(gLoaderFd,COMBO_IOCTL_SET_CHIP_ID,chipId);
+
+	if (g_remove_ko_flag)
+	{
+		if((0x0321 == chipId) || (0x0335 == chipId) || (0x0337 == chipId))
+		{
+			chipId = 0x6735;
+		}
+        if (0x0326 == chipId) {
+            chipId = 0x6755;
+        }
+        if (0x0279 == chipId) {
+            chipId = 0x6797;
+        }
+		do_kernel_module_init(gLoaderFd, chipId);
+		if(gLoaderFd >= 0)
+		{
+			close(gLoaderFd);
+			gLoaderFd = -1;
+		}
+
+	}
+	else
+	{
+		if(gLoaderFd >= 0)
+		{
+			close(gLoaderFd);
+			gLoaderFd = -1;
+		}
+		ALOGI("rmmod mtk_wmt_detect\n");
+		rmmod("mtk_wmt_detect");
+
+		/*INSERT TARGET MODULE TO KERNEL*/
+
+		iRet = insert_wmt_modules(chipId, 0, -1);
+		/*this process should never fail*/
+		if(iRet)
+		{
+			ALOGI("insert wmt modules fail(%d):(%d)\n",iRet,__LINE__);
+			/*goto done;*/
+		}
+
+
+		loadFmResult = load_fm_module(chipId);
+		if(loadFmResult)
+		{
+			ALOGI("load FM modules fail(%d):(%d)\n",iRet,__LINE__);
+			/*continue, we cannot let this process interrupted by subsystem module load fail*/
+			/*goto done;*/
+		}
+
+		loadAntResult = load_ant_module(chipId);
+		if(loadAntResult)
+		{
+			ALOGI("load ANT modules fail(%d):(%d)\n",iRet,__LINE__);
+			/*continue, we cannot let this process interrupted by subsystem module load fail*/
+			/*goto done;*/
+		}
+
+		loadWlanResult = load_wifi_module(chipId);
+		if(loadWlanResult)
+		{
+			ALOGI("load WIFI modules fail(%d):(%d)\n",iRet,__LINE__);
+			/*continue, we cannot let this process interrupted by subsystem module load fail*/
+			/*goto done;*/
+		}
+	}
+
+
+
+	if((chown("/proc/driver/wmt_dbg",AID_SHELL,AID_SYSTEM) == -1) || (chown("/proc/driver/wmt_aee",AID_SHELL,AID_SYSTEM) == -1))
+	{
+		ALOGI("chown wmt_dbg or wmt_aee fail:%s\n",strerror(errno));
+	}
+
+	if(chown("/proc/wmt_tm/wmt_tm",0,1000) == -1)
+	{
+		ALOGI("chown wmt_tm fail:%s\n",strerror(errno));
+	}
+	if (0/*0x6630 == chipId*/)
+	{
+		retryCounter = 0;
+		int i_ret = -1;
+		do {
+			i_ret = loader_wmt_pwr_ctrl(1);
+			if (0 == i_ret)
+				break;
+			else
+			{
+				loader_wmt_pwr_ctrl(0);
+				ALOGI("power on %x failed, retrying, retry counter:%d\n", chipId, retryCounter);
+				usleep(1000000);
+			}
+			retryCounter++;
+		} while (retryCounter < 20);
+        }
+        iRet = property_get(WCN_DRIVER_READY_PROP, readyStr, NULL);
+        if ((0 >= iRet) || (0 == strcmp(readyStr, "yes"))) {
+                ALOGI("get property(%s) failed iRet:%d or property is %s\n", WCN_DRIVER_READY_PROP, iRet, readyStr);
+        }
+        /*set it to yes anyway*/
+        sprintf(readyStr, "%s", "yes");
+        iRet = property_set(WCN_DRIVER_READY_PROP, readyStr);
+        if (0 != iRet) {
+                ALOGI("set property(%s) to %s failed iRet:%d\n", WCN_DRIVER_READY_PROP, readyStr, iRet);
+        } else {
+                ALOGI("set property(%s) to %s succeed\n", WCN_DRIVER_READY_PROP, readyStr);
+	}
+#if 0
+	while (loadWlanResult || loadFmResult)
+	{
+		if(loadFmResult)
+		{
+			static int retryCounter = 0;
+			retryCounter++;
+			ALOGI("retry loading fm module, retryCounter:%d\n", retryCounter);
+			loadFmResult = load_fm_module(chipId);
+		}
+
+		if(loadWlanResult)
+		{
+			static int retryCounter = 0;
+			retryCounter++;
+			ALOGI("retry loading wlan module, retryCounter:%d\n", retryCounter);
+			loadWlanResult = load_wifi_module(chipId);
+		}
+		usleep(1000000);
+	}
+#endif
+
+	return iRet;
+}
+
+
+
diff --git a/src/connectivity/combo_tool/combo_loader/loader.h b/src/connectivity/combo_tool/combo_loader/loader.h
new file mode 100755
index 0000000..6c7afab
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/loader.h
@@ -0,0 +1,16 @@
+#ifndef __WMT_LOADER_H_
+#define __WMT_LOADER_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+//For directory operation
+#include <dirent.h>
+
+#include <cutils/properties.h>
+#include <cutils/misc.h>
+#include <sys/ioctl.h>
+
+#endif
diff --git a/src/connectivity/combo_tool/combo_loader/loader_pwr.c b/src/connectivity/combo_tool/combo_loader/loader_pwr.c
new file mode 100755
index 0000000..a1f5257
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/loader_pwr.c
@@ -0,0 +1,30 @@
+#include "../src/wmt_ioctl.h"
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+int loader_wmt_pwr_ctrl(int on)
+{
+    int i_ret = -1;
+    int wmt_fd;
+    int para = (on == 0) ? 0 : 1;
+    /* open wmt dev */
+    wmt_fd = open("/dev/stpwmt", O_RDWR | O_NOCTTY);
+    if (wmt_fd < 0) {
+        printf("[%s] Can't open stpwmt \n", __FUNCTION__);
+        return -1;
+    }
+    if(ioctl(wmt_fd, WMT_IOCTL_LPBK_POWER_CTRL, para) != 0)
+    {
+        printf("[%s] power on combo chip failed\n", __FUNCTION__);
+        i_ret = -2;
+    } else {
+        printf("[power %s combo chip ok!]\n", para == 0 ? "off" : "on");
+        i_ret = 0;
+    }
+    close(wmt_fd);
+    wmt_fd = -1;
+    
+    return i_ret;
+}
\ No newline at end of file
diff --git a/src/connectivity/combo_tool/combo_loader/loader_pwr.h b/src/connectivity/combo_tool/combo_loader/loader_pwr.h
new file mode 100755
index 0000000..bfe370d
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/loader_pwr.h
@@ -0,0 +1,4 @@
+#ifndef __WMT_LOADER_PWR_H_
+#define __WMT_LOADER_PWR_H_
+int loader_wmt_pwr_ctrl(int on);
+#endif /*__WMT_LOADER_PWR_H_*/
\ No newline at end of file
diff --git a/src/connectivity/combo_tool/combo_loader/yocto_loader.c b/src/connectivity/combo_tool/combo_loader/yocto_loader.c
new file mode 100755
index 0000000..34256a4
--- /dev/null
+++ b/src/connectivity/combo_tool/combo_loader/yocto_loader.c
@@ -0,0 +1,460 @@
+#include "loader_pwr.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+// For directory operation
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/utsname.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "wmt_loader"
+
+#define WCN_COMBO_LOADER_CHIP_ID_PROP    "persist.mtk.wcn.combo.chipid"
+#ifndef ALOGI
+#define ALOGI printf
+#endif
+#ifndef PROPERTY_VALUE_MAX
+#define PROPERTY_VALUE_MAX (128)
+#endif
+
+#define WCN_COMBO_LOADER_DEV    "/dev/wmtdetect"
+#define WCN_COMBO_DEF_CHIPID    "0x6582"
+#define WMT_MODULES_PRE         "/system/lib/modules/"
+#define WMT_KO_PATH_PREFIX      "/lib/modules/"
+#define WMT_WIFI_MODULE_PATH    "/kernel/drivers/misc/mediatek/connectivity/wlan/wmt_chrdev_wifi.ko"
+#define WMT_WLAN_MODULE_PATH    "/kernel/drivers/misc/mediatek/connectivity/wlan/gen3/wlan_gen3.ko"
+/* connectivity modules are built out of kernel tree */
+#define WMT_OUT_KO_PATH_PREFIX          "/lib/modules/mt66xx/"
+#define WMT_OUT_WMT_WIFI_MODULE_PATH    "wmt_chrdev_wifi.ko"
+#define WMT_OUT_WLAN_MODULE_PATH        "wlan_drv_gen3.ko"
+
+#define WMT_MODULES_SUFF        ".ko"
+#define WMT_IOC_MAGIC           'w'
+#define COMBO_IOCTL_GET_CHIP_ID       _IOR(WMT_IOC_MAGIC, 0, int)
+#define COMBO_IOCTL_SET_CHIP_ID       _IOW(WMT_IOC_MAGIC, 1, int)
+#define COMBO_IOCTL_EXT_CHIP_DETECT   _IOR(WMT_IOC_MAGIC, 2, int)
+#define COMBO_IOCTL_GET_SOC_CHIP_ID   _IOR(WMT_IOC_MAGIC, 3, int)
+#define COMBO_IOCTL_DO_MODULE_INIT    _IOR(WMT_IOC_MAGIC, 4, int)
+#define COMBO_IOCTL_MODULE_CLEANUP    _IOR(WMT_IOC_MAGIC, 5, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_ON   _IOR(WMT_IOC_MAGIC, 6, int)
+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF  _IOR(WMT_IOC_MAGIC, 7, int)
+#define COMBO_IOCTL_DO_SDIO_AUDOK     _IOR(WMT_IOC_MAGIC, 8, int)
+
+
+
+#define STP_WMT_MODULE_PRE_FIX "mtk_stp_wmt"
+#define STP_BT_MODULE_PRE_FIX "mtk_stp_bt"
+#define STP_GPS_MODULE_PRE_FIX "mtk_stp_gps"
+#define HIF_SDIO_MODULE_PRE_FIX "mtk_hif_sdio"
+#define STP_SDIO_MODULE_PRE_FIX "mtk_stp_sdio"
+#define STP_UART_MODULE_PRE_FIX "mtk_stp_uart"
+
+
+
+static int gLoaderFd = -1;
+
+static char DRIVER_MODULE_PATH[64]  = {0};
+static char DRIVER_MODULE_ARG[8] = "";
+static int chipid_array[] = {
+0x6620,
+0x6628,
+0x6630,
+0x6572,
+0x6582,
+0x6592,
+0x8127,
+0x6571,
+0x6752,
+0x6735,
+0x0321,
+0x0335,
+0x0337,
+0x8163,
+0x6580,
+0x6755,
+0x0326,
+0x6797,
+0x0279
+};
+static char chip_version[PROPERTY_VALUE_MAX] = {0};
+
+static int g_remove_ko_flag = 1;
+
+
+extern int init_module(void *, unsigned long, const char *);
+extern int delete_module(const char *, unsigned int);
+extern int load_fm_module(int chip_id);
+//extern int load_wifi_module(int chip_id);
+extern int load_ant_module(int chip_id);
+// insmod
+static int is_chipId_vaild(int chipid) {
+        int iret;
+        unsigned char i;
+        iret = -1;
+
+        for (i = 0; i < sizeof(chipid_array)/sizeof(0x6630); i++) {
+                 if (chipid == chipid_array[i]) {
+                        ALOGI("is_chipId_vaild: %d :0x%x!\n", i, chipid);
+                        iret = 0;
+                        break;
+                 }
+        }
+        return iret;
+}
+
+int do_kernel_module_init(int gLoaderFd, int chipId) {
+        int iRet = 0;
+        if (gLoaderFd < 0) {
+                ALOGI("invalid gLoaderFd: %d\n", gLoaderFd);
+                return -1;
+        }
+
+        iRet = ioctl(gLoaderFd, COMBO_IOCTL_MODULE_CLEANUP, chipId);
+        if (iRet) {
+                ALOGI("do WMT-DETECT module cleanup failed: %d\n", iRet);
+                return -2;
+        }
+        iRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_MODULE_INIT, chipId);
+        if (iRet) {
+                ALOGI("do kernel module init failed: %d\n", iRet);
+                return -3;
+        }
+        ALOGI("do kernel module init succeed: %d\n", iRet);
+        return 0;
+}
+
+void *load_file(const char *fn, unsigned *_sz)
+{
+	char *data;
+	int sz;
+	int fd;
+	data = 0;
+
+	fd = open(fn, O_RDONLY);
+	if(fd < 0) return 0;
+
+	sz = lseek(fd, 0, SEEK_END);
+	if(sz < 0)
+		goto oops;
+
+	if(lseek(fd, 0, SEEK_SET) != 0)
+		goto oops;
+
+	data = (char*) malloc(sz + 1);
+	if(data == 0)
+		goto oops;
+
+	if(read(fd, data, sz) != sz)
+		goto oops;
+
+	close(fd);    data[sz] = 0;
+
+	if(_sz)
+		*_sz = sz;
+
+	return data;
+
+oops:
+	close(fd);
+	if(data != 0)
+		free(data);
+
+	return 0;
+}
+
+//insmod
+static int insmod(const char *filename, const char *args)
+{
+	void *module;
+	unsigned int size;
+	int ret;
+
+	module = load_file(filename, &size);
+	if (!module)
+		return -1;
+
+	ret = init_module(module, size, args);
+
+	free(module);
+
+	return ret;
+}
+
+
+int load_wifi_module(int chip_id)
+{
+	int ret = -1;
+	struct utsname utsname;
+	char wifi_module_path[100] = "";
+	char wlan_module_path[100] = "";
+
+	if (!(uname(&utsname))) {
+		/* Use modules built within kernel tree */
+		sprintf(wifi_module_path, "%s%s%s", WMT_KO_PATH_PREFIX, utsname.release, WMT_WIFI_MODULE_PATH);
+		sprintf(wlan_module_path, "%s%s%s", WMT_KO_PATH_PREFIX, utsname.release, WMT_WLAN_MODULE_PATH);
+	} else
+		return -1;
+
+	if ((access(wifi_module_path,0) < 0) && (access(wlan_module_path,0) < 0))
+	{
+		/* Use modules built out of kernel tree */
+		printf("Use modules built out of kernel tree\n");
+		memset(wifi_module_path, 0, sizeof(wifi_module_path));
+		memset(wlan_module_path, 0, sizeof(wlan_module_path));
+		sprintf(wifi_module_path, "%s%s", WMT_OUT_KO_PATH_PREFIX, WMT_OUT_WMT_WIFI_MODULE_PATH);
+		sprintf(wlan_module_path, "%s%s", WMT_OUT_KO_PATH_PREFIX, WMT_OUT_WLAN_MODULE_PATH);
+	}
+
+	if (chip_id == 0x6630) {
+		//insert 6630 driver
+		if(0 == insmod(wifi_module_path, DRIVER_MODULE_ARG)){
+			ret = 0;
+			printf("Success to insmod wmt wifi module\n");
+		} else
+			printf("Fail to insmod wmt wifi module %s\n", wifi_module_path);
+
+		if(0 == insmod(wlan_module_path, DRIVER_MODULE_ARG)){
+			ret = 0;
+			printf("Success to insmod wlan module\n");
+		} else
+			printf("Fail to insmod wlan module %s\n", wlan_module_path);
+    }
+
+	return ret;
+}
+
+
+/* TBD in platform-specific way */
+static int get_persist_chip_id(char *str, size_t len) { return -1; }
+static int set_persist_chip_id(int id) { return 0; }
+static void set_proc_owner(void) { }
+static void update_driver_ready(void) { }
+
+int main(int argc, char *argv[]) {
+        int iRet = -1;
+        int noextChip = -1;
+        int chipId = -1;
+        int count = 0;
+        char chipidStr[PROPERTY_VALUE_MAX] = {0};
+        char readyStr[PROPERTY_VALUE_MAX] = {0};
+        int loadFmResult = -1;
+        int loadAntResult = -1;
+        int loadWlanResult = -1;
+        int retryCounter = 1;
+        int autokRet = 0;
+        do {
+                gLoaderFd = open(WCN_COMBO_LOADER_DEV, O_RDWR | O_NOCTTY);
+                if (gLoaderFd < 0) {
+                        count++;
+                        ALOGI("Can't open device node(%s) count(%d)\n", WCN_COMBO_LOADER_DEV, count);
+                        usleep(300000);
+                } else
+                        break;
+        } while (1);
+
+        // read from system property
+        chipId = get_persist_chip_id(chipidStr, sizeof(chipidStr));
+
+        if (-1 != is_chipId_vaild(chipId)) {
+                /*valid chipid detected*/
+                ALOGI("key:(%s)-value:(%s),chipId:0x%04x,iRet(%d)\n",
+                        WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, chipId, iRet);
+                if (0x6630 == chipId) {
+                        retryCounter = 10;
+                        /*trigger autok process, incase last autok process is 
+                          interrupted by abnormal power off or battery down*/
+                        do {
+                                /*power on combo chip*/
+                                iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_ON);
+                                if (0 != iRet) {
+                                        ALOGI("external combo chip power on failed\n");
+                                        noextChip = 1;
+                                } else {
+                                        /*detect is there is an external combo chip*/
+                                        noextChip = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_DETECT, NULL);
+                                }
+
+                                if (noextChip) {
+                                         // do nothing
+                                         ALOGI("no external combo chip detected\n");
+                                } else {
+                                         ALOGI("external combo chip detected\n");
+                                         chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
+                                         ALOGI("chipid (0x%x) detected\n", chipId);
+                               }
+
+                                if (0 == noextChip) {
+                                        autokRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_SDIO_AUDOK, chipId);
+                                        if (0 != autokRet) {
+                                                ALOGI("do SDIO3.0 autok failed\n");
+                                        } else {
+                                                ALOGI("do SDIO3.0 autok succeed\n");
+                                        }
+                                }
+                                iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_OFF);
+                                if (0 != iRet) {
+                                        ALOGI("external combo chip power off failed\n");
+                                } else {
+                                        ALOGI("external combo chip power off succeed\n");
+                                }
+                                if ((0 == noextChip) && (-1 == chipId)) {
+                                        /*extenral chip detected, but no valid chipId detected, retry*/
+                                        retryCounter--;
+                                        ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
+                                        usleep(500000);
+                                } else
+                                        break;
+                        }while (0 < retryCounter);
+                        chipId = 0x6630;
+                 }
+        } else {
+                /*trigger external combo chip detect and chip identification process*/
+                do {
+                        /*power on combo chip*/
+                        iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_ON);
+                        if (0 != iRet) {
+                                ALOGI("external combo chip power on failed\n");
+                                noextChip = 1;
+                        } else {
+                                /*detect is there is an external combo chip*/
+                                noextChip = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_DETECT, NULL);
+                        }
+
+                        if (noextChip) {   // use soc itself
+                                ALOGI("no external combo chip detected, get current soc chipid\n");
+                                chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_SOC_CHIP_ID, NULL);
+                                ALOGI("soc chipid (0x%x) detected\n", chipId);
+                        } else {
+                                ALOGI("external combo chip detected\n");
+                                chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
+                                ALOGI("chipid (0x%x) detected\n", chipId);
+                       }
+
+                        sprintf(chipidStr, "0x%04x", chipId);
+                        iRet = set_persist_chip_id(chipId);
+                        if (0 != iRet) {
+                                ALOGI("set property(%s) to %s failed,iRet:%d, errno:%d\n",
+                                    WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, iRet, errno);
+                        } else {
+                               ALOGI("set property(%s) to %s succeed.\n", WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr);
+                        }
+                        if (0 == noextChip) {
+                                autokRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_SDIO_AUDOK, chipId);
+                                if (0 != autokRet) {
+                                        ALOGI("do SDIO3.0 autok failed\n");
+                                } else {
+                                        ALOGI("do SDIO3.0 autok succeed\n");
+                                }
+                        }
+                        iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_OFF);
+                        if (0 != iRet) {
+                                ALOGI("external combo chip power off failed\n");
+                        } else {
+                                ALOGI("external combo chip power off succeed\n");
+                        }
+                        if ((0 == noextChip) && (-1 == chipId)) {
+                            /*extenral chip detected, but no valid chipId detected, retry*/
+                            retryCounter--;
+                            usleep(500000);
+                            ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
+                        } else
+                              break;
+                }while (0 < retryCounter);
+        }
+
+        /*set chipid to kernel*/
+        ioctl(gLoaderFd, COMBO_IOCTL_SET_CHIP_ID, chipId);
+
+        if (g_remove_ko_flag) {
+                if ((0x0321 == chipId) || (0x0335 == chipId) || (0x0337 == chipId)) {
+                        chipId = 0x6735;
+                }
+                if (0x0326 == chipId) {
+                        chipId = 0x6755;
+                }
+                if (0x0279 == chipId) {
+                        chipId = 0x6797;
+                }
+                do_kernel_module_init(gLoaderFd, chipId);
+                if (gLoaderFd >= 0) {
+                        close(gLoaderFd);
+                        gLoaderFd = -1;
+               }
+
+        } else {
+#if 0
+                if (gLoaderFd >= 0) {
+                        close(gLoaderFd);
+                        gLoaderFd = -1;
+                }
+                ALOGI("rmmod mtk_wmt_detect\n");
+                rmmod("mtk_wmt_detect");
+                /*INSERT TARGET MODULE TO KERNEL*/
+                iRet = insert_wmt_modules(chipId, 0, -1);
+                /*this process should never fail*/
+                if (iRet) {
+                        ALOGI("insert wmt modules fail(%d):(%d)\n", iRet, __LINE__);
+                        /*goto done;*/
+                }
+
+                loadFmResult = load_fm_module(chipId);
+                if (loadFmResult) {
+                        ALOGI("load FM modules fail(%d):(%d)\n", iRet, __LINE__);
+                        /*continue, we cannot let this process interrupted by subsystem module load fail*/
+                        /*goto done;*/
+                }
+
+                loadAntResult = load_ant_module(chipId);
+                if (loadAntResult) {
+                        ALOGI("load ANT modules fail(%d):(%d)\n", iRet, __LINE__);
+                        /*continue, we cannot let this process interrupted by subsystem module load fail*/
+                        /*goto done;*/
+                }
+
+                loadWlanResult = load_wifi_module(chipId);
+                if (loadWlanResult) {
+                        ALOGI("load WIFI modules fail(%d):(%d)\n", iRet, __LINE__);
+                        /*continue, we cannot let this process interrupted by subsystem module load fail*/
+                        /*goto done;*/
+                }
+#endif
+        }
+
+        // chown to set proc owner
+        set_proc_owner();
+        if (0/*0x6630 == chipId*/) {
+                retryCounter = 0;
+                int i_ret = -1;
+                do {
+                        i_ret = loader_wmt_pwr_ctrl(1);
+                        if (0 == i_ret)
+                                break;
+                        else {
+                                loader_wmt_pwr_ctrl(0);
+                                ALOGI("power on %x failed, retrying, retry counter:%d\n", chipId, retryCounter);
+                                usleep(1000000);
+                       }
+                       retryCounter++;
+                } while (retryCounter < 20);
+        }
+
+	//insmod wmt_chrdev_wifi.ko & wlan_gen3.ko
+	loadWlanResult = load_wifi_module(chipId);
+	if (loadWlanResult) {
+		ALOGI("load WIFI modules fail(%d):(%d)\n", iRet, __LINE__);
+	}
+
+        // update wmt driver ready
+        update_driver_ready();
+
+        return iRet;
+}
+
+
+