[topgen] Change Pinmux IDs to Use C Enums

Signed-off-by: Sam Elliott <selliott@lowrisc.org>
diff --git a/hw/top_earlgrey/data/top_earlgrey.h.tpl b/hw/top_earlgrey/data/top_earlgrey.h.tpl
index 47e7a5d..d20ca5b 100644
--- a/hw/top_earlgrey/data/top_earlgrey.h.tpl
+++ b/hw/top_earlgrey/data/top_earlgrey.h.tpl
@@ -10,46 +10,6 @@
 extern "C" {
 #endif
 
-#define PINMUX_PERIPH_INSEL_IDX_OFFSET 2
-
-// PERIPH_INSEL ranges from 0 to NUM_MIO + 2 -1}
-//  0 and 1 are tied to value 0 and 1
-#define NUM_MIO ${top["pinmux"]["num_mio"]}
-#define NUM_DIO ${sum([x["width"] if "width" in x else 1 for x in top["pinmux"]["dio"]])}
-
-<% offset = 0 %>\
-% for i, sig in enumerate(top["pinmux"]["inouts"] + top["pinmux"]["inputs"]):
-  % if sig["width"] == 1:
-#define PINMUX_${sig["name"].upper()}_IN ${offset + i}
-  % else:
-    % for j in range(sig["width"]):
-#define PINMUX_${sig["name"].upper()}_${j}_IN ${offset + i + j}
-    % endfor
-<% offset += sig["width"] %>\
-  % endif
-% endfor
-
-#define PINMUX_PERIPH_OUTSEL_IDX_OFFSET 3
-
-// PERIPH_OUTSEL ranges from 0 to NUM_MIO + 3 -1}
-// 0, 1 and 2 are tied to value 0, 1 and high-impedance
-
-## offset starts from 3 as 0, 1, 2 are prefixed value
-<% offset = 3 %>\
-#define PINMUX_VALUE_0_OUT 0
-#define PINMUX_VALUE_1_OUT 1
-#define PINMUX_VALUE_Z_OUT 2
-% for i, sig in enumerate(top["pinmux"]["inouts"] + top["pinmux"]["outputs"]):
-  % if sig["width"] == 1:
-#define PINMUX_${sig["name"].upper()}_OUT ${offset + i}
-  % else:
-    % for j in range(sig["width"]):
-#define PINMUX_${sig["name"].upper()}_${j}_OUT ${offset + i + j}
-    % endfor
-<% offset += sig["width"] %>\
-  % endif
-% endfor
-
 % for name, region in helper.modules():
 /**
  * Peripheral base address for ${name} in top ${top["name"]}.
@@ -140,6 +100,35 @@
  */
 ${helper.alert_mapping.render_declaration()}
 
+#define PINMUX_PERIPH_INSEL_IDX_OFFSET 2
+
+// PERIPH_INSEL ranges from 0 to NUM_MIO + 2 -1}
+//  0 and 1 are tied to value 0 and 1
+#define NUM_MIO ${top["pinmux"]["num_mio"]}
+#define NUM_DIO ${sum([x["width"] if "width" in x else 1 for x in top["pinmux"]["dio"]])}
+
+#define PINMUX_PERIPH_OUTSEL_IDX_OFFSET 3
+
+/**
+ * Pinmux Peripheral Input.
+ */
+${helper.pinmux_peripheral_in.render()}
+
+/**
+ * Pinmux MIO Input Selector.
+ */
+${helper.pinmux_insel.render()}
+
+/**
+ * Pinmux MIO Output.
+ */
+${helper.pinmux_mio_out.render()}
+
+/**
+ * Pinmux Peripheral Output Selector.
+ */
+${helper.pinmux_outsel.render()}
+
 // Header Extern Guard
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey.h b/hw/top_earlgrey/sw/autogen/top_earlgrey.h
index db39d92..ffcd1b3 100644
--- a/hw/top_earlgrey/sw/autogen/top_earlgrey.h
+++ b/hw/top_earlgrey/sw/autogen/top_earlgrey.h
@@ -10,87 +10,6 @@
 extern "C" {
 #endif
 
-#define PINMUX_PERIPH_INSEL_IDX_OFFSET 2
-
-// PERIPH_INSEL ranges from 0 to NUM_MIO + 2 -1}
-//  0 and 1 are tied to value 0 and 1
-#define NUM_MIO 32
-#define NUM_DIO 15
-
-#define PINMUX_GPIO_GPIO_0_IN 0
-#define PINMUX_GPIO_GPIO_1_IN 1
-#define PINMUX_GPIO_GPIO_2_IN 2
-#define PINMUX_GPIO_GPIO_3_IN 3
-#define PINMUX_GPIO_GPIO_4_IN 4
-#define PINMUX_GPIO_GPIO_5_IN 5
-#define PINMUX_GPIO_GPIO_6_IN 6
-#define PINMUX_GPIO_GPIO_7_IN 7
-#define PINMUX_GPIO_GPIO_8_IN 8
-#define PINMUX_GPIO_GPIO_9_IN 9
-#define PINMUX_GPIO_GPIO_10_IN 10
-#define PINMUX_GPIO_GPIO_11_IN 11
-#define PINMUX_GPIO_GPIO_12_IN 12
-#define PINMUX_GPIO_GPIO_13_IN 13
-#define PINMUX_GPIO_GPIO_14_IN 14
-#define PINMUX_GPIO_GPIO_15_IN 15
-#define PINMUX_GPIO_GPIO_16_IN 16
-#define PINMUX_GPIO_GPIO_17_IN 17
-#define PINMUX_GPIO_GPIO_18_IN 18
-#define PINMUX_GPIO_GPIO_19_IN 19
-#define PINMUX_GPIO_GPIO_20_IN 20
-#define PINMUX_GPIO_GPIO_21_IN 21
-#define PINMUX_GPIO_GPIO_22_IN 22
-#define PINMUX_GPIO_GPIO_23_IN 23
-#define PINMUX_GPIO_GPIO_24_IN 24
-#define PINMUX_GPIO_GPIO_25_IN 25
-#define PINMUX_GPIO_GPIO_26_IN 26
-#define PINMUX_GPIO_GPIO_27_IN 27
-#define PINMUX_GPIO_GPIO_28_IN 28
-#define PINMUX_GPIO_GPIO_29_IN 29
-#define PINMUX_GPIO_GPIO_30_IN 30
-#define PINMUX_GPIO_GPIO_31_IN 31
-
-#define PINMUX_PERIPH_OUTSEL_IDX_OFFSET 3
-
-// PERIPH_OUTSEL ranges from 0 to NUM_MIO + 3 -1}
-// 0, 1 and 2 are tied to value 0, 1 and high-impedance
-
-#define PINMUX_VALUE_0_OUT 0
-#define PINMUX_VALUE_1_OUT 1
-#define PINMUX_VALUE_Z_OUT 2
-#define PINMUX_GPIO_GPIO_0_OUT 3
-#define PINMUX_GPIO_GPIO_1_OUT 4
-#define PINMUX_GPIO_GPIO_2_OUT 5
-#define PINMUX_GPIO_GPIO_3_OUT 6
-#define PINMUX_GPIO_GPIO_4_OUT 7
-#define PINMUX_GPIO_GPIO_5_OUT 8
-#define PINMUX_GPIO_GPIO_6_OUT 9
-#define PINMUX_GPIO_GPIO_7_OUT 10
-#define PINMUX_GPIO_GPIO_8_OUT 11
-#define PINMUX_GPIO_GPIO_9_OUT 12
-#define PINMUX_GPIO_GPIO_10_OUT 13
-#define PINMUX_GPIO_GPIO_11_OUT 14
-#define PINMUX_GPIO_GPIO_12_OUT 15
-#define PINMUX_GPIO_GPIO_13_OUT 16
-#define PINMUX_GPIO_GPIO_14_OUT 17
-#define PINMUX_GPIO_GPIO_15_OUT 18
-#define PINMUX_GPIO_GPIO_16_OUT 19
-#define PINMUX_GPIO_GPIO_17_OUT 20
-#define PINMUX_GPIO_GPIO_18_OUT 21
-#define PINMUX_GPIO_GPIO_19_OUT 22
-#define PINMUX_GPIO_GPIO_20_OUT 23
-#define PINMUX_GPIO_GPIO_21_OUT 24
-#define PINMUX_GPIO_GPIO_22_OUT 25
-#define PINMUX_GPIO_GPIO_23_OUT 26
-#define PINMUX_GPIO_GPIO_24_OUT 27
-#define PINMUX_GPIO_GPIO_25_OUT 28
-#define PINMUX_GPIO_GPIO_26_OUT 29
-#define PINMUX_GPIO_GPIO_27_OUT 30
-#define PINMUX_GPIO_GPIO_28_OUT 31
-#define PINMUX_GPIO_GPIO_29_OUT 32
-#define PINMUX_GPIO_GPIO_30_OUT 33
-#define PINMUX_GPIO_GPIO_31_OUT 34
-
 /**
  * Peripheral base address for uart in top earlgrey.
  *
@@ -635,6 +554,176 @@
 extern const top_earlgrey_alert_peripheral_t
     top_earlgrey_alert_for_peripheral[12];
 
+#define PINMUX_PERIPH_INSEL_IDX_OFFSET 2
+
+// PERIPH_INSEL ranges from 0 to NUM_MIO + 2 -1}
+//  0 and 1 are tied to value 0 and 1
+#define NUM_MIO 32
+#define NUM_DIO 15
+
+#define PINMUX_PERIPH_OUTSEL_IDX_OFFSET 3
+
+/**
+ * Pinmux Peripheral Input.
+ */
+typedef enum top_earlgrey_pinmux_peripheral_in {
+  kTopEarlgreyPinmuxPeripheralInGpioGpio0 = 0, /**< gpio_gpio 0 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio1 = 1, /**< gpio_gpio 1 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio2 = 2, /**< gpio_gpio 2 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio3 = 3, /**< gpio_gpio 3 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio4 = 4, /**< gpio_gpio 4 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio5 = 5, /**< gpio_gpio 5 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio6 = 6, /**< gpio_gpio 6 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio7 = 7, /**< gpio_gpio 7 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio8 = 8, /**< gpio_gpio 8 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio9 = 9, /**< gpio_gpio 9 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio10 = 10, /**< gpio_gpio 10 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio11 = 11, /**< gpio_gpio 11 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio12 = 12, /**< gpio_gpio 12 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio13 = 13, /**< gpio_gpio 13 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio14 = 14, /**< gpio_gpio 14 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio15 = 15, /**< gpio_gpio 15 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio16 = 16, /**< gpio_gpio 16 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio17 = 17, /**< gpio_gpio 17 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio18 = 18, /**< gpio_gpio 18 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio19 = 19, /**< gpio_gpio 19 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio20 = 20, /**< gpio_gpio 20 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio21 = 21, /**< gpio_gpio 21 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio22 = 22, /**< gpio_gpio 22 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio23 = 23, /**< gpio_gpio 23 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio24 = 24, /**< gpio_gpio 24 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio25 = 25, /**< gpio_gpio 25 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio26 = 26, /**< gpio_gpio 26 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio27 = 27, /**< gpio_gpio 27 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio28 = 28, /**< gpio_gpio 28 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio29 = 29, /**< gpio_gpio 29 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio30 = 30, /**< gpio_gpio 30 */
+  kTopEarlgreyPinmuxPeripheralInGpioGpio31 = 31, /**< gpio_gpio 31 */
+  kTopEarlgreyPinmuxPeripheralInLast = 31, /**< \internal Last valid peripheral input */
+} top_earlgrey_pinmux_peripheral_in_t;
+
+/**
+ * Pinmux MIO Input Selector.
+ */
+typedef enum top_earlgrey_pinmux_insel {
+  kTopEarlgreyPinmuxInselConstantZero = 0, /**< Tie constantly to zero */
+  kTopEarlgreyPinmuxInselConstantOne = 1, /**< Tie constantly to one */
+  kTopEarlgreyPinmuxInselMio0 = 2, /**< MIO Pad 0 */
+  kTopEarlgreyPinmuxInselMio1 = 3, /**< MIO Pad 1 */
+  kTopEarlgreyPinmuxInselMio2 = 4, /**< MIO Pad 2 */
+  kTopEarlgreyPinmuxInselMio3 = 5, /**< MIO Pad 3 */
+  kTopEarlgreyPinmuxInselMio4 = 6, /**< MIO Pad 4 */
+  kTopEarlgreyPinmuxInselMio5 = 7, /**< MIO Pad 5 */
+  kTopEarlgreyPinmuxInselMio6 = 8, /**< MIO Pad 6 */
+  kTopEarlgreyPinmuxInselMio7 = 9, /**< MIO Pad 7 */
+  kTopEarlgreyPinmuxInselMio8 = 10, /**< MIO Pad 8 */
+  kTopEarlgreyPinmuxInselMio9 = 11, /**< MIO Pad 9 */
+  kTopEarlgreyPinmuxInselMio10 = 12, /**< MIO Pad 10 */
+  kTopEarlgreyPinmuxInselMio11 = 13, /**< MIO Pad 11 */
+  kTopEarlgreyPinmuxInselMio12 = 14, /**< MIO Pad 12 */
+  kTopEarlgreyPinmuxInselMio13 = 15, /**< MIO Pad 13 */
+  kTopEarlgreyPinmuxInselMio14 = 16, /**< MIO Pad 14 */
+  kTopEarlgreyPinmuxInselMio15 = 17, /**< MIO Pad 15 */
+  kTopEarlgreyPinmuxInselMio16 = 18, /**< MIO Pad 16 */
+  kTopEarlgreyPinmuxInselMio17 = 19, /**< MIO Pad 17 */
+  kTopEarlgreyPinmuxInselMio18 = 20, /**< MIO Pad 18 */
+  kTopEarlgreyPinmuxInselMio19 = 21, /**< MIO Pad 19 */
+  kTopEarlgreyPinmuxInselMio20 = 22, /**< MIO Pad 20 */
+  kTopEarlgreyPinmuxInselMio21 = 23, /**< MIO Pad 21 */
+  kTopEarlgreyPinmuxInselMio22 = 24, /**< MIO Pad 22 */
+  kTopEarlgreyPinmuxInselMio23 = 25, /**< MIO Pad 23 */
+  kTopEarlgreyPinmuxInselMio24 = 26, /**< MIO Pad 24 */
+  kTopEarlgreyPinmuxInselMio25 = 27, /**< MIO Pad 25 */
+  kTopEarlgreyPinmuxInselMio26 = 28, /**< MIO Pad 26 */
+  kTopEarlgreyPinmuxInselMio27 = 29, /**< MIO Pad 27 */
+  kTopEarlgreyPinmuxInselMio28 = 30, /**< MIO Pad 28 */
+  kTopEarlgreyPinmuxInselMio29 = 31, /**< MIO Pad 29 */
+  kTopEarlgreyPinmuxInselMio30 = 32, /**< MIO Pad 30 */
+  kTopEarlgreyPinmuxInselMio31 = 33, /**< MIO Pad 31 */
+  kTopEarlgreyPinmuxInselLast = 33, /**< \internal Last valid insel value */
+} top_earlgrey_pinmux_insel_t;
+
+/**
+ * Pinmux MIO Output.
+ */
+typedef enum top_earlgrey_pinmux_mio_out {
+  kTopEarlgreyPinmuxMioOut0 = 0, /**< MIO Pad 0 */
+  kTopEarlgreyPinmuxMioOut1 = 1, /**< MIO Pad 1 */
+  kTopEarlgreyPinmuxMioOut2 = 2, /**< MIO Pad 2 */
+  kTopEarlgreyPinmuxMioOut3 = 3, /**< MIO Pad 3 */
+  kTopEarlgreyPinmuxMioOut4 = 4, /**< MIO Pad 4 */
+  kTopEarlgreyPinmuxMioOut5 = 5, /**< MIO Pad 5 */
+  kTopEarlgreyPinmuxMioOut6 = 6, /**< MIO Pad 6 */
+  kTopEarlgreyPinmuxMioOut7 = 7, /**< MIO Pad 7 */
+  kTopEarlgreyPinmuxMioOut8 = 8, /**< MIO Pad 8 */
+  kTopEarlgreyPinmuxMioOut9 = 9, /**< MIO Pad 9 */
+  kTopEarlgreyPinmuxMioOut10 = 10, /**< MIO Pad 10 */
+  kTopEarlgreyPinmuxMioOut11 = 11, /**< MIO Pad 11 */
+  kTopEarlgreyPinmuxMioOut12 = 12, /**< MIO Pad 12 */
+  kTopEarlgreyPinmuxMioOut13 = 13, /**< MIO Pad 13 */
+  kTopEarlgreyPinmuxMioOut14 = 14, /**< MIO Pad 14 */
+  kTopEarlgreyPinmuxMioOut15 = 15, /**< MIO Pad 15 */
+  kTopEarlgreyPinmuxMioOut16 = 16, /**< MIO Pad 16 */
+  kTopEarlgreyPinmuxMioOut17 = 17, /**< MIO Pad 17 */
+  kTopEarlgreyPinmuxMioOut18 = 18, /**< MIO Pad 18 */
+  kTopEarlgreyPinmuxMioOut19 = 19, /**< MIO Pad 19 */
+  kTopEarlgreyPinmuxMioOut20 = 20, /**< MIO Pad 20 */
+  kTopEarlgreyPinmuxMioOut21 = 21, /**< MIO Pad 21 */
+  kTopEarlgreyPinmuxMioOut22 = 22, /**< MIO Pad 22 */
+  kTopEarlgreyPinmuxMioOut23 = 23, /**< MIO Pad 23 */
+  kTopEarlgreyPinmuxMioOut24 = 24, /**< MIO Pad 24 */
+  kTopEarlgreyPinmuxMioOut25 = 25, /**< MIO Pad 25 */
+  kTopEarlgreyPinmuxMioOut26 = 26, /**< MIO Pad 26 */
+  kTopEarlgreyPinmuxMioOut27 = 27, /**< MIO Pad 27 */
+  kTopEarlgreyPinmuxMioOut28 = 28, /**< MIO Pad 28 */
+  kTopEarlgreyPinmuxMioOut29 = 29, /**< MIO Pad 29 */
+  kTopEarlgreyPinmuxMioOut30 = 30, /**< MIO Pad 30 */
+  kTopEarlgreyPinmuxMioOut31 = 31, /**< MIO Pad 31 */
+  kTopEarlgreyPinmuxMioOutLast = 31, /**< \internal Last valid mio output */
+} top_earlgrey_pinmux_mio_out_t;
+
+/**
+ * Pinmux Peripheral Output Selector.
+ */
+typedef enum top_earlgrey_pinmux_outsel {
+  kTopEarlgreyPinmuxOutselConstantZero = 0, /**< Tie constantly to zero */
+  kTopEarlgreyPinmuxOutselConstantOne = 1, /**< Tie constantly to one */
+  kTopEarlgreyPinmuxOutselConstantHighZ = 2, /**< Tie constantly to high-Z */
+  kTopEarlgreyPinmuxOutselGpioGpio0 = 3, /**< gpio_gpio 0 */
+  kTopEarlgreyPinmuxOutselGpioGpio1 = 4, /**< gpio_gpio 1 */
+  kTopEarlgreyPinmuxOutselGpioGpio2 = 5, /**< gpio_gpio 2 */
+  kTopEarlgreyPinmuxOutselGpioGpio3 = 6, /**< gpio_gpio 3 */
+  kTopEarlgreyPinmuxOutselGpioGpio4 = 7, /**< gpio_gpio 4 */
+  kTopEarlgreyPinmuxOutselGpioGpio5 = 8, /**< gpio_gpio 5 */
+  kTopEarlgreyPinmuxOutselGpioGpio6 = 9, /**< gpio_gpio 6 */
+  kTopEarlgreyPinmuxOutselGpioGpio7 = 10, /**< gpio_gpio 7 */
+  kTopEarlgreyPinmuxOutselGpioGpio8 = 11, /**< gpio_gpio 8 */
+  kTopEarlgreyPinmuxOutselGpioGpio9 = 12, /**< gpio_gpio 9 */
+  kTopEarlgreyPinmuxOutselGpioGpio10 = 13, /**< gpio_gpio 10 */
+  kTopEarlgreyPinmuxOutselGpioGpio11 = 14, /**< gpio_gpio 11 */
+  kTopEarlgreyPinmuxOutselGpioGpio12 = 15, /**< gpio_gpio 12 */
+  kTopEarlgreyPinmuxOutselGpioGpio13 = 16, /**< gpio_gpio 13 */
+  kTopEarlgreyPinmuxOutselGpioGpio14 = 17, /**< gpio_gpio 14 */
+  kTopEarlgreyPinmuxOutselGpioGpio15 = 18, /**< gpio_gpio 15 */
+  kTopEarlgreyPinmuxOutselGpioGpio16 = 19, /**< gpio_gpio 16 */
+  kTopEarlgreyPinmuxOutselGpioGpio17 = 20, /**< gpio_gpio 17 */
+  kTopEarlgreyPinmuxOutselGpioGpio18 = 21, /**< gpio_gpio 18 */
+  kTopEarlgreyPinmuxOutselGpioGpio19 = 22, /**< gpio_gpio 19 */
+  kTopEarlgreyPinmuxOutselGpioGpio20 = 23, /**< gpio_gpio 20 */
+  kTopEarlgreyPinmuxOutselGpioGpio21 = 24, /**< gpio_gpio 21 */
+  kTopEarlgreyPinmuxOutselGpioGpio22 = 25, /**< gpio_gpio 22 */
+  kTopEarlgreyPinmuxOutselGpioGpio23 = 26, /**< gpio_gpio 23 */
+  kTopEarlgreyPinmuxOutselGpioGpio24 = 27, /**< gpio_gpio 24 */
+  kTopEarlgreyPinmuxOutselGpioGpio25 = 28, /**< gpio_gpio 25 */
+  kTopEarlgreyPinmuxOutselGpioGpio26 = 29, /**< gpio_gpio 26 */
+  kTopEarlgreyPinmuxOutselGpioGpio27 = 30, /**< gpio_gpio 27 */
+  kTopEarlgreyPinmuxOutselGpioGpio28 = 31, /**< gpio_gpio 28 */
+  kTopEarlgreyPinmuxOutselGpioGpio29 = 32, /**< gpio_gpio 29 */
+  kTopEarlgreyPinmuxOutselGpioGpio30 = 33, /**< gpio_gpio 30 */
+  kTopEarlgreyPinmuxOutselGpioGpio31 = 34, /**< gpio_gpio 31 */
+  kTopEarlgreyPinmuxOutselLast = 34, /**< \internal Last valid outsel value */
+} top_earlgrey_pinmux_outsel_t;
+
 // Header Extern Guard
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/util/topgen/c.py b/util/topgen/c.py
index 17ce546..6edb247 100644
--- a/util/topgen/c.py
+++ b/util/topgen/c.py
@@ -137,6 +137,7 @@
         self._init_plic_targets()
         self._init_plic_mapping()
         self._init_alert_mapping()
+        self._init_pinmux_mapping()
 
     def modules(self):
         return [(m["name"],
@@ -276,3 +277,82 @@
         self.alert_sources = sources
         self.alert_alerts = alerts
         self.alert_mapping = alert_mapping
+
+    def _init_pinmux_mapping(self):
+        """Generate C enums for addressing pinmux registers and in/out selects.
+
+        Inputs are connected in order: inouts, then inputs
+        Outputs are connected in order: inouts, then outputs
+
+        Inputs:
+        - Peripheral chooses register field (pinmux_peripheral_in)
+        - Insel chooses MIO input (pinmux_insel)
+
+        Outputs:
+        - MIO chooses register field (pinmux_mio_out)
+        - Outsel chooses peripheral output (pinmux_outsel)
+
+        Insel and outsel have some special values which are captured here too.
+        """
+        pinmux_info = self.top["pinmux"]
+
+        # Peripheral Inputs
+        peripheral_in = CEnum(self._top_name +
+                              Name(["pinmux", "peripheral", "in"]))
+        for signal in pinmux_info["inouts"] + pinmux_info["inputs"]:
+            if "width" in signal and int(signal["width"]) != 1:
+                for i in range(int(signal["width"])):
+                    name = Name.from_snake_case(
+                        signal["name"]) + Name([str(i)])
+                    peripheral_in.add_constant(name,
+                                               docstring="{} {}".format(
+                                                   signal["name"], i))
+            else:
+                peripheral_in.add_constant(Name.from_snake_case(
+                    signal["name"]),
+                                           docstring=signal["name"])
+        peripheral_in.add_last_constant("Last valid peripheral input")
+
+        # Pinmux Input Selects
+        insel = CEnum(self._top_name + Name(["pinmux", "insel"]))
+        insel.add_constant(Name(["constant", "zero"]),
+                           docstring="Tie constantly to zero")
+        insel.add_constant(Name(["constant", "one"]),
+                           docstring="Tie constantly to one")
+        for i in range(int(pinmux_info["num_mio"])):
+            insel.add_constant(Name(["mio", str(i)]),
+                               docstring="MIO Pad {}".format(i))
+        insel.add_last_constant("Last valid insel value")
+
+        # MIO Outputs
+        mio_out = CEnum(self._top_name + Name(["pinmux", "mio", "out"]))
+        for i in range(int(pinmux_info["num_mio"])):
+            mio_out.add_constant(Name([str(i)]),
+                                 docstring="MIO Pad {}".format(i))
+        mio_out.add_last_constant("Last valid mio output")
+
+        # Pinmux Output Selects
+        outsel = CEnum(self._top_name + Name(["pinmux", "outsel"]))
+        outsel.add_constant(Name(["constant", "zero"]),
+                            docstring="Tie constantly to zero")
+        outsel.add_constant(Name(["constant", "one"]),
+                            docstring="Tie constantly to one")
+        outsel.add_constant(Name(["constant", "high", "z"]),
+                            docstring="Tie constantly to high-Z")
+        for signal in pinmux_info["inouts"] + pinmux_info["outputs"]:
+            if "width" in signal and int(signal["width"]) != 1:
+                for i in range(int(signal["width"])):
+                    name = Name.from_snake_case(
+                        signal["name"]) + Name([str(i)])
+                    outsel.add_constant(name,
+                                        docstring="{} {}".format(
+                                            signal["name"], i))
+            else:
+                outsel.add_constant(Name.from_snake_case(signal["name"]),
+                                    docstring=signal["name"])
+        outsel.add_last_constant("Last valid outsel value")
+
+        self.pinmux_peripheral_in = peripheral_in
+        self.pinmux_insel = insel
+        self.pinmux_mio_out = mio_out
+        self.pinmux_outsel = outsel