Start of public OpenTitan development history

Code contributors:
Alex Bradbury <asb@lowrisc.org>
Cindy Chen <chencindy@google.com>
Eunchan Kim <eunchan@google.com>
Gaurang Chitroda <gaurangg@google.com>
Mark Hayter <mark.hayter@gmail.com>
Michael Schaffner <msf@google.com>
Miguel Osorio <miguelosorio@google.com>
Nils Graf <nilsg@google.com>
Philipp Wagner <phw@lowrisc.org>
Pirmin Vogel <vogelpi@lowrisc.org>
Ram Babu Penugonda <rampenugonda@google.com>
Scott Johnson <scottdj@google.com>
Shail Kushwah <kushwahs@google.com>
Srikrishna Iyer <sriyer@google.com>
Steve Nelson <Steve.Nelson@wdc.com>
Tao Liu <taliu@google.com>
Timothy Chen <timothytim@google.com>
Tobias Wölfel <tobias.woelfel@mailbox.org>
Weicai Yang <weicai@google.com>
diff --git a/sw/lib/usb_controlep.h b/sw/lib/usb_controlep.h
new file mode 100644
index 0000000..3be4840
--- /dev/null
+++ b/sw/lib/usb_controlep.h
@@ -0,0 +1,96 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef __USB_CONTROLEP_H__
+#define __USB_CONTROLEP_H__
+#include <stddef.h>
+
+#include "common.h"
+#include "usbdev.h"
+
+typedef enum ctstate {
+  kCtIdle,
+  kCtWaitIn,      // Queued IN data stage, waiting ack
+  kCtStatOut,     // Waiting for OUT status stage
+  kCtAddrStatIn,  // Queued status stage, waiting ack afterwhich set dev_addr
+  kCtStatIn,      // Queued status stage, waiting ack
+  kCtError        // Something bad
+} ctstate_t;
+
+typedef struct usb_controlep_ctx {
+  usbdev_ctx_t *ctx;
+  int ep;
+  ctstate_t ctrlstate;
+  uint32_t new_dev;
+  uint8_t usb_config;
+  const uint8_t *cfg_dscr;
+  size_t cfg_dscr_len;
+} usb_controlep_ctx_t;
+
+/**
+ * Initialize control endpoint
+ *
+ * @param ctctx uninitialized context for this instance
+ * @param ctx initialized context for usbdev driver
+ * @param ep endpoint (if this is other than 0 make sure you know why)
+ * @param cfg_dscr configuration descriptor for the device
+ * @param cfg_dscr_len length of cfg_dscr
+ */
+void usb_controlep_init(usb_controlep_ctx_t *ctctx, usbdev_ctx_t *ctx, int ep,
+                        const uint8_t *cfg_dscr, size_t cfg_dscr_len);
+
+/********************************************************************/
+/* Below this point are macros used to construct the USB descriptor */
+/* Use them to initialize a uint8_t array for cfg_dscr              */
+
+#define USB_CFG_DSCR_LEN 9
+#define USB_CFG_DSCR_HEAD(total_len, nint)                                    \
+  /* This is the actual configuration descriptor                 */           \
+  USB_CFG_DSCR_LEN,     /* bLength                                   */       \
+      2,                /* bDescriptorType                           */       \
+      (total_len)&0xff, /* wTotalLength[0]                           */       \
+      (total_len) >> 8, /* wTotalLength[1]                           */       \
+      (nint),           /* bNumInterfaces                            */       \
+      1,                /* bConfigurationValu                        */       \
+      0,                /* iConfiguration                            */       \
+      0xC0,             /* bmAttributes: must-be-one, self-powered   */       \
+      50, /* bMaxPower                                 */ /* MUST be followed \
+                                                             by (nint)        \
+                                                             Interface +      \
+                                                             Endpoint         \
+                                                             Descriptors */
+
+// KEEP BLANK LINE ABOVE, it is in the macro!
+
+#define USB_INTERFACE_DSCR_LEN 9
+#define VEND_INTERFACE_DSCR(inum, nep, subclass, protocol)                \
+  /* interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 */    \
+  USB_INTERFACE_DSCR_LEN, /* bLength                             */       \
+      4,                  /* bDescriptorType                     */       \
+      (inum),             /* bInterfaceNumber                    */       \
+      0,                  /* bAlternateSetting                   */       \
+      (nep),              /* bNumEndpoints                       */       \
+      0xff,               /* bInterfaceClass (Vendor Specific)   */       \
+      (subclass),         /* bInterfaceSubClass                  */       \
+      (protocol),         /* bInterfaceProtocol                  */       \
+      0, /* iInterface                          */ /* MUST be followed by \
+                                                      (nep) Endpoint      \
+                                                      Descriptors */
+
+// KEEP BLANK LINE ABOVE, it is in the macro!
+
+#define USB_EP_DSCR_LEN 7
+#define USB_BULK_EP_DSCR(in, ep, maxsize, interval)                           \
+  /* endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13   */       \
+  USB_EP_DSCR_LEN,                 /* bLength                              */ \
+      5,                           /* bDescriptorType                      */ \
+      (ep) | (((in) << 7) & 0x80), /* bEndpointAddress, top bit set for IN */ \
+      0x02,                        /* bmAttributes (0x02=bulk, data)       */ \
+      (maxsize)&0xff,              /* wMaxPacketSize[0]                    */ \
+      (maxsize) >> 8,              /* wMaxPacketSize[1]                    */ \
+      (interval),                  /* bInterval                            */
+
+// KEEP BLANK LINE ABOVE, it is in the macro!
+
+#endif