static int pmu_ldo_rf_poweron(PWC_COMM_MODEM_E modem_id) { unsigned long flags; if(PWC_COMM_MODEM_1 == modem_id){ spin_lock_irqsave(&pctrl_rf_lock[modem_id],flags); /*todo: 调用GPIO 123\124拉高*/ rf_gpio_set_high(); /*将天线管脚切换为功能管脚*/ if(sw_unpd_en){ /*将副modem天线开关配置为antn 功能*/ if(bsp_antn_sw_unpd_config(NAGTIVE , 1)){ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 0,mux 0\n"); } } spin_unlock_irqrestore(&pctrl_rf_lock[modem_id],flags); return MIPI_OK; } else{ mipi_print_error("ldo power didn't supplied to modem[%d],please check nv congfig or hardware!\n",modem_id); return MIPI_ERROR; } }
static PWC_COMM_STATUS_E pmu_hi6561_get_rf_powerstatus(PWC_COMM_MODEM_E modem_id) { int ret = 0; HI6561_POWER_ID power_id1 = PMU_HI6561_POWER_ID_BUTT; HI6561_POWER_ID power_id2 = PMU_HI6561_POWER_ID_BUTT; HI6561_POWER_ID power_id3 = PMU_HI6561_POWER_ID_BUTT; PWC_COMM_STATUS_E result = PWC_COMM_STATUS_BUTT; unsigned long flags; u8 status1 = 0; u8 status2 = 0; u8 status3 = 0; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return PWC_COMM_STATUS_BUTT; } power_id1=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG0); power_id2=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG1); power_id3=bsp_adpter_hi6561_powerid(MODEM_FEM0); /*加锁保护*/ spin_lock_irqsave(&pctrl_rf_lock[modem_id],flags); ret=pmu_hi6561_power_status(power_id1,&status1,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("get rf power status failed!power id is %d\n",power_id1); result = PWC_COMM_STATUS_BUTT; goto out; } ret=pmu_hi6561_power_status(power_id2,&status2,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("get rf power status failed!power id is %d\n",power_id2); result = PWC_COMM_STATUS_BUTT; goto out; } ret=pmu_hi6561_power_status(power_id3,&status3,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("get rf power status failed!power id is %d\n",power_id3); result = PWC_COMM_STATUS_BUTT; goto out; } if(status1&&status2&&status3){ result = PWC_COMM_MODEM_ON; } else if(0 == (status1 | status2 | status3)){ result = PWC_COMM_MODEM_OFF; } else{ result = PWC_COMM_STATUS_BUTT; } out: spin_unlock_irqrestore(&pctrl_rf_lock[modem_id],flags); return result; }
static int pmu_hi6561_power_on_local(HI6561_POWER_ID power_id ,HI6561_ID_ENUM chip_id) { int ret=MIPI_OK; /*judge the paramemt is invalid or not*/ if(power_id>PMU_HI6561_BUCK2||power_id<PMU_HI6561_LDO1) { mipi_print_error("Error:power id is invalid!\n"); ret=MIPI_ERROR; } #if 0 /*查看过流标志位,是否可以打开电源*/ if(power_id>PMU_HI6561_LDO2&&power_id<PMU_HI6561_POWER_ID_BUTT){ if(over_flow_tag[chip_id][power_id]==PMU_HI6561_OVER_FLOW){ mipi_print_error("Error:pastar[%d] power id [%d]has over flow!\n",chip_id,power_id); return MIPI_ERROR; } } /*清除状态寄存器*/ ret=pmu_hi6561_exc_clear((EXCEPTION_TYPE_E)power_id,chip_id); if(MIPI_OK!=ret){ mipi_print_error("Error:clear status register failed!\n"); ret=MIPI_ERROR; } #endif ret=pmu_hi6561_power_switch(power_id, PA_STAR_POWER_ON,chip_id); return ret; }
static int pmu_hi6561_power_off_local(HI6561_POWER_ID power_id,HI6561_ID_ENUM chip_id ) { int ret=MIPI_OK; /*judge the paramemt is invalid or not*/ if(power_id>PMU_HI6561_BUCK2||power_id<PMU_HI6561_LDO1) { mipi_print_error("Error:power id is invalid!\n"); ret=MIPI_ERROR; } #if 0 if(power_id>PMU_HI6561_LDO2&&power_id<PMU_HI6561_POWER_ID_BUTT){ if(!strcmp(pmu_hi6561_exc_isr(chip_id),err_list[power_id])){ over_flow_tag[chip_id][power_id]=PMU_HI6561_OVER_FLOW;/*需要和zhangliping确认,标志位如何让上层知道*/ } } #endif ret=pmu_hi6561_power_switch(power_id, PA_STAR_POWER_OFF,chip_id); if(MIPI_OK!=ret){ mipi_print_error("Error:close buck failed!\n"); ret=MIPI_ERROR; } #if 0 ret=pmu_hi6561_exc_clear((EXCEPTION_TYPE_E)power_id,chip_id); if(MIPI_OK!=ret){ mipi_print_error("Error:close buck failed!\n"); ret=MIPI_ERROR; } #endif return ret; }
/***************************************************************************** 函 数 名 : bsp_pmu_hi6561_get_rf_powerstatus 功能描述 :RF 电源状态查询 输入参数 : 无 输出参数 : PWC_COMM_STATUS_BUTT :error -1:error 0x10:power on 0x20:power off 返 回 值 : pa电源开关状态 *****************************************************************************/ PWC_COMM_STATUS_E bsp_pmu_hi6561_get_pa_powerstatus(PWC_COMM_MODEM_E modem_id) { int ret = 0; unsigned long flags; PWC_COMM_STATUS_E result=PWC_COMM_STATUS_BUTT; HI6561_POWER_ID power_id1 = PMU_HI6561_POWER_ID_BUTT; HI6561_POWER_ID power_id2 = PMU_HI6561_POWER_ID_BUTT; u32 papower_local[PWC_COMM_MODEM_BUTT]; u8 status1 = 0; u8 status2 = 0; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return PWC_COMM_STATUS_BUTT; } papower_local[PWC_COMM_MODEM_0]=pa_power_unit.papower_m0; papower_local[PWC_COMM_MODEM_1]=pa_power_unit.papower_m1; if(PA_POWER_FROM_HI6561 != papower_local[modem_id]) { return PWC_COMM_STATUS_BUTT; } power_id1=bsp_adpter_hi6561_powerid(MODEM_PA0); power_id2=bsp_adpter_hi6561_powerid(MODEM_PA_VBIAS0); /*加锁保护*/ spin_lock_irqsave(&pctrl_pa_lock[modem_id],flags); ret=pmu_hi6561_power_status(power_id1,&status1,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("get pa power status failed!power id is %d\n",power_id1); result = PWC_COMM_STATUS_BUTT; goto out; } ret=pmu_hi6561_power_status(power_id2,&status2,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("get pa power status failed!power id is %d\n",power_id2); result = PWC_COMM_STATUS_BUTT; goto out; } if(status1&&status2){ result = PWC_COMM_MODEM_ON; } else if(0 == (status1 | status2)){ result = PWC_COMM_MODEM_OFF; } else{ result = PWC_COMM_STATUS_BUTT; } out : spin_unlock_irqrestore(&pctrl_pa_lock[modem_id],flags); return result; }
/***************************************************************************** 函数 : bsp_pmu_hi6561_pa_poweron 功能 : PA 上电 输入 : 无 输出 : 无 返回 : pa电源开关状态 *****************************************************************************/ int bsp_pmu_hi6561_pa_poweroff(PWC_COMM_MODEM_E modem_id) { int ret = 0; HI6561_POWER_ID power_id1; HI6561_POWER_ID power_id2; unsigned long flags; u32 papower_local[PWC_COMM_MODEM_BUTT]; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return MIPI_ERROR; } papower_local[PWC_COMM_MODEM_0]=pa_power_unit.papower_m0; papower_local[PWC_COMM_MODEM_1]=pa_power_unit.papower_m1; if(PA_POWER_FROM_HI6561 != papower_local[modem_id]) { return MIPI_OK; } /*电源ID转换*/ power_id1=bsp_adpter_hi6561_powerid(MODEM_PA0); power_id2=bsp_adpter_hi6561_powerid(MODEM_PA_VBIAS0); /*若电源已关闭,不可重复关闭*/ if(PWC_COMM_MODEM_OFF == bsp_pmu_hi6561_get_pa_powerstatus(modem_id)){ ret = MIPI_OK; return ret; } /*加锁保护*/ spin_lock_irqsave(&pctrl_pa_lock[modem_id],flags); ret=pmu_hi6561_power_off(power_id1,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_off failed! power id=%d\n",power_id1); ret = MIPI_ERROR; goto out; } ret=pmu_hi6561_power_off(power_id2,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_off failed! power id=%d\n",power_id2); ret = MIPI_ERROR; goto out; } out: spin_unlock_irqrestore(&pctrl_pa_lock[modem_id],flags); return ret; }
static int pmu_hi6561_reg_read(u8 reg_addr,u8 *data,HI6561_ID_ENUM chip_id) { u8 reg_data=0xff; int ret; if(!data){ mipi_print_error("Error:param pointer is null!\n"); return (int)MIPI_ERROR; } ret=bsp_mipi_data_rev(reg_addr, ®_data,(MIPI_CTRL_ENUM)chip_id); if(ret<0) { mipi_print_error("Error: pmu_hi6561_reg_read fail!\n"); } *data=reg_data; return ret; }
static int pmu_hi6561_reg_write(u8 reg_addr,u8 reg_data,HI6561_ID_ENUM chip_id) { int ret; ret=bsp_mipi_data_send(reg_addr, reg_data,(MIPI_CTRL_ENUM)chip_id); if(ret<0) { mipi_print_error("Error: pmu_hi6561_reg_read fail!\n"); return MIPI_ERROR; } return MIPI_OK; }
static int pmu_hi6561_power_switch( HI6561_POWER_ID power_id,POWER_PROC_ENUM power_proc,HI6561_ID_ENUM chip_id ) { int ret=MIPI_OK; u8 reg_val=0; HI6561_VLTGS_ATTR hi6561_volt={0,0}; /*judge the paramemt is invalid or not*/ if(power_id>PMU_HI6561_BUCK2||power_id<PMU_HI6561_LDO1) { mipi_print_error("Error:power id is invalid!\n"); ret=MIPI_ERROR; } if(power_id<PMU_HI6561_POWER_ID_BUTT)hi6561_volt = hi6561_volt_attr[power_id];/*for pc-Lint*/ ret=pmu_hi6561_reg_read(hi6561_volt.onoff_reg_addr, ®_val, chip_id); if(MIPI_OK!=ret) { mipi_print_error("Error:can't get pastar register value !\n"); goto out; } /*if open*/ if(PA_STAR_POWER_ON==power_proc){ reg_val |= PA_STAR_POWER_ON<<hi6561_volt.onoff_bit_offset; } else{/*close*/ reg_val &= ~(u8)(1<<hi6561_volt.onoff_bit_offset); } ret=pmu_hi6561_reg_write(hi6561_volt.onoff_reg_addr,reg_val,chip_id); if(MIPI_OK!=ret) { mipi_print_error("Error:can't write data to pastar!\n"); } out: return ret; }
static int pmu_ldo_rf_poweroff(PWC_COMM_MODEM_E modem_id) { unsigned long flags; if(PWC_COMM_MODEM_1 == modem_id){ spin_lock_irqsave(&pctrl_rf_lock[modem_id],flags); /*todo: 调用GPIO拉低*/ rf_gpio_set_low(); if(sw_unpd_en && (PWC_COMM_MODEM_1 == modem_id)){ /*将副modem天线开关配置为GPIO默认态*/ if(bsp_antn_sw_unpd_config(NAGTIVE , 0)){/*枚举*/ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 0,mux 0\n"); } /*副modem天线开关不下电在gpio中实现*/ } spin_unlock_irqrestore(&pctrl_rf_lock[modem_id],flags); return MIPI_OK; } else{ mipi_print_error("ldo power didn't supplied to modem[%d],please check nv congfig or hardware!\n",modem_id); return MIPI_ERROR; } }
int pmu_hi6561_power_on(HI6561_POWER_ID power_id ,HI6561_ID_ENUM chip_id) { int ret=MIPI_OK; unsigned long flags=0; /*write after read,add lock */ local_irq_save(flags); ret=pmu_hi6561_power_on_local(power_id,chip_id); if(MIPI_OK!=ret){ mipi_print_error("Error:close power failed!\n"); ret=MIPI_ERROR; } local_irq_restore(flags); return ret; }
/***************************************************************************** 函 数 名 : bsp_pmu_hi6561_get_rf_powerstatus 功能描述 :RF 电源状态查询 输入参数 : 无 输出参数 : PWC_COMM_STATUS_BUTT :error 0x10:power on 0x20:power off 返 回 值 : rf电源开关状态 *****************************************************************************/ PWC_COMM_STATUS_E bsp_pmu_hi6561_get_rf_powerstatus(PWC_COMM_MODEM_E modem_id) { u32 rfpower_local[PWC_COMM_MODEM_BUTT]; rfpower_local[PWC_COMM_MODEM_0]=rf_power_unit.rfpower_m0; rfpower_local[PWC_COMM_MODEM_1]=rf_power_unit.rfpower_m1; if(RF_POWER_FROM_HI6561 == rfpower_local[modem_id]){/*需要pastar供电*/ return pmu_hi6561_get_rf_powerstatus(modem_id); } else if(RF_POWER_FROM_LDO == rfpower_local[modem_id]){/*需要ldo供电*/ return pmu_ldo_get_rf_powerstatus(modem_id); } else{/*不需要pastar或LDO供电*/ mipi_print_error("modem [%d] hasn't use pastar ,please check nv!\n",modem_id); return PWC_COMM_STATUS_BUTT; } }
/***************************************************************************** 函数 : drv_pmu_hi6561_mode_config 功能 : 通信模块配置G模或W模接口 输入 : modem_id 卡号 输出 : 无 返回 : BSP_OK 配置成功/ BSP_ERROR 配置失败 *****************************************************************************/ s32 drv_pmu_hi6561_mode_config(PWC_COMM_MODEM_E modem_id, PWC_COMM_MODE_E mode_id) { u32 rfpower_local[PWC_COMM_MODEM_BUTT]; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return MIPI_ERROR; } rfpower_local[PWC_COMM_MODEM_0]=rf_power_unit.rfpower_m0; rfpower_local[PWC_COMM_MODEM_1]=rf_power_unit.rfpower_m1; /* 副卡不使用PAStar供电,则直接返回 */ if(RF_POWER_FROM_HI6561 != rfpower_local[modem_id]) { return MIPI_OK; } return pmu_hi6561_config_mode(mode_id,(HI6561_ID_ENUM)modem_id); }
/***************************************************************************** 函 数 名 : drv_pmu_hi6561_exc_check 功能描述 : 通信模块检查PASTAR是否有异常接口 输入参数 : modem_id 卡号 输出参数 : 无 返 回 值 : BSP_OK 没有异常 BSP_ERROR 存在异常 *****************************************************************************/ s32 drv_pmu_hi6561_exc_check(PWC_COMM_MODEM_E modem_id) { if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return MIPI_ERROR; } /* 副卡PA/RF不用PAStar供电时,不去check modem1。 */ if((pa_power_unit.papower_m1 != PA_POWER_FROM_HI6561) && (rf_power_unit.rfpower_m1 != RF_POWER_FROM_HI6561) && (PWC_COMM_MODEM_1 == modem_id)) { return MIPI_OK; } if(strcmp("UNKOWN",pmu_hi6561_exc_isr((HI6561_ID_ENUM)modem_id))){ return (BSP_S32)MIPI_ERROR;/*pmu 存在异常*/ } return (BSP_S32)MIPI_OK; }
int adp_pmu_hi6561_initial(HI6561_ID_ENUM chip_id) { mipi_print_error("pmu hi6561 didn't build all function!\n"); return 0; }
static int pmu_hi6561_rf_poweroff(PWC_COMM_MODEM_E modem_id) { int ret = MIPI_OK; HI6561_POWER_ID power_id1; HI6561_POWER_ID power_id2; HI6561_POWER_ID power_id3; unsigned long flags; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return MIPI_ERROR; } power_id1=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG0); power_id2=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG1); power_id3=bsp_adpter_hi6561_powerid(MODEM_FEM0); /*若电源已关闭,无需重新开*/ if(PWC_COMM_MODEM_OFF == bsp_pmu_hi6561_get_rf_powerstatus(modem_id)){ return MIPI_OK; } /*加锁保护*/ spin_lock_irqsave(&pctrl_rf_lock[modem_id],flags); /*关闭RFIC_ANALOG0*/ ret=pmu_hi6561_power_off(power_id1,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_off failed!power id is %d\n",power_id1); ret = MIPI_ERROR; goto out; } /*关闭RFIC_ANALOG1*/ ret=pmu_hi6561_power_off(power_id2,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_off failed!power id is %d\n",power_id2); ret = MIPI_ERROR; goto out; } /* 清除buck1/2的过流标记 */ ret = pmu_hi6561_buck1_2_real_exception_clear((HI6561_ID_ENUM)modem_id); if(MIPI_OK != ret) { mipi_print_error("Error:clear buck1/2 real over current status failed! modem id:%d\n", modem_id); } if(sw_unpd_en && (PWC_COMM_MODEM_0 == modem_id)){ /*将主分集天线开关配置为GPIO默认态*/ ret = bsp_antn_sw_unpd_config(MASTER_0 , 0); if(ret){ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 0,mux 0\n"); } ret = bsp_antn_sw_unpd_config(MASTER_1 , 0); if(ret){ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 1,mux 0\n"); } } else{ /*关闭FEM*/ ret = pmu_hi6561_power_off(power_id3,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_off failed!power id is %d\n",power_id3); ret = MIPI_ERROR; goto out; } } out: spin_unlock_irqrestore(&pctrl_rf_lock[modem_id],flags); return ret; }
static int pmu_hi6561_rf_poweron(PWC_COMM_MODEM_E modem_id) { int ret = MIPI_OK; HI6561_POWER_ID power_id1; HI6561_POWER_ID power_id2; HI6561_POWER_ID power_id3; unsigned long flags; if(PWC_COMM_MODEM_BUTT<=modem_id){ mipi_print_error("invalid param with modem id %d\n",modem_id); return MIPI_ERROR; } power_id1=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG0); power_id2=bsp_adpter_hi6561_powerid(MODEM_RFIC0_ANALOG1); power_id3=bsp_adpter_hi6561_powerid(MODEM_FEM0); /*若电源已打开,无需重新开*/ if(PWC_COMM_MODEM_ON == bsp_pmu_hi6561_get_rf_powerstatus(modem_id)){ return MIPI_OK; } /*上电过程需要加锁,以免中间有关闭电源请求*/ spin_lock_irqsave(&pctrl_rf_lock[modem_id],flags); /* 清除buck1/2的误报过流 */ ret = pmu_hi6561_buck1_2_phony_exception_clear((HI6561_ID_ENUM)modem_id); if(MIPI_OK != ret) { mipi_print_error("Error:clear buck1/2 phony over current status failed! modem id:%d\n", modem_id); } /*打开MODEM_RFIC_ANALOG0*/ ret=pmu_hi6561_power_on(power_id1,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_on failed!power id is %d\n",power_id1); goto out; } /*打开MODEM_RFIC_ANALOG1*/ ret=pmu_hi6561_power_on(power_id2,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_on failed!power id is %d\n",power_id2); goto out; } /*打开FEM*/ ret=pmu_hi6561_power_on(power_id3,(HI6561_ID_ENUM)modem_id); if(ret){ mipi_print_error("pmu_hi6561_power_on failed!power id is %d\n",power_id3); goto out; } /*将天线管脚切换为功能管脚*/ if(sw_unpd_en && (0==modem_id)){ /*将主分集天线开关配置为antn 功能*/ ret = bsp_antn_sw_unpd_config(MASTER_0 , 1); if(ret){ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 0,mux 0\n"); } ret = bsp_antn_sw_unpd_config(MASTER_1 , 1); if(ret){ mipi_print_error("bsp_antn_sw_unpd_config fail!gproup 1,mux 0\n"); } } out: spin_unlock_irqrestore(&pctrl_rf_lock[modem_id],flags); return ret; }