servo: Cleanup EC3PO interfaces

There were some hard-code rules to detect the case for USB PD on servo
v2. As servo v2 doesn't have a dedicated UART for USB PD. It requires
repurposing JTAGS pins for USB PD UART instead. Only the boards with
USBPD define the 'usbpd_uart_pty'.

This change removes the rules and defines the corresponding raw uart
in the servo_interfaces. If no control defines the raw uart (the case
of USB PD), it simply doesn't initialize the interface, as it is
expected that no one will use the raw uart and its EC3PO uart.

BUG=b:37473185
TEST=On servo v2, started servod on Reef, verified EC3PO UART for EC,
and no EC3PO UART for USB PD.

Change-Id: If1ed227ca92fa2245605551e62db1a649bc04b35
Reviewed-on: https://chromium-review.googlesource.com/489321
Commit-Ready: Wai-Hong Tam <waihong@google.com>
Tested-by: Wai-Hong Tam <waihong@google.com>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
diff --git a/servo/servo_interfaces.py b/servo/servo_interfaces.py
index e63401f..e514a73 100644
--- a/servo/servo_interfaces.py
+++ b/servo/servo_interfaces.py
@@ -22,15 +22,22 @@
 # Dummy interface 4,5 == SPI via flashrom
 # ec3po_uart interface 8,9 == usbpd console, ec console.  Applicable to servo v3
 # as well.
-EC3PO_USBPD_INTERFACE_NUM = 8
-EC3PO_EC_INTERFACE_NUM = 9
 SERVO_V2_DEFAULTS = [(0x18d1, 0x5002)]
 for vid, pid in SERVO_V2_DEFAULTS:
   INTERFACE_DEFAULTS[vid][pid] = \
-    ['ftdi_dummy', 'ftdi_i2c', 'ftdi_uart', 'ftdi_uart', 'ftdi_dummy',
-     'ftdi_dummy', 'ftdi_uart', 'ftdi_uart',
-     {'name': 'ec3po_uart'},
-     {'name': 'ec3po_uart'}]
+    ['ftdi_dummy',
+     'ftdi_i2c',
+     'ftdi_uart',
+     'ftdi_uart',
+     'ftdi_dummy',
+     'ftdi_dummy',
+     'ftdi_uart',
+     'ftdi_uart',
+     {'name': 'ec3po_uart',
+      'raw_pty': 'raw_usbpd_uart_pty'},
+     {'name': 'ec3po_uart',
+      'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 # servo v3
 SERVO_V3_DEFAULTS = [(0x18d1, 0x5004)]
@@ -45,9 +52,12 @@
      'dummy',
      {'name': 'bb_uart', 'uart_num': 1},
      {'name': 'bb_uart', 'uart_num': 2},
-     {'name': 'ec3po_uart'},
-     {'name': 'ec3po_uart'},
-     {'name': 'bb_uart', 'uart_num': 4}]
+     {'name': 'ec3po_uart',
+      'raw_pty': 'raw_usbpd_uart_pty'},
+     {'name': 'ec3po_uart',
+      'raw_pty': 'raw_ec_uart_pty'},
+     {'name': 'bb_uart', 'uart_num': 4},
+    ]
 
 INTERFACE_DEFAULTS[0x0403][0x6014] = INTERFACE_DEFAULTS[0x18d1][0x5004]
 
@@ -128,35 +138,50 @@
 # miniservo
 MINISERVO_ID_DEFAULTS = [(0x403, 0x6001), (0x18d1, 0x5000)]
 for vid, pid in MINISERVO_ID_DEFAULTS:
