re-add uart into m_class
[pinmux.git] / src / spec / m_class.py
index 8c176423b19b76a7c33842ebfb059ae4dca194eb..4e28a444c954aba41b53ebbff5049ac5664d5037 100644 (file)
 #!/usr/bin/env python
 
-from spec.interfaces import Pinouts
-
-from spec.ifaceprint import display, display_fns, check_functions
-from spec.ifaceprint import display_fixed
+from spec.base import PinSpec
 
 
 def pinspec():
-    pinbanks = {'A': 16,
-                'B': 28,
-                'C': 24,
-                'D': 24,
-                'E': 24,
-                'F': 10,
-                'G': 32,
+    pinbanks = {'A': (16, 4),
+                'B': (28, 4),
+                'C': (24, 4),
+                'D': (24, 4),
+                'E': (24, 4),
+                'F': (10, 4),
+                'G': (32, 4),
                 }
-    bankspec = {}
-    pkeys = sorted(pinbanks.keys())
-    offs = 0
-    for kn in pkeys:
-        bankspec[kn] = offs
-        offs += pinbanks[kn]
-
-    pinouts = Pinouts(bankspec)
-
-    # Bank A, 0-15
-    pinouts.gpio("", ('A', 0), "A", 0, 16, 0)
-    pinouts.spi("0", ('A', 0), "A", 3)
-    pinouts.uartfull("1", ('A', 0), "A", 2)
-    pinouts.i2c("0", ('A', 4), "A", 2)
-    pinouts.emmc("", ('A', 0), "A", 1)
-    #pinouts.uart("0", ('A', 14), "A", 1)
-    pinouts.spi("1", ('A', 6), "A", 2)
-    pinouts.eint("", ('A', 10), "A", 0, 6)
-    pinouts.eint("", ('A', 4), "A", 0, 6, mux=3)
-    pinouts.sdmmc("0", ('A', 10), "A", 2)
-    pinouts.jtag("0", ('A', 10), "A", 3)
-    pinouts.uart("0", ('A', 14), "A", 3)
-
-    # Bank B, 16-47
-    pinouts.gpio("", ('B', 0), "B", 0, 28, 0)
-    pinouts.rgbttl("0", ('B', 0), "B", 1)
-    pinouts.spi("0", ('B', 12), "B", 2)
-    pinouts.quadspi("", ('B', 4), "B", 2, limit=4)
-    pinouts.uart("1", ('B', 16), "B", 2)
-    pinouts.i2c("2", ('B', 18), "B", 2)
-    pinouts.pwm("", ('B', 9), "B", 0, 1, mux=2)
-    pinouts.pwm("", ('B', 20), "B", 1, 2, mux=2)
-    pinouts.sdmmc("0", ('B', 22), "B", 2)
-    pinouts.eint("", ('B', 0), "B", 6, 4, mux=3)
-    pinouts.flexbus2("", ('B', 4), "B", 3)
-    pinouts.i2c("0", ('B', 0), "B", 2)
-    pinouts.uart("0", ('B', 2), "B", 2)
-    pinouts.uart("2", ('B', 10), "B", 2)
-
-    # Bank C, 48-71
-    pinouts.gpio("", ("C", 0), "C", 0, 24, 0)
-    pinouts.ulpi("0", ('C', 0), "C", 1)
-    pinouts.ulpi("1", ('C', 12), "C", 1)
-    pinouts.spi("1", ('C', 8), "C", 2)
-    #pinouts.spi("1", ('C', 28), "C", 2)
-    pinouts.uartfull("0", ('C', 20), "C", 3)
-    pinouts.eint("", ('C', 0), "C", 10, 8, mux=3)
-    pinouts.jtag("1", ('C', 8), "C", 3)
-    pinouts.eint("", ('C', 12), "C", 22, 8, mux=3)
-    pinouts.uart("0", ('C', 22), "C", 2)
-    pinouts.i2s("", ('C', 13), "C", 2)
-    pinouts.pwm("", ('C', 21), "C", 2, 1, mux=2)
-
-    # Bank D, 72-96
-
-    # ok this is slightly complicated, basically there's extra
-    # functions that we want to be on the same pin (but a different mux)
-    # because their use is mutually-exclusive.  you can't have FB_TS
-    # at the same time as FB_ALE for example.  FB_BWE2 even has two
-    # mutually exclusive functions.  these extra functions are
-    # specified here, so that when e.g. FB_BWE2 has been positioned,
-    # FB_A0 will be placed in bank d, mux column 3, *on the same pin*.
-    # this saves messing about, because if FB_BWE2 moved to a
-    # different pin so would FB_A0 (and FB_CS2) likewise have to be
-    # moved.  and the rest.
-    flexspec = {
-        'FB_TS': ('FB_ALE', 2, "D"),
-        'FB_CS2': ('FB_BWE2', 2, "D"),
-        'FB_A0': ('FB_BWE2', 3, "D"),
-        'FB_CS3': ('FB_BWE3', 2, "D"),
-        'FB_A1': ('FB_BWE3', 3, "D"),
-        'FB_TBST': ('FB_OE', 2, "D"),
-        'FB_TSIZ0': ('FB_BWE0', 2, "D"),
-        'FB_TSIZ1': ('FB_BWE1', 2, "D"),
-    }
-    #pinouts.mcu8080("", 72, "D", 1)
-    pinouts.gpio("", ('D', 0), "D", 0, 24, 0)
-    pinouts.flexbus1("", ('D', 0), "D", 1, spec=flexspec)
-    pinouts.i2c("1", ('D', 8), "D", 3)
-    pinouts.pwm("", ('D', 21), "D", 0, 3, mux=1)
-    pinouts.i2c("0", ('D', 10), "D", 3)
-    pinouts.i2c("2", ('D', 19), "D", 2)
-    pinouts.uartfull("0", ('D', 0), "D", 2)
-    pinouts.uart("1", ('D', 21), "D", 2)
-    pinouts.uart("2", ('D', 13), "D", 2)
-    pinouts.eint("", ('D', 19), "D", 18, 4, mux=3)
-    pinouts.eint("", ('D', 23), "D", 9, 1, mux=3)
-    pinouts.eint("", ('D', 13), "D", 5, 4, mux=3)
-    pinouts.eint("", ('D', 0), "D", 30, 2, mux=3)
-    pinouts.i2c("1", ('D', 2), "D", 3)
-    pinouts.sdmmc("1", ('D', 4), "D", 2)
-
-    # Bank E
-    pinouts.gpio("", ('E', 0), "E", 0, 24, 0)
-    pinouts.flexbus2("", ('E', 0), "E", 1)
-    pinouts.sdmmc("1", ('E', 0), "E", 2)
-    pinouts.sdmmc("2", ('E', 8), "E", 2)
-    pinouts.quadspi("", ('E', 18), "E", 2)
-    pinouts.uartfull("1", ('E', 14), "E", 2)
-    pinouts.i2c("1", ('E', 6), "E", 2)
-    pinouts.eint("", ('E', 0), "E", 10, 8, mux=3)
-    pinouts.eint("", ('E', 8), "E", 22, 6, mux=3)
-    pinouts.emmc("", ('E', 14), "E", 3)
-
-    # Bank F
-    pinouts.gpio("", ('F', 0), "F", 0, 10, 0)
-    pinouts.i2s("", ('F', 0), "F", 1)
-    pinouts.i2c("0", ('F', 6), "F", 2)
-    pinouts.pwm("", ('F', 8), "F", 0, 1, mux=2)
-    pinouts.pwm("", ('F', 9), "F", 1, 1, mux=2)
-    pinouts.uart("2", ('F', 8), "F", 1)
-    pinouts.sdmmc("2", ('F', 0), "F", 2)
-    pinouts.eint("", ('F', 0), "F", 18, 4, mux=3)
-    pinouts.pwm("", ('F', 4), "F", 2, 1, mux=3)
-    pinouts.eint("", ('F', 5), "F", 7, 1, mux=3)
-    pinouts.eint("", ('F', 6), "F", 28, 4, mux=3)
-
-    # Bank G
-    pinouts.gpio("", ('G', 0), "G", 0, 32, 0)
-    pinouts.rgmii("", ('G', 0), "G", 1)
-    pinouts.ulpi("2", ('G', 20), "G", 1)
-    pinouts.rgbttl("1", ('G', 0), "G", 2)
-    pinouts.quadspi("", ('G', 26), "G", 3)
-    pinouts.flexbus2("", ('G', 0), "G", 3)
-    pinouts.sdmmc("1", ('G', 24), "G", 3, limit=2)
-    pinouts.sdmmc("1", ('G', 28), "G", 2, start=2)
-
-    print ("""# Pinouts (PinMux)
-auto-generated by [[pinouts.py]]
-
-[[!toc  ]]
-""")
-    display(pinouts)
-
-    print ("\n# Pinouts (Fixed function)\n")
-
     fixedpins = {
         'DDR3': [
-            'SDQ0',
-            'SDQ1',
-            'SDQ2',
-            'SDQ3',
-            'SDQ4',
-            'SDQ5',
-            'SDQ6',
-            'SDQ7',
-            'SDQ8',
-            'SDQ9',
-            'SDQ10',
-            'SDQ11',
-            'SDQ12',
-            'SDQ13',
-            'SDQ14',
-            'SDQ15',
-            'SDQ16',
-            'SDQ17',
-            'SDQ18',
-            'SDQ19',
-            'SDQ20',
-            'SDQ21',
-            'SDQ22',
-            'SDQ23',
-            'SDQ24',
-            'SDQ25',
-            'SDQ26',
-            'SDQ27',
-            'SDQ28',
-            'SDQ29',
-            'SDQ30',
-            'SDQ31',
-            'SVREF0',
-            'SVREF1',
-            'SVREF2',
-            'SVREF3',
-            'SDQS0',
-            'SDQS0#',
-            'SDQS1',
-            'SDQS1#',
-            'SDQS2',
-            'SDQS2#',
-            'SDQS3',
-            'SDQS3#',
-            'SDQM0',
-            'SDQM1',
-            'SDQM2',
-            'SDQM3',
-            'SCK#',
-            'SCK',
-            'SCKE0',
-            'SCKE1',
-            'SA0',
-            'SA1',
-            'SA2',
-            'SA3',
-            'SA4',
-            'SA5',
-            'SA6',
-            'SA7',
-            'SA8',
-            'SA9',
-            'SA10',
-            'SA11',
-            'SA12',
-            'SA13',
-            'SA14',
-            'SBA0',
-            'SBA1',
-            'SBA2',
-            'SWE',
-            'SCAS',
-            'SRAS',
-            'SCS0',
-            'SCS1',
-            'SZQ',
-            'SRST',
-            'SDBG0',
-            'SDBG1',
-            'ADBG',
-            'ODT0',
-            'ODT1'],
+            'SDQ0', 'SDQ1', 'SDQ2', 'SDQ3',
+            'SDQ4', 'SDQ5', 'SDQ6', 'SDQ7',
+            'SDQ8', 'SDQ9', 'SDQ10', 'SDQ11',
+            'SDQ12', 'SDQ13', 'SDQ14', 'SDQ15',
+            'SDQ16', 'SDQ17', 'SDQ18', 'SDQ19',
+            'SDQ20', 'SDQ21', 'SDQ22', 'SDQ23',
+            'SDQ24', 'SDQ25', 'SDQ26', 'SDQ27',
+            'SDQ28', 'SDQ29', 'SDQ30', 'SDQ31',
+            'SVREF0', 'SVREF1', 'SVREF2', 'SVREF3',
+            'SDQS0', 'SDQS0#', 'SDQS1', 'SDQS1#',
+            'SDQS2', 'SDQS2#', 'SDQS3', 'SDQS3#',
+            'SDQM0', 'SDQM1', 'SDQM2', 'SDQM3',
+            'SCK#', 'SCK', 'SCKE0', 'SCKE1',
+            'SA0', 'SA1', 'SA2', 'SA3',
+            'SA4', 'SA5', 'SA6', 'SA7',
+            'SA8', 'SA9', 'SA10', 'SA11',
+            'SA12', 'SA13', 'SA14',
+            'SBA0', 'SBA1', 'SBA2',
+            'SWE', 'SCAS', 'SRAS', 'SCS0',
+            'SCS1', 'SZQ', 'SRST',
+            'SDBG0', 'SDBG1', 'ADBG',
+            'ODT0', 'ODT1'],
         'CTRL_SYS': [
-            'TEST',
-            'JTAG_SEL',
-            'UBOOT_SEL',
-            'NMI#',
-            'RESET#',
-            'CLK24M_IN',
-            'CLK24M_OUT',
-            'PLLTEST',
-            'PLLREGIO',
-            'PLLVP25',
-            'PLLDV',
-            'PLLVREG',
-            'PLLGND',
+            'TEST', 'JTAG_SEL', 'UBOOT_SEL',
+            'NMI#', 'RESET#', 'CLK24M_IN', 'CLK24M_OUT',
+            'PLLTEST', 'PLLREGIO', 'PLLVP25',
+            'PLLDV', 'PLLVREG', 'PLLGND',
         ],
         'POWER_DRAM': [
-            'VCC0_DRAM',
-            'VCC1_DRAM',
-            'VCC2_DRAM',
-            'VCC3_DRAM',
-            'VCC4_DRAM',
-            'VCC5_DRAM',
-            'VCC6_DRAM',
-            'VCC7_DRAM',
-            'VCC8_DRAM',
-            'VCC9_DRAM',
-            'GND0_DRAM',
-            'GND1_DRAM',
-            'GND2_DRAM',
-            'GND3_DRAM',
-            'GND4_DRAM',
-            'GND5_DRAM',
-            'GND6_DRAM',
-            'GND7_DRAM',
-            'GND8_DRAM',
-            'GND9_DRAM',
+            'VCC0_DRAM', 'VCC1_DRAM', 'VCC2_DRAM', 'VCC3_DRAM',
+            'VCC4_DRAM', 'VCC5_DRAM', 'VCC6_DRAM', 'VCC7_DRAM',
+            'VCC8_DRAM', 'VCC9_DRAM',
+            'GND0_DRAM', 'GND1_DRAM', 'GND2_DRAM', 'GND3_DRAM',
+            'GND4_DRAM', 'GND5_DRAM', 'GND6_DRAM', 'GND7_DRAM',
+            'GND8_DRAM', 'GND9_DRAM',
         ],
         'POWER_CPU': [
-            'VDD0_CPU',
-            'VDD1_CPU',
-            'VDD2_CPU',
-            'VDD3_CPU',
-            'VDD4_CPU',
-            'VDD5_CPU',
-            'GND0_CPU',
-            'GND1_CPU',
-            'GND2_CPU',
-            'GND3_CPU',
-            'GND4_CPU',
-            'GND5_CPU',
+            'VDD0_CPU', 'VDD1_CPU', 'VDD2_CPU',
+            'VDD3_CPU', 'VDD4_CPU', 'VDD5_CPU',
+            'GND0_CPU', 'GND1_CPU', 'GND2_CPU',
+            'GND3_CPU', 'GND4_CPU', 'GND5_CPU',
         ],
         'POWER_DLL': [
-            'VDD0_DLL',
-            'VDD1_DLL',
-            'VDD2_DLL',
-            'GND0_DLL',
-            'GND1_DLL',
-            'GND2_DLL',
+            'VDD0_DLL', 'VDD1_DLL', 'VDD2_DLL',
+            'GND0_DLL', 'GND1_DLL', 'GND2_DLL',
         ],
         'POWER_INT': [
-            'VDD0_INT',
-            'VDD1_INT',
-            'VDD2_INT',
-            'VDD3_INT',
-            'VDD4_INT',
-            'VDD5_INT',
-            'VDD6_INT',
-            'VDD7_INT',
-            'VDD8_INT',
-            'VDD9_INT',
-            'GND0_INT',
-            'GND1_INT',
-            'GND2_INT',
-            'GND3_INT',
-            'GND4_INT',
-            'GND5_INT',
-            'GND6_INT',
-            'GND7_INT',
-            'GND8_INT',
-            'GND9_INT',
+            'VDD0_INT', 'VDD1_INT', 'VDD2_INT', 'VDD3_INT', 'VDD4_INT',
+            'VDD5_INT', 'VDD6_INT', 'VDD7_INT', 'VDD8_INT', 'VDD9_INT',
+            'GND0_INT', 'GND1_INT', 'GND2_INT', 'GND3_INT', 'GND4_INT',
+            'GND5_INT', 'GND6_INT', 'GND7_INT', 'GND8_INT', 'GND9_INT',
         ],
         'POWER_GPIO': [
-            'VDD_GPIOA',
-            'VDD_GPIOB',
-            'VDD_GPIOC',
-            'VDD_GPIOD',
-            'VDD_GPIOE',
-            'VDD_GPIOF',
+            'VDD_GPIOA', 'VDD_GPIOB', 'VDD_GPIOC',
+            'VDD_GPIOD', 'VDD_GPIOE', 'VDD_GPIOF',
             'VDD_GPIOG',
-            'GND_GPIOA',
-            'GND_GPIOB',
-            'GND_GPIOC',
-            'GND_GPIOD',
-            'GND_GPIOE',
-            'GND_GPIOF',
+            'GND_GPIOA', 'GND_GPIOB', 'GND_GPIOC',
+            'GND_GPIOD', 'GND_GPIOE', 'GND_GPIOF',
             'GND_GPIOG',
         ]}
 
