【一】typec/PD部分:
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/tcpc/platforms/src/PmicTccPlatform_Schg_PDPhy_R1.c
通过 PmicTccStateMachine_SignalThread .函数传递信号:
PmicTccStateMachine_SignalThread函数此处定义: /ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/tcpc/statemachine/src/PmicTccStateMachine.c
* @function PmicTccStateMachine_SignalThread
其中的类型有:
typedef enum _USBPD_TCPC_EVENT_TYPE
{
USBPD_TCPC_EVENT_EXIT, // Event: State Machine Exit
USBPD_TCPC_EVENT_REGWRITE, // Event: LPM is writing to a TCPCI register
USBPD_TCPC_EVENT_CABLE, // Event: CC / Vbus Cable event
USBPD_TCPC_EVENT_CTRL, // Event: Control event signaled from LPM regwrite
USBPD_TCPC_EVENT_HWFAIL, // Event: Hardware fault
USBPD_TCPC_EVENT_HARDRESET, // Event: PD signalled Hard reset
USBPD_TCPC_EVENT_SWTIMEOUT, // Event: Timeout waiting for a state transition
USBPD_TCPC_EVENT_PRSWAP, // Event: PD signalled PR Swap
USBPD_TCPC_EVENT_LPD, // Event: Liquid Present Detected
USBPD_TCPC_EVENT_LPDTO, // Event: LPD Time-out Event
USBPD_TCPC_EVENT_INVALID
} USBPD_TCPC_EVENT_TYPE;
类型在文件/ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/tcpc/statemachine/src/PmicTccStateMachine.c
函数 PmicTccStateMachine_Main_Thread 中进行传递
PmicTccStateMachine_Main_Thread 函数的作用是轮询处理typec底层事件
调用了 PmicTccStateMachineLevels_Run_StateMachine 函数去进一步处理不同事件
其中先进行了一些列异常判断,之后在循环中检测状态变化(CurrStateID和NextStateID进行比较
一旦发现状态变化,运行新的状态初始化函数:初始化新状态的硬件,更新上下文和硬件状态,更新新状态
/ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/tcpc/statemachine/src/PmicTccStateMachineLevels.c
其中函数 PmicTccStateMachineLevels_Offline_State_Main 中会对cc状态作出判断:
--如果cc1或cc2状态发生变化:就进入"PMICTCC_STATE_ID_STANDBY"新状态进行处理
--如果cc状态没有发生改变:如果当前状态为 USBPD_TCPC_EVENT_CABLE ,并且pogopin状态为 BATTMNGR_POGOPIN_TYPEC_MODE时 ,会根据 snk_vbus_sts 和 g_typec_connect_status 状态判断是否进DC直冲
然后利用 pmic_glink_send_oem_notification 通知ap侧检测结果。(后面GLINK部分会展开讲)
如果在 PmicTccStateMachineLevels_Run_StateMachine 函数中不需变更状态,就去判断是否需要发出alert:PmicTccRegister_UpdateStatusAlert--->PmicTccRegister_UpdateAlert--->PmicTccRegister_Send_Alert_Notification-
最终将Alert发送给lpm(BPD_LPM_EVENT_ALERT)
【二】LPM部分
上面说到PmicTccStateMachineLevels_Run_StateMachine会将Alert发送给lpm
USBPD_LPM_EVENT_TYPE是在 Q8201_modem_user/ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/lpm/inc/lpm.h 中定义的:
/*
* Enum specify type of event
*/
typedef enum _USBPD_LPM_EVENT_TYPE
{
/*General Event 通用事件(退出和定时器超时)*/
USBPD_LPM_EVENT_EXIT,
USBPD_LPM_EVENT_HKTIMER_TO,
/*Event from TCPC/PHY 来自TCPC/PHY的事件*/
USBPD_LPM_EVENT_ALERT,
/*Event within LPM/TCPM*/
/*Event from PRL*/
USBPD_LPM_EVENT_PE_TIMEOUT,
#ifdef CONFIG_ontim_POWER_EMBEDDED_ISOLATION
USBPD_LPM_EVENT_PE_PDPOLICY_TIMEOUT,
USBPD_LPM_EVENT_PE_UVDM_TIMEOUT,
USBPD_LPM_EVENT_PE_UVDM_SEND,
#endif
USBPD_LPM_EVENT_PE_VDM_TIMEOUT,
USBPD_LPM_EVENT_PPS_REQUEST_TIMEOUT,
USBPD_LPM_EVENT_PRL_TIMEOUT,
/*Event from PE 来自PD的事件*/
USBPD_LPM_EVENT_PE_REQUEST_MESSAGE,
USBPD_LPM_EVENT_PE_REQUEST_SIGNAL,
USBPD_LPM_EVENT_PE_REQUEST_PRL_RESET,
USBPD_LPM_EVENT_PE_PM_REQUEST_RTN,
USBPD_LPM_EVENT_PE_RESET_COMPLETE,
USBPD_LPM_EVENT_PE_AMS_REQUEST,
/*Event from PM/DPM 来自PM/DPM的事件*/
USBPD_LPM_EVENT_PM_REQUEST,
USBPD_LPM_EVENT_PM_ACK,
USBPD_LPM_EVENT_PAN_ACK,
/*Event from TCPC/PHY Extended - Not used by OS event system 来自TCPC/PH的外部事件*/
USBPD_LPM_EVENT_ALERT_CC_STATUS,
USBPD_LPM_EVENT_ALERT_POWER_STATUS,
USBPD_LPM_EVENT_ALERT_RECEIVE_SOP_MESSAGE_STATUS,
USBPD_LPM_EVENT_ALERT_RECEIVE_HARDRESET_STATUS,
USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_FAILED,
USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_DISCARDED,
USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_SUCCESSFUL,
USBPD_LPM_EVENT_ALERT_VBUS_VOLTAGE_ALARM_HI,
USBPD_LPM_EVENT_ALERT_VBUS_VOLTAGE_ALARM_LO,
USBPD_LPM_EVENT_ALERT_FAULT,
USBPD_LPM_EVENT_ALERT_RX_BUFFER_OVERFLOW,
USBPD_LPM_EVENT_ALERT_VBUS_SINK_DISCONNECT_DETECTED,
USBPD_LPM_EVENT_ALERT_VENDOR_DEFINE_ALERT,
USBPD_LPM_EVENT_ALERT_TRANSMIT_SIGNAL_COMPLETE,
USBPD_LPM_EVENT_INVALID
}USBPD_LPM_EVENT_TYPE;
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/lpm/src/lpm.c
在 lpm_mainloop 函数中循环等待事件:LpmEvent = event_handler_wait_for_events(&(pLpmCtx->EvtHandler.EvtListner), LPM_WAIT_EVENT);
lpm_mainloop 中会根据事件的不同类型进行分别处理
(1)检测到来自PM/DPM的请求: USBPD_LPM_EVENT_PM_REQUEST ---->lpm_add_dpm_request_event ---> switch(pLpmCtx->pDPMInterface->RequestBuffer.RequestData.RequestType)区分请求内容,添加到队列中
lpm_add_dpm_request_event
此函数将 dpm 请求事件添加到事件队列
其中包括:
typedef enum _USBPD_DPM2LPM_REQUEST_TYPE
{
USBPD_DPM2LPM_REQUEST_NONE,
USBPD_DPM2LPM_REQUEST_POLICY_CHANGE,
USBPD_DPM2LPM_REQUEST_RDO_UPDATE,
USBPD_DPM2LPM_REQUEST_PD_DR_UFP,
USBPD_DPM2LPM_REQUEST_PD_DR_DFP,
USBPD_DPM2LPM_REQUEST_PD_PR_SNK,
USBPD_DPM2LPM_REQUEST_PD_PR_SRC,
USBPD_DPM2LPM_REQUEST_PD_PARNTER_GET_SRC_CAP,
USBPD_DPM2LPM_REQUEST_PD_PARNTER_GET_SNK_CAP,
USBPD_DPM2LPM_REQUEST_PD_SOFTRESET,
USBPD_DPM2LPM_REQUEST_PD_HARDRESET,
USBPD_DPM2LPM_REQUEST_RESET,
USBPD_DPM2LPM_REQUEST_DP_OVERRIDE,
USBPD_DPM2LPM_REQUEST_GET_PPS_STATUS,
USBPD_DPM2LPM_REQUEST_TYPECUV_THRESHOLD_OVERRIDE,
USBPD_DPM2LPM_REQUEST_LPD_CHECK,
USBPD_DPM2LPM_REQUEST_EMARK_DETECT,
USBPD_DPM2LPM_REQUEST_UVDM_SEND,
}USBPD_DPM2LPM_REQUEST_TYPE, *PUSBPD_DPM2LPM_REQUEST_TYPE;
(2)检测到定时器超时:USBPD_LPM_EVENT_HKTIMER_TO,判断是否需要处理dpm请求
(3)检测到 USBPD_LPM_EVENT_EXIT:清除所有事件,退出当前循环 ---> lpm_update_new_events_to_queue ---> case EVENTTYPE_TO_EVENT(USBPD_LPM_EVENT_PAN_ACK) ---> pLpmCtx->bPANPending = false;
所有lpm添加进队列的事务都会进行统一处理,在 while(pLpmCtx->EvtHandler.Queue.NoOfEvent) 这个循环中调用lpm_process_event进行处理,此函数用来处理输入事件
在此处定义:ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/common/inc/event_handler.h
typedef enum _USBPD_MODULE_TYPE
{
USBPD_MODULE_NONE = 0,
/* LPM Modules for Protocol Layers */
USBPD_MODULE_LPM_PRL_RX = 1 << 0,
USBPD_MODULE_LPM_PRL_TX = 1 << 1,
USBPD_MODULE_LPM_PRL_HR = 1 << 2,
USBPD_MODULE_LPM_RTR = 1 << 3,
USBPD_MODULE_LPM_RCH = 1 << 4,
USBPD_MODULE_LPM_TCH = 1 << 5,
/* LPM Modules for Policy Engine */
USBPD_MODULE_LPM_PE = 1 << 6,
/* LPM Modules for Port Manager */
USBPD_MODULE_LPM_PM = 1 << 7,
/* TCPC */
USBPD_MODULE_TCPC_PHY = 1 << 8,
/* DPM */
USBPD_MODULE_DPM = 1 << 9,
USBPD_MODULE_PPM = 1 << 10,
/* OPM */
USBPD_MODULE_OPM = 1 << 11,
}USBPD_MODULE_TYPE;
(1)如果input事件为:USBPD_MODULE_LPM_PM(发送给DPM的)
<1>USBPD_LPM_EVENT_TYPE类型为:USBPD_LPM_EVENT_PE_REQUEST_SIGNAL,USBPD_LPM_EVENT_ALERT_RECEIVE_HARDRESET_STATUS
lpm_process_hardreset_event(pLpmCtx, pInputEvent);
<2>USBPD_LPM_EVENT_TYPE类型为:USBPD_LPM_EVENT_PE_PM_REQUEST_RTN
lpm_process_event2dpm(pLpmCtx, pInputEvent);
<3>其他事件:tcpm_state_run(&(pLpmCtx->Tcpm), pInputEvent, &bGoNextState);
(2)如果input事件为:USBPD_MODULE_LPM_PRL_RX ,USBPD_MODULE_LPM_PRL_TX,USBPD_MODULE_LPM_PRL_HR ,USBPD_MODULE_LPM_RTR , USBPD_MODULE_LPM_RCH , USBPD_MODULE_LPM_TCH:
分各自调用 usbtypec_statemachine_state_run ---> 运行函数至真列表中的指定函数
其中包括:StateInitFPtr(初始化),StateMainFPtr(main函数),StateExitFPtr(退出函数)
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/common/src/usbtypec_statemachine.c
USBPD_MODULE_LPM_PRL_RX && pLpmCtx->bSupportPD ---> prl_rx_state_run ---> usbtypec_statemachine_state_run ( PD协议接收)
USBPD_MODULE_LPM_PRL_TX && pLpmCtx->bSupportPD ---> prl_tx_state_run ---> usbtypec_statemachine_state_run (PD协议传输)
USBPD_MODULE_LPM_PRL_HR && pLpmCtx->bSupportPD ---> prl_hr_state_run ---> usbtypec_statemachine_state_run (PD协议硬重置)
USBPD_MODULE_LPM_RTR ---> rtr_state_run ---> usbtypec_statemachine_state_run (PD协议Chunked Message Router)
USBPD_MODULE_LPM_RCH ---> rch_state_run ---> usbtypec_statemachine_state_run (PD协议Chunked Rx相关的)
USBPD_MODULE_LPM_TCH ---> tch_state_run ---> usbtypec_statemachine_state_run (PD协议Chunked Tx相关的)
(3)如果input事件为:USBPD_MODULE_LPM_PE
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/lpm/src/lpm.c
先通过 pLpmCtx->pPDCtx->PE.Context.StateMachine.nextState 判断是硬重置or软重置
在调用函数:pe_state_run
在函数 pe_state_run 中做了如下处理:
<1>先判断软硬重置标记位进行软硬重置
<2>判断bTxPending标记位,如果为ture:
(pEvent->EventHeader.EvtType == USBPD_LPM_EVENT_ALERT_RECEIVE_SOP_MESSAGE_STATUS) ---> 返回USBPD_LPM_EVENT_ALERT_RECEIVE_SOP_MESSAGE_STATUS
(pEvent->EventHeader.EvtType == USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_FAILED ||
pEvent->EventHeader.EvtType == USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_DISCARDED ||
pEvent->EventHeader.EvtType == USBPD_LPM_EVENT_ALERT_TRANSMIT_SOP_MESSAGE_SUCCESSFUL) ---> pState->Context.bTxPending = false 将标记为写为false继续往下走
<3>usbtypec_statemachine_state_run ---> 运行指定的状态进入初始化函数、main函数、退出函数
(4)如果input事件不在上面的范围内:
ModuleInProcess = USBPD_MODULE_NONE;
pInputEvent->EventHeader.EvtDest = USBPD_MODULE_NONE;
lpm_process_event处理完输入事件之后,根据当前的状态对一些标记位和状态机进行重置,以便处理下一次的事务,到这里 lpm_process_event 的工作就结束了。
让我们再回到lpm主循环函数 lpm_mainloop:
在处理完lpm_process_event的事情之后,lpm需要判断是否需要通知dpm :
如果(LpmEvent & LPM_EVENTS_NOTIFY_DPM) 值为ture ---> lpm_notify_dpm(pLpmCtx);
让我们进入 lpm_notify_dpm 函数看看在这里都做了什么工作:
(1)判断 pLpmCtx->bPANEn 是否打开(启用 PAN 后,会阻止异步事件更新,直到 PAN 完成)
在该处配置: adsp_proc/core/settings/battman/battmngr/config/xxxx/battmngrconfig_props.c 检索关键字:LpmCfg
如果 pLpmCtx->bPANEn 打开:
未pending:
dpm_notify(pLpmCtx->pDPMInterface->pNotifyListener, USBPD_DPM_EVENT_LPM_PAN);
pending:
lpm_async_event_update
bNotifyAsyncEvent = true
如果 pLpmCtx->bPANEn 未打开:直接调用 lpm_async_event_update(pLpmCtx);
然后将标记位设置为ture: bNotifyAsyncEvent = true;
在 lpm_async_event_update 中:
<1>重置 LPM change flags
<2>判断是否支持PD,如果支持PD,需要判断是否需要同步PD的新事件
lpm_async_event_update_from_tcpm(pLpmCtx); //此函数遍历 tcpm 上下文以检查是否需要发送异步事件通知
if(pLpmCtx->pPDCtx->PE.Context.PDConnectorStatus.ConnectStatus)
{
lpm_async_event_update_from_pe(pLpmCtx);
}
<3>将 bNotifyAsyncEvent 设置为 true;
(2)判断 bNotifyAsyncEvent 以及多个标志位的状态(连接器状态变化,PD状态变化,bLiquidDetected使能)
经过一系列的动作(刷新缓存,判断,更新上下文)以后最终调用 dpm_notif 通知USBPD_DPM_EVENT_LPM_ASYNC_EVENT事件
dpm_notify(pLpmCtx->pDPMInterface->pNotifyListener, USBPD_DPM_EVENT_LPM_ASYNC_EVENT);
(3)如果 bNotifyAsyncEvent 值不为ture,判断是否需要同步PD事件
经过一系列的动作(刷新缓存,判断,更新上下文)以后最终调用 dpm_notif 通知USBPD_DPM_EVENT_LPM_MISC_EVENT事件
dpm_notify(pLpmCtx->pDPMInterface->pNotifyListener, USBPD_DPM_EVENT_LPM_MISC_EVENT);
【三】DPM部分
最终我们知道,通知是通过 dpm_notify下发的,这里已经到了dpm的范畴,那么我们就看一下 dpm_notify 这个函数都做了什么处理:
/ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/dpm/src/dpm.c
首先看一下函数的官方介绍:从 LPM 调用此函数以向 DPM 发送事件通知,所以这里就是LPM和DPM沟通的桥梁
/*!
* @function dpm_notify
* @detailed
* This function is called from LPM to send event notification to DPM
* @param[in] pPortConfig - pointer to port configuration data
* @return USBPDSTS USBPDSTS_SUCCESS on success or error code on failure.
*/
先判断事件是否在下列范围内?
case USBPD_DPM_EVENT_LPM_ASYNC_EVENT:
case USBPD_DPM_EVENT_LPM_RTN4REQUEST:
case USBPD_DPM_EVENT_LPM_PAN:
case USBPD_DPM_EVENT_LPM_MISC_EVENT:
case USBPD_DPM_EVENT_LPM_BM_SYNC:
case USBPD_DPM_EVENT_OPM_PAN_ACK:
case USBPD_DPM_EVENT_OPM_PAN_EN:
case USBPD_DPM_EVENT_OPM_COMMAND:
case USBPD_DPM_EVENT_BM_REQUEST:
case USBPD_DPM_EVENT_BM_DATAPORT_DETECTED:
如果在范围内,则调用 event_handler_set_event 函数添加事件给DPM:status = event_handler_set_event(pNotifyListner, EVENTTYPE_TO_EVENT(EventToNotify));
如果不在范围内,则认为是无效事件,不会添加;
事件类型定义在:ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/dpm/inc/dpm.h
typedef enum _USBPD_DPM_EVENT_TYPE
{
/*General Event*/
USBPD_DPM_EVENT_EXIT,
USBPD_DPM_EVENT_HKTIMER_TO,
/*Event from LPM/TCPM*/
USBPD_DPM_EVENT_LPM_ASYNC_EVENT,
USBPD_DPM_EVENT_LPM_RTN4REQUEST,
USBPD_DPM_EVENT_LPM_PAN,
USBPD_DPM_EVENT_LPM_MISC_EVENT,
USBPD_DPM_EVENT_LPM_BM_SYNC,
/*Event from PPM*/
USBPD_DPM_EVENT_PPM_TO,
/*Event from DPM*/
USBPD_DPM_EVENT_DPM_CABLE_EVENT,
USBPD_DPM_EVENT_DPM_PAN_ACK_TO,
/*Event from OPM*/
USBPD_DPM_EVENT_OPM_COMMAND,
USBPD_DPM_EVENT_OPM_PAN_EN,
USBPD_DPM_EVENT_OPM_PAN_ACK,
/*Event from BM*/
USBPD_DPM_EVENT_BM_REQUEST,
USBPD_DPM_EVENT_BM_DATAPORT_DETECTED,
USBPD_DPM_EVENT_INVALID
}USBPD_DPM_EVENT_TYPE;
接下来我们走进DPM阶段的循环 dpm_mainloop 中看看在该阶段都有什么处理:
(1)检查有没有pending的事件,如果有 USBPD_DPM_EVENT_EXIT 类型的事件,先处理lpm退出事件
DpmEvent & EVENTTYPE_TO_EVENT(USBPD_DPM_EVENT_EXIT ?
lpm_request(pDpmCtx->LpmInterface[port].pRequestListener, USBPD_LPM_EVENT_EXIT);
battman_os_sem_safe_destroy(&(pDpmCtx->LpmInterface[port].RequestBufferbSem), 1);
battman_os_sem_safe_destroy(&(pDpmCtx->LpmInterface[port].NotifyBufferbSem), 1);
usbtypec_timer_delete(pDpmCtx->PANAckTimer.Handle);
usbtypec_timer_delete(pDpmCtx->PPMTimer.Handle);
status |= event_handler_deinit(&(pDpmCtx->EvtHandler));
(2)记录新事件:dpm_update_new_events_to_queue
判断事件类型:
<1>USBPD_DPM_EVENT_OPM_COMMAND
evt_data_buffer.EventHeader.EvtType = USBPD_DPM_EVENT_OPM_COMMAND;
evt_data_buffer.EventHeader.EvtSrc = USBPD_MODULE_OPM;
evt_data_buffer.EventHeader.EvtDest = USBPD_MODULE_PPM;
evt_data_buffer.Payload.PayloadType = USBPD_EVENT_PAYLOAD_NONE;
status = event_handler_add_new_event(&(pDpmCtx->EvtHandler), &evt_data_buffer); //此函数获取输入事件并放入事件处理程序的队列中
<2>USBPD_DPM_EVENT_LPM_ASYNC_EVENT (LPM的同步事件)
status = dpm_queue_lpm_async_event(pDpmCtx, &evt_data_buffer);
<3>USBPD_DPM_EVENT_LPM_PAN
status = dpm_queue_lpm_pan_event(pDpmCtx);
<4>USBPD_DPM_EVENT_LPM_MISC_EVENT
status = dpm_queue_lpm_misc_event(pDpmCtx);
<5>USBPD_DPM_EVENT_DPM_PAN_ACK_TO
PAN_ACK超时,首先检查这是否是 BOOT/SSR 期间发送的初始断开连接请求的超时
dpm_usbc_pan_en_timeout()
否:dpm_usbc_pin_assignment_notify();
是,且 pDpmCtx->bPANEn 打开: dpm_handle_pan_ack_event(pDpmCtx); //PAN ACK Timeout
<6>USBPD_DPM_EVENT_OPM_PAN_ACK
status = dpm_handle_pan_ack_event(pDpmCtx);
<7>USBPD_DPM_EVENT_OPM_PAN_EN
status = dpm_usbc_handle_pan_en(pDpmCtx->ppm.Context.config.capability.bNumConnector, &(pDpmCtx->bPANEn));
<8> USBPD_DPM_EVENT_BM_REQUEST (来自BM侧请求)
evt_data_buffer.EventHeader.EvtType = USBPD_DPM_EVENT_BM_REQUEST;
evt_data_buffer.EventHeader.EvtDest = USBPD_MODULE_DPM;
evt_data_buffer.Payload.PayloadType = USBPD_EVENT_PAYLOAD_NONE;
status = event_handler_add_new_event(&(pDpmCtx->EvtHandler), &evt_data_buffer);//此函数获取输入事件并放入事件处理程序的队列中
<9>USBPD_DPM_EVENT_LPM_RTN4REQUEST (LPM对DPM请求的返回值,DPM请求后,LPM处理完,需要告知DPM返回结果)
status = dpm_queue_lpm_rtn4request_event(pDpmCtx);
<10>USBPD_DPM_EVENT_PPM_TO
TraceInfo(USBC_DPM, "PPM Timeout");
evt_data_buffer.EventHeader.EvtType = USBPD_DPM_EVENT_PPM_TO;
evt_data_buffer.EventHeader.EvtDest = USBPD_MODULE_PPM;
evt_data_buffer.Payload.PayloadType = USBPD_EVENT_PAYLOAD_NONE;
status = event_handler_add_new_event(&(pDpmCtx->EvtHandler), &evt_data_buffer);
<11>USBPD_DPM_EVENT_LPM_BM_SYNC (LPM发给BM的同步事件)
event_handler_set_event(pDpmCtx->PwrMgr.pBattMngrEvtHandler, BATTMNGR_DRV_HEARTBEAT_EVENT);
<12>USBPD_DPM_EVENT_BM_DATAPORT_DETECTED (检测到SDP/CDP后,通知DPM传统数据端口检测到)
TraceInfo(USBC_DPM, "DPM: BM inform data port detected");
evt_data_buffer.EventHeader.EvtType = USBPD_DPM_EVENT_BM_DATAPORT_DETECTED;
evt_data_buffer.EventHeader.EvtDest = USBPD_MODULE_PPM;
evt_data_buffer.Payload.PayloadType = USBPD_EVENT_PAYLOAD_NONE;
status = event_handler_add_new_event(&(pDpmCtx->EvtHandler), &evt_data_buffer);//此函数获取输入事件并放入事件处理程序的队列中
<13>其他:skipped events
剩余待记录事件-1
(3)处理事件:dpm_process_event
这里是重点,此函数处理dpm中的输入事件
在 dpm_process_event 中:
首先判断是否有输入事件信号,若没有返回异常
然后在循环中判断事件目标
<1>USBPD_MODULE_PPM & pInputEvent->EventHeader.EvtDest (要发往PPM的事件)
ModuleInProcess = USBPD_MODULE_PPM;
pDpmCtx->ppm.Context.pDpmPwrMngr = &(pDpmCtx->PwrMgr);
status = ppm_state_run(&(pDpmCtx->ppm), pInputEvent, &bGoNextState); //设置ppm状态机
在 ppm_state_run 中:
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/dpm/src/ppm.c
1.首先判断是否为重置命令,如果是,执行重置操作,并返回:USBPD_UCSI_COMMAND_CODE_PPM_RESET
若非重置命令:usbtypec_statemachine_state_run ---> 运行指定的状态进入初始化函数、main函数、退出函数
2.然后判断是否需要通知opm:pState->Context.bNotify
ppm_notify_opm ---> pmic_glink_send_notification(通知UCSI,AP和ADSP的通信渠道)
<2>USBPD_MODULE_DPM & pInputEvent->EventHeader.EvtDest (发给自己的事件)
ModuleInProcess = USBPD_MODULE_DPM;
status = dpm_event_handler(pDpmCtx, pInputEvent);
在 dpm_event_handler 中 ://此函数将调用特定于 DPM 事件(来自总线和BM)的处理程序函数
首先判断事件类型:
1.USBPD_DPM_EVENT_DPM_CABLE_EVENT
---> dpm_handle_cable_event //此函数通过将cable事件发送到 battmngr 来处理 DPM cable事件
---> charger_notify(CHARGER_EVENT_DETECTION_UPDATE);
2.USBPD_DPM_EVENT_BM_REQUEST
---> dpm_handle_bm_request_event //此函数处理 BM 请求事件
---> 判断请求类型,发送给lpm:dpm_set_request_to_lpm
3.USBPD_DPM_EVENT_INVALID 和其他
---> return USBPDSTS_ERROR_NOT_SUPPORTED;
<3>其他将发往目标标记为none
【四】PPM,OPM部分
DPM会通过 ppm_state_run 函数向PPM发送事件
PPM主要分为两个部分,一是PPM状态机,二是OPM
(1)PPM状态机:
PPM的状态在此处定义:/ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/dpm/inc/ppm.h
typedef enum _USBPD_PPM_STATE_TYPE
{
//USBPD_PPM_STATE_PPM_ENTRY,
USBPD_PPM_STATE_PPM_IDLE_NOTIFY_DISABLE, /*Enter this State after PPM Reset or Init*/
//USBPD_PPM_STATE_PPM_BUSY,
USBPD_PPM_STATE_PPM_IDLE_NOTIFY_ENABLE,
USBPD_PPM_STATE_PPM_PROCESS_ASYNC_EVENT,
USBPD_PPM_STATE_PPM_PROCESS_COMMAND,
USBPD_PPM_STATE_PPM_WAIT_FOR_COMMAND_COMPLETION_ACK,
USBPD_PPM_STATE_MAX
}USBPD_PPM_STATE_TYPE;
不同的状态对应不同的函数:
//USBPD_PPM_STATE_PPM_IDLE_NOTIFY_DISABLE,
USBPD_PPM_STATE_PPM_IDLE_NOTIFY_DISABLE ---> ppm_state_ppm_idle_notify_disable_main
//USBPD_PPM_STATE_PPM_IDLE_NOTIFY_ENABLE,
USBPD_PPM_STATE_PPM_IDLE_NOTIFY_ENABLE ---> ppm_state_ppm_idle_notify_enable_main
//USBPD_PPM_STATE_PPM_PROCESS_ASYNC_EVENT,
USBPD_PPM_STATE_PPM_PROCESS_ASYNC_EVENT ---> ppm_state_ppm_proccess_async_event_main
//USBPD_PPM_STATE_PPM_PROCESS_COMMAND, ***这里是重点
USBPD_PPM_STATE_PPM_PROCESS_COMMAND ---> ppm_state_process_command_main
//USBPD_PPM_STATE_PPM_WAIT_FOR_COMMAND_COMPLETION_ACK, ***通知opm的状态
USBPD_PPM_STATE_PPM_WAIT_FOR_COMMAND_COMPLETION_ACK ---> ppm_state_ppm_wait_for_command_completion_main
先看 ppm_state_process_command_main :
<1>USBPD_DPM_EVENT_OPM_COMMAND: ppm_proccess_cancel_command
判断是否为OPM的取消操作
<2>USBPD_DPM_EVENT_LPM_RTN4REQUEST:
根据LPM的返回值判是否有负载:
无负载:
case USBPD_DPM2LPM_REQUEST_PD_DR_UFP:
case USBPD_DPM2LPM_REQUEST_PD_DR_DFP:
case USBPD_DPM2LPM_REQUEST_PD_PR_SNK:
case USBPD_DPM2LPM_REQUEST_PD_PR_SRC:
case USBPD_DPM2LPM_REQUEST_PD_SOFTRESET:
case USBPD_DPM2LPM_REQUEST_PD_HARDRESET:
通过 ppm_set_cci 函数更新成功或失败(设置cc状态)
存在负载:
case USBPD_DPM2LPM_REQUEST_PD_PARNTER_GET_SRC_CAP:
case USBPD_DPM2LPM_REQUEST_PD_PARNTER_GET_SNK_CAP:
先读取负载: ppm_update_caps_from_rtnrequest
ppm_proccess_get_pdos_command //This function will go over partner pdos
<3>USBPD_DPM_EVENT_LPM_ASYNC_EVENT :ppm_handle_async_event_update (LPM的同步事件)
<4>USBPD_DPM_EVENT_BM_DATAPORT_DETECTED : ppm_handle_legacy_dataport_events (检测到SDP/CDP后,通知DPM传统数据端口检测到)
再看 ppm_state_ppm_wait_for_command_completion_main
<1>USBPD_DPM_EVENT_OPM_COMMAND && USBPD_UCSI_COMMAND_CODE_ACK_CC_CI
处理来自 OPM 的确认命令
将状态设为 USBPD_PPM_STATE_PPM_IDLE_NOTIFY_ENABLE
<2>USBPD_DPM_EVENT_LPM_ASYNC_EVENT
ppm_handle_async_event_update
<3>USBPD_DPM_EVENT_PPM_TO
PP超时
<4>USBPD_DPM_EVENT_BM_DATAPORT_DETECTED
ppm_handle_legacy_dataport_events
(2)OPM,即ucsi(通过glink机制和AP通信):
AP和ADSP是通过glink机制进行数据传输的(pmic_glink_process_rx_data):/ADSP.HT.5.5/adsp_proc/core/battman/framework/pmicglink/src/pmic_glink.c
在 pmic_glink_process_rx_data 函数中调用 ppm_ucsi_mailbox_write 和 ppm_ucsi_mailbox_read 实现外部对ucsi mailbo的读写请求
<1>ppm_ucsi_mailbox_write:AP--->GLINK--->OPM--->PPM
先通过 BattMngr_memscpy 拷贝OPM侧control data和message data到PPM
然后通过 dpm_notify下发通知,唤醒listener监听
<2>ppm_ucsi_mailbox_read:PPM--->OPM--->GLINK--->AP
将sMailbox中的提供给pReadBuf,然后通过 BattMngr_memscpy拷贝到OPM,通过glink发送给AP
sMailbox是一个 USBPD_UCSI_DATA 类型的结构体,定义如下:
static USBPD_UCSI_DATA sMailbox;
ADSP.HT.5.5/adsp_proc/core/battman/usbtypec/common/inc/ucsi.h
typedef struct _USBPD_UCSI_DATA
{
USBPD_UCSI_VERSION_DATA version; //VERSION(16 bits)
unsigned short reserve; //RESERVE(16 bits)
USBPD_UCSI_CCI_DATA cci; //CCI(32 bits)
USBPD_UCSI_GENERIC_CONTROL_DATA control; //CONTROL(64 bits)
USBPD_UCSI_GENERIC_MESSAGE_DATA message_in; //MESSAGE_IN(128 bits) In to OPM/OS
USBPD_UCSI_GENERIC_MESSAGE_DATA message_out; //MESSAGE_OUT(128 bits) Out to OPM/OS
} USBPD_UCSI_DATA, *PUSBPD_UCSI_DATA;
【五】GLINK部分:
pmic_glink 是BM线程中的一部分,是AP和ADSP数据交互的通道
其中函数 pmic_glink_process_rx_data 在ADSP侧是最为重要的部分,用来处理数据。
在其中先判断 evt_buf->msg_owner 类型:五种类型中我们主要关注后四种:
(1)PMIC_GLINK_MSG_OWNER_B2
b2 LED控制,这里不展开赘述了
(2)PMIC_GLINK_MSG_OWNER_CHARGER 32778 (ap侧为:qti_battery_charger.c)
处理 battmngr 请求
switch (evt_buf->opcode)
{
case BATT_MNGR_GET_BATT_ID_REQ:
// need to send back the battery ID
...
case BATT_MNGR_GET_CHARGER_STATUS_REQ:
// need to send back the charger status
...
case BATT_MNGR_SET_OPERATIONAL_MODE_REQ:
...
case BATT_MNGR_SET_NOTIFICATION_CRITERIA_REQ:
...
case BATT_MNGR_DISABLE_NOTIFICATION_REQ:
...
case BATT_MNGR_GET_BATTERY_INFORMATION_REQ:
...
case BATT_MNGR_SET_CHARGE_RATE_REQ:
...
case BATT_MNGR_GET_TEST_INFO_REQ:
...
case BATT_MNGR_POWER_SUPPLY_GET_REQ:
...
case BATT_MNGR_POWER_SUPPLY_SET_REQ:
...
case BATT_MNGR_SET_SHIP_MODE_REQ:
...
case USB_POWER_SUPPLY_GET_REQ:
...
case USB_POWER_SUPPLY_SET_REQ:
...
case DC_POWER_SUPPLY_GET_REQ:
...
case DC_POWER_SUPPLY_SET_REQ:
...
case BATT_MNGR_GET_DEBUG_PARAM_REQ:
...
case BATT_MNGR_SET_DEBUG_PARAM_REQ:
...
case WLS_IDT_FW_CHECK_REQ:
...
case WLS_IDT_FW_GET_REVISION_REQ:
...
case BATT_MNGR_SET_SHDN_REQ:
...
case WLS_IDT_FW_PUSH_BUFFER_REQ:
...
}
pmic_glink_tx
(3)PMIC_GLINK_MSG_OWNER_USB_TYPE_C 32779 (ap侧为:ucsi_glink.c)
处理PD/TYPEC请求 (opm中提到的就是此处)
switch (evt_buf->opcode)
{
case UCSI_READ_BUFFER_REQ:
---> ppm_ucsi_mailbox_read
...
case UCSI_WRITE_BUFFER_REQ:
---> ppm_ucsi_mailbox_write
...
}
pmic_glink_tx
(4)PMIC_GLINK_MSG_OWNER_USBC_PAN 32780 (ap侧为:altmode-glink.c)
处理PAN请求
switch (evt_buf->opcode)
{
case USBC_CMD_READ_REQ:
--->dpm_usbc_cmd_read
...
case USBC_CMD_WRITE_REQ:
--->dpm_usbc_cmd_write
...
}
pmic_glink_tx
(5)PMIC_GLINK_MSG_OWNER_OEM 32782 (ap侧为:power_glink.c)
OEM 的 glink 消息
switch (evt_buf->opcode)
{
case OEM_OPCODE_READ_BUFFER:
--->battman_oem_get_buffer
...
case OEM_OPCODE_WRITE_BUFFER:
--->battman_oem_set_buffer
...
}
pmic_glink_tx
ADSP.HT.5.5/adsp_proc/core/battman/battmngr/common/src/battmngr_i.c
在 battman_oem_get_buffer 和 battman_oem_set_buffer 中会传递 oem_property_type_e 类型的 oem_property_id ,这个对应ap侧的power_glink_property_id
adsp:/ADSP.HT.5.5/adsp_proc/core/battman/framework/pmicglink/inc/pmic_glink_msg.h
typedef enum {
OEM_PROPERTY_TEST,
OEM_PROPERTY_SET_INPUT_SUSPEND,
OEM_PROPERTY_SET_CHARGE_ENABLE,
OEM_PROPERTY_SET_VBOOST,
OEM_PROPERTY_SET_OTG,
OEM_PROPERTY_SET_WLS_BST,
OEM_PROPERTY_SET_USB_ICL,
OEM_PROPERTY_SET_SHIP_MODE_TIMING,
OEM_PROPERTY_SET_SHIP_MODE,
OEM_PROPERTY_SET_FV_FOR_BASP,
OEM_PROPERTY_SET_REGISTER_VALUE, /* 10 */
OEM_PROPERTY_GET_REGISTER_VALUE,
OEM_PROPERTY_SET_VBUS_CTRL,
OEM_PROPERTY_SET_FFC_FV_DELTA,
OEM_PROPERTY_SET_FFC_ITERM,
OEM_PROPERTY_SET_TIME_SYNC,
OEM_PROPERTY_GET_INIT_STATUS,
OEM_PROPERTY_SET_INIT_DATA,
OEM_PROPERTY_GET_CC_STATUS,
OEM_PROPERTY_GET_PLUGIN_STATUS,
OEM_PROPERTY_SET_PORT_ROLE, /* 20 */
OEM_PROPERTY_SET_USB_MODE,
OEM_PROPERTY_SET_PD_DISABLE_FLAG,
OEM_PROPERTY_SET_VSYS_MIN,
OEM_PROPERTY_SET_IBAT,
OEM_PROPERTY_SET_VTERM,
OEM_PROPERTY_SET_JEITA_TABLE,
OEM_PROPERTY_GET_CHARGE_STATUS,
OEM_PROPERTY_CURR_CALI,
OEM_PROPERTY_LAST_CAP_REG_VALUE,
OEM_PROPERTY_SET_UVDM_FUNC_CMD,
OEM_PROPERTY_SET_USB_PHY_HIZ,
OEM_PROPERTY_GET_VOLTAGE_SYS,
OEM_PROPERTY_SET_RETRIGGER_APSD,
OEM_PROPERTY_SET_NON_CC_INSERT_EVENT_MASK,
OEM_PROPERTY_SET_MISC_CMD,
OEM_PROPERTY_MAX
} oem_property_type_e;
ap:/vendor/ontim/chipset_common/plugins/kernel/include/ontim_platform/hwpower/common_module/power_glink.h
enum power_glink_property_id {
POWER_GLINK_PROP_ID_BEGIN = 0,
POWER_GLINK_PROP_ID_TEST = POWER_GLINK_PROP_ID_BEGIN,
POWER_GLINK_PROP_ID_SET_INPUT_SUSPEND,
POWER_GLINK_PROP_ID_SET_CHARGE_ENABLE,
POWER_GLINK_PROP_ID_SET_VBOOST,
POWER_GLINK_PROP_ID_SET_OTG,
POWER_GLINK_PROP_ID_SET_WLSBST,
POWER_GLINK_PROP_ID_SET_USB_ICL,
POWER_GLINK_PROP_ID_SET_SHIP_MODE_TIMING,
POWER_GLINK_PROP_ID_SET_SHIP_MODE,
POWER_GLINK_PROP_ID_SET_FV_FOR_BASP,
POWER_GLINK_PROP_ID_SET_REGISTER_VALUE, /* 10 */
POWER_GLINK_PROP_ID_GET_REGISTER_VALUE,
POWER_GLINK_PROP_ID_SET_VBUS_CTRL,
POWER_GLINK_PROP_ID_SET_FFC_FV_DELTA,
POWER_GLINK_PROP_ID_SET_FFC_ITERM,
POWER_GLINK_PROP_ID_SET_TIME_SYNC,
POWER_GLINK_PROP_ID_GET_ADSP_INIT_STATUS,
POWER_GLINK_PROP_ID_SET_INIT_DATA,
POWER_GLINK_PROP_ID_GET_CC_SHORT_STATUS,
POWER_GLINK_PROP_ID_GET_PLUGIN_STATUS,
POWER_GLINK_PROP_ID_SET_PORT_ROLE, /* 20 */
POWER_GLINK_PROP_ID_SET_USB_MODE,
POWER_GLINK_PROP_ID_SET_PD_DISABLE_FLAG,
POWER_GLINK_PROP_ID_SET_IBAT,
POWER_GLINK_PROP_ID_SET_VTERM,
POWER_GLINK_PROP_ID_SET_JEITA_TABLE,
POWER_GLINK_PROP_ID_GET_CHARGE_STATUS,
POWER_GLINK_PROP_ID_CURR_CALI,
POWER_GLINK_PROP_ID_LAST_CAP_REG_VALUE,
POWER_GLINK_PROP_ID_SET_UVDM_FUNC_CMD,
POWER_GLINK_PROP_ID_SET_USB_PHY_HIZ,
POWER_GLINK_PROP_ID_GET_VOLTAGE_SYS,
POWER_GLINK_PROP_ID_END,
};
除了此之外,我们在前面typec阶段的时侯提到过:pmic_glink_send_oem_notification 函数用来通知ap侧检测结果,该函数传递的信息为:oem_notify_id
adsp:/ADSP.HT.5.5/adsp_proc/core/battman/framework/pmicglink/inc/pmic_glink_msg.h
typedef enum {
OEM_PROPERTY_ID_USB_CONNECTION_EVENT,
OEM_PROPERTY_ID_DC_CONNECTION_EVENT,
OEM_PROPERTY_ID_TYPEC_EVENT,
OEM_PROPERTY_ID_PD_EVENT,
OEM_PROPERTY_ID_APSD_EVENT,
OEM_PROPERTY_ID_WLS2WIRED,
OEM_PROPERTY_ID_WLSIN_VBUS,
OEM_PROPERTY_ID_EMARK_EVENT,
OEM_PROPERTY_ID_QBG_EVENT,
OEM_PROPERTY_ID_UEM_EVENT,
} oem_notify_id;
对应AP侧的定义为:
ap:/vendor/ontim/chipset_common/plugins/kernel/include/ontim_platform/hwpower/common_module/power_glink.h
enum power_glink_notify_id {
POWER_GLINK_NOTIFY_ID_BEGIN = 0,
POWER_GLINK_NOTIFY_ID_USB_CONNECT_EVENT = POWER_GLINK_NOTIFY_ID_BEGIN,
POWER_GLINK_NOTIFY_ID_DC_CONNECT_EVENT,
POWER_GLINK_NOTIFY_ID_TYPEC_EVENT,
POWER_GLINK_NOTIFY_ID_PD_EVENT,
POWER_GLINK_NOTIFY_ID_APSD_EVENT,
POWER_GLINK_NOTIFY_ID_WLS2WIRED,
POWER_GLINK_NOTIFY_ID_WLSIN_VBUS,
POWER_GLINK_NOTIFY_ID_EMARK_EVENT,
POWER_GLINK_NOTIFY_ID_QBG_EVENT,
POWER_GLINK_NOTIFY_ID_UEM_EVENT,
POWER_GLINK_NOTIFY_ID_END,
};
pmic_glink_msg.h 中还定义了很多信息类型,在BM线程中和AP交互传输数据
【六】BM部分
BM是电池管理的核心部分,其代码在:/ADSP.HT.5.5/adsp_proc/core/battman/battmngr/
adsp_proc/core/
|
|----battman
| |
| |----battmngr/ BM代码
| | |
| | |----battmngrinit/ 初始化代码初始化各个BM的各个模块
| | |----build/ 编译配置
| | |----charger/ 充电子模块
| | | |
| | | |----bcs/ 电池充电状态接口
| | | |----build/ 编译配置
| | | |----icm/ 智能充电管理
| | | |----main/ 充电主程序
| | | |----ssdev/ 充电设备操作接口
| | | | |
| | | | |----i2c_idt.c i2c充电控制接口(smb/CP)
| | | | |----ssdev_typec.c typc充电控制接口(Type-C/PD)
| | | | |----ssdev_usb.c usb充电控制接口(普充电/QC)
| | | | |----ssdev_wls.c 无限充电控制接口(无限充电)
| | | |
| | | |----switchers/ DCDC开关器控制
| | |
| | |----externalfg/ 外部电量计
| | |----qbg/ Q电量计
| | |----statemachine/ 状态机
| | |----technologyspecific/ 技术规范(各个子模块的功能接口比如QG,chg等等)
| | |----platform// 平台资源(Non-Hlos的资源比如中断和寄存器,需要自己封装接口来操作"pmic/"下的端口实现)
| |
| |
| |----build/ 编译配置
| |----framework/ 通信框架(AP和ADSP)
| |----pmic/ PMIC各个子模块寄存器操作接口(可以认为是调用封装库)
| |----usbtypec/ Type-C模块
|
|----settings/battman/battmngr/config/kodiak/battmngr_config.xml
|
|----配置文件
|
|-----settings/battman/battmngr/config/kodiak/battmngrconfig_props.c
|
|----配置文件引用的源码
charger初始化的时侯通过 BattMngr_Thread_Create 函数创建了charger_main 线程
在 charger_main_loop 中,charger_process_events 函数主要负责充电相关的事件处理
ADSP.HT.5.5/adsp_proc/core/battman/battmngr/charger/main/src/charger_thread.c
事件主要有:
(1)CHARGER_EVENT_USBIN_UVLO || CHARGER_EVENT_USBIN_OVLO || CHARGER_EVENT_USBIN_COLLAPSE
ssdev_handle_charger_failure
(2)CHARGER_EVENT_DETECTION_UPDATE
ADSP.HT.5.5/adsp_proc/core/battman/battmngr/charger/main/src/charger_detection.c
charger_detection_event_handler :This function handle events signaled from USB Typec/PD stack or Hardware Interrupt
ADSP.HT.5.5/adsp_proc/core/battman/battmngr/charger/ssdev/src/ssdev.c
ssdev_get_plugin_state
SSDEV_MODULE_TYPEC:ssdev_usb_get_plugin_state
SSDEV_MODULE_USB:ssdev_usb_get_plugin_state(同上)
检测插入--->PmSchgUsb_GetIrqStatus
SSDEV_MODULE_WLS:ssdev_wls_get_plugin_status
检测无线充电
ssdev_detect_partner
SSDEV_MODULE_TYPEC:ssdev_typec_detect_partner
/ADSP.HT.5.5/adsp_proc/core/battman/battmngr/charger/ssdev/src/ssdev_typec.c
检测typec类型
case USBPD_UCSI_CSC_POWER_OPMODE_BC:
...
case USBPD_UCSI_CSC_POWER_OPMODE_TYPEC_1P5A:
...
case USBPD_UCSI_CSC_POWER_OPMODE_TYPEC_3A:
...
default:
...
SSDEV_MODULE_USB:ssdev_usb_detect_partner
/Q8201_modem_user/ADSP.HT.5.5/adsp_proc/core/battman/battmngr/charger/ssdev/src/ssdev_usb.c
通过bc1.2获取apsd_result,得到插入检测结果
case PM_SCHG_USB_APSD_RESULT_STATUS_SDP_CHARGER:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_OCP_CHARGER:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_CDP_CHARGER:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_DCP_CHARGER:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_FLOAT_CHARGER:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_QC_2P0:
...
case PM_SCHG_USB_APSD_RESULT_STATUS_QC_3P0:
...
default:
...
SSDEV_MODULE_WLS:ssdev_wls_detect_partner
检测无线充电
(3)CHARGER_EVENT_CONTRACT_UPDATE (在前面的dpm阶段,CABLE变化,刷新相关数据并通知charger线程会发送该通知)
charger_detection_event_handler //具体处理同上
(4)CHARGER_EVENT_RERUN_APSD //ADSP重启
PmSchgUsb_SetRerunApsd
BattMngrStateMachine_Main_Thread:
在BM状态机中处理各种状态:
(1)if(Event & BATTMNGR_DRV_EXIT_EVENT)
直接退出
(2)if (Event & BATTMNGR_DRV_BATT_OV_EVENT) {
...
(3)if (Event & BATTMNGR_DRV_FCC_STEPPER_EVENT) {
...
(4)if(Event & BATTMNGR_DRV_HEARTBEAT_EVENT)
...
(5)if(Event & BATTMNGR_DRV_CHGTIMEOUT_EVENT)
...
(6)if(Event & BATTMNGR_DRV_PRE_CHARGER_CABLE_EVENT)
(void)battmngr_platform_charger_update(pDeviceContext);
(7)if(Event & BATTMNGR_DRV_USB_PLUGIN_EVENT)
battmngr_platform_wls_switch_usb();
charger_notify(CHARGER_EVENT_DETECTION_UPDATE);
(8)if(Event & BATTMNGR_DRV_CHARGER_PLUGIN_EVENT)
(void)battmngr_platform_charger_update(pDeviceContext);
(9)if(Event & BATTMNGR_DRV_CHARGER_CABLE_EVENT)
判断是否为无线充电,设置充电电流
(void)BattMngrStateMachineLevel_Run_Current_State(pDeviceContext);
prevMaxChargeCurrent = pDeviceContext->BattMngrData.ControlCharging.batt_max_charge_current;
(10)if(Event & BATTMNGR_DRV_THERMAL_EVENT)
(void)BattMngrStateMachineLevel_Run_Current_State(pDeviceContext);
(11)if(Event & BATTMNGR_DRV_BATTERY_PRESENT_EVENT)
...
(12)if(Event & BATTMNGR_DRV_ESDTIMER_EVENT)
(void)battmngr_platform_serve_esd_timer_expire();
(13)if(Event & BATTMNGR_DRV_BATT_AUTH_CHECK_EVENT)
(void)battmngr_platform_serve_batt_auth_check_timer();
(14)if(Event & BATTMNGR_DRV_QBG_DATA_FULL_EVENT)
...
(15)if(Event & BATTMNGR_DRV_FIFO_UPDATE_DONE_EVENT)
...
(16)if(Event & BATTMNGR_DRV_QG_STATE_CHANGE_EVENT)
...
(17)if (Event & BATTMNGR_DRV_CHG_ST_CHANGE_EVENT)
...
(18)if(Event & BATTMNGR_DRV_USB_OTG_EVENT)
(void)battmngr_platform_handle_uusb_otg(pDeviceContext);
(void)battmngr_platform_charger_update(pDeviceContext);
最后下发通知:(void)BattMngrNotify_CallBattMiniClass(pDeviceContext);
电池管理电量上报机制:
BM Thread -> battmngr_platform_charger_update
BattMngrPlatformFuncs.BattMngrPlat_Charger_Update_FuncPtr->battmngr_plat_schgp_qg_charger_update
ADSP.HT.5.5/adsp_proc/core/battman/battmngr/platform/xxxx/tioman/src/battmngr_plat_schgp_qg.c
将propery都存到到对应的属性中,例如usb_power_supply_properties
pmic_glink_send_power_supply_notification (msg.notifcation == USB_POWER_SUPPLY_GET_REQ == BC_USB_STATUS_GET)
pmic_glink_tx(msg.hdr.opcode = BATT_MNGR_NOTIFY_IND == BC_NOTIFY_IND)
根据opcode在callback回kernel中调用handle_notification发生变化,再去将ADSP返回的值更新到powersupply properties
最后还是调用到 power_supply_changed 就跟原先的上报流程一样了,通过uevent上报各上层的healthd
电源管理温度采集框架:通过battman_adc_read函数获取温度:/ADSP.HT.5.5/adsp_proc/core/battman/framework/osservice/osa/src/battman_adc.c
端口防烧温控节点:
usb port就是CONN_THERM(PM7250B),ADC_INPUT_CONN_THERM
温度曲线表:
/ADSP.HT.5.5/adsp_proc/core/settings/pmic/adc/config/kodiak/VAdcSettings.c
ADC_INPUT_CONN_THERM(PM_03)
static const AdcMapPtInt32toInt32Type adcMap_NTC30K[] =
{
......
};
const AdcIntTableType gVAdcSys30KThermTable =
{
.pTable = adcMap_NTC30K,
.uLength = ARRAY_LENGTH(adcMap_NTC30K),
};
{
.pszName = ADC_INPUT_CONN_THERM(PM_03),
.uAdcHardwareChannel = 0x27,
.eSettlingDelay = VADC_SETTLING_DELAY_100_US,
.eAverageMode = VADC_AVERAGE_1_SAMPLE,
.eDecimationRatio = VADC_DECIMATION_RATIO_1024,
.eCalMethod = VADC_CAL_METHOD_RATIOMETRIC,
.scalingFactor = {1, 1}, /* {num, den} */
.eScalingMethod = VADC_SCALE_THERMISTOR,
.uPullUp = 30000,
.pIntTable = &gVAdcSys30KThermTable,
},