Android Qcom USB Driver学习(九)

该系列文章总目录链接与各部分简介: 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

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

你可能感兴趣的:(Android_USB,android,charging)