-    fixedpins = display_fixed(fixedpins, len(pinouts))
-
-    print ("""# Functions (PinMux)
-
-auto-generated by [[pinouts.py]]
-""")
-
     function_names = {'EINT': 'External Interrupt',
                       'FB': 'MC68k FlexBus',
                       'IIS': 'I2S Audio',
@@ -347,19 +82,19 @@ auto-generated by [[pinouts.py]]
                       'JTAG1': 'JTAG (same as JTAG0, JTAG_SEL=HIGH)',
                       'LCD': '24-pin RGB/TTL LCD',
                       'RG': 'RGMII Ethernet',
-                      'MMC': 'eMMC 1/2/4/8 pin',
+                      'EMMC': 'eMMC 1/2/4/8 pin',
                       'PWM': 'PWM (pulse-width modulation)',
-                      'SD0': 'SD/MMC 0',
-                      'SD1': 'SD/MMC 1',
-                      'SD2': 'SD/MMC 2',
+                      'MMC0': 'SD/MMC 0',
+                      'MMC1': 'SD/MMC 1',
+                      'MMC2': 'SD/MMC 2',
                       'SPI0': 'SPI (Serial Peripheral Interface) 0',
                       'SPI1': 'SPI (Serial Peripheral Interface) 1',
                       'QSPI': 'Quad SPI (Serial Peripheral Interface) 1',
                       'TWI0': 'I2C 1',
                       'TWI1': 'I2C 2',
                       'TWI2': 'I2C 3',
-                      'UARTQ0': 'UART (TX/RX/CTS/RTS) 0',
-                      'UARTQ1': 'UART (TX/RX/CTS/RTS) 1',
+                      'QUART0': 'UART (TX/RX/CTS/RTS) 0',
+                      'QUART1': 'UART (TX/RX/CTS/RTS) 1',
                       'UART0': 'UART (TX/RX) 0',
                       'UART1': 'UART (TX/RX) 1',
                       'UART2': 'UART (TX/RX) 2',
@@ -368,32 +103,133 @@ auto-generated by [[pinouts.py]]
                       'ULPI2': 'ULPI (USB Low Pin-count) 3',
                       }
 
