|
@@ -142,8 +142,9 @@ static enum policy_engine_state pe_sink_wait_cap(struct pdb_config *cfg)
|
142
|
142
|
|
143
|
143
|
static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
|
144
|
144
|
{
|
145
|
|
- /* If we have a message, remember the index of the first PPS APDO so we can
|
146
|
|
- * check if the request is for a PPS APDO in PE_SNK_Select_Cap. */
|
|
145
|
+ /* If we have a Source_Capabilities message, remember the index of the
|
|
146
|
+ * first PPS APDO so we can check if the request is for a PPS APDO in
|
|
147
|
+ * PE_SNK_Select_Cap. */
|
147
|
148
|
if (cfg->pe._message != NULL) {
|
148
|
149
|
/* Start by assuming we won't find a PPS APDO (set the index greater
|
149
|
150
|
* than the maximum possible) */
|
|
@@ -156,10 +157,21 @@ static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
|
156
|
157
|
break;
|
157
|
158
|
}
|
158
|
159
|
}
|
|
160
|
+ /* New capabilities also means we can't be making a request from the
|
|
161
|
+ * same PPS APDO */
|
|
162
|
+ cfg->pe._last_pps = 8;
|
159
|
163
|
}
|
160
|
164
|
/* Get a message object for the request if we don't have one already */
|
161
|
165
|
if (cfg->pe._last_dpm_request == NULL) {
|
162
|
166
|
cfg->pe._last_dpm_request = chPoolAlloc(&pdb_msg_pool);
|
|
167
|
+ } else {
|
|
168
|
+ /* Remember the last PDO we requested if it was a PPS APDO */
|
|
169
|
+ if (PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request) >= cfg->pe._pps_index) {
|
|
170
|
+ cfg->pe._last_pps = PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request);
|
|
171
|
+ /* Otherwise, forget any PPS APDO we had requested */
|
|
172
|
+ } else {
|
|
173
|
+ cfg->pe._last_pps = 8;
|
|
174
|
+ }
|
163
|
175
|
}
|
164
|
176
|
/* Ask the DPM what to request */
|
165
|
177
|
cfg->dpm.evaluate_capability(cfg, cfg->pe._message,
|
|
@@ -221,7 +233,9 @@ static enum policy_engine_state pe_sink_select_cap(struct pdb_config *cfg)
|
221
|
233
|
if (PD_MSGTYPE_GET(cfg->pe._message) == PD_MSGTYPE_ACCEPT
|
222
|
234
|
&& PD_NUMOBJ_GET(cfg->pe._message) == 0) {
|
223
|
235
|
/* Transition to Sink Standby if necessary */
|
224
|
|
- cfg->dpm.transition_standby(cfg);
|
|
236
|
+ if (PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request) != cfg->pe._last_pps) {
|
|
237
|
+ cfg->dpm.transition_standby(cfg);
|
|
238
|
+ }
|
225
|
239
|
|
226
|
240
|
cfg->pe._min_power = false;
|
227
|
241
|
|
|
@@ -770,6 +784,8 @@ static THD_FUNCTION(PolicyEngine, vcfg) {
|
770
|
784
|
cfg->pe._old_tcc_match = -1;
|
771
|
785
|
/* Initialize the pps_index */
|
772
|
786
|
cfg->pe._pps_index = 8;
|
|
787
|
+ /* Initialize the last_pps */
|
|
788
|
+ cfg->pe._last_pps = 8;
|
773
|
789
|
/* Initialize the PD message header template */
|
774
|
790
|
cfg->pe.hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
|
775
|
791
|
|