servo_micro: add UART3 routing in servod
This provides a driver and control for switching the usbpd uart
to spi lines (samus) or jtag lines (glados), allowing pd controller
interaction through servod.
BUG=chromium:660922
TEST=can access PD uart on samus, chell after usbpd_uart_routing:glados/samus
Change-Id: Ie41d5b045a15bf640ee107f4f014b219c08b20a6
Reviewed-on: https://chromium-review.googlesource.com/407539
Commit-Ready: Nick Sanders <nsanders@chromium.org>
Tested-by: Nick Sanders <nsanders@chromium.org>
Reviewed-by: Kevin Cheng <kevcheng@chromium.org>
diff --git a/servo/data/servo_micro.xml b/servo/data/servo_micro.xml
index 5f329bc..a44f9ee 100644
--- a/servo/data/servo_micro.xml
+++ b/servo/data/servo_micro.xml
@@ -12,6 +12,11 @@
Default is off</doc>
<params off="0" pp3300="1" pp1800="2"></params>
</map>
+ <map>
+ <name>usbpd_uart_map</name>
+ <doc>Enable alternate uart3 routing for PD</doc>
+ <params off="0" samus="1" glados="2"></params>
+ </map>
<control>
<name>uart1_enable</name>
@@ -336,4 +341,11 @@
<params interface="9" drv="ec3po_driver" map="onoff" init="on"
subtype="interp_connect"></params>
</control>
+
+ <control>
+ <name>usbpd_uart_routing</name>
+ <doc>enable pd uart routing</doc>
+ <params interface="7" drv="ec3po_servo_micro"
+ subtype="usbpd_console" map="usbpd_uart_map"></params>
+ </control>
</root>
diff --git a/servo/drv/__init__.py b/servo/drv/__init__.py
index 5dc8e4a..78688c5 100644
--- a/servo/drv/__init__.py
+++ b/servo/drv/__init__.py
@@ -21,6 +21,7 @@
import ec_lm4
import ec3po_gpio
import ec3po_driver
+import ec3po_servo_micro
import gpio
import hw_driver
import i2c_reg
diff --git a/servo/drv/ec3po_servo_micro.py b/servo/drv/ec3po_servo_micro.py
new file mode 100644
index 0000000..839b2a8
--- /dev/null
+++ b/servo/drv/ec3po_servo_micro.py
@@ -0,0 +1,92 @@
+# Copyright 2016 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Driver for servo micro specific controls through ec3po.
+
+Provides the following console controlled function subtypes:
+ usbpd_console
+"""
+
+import logging
+
+import pty_driver
+import servo
+
+
+# EC console mask for enabling only command channel
+COMMAND_CHANNEL_MASK = 0x1
+
+
+# Controls to set in batch operations.
+# [off, samus, glados]
+usbpd_uart_config = {
+ "UART3_RX_JTAG_BUFFER_TO_SERVO_TDO": ("IN", "ALT", "ALT"),
+ "UART3_TX_SERVO_JTAG_TCK": ("IN", "ALT", "ALT"),
+ "SPI1_MUX_SEL": ("1", "0", "1"),
+ "SPI1_BUF_EN_L": ("1", "0", "1"),
+ "SPI1_VREF_18": ("0", "1", "0"),
+ "SPI1_VREF_33": ("0", "0", "0"),
+ "JTAG_BUFIN_EN_L": ("1", "1", "0"),
+ "SERVO_JTAG_TDO_BUFFER_EN": ("0", "0", "1"),
+ "SERVO_JTAG_TDO_SEL": ("0", "0", "1"),
+}
+
+class ec3poServoMicroError(Exception):
+ """Exception class for ec."""
+
+
+class ec3poServoMicro(pty_driver.ptyDriver):
+ """Object to access drv=ec3po_servo_micro controls.
+
+ Note, instances of this object get dispatched via base class,
+ HwDriver's get/set method. That method ultimately calls:
+ "_[GS]et_%s" % params['subtype'] below.
+
+ For example, a control to read kbd_en would be dispatched to
+ call _Get_kbd_en.
+ """
+
+ def __init__(self, interface, params):
+ """Constructor.
+
+ Args:
+ interface: ec3po interface object to handle low-level communication to
+ control
+ params: dictionary of params needed
+ Raises:
+ ec3poServoMicroError: on init failure
+ """
+ super(ec3poServoMicro, self).__init__(interface, params)
+
+ if "console" in params:
+ if params["console"] == "enhanced" and \
+ type(interface) is servo.ec3po_interface.EC3PO:
+ interface._console.oobm_queue.put('interrogate never enhanced')
+ else:
+ raise ec3poServoMicroError("Enhanced console must be ec3po!")
+
+ self._logger.debug("")
+
+
+ def batch_set(self, batch, index):
+ """Set a batch of values on servo micro.
+
+ Args:
+ batch: dict of GPIO names, and on/off value
+ index: index of batch preset
+ """
+ if index not in [0, 1, 2]:
+ raise ec3poServoMicroError("Index (%s) must be 0, 1, or 2" % index)
+
+ for name, values in batch.items():
+ cmd = "gpioset %s %s\r" % (name, values[index])
+ self._issue_cmd(cmd)
+
+
+ def _Set_usbpd_console(self, value):
+ """Set or unset PD console routing
+
+ Args:
+ value: An integer value, 0: none, 1:samus, 2:glados
+ """
+ self.batch_set(usbpd_uart_config, value)