-    fns = display_fns(bankspec, pinouts, function_names)
-    print
+    ps = PinSpec(pinbanks, fixedpins, function_names)
+
+    # Bank A, 0-15
+    ps.gpio("", ('A', 0), 0, 0, 16)
+    ps.spi("0", ('A', 0), 3)
+    ps.uartfull("1", ('A', 0), 2)
+    ps.i2c("0", ('A', 4), 2)
+    ps.emmc("", ('A', 0), 1)
+    #ps.uart("0", ('A', 14), 1)
+    ps.spi("1", ('A', 6), 2)
+    ps.eint("", ('A', 10), 1, start=0, limit=6)
+    ps.eint("", ('A', 4), 3, start=0, limit=6)
+    ps.sdmmc("0", ('A', 10), 2)
+    ps.jtag("0", ('A', 10), 3)
+    ps.uart("0", ('A', 14), 3)
+
+    # Bank B, 16-47
+    ps.gpio("", ('B', 0), 0, 0, 28)
+    ps.rgbttl("0", ('B', 0), 1)
+    ps.spi("0", ('B', 12), 2)
+    ps.quadspi("", ('B', 4), 2, limit=4)
+    ps.uart("1", ('B', 16), 2)
+    ps.i2c("2", ('B', 18), 2)
+    ps.pwm("", ('B', 9), 2, start=0, limit=1)
+    ps.pwm("", ('B', 20), 2, start=1, limit=2)
+    ps.sdmmc("0", ('B', 22), 2)
+    ps.eint("", ('B', 0), 3, start=6, limit=4)
+    ps.flexbus2("", ('B', 4), 3)
+    ps.i2c("0", ('B', 0), 2)
+    ps.uart("0", ('B', 2), 2)
+    ps.uart("2", ('B', 10), 2)
+
+    # Bank C, 48-71
+    ps.gpio("", ("C", 0), 0, 0, 24)
+    ps.ulpi("0", ('C', 0), 1)
+    ps.ulpi("1", ('C', 12), 1)
+    ps.spi("1", ('C', 8), 2)
+    #ps.spi("1", ('C', 28), 2)
+    ps.uartfull("0", ('C', 20), 3)
+    ps.eint("", ('C', 0), 3, start=10, limit=8)
+    ps.jtag("1", ('C', 8), 3)
+    ps.eint("", ('C', 12), 3, start=22, limit=8)
+    ps.uart("0", ('C', 22), 2)
+    ps.i2s("", ('C', 13), 2)
+    ps.pwm("", ('C', 21), 2, start=2, limit=1)
+
+    # Bank D, 72-96
+
+    # see comment in spec.interfaces.PinGen, this is complicated.
+    flexspec = {
+        'FB_TS': ('FB_ALE', 2),
+        'FB_CS2': ('FB_BWE2', 2),
+        'FB_A0': ('FB_BWE2', 3),
+        'FB_CS3': ('FB_BWE3', 2),
+        'FB_A1': ('FB_BWE3', 3),
+        'FB_TBST': ('FB_OE', 2),
+        'FB_TSIZ0': ('FB_BWE0', 2),
+        'FB_TSIZ1': ('FB_BWE1', 2),
+    }
+    #ps.mcu8080("", 72, 1)
+    ps.gpio("", ('D', 0), 0, 0, 24)
+    ps.flexbus1("", ('D', 0), 1, spec=flexspec)
+    ps.i2c("1", ('D', 8), 3)
+    ps.pwm("", ('D', 21), 1, start=0, limit=3)
+    ps.i2c("0", ('D', 10), 3)
+    ps.i2c("2", ('D', 19), 2)
+    ps.uartfull("0", ('D', 0), 2)
+    ps.uart("1", ('D', 21), 2)
+    ps.uart("2", ('D', 12), 2)
+    ps.eint("", ('D', 19), 3, start=18, limit=4)
+    ps.eint("", ('D', 23), 3, start=9, limit=1)
+    ps.eint("", ('D', 13), 3, start=5, limit=4)
+    ps.eint("", ('D', 0), 3, start=30, limit=2)
+    ps.i2c("1", ('D', 2), 3)
+    ps.sdmmc("1", ('D', 4), 2)
+
+    # Bank E
+    ps.gpio("", ('E', 0), 0, 0, 24)
+    ps.flexbus2("", ('E', 0), 1)
+    ps.sdmmc("1", ('E', 0), 2)
+    ps.sdmmc("2", ('E', 8), 2)
+    ps.quadspi("", ('E', 18), 2)
+    ps.uartfull("1", ('E', 14), 2)
+    ps.i2c("1", ('E', 6), 2)
+    ps.eint("", ('E', 0), 3, start=10, limit=8)
+    ps.eint("", ('E', 8), 3, start=22, limit=6)
+    ps.emmc("", ('E', 14), 3)
 
