hc
2023-11-22 9ca5fbcb63a8dcaee0527f96afb91dc4b4bd8fa9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * Copyright 2015-2017 Google, Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
 
#ifndef __LINUX_USB_TCPM_H
#define __LINUX_USB_TCPM_H
 
#include <linux/bitops.h>
#include <linux/usb/typec.h>
#include "pd.h"
 
enum typec_cc_status {
   TYPEC_CC_OPEN,
   TYPEC_CC_RA,
   TYPEC_CC_RD,
   TYPEC_CC_RP_DEF,
   TYPEC_CC_RP_1_5,
   TYPEC_CC_RP_3_0,
};
 
/* Collision Avoidance */
#define SINK_TX_NG    TYPEC_CC_RP_1_5
#define SINK_TX_OK    TYPEC_CC_RP_3_0
 
enum typec_cc_polarity {
   TYPEC_POLARITY_CC1,
   TYPEC_POLARITY_CC2,
};
 
/* Time to wait for TCPC to complete transmit */
#define PD_T_TCPC_TX_TIMEOUT    100        /* in ms    */
#define PD_ROLE_SWAP_TIMEOUT    (MSEC_PER_SEC * 10)
#define PD_PPS_CTRL_TIMEOUT    (MSEC_PER_SEC * 10)
 
enum tcpm_transmit_status {
   TCPC_TX_SUCCESS = 0,
   TCPC_TX_DISCARDED = 1,
   TCPC_TX_FAILED = 2,
};
 
enum tcpm_transmit_type {
   TCPC_TX_SOP = 0,
   TCPC_TX_SOP_PRIME = 1,
   TCPC_TX_SOP_PRIME_PRIME = 2,
   TCPC_TX_SOP_DEBUG_PRIME = 3,
   TCPC_TX_SOP_DEBUG_PRIME_PRIME = 4,
   TCPC_TX_HARD_RESET = 5,
   TCPC_TX_CABLE_RESET = 6,
   TCPC_TX_BIST_MODE_2 = 7
};
 
/* Mux state attributes */
#define TCPC_MUX_USB_ENABLED        BIT(0)    /* USB enabled */
#define TCPC_MUX_DP_ENABLED        BIT(1)    /* DP enabled */
#define TCPC_MUX_POLARITY_INVERTED    BIT(2)    /* Polarity inverted */
 
/**
 * struct tcpc_dev - Port configuration and callback functions
 * @fwnode:    Pointer to port fwnode
 * @get_vbus:    Called to read current VBUS state
 * @get_current_limit:
 *        Optional; called by the tcpm core when configured as a snk
 *        and cc=Rp-def. This allows the tcpm to provide a fallback
 *        current-limit detection method for the cc=Rp-def case.
 *        For example, some tcpcs may include BC1.2 charger detection
 *        and use that in this case.
 * @set_cc:    Called to set value of CC pins
 * @get_cc:    Called to read current CC pin values
 * @set_polarity:
 *        Called to set polarity
 * @set_vconn:    Called to enable or disable VCONN
 * @set_vbus:    Called to enable or disable VBUS
 * @set_current_limit:
 *        Optional; called to set current limit as negotiated
 *        with partner.
 * @set_pd_rx:    Called to enable or disable reception of PD messages
 * @set_roles:    Called to set power and data roles
 * @start_toggling:
 *        Optional; if supported by hardware, called to start dual-role
 *        toggling or single-role connection detection. Toggling stops
 *        automatically if a connection is established.
 * @try_role:    Optional; called to set a preferred role
 * @pd_transmit:Called to transmit PD message
 * @enable_frs:
 *        Optional; Called to enable/disable PD 3.0 fast role swap.
 *        Enabling frs is accessory dependent as not all PD3.0
 *        accessories support fast role swap.
 */
struct tcpc_dev {
   struct fwnode_handle *fwnode;
 
   int (*init)(struct tcpc_dev *dev);
   int (*get_vbus)(struct tcpc_dev *dev);
   int (*get_current_limit)(struct tcpc_dev *dev);
   int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc);
   int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1,
             enum typec_cc_status *cc2);
   int (*set_polarity)(struct tcpc_dev *dev,
               enum typec_cc_polarity polarity);
   int (*set_vconn)(struct tcpc_dev *dev, bool on);
   int (*set_vbus)(struct tcpc_dev *dev, bool on, bool charge);
   int (*set_current_limit)(struct tcpc_dev *dev, u32 max_ma, u32 mv);
   int (*set_pd_rx)(struct tcpc_dev *dev, bool on);
   int (*set_roles)(struct tcpc_dev *dev, bool attached,
            enum typec_role role, enum typec_data_role data);
   int (*start_toggling)(struct tcpc_dev *dev,
                 enum typec_port_type port_type,
                 enum typec_cc_status cc);
   int (*try_role)(struct tcpc_dev *dev, int role);
   int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type,
              const struct pd_message *msg);
   int (*enable_frs)(struct tcpc_dev *dev, bool enable);
};
 
struct tcpm_port;
 
struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc);
void tcpm_unregister_port(struct tcpm_port *port);
 
int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
                   unsigned int nr_pdo);
int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo,
                 unsigned int nr_pdo,
                 unsigned int operating_snk_mw);
 
void tcpm_vbus_change(struct tcpm_port *port);
void tcpm_cc_change(struct tcpm_port *port);
void tcpm_sink_frs(struct tcpm_port *port);
void tcpm_sourcing_vbus(struct tcpm_port *port);
void tcpm_pd_receive(struct tcpm_port *port,
            const struct pd_message *msg);
void tcpm_pd_transmit_complete(struct tcpm_port *port,
                  enum tcpm_transmit_status status);
void tcpm_pd_hard_reset(struct tcpm_port *port);
void tcpm_tcpc_reset(struct tcpm_port *port);
 
#endif /* __LINUX_USB_TCPM_H */