-  INTERFACE_DEFAULTS[vid][pid] = ['ftdi_gpiouart', {'name': 'ec3po_uart'}]
+  INTERFACE_DEFAULTS[vid][pid] = \
+    ['ftdi_gpiouart',
+     {'name': 'ec3po_uart', 'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 SERVO_ID_DEFAULTS.extend(MINISERVO_ID_DEFAULTS)
 
 # Toad
 TOAD_ID_DEFAULTS = [(0x403, 0x6015)]
 for vid, pid in TOAD_ID_DEFAULTS:
-  INTERFACE_DEFAULTS[vid][pid] = ['ftdi_gpiouart', {'name': 'ec3po_uart'}]
+  INTERFACE_DEFAULTS[vid][pid] = \
+    ['ftdi_gpiouart',
+     {'name': 'ec3po_uart', 'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 SERVO_ID_DEFAULTS.extend(TOAD_ID_DEFAULTS)
 
 # Reston
 RESTON_ID_DEFAULTS = [(0x18d1, 0x5007)]
 for vid, pid in RESTON_ID_DEFAULTS:
-  INTERFACE_DEFAULTS[vid][pid] = ['ftdi_gpiouart', {'name': 'ec3po_uart'}]
+  INTERFACE_DEFAULTS[vid][pid] = \
+    ['ftdi_gpiouart',
+     {'name': 'ec3po_uart', 'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 SERVO_ID_DEFAULTS.extend(RESTON_ID_DEFAULTS)
 
 # Fruitpie
 FRUITPIE_ID_DEFAULTS = [(0x18d1, 0x5009)]
 for vid, pid in FRUITPIE_ID_DEFAULTS:
-  INTERFACE_DEFAULTS[vid][pid] = ['ftdi_gpiouart', {'name': 'ec3po_uart'}]
+  INTERFACE_DEFAULTS[vid][pid] = \
+    ['ftdi_gpiouart',
+     {'name': 'ec3po_uart', 'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 SERVO_ID_DEFAULTS.extend(FRUITPIE_ID_DEFAULTS)
 
 # Plankton
 PLANKTON_ID_DEFAULTS = [(0x18d1, 0x500c)]
 for vid, pid in PLANKTON_ID_DEFAULTS:
-  INTERFACE_DEFAULTS[vid][pid] = ['ftdi_gpiouart', {'name': 'ec3po_uart'}]
+  INTERFACE_DEFAULTS[vid][pid] = \
+    ['ftdi_gpiouart',
+     {'name': 'ec3po_uart', 'raw_pty': 'raw_ec_uart_pty'},
+    ]
 
 SERVO_ID_DEFAULTS.extend(PLANKTON_ID_DEFAULTS)
 
diff --git a/servo/servo_server.py b/servo/servo_server.py
index 9c7f326..c4a06f9 100755
--- a/servo/servo_server.py
+++ b/servo/servo_server.py
@@ -471,63 +471,17 @@
       An EC3PO object representing the EC-3PO interface or None if there's no
       interface for the USB PD UART.
     """
-    vid = vendor
-    pid = product
-    # The current PID might be incremented if there are multiple FTDI.
-    # Therefore, try rewinding the PID back one if we don't find the base PID in
-    # the SERVO_ID_DEFAULTS
-    if (vid, pid) not in servo_interfaces.SERVO_ID_DEFAULTS:
-      self._logger.debug('VID:PID pair not found.  Rewinding PID back one...')
-      pid -= 1
-    self._logger.debug('vid:0x%04x, pid:0x%04x', vid, pid)
-
-    if 'raw_pty' in interface:
-      # We have specified an explicit target for this ec3po.
-      raw_uart_name = interface['raw_pty']
+    raw_uart_name = interface['raw_pty']
+    if self._syscfg.is_control(raw_uart_name):
       raw_ec_uart = self.get(raw_uart_name)
-
-    # Servo V2 / V3 should have the interface indicies in the same spot.
-    elif ((vid, pid) in servo_interfaces.SERVO_V2_DEFAULTS or
-        (vid, pid) in servo_interfaces.SERVO_V3_DEFAULTS):
-      # Determine if it's a PD interface or just main EC console.
-      if interface['index'] == servo_interfaces.EC3PO_USBPD_INTERFACE_NUM:
-        try:
-          # Obtain the raw EC UART PTY and create the EC-3PO interface.
-          raw_ec_uart = self.get('raw_usbpd_uart_pty')
-        except NameError:
-          # This overlay doesn't have a USB PD MCU, so skip init.
-          self._logger.info('No PD MCU UART.')
-          return None
-        except AttributeError:
-          # This overlay has no get method for the interface so skip init.  For
-          # servo v2, it's common for interfaces to be overridden such as
-          # reusing JTAG pins for the PD MCU UART instead.  Therefore, print an
-          # error message indicating that the interface might be set
-          # incorrectly.
-          if (vid, pid) in servo_interfaces.SERVO_V2_DEFAULTS:
-            self._logger.warn('No interface for PD MCU UART.')
-            self._logger.warn('Usually, this happens because the interface is '
-                              'set incorrectly.  If you\'re overriding an '
-                              'existing interface, be sure to update the '
-                              'interface lists for your board at the end of '
-                              'servo/servo_interfaces.py')
-          return None
-
-      elif interface['index'] == servo_interfaces.EC3PO_EC_INTERFACE_NUM:
-        raw_ec_uart = self.get('raw_ec_uart_pty')
-
-    # Servo V3, miniservo, Toad, Reston, Fruitpie, or Plankton
-    elif ((vid, pid) in servo_interfaces.MINISERVO_ID_DEFAULTS or
-          (vid, pid) in servo_interfaces.TOAD_ID_DEFAULTS or
-          (vid, pid) in servo_interfaces.RESTON_ID_DEFAULTS or
-          (vid, pid) in servo_interfaces.FRUITPIE_ID_DEFAULTS or
-          (vid, pid) in servo_interfaces.PLANKTON_ID_DEFAULTS):
-      raw_ec_uart = self.get('raw_ec_uart_pty')
+      return ec3po_interface.EC3PO(raw_ec_uart)
     else:
-      raise ServodError(('Unexpected EC-3PO interface!'
-                         ' (0x%04x:0x%04x) %r') % (vid, pid, interface))
-
-    return ec3po_interface.EC3PO(raw_ec_uart)
+      # The overlay doesn't have the raw PTY defined, therefore we can skip
+      # initializing this interface since no control relies on it.
+      self._logger.debug(
+          'Skip initializing EC3PO for %s, no control specified.',
+          raw_uart_name)
+      return None
 
   def _camel_case(self, string):
     output = ''