@@ -88,9 +88,13 @@ struct extended_msg tx_emsg[CONFIG_USB_PD_PORT_MAX_COUNT];
8888bool verbose_msg_logging ;
8989static bool firmware_update ;
9090static int pd_3a_flag ;
91+ static int pd_3a_set ;
9192static int pd_3a_controller ;
9293static int pd_3a_port ;
93-
94+ static int pd_port0_1_5A ;
95+ static int pd_port1_1_5A ;
96+ static int pd_port2_1_5A ;
97+ static int pd_port3_1_5A ;
9498
9599void set_pd_fw_update (bool update )
96100{
@@ -971,16 +975,14 @@ void cyp5525_port_int(int controller, int port)
971975 pd_port_states [port_idx ].current = 0 ;
972976 pd_port_states [port_idx ].voltage = 0 ;
973977 pd_set_input_current_limit (port_idx , 0 , 0 );
974- cypd_port_3a_release (controller , port );
975- cypd_set_typec_profile (controller , port );
978+ cypd_release_port (controller , port );
976979 cypd_update_port_state (controller , port );
977980
978981 if (IS_ENABLED (CONFIG_CHARGE_MANAGER ))
979982 charge_manager_update_dualrole (port_idx , CAP_UNKNOWN );
980983 break ;
981984 case CYPD_RESPONSE_PD_CONTRACT_NEGOTIATION_COMPLETE :
982985 CPRINTS ("CYPD_RESPONSE_PD_CONTRACT_NEGOTIATION_COMPLETE %d" , port_idx );
983- /*todo we can probably clean this up to remove some of this*/
984986 cypd_set_typec_profile (controller , port );
985987 cypd_update_port_state (controller , port );
986988 break ;
@@ -1302,6 +1304,7 @@ void cypd_interrupt_handler_task(void *p)
13021304 * need setting port current again
13031305 */
13041306 if (evt & CYPD_EVT_UCSI_PPM_RESET ) {
1307+ cypd_ppm_port_clear ();
13051308 cypd_port_current_setting ();
13061309 }
13071310
@@ -1405,13 +1408,15 @@ void cypd_aconly_reconnect(void)
14051408 cypd_enque_evt (CYPD_EVT_PORT_DISABLE , 0 );
14061409}
14071410
1408- void cypd_usci_ppm_reset (void )
1411+ static void cypd_ucsi_wait_delay_deferred (void )
14091412{
1410- int events ;
1413+ cypd_enque_evt (CYPD_EVT_UCSI_PPM_RESET , 0 );
1414+ }
1415+ DECLARE_DEFERRED (cypd_ucsi_wait_delay_deferred );
14111416
1412- events = task_wait_event_mask ( TASK_EVENT_TIMER , 50 * MSEC );
1413- if ( events & TASK_EVENT_TIMER )
1414- cypd_enque_evt ( CYPD_EVT_UCSI_PPM_RESET , 0 );
1417+ void cypd_usci_ppm_reset ( void )
1418+ {
1419+ hook_call_deferred ( & cypd_ucsi_wait_delay_deferred_data , 1 );
14151420}
14161421
14171422void cypd_port_current_setting (void )
@@ -1433,54 +1438,162 @@ int cypd_port_3a_status(int controller, int port)
14331438 return false;
14341439}
14351440
1436- void cypd_port_3a_release (int controller , int port )
1441+ int cypd_port_3a_set (int controller , int port )
14371442{
1443+ int port_idx = (controller << 1 ) + port ;
1444+
1445+ if (pd_3a_set )
1446+ return false;
1447+
1448+ pd_3a_set = 1 ;
1449+ pd_3a_flag = 1 ;
1450+ pd_3a_controller = controller ;
1451+ pd_3a_port = port_idx ;
1452+
1453+ return true;
1454+ }
1455+
1456+ void cypd_port_1_5a_set (int controller , int port )
1457+ {
1458+ int port_idx = (controller << 1 ) + port ;
1459+
1460+ switch (port_idx ) {
1461+ case 0 :
1462+ pd_port0_1_5A = 1 ;
1463+ break ;
1464+ case 1 :
1465+ pd_port1_1_5A = 1 ;
1466+ break ;
1467+ case 2 :
1468+ pd_port2_1_5A = 1 ;
1469+ break ;
1470+ case 3 :
1471+ pd_port3_1_5A = 1 ;
1472+ break ;
1473+ }
1474+ }
1475+
1476+ int cypd_port_force_3A (int controller , int port )
1477+ {
1478+ int port_idx = (controller << 1 ) + port ;
1479+ int port_1_5A_idx ;
1480+
1481+ port_1_5A_idx = pd_port0_1_5A + pd_port1_1_5A + pd_port2_1_5A + pd_port3_1_5A ;
1482+
1483+ if (port_1_5A_idx >= 3 ) {
1484+ switch (port_idx ) {
1485+ case 0 :
1486+ if (!pd_port0_1_5A )
1487+ return true;
1488+ break ;
1489+ case 1 :
1490+ if (!pd_port1_1_5A )
1491+ return true;
1492+ break ;
1493+ case 2 :
1494+ if (!pd_port2_1_5A )
1495+ return true;
1496+ break ;
1497+ case 3 :
1498+ if (!pd_port3_1_5A )
1499+ return true;
1500+ break ;
1501+ }
1502+ }
1503+ return false;
1504+ }
1505+
1506+ void cypd_profile_setting (int controller , int port , int profile )
1507+ {
1508+ cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), profile );
1509+ cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), profile );
1510+ }
1511+
1512+ void cypd_ppm_port_clear (void )
1513+ {
1514+ pd_port0_1_5A = 0 ;
1515+ pd_port1_1_5A = 0 ;
1516+ pd_port2_1_5A = 0 ;
1517+ pd_port3_1_5A = 0 ;
1518+ pd_3a_set = 0 ;
1519+ }
1520+
1521+ void cypd_release_port (int controller , int port )
1522+ {
1523+ int port_idx = (controller << 1 ) + port ;
1524+
1525+ /* if port disconnect should set RP and PDO to default */
1526+ cypd_write_reg8_wait_ack (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1527+ cypd_write_reg8_wait_ack (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1528+
14381529 if (cypd_port_3a_status (controller , port )) {
1530+ pd_3a_set = 0 ;
14391531 pd_3a_flag = 0 ;
1440- CPRINTS ("CYPD release 3A" );
1532+ }
1533+
1534+ switch (port_idx ) {
1535+ case 0 :
1536+ pd_port0_1_5A = 0 ;
1537+ break ;
1538+ case 1 :
1539+ pd_port1_1_5A = 0 ;
1540+ break ;
1541+ case 2 :
1542+ pd_port2_1_5A = 0 ;
1543+ break ;
1544+ case 3 :
1545+ pd_port3_1_5A = 0 ;
1546+ break ;
14411547 }
14421548}
14431549
1444- void cypd_set_port_3a (int controller , int port )
1550+ int cypd_profile_wait_check (int controller , int port )
14451551{
14461552 int port_idx = (controller << 1 ) + port ;
14471553
1448- pd_3a_flag = 1 ;
1449- pd_3a_controller = controller ;
1450- pd_3a_port = port_idx ;
1554+ /*
1555+ * according PD vendor suggest after PD NEGOTIATION COMPLETE
1556+ * need to wait 420ms before send Profile
1557+ */
1558+ switch (port_idx ) {
1559+ case 0 :
1560+ if (pd_port0_1_5A )
1561+ return true;
1562+ break ;
1563+ case 1 :
1564+ if (pd_port1_1_5A )
1565+ return true;
1566+ break ;
1567+ case 2 :
1568+ if (pd_port2_1_5A )
1569+ return true;
1570+ break ;
1571+ case 3 :
1572+ if (pd_port3_1_5A )
1573+ return true;
1574+ break ;
1575+ }
1576+
1577+ task_wait_event_mask (TASK_EVENT_TIMER , 420 * MSEC );
1578+ return false;
14511579}
14521580
1581+
14531582void cypd_set_typec_profile (int controller , int port )
14541583{
14551584 int rv ;
14561585 uint8_t pd_status_reg [4 ];
14571586 uint8_t rdo_reg [4 ];
14581587
1459- int typec_status_reg ;
14601588 int rdo_max_current = 0 ;
14611589 int port_idx = (controller << 1 ) + port ;
14621590
1463- rv = cypd_read_reg8 (controller , CYP5525_TYPE_C_STATUS_REG (port ), & typec_status_reg );
1464- if (rv != EC_SUCCESS )
1465- CPRINTS ("CYP5525_TYPE_C_STATUS_REG failed" );
1466- pd_port_states [port_idx ].c_state = (typec_status_reg >> 2 ) & 0x7 ;
1467-
1468- /* if port no device connect set type c current to 1.5A */
1469- if (pd_port_states [port_idx ].c_state == CYPD_STATUS_NOTHING ) {
1470- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1471- return ;
1472- }
1473-
14741591 rv = cypd_read_reg_block (controller , CYP5525_PD_STATUS_REG (port ), pd_status_reg , 4 );
14751592 if (rv != EC_SUCCESS )
14761593 CPRINTS ("CYP5525_PD_STATUS_REG failed" );
1594+
14771595 pd_port_states [port_idx ].pd_state = pd_status_reg [1 ] & BIT (2 ) ? 1 : 0 ; /*do we have a valid PD contract*/
14781596 pd_port_states [port_idx ].power_role = pd_status_reg [1 ] & BIT (0 ) ? PD_ROLE_SOURCE : PD_ROLE_SINK ;
1479- pd_port_states [port_idx ].data_role = pd_status_reg [0 ] & BIT (6 ) ? PD_ROLE_DFP : PD_ROLE_UFP ;
1480- pd_port_states [port_idx ].vconn = pd_status_reg [1 ] & BIT (5 ) ? PD_ROLE_VCONN_SRC : PD_ROLE_VCONN_OFF ;
1481-
1482- if (pd_port_states [port_idx ].power_role == PD_ROLE_SINK )
1483- return ;
14841597
14851598 if (pd_port_states [port_idx ].power_role == PD_ROLE_SOURCE ) {
14861599 if (pd_port_states [port_idx ].pd_state ) {
@@ -1489,31 +1602,31 @@ void cypd_set_typec_profile(int controller, int port)
14891602 * when device request RDO <= 1.5A
14901603 * resend 1.5A pdo to device
14911604 */
1492- if (cypd_port_3a_status (controller , port ) || !pd_3a_flag )
1493- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1494- else
1495- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1496-
14971605 cypd_read_reg_block (controller , CYP5525_CURRENT_RDO_REG (port ), rdo_reg , 4 );
14981606 rdo_max_current = (((rdo_reg [1 ]>>2 ) + (rdo_reg [2 ]<<6 )) & 0x3FF )* 10 ;
14991607
1500- if (rdo_max_current <= 1500 ) {
1501- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1502- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1608+ if ((cypd_port_force_3A (controller , port ) && !pd_3a_flag ) ||
1609+ cypd_port_3a_status (controller , port )) {
1610+ if (!cypd_port_3a_set (controller , port ))
1611+ return ;
1612+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_3A );
1613+ } else if (rdo_max_current <= 1500 ) {
1614+ if (cypd_profile_wait_check (controller , port ))
1615+ return ;
1616+ cypd_port_1_5a_set (controller , port );
1617+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_1_5A );
15031618 } else if (!pd_3a_flag ) {
1504- cypd_set_port_3a (controller , port );
1505- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1506- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1507- } else if (cypd_port_3a_status (controller , port )) {
1508- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1509- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1619+ if (!cypd_port_3a_set (controller , port ))
1620+ return ;
1621+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_3A );
15101622 } else {
1511- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1512- cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1623+ if (cypd_profile_wait_check (controller , port ))
1624+ return ;
1625+ cypd_port_1_5a_set (controller , port );
1626+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_1_5A );
15131627 }
1514- } else {
1628+ } else
15151629 cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1516- }
15171630 }
15181631}
15191632
0 commit comments