* VDM object is minimum of VDM header + 6 additional data objects.
*/
+#define VDO_MAX_OBJECTS 6
+#define VDO_MAX_SIZE (VDO_MAX_OBJECTS + 1)
+
/*
* VDM header
* ----------
* <5> :: reserved (SVDM), command type (UVDM)
* <4:0> :: command
*/
-#define VDO_MAX_SIZE 7
#define VDO(vid, type, custom) \
(((vid) << 16) | \
((type) << 15) | \
unsigned int nr_src_pdo;
u32 snk_pdo[PDO_MAX_OBJECTS];
unsigned int nr_snk_pdo;
+ u32 snk_vdo[VDO_MAX_OBJECTS];
+ unsigned int nr_snk_vdo;
unsigned int max_snk_mv;
unsigned int max_snk_ma;
struct pd_mode_data *modep;
int rlen = 0;
u16 svid;
+ int i;
tcpm_log(port, "Rx VDM cmd 0x%x type %d cmd %d len %d",
p0, cmd_type, cmd, cnt);
case CMDT_INIT:
switch (cmd) {
case CMD_DISCOVER_IDENT:
+ /* 6.4.4.3.1: Only respond as UFP (device) */
+ if (port->data_role == TYPEC_DEVICE &&
+ port->nr_snk_vdo) {
+ for (i = 0; i < port->nr_snk_vdo; i++)
+ response[i + 1]
+ = cpu_to_le32(port->snk_vdo[i]);
+ rlen = port->nr_snk_vdo + 1;
+ }
break;
case CMD_DISCOVER_SVID:
break;
return nr_pdo;
}
+static int tcpm_copy_vdos(u32 *dest_vdo, const u32 *src_vdo,
+ unsigned int nr_vdo)
+{
+ unsigned int i;
+
+ if (nr_vdo > VDO_MAX_OBJECTS)
+ nr_vdo = VDO_MAX_OBJECTS;
+
+ for (i = 0; i < nr_vdo; i++)
+ dest_vdo[i] = src_vdo[i];
+
+ return nr_vdo;
+}
+
void tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
unsigned int nr_pdo)
{
tcpc->config->nr_src_pdo);
port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, tcpc->config->snk_pdo,
tcpc->config->nr_snk_pdo);
+ port->nr_snk_vdo = tcpm_copy_vdos(port->snk_vdo, tcpc->config->snk_vdo,
+ tcpc->config->nr_snk_vdo);
port->max_snk_mv = tcpc->config->max_snk_mv;
port->max_snk_ma = tcpc->config->max_snk_ma;