-    # Scenarios below can be spec'd out as either "find first interface"
-    # by name/number e.g. SPI0, or as "find in bank/mux" which must be
-    # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
-    # EINT and PWM are grouped together, specially, but may still be spec'd
-    # using "BM:Name".  Pins are removed in-order as listed from
-    # lists (interfaces, EINTs, PWMs) from available pins.
+    # Bank F
+    ps.gpio("", ('F', 0), 0, 0, 10)
+    ps.i2s("", ('F', 0), 1)
+    ps.i2c("0", ('F', 6), 2)
+    ps.pwm("", ('F', 8), 2, start=0, limit=1)
+    ps.pwm("", ('F', 9), 2, start=1, limit=1)
+    ps.uart("2", ('F', 8), 1)
+    ps.sdmmc("2", ('F', 0), 2)
+    ps.eint("", ('F', 0), 3, start=18, limit=4)
+    ps.pwm("", ('F', 4), 3, start=2, limit=1)
+    ps.eint("", ('F', 5), 3, start=7, limit=1)
+    ps.eint("", ('F', 6), 3, start=28, limit=4)
+
+    # Bank G
+    ps.gpio("", ('G', 0), 0, 0, 32)
+    ps.rgmii("", ('G', 0), 1)
+    ps.ulpi("2", ('G', 20), 1)
+    ps.rgbttl("1", ('G', 0), 2)
+    ps.quadspi("", ('G', 26), 3)
+    ps.flexbus2("", ('G', 0), 3)
+    ps.sdmmc("1", ('G', 24), 3, limit=2)
+    ps.sdmmc("1", ('G', 28), 2, start=2)
 
     # EOMA68 scenario.  not totally complete (some GPIO needed for PMIC)
     # One interface to be connected to the MCU to give RTC and boot/dbg
     # VBUS_EN, OTG_ID etc. are all not included below, there is plenty
     # of spare GPIO.
 
