Browse Source

Make requests from PPS APDOs

PPS APDOs are second priority, behind fixed supply PDOs.
Clara Hobbs 6 years ago
parent
commit
6e1c09f649
2 changed files with 64 additions and 8 deletions
  1. 35
    0
      lib/include/pd.h
  2. 29
    8
      src/device_policy_manager.c

+ 35
- 0
lib/include/pd.h View File

@@ -177,6 +177,21 @@
177 177
 /* PD Source Fixed PDO voltage */
178 178
 #define PD_PDO_SRC_FIXED_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
179 179
 
180
+/* PD Source Programmable Power Supply APDO */
181
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT 17
182
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE (0xFF << PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT)
183
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT 8
184
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE (0xFF << PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT)
185
+#define PD_APDO_SRC_PPS_CURRENT_SHIFT 0
186
+#define PD_APDO_SRC_PPS_CURRENT (0x7F << PD_APDO_SRC_PPS_CURRENT_SHIFT)
187
+
188
+/* PD Source Programmable Power Supply APDO voltages */
189
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_MAX_VOLTAGE) >> PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT)
190
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_MIN_VOLTAGE) >> PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT)
191
+
192
+/* PD Source Programmable Power Supply APDO current */
193
+#define PD_APDO_SRC_PPS_CURRENT_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_CURRENT) >> PD_APDO_SRC_PPS_CURRENT_SHIFT)
194
+
180 195
 /* TODO: other types of source PDO */
181 196
 
182 197
 /* PD Sink Fixed PDO */
@@ -240,6 +255,15 @@
240 255
 
241 256
 /* TODO: Battery RDOs */
242 257
 
258
+/* Programmable RDO */
259
+#define PD_RDO_PROG_VOLTAGE_SHIFT 9
260
+#define PD_RDO_PROG_VOLTAGE (0x7FF << PD_RDO_PROG_VOLTAGE_SHIFT)
261
+#define PD_RDO_PROG_CURRENT_SHIFT 0
262
+#define PD_RDO_PROG_CURRENT (0x7F << PD_RDO_PROG_CURRENT_SHIFT)
263
+
264
+#define PD_RDO_PROG_VOLTAGE_SET(i) (((i) << PD_RDO_PROG_VOLTAGE_SHIFT) & PD_RDO_PROG_VOLTAGE)
265
+#define PD_RDO_PROG_CURRENT_SET(i) (((i) << PD_RDO_PROG_CURRENT_SHIFT) & PD_RDO_PROG_CURRENT)
266
+
243 267
 
244 268
 /*
245 269
  * Time values
@@ -278,16 +302,27 @@
278 302
  * V: volt
279 303
  * CV: centivolt
280 304
  * MV: millivolt
305
+ * PRV: Programmable RDO voltage unit (20 mV)
281 306
  * PDV: Power Delivery voltage unit (50 mV)
307
+ * PAV: PPS APDO voltage unit (100 mV)
282 308
  * A: ampere
283 309
  * CA: centiampere
284 310
  * MA: milliampere
285 311
  * PDI: Power Delivery current unit (10 mA)
312
+ * PAI: PPS APDO current unit (50 mA)
286 313
  */
314
+#define PD_MV2PRV(mv) ((mv) / 20)
287 315
 #define PD_MV2PDV(mv) ((mv) / 50)
316
+#define PD_MV2PAV(mv) ((mv) / 100)
317
+#define PD_PRV2MV(prv) ((prv) * 20)
288 318
 #define PD_PDV2MV(pdv) ((pdv) * 50)
319
+#define PD_PAV2MV(pav) ((pav) * 100)
289 320
 #define PD_MA2PDI(ma) ((ma) / 10)
321
+#define PD_MA2PAI(ma) ((ma) / 50)
322
+#define PD_CA2PAI(ca) ((ca) / 5)
290 323
 #define PD_PDI2MA(pdi) ((pdi) * 10)
324
+#define PD_PAI2MA(pai) ((pai) * 50)
325
+#define PD_PAI2CA(pai) ((pai) * 5)
291 326
 
292 327
 /* Get portions of a voltage in more normal units */
293 328
 #define PD_MV_V(mv) ((mv) / 1000)

+ 29
- 8
src/device_policy_manager.c View File

@@ -65,14 +65,10 @@ bool pdbs_dpm_evaluate_capability(struct pdb_config *cfg,
65 65
     if (scfg != NULL && dpm_data->output_enabled) {
66 66
         /* Look at the PDOs to see if one matches our desires */
67 67
         for (uint8_t i = 0; i < numobj; i++) {
68
-            /* Fixed Supply PDOs come first, so when we see a PDO that isn't a
69
-             * Fixed Supply, stop reading. */
70
-            if ((capabilities->obj[i] & PD_PDO_TYPE) != PD_PDO_TYPE_FIXED) {
71
-                break;
72
-            }
73
-            /* If the V from the PDO equals our desired V and the I is at least
74
-             * our desired I */
75
-            if (PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == PD_MV2PDV(scfg->v)
68
+            /* If we have a fixed PDO, its V equals our desired V, and its I is
69
+             * at least our desired I */
70
+            if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED
71
+                    && PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == PD_MV2PDV(scfg->v)
76 72
                     && PD_PDO_SRC_FIXED_CURRENT_GET(capabilities, i) >= scfg->i) {
77 73
                 /* We got what we wanted, so build a request for that */
78 74
                 request->hdr = cfg->pe.hdr_template | PD_MSGTYPE_REQUEST
@@ -96,6 +92,31 @@ bool pdbs_dpm_evaluate_capability(struct pdb_config *cfg,
96 92
                 /* Update requested voltage */
97 93
                 dpm_data->_requested_voltage = PD_PDV2MV(PD_MV2PDV(scfg->v));
98 94
 
95
+                dpm_data->_capability_match = true;
96
+                return true;
97
+            }
98
+            /* If we have a PPS APDO, our desired V lies within its range, and
99
+             * its I is at least our desired I */
100
+            if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED
101
+                    && (capabilities->obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS
102
+                    && PD_APDO_SRC_PPS_MAX_VOLTAGE_GET(capabilities, i) >= PD_MV2PAV(scfg->v)
103
+                    && PD_APDO_SRC_PPS_MIN_VOLTAGE_GET(capabilities, i) <= PD_MV2PAV(scfg->v)
104
+                    && PD_APDO_SRC_PPS_CURRENT_GET(capabilities, i) >= PD_CA2PAI(scfg->i)) {
105
+                /* We got what we wanted, so build a request for that */
106
+                request->hdr = cfg->pe.hdr_template | PD_MSGTYPE_REQUEST
107
+                    | PD_NUMOBJ(1);
108
+
109
+                /* Build a request */
110
+                request->obj[0] = PD_RDO_PROG_CURRENT_SET(PD_CA2PAI(scfg->i))
111
+                    | PD_RDO_PROG_VOLTAGE_SET(PD_MV2PRV(scfg->v))
112
+                    | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
113
+                if (dpm_data->usb_comms) {
114
+                    request->obj[0] |= PD_RDO_USB_COMMS;
115
+                }
116
+
117
+                /* Update requested voltage */
118
+                dpm_data->_requested_voltage = PD_PRV2MV(PD_MV2PRV(scfg->v));
119
+
99 120
                 dpm_data->_capability_match = true;
100 121
                 return true;
101 122
             }

Loading…
Cancel
Save