static int pd_eval_src_caps(struct usbpd *pd) { int i; union power_supply_propval val; bool pps_found = false; u32 first_pdo = pd->received_pdos[0]; int pdo_select = -1; u32 mv_select = 0, ma_select = 0; if (PD_SRC_PDO_TYPE(first_pdo) != PD_SRC_PDO_TYPE_FIXED) { usbpd_err(&pd->dev, "First src_cap invalid! %08x\n", first_pdo); return -EINVAL; } pd->peer_usb_comm = PD_SRC_PDO_FIXED_USB_COMM(first_pdo); pd->peer_pr_swap = PD_SRC_PDO_FIXED_PR_SWAP(first_pdo); pd->peer_dr_swap = PD_SRC_PDO_FIXED_DR_SWAP(first_pdo); val.intval = PD_SRC_PDO_FIXED_USB_SUSP(first_pdo); power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val); /* Check for PPS APDOs */ if (pd->spec_rev == USBPD_REV_30) { for (i = 1; i < PD_MAX_DATA_OBJ; i++) { if ((PD_SRC_PDO_TYPE(pd->received_pdos[i]) == PD_SRC_PDO_TYPE_AUGMENTED) && !PD_APDO_PPS(pd->received_pdos[i])) { pps_found = true; break; } } } val.intval = pps_found ? POWER_SUPPLY_PD_PPS_ACTIVE : POWER_SUPPLY_PD_ACTIVE; power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_ACTIVE, &val); /* First time connecting to a PD source and it supports USB data */ if (pd->peer_usb_comm && pd->current_dr == DR_UFP && !pd->pd_connected) start_usb_peripheral(pd); /* Select the first PDO (vSafe5V) immediately. */ pdo_select = select_match_pdo(pd,&mv_select,&ma_select); if (pdo_select == -1) { usbpd_dbg(&pd->dev, "%s, invaild pdo select\n",__func__); pd_select_pdo(pd, 1, 0, 0); } else { usbpd_dbg(&pd->dev, "%s, pdo_select = %d, mv= %dmV, ma = %dmA\n",__func__,pdo_select + 1,mv_select,ma_select); pd_select_pdo(pd, pdo_select + 1, mv_select * 1000, ma_select * 1000); } return 0; }代码分析
时间: 2023-09-12 17:08:15 浏览: 92
这段代码是一个函数,名为pd_eval_src_caps,接收一个usbpd结构体指针作为参数。这个函数的作用是评估PD源设备的能力,并设置相关的属性。函数中有许多变量和语句,我们逐一来看:
1. 变量i是一个整型变量,用于循环迭代。
2. 变量val是一个power_supply_propval类型的联合体,用于存储电源供应器的属性值。
3. 变量pps_found是一个布尔型变量,表示是否找到了PPS APDO。
4. 变量first_pdo是一个32位无符号整型变量,表示接收到的第一个PDO。
5. 变量pdo_select是一个整型变量,用于选择PDO。
6. 变量mv_select和ma_select是两个整型变量,用于存储所选PDO的电压和电流值。
7. 如果接收到的第一个PDO不是固定类型的,则函数返回错误。
8. 解析第一个PDO的一些属性,并将这些属性存储到usbpd结构体中。
9. 检查是否有PPS APDO,如果有,则设置PD的活动状态为PPS活动状态,否则为PD活动状态。
10. 如果PD支持USB数据,并且当前的数据角色是UFP,则启动USB外设。
11. 选择第一个PDO(vSafe5V),并设置该PDO的电压和电流值。
12. 函数返回0表示执行成功。
总之,这段代码是用于评估PD源设备的能力并设置相关属性的函数,其中包括了一些错误检查和选择PDO的逻辑。
相关问题
usbpd_info(&pd->dev, "Type-C Source (%s) connected\n", src_current(typec_mode)); /* if waiting for SinkTxOk to start an AMS */ if (pd->spec_rev == USBPD_REV_30 && typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH && (pd->send_pr_swap || pd->send_dr_swap || pd->vdm_tx)) break; if (pd->current_pr == PR_SINK) return 0; /* * Unexpected if not in PR swap; need to force disconnect from * source so we can turn off VBUS, Vconn, PD PHY etc. */ if (pd->current_pr == PR_SRC) { usbpd_info(&pd->dev, "Forcing disconnect from source mode\n"); pd->current_pr = PR_NONE; break; } pd->current_pr = PR_SINK; eval.intval = typec_mode > POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ? 1 : 0; extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_TYPEC_MED_HIGH_CURRENT, eval); break;代码分析
这段代码是在USB Type-C协议中进行电源角色协商时使用的。它的作用是在设备检测到Type-C源设备连接时,根据当前的协议状态进行相应的操作。
首先,代码使用usbpd_info函数输出Type-C源设备连接的消息。然后,它根据当前的协议状态进行判断。如果当前状态是USB-PD 3.0协议且Type-C模式是高电流源模式,并且等待SinkTxOk去开始一个AMS,则跳过该代码块。
如果当前状态是PR_SINK(电源角色是Sink),则直接返回。如果当前状态是PR_SRC(电源角色是Source),则输出日志信息,强制从源模式断开连接,并将当前状态设置为PR_NONE(无电源角色)。最后,将当前状态设置为PR_SINK,并根据Type-C模式设置EXTCON_USB的属性EXTCON_PROP_USB_TYPEC_MED_HIGH_CURRENT。
这段代码的目的是确保设备在进行电源角色协商时,能够正确地处理各种状态,并根据当前状态进行相应的操作。
阅读全文