-    eoma68 = ['B1:LCD/22', 'ULPI0/8', 'ULPI1', 'MMC', 'SD0', 'UART1',
-              'TWI2', 'SPI1', 'E2:SD1', ]
+    eoma68 = ['B1:LCD/22', 'ULPI0/8', 'ULPI1', 'EMMC', 'MMC0', 'UART1',
+              'TWI2', 'SPI1', 'E2:MMC1', ]
     eoma68_eint = ['EINT_16', 'EINT_17', 'EINT_18', 'EINT_19']
     eoma68_pwm = ['D1:PWM_2']
     descriptions = {
-        'MMC': 'internal (on Card)',
-        'SD0': 'user-facing: internal (on Card), multiplexed with JTAG0\n'
+        'EMMC': 'internal (on Card)',
+        'MMC0': 'user-facing: internal (on Card), multiplexed with JTAG0\n'
         'and UART0, for debug purposes',
         'TWI2': 'EOMA68-compliance: must be entirely free of devices.\n'
         'Address 0x51 used (externally) for EOMA68 EEPROM Id',
-        'E2:SD1': 'EOMA68-compliance',
+        'E2:MMC1': 'EOMA68-compliance',
         'SPI1': 'EOMA68-compliance',
         'UART1': 'EOMA68-compliance',
         'B1:LCD/22': 'EOMA68-compliance, 18-bit RGB/TTL LCD',
@@ -401,9 +237,7 @@ auto-generated by [[pinouts.py]]
         'ULPI1': 'EOMA68-compliance: dual USB2 Host ULPI PHY'
     }
 
