Fork me on GitHub

Android Qcom USB Driver学习(九)

高通的某些平台将电源管理移植到了ADSP Subsystem, 分析一下其中比较关心的部分

Architecture

    —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —
    | Generic TypeC Drvier             PowerSupply Framework  |
	|  GlinkClient-UCSI                   GlinkClient-BM      |
	|               PMIC Glink(Linux kernel)                  |
    —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —
	|                  PMIC GLink(ADSP)                       |
	|     Charger Thread	                   BM Thread      |
	 —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —

BM    (Battery Manager)
SSDEV (Sink/Source devices)
BCS   (Battery Charging Status)
ICM   (Intelligent Charging Module)
APSD  (Automatic power source detection)
AICL  (automatic input current limiting)
UCSI  (USB Type-C Connector System Software Interface driver)

Charge Detection

不同于之前是先运行BC1.2再运行APSD,这里是直接运行APSD其中兼容BC1.2

BattMngrDevice_InitContext (既然ChgConfigData没有初始化 usb_connector_type,但检测的时候需要判断类型)
//CHARGER_CONFIG_DATA -> CHARGER_DETECTION_CONFIG_DATA usb_connector_type + NoofInputs 检测时有用
//charget_cfg.NoOfInputs = 2; (Input0  Type-C port or microUSB port + Input1  Wireless charging)

ssdev_initialize(0, (usb_connector_type == CONNECTOR_TYPE_MICRO_USB) ? SSDEV_MODULE_USB : SSDEV_MODULE_TYPEC);
ssdev_initialize(1, SSDEV_MODULE_WLS);

PmSchgAdcCmn2_GetUSBConnectorType(&usb_connector_type) (battmngrconfig_props.c CONNCfg定义的属性 0:microB 1:typec)
从这里我们可以得知,如果没有定义属性或者属性置为0,则默认是 SSDEV_MODULE_TYPEC,否则则需要通过PMIC内部来进行判断

charger初始化的时候通过BattMngr_Thread_Create创建了线程charger_main,
while的循环执行charger_events (CHARGER_EVENT_TYPE 包含CHARGER_EVENT_CHGTYPE_CHANGE 角色电压电流等)
charger_process_events
	charger_detection_event_handler
	    ssdev_detect_partner
		    SSDEV_MODULE_TYPEC ->  ssdev_typec_detect_partner
			SSDEV_MODULE_USB   ->  ssdev_usb_detect_partner
			break
		charger_detection_evaluate_charger
			SSDEV_MODULE_TYPEC ->  charger_detection_evaluate_typec_charger
			break
			SSDEV_MODULE_USB   ->  charger_detection_evaluate_usb_charger
			break

SSDEV_PARTNER_TYPE
	SSDEV_PARTNER_SNK_USB_SDP  SSDEV_PARTNER_SNK_USB_OCP, SSDEV_PARTNER_SNK_USB_CDP,
	SSDEV_PARTNER_SNK_USB_DCP, SSDEV_PARTNER_SNK_USB_FLOAT,...

SSDEV_PARTNER_TYPE跟之前平台类似 Android Qcom USB Driver学习(二)

需要注意在SSDEV_MODULE_TYPEC中ssdev_typec_detect_partner 和 ssdev_usb_detect_partner之间是没有break的,
也就是说无论是Typec还是usb都要通过ssdev_usb_detect_partner来调用PmSchgUsb_GetApsdResultStatus (APSD算法兼容BC1.2)返回
UsbPartnerType (充电类型),并且在charger_detection_evaluate_charger中应用,只执行一个来进行Input Current Limit的配置,
charger_detection_evaluate_typec_charger与charger_detection_evaluate_usb_charger 中就有break,

那时什么情况下会去触发detect呢? 中断 BATTMNGR_INTERRUPT_TYPE

