Add basic change for v1453

Change-Id: I9497a61bbc3717f66413794a4e7dee0347c0bc33
diff --git a/mbtk/mbtk_at/src/factory/mbtk_gpio.c b/mbtk/mbtk_at/src/factory/mbtk_gpio.c
new file mode 100755
index 0000000..df94926
--- /dev/null
+++ b/mbtk/mbtk_at/src/factory/mbtk_gpio.c
@@ -0,0 +1,2006 @@
+/**
+ *   \file gpio-test.c
+ *   \brief A Documented file.
+ *
+ *  Detailed description
+ *   \Author:  Sniper <js.wang@mobiletek.cn>
+ *   \Version: 1.0.0
+ *   \Date: 2022-04-26
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/mman.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <cutils/properties.h>
+#include "mbtk_gpio_def.h"
+#include "gpio-define.h"
+
+#ifndef TRUE
+#define TRUE   1   /* Boolean true value. */
+#endif
+
+#ifndef FALSE
+#define FALSE  0   /* Boolean false value. */
+#endif
+
+#define gpio_log(...)     if(gpio_debug)printf(__VA_ARGS__)
+#define HWMAP_DEVICE "/dev/hwmap"
+#define PAGE_OFFS_BITS(pgsz) ((unsigned int)(pgsz)-1)
+#define PAGE_MASK_BITS(pgsz) (~PAGE_OFFS_BITS(pgsz))
+#define STR_MAX_LEN 220
+typedef enum {
+    MBTK_ADC0 = 0,  /* ADC 0 */
+    MBTK_ADC1       /* ADC 1 */
+} mbtk_adc_enum;
+
+static int gpio_debug = 0;
+#define DEBUG_GPIO_TEST 1
+
+/**/
+#define GPIO_MAX_CURRENT     (7<<10)  //设置GPIO最大输出电流
+#define GPIO_STRONG_PULLUP   (1<<3)   //设置GPIO强上拉
+#define GPIO_PULLUP_ENABLE   ((1<<15)|(1<<14)) //GPIO上拉
+#define GPIO_PULLDOWN_ENABLE ((1<<15)|1<<13) //GPIO下拉
+
+#define MBTK_GPIO_OUTPUT 1
+#define MBTK_GPIO_INPUT  0
+
+#if (defined(MBTK_PROJECT_L508_X6) || defined(MBTK_PROJECT_T108))
+struct gpio_register_function gpio_func_register[128] = {
+    {GPIO_FUNC_GPIO_00, 0},
+    {GPIO_FUNC_GPIO_01, 0},
+    {GPIO_FUNC_GPIO_02, 0},
+    {GPIO_FUNC_GPIO_03, 0},
+    {GPIO_FUNC_GPIO_04, 0},
+    {GPIO_FUNC_GPIO_05, 0},
+    {GPIO_FUNC_GPIO_06, 0},
+    {GPIO_FUNC_GPIO_07, 0},
+    {GPIO_FUNC_GPIO_08, 0},
+    {GPIO_FUNC_GPIO_09, 0},
+    {GPIO_FUNC_GPIO_10, 0},
+    {GPIO_FUNC_GPIO_11, 0},
+    {GPIO_FUNC_GPIO_12, 0},
+    {GPIO_FUNC_GPIO_13, 0},
+    {GPIO_FUNC_GPIO_14, 0},
+    {GPIO_FUNC_GPIO_15, 0},
+    {GPIO_FUNC_GPIO_16, 0},
+    {GPIO_FUNC_GPIO_17, 0},
+    {GPIO_FUNC_GPIO_18, 0},
+    {GPIO_FUNC_GPIO_19, 0},
+    {GPIO_FUNC_GPIO_20, 0},
+    {GPIO_FUNC_GPIO_21, 0},
+    {GPIO_FUNC_GPIO_22, 0},
+    {GPIO_FUNC_GPIO_23, 0},
+    {GPIO_FUNC_GPIO_24, 0},
+    {GPIO_FUNC_GPIO_25, 0},
+    {GPIO_FUNC_GPIO_26, 0},
+    {GPIO_FUNC_GPIO_27, 0},
+    {GPIO_FUNC_GPIO_28, 0},
+    {GPIO_FUNC_GPIO_29, 0},
+    {GPIO_FUNC_GPIO_30, 0},
+    {GPIO_FUNC_GPIO_31, 0},
+    {GPIO_FUNC_GPIO_32, 0},
+    {GPIO_FUNC_GPIO_33, 0},
+    {GPIO_FUNC_GPIO_34, 0},
+    {GPIO_FUNC_GPIO_35, 0},
+    {GPIO_FUNC_GPIO_36, 0},
+	{GPIO_FUNC_GPIO_37, 0}, // GPIO_37
+    {GPIO_FUNC_GPIO_38, 0}, // GPIO_38
+    {GPIO_FUNC_GPIO_39, 0}, // GPIO_39
+    {GPIO_FUNC_GPIO_40, 0}, // GPIO_40
+    {GPIO_FUNC_GPIO_41, 0},  //GPIO_41
+    {GPIO_FUNC_GPIO_42, 0},  //GPIO_42
+    {GPIO_FUNC_GPIO_43, 0},  //GPIO_43
+    {GPIO_FUNC_GPIO_44,0},	//GPIO_44
+	{GPIO_FUNC_GPIO_45,0},	//GPIO_45
+	{GPIO_FUNC_GPIO_46,0},		//GPIO_46
+	{GPIO_FUNC_GPIO_47,0},		//GPIO_47
+    {GPIO_FUNC_SDIO_DAT3, 1}, //GPIO_48
+    {GPIO_FUNC_GPIO_49, 0},
+    {GPIO_FUNC_GPIO_50, 0},
+    {GPIO_FUNC_GPIO_51, 0},
+    {GPIO_FUNC_GPIO_52, 0},
+    {GPIO_FUNC_GPIO_53, 0},
+    {GPIO_FUNC_GPIO_54, 0},
+    {GPIO_FUNC_SDIO_DAT2, 1}, //GPIO_55
+    {GPIO_FUNC_SDIO_DAT1, 1}, //GPIO_56
+    {GPIO_FUNC_SDIO_DAT0, 1}, //GPIO_57
+    {GPIO_FUNC_SDIO_CMD, 1},  //GPIO_58
+    {GPIO_FUNC_SDIO_CLK, 1},  //GPIO_59
+    {GPIO_FUNC_GPIO_60, 0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},
+    {GPIO_FUNC_DVL_0, 1},//GPIO_67
+    {GPIO_FUNC_DVL_1, 1},//GPIO_68
+    {GPIO_FUNC_GPIO_69, 0},
+    {GPIO_FUNC_GPIO_70, 0},
+    {GPIO_FUNC_QSPI_DAT3, 1}, //GPIO_71
+    {GPIO_FUNC_QSPI_DAT2, 1}, //GPIO_72
+    {GPIO_FUNC_QSPI_DAT1, 1}, //GPIO_73
+    {GPIO_FUNC_QSPI_DAT0, 1}, //GPIO_74
+    {GPIO_FUNC_QSPI_CLK, 1},  //GPIO_75
+    {GPIO_FUNC_QSPI_CS1, 1},  //GPIO_76
+    {GPIO_FUNC_GPIO_77, 0},
+    {GPIO_FUNC_GPIO_78, 0},
+    {GPIO_FUNC_GPIO_79, 0},
+    {GPIO_FUNC_GPIO_80, 0},
+    {GPIO_FUNC_USIM_UCLK, 1},//GPIO_81
+    {GPIO_FUNC_USIM_UIO, 1},//GPIO_82
+    {GPIO_FUNC_USIM_URSTn, 1},//GPIO_83
+
+    {GPIO_FUNC_MMC1_DAT3,5},			//GPIO_84
+	{GPIO_FUNC_MMC1_DAT2,5},			//GPIO_85
+	{GPIO_FUNC_MMC1_DAT1,5},			//GPIO_86
+	{GPIO_FUNC_MMC1_DAT0,5},			//GPIO_87
+    {GPIO_FUNC_MMC1_CMD,5},			//GPIO_88
+	{GPIO_FUNC_MMC1_CLK,5},			//GPIO_89
+	{GPIO_FUNC_MMC1_CD,1},						//GPIO_90
+	{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},
+    {GPIO_FUNC_USB_ID, 1},//GPIO_99
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},
+    {GPIO_FUNC_PRI_TDI, 1},         //GPIO_117
+    {GPIO_FUNC_PRI_TMS, 1},         //GPIO_118
+    {GPIO_FUNC_PRI_TCK, 1},         //GPIO_119
+    {GPIO_FUNC_PRI_TDO, 1},         //GPIO_120
+    {GPIO_FUNC_QSPI_VMODE_GPIO, 1}, //GPIO_121
+    {GPIO_FUNC_VBUS_DRV, 1},        //GPIO_122
+    {GPIO_FUNC_CLK_REQ, 1},         //GPIO_123
+    {0,0},
+    {GPIO_FUNC_VCXO_REQ, 1},        //GPIO_125
+	{0,0},							//GPIO_126
+    {GPIO_FUNC_VCXO_OUT, 1},        //GPIO_127
+    {0,0},
+};
+
+#else
+struct gpio_register_function gpio_func_register[128] = {
+    {GPIO_FUNC_GPIO_00, 0},
+    {GPIO_FUNC_GPIO_01, 0},
+    {GPIO_FUNC_GPIO_02, 0},
+    {GPIO_FUNC_GPIO_03, 0},
+    {GPIO_FUNC_GPIO_04, 0},
+    {GPIO_FUNC_GPIO_05, 0},
+    {GPIO_FUNC_GPIO_06, 0},
+    {GPIO_FUNC_GPIO_07, 0},
+    {GPIO_FUNC_GPIO_08, 0},
+    {GPIO_FUNC_GPIO_09, 0},
+    {GPIO_FUNC_GPIO_10, 0},
+    {GPIO_FUNC_GPIO_11, 0},
+    {GPIO_FUNC_GPIO_12, 0},
+    {GPIO_FUNC_GPIO_13, 0},
+    {GPIO_FUNC_GPIO_14, 0},
+    {GPIO_FUNC_GPIO_15, 0},
+    {GPIO_FUNC_GPIO_16, 0},
+    {GPIO_FUNC_GPIO_17, 0},
+    {GPIO_FUNC_GPIO_18, 0},
+    {GPIO_FUNC_GPIO_19, 0},
+    {GPIO_FUNC_GPIO_20, 0},
+    {GPIO_FUNC_GPIO_21, 0},
+    {GPIO_FUNC_GPIO_22, 0},
+    {GPIO_FUNC_GPIO_23, 0},
+    {GPIO_FUNC_GPIO_24, 0},
+    {GPIO_FUNC_GPIO_25, 0},
+    {GPIO_FUNC_GPIO_26, 0},
+    {GPIO_FUNC_GPIO_27, 0},
+    {GPIO_FUNC_GPIO_28, 0},
+    {GPIO_FUNC_GPIO_29, 0},
+    {GPIO_FUNC_GPIO_30, 0},
+    {GPIO_FUNC_GPIO_31, 0},
+    {GPIO_FUNC_GPIO_32, 0},
+    {GPIO_FUNC_GPIO_33, 0},
+    {GPIO_FUNC_GPIO_34, 0},
+    {GPIO_FUNC_GPIO_35, 0},
+    {GPIO_FUNC_GPIO_36,   0},
+    {GPIO_FUNC_MMC1_DAT3, 5}, // GPIO_37
+    {GPIO_FUNC_MMC1_DAT2, 5}, // GPIO_38
+    {GPIO_FUNC_MMC1_DAT1, 5}, // GPIO_39
+    {GPIO_FUNC_MMC1_DAT0, 5}, // GPIO_40
+    {GPIO_FUNC_MMC1_CMD, 5},  //GPIO_41
+    {GPIO_FUNC_MMC1_CLK, 5},  //GPIO_42
+    {GPIO_FUNC_MMC1_CD , 1},  //GPIO_43
+    {0,0},{0,0},{0,0},{0,0},
+    {GPIO_FUNC_SDIO_DAT3, 1}, //GPIO_48
+    {GPIO_FUNC_GPIO_49, 0},
+    {GPIO_FUNC_GPIO_50, 0},
+    {GPIO_FUNC_GPIO_51, 0},
+    {GPIO_FUNC_GPIO_52, 0},
+    {GPIO_FUNC_GPIO_53, 0},
+    {GPIO_FUNC_GPIO_54, 0},
+    {GPIO_FUNC_SDIO_DAT2, 1}, //GPIO_55
+    {GPIO_FUNC_SDIO_DAT1, 1}, //GPIO_56
+    {GPIO_FUNC_SDIO_DAT0, 1}, //GPIO_57
+    {GPIO_FUNC_SDIO_CMD, 1},  //GPIO_58
+    {GPIO_FUNC_SDIO_CLK, 1},  //GPIO_59
+    {GPIO_FUNC_GPIO_60, 0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},
+    {GPIO_FUNC_DVL_0, 1},//GPIO_67
+    {GPIO_FUNC_DVL_1, 1},//GPIO_68
+    {GPIO_FUNC_GPIO_69, 0},
+    {GPIO_FUNC_GPIO_70, 0},
+    {GPIO_FUNC_QSPI_DAT3, 1}, //GPIO_71
+    {GPIO_FUNC_QSPI_DAT2, 1}, //GPIO_72
+    {GPIO_FUNC_QSPI_DAT1, 1}, //GPIO_73
+    {GPIO_FUNC_QSPI_DAT0, 1}, //GPIO_74
+    {GPIO_FUNC_QSPI_CLK, 1},  //GPIO_75
+    {GPIO_FUNC_QSPI_CS1, 1},  //GPIO_76
+    {GPIO_FUNC_GPIO_77, 0},
+    {GPIO_FUNC_GPIO_78, 0},
+    {GPIO_FUNC_GPIO_79, 0},
+    {GPIO_FUNC_GPIO_80, 0},
+    {GPIO_FUNC_USIM_UCLK, 1},//GPIO_81
+    {GPIO_FUNC_USIM_UIO, 1},//GPIO_82
+    {GPIO_FUNC_USIM_URSTn, 1},//GPIO_83
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},
+    {GPIO_FUNC_USB_ID, 1},//GPIO_99
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},{0,0},{0,0},{0,0},
+    {0,0},
+    {GPIO_FUNC_PRI_TDI, 1},         //GPIO_117
+    {GPIO_FUNC_PRI_TMS, 1},         //GPIO_118
+    {GPIO_FUNC_PRI_TCK, 1},         //GPIO_119
+    {GPIO_FUNC_PRI_TDO, 1},         //GPIO_120
+    {GPIO_FUNC_QSPI_VMODE_GPIO, 1}, //GPIO_121
+    {GPIO_FUNC_VBUS_DRV, 1},        //GPIO_122
+    {GPIO_FUNC_CLK_REQ, 1},         //GPIO_123
+    {0,0},
+    {GPIO_FUNC_VCXO_REQ, 1},        //GPIO_125
+    {GPIO_FUNC_VCXO_OUT, 1},        //GPIO_126
+    {0,0},
+};
+
+#endif
+
+static int mbtk_gpio_adc(channel)
+{
+    int ret = 0;
+
+    ret =  mbtk_adc_get(channel);
+#if DEBUG_GPIO_TEST
+    printf("ADC_%d_value =%d\n", channel, ret);
+#endif
+    if(ret >= 500 ){	//TODO: 各项目高电平标准?
+        ret = 1;
+    }
+    else if (ret>=0 && ret<=480){
+        ret = 0;
+    }
+    else{
+        ret = -1;
+    }
+    return ret;
+}
+
+
+static int hwacc_register(int rw, unsigned int addr, unsigned int *data)
+{
+	int fid;
+	unsigned int pagesize, len, len_aligned;
+	unsigned int addr_aligned;
+	volatile unsigned int *pa;
+	void *vpa;
+
+	len = pagesize = sysconf(_SC_PAGESIZE);
+	if((fid = open(HWMAP_DEVICE, O_RDWR)) < 0)
+	{
+		printf("Failed to open %s\n", HWMAP_DEVICE);
+		exit(-1);
+	}
+
+	// Align the length so the mapped area is page-aligned and contains the requested area
+	addr_aligned = addr & PAGE_MASK_BITS(pagesize);
+	len_aligned =((addr + len - addr_aligned) + pagesize - 1) & PAGE_MASK_BITS(pagesize);
+
+	/* Notes on flags: MAP_PRIVATE results in copy on write; MAP_SHARED allows normal write */
+	/*   MAP_SHARED required O_RDWR in open above, otherwise mmap fails with errno=EACCES   */
+	/* Notes on prot:  PROT_WRITE allows read and write; PROT_READ allows read only         */
+	/* Notes on off: an unsigned 32-bit value, should be aligned to page size according to mmap manpage */
+	if((vpa = mmap(0, len_aligned, PROT_READ|PROT_WRITE, MAP_SHARED, fid, addr_aligned)) == MAP_FAILED)
+	{
+		printf("mmap failed (%d)\n", errno);
+	}
+	else
+	{
+		pa = (volatile unsigned int *)((unsigned char *)vpa + (addr & PAGE_OFFS_BITS(pagesize)));
+		if(rw == 0)
+		{
+			*data = *pa;
+			gpio_log("Value read from 0x%.8x via MVA=0x%p is 0x%.8x\n", addr, pa, *data);
+		}
+		else if(rw == 1)
+		{
+			*pa = *data;
+			gpio_log("Value %.8x written to 0x%.8x via MVA=0x%p\n", *data, addr, pa);
+#if defined(HWACC_DEBUG)
+			{
+				unsigned int val;
+				val = *pa;
+				printf("Value read from 0x%.8x via MVA=0x%p is 0x%.8x\n", addr, pa, val);
+			}
+#endif
+		}
+		munmap(vpa, len);
+	}
+
+	close(fid);
+	return 0;
+}
+/*
+设置GPIO 模式:第一步读GPIO22默认function
+root@OpenWrt:/# hwacc r 0xd401e134
+Option = r Addr = d401e134
+Value read from 0xd401e134 via MVA=0x0xb6fc3134 is 0x0000d040   //默认GPIO功能
+Bit0~bit2值对应上面表格各function,0代表GPIO功能
+ */
+static int gpio_register_read(int reg)
+{
+    int ret = -1;
+#if 0
+    FILE * fp;
+    // "/bin/hwacc r 0xd401e134";
+    char command[36] = {0};
+    char buffer[1024];
+    int i = 0;
+
+    sprintf(command, "/bin/hwacc r 0x%x", reg);
+    fp = popen(command, "r");
+    while(1)
+    {
+        if( fgets (buffer, sizeof(buffer), fp)!=NULL ) {
+            buffer[strlen(buffer) - 1] = 0;
+            // gpio_log("out [%d]: %s\n", strlen(buffer), buffer);
+        }else{
+            break;
+        }
+        i = strstr_n(buffer, "is");
+        if(i)
+        {
+            ret = str_to_hex(&buffer[i + 2]);
+            gpio_log("read 0x%x value:%s, %x\n", reg, &buffer[i + 2], ret);
+        }
+    }
+    pclose(fp);
+#else
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+    hwacc_register(0, reg, &ret);
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+#endif
+    return ret;
+}
+/*
+设置输入输出状态,设置PDR寄存器GPIO22为output
+root@OpenWrt:/# hwacc w 0xD401900c 0x00c03800
+Option = w Addr = d401900c Data=00c03800
+Value 00c03800 written to 0xd401900c via MVA=0x0xb6f9f00c
+ */
+static void gpio_register_write(int reg, int value)
+{
+#if 0
+    FILE * fp;
+    //  "/bin/hwacc w 0xD401900c 0x00c03800"
+    char command[36] = {0};
+    char buffer[1024];
+
+    sprintf(command, "/bin/hwacc w 0x%x 0x%x", reg, value);
+    gpio_log("command: %s\n", command);
+    fp = popen(command, "r");
+    while(1)
+    {
+        if( fgets (buffer, sizeof(buffer), fp)!=NULL ) {
+            gpio_log("%s\n", buffer);
+        }else{
+            break;
+        }
+    }
+    pclose(fp);
+
+#else
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+    hwacc_register(1, reg, &value);
+#ifndef MBTK_PROJECT_PN1803
+    usleep(50);
+#endif
+#endif
+}
+/*
+AF SEL<p>This field is used for alternate function selection for a pin.
+It selects between the eight possible alternate functions for the pin.
+Alternate function 0 is always the reset case.
+
+<p>0x0 = Alternate function 0 (primary function at reset)
+<p>0x1 = Alternate function 1
+<p>0x2 = Alternate function 2
+<p>0x3 = Alternate function 3
+<p>0x4 = Alternate function 4
+<p>0x5 = Alternate function 5
+<p>0x6 = Alternate function 6
+<p>0x7 = Alternate function 7
+ */
+static int gpio_register_set_func_0(int port)
+{
+    int ret;
+    struct gpio_register_function *reg = NULL;
+    if(port > 128)
+        return -1;
+    reg = &gpio_func_register[port];
+    if(0 == reg->reg)
+        return -1;
+    ret = gpio_register_read(reg->reg);
+    if((ret & 0x7) != reg->func_gpio)
+    {
+        //printf("Gpio set func [%d] [0x%x]!\n", reg->func_gpio, (ret & 0xfffffff8) | reg->func_gpio);
+        gpio_register_write(reg->reg, (ret & 0xfffffff8) | reg->func_gpio);
+    }
+    return 0;
+}
+/*
+设置GPIO  方向
+读取输入输出状态,读PDR寄存器:0x0c
+root@OpenWrt:/# hwacc r 0xD401900c
+Option = r Addr = d401900c
+Value read from 0xd401900c via MVA=0x0xb6f3900c is 0x00803800  //bit22为0,代表Input
+ */
+static void gpio_register_set_direction(int port, int dir)
+{
+    int ret;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+
+    reg += 0x0c;
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    //printf("[Direction] reg_value=%x\n", ret);
+    // 设置 输出 0 && 1
+    if(!(ret & (0x1 << port)) && dir)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));  //set the gpio bit
+        //printf("[Direction out] reg_value=%x\n",  gpio_register_read(reg));
+    }
+    // 设置 输入 1 && 0
+    if((ret & (0x1 << port)) && !dir)
+    {
+#if 1
+        gpio_register_write(reg, ret & (~(0x1 << port)));  //clear the gpio bit,mbtk_tanggaoyou
+#else
+	     gpio_register_write(reg, ret | !(0x1 << port)); //这是错误配置,实际没有任何作用,还是原来的值
+#endif
+        //printf("[Direction in] reg_value=%x\n",  gpio_register_read(reg));
+    }
+}
+/*
+设置GPIO 输出电平
+
+读取电平状态,先读PLR寄存器:0x00
+root@OpenWrt:/# hwacc r 0xD4019000
+Option = r Addr = d4019000
+Value read from 0xd4019000 via MVA=0x0xb6f1c000 is 0x81e82a30
+对应下面具体BIT
+1000 0001 1110 1000 0010 1010 0011 0000   BIT22默认电平高
+
+设置输出高:设置PSR寄存器:0x18(只写寄存器)
+root@OpenWrt:/# hwacc w 0xD4019018 0x400000
+Option = w Addr = d4019018 Data=00400000
+Value 00400000 written to 0xd4019018 via MVA=0x0xb6f56018 //bit22写1,输出高
+
+设置输出低:设置PCR寄存器:0x24
+root@OpenWrt:/# hwacc w 0xD4019024 0x400000
+Option = w Addr = d4019024 Data=00400000
+Value 00400000 written to 0xd4019024 via MVA=0x0xb6faa024   //Bit22写1,GPIO22输出低
+
+ */
+static void gpio_register_set_value(int port, int value)
+{
+    int ret;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+
+    if(value)
+    {
+        reg += 0x18;
+    }
+    else
+        reg += 0x24;
+
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    //printf("[Value] reg_value=%x\n", gpio_register_read(0xD4019004));
+    // 设置 高电平 0 && 1
+    if(value)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));
+        //printf("[Value high] reg_value=%x\n", gpio_register_read(0xD4019004));
+        return;
+    }
+    // 设置 低电平 1 && 0
+    if(!(ret & (0x1 << port)) && !value)
+    {
+        gpio_register_write(reg, ret | (0x1 << port));
+        //printf("[Value low] reg_value=%x\n", gpio_register_read(0xD4019004));
+    }
+}
+/*
+读取电平状态,先读PLR寄存器:0x00
+root@OpenWrt:/# hwacc r 0xD4019000
+Option = r Addr = d4019000
+Value read from 0xd4019000 via MVA=0x0xb6f1c000 is 0x81e82a30
+对应下面具体BIT
+1000 0001 1110 1000 0010 1010 0011 0000   BIT22默认电平高
+ */
+static int gpio_register_get_value(int port)
+{
+    int ret = -1;
+    int reg = 0xD4019000;
+
+    if(port > (32 - 1))
+        reg = 0xD4019004;
+    if(port > (32 * 2 - 1))
+        reg = 0xD4019008;
+    if(port > (32 * 3 - 1))
+        reg = 0xD4019100;
+    port = port % 0x20;
+    ret = gpio_register_read(reg);
+    if(ret & (0x1 << port))
+    {
+        return 1;
+    }
+    return 0;
+}
+
+void gpio_debug_set(int enable)
+{
+    gpio_debug = enable;
+}
+
+
+
+#if defined(MBTK_PROJECT_PN1803)
+int gpio_register_test_out(int port, int value)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    //usleep(10000);
+    for(i = 0; i <= 35; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+    printf("******gpio should is high: %d.******\n", ret);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    //usleep(10000);
+    for(i = 0; i <= 35; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    //gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    int test_gpio[] = {
+     56, 55, 58, 57, 48, 59, 12, 20, 5, 43, 21,
+     49, 50, 27, 28, 26, 25, 16, 17, 15, 126, 125,
+      4,  0, 3, 18, 7, 6, 1, 2, /*54,*/ 19, 13,
+     32, 31, 23, 24, 22, /*122,*/ 33, 35, 36, 34, 14,
+     99,/* 53,*/ 37, 38, 39, 40, 41, 42};
+
+    int i, j, ret, total, n = 0;
+    int *fail_io = (int *)arg;
+    total = (sizeof(test_gpio)/sizeof(int));
+    //printf("Start test gpio total: %d\n", total);
+
+    /* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+        }
+      //usleep(10000);
+      for(i = 0; i <= 35; i++){
+          ret = mbtk_gpio_adc(0);
+          usleep(3000);
+          if(0 == ret){
+              break;
+          }
+      }
+      printf("pre set ADC: %d, times: %d\n",ret, j);
+      if(0 == ret){
+          break;
+      }
+    }
+	if(0 != ret){
+		printf("Fail, please retest");
+		return -1;
+	}
+
+
+    /* [2 GPIOTEST] */
+    for(i = 0; i < total; i++){
+        ret = gpio_register_test_out(test_gpio[i], 0);
+        if(-1 == ret){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+            fail_io[n] = test_gpio[i];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio[i]);
+        }
+    }
+    mbtk_adc_close();
+    return n;
+}
+
+#elif defined(MBTK_PROJECT_L508)
+
+
+#define READ_GPIO_NUM 22
+
+#define DEBUG_GPIO_TEST 1
+
+mbtk_gpio_test_pin_and_gpio *p_test_gpio =NULL;
+mbtk_gpio_test_pin_and_gpio *p_gnss_gpio = NULL;
+int test_gpio_group_total_pin = 0;
+int gnss_gpio_group_total_pin = 0;
+
+int gpio_test_set_group_pin_to_low(mbtk_gpio_test_pin_and_gpio *p_pin_group_array, int total_num)
+{
+    int i;
+    int gpio_num = 0;
+    int ret = 0;
+
+    if(p_pin_group_array == NULL)
+       return -1;
+
+	for(i=0; i < total_num; i++)
+	{
+       gpio_num = p_pin_group_array[i].gpio_num;
+	   ret += gpio_register_set_func_0(gpio_num);
+	   gpio_register_set_direction(gpio_num, MBTK_GPIO_OUTPUT);
+	   gpio_register_set_value(gpio_num, 0);
+	}
+	return ret;
+}
+
+
+int gpio_test_init(void)
+{
+	int i,j,ret;
+    int gpio_num = 0;
+
+
+
+
+	system("i2cset -y -f 2 0x31 0x12 0x46");
+	system("echo 53 > /sys/class/gpio/export");  //gnss uart rx
+	system("echo out > /sys/class/gpio/gpio53/direction");
+	system("echo 54 > /sys/class/gpio/export");//gnss uart tx
+	system("echo out > /sys/class/gpio/gpio54/direction");
+	system("echo 22 > /sys/class/gpio/export");//check pin
+
+	gpio_register_set_func_0(READ_GPIO_NUM);
+	gpio_register_set_direction(READ_GPIO_NUM, 1);	//输出
+
+	usleep(500);
+/*
+     GPIO22默认是上拉,如果改成GPIO输入模式,其PIN脚电压是高电平,必须改成下拉后GPIO22才处于低电平状态,否则测试PIN拉低失败
+*/
+	gpio_register_set_direction(READ_GPIO_NUM, MBTK_GPIO_INPUT);	//设置输入模式
+	gpio_register_write(GPIO_FUNC_GPIO_22,0xb040);  //PULL DOWN
+
+
+    gpio_test_set_group_pin_to_low(p_gnss_gpio,gnss_gpio_group_total_pin); //set all gnss reserver pin to low
+
+
+	/* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+         gpio_test_set_group_pin_to_low(p_test_gpio,test_gpio_group_total_pin);
+
+		for(i = 0; i <= 5; i++){
+			ret = gpio_register_get_value(READ_GPIO_NUM);
+			if(0 == ret){
+				break;
+			}
+			usleep(3000);
+		}
+
+		if(0 == ret){
+			break;
+		}
+	}
+
+	if(0 != ret){
+		printf("[GPIOTEST]set all low Fail, please retest\n");
+		return -1;
+	}
+	printf("[GPIOTEST]pre set SUCCESS\n");
+	return 0;
+}
+
+int gpio_test(void* arg,int index,mbtk_gpio_test_pin_and_gpio *p_pin_group_array,int total)
+{
+	int ret,i;
+	int *fail_io = (int *)arg;
+	int failed_num = index;
+	int gpio_num = 0;
+	int pin_num = 0;
+    bool falied_flag = FALSE;
+
+	for(i = 0; i < total; i++){
+        gpio_num = p_pin_group_array[i].gpio_num;
+		pin_num = p_pin_group_array[i].pin_num;
+		falied_flag = FALSE;
+
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d default value= %d\n", pin_num, ret);
+#endif
+
+		//set high
+		gpio_register_set_value(gpio_num, 1);
+
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d set high= %d\n", pin_num, ret);
+#endif
+		//get
+		ret = gpio_register_get_value(READ_GPIO_NUM);
+		if(1 != ret){
+            printf("[GPIOTEST]pin%d test high failed\n", pin_num);
+            falied_flag = TRUE;
+        }else{
+            printf("[GPIOTEST]pin[%d] test high success\n", pin_num);
+        }
+
+		//set low
+	    gpio_register_set_value(gpio_num, 0);
+#if DEBUG_GPIO_TEST
+		ret = gpio_register_get_value(gpio_num);
+		printf("[GPIOTEST]pin_num%d set low= %d\n", pin_num, ret);
+#endif
+		//get
+		ret = gpio_register_get_value(READ_GPIO_NUM);
+		if(0 != ret){
+            printf("[GPIOTEST]pin_num%d test low failed\n", pin_num);
+			falied_flag = TRUE;
+
+        }else{
+            printf("[GPIOTEST]pin_num%d test low success\n", pin_num);
+        }
+
+		if(falied_flag)
+		{
+            fail_io[failed_num] = p_pin_group_array[i].pin_num;
+#if DEBUG_GPIO_TEST
+		 printf("[GPIOTEST]NO.%d pin_num%d failed %d\n",i,pin_num, failed_num);
+#endif
+			failed_num++;
+		}
+	}
+	return failed_num;
+}
+
+
+int mbtk_at_gpio(bool gnss_support,void* arg)
+{
+	int n = 0;
+	mbtk_gpio_test_pin_and_gpio test_gpio[] =
+	{
+		//{GPIO , PIN}
+		{0,100}, //RMII_RX-DV
+		{1,101}, //RMII_RXD0
+		{2,102},//RMII_RXD1
+		{3,103},//RMII_CLK
+		{6,104},//RMII_TXD0
+		{7,105},//RMII_TXD1
+		{15,106},//RMII_TX_EN
+		{16,109},//RMII_MDC
+		{17,110},//RMII_MDIO
+		{18,107},//RMII_INT
+		{99,16},//USB_ID
+		{34,9}, //SPI0_CS
+		{36,8},//SPI0_TXD
+		{35,7},//SPI0_RXD
+		{33,6},//SPI0_CLK
+		{14,51}, //NET_LIGHT
+		{13,49}, //STATUS LED
+		{12,50},//WAKE_IN
+		{49,55}, //I2C SCL
+		{50,56}, //I2C SDA
+		{19,53}, //USIM_DET
+		{43,48}, //SD_DET
+		{118,52}, //WAKE OUT
+		{120,54}, //FLIGHT MODE
+
+
+		{20,45}, //NORMAL GPIO
+		{59,122},  //SDIO_CLK
+		{56,117}, //SDIO_DATA1
+		{55,118},//SDIO_DATA2
+		{58,119},//SDIO_CMD
+		{48,120},//SDIO_DATA3
+		{57,121},//SDIO_DATA0
+		{5,84}, //NORMAL GPIO
+		{4,30},//NORMAL GPIO
+		{21,28}, //NORMAL GPIO
+		{23,69}, //UART_RING
+		{24,70}, //UART_DCD
+		{27,73}, //PCM_OUT
+		{28,74}, //PCM_IN
+		{26,75}, //PCM_SYNC
+		{25,76}, //PCM_CLK
+
+		{126,112},//NORMAL GPIO or pwm3
+		{117,123},	//PWM
+		{125,116}, //CLK_REQ
+
+		//{54,114}, //debug uart2, no need be tested
+		//{53,115}, //debug uart2, no need be tested
+
+	};
+
+	mbtk_gpio_test_pin_and_gpio GNSS_test_gpio[] = {
+		{54,114}, //GPS UTXD, UART1_TXD,L508LAN+L508CN(D)+L508EN+L508LEN+L508TLCN NOT CONNECTED
+		{53,115}, //GPS URXD,UART1-RXD,L508LAN+L508CN(D)+L508EN+L508LEN+L508TLCN NOT CONNECTED
+		{32,66}, //PIN66,host wake GPS, RTS, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{31,67}, //PIN67,GPS wake Host,CTS, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{123,42},//GPS_EN, L508TLCN_V2+L508LEN_V2+L508EN_V2 NOT CONNECTED
+		{122,35},  //32K OUT, L508TLCN_V2+L508LEN_V2+L508EN_V2 not connected
+	};
+	p_gnss_gpio = GNSS_test_gpio;
+	gnss_gpio_group_total_pin = (sizeof(GNSS_test_gpio)/sizeof(GNSS_test_gpio[0]));
+
+    p_test_gpio = test_gpio;
+	test_gpio_group_total_pin = (sizeof(test_gpio)/sizeof(test_gpio[0]));
+
+   if(!gnss_support)
+       n = test_gpio_group_total_pin+gnss_gpio_group_total_pin;
+    else
+       n = test_gpio_group_total_pin;
+
+	printf("[init] L508 XX GPIOTEST v1.3 total pin=%d\n",n);
+
+	n = gpio_test_init();
+	if(-1 == n)
+	{
+		goto gpiotest_finished;
+	}
+    n = 0;
+
+	n = gpio_test(arg,0,p_test_gpio,test_gpio_group_total_pin);
+
+   //if the module has gnss chip, don't test the gnss's pins
+    if(!gnss_support)
+	{
+    	n = gpio_test(arg,n,p_gnss_gpio,gnss_gpio_group_total_pin);
+	}
+
+gpiotest_finished:
+	system("echo 53 > /sys/class/gpio/unexport"); //unexport gnss uart rx
+	system("echo 54 > /sys/class/gpio/unexport");//unexportgnss uart tx
+	system("echo 22 > /sys/class/gpio/unexport");//unexportcheck pin
+
+	printf("\n[GPIOTEST] Finished %d!!\n\n",n);
+	return n;
+}
+
+
+
+#elif defined(MBTK_PROJECT_L509)
+//测低
+static uint16 mbtk_gpio_test_all_low(mbtk_gpio_paired_info_struct *pin_array, uint16 MAX_pin_num)
+{
+    uint16 index = 0;
+    uint16 OUT_pin, Read_pin;
+    uint32 read_high_value;
+    uint32 read_low_value;
+    uint16 fail_num = 0;
+    //int res;
+
+    printf("[GPIOTEST][run test all pin low]\n");
+
+    for(index = 0; index < MAX_pin_num; index++){
+       OUT_pin = pin_array[index].output_gpio;
+       Read_pin = pin_array[index].input_gpio;
+
+       //输出低
+       gpio_register_set_direction(OUT_pin, 1);
+       gpio_register_set_value(OUT_pin, 0);
+
+       //输入脚设为输入
+       gpio_register_set_direction(Read_pin,0);
+   }
+
+    for(index = 0; index < MAX_pin_num; index++){
+        OUT_pin = pin_array[index].output_gpio;
+        Read_pin = pin_array[index].input_gpio;
+        read_low_value = gpio_register_get_value(Read_pin);
+
+        //结果检测
+        if(read_low_value != 0){
+           printf("[GPIOTEST][!Low Failed!]: GPIO%d PIN%d\n", Read_pin, pin_array[index].input_pin);
+           pin_array[index].mbtk_gpio_test_result = 1;
+           fail_num ++;
+        }
+#if DEBUG_GPIO_TEST
+        else{
+			printf("[GPIOTEST][-Low Success-]: GPIO%d \n", Read_pin);
+        }
+#endif
+    }
+    return fail_num;
+}
+
+
+//测高
+static uint16 mbtk_gpio_test_pin_high(mbtk_gpio_paired_info_struct *pin_array, uint16 MAX_pin_num)
+{
+    uint16 index = 0;
+    uint16 OUT_pin, Read_pin;
+    uint32 read_high_value;
+    uint32 read_low_value;
+    uint16 fail_num = 0;
+    int i = 0;
+
+    printf("[GPIOTEST][run test pin high]\n");
+
+    for(index = 0; index < MAX_pin_num; index++){
+        OUT_pin = pin_array[index].output_gpio;
+        Read_pin = pin_array[index].input_gpio;
+
+        //设高
+        gpio_register_set_direction(OUT_pin,1);
+        gpio_register_set_direction(Read_pin,0);
+        gpio_register_set_value(OUT_pin, 1);
+        usleep(10000);
+        read_high_value = gpio_register_get_value(Read_pin);
+#if DEBUG_GPIO_TEST
+        printf("[GPIOTEST][test_high]: PIN%d: get value =%d \n", pin_array[index].input_pin, read_high_value);
+#endif
+
+        //设高后重新设低
+        usleep(10000);
+        gpio_register_set_value(OUT_pin, 0);
+        usleep(10000);
+        for(i = 0; i < 10; i++){
+            read_low_value = gpio_register_get_value(Read_pin);
+            if(0 == read_low_value){
+                break;
+            }
+            usleep(20000);
+        }
+#if DEBUG_GPIO_TEST
+		printf("[GPIOTEST][test_low]: PIN%d: get value =%d  \n", pin_array[index].input_pin, read_low_value);
+#endif
+		if(read_high_value != 1 || read_low_value != 0){
+			printf("[GPIOTEST][!High Failed!]: Gpio%d PIN%d\n", Read_pin,pin_array[index].input_pin);
+			pin_array[index].mbtk_gpio_test_result = 2;
+			fail_num ++;
+        }
+#if DEBUG_GPIO_TEST
+        else{
+            printf("[GPIOTEST][-High Success-]: Gpio%d \n", Read_pin);
+		}
+#endif
+    }
+	return fail_num;
+}
+
+
+static void gpio_test_init_test_gpio_mode(mbtk_gpio_paired_info_struct pin_array[], int MAX_pin_num)
+{
+	int index = 0;
+	int OUT_pin, Read_pin;
+
+	printf("[GPIOTEST] L509 GPIOTEST v2.2 --init\n");
+
+	gpio_register_set_func_0(125);
+	gpio_register_set_direction(125, 1);
+	gpio_register_set_value(125, 1);			//RS2299开关的使能脚
+
+	system("i2cset -y -f 2 0x31 0x12 0x46");	//使能0x12地址的VLDO, 某组GPIO的供电
+
+	gpio_register_write(GPIO_FUNC_GPIO_53, 0xb040);  //GPIO53 DTR set PULL DOWN
+
+	for(index = 0; index < MAX_pin_num; index++){
+		OUT_pin = pin_array[index].output_gpio;
+		Read_pin = pin_array[index].input_gpio;
+		pin_array[index].mbtk_gpio_test_result = 0;	 //init as passed
+		gpio_register_set_func_0(OUT_pin);
+		gpio_register_set_func_0(Read_pin);
+		gpio_register_set_value(OUT_pin, 0);
+	}
+
+#if DEBUG_GPIO_TEST
+	printf("[GPIOTEST]gpio_test_init_test_gpio_mode FINISH\n");
+#endif
+
+}
+
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+	int i, num;
+	int *fail_io = (int *)arg;
+	/*OPEN SWITCH */
+	uint16 test_fail_count = 0;
+	uint16 test_MAX_pin_num = 0;
+	char buf[STR_MAX_LEN];
+	//uint16 str_len = 0;
+	uint16 temp_len =0;
+	uint16 Out_pin;
+	uint16 in_pin;
+	//uint16 fail_print_num = 0;
+
+	mbtk_gpio_paired_info_struct  test_pin_array[] ={
+        //output_pin, output_gpio,    input_gpio, input_pin,    test_result
+        {122, 16,	 	   17,  121,         0},		/* RGMII/RMII_MD_CLK	<---SW RS2299--->		RGMII/RMII_MD_IO	*/
+
+        {78,  7,           2,   73, 	     0},		/* RGMII/RMII_TX_1		<---SW RS2299--->		RGMII/RMII_RXD1		*/
+        {77,  6,           1,   76,          0}, 	    /* RGMII/RMII_TXD0		<---SW RS2299--->		RGMII/RMII_RXD0		*/
+        {81,  15,          3,   75, 	     0},		/* RGMII/RMII_TX_EN		<---SW RS2299--->		RGMII/RMII_CLK		*/
+        {74,  0,           18,  120,	     0},		/* RGMII/RMII_RX_DV		<---SW RS2299--->		RGMII/RMII_INT		*/
+
+        {1,   117,         120, 2,	         0}, 	    /* WAKEUP_IN			<---SW RS2299--->		AP_READY			*/
+        {4,   118,         19,  13,	         0},		/* FLIGHTMODE			<---SW RS2299--->		USIM_CD				*/
+        {5,   123,         126, 6,           0},		/* NET_MODE				<---SW RS2299--->		NET_STATUS			*/
+        {23,  43,          23,  62, 	     0},		/* MMC1_CD				<---SW RS2299--->		UART_RI				*/
+
+        {79,  4,           5,   82, 	     0},		/* RGMII_RX_2			<---SW RS2299--->		RGMII_RX_3			*/
+        {80,  13,          14,  84, 	     0},		/* RGMII_TX_2			<---SW RS2299--->		RGMII_TX_3			*/
+        {129, 48,          55,  130,	     0},		/* WLAN_DAT3			<---SW RS2299--->		WLAN_DAT2			*/
+        {131, 56,          57,  132,	     0},		/* WLAN_DAT1			<---SW RS2299--->		WLAN_DAT0			*/
+
+        {24,  28,          27,  25,          0},		/* PCM_IN				<---SW RS2299--->		PCM_OUT				*/
+        {26,  26,          25,  27, 	     0},		/* PCM_SYNC				<---SW RS2299--->		PCM_CLK				*/
+        {37,  34,          33,  40, 	     0}, 	    /* SPI_CS				<---SW RS2299--->		SPI_CLK				*/
+        {38,  36,          35,  39, 	     0},		/* SPI_DOUT				<---SW RS2299--->		SPI_DIN				*/
+
+        {133, 59,          58,  134,	     0},		/* WLAN_CLK/PCIE_RSTN	<---SW RS2299--->		WLAN_CMD/PCIE_WK	*/
+        {135, 21,          99,  139,	     0},		/* WLAN_WAKE_HOST		<---SW RS2299--->		USB_ID				*/
+        {119, 20,          22,  136,	     0}, 	    /* RGMII/RMII_RST_N		<---SW RS2299--->		WLAN_EN				*/
+        {83,  12,          122, 118,	     0},        /* RGMII_CLK_TX			<---SW RS2299--->		WLAN_SLP_CLK		*/
+
+        {41,  49,          50,  42, 	     0},		/* I2C_SCL				<---SW RS2299--->		I2C_SDA				*/
+        {143, 10,          11,  144,	     0},		/* GRFC1				<---SW RS2299--->		GRFC2				*/
+        {64,  32,          31,  65, 	     0},		/* UART_CTS				<---SW RS2299--->		UART_RTS			*/
+        {63,  54,          53,  66, 	     0},        /* UART_DCD				<---SW RS2299--->		UART_DTR			*/
+    };
+
+
+	/* [1]初始化待测GPIO */
+	test_MAX_pin_num = sizeof(test_pin_array) / sizeof(test_pin_array[0]);
+    if(gnss_support){    //TODO: When the hardware does not have GNSS, do not test GPIO53, 54
+                          //bad implement, need modify
+        test_MAX_pin_num = test_MAX_pin_num - 1;
+    }
+	gpio_test_init_test_gpio_mode(test_pin_array, test_MAX_pin_num);
+
+
+	/* [2]测试过程 */
+	test_fail_count = mbtk_gpio_test_all_low(test_pin_array, test_MAX_pin_num);
+
+	if(!test_fail_count){ //set all pin to low success
+		printf("[GPIOTEST]set all pin to low: success\n");
+		test_fail_count = mbtk_gpio_test_pin_high(&test_pin_array, test_MAX_pin_num);
+	}
+	else{
+		printf("[GPIOTEST]set all pin low: failed num=%d!!!\n", test_fail_count);
+	}
+
+
+	//memset(buf,0,STR_MAX_LEN);
+	/* [3]测试结果检测与上报 */
+	if(test_fail_count ){
+		//printf( "GPIOTEST Fail %02d PINs:\n", test_fail_count*2);
+		sprintf(buf, "GPIOTEST Fail %02d PINs:", test_fail_count * 2);
+		temp_len = strlen(buf);
+
+		num = 0;
+		for(i = 0; i < test_MAX_pin_num; i++){
+			if(test_pin_array[i].mbtk_gpio_test_result){
+				Out_pin = test_pin_array[i].output_pin;
+				in_pin = test_pin_array[i].input_pin;
+				fail_io[num++] = Out_pin;
+				fail_io[num++] = in_pin;
+			}
+		}
+	}
+
+	else{
+		printf(buf, "ALL GPIO TEST PASS\r\n");
+	}
+
+    printf("\n[GPIOTEST] Finished !!\n\n");
+	return  test_fail_count * 2;
+}
+
+
+#elif defined(MBTK_PROJECT_L508_X6)
+int gpio_register_test_out_0(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+	//printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(0);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+	gpio_register_set_value(port, 0);
+    //gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int gpio_register_test_out_1(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is : %d.\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+    usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(1);
+        usleep(3000);
+        if(1 == ret){
+            break;
+        }
+    }
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+    //printf("******gpio should is high: %d.******\n", ret);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+    usleep(10000);
+    for(i = 0; i <= 10; i++){
+        ret = mbtk_gpio_adc(1);
+        usleep(3000);
+        if(0 == ret){
+            break;
+        }
+    }
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port, 0);
+    //error: no need set direction in gpio_register_set_direction(port, 0);
+    return ret;
+}
+
+
+int gpio_register_test_out_2(int port_in, int port_out)
+{
+    int ret_in;
+	int ret_out;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port_out);
+    ret_in = gpio_register_set_func_0(port_in);           //设功能为GPIO
+	ret_out = gpio_register_set_func_0(port_out);
+    if((ret_in+ret_out)){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port_out, 1);           //设方向为输出
+	gpio_register_set_direction(port_in, 0);           //设方向为输入
+    //ret_in = gpio_register_get_value(port_in);
+    //printf("gpio default value is : %d.\n", ret_in);
+
+
+    //[High]
+    for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port_out, 1);
+        usleep(50);
+        valueh = gpio_register_get_value(port_out);
+        //printf("set high? %d\n",valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+	usleep(5000);
+    for(i = 0; i <= 10; i++){
+       ret_in = gpio_register_get_value(port_in);
+        usleep(3000);
+        if(1 == ret_in){
+            break;
+        }
+    }
+    if(1 != ret_in){
+        ret_in=-1;
+		printf("get high failed! \n");
+        goto exit;
+    }
+    //printf("******gpio should is high: %d.******\n", ret_in);
+
+
+    //[Low]
+     usleep(200);
+     for(i = 0; i <= 10; i++){
+        gpio_register_set_value(port_out, 0);               //输出低
+        usleep(50);
+        valuel = gpio_register_get_value(port_out);
+        //printf("set low? %d\n",valuel);
+        if(0 == valuel){
+            break;
+        }
+    }
+
+	usleep(5000);
+    for(i = 0; i <= 10; i++){
+        ret_in = gpio_register_get_value(port_in);
+        usleep(3000);
+        if(0 == ret_in){
+            break;
+        }
+    }
+    //printf("******gpio should is low: %d.******\n", ret_in);
+    if(0 != ret_in){
+        ret_in=-1;
+		printf("get low failed! \n");
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port_out, 0);
+    //gpio_register_set_direction(port_out, 0);
+    return ret_in;
+}
+
+
+static int gpio_test_init_test_gpio_mode(void )
+{
+	const int test_gpio_1[] = {
+		40, 33, 34, 39, 99, 10, 11, 88, 87, 86, 85, 84, 89,
+		56, 55, 58, 57, 48, 59, 10, 90, 20, 53, 19, 46, 127,
+		49, 50, 32, 31, 6, 7
+	};
+
+	const int test_gpio_0[] = {
+		8, 27, 28, 26, 25, 15, 1, 3, 0,
+		37, 38,35, 36, 42, 41, 21, 22, 24, 23,
+		54, 125, 18, 13, 14, 17, 16, 5, 4, 2, 12,
+		43, 44, 45, 47, 117, 119
+	};
+    int i, j, ret_0, ret_1, total_1, total_0, n = 0;
+    total_0 = (sizeof(test_gpio_0)/sizeof(int));
+    total_1 = (sizeof(test_gpio_1)/sizeof(int));
+
+	//system("at at+gpsinit=0");
+	system("i2cset -y -f 2 0x32 0x0d 0x00");
+	system("i2cset -y -f 2 0x31 0x18 0x8f");
+	usleep(10000);
+
+       //printf("[init]gpio_test_init_test_gpio_mode FINISH\n");
+		/* [1 all gpio set to low] */
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total_0; i++){
+            gpio_register_set_func_0(test_gpio_0[i]);
+            gpio_register_set_direction(test_gpio_0[i], 1);
+            gpio_register_set_value(test_gpio_0[i], 0);
+        }
+        for(i = 0; i < total_1; i++){
+            gpio_register_set_func_0(test_gpio_1[i]);
+            gpio_register_set_direction(test_gpio_1[i], 1);
+            gpio_register_set_value(test_gpio_1[i], 0);
+        }
+
+        usleep(50000);
+        for(i = 0; i <= 10; i++){
+            ret_0 = mbtk_gpio_adc(0);
+            usleep(3000);
+            ret_1 = mbtk_gpio_adc(1);
+
+            if(ret_0 ==0  && ret_1 == 0){
+                break;
+            }
+        }
+        printf("pre set ADC0: %d, ADC1: %d, times: %d\n", ret_0, ret_1, j);
+        if(ret_0 ==0  && ret_1 == 0){
+            break;
+        }
+    }
+	if(!(ret_0 ==0  && ret_1 == 0)){
+
+		printf("Fail, please retest");
+		return -1;
+	}
+	gpio_register_set_value(119, 1);
+	gpio_register_set_value(117, 1);
+    return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+	const int test_gpio_0[] = {
+		35, 93,
+		36, 94,
+		42, 97,
+		41, 98,
+		21, 100,
+		22, 101,
+		24, 102,
+		23, 103,
+		54, 107,
+		125, 108,
+		18, 109,
+		13, 114,
+		14, 115,
+		17, 116,
+		16, 117,
+		5, 119,
+		4, 127,
+		2, 120,
+		12, 126,
+		0, 90,
+		27, 73,
+		28, 74,
+		26, 75,
+		25, 76,
+		15, 86,
+		1, 88,
+		3, 89,
+		37, 91,
+		38, 92,
+		8, 72
+	};
+
+    const int test_gpio_1[] = {
+		40,	6,
+		33, 7,
+		34, 8,
+		39, 9,
+		99, 16,
+		56, 27,
+		58, 29,
+		55, 28,
+		57, 30,
+		48, 31,
+		59, 32,
+		20, 49,
+		53, 50,
+		19, 51,
+		49, 55,
+		50, 56,
+		32, 66,
+		31, 67,
+		6, 68,
+		11, 83,
+		10, 84,
+		7, 69,
+		90, 48,
+		46, 52,
+		127, 54,
+		88, 21,
+		87, 22,
+		86, 23,
+		85, 24,
+		84, 25,
+		89, 26,
+	};
+
+	const int test_gpio_2[] = {		//GPS组
+		43, 53,
+		47, 95,
+		45, 71,
+		44, 70,
+	};
+
+    int i, j, ret_0, ret_1, ret_2, total_1, total_0, total_2, n = 0;
+    int *fail_io = (int *)arg;
+    total_0 = (sizeof(test_gpio_0)/sizeof(int));	//GPIO+PIN
+    total_1 = (sizeof(test_gpio_1)/sizeof(int));
+	total_2 = (sizeof(test_gpio_2)/sizeof(int));
+	if(gnss_support == 1){
+		total_2 = total_2 - 4;
+	}
+    printf("L508-X6 Start test gpio V1.1\n");
+    /* [1 all gpio Init] */
+    gpio_test_init_test_gpio_mode();
+
+
+    /* [2 GPIOTEST] */
+	//Test 0
+	for(i = 0; i < total_0; i=i+2){
+        ret_0 = gpio_register_test_out_0(test_gpio_0[i]);
+        if(-1 == ret_0){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_0[i]);
+            fail_io[n] = test_gpio_0[i+1];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_0[i]);
+        }
+    }
+
+	//Test 1
+    for(i = 0; i < total_1; i=i+2){
+        ret_1 = gpio_register_test_out_1(test_gpio_1[i]);
+        if(-1 == ret_1){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_1[i]);
+            fail_io[n] = test_gpio_1[i+1];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_1[i]);
+        }
+    }
+
+	//Test 2
+    for(i = 0; i < total_2; i=i+4){
+        ret_2 = gpio_register_test_out_2(test_gpio_2[i], test_gpio_2[i+2]);
+        if(-1 == ret_2){
+            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio_2[i+2]);
+            fail_io[n] = test_gpio_2[i+3];
+            n++;
+        }else{
+            //printf("############gpio [%d] test success############\n", test_gpio_2[i+2]);
+        }
+    }
+
+    mbtk_adc_close();
+    return n;
+}
+
+#elif 0//(MBTK_PROJECT_T108)
+int gpio_register_test_out(int port, int value)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);           //设功能为GPIO
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);           //设方向为输出
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is: %d\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 9; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        //valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n", valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+    for(i = 0; i <= 35; i++){
+        ret = gpio_register_get_value(118);
+        if(1 == ret){
+            break;
+        }
+		usleep(3000);
+    }
+	printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+    //[Low]
+	usleep(200);
+	for(i = 0; i <= 9; i++){
+		gpio_register_set_value(port, 0);               //输出低
+		usleep(50);
+		//valuel = gpio_register_get_value(port);
+		//printf("set low? %d\n", valuel);
+		if(0 == valuel){
+			break;
+		}
+	}
+
+    for(i = 0; i <= 35; i++){
+        ret = gpio_register_get_value(118);
+        if(0 == ret){
+            break;
+        }
+        usleep(3000);
+    }
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+	gpio_register_set_value(port, 0);
+    gpio_register_set_direction(port, 0);  //设方向为输入
+    return ret;
+}
+
+int gpio_test_init_test_gpio_mode(void)
+{
+    const int test_gpio[] = {
+		99,
+		117,
+		21,22,23,24,44,41,120,
+		8,127,46,59,58,57,56,55,48,19,34,33,35,36,49,
+		50,25,28,26,122,20,10,11,
+		39,40,37,38,
+		51,52,31,32,
+	};
+
+    int i, j, ret, total, n = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+    printf("[init]gpio_test_init_test_gpio_mode BEGIN\n");
+
+	/* [1 all gpio set to low] */
+	gpio_register_set_func_0(118);
+	gpio_register_set_direction(118, 0);
+	system("echo in  > /sys/class/gpio/gpio118/direction");
+
+    for(j = 0; j < 6 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+			//ret = gpio_register_get_value(test_gpio[i]);
+			//printf("[init]get gpio%d=%d\n", test_gpio[i], ret);
+        }
+
+		for(i = 0; i <= 35; i++){
+		  ret = gpio_register_get_value(118);
+		  printf("[init]get gpi118=%d\n", ret);
+		  usleep(3000);
+		  if(0 == (ret)){
+			  break;
+		  }
+		}
+
+		printf("pre set ADC: %d, times: %d\n",(ret), j);
+		if(0 == (ret)){
+		  break;
+		}
+    }
+	if(0 != (ret)){
+		printf("!!!Set all low FAIL, please retest\n");
+		return -1;
+	}
+	return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+
+    const int test_gpio[] = {
+	  //GPIO	PIN		GPIO	PIN		GPIO	PIN		GPIO	PIN
+		99,		170,	117,	59,		21,		61,		22,		62,
+		23,		144,	24,		147,	44,		5,		41,		159,
+		120,	143,	8,		171,	127,	160,	46,		149,
+		59,		19,		58,		18,		57,		20,		56,		21,
+		55,		22,		48,		23,		19,		3,		34,		79,
+		33,		80,		35,		78,		36,		77,		49,		43,
+		50,		42,		25,		67,		28,		66,		26,		65,
+		122,	169,	20,		152,	10,		74,		11,		73,
+		39,		166,	40,		164,	37,		165,	38,		163,
+		51,		58,		52,		60,		31,		57,		32,		56,
+	};
+
+    int i, n = 0, ret, total;
+    int *fail_io = (int *)arg;
+	int try_count = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+	printf("T108 Start test gpio V1.0, total gpio=%d\n", (total/2));
+
+	for(try_count; try_count < 4; try_count++){
+	    n = 0;
+	    /* [1 all gpio Init] */
+	    gpio_test_init_test_gpio_mode();
+
+	    /* [2 GPIOTEST] */
+		for(i = 0; i < total; i = i + 2){
+	        ret = gpio_register_test_out(test_gpio[i], 0);
+	        if(-1 == ret){
+				n++;
+	            printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+				if(try_count != 3){
+					printf(" ---TEST FAILED! RETRY!--- \n");
+        			usleep(5000);
+					break;
+				}
+	            fail_io[n - 1] = test_gpio[i+1];
+	        }else{
+	            //printf("############gpio [%d] test success############\n", test_gpio[i]);
+	        }
+	    }
+	    if(0 == n){
+	    	break;
+		}
+    }
+    return n;
+}
+
+
+#elif (MBTK_PROJECT_T108)
+static int gpio_test(int port)
+{
+    int ret;
+    int i;
+    int valueh = 0;
+    int valuel = 1;
+
+    //printf("Gpio port [%d] test start!\n", port);
+    ret = gpio_register_set_func_0(port);
+    if(ret){
+        printf("gpio_port can't support!\n");
+        return -1;
+    }
+    gpio_register_set_direction(port, 1);
+    //ret = gpio_register_get_value(port);
+    //printf("gpio default value is: %d\n", ret);
+
+
+    //[High]
+    for(i = 0; i <= 5; i++){
+        gpio_register_set_value(port, 1);
+        usleep(50);
+        //valueh = gpio_register_get_value(port);
+        //printf("set high? %d\n", valueh);
+        if(1 == valueh){
+            break;
+        }
+    }
+
+    for(i = 0; i <= 5; i++){
+        ret = gpio_register_get_value(118);
+        if(1 == ret){
+
+            break;
+        }
+		usleep(3000);
+    }
+    //printf("count=%d \n", i);
+  	//printf("******gpio should is high: %d.******\n", ret);
+    if(1 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+    //[Low]
+	usleep(200);
+	for(i = 0; i <= 9; i++){
+		gpio_register_set_value(port, 0);
+		usleep(50);
+		//valuel = gpio_register_get_value(port);
+		//printf("set low? %d\n", valuel);
+		if(0 == valuel){
+			break;
+		}
+	}
+
+    for(i = 0; i <= 5; i++){
+        ret = gpio_register_get_value(118);
+        if(0 == ret){
+
+            break;
+        }
+        usleep(3000);
+    }
+    //printf("count=%d \n", i);
+    //printf("******gpio should is low: %d.******\n", ret);
+    if(0 != ret){
+        ret=-1;
+        goto exit;
+    }
+
+exit:
+    gpio_register_set_value(port, 0);
+    gpio_register_set_direction(port, 0);
+    return ret;
+
+}
+
+static int gpio_test_init_test_gpio_mode(void)
+{
+	const int test_gpio[] = {
+      99,8,117,21,22,23,24,41,120,19,123,
+      58,59,57,56,55,48,125,127,36,35,34,
+      33,54,47,53,46,50,49,11,10,26,28,25,
+      27,32,31,51,52,39,40,37,38,
+      44,45
+	};
+
+    int i, j, ret, total, n = 0;
+    total = (sizeof(test_gpio)/sizeof(int));
+    //printf("[init]gpio_test_init_test_gpio_mode BEGIN\n");
+
+	/* [1 all gpio set to low] */
+	gpio_register_set_func_0(118);
+	gpio_register_set_direction(118, 0);
+
+    for(j = 0; j < 5 ; j++){
+        for(i = 0; i < total; i++){
+            gpio_register_set_func_0(test_gpio[i]);
+            gpio_register_set_direction(test_gpio[i], 1);
+            gpio_register_set_value(test_gpio[i], 0);
+			//ret = gpio_register_get_value(test_gpio[i]);
+			//printf("[init]get gpio%d=%d\n", test_gpio[i], ret);
+        }
+
+
+		for(i = 0; i <= 10; i++){
+		  ret = gpio_register_get_value(118);
+		  //printf("[init]get gpi118=%d\n", ret);
+		  usleep(3000);
+		  if(0 == (ret)){
+			  break;
+		  }
+		}
+
+		//printf("pre set 118: %d, times: %d\n",(ret), j);
+		if(0 == (ret)){
+		  break;
+		}
+    }
+	if(0 != (ret)){
+		printf("!!!Set all low FAIL, please retest\n");
+		return -1;
+	}
+	return 0;
+}
+
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    const int test_gpio[] = {
+	//GPIO	PIN		GPIO	PIN		GPIO	PIN		GPIO	PIN
+	99,		170,	8,		171,	117,	59,		21,		61,
+	22,		62,		23,		144,	24,		147,	41,		159,
+	120,	143,	19,		3,		123,	5,		58,		18,
+	59,		19,		57,		20,		56,		21,		55,		22,
+	48,		23,		125,	149,	127,	160,	36,		77,
+	35,		78,		34,		79,		33,		80,		54,		163,
+	#if 0	//Hard Ware ERROR!
+	47,		164,
+	46,		166,
+	#endif
+	53,		165,	50,		42,		49,		43,		11,		73,
+	10,		74,		26,		65,		28,		66,		25,		67,
+	27,		68,		32,		56,		31,		57,		51,		58,
+	52,		60,		39,		192,	40,		193,	37,		194,
+	38,		195,
+	#if 0	//undefine GNSS
+	44,		161,
+	45,		151,
+	#endif
+	};
+
+    int i, n = 0, ret, total;
+    int *fail_io = (int *)arg;
+    int try_count;
+    total = (sizeof(test_gpio)/sizeof(int));
+	printf("T108 V2 Start test gpio V0.8, total gpio=%d\n", (total/2));
+
+    for(try_count = 0; try_count < 4; try_count++){
+        n = 0;
+        /* [1 all gpio Init] */
+        gpio_test_init_test_gpio_mode();
+
+        /* [2 GPIOTEST] */
+    	for(i = 0; i < total; i = i + 2){
+            ret = gpio_test(test_gpio[i]);
+            if(-1 == ret){
+				n++;
+				printf("!!!!!!!!!!!!gpio [%d] test failed!!!!!!!!!!!!\n", test_gpio[i]);
+				if(try_count != 3){
+					printf(" ---TEST FAILED! RETRY!--- \n");
+        			usleep(5000);
+					break;
+				}
+                fail_io[n - 1] = test_gpio[i + 1];
+            }else{
+                //printf("############gpio [%d] test success############\n", test_gpio[i]);
+            }
+        }
+        if(0 == n){
+			printf(" ---ALL PASS---\n");
+            break;
+        }
+    }
+    return n;
+}
+
+
+#else
+int mbtk_at_gpio(bool gnss_support, void* arg)
+{
+    return -1;
+}
+
+#endif
+