/*================================================================ Copyright (c) 2018 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. =================================================================*/ /*================================================================= EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. WHEN WHO WHAT, WHERE, WHY ------------ ------- ------------------------------------------------------------------------------- 25/09/2020 Destin Add gpio pin power led,show csq value 03/06/2019 Fitz Add LCC gpio reconfig process. 11/02/2018 Jensen added gpio access interface, added EC26C gpio config 10/15/2018 Chaim add gpio init function =================================================================*/ /*=========================================================================== * include files ===========================================================================*/ #include "quec_gpio.h" #include "quec_cust_feature.h" #include "pmic.h" #include "ningbo.h" #include "guilin_lite.h" #include "quec_mfpr_api.h" #include "cgpio.h" #include "cgpio_HW.h" #include "bsp_hisr.h" #include "usim_hw.h" #include "bsp.h" #ifdef QUEC_GPIO_ENABLE /*=========================================================================== * Macro Definition ===========================================================================*/ #ifdef QUEC_GPIO_LOG_ENABLE #define gpio_log(msg,...) custom_log("GPIO",msg,##__VA_ARGS__) #else #define gpio_log(msg,...) #endif #define INVALID_GPIO_MFPR_ADDR 0xFFFFFFFF #define QUEC_RESERVED_MASK 0x00C0 #define write32(addr, val) (*(volatile unsigned int *)(addr) = (val)) #define read32(addr) (*(volatile unsigned int *)(addr)) static OS_HISR quec_gpio_hisr[GPIO_PIN_NO_MAX] = {NULL}; static OS_HISR quec_gpio_wu_hisr[GPIO_PIN_NO_MAX] = {NULL}; static OS_HISR quec_common_gpio_hisr = NULL; /*=========================================================================== * struct,enum definition ===========================================================================*/ typedef struct { GPIO_PinNumbers pin_num; unsigned long reg_addr; }quec_gpio_regaddr_s; static int quec_gpio_config_set(GPIO_PIN_NUMBER_E gpio_num, PIN_DIRECTION_E pin_dir, PIN_PULL_E pin_pull, PIN_LEVEL_E pin_level) { GPIOConfiguration gpio_config_data = { .pinDir = (GPIOPinDirection)pin_dir, .pinPull = (GPIOPullUpDown)pin_pull, .initLv = pin_level, .pinEd = GPIO_NO_EDGE, .isr = NULL, .wu = NULL, }; return GpioInitConfiguration((unsigned int)gpio_num, gpio_config_data); } //init single gpio pin,if init before,return direct int quec_gpio_init(GPIO_PIN_NUMBER_E gpio_num, PIN_DIRECTION_E pin_dir, PIN_PULL_E pin_pull, PIN_LEVEL_E pin_level) { int ret = -1; unsigned long mfpr_data = MFP_DRIVE_MEDIUM | MFP_LPM_EDGE_NONE; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } /*必须先config,再设置MFPR(此寄存器中包含复用功能的配置)。*/ /* step 1: set gpio reg */ ret = quec_gpio_config_set(gpio_num, pin_dir, pin_pull, pin_level); if (ret) { gpio_log("config gpio reg failed, gpio_num:%d, ret = %d \n", gpio_num, ret); return -1; } if(CHIP_IS_CRANEL || CHIP_IS_CRANELS) { if ((GPIO_PIN_NO_117==gpio_num) || ((GPIO_PIN_NO_45 <= gpio_num && gpio_num <= GPIO_PIN_NO_47)) || (GPIO_PIN_NO_77==gpio_num)||(GPIO_PIN_NO_56==gpio_num)) { //MMC2 GPIOS *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } if(CHIP_IS_CRANELR || CHIP_IS_CRANELRH) { if(((GPIO_PIN_NO_84<=gpio_num) && (GPIO_PIN_NO_90>=gpio_num)) || (GPIO_PIN_NO_67==gpio_num) || (GPIO_PIN_NO_77==gpio_num)) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } if(CHIP_IS_CRANELG) { if(((GPIO_PIN_NO_87<=gpio_num) && (GPIO_PIN_NO_90>=gpio_num)) || (GPIO_PIN_NO_85==gpio_num)) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } if(CHIP_IS_CRANEM) { if(((GPIO_PIN_NO_117<=gpio_num) && (GPIO_PIN_NO_120>=gpio_num)) || ((GPIO_PIN_NO_77<=gpio_num) && (GPIO_PIN_NO_78>=gpio_num))) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } //[START]2020-10-13 [nebula.li][add] 初始化时增加设置gpio上下拉操作,修复gpio设置为输入时,上下拉不生效 ret = GpioSetPullControl(gpio_num, (GPIOPullUpDown)pin_pull); if (ret) { gpio_log("set gpio pin pull failed, ret = %d \n", ret); return -1; } //[END]2020-10-13 [nebula.li][add] return 0; } int quec_gpio_map_clock(GPIO_PIN_NUMBER_E gpio_num) { unsigned long mfpr_data = MFP_DRIVE_MEDIUM | MFP_LPM_EDGE_NONE; if ((GPIO_PIN_NO_28 != gpio_num) && (GPIO_PIN_NO_20 != gpio_num ) && (GPIO_PIN_NO_56 != gpio_num )&& (GPIO_PIN_NO_57 != gpio_num )) { gpio_log("gpio number is invalid and not gpio_28 or GPIO_PIN_NO_20 \n"); return -1; } if (GPIO_PIN_NO_28 == gpio_num ) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF3 | mfpr_data; } else if (GPIO_PIN_NO_20 == gpio_num ) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF6 | mfpr_data; } else if (GPIO_PIN_NO_56 == gpio_num) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | mfpr_data; } else if (GPIO_PIN_NO_57 == gpio_num) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF3 | mfpr_data; } return 0; } int quec_gpio_deinit(GPIO_PIN_NUMBER_E gpio_num) { GpioClearEdgeDetection(gpio_num); GpioDisableEdgeDetection(gpio_num, GPIO_TWO_EDGE); GpioClearEdgeDetection_wakeup((UINT32)gpio_num); GpioDisableEdgeDetection_wakeup(gpio_num, GPIO_TWO_EDGE); return 0; } int quec_pin_set_func(GPIO_PIN_NUMBER_E gpio_num, unsigned char func_sel) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } if(func_sel > 7){ gpio_log("func_sel is invalid\n"); return -1; } volatile unsigned int reg_val = 0; volatile unsigned int mfpr_addr = 0; mfpr_addr = GPIO_MFPR_ADDR(gpio_num); reg_val = *(volatile unsigned int *)mfpr_addr; reg_val = reg_val & ~(0x7) | func_sel; (*(volatile unsigned int *)mfpr_addr = reg_val); return 0; } int quec_gpio_set_drive_level(GPIO_PIN_NUMBER_E gpio_num, QL_PIN_DRIVE_LEVEL_E drive_level) { int ret = -1; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } volatile unsigned int * mfpr_addr = (volatile unsigned int *)GPIO_MFPR_ADDR(gpio_num); if (INVALID_GPIO_MFPR_ADDR == (unsigned int) mfpr_addr) { return -1; } if(GPIO_DRV_LEVEL_FAST == drive_level) { *(mfpr_addr) |= GPIO_BIT_DRIVE_0; // 11bit =1 *(mfpr_addr) |= GPIO_BIT_DRIVE_1; //12bit = 1 } else if(GPIO_DRV_LEVEL_MED == drive_level) { *(mfpr_addr) &= 0xF7FF; // 11bit =0 *(mfpr_addr) |= GPIO_BIT_DRIVE_1; //12bit = 1 } else if(GPIO_DRV_LEVEL_SLOW == drive_level) { *(mfpr_addr) |= GPIO_BIT_DRIVE_0; // 11bit =1 *(mfpr_addr) &= 0xEFFF; //12bit = 0 } else if(GPIO_DRV_LEVEL_VERY_SLOW == drive_level) { *(mfpr_addr) &= 0xE7FF; //11 bit 12 bit =0 } else { gpio_log("drive_level is invalid\n"); return -1; } return 0; } int quec_gpio_get_drive_level(GPIO_PIN_NUMBER_E gpio_num, QL_PIN_DRIVE_LEVEL_E *drive_level) { int ret = -1; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } volatile unsigned int * mfpr_addr = (volatile unsigned int *)GPIO_MFPR_ADDR(gpio_num); if (INVALID_GPIO_MFPR_ADDR == (unsigned int)mfpr_addr) { return -1; } // get bit11 int bit_11 = (*mfpr_addr >> 11) & 1; // get bit11 int bit_12 = (*mfpr_addr >> 12) & 1; if( 1 == bit_12 && 1 == bit_11 ) { *drive_level = GPIO_DRV_LEVEL_FAST; } else if( 1 == bit_12 && 0 == bit_11 ) { *drive_level = GPIO_DRV_LEVEL_MED; } else if( 0 == bit_12 && 1 == bit_11 ) { *drive_level = GPIO_DRV_LEVEL_SLOW; } else if( 0 == bit_12 && 0 == bit_11 ) { *drive_level = GPIO_DRV_LEVEL_VERY_SLOW; } else { return -1; } return 0; } //set gpio level int quec_gpio_set_level(GPIO_PIN_NUMBER_E gpio_num, PIN_LEVEL_E pin_level) { int ret = -1; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } ret = GpioSetLevel(gpio_num, pin_level); if (ret) { gpio_log("set gpio pin level failed, gpio_num:%d, ret = %d \n", gpio_num, ret); return -1; } return 0; } //get gpio level int quec_gpio_get_level(GPIO_PIN_NUMBER_E gpio_num, PIN_LEVEL_E *p_pin_level) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num || NULL == p_pin_level) { gpio_log("para is invalid \n"); return -1; } *p_pin_level = (PIN_LEVEL_E)GpioGetLevel(gpio_num); return 0; } int quec_gpio_set_direction(GPIO_PIN_NUMBER_E gpio_num, PIN_DIRECTION_E pin_dir) { int ret = -1; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } ret = GpioSetDirection(gpio_num, (GPIOPinDirection)pin_dir); if (ret) { gpio_log("set gpio pin direction failed, ret = %d \n", ret); return -1; } return 0; } int quec_gpio_get_direction(GPIO_PIN_NUMBER_E gpio_num, PIN_DIRECTION_E *p_pin_dir) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num || NULL == p_pin_dir) { gpio_log("para is invalid \n"); return -1; } *p_pin_dir = (PIN_DIRECTION_E)GpioGetDirection(gpio_num); return 0; } int quec_gpio_set_pull(GPIO_PIN_NUMBER_E gpio_num, PIN_PULL_E pin_pull) { int ret = -1; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } ret = GpioSetPullControl(gpio_num, (GPIOPullUpDown)pin_pull); if (ret) { gpio_log("set gpio pin pull failed, ret = %d \n", ret); return -1; } return 0; } int quec_gpio_get_pull(GPIO_PIN_NUMBER_E gpio_num, PIN_PULL_E *p_pin_pull) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num || NULL == p_pin_pull) { gpio_log("para is invalid \n"); return -1; } *p_pin_pull = (PIN_PULL_E)GpioGetPullControl(gpio_num); return 0; } void quec_active_gpio_hisr(unsigned int gpio_num) { if(NULL != quec_gpio_hisr[gpio_num]) { OS_Activate_HISR(&quec_gpio_hisr[gpio_num]); } } void quec_active_gpio_wu_hisr(unsigned int gpio_num) { if(NULL != quec_gpio_wu_hisr[gpio_num]) { OS_Activate_HISR(&quec_gpio_wu_hisr[gpio_num]); } } int quec_eint_register(GPIO_PIN_NUMBER_E gpio_num, PIN_EDGE_E pin_edge, PIN_PULL_E pin_pull, void *eint_cb, void *wakeup_eint_cb) { int ret = -1; unsigned long mfpr_data = QUEC_RESERVED_MASK; GPIOConfiguration gpio_config_data = { .pinDir = (GPIOPinDirection)PIN_DIRECTION_IN, .pinPull = (GPIOPullUpDown)pin_pull, .initLv = PIN_LEVEL_LOW, .pinEd = (GPIOTransitionType)pin_edge, .isr = NULL, .wu = NULL, }; if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } if(GPIO_MFPR_ADDR(gpio_num) == 0XFFFFFFFF) { gpio_log("gpio num is not supported\n"); return -1; } /*此处设置的是mfpr寄存器边沿检测,用于唤醒功能*/ switch (pin_edge) { case PIN_NO_EDGE: mfpr_data |= MFP_LPM_EDGE_NONE; break; case PIN_RISING_EDGE: mfpr_data |= MFP_LPM_EDGE_RISE; break; case PIN_FALLING_EDGE: mfpr_data |= MFP_LPM_EDGE_FALL; break; case PIN_BOTH_EDGE: mfpr_data |= MFP_LPM_EDGE_BOTH; break; default: mfpr_data |= MFP_LPM_EDGE_NONE; break; } if(CHIP_IS_CRANEL || CHIP_IS_CRANELS) { if (GPIO_PIN_NO_117==gpio_num) { //MMC2 GPIOS *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | MFP_DRIVE_MEDIUM | mfpr_data; } } if(CHIP_IS_CRANELR || CHIP_IS_CRANELRH) { if(((GPIO_PIN_NO_84<=gpio_num) && (GPIO_PIN_NO_90>=gpio_num)) || (GPIO_PIN_NO_67==gpio_num) || (GPIO_PIN_NO_77==gpio_num)) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else{ *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | MFP_DRIVE_MEDIUM | mfpr_data; } } if(CHIP_IS_CRANELG) { if(((GPIO_PIN_NO_87<=gpio_num) && (GPIO_PIN_NO_90>=gpio_num)) || (GPIO_PIN_NO_85==gpio_num)) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } if(CHIP_IS_CRANEM) { if(((GPIO_PIN_NO_117<=gpio_num) && (GPIO_PIN_NO_120>=gpio_num)) || ((GPIO_PIN_NO_77<=gpio_num) && (GPIO_PIN_NO_78>=gpio_num))) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF1 | MFP_DRIVE_MEDIUM | mfpr_data; } else { *(volatile unsigned long *)(GPIO_MFPR_ADDR(gpio_num)) = MFP_AF0 | mfpr_data; } } if (PIN_PULL_DISABLE == pin_pull || PIN_PULL_PD == pin_pull) { gpio_config_data.initLv = PIN_LEVEL_LOW; } else if (PIN_PULL_PU == pin_pull) { gpio_config_data.initLv = PIN_LEVEL_HIGH; } /* 两种中断都注册优先使用唤醒中断,*/ if (eint_cb && !wakeup_eint_cb) { OS_Create_HISR(&quec_gpio_hisr[gpio_num], "gpio_irq", (void(*)(void))eint_cb, HISR_PRIORITY_2); } if (wakeup_eint_cb) { OS_Create_HISR(&quec_gpio_wu_hisr[gpio_num], "gpio_wu_irq", (void(*)(void))wakeup_eint_cb, HISR_PRIORITY_2); } /***************************************/ ret = GpioInitConfiguration((unsigned int)gpio_num, gpio_config_data); if (0 != ret) { gpio_log("config gpio[%d] failed \n", gpio_num); return ret; } return 0; } int quec_eint_unregister(GPIO_PIN_NUMBER_E gpio_num) { if (quec_gpio_hisr[gpio_num] != NULL) { Os_Delete_HISR(&quec_gpio_hisr[gpio_num]); quec_gpio_hisr[gpio_num] = NULL; } if (quec_gpio_wu_hisr[gpio_num] != NULL) { Os_Delete_HISR(&quec_gpio_wu_hisr[gpio_num]); quec_gpio_wu_hisr[gpio_num] = NULL; } GpioClearEdgeDetection(gpio_num); GpioDisableEdgeDetection(gpio_num, GPIO_TWO_EDGE); GpioClearEdgeDetection_wakeup(gpio_num); GpioDisableEdgeDetection_wakeup(gpio_num, GPIO_TWO_EDGE); return 0; } int quec_eint_enable(GPIO_PIN_NUMBER_E gpio_num, PIN_EDGE_E pin_edge) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } GpioClearEdgeDetection(gpio_num); GpioEnableEdgeDetection(gpio_num, (GPIOTransitionType)pin_edge); return 0; } int quec_eint_disable(GPIO_PIN_NUMBER_E gpio_num) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } GpioClearEdgeDetection(gpio_num); GpioDisableEdgeDetection(gpio_num,GPIO_TWO_EDGE); return 0; } int quec_eint_enable_wakeup(GPIO_PIN_NUMBER_E gpio_num, PIN_EDGE_E pin_edge) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } GpioClearEdgeDetection_wakeup(gpio_num); GpioEnableEdgeDetection_wakeup(gpio_num, (GPIOTransitionType)pin_edge); return 0; } int quec_eint_disable_wakeup(GPIO_PIN_NUMBER_E gpio_num) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } GpioClearEdgeDetection_wakeup(gpio_num); GpioDisableEdgeDetection_wakeup(gpio_num, GPIO_TWO_EDGE); return 0; } /*somer.zhang-2020/05/11-set pmic gpio out high level(1) or low level(0)*/ //此接口是设置PMIC芯片上的GPIO,ECxxxY系列采用PM813电源原理芯片才有此功能 int quec_set_pmic_gpio_level(QL_PIMC_GPIO_E PINx,unsigned char level) { if (level > 1) level=1; switch(PINx) { case PMIC_GPIO_PIN_210:/*keyboard led*/ { unsigned char var; NingboRead(NINGBO_BASE_Reg, 0x4C, &var); NingboWrite(NINGBO_BASE_Reg, 0x40, 0x7f); /*set pwm duty (127+1)/128 */ NingboWrite(NINGBO_BASE_Reg, 0x46, 1*6); /*31/5, register 0x46 has 5 bits*/ if (level == 0) //switch off { NingboWrite(NINGBO_BASE_Reg, 0x4C, (var&~(0x1<<0))); //write 0 to 0x4Creg.bit0 return 0; }else{ //switch on NingboWrite(NINGBO_BASE_Reg, 0x4C, (var|(0x1<<0))); //write 1 to 0x4Creg.bit0 return 0; } //break; } case PMIC_GPIO_PIN_217:/*torch led*/ { unsigned char var; NingboRead(NINGBO_BASE_Reg, 0x4C, &var); NingboWrite(NINGBO_BASE_Reg, 0x41, 0x7f); /*set pwm duty (127+1)/128 */ NingboWrite(NINGBO_BASE_Reg, 0x47, 1*6); /*31/5, register 0x47 has 5 bits*/ if (level == 0) //switch off { NingboWrite(NINGBO_BASE_Reg, 0x4C, (var&~(0x1<<1))); //write 0 to 0x4Creg.bit1 return 0; }else{ //switch on NingboWrite(NINGBO_BASE_Reg, 0x4C, (var|(0x1<<1))); //write 1 to 0x4Creg.bit1 return 0; } //break; } case PMIC_GPIO_PIN_209:/*blacklight led*/ { unsigned char var; //unsigned char reg45h; NingboRead(NINGBO_BASE_Reg, 0x4C, &var); //NingboRead(NINGBO_BASE_Reg, 0x45, ®45h); //NingboWrite(NINGBO_BASE_Reg, 0x45, (reg45h|(0x07))); NingboWrite(NINGBO_BASE_Reg, 0x42, 0x7f); /*set pwm duty (127+1)/128 */ NingboWrite(NINGBO_BASE_Reg, 0x48, 2*6); /*31/5, register 0x48 has 5 bits*/ if (level == 0) //switch off { //if ((var&(0x1<<2))==0x02) NingboWrite(NINGBO_BASE_Reg, 0x4C, (var&~(0x1<<2))); //write 0 to 0x4Creg.bit2 return 0; }else{ //switch on //if ((var&(0x1<<2))==0x00) NingboWrite(NINGBO_BASE_Reg, 0x4C, (var|(0x1<<2))); //write 1 to 0x4Creg.bit2 return 0; } //break; } default: break; } return 0; } int quec_set_usim2_io_vol(char onoff, QL_USIM2_IO_E vol) { switch (PMIC_ID_GET()) { #if !defined(NOT_SUPPORT_PM802) case PMIC_802: case PMIC_802S: return 0; #endif #if !defined(NOT_SUPPORT_PM813) case PMIC_813: case PMIC_813A3: case PMIC_813S: return 0; #endif #if !defined(NOT_SUPPORT_PM803) case PMIC_803: if(!onoff){ GuilinLite_Ldo_8_set(onoff); return 0; }else{ switch(vol) { case USIM2_IO_VOL_1_8V: GuilinLite_Ldo_8_set_1_8(); AIB_USIM2_IO_Set_1_8V(); GuilinLite_Ldo_8_set(onoff); return 0; case USIM2_IO_VOL_3_3V: GuilinLite_Ldo_8_set_3_3(); AIB_USIM2_IO_Set_3_3V(); GuilinLite_Ldo_8_set(onoff); return 0; } } #endif default: break; } return -1; } //设置Pin脚的复用功能以及驱动能力,上下拉 int quec_set_gpio_mfprReg(GPIO_PIN_NUMBER_E pin_num, unsigned long mfprReg_data ) { if( pin_num > GPIO_MAX_AMOUNT_OF_PINS || pin_num < GPIO_PIN_NO_0 ) { uart_printf("pin_num=%d error", pin_num); return -1; } *(volatile unsigned long *)(GPIO_MFPR_ADDR(pin_num)) = mfprReg_data; return 0; } //jensen.fang 20181102: to read mfpr register of gpio QuecOSStatus quec_gpio_get_mfprReg(GPIO_PinNumbers pin_num, unsigned long *p_mfprReg_data) { if (pin_num > GPIO_MAX_AMOUNT_OF_PINS) { gpio_log("pin_num=%d error", pin_num); return kParamErr; } if (NULL == p_mfprReg_data) { gpio_log("p_mfprReg_data is null"); return kParamErr; } *p_mfprReg_data = *((volatile unsigned long *)(GPIO_MFPR_ADDR(pin_num))); return QUEC_SUCCESS; } int quec_sfp_eint_register(GPIO_PIN_NUMBER_E gpio_num, void *wakeup_eint_cb) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } if (wakeup_eint_cb) { OS_Create_HISR(&quec_gpio_wu_hisr[gpio_num], "gpio_wu_irq", (void(*)(void))wakeup_eint_cb, HISR_PRIORITY_2); } return 0; } int quec_sfp_eint_unregister(GPIO_PIN_NUMBER_E gpio_num) { if (GPIO_PIN_NO_0 > gpio_num || GPIO_PIN_NO_MAX < gpio_num) { gpio_log("gpio number is invalid\n"); return -1; } if (quec_gpio_wu_hisr[gpio_num] != NULL) { Os_Delete_HISR(&quec_gpio_wu_hisr[gpio_num]); quec_gpio_wu_hisr[gpio_num] = NULL; } return 0; } void* quec_get_gpio_wu_hisr(int gpio_num) { return quec_gpio_wu_hisr[gpio_num]; } #if defined (__QUECTEL_PROJECT_EC800MCN_LE__) || defined (__QUECTEL_PROJECT_EC800MCN_LF__) int quec_pa_level_check(void) { QuecOSStatus ret =kGeneralErr; PIN_LEVEL_E pa_gpio_level = PIN_LEVEL_LOW; ret = quec_gpio_init(GPIO_PIN_NO_37,PIN_DIRECTION_IN,PIN_PULL_PD,PIN_LEVEL_LOW); ret = quec_gpio_get_level(GPIO_PIN_NO_37,&pa_gpio_level); RTI_LOG("pa gpio ret=%d,level=%d\r\n",ret,pa_gpio_level); return pa_gpio_level; } #endif #if defined(QUEC_DUAL_SINGLE_PS_SUPPORT) void quec_simslotswitch_init(void) { if(CHIP_IS_CRANELRH || CHIP_IS_CRANELG) { quec_set_gpio_mfprReg((GPIO_PIN_NUMBER_E)QUEC_USIM2_DAT_PIN, QUEC_USIM2_DAT_PIN_AF); quec_set_gpio_mfprReg((GPIO_PIN_NUMBER_E)QUEC_USIM2_RST_PIN, QUEC_USIM2_RST_PIN_AF); quec_set_gpio_mfprReg((GPIO_PIN_NUMBER_E)QUEC_USIM2_CLK_PIN, QUEC_USIM2_CLK_PIN_AF); } } #endif char peripherals_pin_config_flags[GPIO_PIN_NO_MAX] = {0}; //设置gpio脚不配置复用功能 int quec_peripherals_pin_not_config(GPIO_PIN_NUMBER_E pin_num) { if( pin_num > GPIO_PIN_NO_MAX || pin_num < GPIO_PIN_NO_0 ) { uart_printf("pin_num=%d error", pin_num); return -1; } peripherals_pin_config_flags[pin_num] = 1; return 0; } #endif