battmngr_plat_irq_schgp_qg_apsd_done
在APSD运行的结束的中断后charger_notify(CHARGER_EVENT_DETECTION_UPDATE)通知到Charger Thread
battmngr_plat_irq_schgp_qg_plug_in
在插入的时候会发送BATTMNGR_DRV_USB_PLUGIN_EVENT,再通过charger_notify通知到Charger Thread

那时什么情况下会去触发detect呢? 中断 BATTMNGR_INTERRUPT_TYPE

battmngr_plat_irq_schgp_qg_apsd_done
在APSD运行的结束的中断后charger_notify(CHARGER_EVENT_DETECTION_UPDATE)通知到Charger Thread
battmngr_plat_irq_schgp_qg_plug_in
在插入的时候会发送BATTMNGR_DRV_USB_PLUGIN_EVENT,再通过charger_notify通知到Charger Thread

Kernel communication with ADSP

Battery Charging

battery_chg_write -> pmic_glink_write + wait_for_completion_timeout(等待ADSP的ack)
pmic_glink_process_rx_data -> pmic_glink_tx 
处理数据并且回调给Kernel,返回响应,使得上面发送时的wait_for_completion_timeout等待结束
pmic_glink_rx_callback -> client->msg_cb
	battery_chg_callback -> handle_message -> completion ack

battery_dock_charger_notify_msg(通信的message由两部分组成)	
(1)PMIC Glink message header
#define MSG_OWNER_BC			32778   (kernel)
#define MSG_TYPE_REQ_RESP		1

req_msg.hdr.owner = MSG_OWNER_BC;
req_msg.hdr.type = MSG_TYPE_REQ_RESP;
req_msg.hdr.opcode = (opcode for battery charger)

(2)req_msg.value + req_msg.property_id


注意Kernle和ADSP定义的名称不同 
#define PMIC_GLINK_MSG_OWNER_CHARGER     32778  (ADSP)
#define PMIC_GLINK_MSG_TYPE_REQ_RESP      1

Type-C Role

Android Qcom USB Driver学习(一)

#define MSG_OWNER_UC			32779             (kernel)
#define PMIC_GLINK_MSG_OWNER_USB_TYPE_C  32779    (ADSP)

ucsi_acknowledge_connector_change 
    ucsi_qti_async_write -> ucsi_qti_glink_write -> pmic_glink_write
UCSI最终还是通过PMIC GLink的API来实现,并且同样会产生回调,会通过msg head中的owner来区分Client
pmic_glink_rx_callback->client->msg_cb
	ucsi_callback -> handle_ucsi_notify -> ucsi_connector_change


 typedef enum _PM_TYPEC_PORT_ROLE_TYPE                typedef enum _PM_TYPEC_EXIT_CONTROL_TYPE
{                                                     {
    TYPEC_PORT_ROLE_DRP,    //Source还是Sink由CC决定       TYPEC_EXIT_CONTROL_SNK,
    TYPEC_PORT_ROLE_SNK,    //Source 供电                  TYPEC_EXIT_CONTROL_SRC,
    TYPEC_PORT_ROLE_SRC,    //Sink接受供电            } PM_TYPEC_EXIT_CONTROL_TYPE;
    TYPEC_PORT_ROLE_DISABLE,
    TYPEC_PORT_ROLE_INVALID
} PM_TYPEC_PORT_ROLE_TYPE;


这个还是跟之前如果需要转变则需要kernel调用两个API(1)typec_set_data_role (2)usb_role_switch_set_role

enum typec_data_role {                               enum typec_role {
 	TYPEC_DEVICE,                                        TYPEC_SINK,
 	TYPEC_HOST,                                          TYPEC_SOURCE,
};       

Battery Status

Android uevent 电池电量上报机制

BM Thread -> battmngr_platform_charger_update
BattMngrPlatformFuncs.BattMngrPlat_Charger_Update_FuncPtr -> battmngr_plat_scpqchg_qbg_update_charger_power_supply
  将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
posted @ 2024-08-25 18:44  yooooooo  阅读(54)  评论(0编辑  收藏  举报