@@ -90,7 +90,10 @@ static bool firmware_update;
9090static int pd_3a_flag ;
9191static int pd_3a_controller ;
9292static int pd_3a_port ;
93-
93+ static int pd_port0_1_5A ;
94+ static int pd_port1_1_5A ;
95+ static int pd_port2_1_5A ;
96+ static int pd_port3_1_5A ;
9497
9598void set_pd_fw_update (bool update )
9699{
@@ -971,8 +974,7 @@ void cyp5525_port_int(int controller, int port)
971974 pd_port_states [port_idx ].current = 0 ;
972975 pd_port_states [port_idx ].voltage = 0 ;
973976 pd_set_input_current_limit (port_idx , 0 , 0 );
974- cypd_port_3a_release (controller , port );
975- cypd_set_typec_profile (controller , port );
977+ cypd_release_port (controller , port );
976978 cypd_update_port_state (controller , port );
977979
978980 if (IS_ENABLED (CONFIG_CHARGE_MANAGER ))
@@ -986,7 +988,6 @@ void cyp5525_port_int(int controller, int port)
986988 break ;
987989 case CYPD_RESPONSE_PORT_CONNECT :
988990 CPRINTS ("CYPD_RESPONSE_PORT_CONNECT %d" , port_idx );
989- cypd_set_typec_profile (controller , port );
990991 cypd_update_port_state (controller , port );
991992 break ;
992993 case CYPD_RESPONSE_EXT_MSG_SOP_RX :
@@ -1302,6 +1303,7 @@ void cypd_interrupt_handler_task(void *p)
13021303 * need setting port current again
13031304 */
13041305 if (evt & CYPD_EVT_UCSI_PPM_RESET ) {
1306+ cypd_ppm_port_clear ();
13051307 cypd_port_current_setting ();
13061308 }
13071309
@@ -1433,23 +1435,120 @@ int cypd_port_3a_status(int controller, int port)
14331435 return false;
14341436}
14351437
1436- void cypd_port_3a_release (int controller , int port )
1438+ void cypd_port_3a_set (int controller , int port )
1439+ {
1440+ int port_idx = (controller << 1 ) + port ;
1441+
1442+ pd_3a_flag = 1 ;
1443+ pd_3a_controller = controller ;
1444+ pd_3a_port = port_idx ;
1445+ }
1446+
1447+ void cypd_port_1_5a_set (int controller , int port )
14371448{
1438- if (cypd_port_3a_status (controller , port )) {
1449+ int port_idx = (controller << 1 ) + port ;
1450+
1451+ switch (port_idx ) {
1452+ case 0 :
1453+ pd_port0_1_5A = 1 ;
1454+ break ;
1455+ case 1 :
1456+ pd_port1_1_5A = 1 ;
1457+ break ;
1458+ case 2 :
1459+ pd_port2_1_5A = 1 ;
1460+ break ;
1461+ case 3 :
1462+ pd_port3_1_5A = 1 ;
1463+ break ;
1464+ }
1465+ }
1466+
1467+ int cypd_port_force_3A (void ) {
1468+
1469+ int port_1_5A_idx ;
1470+
1471+ port_1_5A_idx = pd_port0_1_5A + pd_port1_1_5A + pd_port2_1_5A + pd_port3_1_5A ;
1472+
1473+ if (port_1_5A_idx > 3 )
1474+ return true;
1475+ else
1476+ return false;
1477+ }
1478+
1479+ void cypd_profile_setting (int controller , int port , int profile )
1480+ {
1481+ cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), profile );
1482+ cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), profile );
1483+ }
1484+
1485+ void cypd_ppm_port_clear (void )
1486+ {
1487+ pd_port0_1_5A = 0 ;
1488+ pd_port1_1_5A = 0 ;
1489+ pd_port2_1_5A = 0 ;
1490+ pd_port3_1_5A = 0 ;
1491+ }
1492+
1493+ void cypd_release_port (int controller , int port )
1494+ {
1495+ int port_idx = (controller << 1 ) + port ;
1496+
1497+ /* if port disconnect should set RP and PDO to default */
1498+ cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1499+ cypd_write_reg8 (controller , CYP5525_SELECT_SOURCE_PDO_REG (port ), CYPD_PD_CMD_SET_TYPEC_3A );
1500+
1501+ if (cypd_port_3a_status (controller , port ))
14391502 pd_3a_flag = 0 ;
1440- CPRINTS ("CYPD release 3A" );
1503+
1504+ switch (port_idx ) {
1505+ case 0 :
1506+ pd_port0_1_5A = 0 ;
1507+ break ;
1508+ case 1 :
1509+ pd_port1_1_5A = 0 ;
1510+ break ;
1511+ case 2 :
1512+ pd_port2_1_5A = 0 ;
1513+ break ;
1514+ case 3 :
1515+ pd_port3_1_5A = 0 ;
1516+ break ;
14411517 }
14421518}
14431519
1444- void cypd_set_port_3a (int controller , int port )
1520+ int cypd_profile_wait_check (int controller , int port )
14451521{
14461522 int port_idx = (controller << 1 ) + port ;
14471523
1448- pd_3a_flag = 1 ;
1449- pd_3a_controller = controller ;
1450- pd_3a_port = port_idx ;
1524+ /*
1525+ * according PD vendor suggest after PD NEGOTIATION COMPLETE
1526+ * need to wait 280ms before send Profile
1527+ */
1528+ task_wait_event_mask (TASK_EVENT_TIMER , 280 * MSEC );
1529+
1530+ switch (port_idx ) {
1531+ case 0 :
1532+ if (pd_port0_1_5A )
1533+ return true;
1534+ break ;
1535+ case 1 :
1536+ if (pd_port1_1_5A )
1537+ return true;
1538+ break ;
1539+ case 2 :
1540+ if (pd_port2_1_5A )
1541+ return true;
1542+ break ;
1543+ case 3 :
1544+ if (pd_port3_1_5A )
1545+ return true;
1546+ break ;
1547+ }
1548+ return false;
14511549}
14521550
1551+
14531552void cypd_set_typec_profile (int controller , int port )
14541553{
14551554 int rv ;
@@ -1463,24 +1562,15 @@ void cypd_set_typec_profile(int controller, int port)
14631562 rv = cypd_read_reg8 (controller , CYP5525_TYPE_C_STATUS_REG (port ), & typec_status_reg );
14641563 if (rv != EC_SUCCESS )
14651564 CPRINTS ("CYP5525_TYPE_C_STATUS_REG failed" );
1466- pd_port_states [port_idx ].c_state = (typec_status_reg >> 2 ) & 0x7 ;
14671565
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- }
1566+ pd_port_states [port_idx ].c_state = (typec_status_reg >> 2 ) & 0x7 ;
14731567
14741568 rv = cypd_read_reg_block (controller , CYP5525_PD_STATUS_REG (port ), pd_status_reg , 4 );
14751569 if (rv != EC_SUCCESS )
14761570 CPRINTS ("CYP5525_PD_STATUS_REG failed" );
1571+
14771572 pd_port_states [port_idx ].pd_state = pd_status_reg [1 ] & BIT (2 ) ? 1 : 0 ; /*do we have a valid PD contract*/
14781573 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 ;
14841574
14851575 if (pd_port_states [port_idx ].power_role == PD_ROLE_SOURCE ) {
14861576 if (pd_port_states [port_idx ].pd_state ) {
@@ -1489,31 +1579,27 @@ void cypd_set_typec_profile(int controller, int port)
14891579 * when device request RDO <= 1.5A
14901580 * resend 1.5A pdo to device
14911581 */
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-
14971582 cypd_read_reg_block (controller , CYP5525_CURRENT_RDO_REG (port ), rdo_reg , 4 );
14981583 rdo_max_current = (((rdo_reg [1 ]>>2 ) + (rdo_reg [2 ]<<6 )) & 0x3FF )* 10 ;
14991584
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 );
1503- } 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 );
1585+ if (cypd_port_force_3A () && !pd_3a_flag ) {
1586+ cypd_port_3a_set (controller , port );
1587+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_3A );
1588+ } else if (rdo_max_current <= 1500 ) {
1589+ if (cypd_profile_wait_check (controller , port ))
1590+ return ;
1591+ cypd_port_1_5a_set (controller , port );
1592+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_1_5A );
1593+ } else if (cypd_port_3a_status (controller , port ) || !pd_3a_flag ) {
1594+ cypd_port_3a_set (controller , port );
1595+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_3A );
15101596 } 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 );
1597+ cypd_profile_wait_check (controller , port );
1598+ cypd_port_1_5a_set (controller , port );
1599+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_1_5A );
15131600 }
1514- } else {
1515- cypd_write_reg8 (controller , CYP5525_PD_CONTROL_REG (port ), CYPD_PD_CMD_SET_TYPEC_1_5A );
1516- }
1601+ } else
1602+ cypd_profile_setting (controller , port , CYPD_PD_CMD_SET_TYPEC_1_5A );
15171603 }
15181604}
15191605
0 commit comments