Skip to content

Commit c710d0b

Browse files
kyletsoadlgregkh
authored andcommitted
usb: typec: tcpm: Extend the matching rules on PPS APDO selection
Current matching rules ensure that the voltage range of selected Source Capability is entirely within the range defined in one of the Sink Capabilities. This is reasonable but not practical because Sink may not support wide range of voltage when sinking power while Source could advertise its capabilities in relatively wider range. For example, a Source PDO advertising 3.3V-11V@3A (9V Prog of Fixed Nominal Voltage) will not be selected if the Sink requires 5V-12V@3A PPS power. However, the Sink could work well if the requested voltage range in RDOs is 5V-11V@3A. Currently accepted: |--------- source -----| |----------- sink ---------------| Currently not accepted: |--------- source -----| |----------- sink ---------------| |--------- source -----| |----------- sink ---------------| |--------- source -----------------| |------ sink -------| To improve the usability, change the matching rules to what listed below: a. The Source PDO is selectable if any portion of the voltage range overlaps one of the Sink PDO's voltage range. b. The maximum operational voltage will be the lower one between the selected Source PDO and the matching Sink PDO. c. The maximum power will be the maximum operational voltage times the maximum current defined in the selected Source PDO d. Select the Source PDO with the highest maximum power Signed-off-by: Kyle Tso <kyletso@google.com> Acked-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 28ce553 commit c710d0b

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,8 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port)
22132213
unsigned int i, j, max_mw = 0, max_mv = 0;
22142214
unsigned int min_src_mv, max_src_mv, src_ma, src_mw;
22152215
unsigned int min_snk_mv, max_snk_mv;
2216-
u32 pdo;
2216+
unsigned int max_op_mv;
2217+
u32 pdo, src, snk;
22172218
unsigned int src_pdo = 0, snk_pdo = 0;
22182219

22192220
/*
@@ -2263,16 +2264,18 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port)
22632264
continue;
22642265
}
22652266

2266-
if (max_src_mv <= max_snk_mv &&
2267-
min_src_mv >= min_snk_mv) {
2267+
if (min_src_mv <= max_snk_mv &&
2268+
max_src_mv >= min_snk_mv) {
2269+
max_op_mv = min(max_src_mv, max_snk_mv);
2270+
src_mw = (max_op_mv * src_ma) / 1000;
22682271
/* Prefer higher voltages if available */
22692272
if ((src_mw == max_mw &&
2270-
min_src_mv > max_mv) ||
2273+
max_op_mv > max_mv) ||
22712274
src_mw > max_mw) {
22722275
src_pdo = i;
22732276
snk_pdo = j;
22742277
max_mw = src_mw;
2275-
max_mv = max_src_mv;
2278+
max_mv = max_op_mv;
22762279
}
22772280
}
22782281
}
@@ -2285,16 +2288,18 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port)
22852288
}
22862289

22872290
if (src_pdo) {
2288-
pdo = port->source_caps[src_pdo];
2289-
2290-
port->pps_data.min_volt = pdo_pps_apdo_min_voltage(pdo);
2291-
port->pps_data.max_volt = pdo_pps_apdo_max_voltage(pdo);
2292-
port->pps_data.max_curr =
2293-
min_pps_apdo_current(pdo, port->snk_pdo[snk_pdo]);
2294-
port->pps_data.out_volt =
2295-
min(pdo_pps_apdo_max_voltage(pdo), port->pps_data.out_volt);
2296-
port->pps_data.op_curr =
2297-
min(port->pps_data.max_curr, port->pps_data.op_curr);
2291+
src = port->source_caps[src_pdo];
2292+
snk = port->snk_pdo[snk_pdo];
2293+
2294+
port->pps_data.min_volt = max(pdo_pps_apdo_min_voltage(src),
2295+
pdo_pps_apdo_min_voltage(snk));
2296+
port->pps_data.max_volt = min(pdo_pps_apdo_max_voltage(src),
2297+
pdo_pps_apdo_max_voltage(snk));
2298+
port->pps_data.max_curr = min_pps_apdo_current(src, snk);
2299+
port->pps_data.out_volt = min(port->pps_data.max_volt,
2300+
port->pps_data.out_volt);
2301+
port->pps_data.op_curr = min(port->pps_data.max_curr,
2302+
port->pps_data.op_curr);
22982303
}
22992304

23002305
return src_pdo;

0 commit comments

Comments
 (0)