-    unused_pins = check_functions("EOMA68", bankspec, fns, pinouts,
-                                  eoma68, eoma68_eint, eoma68_pwm,
-                                  descriptions)
+    ps.add_scenario("EOMA68", eoma68, eoma68_eint, eoma68_pwm, descriptions)
 
     # Industrial scenario.  not totally complete (some GPIO needed for PMIC)
     # One interface to be connected to the MCU to give RTC, boot/dbg,
@@ -411,19 +245,19 @@ auto-generated by [[pinouts.py]]
     # Focus is on getting as many UARTs, SPIs and TWIs as possible.
     # OTG_ID (if to be used) would require dropping some functions in order
     # to free up GPIO.  LCD could be reduced to 15-bit (freeing 3).
-    # MMC could be reduced to 4-bit-wide, used as SD/MMC (freeing 4).
+    # EMMC could be reduced to 4-bit-wide, used as SD/MMC (freeing 4).
     # QSPI could be used in 1-bit (MOSI/MISO) mode (freeing up 2 more).
 
     industrial = ['D1:FB/17', 'E1:FB/8', 'B1:LCD/22', 'ULPI0/8', 'ULPI1/8',
-                  'MMC', 'B2:SD0',
-                  'JTAG0', 'A3:UART0', 'E2:UARTQ1', 'C3:UARTQ0',
-                  'F2:TWI0', 'D2:TWI1', 'D2:TWI2', 'SPI1', 'QSPI', 'F2:SD2']
+                  'EMMC', 'B2:MMC0',
+                  'JTAG0', 'A3:UART0', 'E2:QUART1', 'C3:QUART0',
+                  'F2:TWI0', 'D2:TWI1', 'D2:TWI2', 'SPI1', 'QSPI', 'F2:MMC2']
     industrial_pwm = ['F2:PWM_0', 'F2:PWM_1', 'D1:PWM_2']
     industrial_eint = ['EINT_24', 'EINT_25', 'EINT_26', 'EINT_27',
                        'EINT_20', 'EINT_21', 'EINT_22', 'EINT_23']
 
-    unused_pins = check_functions("Industrial", bankspec, fns, pinouts,
-                                  industrial, industrial_eint, industrial_pwm)
+    ps.add_scenario("Industrial", industrial, industrial_eint,
+                    industrial_pwm, None)
 
     # Industrial scenario, using an SPI-based LCD instead of RGB/TTL
     # not totally complete (some GPIO needed for PMIC)
@@ -434,10 +268,10 @@ auto-generated by [[pinouts.py]]
     # also possibility of freeing up FlexBus CS# with a little reorg.
 
     industrial = ['D1:FB/17', 'E1:FB/8', 'B2:SPI0', 'ULPI0/8', 'ULPI1/8',
-                  'MMC', 'B2:SD0',
+                  'EMMC', 'B2:MMC0',
                   'JTAG0',
-                  'A3:UART0', 'E2:UARTQ1', 'C3:UARTQ0', 'B2:UART2', 'B2:UART1',
-                  'F2:TWI0', 'D2:TWI1', 'D2:TWI2', 'SPI1', 'QSPI', 'F2:SD2']
+                  'A3:UART0', 'E2:QUART1', 'C3:QUART0', 'B2:UART2', 'B2:UART1',
+                  'F2:TWI0', 'D2:TWI1', 'D2:TWI2', 'SPI1', 'QSPI', 'F2:MMC2']
     industrial_pwm = ['F2:PWM_0', 'F2:PWM_1', 'D1:PWM_2']
     industrial_eint = ['EINT_24', 'EINT_25', 'EINT_26', 'EINT_27',
                        'EINT_20', 'EINT_21', 'EINT_22', 'EINT_23']
