platform/chrome: cros_ec_typec: Add initial VDM support
authorPrashant Malani <pmalani@chromium.org>
Wed, 28 Dec 2022 00:45:11 +0000 (00:45 +0000)
committerPrashant Malani <pmalani@chromium.org>
Mon, 9 Jan 2023 20:32:53 +0000 (20:32 +0000)
Add ops to support USB PD VDM (Vendor Defined Message) from the port
driver. This enables the port driver to interface with alternate mode
drivers and communicate with connected peripherals.

The initial support just contains an implementation of the Enter
Mode command.

Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Prashant Malani <pmalani@chromium.org>
[pmalani: Fixed trivial conflict in Makefile]
Reviewed-by: Benson Leung <bleung@chromium.org>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20221228004648.793339-9-pmalani@chromium.org
MAINTAINERS
drivers/platform/chrome/Makefile
drivers/platform/chrome/cros_ec_typec.c
drivers/platform/chrome/cros_typec_vdm.c [new file with mode: 0644]
drivers/platform/chrome/cros_typec_vdm.h [new file with mode: 0644]

index f383b78bceb2fdea208a8825c21d64e2619061f4..4c1747067624323c6bfa02933418c6fa8738ebcb 100644 (file)
@@ -5007,6 +5007,7 @@ L:        chrome-platform@lists.linux.dev
 S:     Maintained
 F:     drivers/platform/chrome/cros_ec_typec.*
 F:     drivers/platform/chrome/cros_typec_switch.c
+F:     drivers/platform/chrome/cros_typec_vdm.*
 
 CHROMEOS EC USB PD NOTIFY DRIVER
 M:     Prashant Malani <pmalani@chromium.org>
index fc2335d699d8327b975f2699a877a5f8570819a2..9e26e45c4a375882e3de36ae4c6b5d62d8d6abb9 100644 (file)
@@ -17,7 +17,7 @@ obj-$(CONFIG_CROS_EC_RPMSG)           += cros_ec_rpmsg.o
 obj-$(CONFIG_CROS_EC_SPI)              += cros_ec_spi.o
 obj-$(CONFIG_CROS_EC_UART)             += cros_ec_uart.o
 cros_ec_lpcs-objs                      := cros_ec_lpc.o cros_ec_lpc_mec.o
-cros-ec-typec-objs                     := cros_ec_typec.o
+cros-ec-typec-objs                     := cros_ec_typec.o cros_typec_vdm.o
 obj-$(CONFIG_CROS_EC_TYPEC)            += cros-ec-typec.o
 obj-$(CONFIG_CROS_EC_LPC)              += cros_ec_lpcs.o
 obj-$(CONFIG_CROS_EC_PROTO)            += cros_ec_proto.o cros_ec_trace.o
index a4eff590ca5699f46aa3771c15bf7731d8a7c2e2..1e28d56b094d5cc8dcacc970e3c96756590e8b78 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/usb/typec_tbt.h>
 
 #include "cros_ec_typec.h"
+#include "cros_typec_vdm.h"
 
 #define DRV_NAME "cros-ec-typec"
 
@@ -272,6 +273,7 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
                return PTR_ERR(amode);
        port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
        typec_altmode_set_drvdata(amode, port);
+       amode->ops = &port_amode_ops;
 
        /*
         * Register TBT compatibility alt mode. The EC will not enter the mode
@@ -286,6 +288,7 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
                return PTR_ERR(amode);
        port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
        typec_altmode_set_drvdata(amode, port);
+       amode->ops = &port_amode_ops;
 
        port->state.alt = NULL;
        port->state.mode = TYPEC_STATE_USB;
diff --git a/drivers/platform/chrome/cros_typec_vdm.c b/drivers/platform/chrome/cros_typec_vdm.c
new file mode 100644 (file)
index 0000000..df0102c
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * USB Power Delivery Vendor Defined Message (VDM) support code.
+ *
+ * Copyright 2023 Google LLC
+ * Author: Prashant Malani <pmalani@chromium.org>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/usb/pd_vdo.h>
+
+#include "cros_ec_typec.h"
+#include "cros_typec_vdm.h"
+
+static int cros_typec_port_amode_enter(struct typec_altmode *amode, u32 *vdo)
+{
+       struct cros_typec_port *port = typec_altmode_get_drvdata(amode);
+       struct ec_params_typec_control req = {
+               .port = port->port_num,
+               .command = TYPEC_CONTROL_COMMAND_SEND_VDM_REQ,
+       };
+       struct typec_vdm_req vdm_req = {};
+       u32 hdr;
+
+       hdr = VDO(amode->svid, 1, SVDM_VER_2_0, CMD_ENTER_MODE);
+       hdr |= VDO_OPOS(amode->mode);
+
+       vdm_req.vdm_data[0] = hdr;
+       vdm_req.vdm_data_objects = 1;
+       vdm_req.partner_type = TYPEC_PARTNER_SOP;
+       req.vdm_req_params = vdm_req;
+
+       dev_dbg(port->typec_data->dev, "Sending EnterMode VDM, hdr: %x, port: %d\n",
+               hdr, port->port_num);
+
+       return cros_ec_cmd(port->typec_data->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
+                          sizeof(req), NULL, 0);
+}
+
+struct typec_altmode_ops port_amode_ops = {
+       .enter = cros_typec_port_amode_enter,
+};
diff --git a/drivers/platform/chrome/cros_typec_vdm.h b/drivers/platform/chrome/cros_typec_vdm.h
new file mode 100644 (file)
index 0000000..7e282d1
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __CROS_TYPEC_VDM__
+#define __CROS_TYPEC_VDM__
+
+#include <linux/usb/typec_altmode.h>
+
+extern struct typec_altmode_ops port_amode_ops;
+
+#endif /*  __CROS_TYPEC_VDM__ */