| /* |
| * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd |
| * Author: Zain Wang <zain.wang@rock-chips.com> |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms and conditions of the GNU General Public License, |
| * version 2, as published by the Free Software Foundation. |
| * |
| * Some ideas are from chrome ec and fairchild GPL fusb302 driver. |
| */ |
| |
| #ifndef FUSB302_H |
| #define FUSB302_H |
| |
| #include <fdtdec.h> |
| |
| #define FUSB_VCONN_SUPPORT |
| /* TODO: more modes would be added here later on */ |
| #define FUSB_HAVE_DRP |
| |
| #define FUSB_DT_GPIO_INTN "fairchild,int_n" |
| #define FUSB_DT_GPIO_VBUS_5V "fairchild,vbus5v" |
| #define FUSB_DT_GPIO_VBUS_OTHER "fairchild,vbusOther" |
| |
| #define FUSB30X_I2C_DRIVER_NAME "fusb302" |
| #define FUSB30X_I2C_DEVICETREE_NAME "fairchild,fusb302" |
| |
| /* FUSB300 Register Addresses */ |
| #define FUSB_REG_DEVICEID 0x01 |
| #define FUSB_REG_SWITCHES0 0x02 |
| #define FUSB_REG_SWITCHES1 0x03 |
| #define FUSB_REG_MEASURE 0x04 |
| #define FUSB_REG_SLICE 0x05 |
| #define FUSB_REG_CONTROL0 0x06 |
| #define FUSB_REG_CONTROL1 0x07 |
| #define FUSB_REG_CONTROL2 0x08 |
| #define FUSB_REG_CONTROL3 0x09 |
| #define FUSB_REG_MASK 0x0A |
| #define FUSB_REG_POWER 0x0B |
| #define FUSB_REG_RESET 0x0C |
| #define FUSB_REG_OCPREG 0x0D |
| #define FUSB_REG_MASKA 0x0E |
| #define FUSB_REG_MASKB 0x0F |
| #define FUSB_REG_CONTROL4 0x10 |
| #define FUSB_REG_STATUS0A 0x3C |
| #define FUSB_REG_STATUS1A 0x3D |
| #define FUSB_REG_INTERRUPTA 0x3E |
| #define FUSB_REG_INTERRUPTB 0x3F |
| #define FUSB_REG_STATUS0 0x40 |
| #define FUSB_REG_STATUS1 0x41 |
| #define FUSB_REG_INTERRUPT 0x42 |
| #define FUSB_REG_FIFO 0x43 |
| |
| enum connection_state { |
| disabled = 0, |
| error_recovery, |
| unattached, |
| attach_wait_sink, |
| attach_wait_source, |
| attached_source, |
| attached_sink, |
| |
| policy_src_startup, |
| policy_src_send_caps, |
| policy_src_discovery, |
| policy_src_negotiate_cap, |
| policy_src_cap_response, |
| policy_src_transition_supply, |
| policy_src_transition_default, |
| |
| policy_src_ready, |
| policy_src_get_sink_caps, |
| |
| policy_src_send_softrst, |
| policy_src_send_hardrst, |
| |
| policy_snk_startup, |
| policy_snk_discovery, |
| policy_snk_wait_caps, |
| policy_snk_evaluate_caps, |
| policy_snk_select_cap, |
| policy_snk_transition_sink, |
| policy_snk_ready, |
| |
| policy_snk_send_softrst, |
| policy_snk_send_hardrst, |
| |
| policy_snk_transition_default, |
| }; |
| |
| enum tcpm_rp_value { |
| TYPEC_RP_USB = 0, |
| TYPEC_RP_1A5 = 1, |
| TYPEC_RP_3A0 = 2, |
| TYPEC_RP_RESERVED = 3, |
| }; |
| |
| #define SBF(s, v) ((s) << (v)) |
| #define SWITCHES0_PDWN1 SBF(1, 0) |
| #define SWITCHES0_PDWN2 SBF(1, 1) |
| #define SWITCHES0_MEAS_CC1 SBF(1, 2) |
| #define SWITCHES0_MEAS_CC2 SBF(1, 3) |
| #define SWITCHES0_VCONN_CC1 SBF(1, 4) |
| #define SWITCHES0_VCONN_CC2 SBF(1, 5) |
| #define SWITCHES0_PU_EN1 SBF(1, 6) |
| #define SWITCHES0_PU_EN2 SBF(1, 7) |
| |
| #define SWITCHES1_TXCC1 SBF(1, 0) |
| #define SWITCHES1_TXCC2 SBF(1, 1) |
| #define SWITCHES1_AUTO_CRC SBF(1, 2) |
| #define SWITCHES1_DATAROLE SBF(1, 4) |
| #define SWITCHES1_SPECREV SBF(3, 5) |
| #define SWITCHES1_POWERROLE SBF(1, 7) |
| |
| #define MEASURE_MDAC SBF(0x3f, 0) |
| #define MEASURE_VBUS SBF(1, 6) |
| |
| #define SLICE_SDAC SBF(0x3f, 0) |
| #define SLICE_SDAC_HYS SBF(3, 6) |
| |
| #define CONTROL0_TX_START SBF(1, 0) |
| #define CONTROL0_AUTO_PRE SBF(1, 1) |
| #define CONTROL0_HOST_CUR SBF(3, 2) |
| #define CONTROL0_HOST_CUR_USB SBF(1, 2) |
| #define CONTROL0_HOST_CUR_1A5 SBF(2, 2) |
| #define CONTROL0_HOST_CUR_3A0 SBF(3, 2) |
| #define CONTROL0_INT_MASK SBF(1, 5) |
| #define CONTROL0_TX_FLUSH SBF(1, 6) |
| |
| #define CONTROL1_ENSOP1 SBF(1, 0) |
| #define CONTROL1_ENSOP2 SBF(1, 1) |
| #define CONTROL1_RX_FLUSH SBF(1, 2) |
| #define CONTROL1_BIST_MODE2 SBF(1, 4) |
| #define CONTROL1_ENSOP1DB SBF(1, 5) |
| #define CONTROL1_ENSOP2DB SBF(1, 6) |
| |
| #define CONTROL2_TOGGLE SBF(1, 0) |
| #define CONTROL2_MODE SBF(3, 1) |
| #define CONTROL2_WAKE_EN SBF(1, 3) |
| #define CONTROL2_TOG_RD_ONLY SBF(1, 5) |
| #define CONTROL2_TOG_SAVE_PWR1 SBF(1, 6) |
| #define CONTROL2_TOG_SAVE_PWR2 SBF(1, 7) |
| |
| #define CONTROL3_AUTO_RETRY SBF(1, 0) |
| #define CONTROL3_N_RETRIES SBF(3, 1) |
| #define CONTROL3_AUTO_SOFTRESET SBF(1, 3) |
| #define CONTROL3_AUTO_HARDRESET SBF(1, 4) |
| #define CONTROL3_SEND_HARDRESET SBF(1, 6) |
| |
| #define MASK_M_BC_LVL SBF(1, 0) |
| #define MASK_M_COLLISION SBF(1, 1) |
| #define MASK_M_WAKE SBF(1, 2) |
| #define MASK_M_ALERT SBF(1, 3) |
| #define MASK_M_CRC_CHK SBF(1, 4) |
| #define MASK_M_COMP_CHNG SBF(1, 5) |
| #define MASK_M_ACTIVITY SBF(1, 6) |
| #define MASK_M_VBUSOK SBF(1, 7) |
| |
| #define POWER_PWR SBF(0xf, 0) |
| |
| #define RESET_SW_RESET SBF(1, 0) |
| #define RESET_PD_RESET SBF(1, 1) |
| |
| #define MASKA_M_HARDRST SBF(1, 0) |
| #define MASKA_M_SOFTRST SBF(1, 1) |
| #define MASKA_M_TXSENT SBF(1, 2) |
| #define MASKA_M_HARDSENT SBF(1, 3) |
| #define MASKA_M_RETRYFAIL SBF(1, 4) |
| #define MASKA_M_SOFTFAIL SBF(1, 5) |
| #define MASKA_M_TOGDONE SBF(1, 6) |
| #define MASKA_M_OCP_TEMP SBF(1, 7) |
| |
| #define MASKB_M_GCRCSEND SBF(1, 0) |
| |
| #define CONTROL4_TOG_USRC_EXIT SBF(1, 0) |
| |
| #define MDAC_1P6V 0x26 |
| |
| #define STATUS0A_HARDRST SBF(1, 0) |
| #define STATUS0A_SOFTRST SBF(1, 1) |
| #define STATUS0A_POWER23 SBF(3, 2) |
| #define STATUS0A_RETRYFAIL SBF(1, 4) |
| #define STATUS0A_SOFTFAIL SBF(1, 5) |
| #define STATUS0A_TOGDONE SBF(1, 6) |
| #define STATUS0A_M_OCP_TEMP SBF(1, 7) |
| |
| #define STATUS1A_RXSOP SBF(1, 0) |
| #define STATUS1A_RXSOP1DB SBF(1, 1) |
| #define STATUS1A_RXSOP2DB SBF(1, 2) |
| #define STATUS1A_TOGSS SBF(7, 3) |
| |
| #define INTERRUPTA_HARDRST SBF(1, 0) |
| #define INTERRUPTA_SOFTRST SBF(1, 1) |
| #define INTERRUPTA_TXSENT SBF(1, 2) |
| #define INTERRUPTA_HARDSENT SBF(1, 3) |
| #define INTERRUPTA_RETRYFAIL SBF(1, 4) |
| #define INTERRUPTA_SOFTFAIL SBF(1, 5) |
| #define INTERRUPTA_TOGDONE SBF(1, 6) |
| #define INTERRUPTA_OCP_TEMP SBF(1, 7) |
| |
| #define INTERRUPTB_GCRCSENT SBF(1, 0) |
| |
| #define STATUS0_BC_LVL SBF(3, 0) |
| #define STATUS0_WAKE SBF(1, 2) |
| #define STATUS0_ALERT SBF(1, 3) |
| #define STATUS0_CRC_CHK SBF(1, 4) |
| #define STATUS0_COMP SBF(1, 5) |
| #define STATUS0_ACTIVITY SBF(1, 6) |
| #define STATUS0_VBUSOK SBF(1, 7) |
| |
| #define STATUS1_OCP SBF(1, 0) |
| #define STATUS1_OVRTEMP SBF(1, 1) |
| #define STATUS1_TX_FULL SBF(1, 2) |
| #define STATUS1_TX_EMPTY SBF(1, 3) |
| #define STATUS1_RX_FULL SBF(1, 4) |
| #define STATUS1_RX_EMPTY SBF(1, 5) |
| #define STATUS1_RXSOP1 SBF(1, 6) |
| #define STATUS1_RXSOP2 SBF(1, 7) |
| |
| #define INTERRUPT_BC_LVL SBF(1, 0) |
| #define INTERRUPT_COLLISION SBF(1, 1) |
| #define INTERRUPT_WAKE SBF(1, 2) |
| #define INTERRUPT_ALERT SBF(1, 3) |
| #define INTERRUPT_CRC_CHK SBF(1, 4) |
| #define INTERRUPT_COMP_CHNG SBF(1, 5) |
| #define INTERRUPT_ACTIVITY SBF(1, 6) |
| #define INTERRUPT_VBUSOK SBF(1, 7) |
| |
| #define FUSB_TKN_TXON 0xa1 |
| #define FUSB_TKN_SYNC1 0x12 |
| #define FUSB_TKN_SYNC2 0x13 |
| #define FUSB_TKN_SYNC3 0x1b |
| #define FUSB_TKN_RST1 0x15 |
| #define FUSB_TKN_RST2 0x16 |
| #define FUSB_TKN_PACKSYM 0x80 |
| #define FUSB_TKN_JAMCRC 0xff |
| #define FUSB_TKN_EOP 0x14 |
| #define FUSB_TKN_TXOFF 0xfe |
| |
| /* USB PD Control Message Types */ |
| #define CONTROLMESSAGE 0 |
| #define CMT_GOODCRC 1 |
| #define CMT_GOTOMIN 2 |
| #define CMT_ACCEPT 3 |
| #define CMT_REJECT 4 |
| #define CMT_PING 5 |
| #define CMT_PS_RDY 6 |
| #define CMT_GETSOURCECAP 7 |
| #define CMT_GETSINKCAP 8 |
| #define CMT_DR_SWAP 9 |
| #define CMT_PR_SWAP 10 |
| #define CMT_VCONN_SWAP 11 |
| #define CMT_WAIT 12 |
| #define CMT_SOFTRESET 13 |
| |
| /* USB PD Data Message Types */ |
| #define DATAMESSAGE 1 |
| #define DMT_SOURCECAPABILITIES 1 |
| #define DMT_REQUEST 2 |
| #define DMT_BIST 3 |
| #define DMT_SINKCAPABILITIES 4 |
| #define DMT_VENDERDEFINED 15 |
| |
| /* VDM Command Types */ |
| #define VDM_DISCOVERY_ID 0X01 |
| #define VDM_DISCOVERY_SVIDS 0X02 |
| #define VDM_DISCOVERY_MODES 0X03 |
| #define VDM_ENTER_MODE 0X04 |
| #define VDM_EXIT_MODE 0X05 |
| #define VDM_ATTENTION 0X06 |
| #define VDM_DP_STATUS_UPDATE 0X10 |
| #define VDM_DP_CONFIG 0X11 |
| |
| #define VDM_TYPE_INIT 0 |
| #define VDM_TYPE_ACK 1 |
| #define VDM_TYPE_NACK 2 |
| #define VDM_TYPE_BUSY 3 |
| |
| #define N_DEBOUNCE_CNT (10 - 1) |
| #define N_CAPS_COUNT 100 |
| #define N_HARDRESET_COUNT 0 |
| |
| #define T_NO_RESPONSE 5000 |
| #define T_SRC_RECOVER 830 |
| #define T_TYPEC_SEND_SOURCECAP 3 |
| #define T_SENDER_RESPONSE 30 |
| #define T_SRC_TRANSITION 30 |
| #define T_TYPEC_SINK_WAIT_CAP 500 |
| #define T_PS_TRANSITION 500 |
| #define T_BMC_TIMEOUT 5 |
| #define T_PS_HARD_RESET_MAX 35 |
| #define T_SAFE_0V 650 |
| #define T_SRC_TURN_ON 275 |
| #define T_SRC_RECOVER_MAX 1000 |
| |
| #define T_NO_TRIGGER 500 |
| #define T_DISABLED 0xffff |
| |
| #define PD_HEADER_CNT(header) (((header) >> 12) & 7) |
| #define PD_HEADER_TYPE(header) ((header) & 0xF) |
| #define PD_HEADER_ID(header) (((header) >> 9) & 7) |
| |
| #define VDM_HEADER_TYPE(header) (((header) >> 6) & 3) |
| #define VDMHEAD_CMD_TYPE_MASK (3 << 6) |
| #define VDMHEAD_CMD_MASK (0x1f << 0) |
| #define VDMHEAD_STRUCT_TYPE_MASK BIT(15) |
| |
| #define GET_VDMHEAD_CMD_TYPE(head) ((head & VDMHEAD_CMD_TYPE_MASK) >> 6) |
| #define GET_VDMHEAD_CMD(head) (head & VDMHEAD_CMD_MASK) |
| #define GET_VDMHEAD_STRUCT_TYPE(head) ((head & VDMHEAD_STRUCT_TYPE_MASK) >> 15) |
| |
| #define VDM_IDHEAD_USBVID_MASK (0xffff << 0) |
| #define VDM_IDHEAD_MODALSUPPORT_MASK BIT(26) |
| #define VDM_IDHEAD_PRODUCTTYPE (7 << 27) |
| #define VDM_IDHEAD_USBDEVICE BIT(30) |
| #define VDM_IDHEAD_USBHOST BIT(30) |
| |
| #define CAP_POWER_TYPE(PDO) ((PDO >> 30) & 3) |
| #define CAP_FPDO_VOLTAGE(PDO) ((PDO >> 10) & 0x3ff) |
| #define CAP_VPDO_VOLTAGE(PDO) ((PDO >> 20) & 0x3ff) |
| #define CAP_FPDO_CURRENT(PDO) ((PDO >> 0) & 0x3ff) |
| #define CAP_VPDO_CURRENT(PDO) ((PDO >> 0) & 0x3ff) |
| |
| enum CC_ORIENTATION { |
| NONE, |
| CC1, |
| CC2, |
| }; |
| |
| struct notify_info { |
| enum CC_ORIENTATION orientation; |
| /* 0 UFP : 1 DFP */ |
| bool power_role; |
| bool data_role; |
| |
| bool is_cc_connected; |
| bool is_pd_connected; |
| |
| bool is_enter_mode; |
| int pin_assignment_support; |
| int pin_assignment_def; |
| bool attention; |
| }; |
| |
| enum tx_state { |
| tx_idle, |
| tx_busy, |
| tx_failed, |
| tx_success |
| }; |
| |
| struct PD_CAP_INFO { |
| u32 peak_current; |
| u32 specification_revision; |
| u32 externally_powered; |
| u32 usb_suspend_support; |
| u32 usb_communications_cap; |
| u32 dual_role_power; |
| u32 data_role_swap; |
| u32 supply_type; |
| }; |
| |
| struct fusb30x_chip { |
| const char *name; |
| int node; |
| bool uboot_charge; |
| unsigned char bus; |
| unsigned int addr; |
| unsigned char *buf; |
| unsigned char tx_num; |
| |
| enum connection_state conn_state; |
| |
| /* 0 UFP : 1 DFP */ |
| bool power_role; |
| bool data_role; |
| |
| bool is_cc_connected; |
| bool is_pd_connected; |
| |
| bool is_enter_mode; |
| int pin_assignment_support; |
| int pin_assignment_def; |
| bool attention; |
| |
| struct PD_CAP_INFO pd_cap_info; |
| |
| struct fdt_gpio_state gpio_vbus_5v; |
| struct fdt_gpio_state gpio_discharge; |
| struct fdt_gpio_state gpio_cc_int; |
| int gpio_irq; |
| int timer_state; |
| int timer_mux; |
| int port_num; |
| int work_continue; |
| int gpio_int_irq; |
| int enable_irq; |
| |
| /* |
| * --------------------------------- |
| * | role 0x03 << 2, | cc_use 0x03 | |
| * | src 1 << 2, | cc1 1 | |
| * | snk 2 << 2, | cc2 2 | |
| * --------------------------------- |
| */ |
| u8 cc_state; |
| int cc1; |
| int cc2; |
| /* 0 cc1 : 1 cc2 */ |
| bool cc_polarity; |
| u8 val_tmp; |
| u8 debounce_cnt; |
| int sub_state; |
| int caps_counter; |
| u32 send_load[7]; |
| u32 rec_load[7]; |
| u16 send_head; |
| u16 rec_head; |
| int msg_id; |
| enum tx_state tx_state; |
| int hardrst_count; |
| u32 source_power_supply[7]; |
| /* 50mv unit */ |
| u32 source_max_current[7]; |
| /* 10ma uint*/ |
| int pos_power; |
| /* |
| * if PartnerCap[0] == 0xffffffff |
| * show Partner Device do not support supply |
| */ |
| u32 partner_cap[7]; |
| int n_caps_used; |
| int vdm_state; |
| int vdm_substate; |
| int vdm_send_state; |
| u32 dp_status; |
| u16 vdm_svid[12]; |
| int vdm_svid_num; |
| u32 vdm_id; |
| u8 chip_id; |
| bool vconn_enabled; |
| int togdone_pullup; |
| int pd_output_vol; |
| int pd_output_cur; |
| int cc_meas_high; |
| int cc_meas_low; |
| }; |
| |
| int fusb302_init(void); |
| int get_pd_port_num(void); |
| void typec_discharge(void); |
| int get_pd_output_val(int *pd_output_vol, int *pd_output_cur); |
| |
| #endif /* FUSB302_H */ |