@@ -445,20 +279,20 @@ auto-generated by [[pinouts.py]]
         'B2:SPI0': 'Used for 320x240 or 640x480 etc. SPI-based LCD.\n'
         'Frees up large numbers of GPIO from RGB/TTL bank'
     }
-    unused_pins = check_functions("Industrial with SPI-LCD",
-                                  bankspec, fns, pinouts,
-                                  industrial, industrial_eint, industrial_pwm,
-                                  ind_descriptions)
+
+    ps.add_scenario("Industrial with SPI-LCD",
+                    industrial, industrial_eint, industrial_pwm,
+                    ind_descriptions)
 
     # Smartphone / Tablet - basically the same thing
 
     tablet = ['B1:LCD/22', 'ULPI0/8', 'ULPI1/8',
-              'MMC', 'SD0',
+              'EMMC', 'MMC0',
               'F1:IIS',  # I2C Audio
               'TWI1',   # I2C Audio
-              'E2:UARTQ1',  # WIFI/BT
-              'E2:SD1',   # WIFI
-              'C3:UARTQ0',  # GPS
+              'E2:QUART1',  # WIFI/BT
+              'E2:MMC1',   # WIFI
+              'C3:QUART0',  # GPS
               'D2:UART1',
               'D2:UART2',
               'D3:TWI0', 'D2:TWI2', 'SPI1', 'QSPI']
@@ -480,18 +314,18 @@ auto-generated by [[pinouts.py]]
     descriptions = {
         'B1:LCD/22':
         'RGB/TTL LCD, 800x480 or use SN75LVDS83b for up to 1440x900',
-        'MMC': 'eMMC: main internal storage',
+        'EMMC': 'eMMC: main internal storage',
         'ULPI0/8': 'USB-OTG, connect to ULPI OTG PHY (for charging)\n'
                    'as well as USB Host or USB Device',
         'ULPI1/8': 'USB2 Host, connect to ULPI PHY w/and 4-port USB2 Hub\n'
         'for example GL850G or FE1.1. '
         'Connects to 2/3/4G/LTE Modem, 2x USB-Camera (VC0345)',
-        'SD0': 'internal, multiplexed with JTAG0\n'
+        'MMC0': 'internal, multiplexed with JTAG0\n'
                'and UART0, for debug purposes',
         'F1:IIS': 'I2C Audio, connect to AC97 Audio IC',
         'TWI1': 'Connect to AC97 Audio IC',
-        'E2:UARTQ1': 'Connect to BT on AP6234/AP6335',
-        'E2:SD1': 'Connect to WIFI on AP6234/AP6335',
+        'E2:QUART1': 'Connect to BT on AP6234/AP6335',
+        'E2:MMC1': 'Connect to WIFI on AP6234/AP6335',
         'QSPI': 'Boot Storage (connection to companion / debug / boot MCU)\n'
                 'Only actually needs MISO/MOSI, bootstrap loader v. small\n'
                 'Bootstrap loader checks eMMC, USB-OTG, SD/MMC, SPI, etc.',
@@ -526,19 +360,19 @@ auto-generated by [[pinouts.py]]
         'EINT_30': 'OTG_ID',
         'EINT_31': 'Spare?',
     }
-    unused_pins = check_functions("Smartphone / Tablet",
-                                  bankspec, fns, pinouts,
-                                  tablet, tablet_eint, tablet_pwm,
-                                  descriptions)
+
+    ps.add_scenario("Smartphone / Tablet",
+                    tablet, tablet_eint, tablet_pwm,
+                    descriptions)
 
     # Laptop
 
     laptop = ['D1:FB/17', 'E1:FB/8', 'B1:LCD/22', 'ULPI0/8', 'ULPI1/8',
-              'MMC', 'SD0',
+              'EMMC', 'MMC0',
               'F1:IIS',  # I2C Audio
               'TWI1',   # I2C Audio
-              'E2:UARTQ1',  # WIFI/BT
-              'E2:SD2',   # WIFI
+              'E2:QUART1',  # WIFI/BT
+              'E2:MMC2',   # WIFI
               'D2:TWI2', 'QSPI']
     laptop_pwm = ['F2:PWM_0',  # LCD_BACKLIGHT
                   ]
@@ -552,22 +386,22 @@ auto-generated by [[pinouts.py]]
         '10/100 Ethernet PHY.',
         'E1:FB/8': 'FlexBus bus bits 8-15, needed to make a 16-bit bus width',
         'B1:LCD/22': 'RGB/TTL LCD, use SN75LVDS83b for '
-                     'LVDS or SSD2828 for MIPI,\n'
+                     'LVDS or SMMC2828 for MIPI,\n'
         'or a Chrontel CH7039, CH7038, CH7034 or CH7018 for dual\n'
         'display output (eDP/LVDS and HDMI/VGA) '
         'conversion.',
-        'MMC': 'eMMC: main internal storage',
+        'EMMC': 'eMMC: main internal storage',
         'ULPI0/8': 'USB-OTG, connect to ULPI OTG PHY (for charging)\n'
         'as well as USB Host or USB Device',
         'ULPI1/8': 'USB2 Host, connect to ULPI PHY w/and 4-port USB2 Hub\n'
         'for example GL850G or FE1.1. '
         'Connects to USB-Camera (VC0345 and 3x external USB Ports)',
