@@ -446,3 +446,239 @@ int tcpci_tcpm_get_cc(const struct i2c_dt_spec *bus, enum tc_cc_voltage_state *c
446446
447447 return 0 ;
448448}
449+
450+ int tcpci_tcpm_get_chip_info (const struct i2c_dt_spec * bus , struct tcpc_chip_info * chip_info )
451+ {
452+ int ret ;
453+
454+ if (chip_info == NULL ) {
455+ return - EIO ;
456+ }
457+
458+ ret = tcpci_read_reg16 (bus , TCPC_REG_VENDOR_ID , & chip_info -> vendor_id );
459+ if (ret != 0 ) {
460+ return ret ;
461+ }
462+
463+ ret = tcpci_read_reg16 (bus , TCPC_REG_PRODUCT_ID , & chip_info -> product_id );
464+ if (ret != 0 ) {
465+ return ret ;
466+ }
467+
468+ return tcpci_read_reg16 (bus , TCPC_REG_BCD_DEV , & chip_info -> device_id );
469+ }
470+
471+ int tcpci_tcpm_dump_std_reg (const struct i2c_dt_spec * bus )
472+ {
473+ uint16_t value ;
474+
475+ for (unsigned int a = 0 ; a < ARRAY_SIZE (tcpci_std_regs ); a ++ ) {
476+ switch (tcpci_std_regs [a ].size ) {
477+ case 1 :
478+ tcpci_read_reg8 (bus , tcpci_std_regs [a ].addr , (uint8_t * )& value );
479+ LOG_INF ("- %-30s(0x%02x) = 0x%02x" , tcpci_std_regs [a ].name ,
480+ tcpci_std_regs [a ].addr , (uint8_t )value );
481+ break ;
482+ case 2 :
483+ tcpci_read_reg16 (bus , tcpci_std_regs [a ].addr , & value );
484+ LOG_INF ("- %-30s(0x%02x) = 0x%04x" , tcpci_std_regs [a ].name ,
485+ tcpci_std_regs [a ].addr , value );
486+ break ;
487+ }
488+ }
489+
490+ return 0 ;
491+ }
492+
493+ int tcpci_tcpm_set_bist_test_mode (const struct i2c_dt_spec * bus , bool enable )
494+ {
495+ return tcpci_update_reg8 (bus , TCPC_REG_TCPC_CTRL , TCPC_REG_TCPC_CTRL_BIST_TEST_MODE ,
496+ enable ? TCPC_REG_TCPC_CTRL_BIST_TEST_MODE : 0 );
497+ }
498+
499+ int tcpci_tcpm_transmit_data (const struct i2c_dt_spec * bus , struct pd_msg * msg ,
500+ const uint8_t retries )
501+ {
502+ int reg = TCPC_REG_TX_BUFFER ;
503+ int rv ;
504+ int cnt = 4 * msg -> header .number_of_data_objects ;
505+
506+ /* If not SOP* transmission, just write to the transmit register */
507+ if (msg -> header .message_type >= NUM_SOP_STAR_TYPES ) {
508+ /*
509+ * Per TCPCI spec, do not specify retry (although the TCPC
510+ * should ignore retry field for these 3 types).
511+ */
512+ return tcpci_write_reg8 (
513+ bus , TCPC_REG_TRANSMIT ,
514+ TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY (msg -> header .message_type ));
515+ }
516+
517+ if (cnt > 0 ) {
518+ reg = TCPC_REG_TX_BUFFER ;
519+ /* TX_BYTE_CNT includes extra bytes for message header */
520+ cnt += sizeof (msg -> header .raw_value );
521+
522+ struct i2c_msg buf [3 ];
523+
524+ uint8_t tmp [2 ] = {TCPC_REG_TX_BUFFER , cnt };
525+
526+ buf [0 ].buf = tmp ;
527+ buf [0 ].len = 2 ;
528+ buf [0 ].flags = I2C_MSG_WRITE ;
529+
530+ buf [1 ].buf = (uint8_t * )& msg -> header .raw_value ;
531+ buf [1 ].len = sizeof (msg -> header .raw_value );
532+ buf [1 ].flags = I2C_MSG_WRITE ;
533+
534+ buf [2 ].buf = (uint8_t * )msg -> data ;
535+ buf [2 ].len = msg -> len ;
536+ buf [2 ].flags = I2C_MSG_WRITE | I2C_MSG_STOP ;
537+
538+ if (cnt > sizeof (msg -> header .raw_value )) {
539+ rv = i2c_transfer (bus -> bus , buf , 3 , bus -> addr );
540+ } else {
541+ buf [1 ].flags |= I2C_MSG_STOP ;
542+ rv = i2c_transfer (bus -> bus , buf , 2 , bus -> addr );
543+ }
544+
545+ /* If tcpc write fails, return error */
546+ if (rv ) {
547+ return rv ;
548+ }
549+ }
550+
551+ /*
552+ * We always retry in TCPC hardware since the TCPM is too slow to
553+ * respond within tRetry (~195 usec).
554+ *
555+ * The retry count used is dependent on the maximum PD revision
556+ * supported at build time.
557+ */
558+ rv = tcpci_write_reg8 (bus , TCPC_REG_TRANSMIT ,
559+ TCPC_REG_TRANSMIT_SET_WITH_RETRY (retries , msg -> type ));
560+
561+ return rv ;
562+ }
563+
564+ int tcpci_tcpm_select_rp_value (const struct i2c_dt_spec * bus , enum tc_rp_value rp )
565+ {
566+ return tcpci_update_reg8 (bus , TCPC_REG_ROLE_CTRL , TCPC_REG_ROLE_CTRL_RP_MASK ,
567+ TCPC_REG_ROLE_CTRL_SET (0 , rp , 0 , 0 ));
568+ }
569+
570+ int tcpci_tcpm_get_rp_value (const struct i2c_dt_spec * bus , enum tc_rp_value * rp )
571+ {
572+ uint8_t reg_value = 0 ;
573+ int ret ;
574+
575+ ret = tcpci_read_reg8 (bus , TCPC_REG_ROLE_CTRL , & reg_value );
576+ * rp = TCPC_REG_ROLE_CTRL_RP (reg_value );
577+
578+ return ret ;
579+ }
580+
581+ int tcpci_tcpm_set_cc (const struct i2c_dt_spec * bus , enum tc_cc_pull pull )
582+ {
583+ return tcpci_update_reg8 (bus , TCPC_REG_ROLE_CTRL ,
584+ TCPC_REG_ROLE_CTRL_CC1_MASK | TCPC_REG_ROLE_CTRL_CC2_MASK ,
585+ TCPC_REG_ROLE_CTRL_SET (0 , 0 , pull , pull ));
586+ }
587+
588+ int tcpci_tcpm_set_vconn (const struct i2c_dt_spec * bus , bool enable )
589+ {
590+ return tcpci_update_reg8 (bus , TCPC_REG_POWER_CTRL , TCPC_REG_POWER_CTRL_VCONN_EN ,
591+ enable ? TCPC_REG_POWER_CTRL_VCONN_EN : 0 );
592+ }
593+
594+ int tcpci_tcpm_set_roles (const struct i2c_dt_spec * bus , enum pd_rev_type pd_rev ,
595+ enum tc_power_role power_role , enum tc_data_role data_role )
596+ {
597+ return tcpci_update_reg8 (bus , TCPC_REG_MSG_HDR_INFO , TCPC_REG_MSG_HDR_INFO_ROLES_MASK ,
598+ TCPC_REG_MSG_HDR_INFO_SET (pd_rev , data_role , power_role ));
599+ }
600+
601+ int tcpci_tcpm_set_drp_toggle (const struct i2c_dt_spec * bus , bool enable )
602+ {
603+ return tcpci_update_reg8 (bus , TCPC_REG_ROLE_CTRL , TCPC_REG_ROLE_CTRL_DRP_MASK ,
604+ TCPC_REG_ROLE_CTRL_SET (enable , 0 , 0 , 0 ));
605+ }
606+
607+ int tcpci_tcpm_set_rx_type (const struct i2c_dt_spec * bus , uint8_t rx_type )
608+ {
609+ return tcpci_write_reg8 (bus , TCPC_REG_RX_DETECT , rx_type );
610+ }
611+
612+ int tcpci_tcpm_set_cc_polarity (const struct i2c_dt_spec * bus , enum tc_cc_polarity polarity )
613+ {
614+ return tcpci_update_reg8 (
615+ bus , TCPC_REG_TCPC_CTRL , TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION ,
616+ (polarity == TC_POLARITY_CC1 ) ? 0 : TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION );
617+ }
618+
619+ int tcpci_tcpm_get_status_register (const struct i2c_dt_spec * bus , enum tcpc_status_reg reg ,
620+ uint16_t * status )
621+ {
622+ switch (reg ) {
623+ case TCPC_ALERT_STATUS :
624+ return tcpci_read_reg16 (bus , TCPC_REG_ALERT , status );
625+ case TCPC_CC_STATUS :
626+ return tcpci_read_reg16 (bus , TCPC_REG_CC_STATUS , status );
627+ case TCPC_POWER_STATUS :
628+ return tcpci_read_reg8 (bus , TCPC_REG_POWER_STATUS , (uint8_t * )status );
629+ case TCPC_FAULT_STATUS :
630+ return tcpci_read_reg8 (bus , TCPC_REG_FAULT_STATUS , (uint8_t * )status );
631+ case TCPC_EXTENDED_STATUS :
632+ return tcpci_read_reg8 (bus , TCPC_REG_EXT_STATUS , (uint8_t * )status );
633+ case TCPC_EXTENDED_ALERT_STATUS :
634+ return tcpci_read_reg8 (bus , TCPC_REG_ALERT_EXT , (uint8_t * )status );
635+ default :
636+ LOG_ERR ("Not a TCPCI-specified reg address" );
637+ return - EINVAL ;
638+ }
639+ }
640+
641+ int tcpci_tcpm_clear_status_register (const struct i2c_dt_spec * bus , enum tcpc_status_reg reg ,
642+ uint16_t mask )
643+ {
644+ switch (reg ) {
645+ case TCPC_ALERT_STATUS :
646+ return tcpci_write_reg16 (bus , TCPC_REG_ALERT , mask );
647+ case TCPC_CC_STATUS :
648+ return tcpci_write_reg16 (bus , TCPC_REG_CC_STATUS , mask );
649+ case TCPC_POWER_STATUS :
650+ return tcpci_write_reg8 (bus , TCPC_REG_POWER_STATUS , (uint8_t )mask );
651+ case TCPC_FAULT_STATUS :
652+ return tcpci_write_reg8 (bus , TCPC_REG_FAULT_STATUS , (uint8_t )mask );
653+ case TCPC_EXTENDED_STATUS :
654+ return tcpci_write_reg8 (bus , TCPC_REG_EXT_STATUS , (uint8_t )mask );
655+ case TCPC_EXTENDED_ALERT_STATUS :
656+ return tcpci_write_reg8 (bus , TCPC_REG_ALERT_EXT , (uint8_t )mask );
657+ default :
658+ LOG_ERR ("Not a TCPCI-specified reg address" );
659+ return - EINVAL ;
660+ }
661+ }
662+
663+ int tcpci_tcpm_mask_status_register (const struct i2c_dt_spec * bus , enum tcpc_status_reg reg ,
664+ uint16_t mask )
665+ {
666+ switch (reg ) {
667+ case TCPC_ALERT_STATUS :
668+ return tcpci_write_reg16 (bus , TCPC_REG_ALERT_MASK , mask );
669+ case TCPC_CC_STATUS :
670+ LOG_ERR ("CC_STATUS does not have a corresponding mask register" );
671+ return - EINVAL ;
672+ case TCPC_POWER_STATUS :
673+ return tcpci_write_reg8 (bus , TCPC_REG_POWER_STATUS_MASK , (uint8_t )mask );
674+ case TCPC_FAULT_STATUS :
675+ return tcpci_write_reg8 (bus , TCPC_REG_FAULT_STATUS_MASK , (uint8_t )mask );
676+ case TCPC_EXTENDED_STATUS :
677+ return tcpci_write_reg8 (bus , TCPC_REG_EXT_STATUS_MASK , (uint8_t )mask );
678+ case TCPC_EXTENDED_ALERT_STATUS :
679+ return tcpci_write_reg8 (bus , TCPC_REG_ALERT_EXT_MASK , (uint8_t )mask );
680+ default :
681+ LOG_ERR ("Not a TCPCI-specified reg address" );
682+ return - EINVAL ;
683+ }
684+ }
0 commit comments