summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2016-07-12 16:01:07 -0700
committerJack Pham <jackp@codeaurora.org>2016-07-25 16:18:11 -0700
commit34d404c41995fa63340fbe819a09558ffb1ceda9 (patch)
tree5e86c2cd354ab0d740e9fd718867ae6b26091617 /include
parent7eb20e5733b82473d2d1e9e59aa42989e73f3c70 (diff)
usb: pd: Add vendor defined message handling
Add APIs to send and receive vendor defined messages (VDM) over USB PD. A handler for a standard or vendor ID (SVID) can register callbacks to be notified of reception of VDM messages. One use case is for another kernel driver, such as DisplayPort, to be able to be notified when an Alternate Mode adapter is connected to the Type-C port in order to enter modal operation. SVID handlers should maintain their own state and timer resources in order to comply with the Power Delivery Specification. Change-Id: Ibe26e6deeca587f21f8121f6f32cf7cc0a5c3e23 Signed-off-by: Hemant Kumar <hemantk@codeaurora.org> Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/usb/usbpd.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/include/linux/usb/usbpd.h b/include/linux/usb/usbpd.h
new file mode 100644
index 000000000000..c2c1025feb8e
--- /dev/null
+++ b/include/linux/usb/usbpd.h
@@ -0,0 +1,156 @@
+/* Copyright (c) 2016, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_USB_USBPD_H
+#define __LINUX_USB_USBPD_H
+
+#include <linux/list.h>
+
+struct usbpd;
+
+/* Standard IDs */
+#define USBPD_SID 0xff00
+
+/* Structured VDM Command Type */
+enum usbpd_svdm_cmd_type {
+ SVDM_CMD_TYPE_INITIATOR,
+ SVDM_CMD_TYPE_RESP_ACK,
+ SVDM_CMD_TYPE_RESP_NAK,
+ SVDM_CMD_TYPE_RESP_BUSY,
+};
+
+/* Structured VDM Commands */
+#define USBPD_SVDM_DISCOVER_IDENTITY 0x1
+#define USBPD_SVDM_DISCOVER_SVIDS 0x2
+#define USBPD_SVDM_DISCOVER_MODES 0x3
+#define USBPD_SVDM_ENTER_MODE 0x4
+#define USBPD_SVDM_EXIT_MODE 0x5
+#define USBPD_SVDM_ATTENTION 0x6
+
+/*
+ * Implemented by client
+ */
+struct usbpd_svid_handler {
+ u16 svid;
+
+ void (*connect)(struct usbpd_svid_handler *hdlr);
+ void (*disconnect)(struct usbpd_svid_handler *hdlr);
+
+ /* Unstructured VDM */
+ void (*vdm_received)(struct usbpd_svid_handler *hdlr, u32 vdm_hdr,
+ const u32 *vdos, int num_vdos);
+
+ /* Structured VDM */
+ void (*svdm_received)(struct usbpd_svid_handler *hdlr, u8 cmd,
+ enum usbpd_svdm_cmd_type cmd_type, const u32 *vdos,
+ int num_vdos);
+
+ struct list_head entry;
+};
+
+enum plug_orientation {
+ ORIENTATION_NONE,
+ ORIENTATION_CC1,
+ ORIENTATION_CC2,
+};
+
+#if IS_ENABLED(CONFIG_USB_PD_POLICY)
+/*
+ * Obtains an instance of usbpd from a DT phandle
+ */
+struct usbpd *devm_usbpd_get_by_phandle(struct device *dev,
+ const char *phandle);
+
+/*
+ * Called by client to handle specific SVID messages.
+ * Specify callback functions in the usbpd_svid_handler argument
+ */
+int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr);
+
+void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr);
+
+/*
+ * Transmit a VDM message.
+ */
+int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos,
+ int num_vdos);
+
+/*
+ * Transmit a Structured VDM message.
+ */
+int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
+ enum usbpd_svdm_cmd_type cmd_type, int obj_pos,
+ const u32 *vdos, int num_vdos);
+
+/*
+ * Get current status of CC pin orientation.
+ *
+ * Return: ORIENTATION_CC1 or ORIENTATION_CC2 if attached,
+ * otherwise ORIENTATION_NONE if not attached
+ */
+enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd);
+#else
+static inline struct usbpd *devm_usbpd_get_by_phandle(struct device *dev,
+ const char *phandle)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline int usbpd_register_svid(struct usbpd *pd,
+ struct usbpd_svid_handler *hdlr)
+{
+ return -EINVAL;
+}
+
+static inline void usbpd_unregister_svid(struct usbpd *pd,
+ struct usbpd_svid_handler *hdlr)
+{
+}
+
+static inline int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos,
+ int num_vdos)
+{
+ return -EINVAL;
+}
+
+static inline int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
+ enum usbpd_svdm_cmd_type cmd_type, int obj_pos,
+ const u32 *vdos, int num_vdos)
+{
+ return -EINVAL;
+}
+
+static inline enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
+{
+ return ORIENTATION_NONE;
+}
+#endif /* IS_ENABLED(CONFIG_USB_PD_POLICY) */
+
+/*
+ * Additional helpers for Enter/Exit Mode commands
+ */
+
+static inline int usbpd_enter_mode(struct usbpd *pd, u16 svid, int mode,
+ const u32 *vdo)
+{
+ return usbpd_send_svdm(pd, svid, USBPD_SVDM_ENTER_MODE,
+ SVDM_CMD_TYPE_INITIATOR, mode, vdo, vdo ? 1 : 0);
+}
+
+static inline int usbpd_exit_mode(struct usbpd *pd, u16 svid, int mode,
+ const u32 *vdo)
+{
+ return usbpd_send_svdm(pd, svid, USBPD_SVDM_EXIT_MODE,
+ SVDM_CMD_TYPE_INITIATOR, mode, vdo, vdo ? 1 : 0);
+}
+
+#endif /* __LINUX_USB_USBPD_H */