-        'SD0': 'internal, multiplexed with JTAG0\n'
+        'MMC0': 'internal, multiplexed with JTAG0\n'
         'and UART0, for debug purposes',
         'F1:IIS': 'I2C Audio, connect to AC97 Audio IC',
         'TWI1': 'Connect to AC97 Audio IC',
-        'E2:UARTQ1': 'Connect to BT on AP6234/AP6335',
-        'E2:SD2': 'Connect to WIFI on AP6234/AP6335',
+        'E2:QUART1': 'Connect to BT on AP6234/AP6335',
+        'E2:MMC2': 'Connect to WIFI on AP6234/AP6335',
         'QSPI': 'Boot Storage (connection to companion / debug / boot MCU)\n'
         'Only actually needs MISO/MOSI, bootstrap loader v. small\n'
         'Bootstrap loader checks eMMC, USB-OTG, SD/MMC, SPI, etc.\n'
@@ -582,21 +416,20 @@ auto-generated by [[pinouts.py]]
         'EINT_9': 'MCU_INT',
         'EINT_31': 'PMIC_INT',
     }
-    unused_pins = check_functions("Laptop / Netbook",
-                                  bankspec, fns, pinouts,
-                                  laptop, laptop_eint, laptop_pwm,
-                                  descriptions)
+    ps.add_scenario("Laptop / Netbook",
+                    laptop, laptop_eint, laptop_pwm,
+                    descriptions)
 
     # IoT
 
     iot = ['B1:LCD', 'ULPI1/8', 'ULPI0/8',
-           'MMC', 'SD0',
+           'EMMC', 'MMC0',
            'F1:IIS',  # I2C Audio
            #'TWI1',   # I2C Audio
-           'C3:UARTQ0',  # HSPA UART
-           'E2:UARTQ1',  # BT UART
+           'C3:QUART0',  # HSPA UART
+           'E2:QUART1',  # BT UART
            'C2:SPI1',  # HSPI SPI
-           'E2:SD2',   # WIFI
+           'E2:MMC2',   # WIFI
            'D3:TWI0',  # sensors CTP,
            'D2:TWI2', 'QSPI']
     iot_pwm = ['F2:PWM_0',  # LCD_BACKLIGHT
@@ -619,20 +452,20 @@ auto-generated by [[pinouts.py]]
                 ]
     descriptions = {
         'B1:LCD':
-        'RGB/TTL LCD, use SN75LVDS83b for LVDS or SSD2828 for MIPI,\n'
+        'RGB/TTL LCD, use SN75LVDS83b for LVDS or SMMC2828 for MIPI,\n'
         'or a Chrontel CH7039, CH7038, CH7034 or CH7018 for dual\n'
         'display output (eDP/LVDS and HDMI/VGA) '
         'conversion.',
-        'MMC': 'eMMC: main internal storage',
+        'EMMC': 'eMMC: main internal storage',
         'F1:IIS': 'I2C Audio, connect to AC97 Audio IC',
         'ULPI1/8': 'USB-OTG, connect to ULPI OTG PHY (for charging)\n'
                    'as well as USB Host or USB Device',
         'ULPI0/8': 'USB2 Host, connect to ULPI PHY',
-        'SD0': 'internal, multiplexed with JTAG0\n'
+        'MMC0': 'internal, multiplexed with JTAG0\n'
                'and UART0, for debug purposes',
-        'C3:UARTQ0': 'Connect to HSPA UART',
-        'E2:UARTQ1': 'Connect to BT UART',
-        'E2:SD2': 'Connect to WIFI',
+        'C3:QUART0': 'Connect to HSPA UART',
+        'E2:QUART1': 'Connect to BT UART',
+        'E2:MMC2': 'Connect to WIFI',
         'C2:SPI1': 'HSPA SPI',
         'QSPI': 'Boot Storage (connection to companion / debug / boot MCU)\n'
                 'Only actually needs MISO/MOSI, bootstrap loader v. small\n'
@@ -675,23 +508,8 @@ auto-generated by [[pinouts.py]]
         'EINT_30': 'CTP_INT',
         'EINT_31': 'SD_DETN',
     }
-    unused_pins = check_functions("IoT",
-                                  bankspec, fns, pinouts,
-                                  iot, iot_eint, iot_pwm,
-                                  descriptions)
-
-    print ("""# Reference Datasheets
-
-datasheets and pinout links
-* <http://datasheets.chipdb.org/AMD/8018x/80186/amd-80186.pdf>
-* <http://hands.com/~lkcl/eoma/shenzen/frida/FRD144A2701.pdf>
-* <http://pinouts.ru/Memory/sdcard_pinout.shtml>
-* p8 <http://www.onfi.org/~/media/onfi/specs/onfi_2_0_gold.pdf?la=en>
-* <https://www.heyrick.co.uk/blog/files/datasheets/dm9000aep.pdf>
-* <http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4393.pdf>
-* <https://www.nxp.com/docs/en/data-sheet/MCF54418.pdf>
-* ULPI OTG PHY, ST <http://www.st.com/en/interfaces-and-transceivers/stulpi01a.html>
-* ULPI OTG PHY, TI TUSB1210 <http://ti.com/product/TUSB1210/>
-""")
-
-    return pinouts, bankspec, pinbanks, fixedpins
+    ps.add_scenario("IoT",
+                    iot, iot_eint, iot_pwm,
+                    descriptions)
+
+    return ps