xref: /aosp_15_r20/external/autotest/server/cros/usb_mux_controller.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Lint as: python2, python3
2*9c5db199SXin Li# Copyriht (c) 2014 The Chromium OS Authors. All rights reserved.
3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be
4*9c5db199SXin Li# found in the LICENSE file.
5*9c5db199SXin Li
6*9c5db199SXin Lifrom __future__ import absolute_import
7*9c5db199SXin Lifrom __future__ import division
8*9c5db199SXin Lifrom __future__ import print_function
9*9c5db199SXin Liimport logging
10*9c5db199SXin Liimport six
11*9c5db199SXin Li
12*9c5db199SXin Li# Following Beaglebone GPIO pins are used to control the 8 port multiplexer.
13*9c5db199SXin LiMUX_EN = '20'
14*9c5db199SXin LiMUX_S0 = '115'
15*9c5db199SXin LiMUX_S1 = '117'
16*9c5db199SXin LiMUX_S2 = '49'
17*9c5db199SXin Li
18*9c5db199SXin LiENABLE_MUX = '1'
19*9c5db199SXin LiDISABLE_MUX = '0'
20*9c5db199SXin Li
21*9c5db199SXin Li# Various commands used to control the GPIO pins at the kernel level.
22*9c5db199SXin LiLS_GPIO_DIRECTORY = 'ls /sys/class/gpio'
23*9c5db199SXin LiEXPORT_GPIO_PIN = 'echo %s > /sys/class/gpio/export'
24*9c5db199SXin LiSET_GPIO_DIRECTION = 'echo high > /sys/class/gpio/gpio%s/direction'
25*9c5db199SXin LiSET_GPIO_VALUE = 'echo %s > /sys/class/gpio/gpio%s/value'
26*9c5db199SXin LiUNEXPORT_GPIO_PIN = 'echo %s > /sys/class/gpio/unexport'
27*9c5db199SXin Li
28*9c5db199SXin Li# Values passed to each GPIO pin to enable a specific port.
29*9c5db199SXin Li# Bit sequence: MUX_S2, MUX_S1, MUX_S0
30*9c5db199SXin Li# Example: To enable port 5, MUX_S2 will be set to 1, MUX_S1 will be set to 0
31*9c5db199SXin Li# and MUX_S0 will be set to 1
32*9c5db199SXin Liports = {0:'000', 1:'001', 2:'010', 3:'011', 4:'100', 5:'101', 6:'110', 7:'111'}
33*9c5db199SXin Li
34*9c5db199SXin Liclass USBMuxController(object):
35*9c5db199SXin Li    """Class to control individual ports on a 8 port USB switch/hub.
36*9c5db199SXin Li
37*9c5db199SXin Li    This class is responsible for enabling all the GPIO pins on the beaglebone
38*9c5db199SXin Li    needed to control the 8 port USB switch/hub. In order to use this USB mux
39*9c5db199SXin Li    controller you need custom hardware setup which connects to the beaglebone
40*9c5db199SXin Li    and drives the 8 port relay switch to turn the individual ports on the USB
41*9c5db199SXin Li    hub 'on'/'off'.
42*9c5db199SXin Li
43*9c5db199SXin Li    TODO(harpreet) Write a USB mux hardware design document and provide a link
44*9c5db199SXin Li    here.
45*9c5db199SXin Li
46*9c5db199SXin Li    """
47*9c5db199SXin Li
48*9c5db199SXin Li    version = 1
49*9c5db199SXin Li
50*9c5db199SXin Li    def __init__(self, host):
51*9c5db199SXin Li        """Initializes this USB Mux Controller instance.
52*9c5db199SXin Li
53*9c5db199SXin Li        @param host: Host where the test will be run.
54*9c5db199SXin Li
55*9c5db199SXin Li        """
56*9c5db199SXin Li        self.host = host
57*9c5db199SXin Li
58*9c5db199SXin Li    def __del__(self):
59*9c5db199SXin Li        """Destructor of USBMuxController.
60*9c5db199SXin Li
61*9c5db199SXin Li        Disables all GPIO pins used that control the multiplexer.
62*9c5db199SXin Li
63*9c5db199SXin Li        """
64*9c5db199SXin Li        self.mux_teardown()
65*9c5db199SXin Li
66*9c5db199SXin Li    def mux_setup(self):
67*9c5db199SXin Li        """
68*9c5db199SXin Li        Enable GPIO pins that control the multiplexer.
69*9c5db199SXin Li
70*9c5db199SXin Li        """
71*9c5db199SXin Li        logging.info('Enable GPIO pins that control the multiplexer.')
72*9c5db199SXin Li        self.enable_gpio_pins(MUX_EN)
73*9c5db199SXin Li        self.disable_all_ports()
74*9c5db199SXin Li        self.enable_gpio_pins(MUX_S2)
75*9c5db199SXin Li        self.enable_gpio_pins(MUX_S1)
76*9c5db199SXin Li        self.enable_gpio_pins(MUX_S0)
77*9c5db199SXin Li
78*9c5db199SXin Li    def mux_teardown(self):
79*9c5db199SXin Li        """
80*9c5db199SXin Li        Disable the multiplexer and unexport all GPIO pins.
81*9c5db199SXin Li
82*9c5db199SXin Li        """
83*9c5db199SXin Li        logging.info('Start USB multiplexer teardown.')
84*9c5db199SXin Li        self.disable_all_ports()
85*9c5db199SXin Li        # unexport gpio pins
86*9c5db199SXin Li        logging.info('Unexport all GPIO pins.')
87*9c5db199SXin Li        self.host.servo.system(UNEXPORT_GPIO_PIN % MUX_S0)
88*9c5db199SXin Li        self.host.servo.system(UNEXPORT_GPIO_PIN % MUX_S1)
89*9c5db199SXin Li        self.host.servo.system(UNEXPORT_GPIO_PIN % MUX_S2)
90*9c5db199SXin Li        self.host.servo.system(UNEXPORT_GPIO_PIN % MUX_EN)
91*9c5db199SXin Li        logging.info('Completed USB multiplexer teardown. All USB ports should'
92*9c5db199SXin Li                     'now be turned off.')
93*9c5db199SXin Li
94*9c5db199SXin Li    def enable_gpio_pins(self, pin):
95*9c5db199SXin Li        """
96*9c5db199SXin Li        Enables the given GPIO pin by exporting the pin and setting the
97*9c5db199SXin Li        direction.
98*9c5db199SXin Li
99*9c5db199SXin Li        @param pin: GPIO pin to be enabled.
100*9c5db199SXin Li
101*9c5db199SXin Li        """
102*9c5db199SXin Li        if 'gpio' + pin not in self.host.servo.system_output(LS_GPIO_DIRECTORY):
103*9c5db199SXin Li            self.host.servo.system(EXPORT_GPIO_PIN % pin)
104*9c5db199SXin Li            self.host.servo.system(SET_GPIO_DIRECTION % pin)
105*9c5db199SXin Li
106*9c5db199SXin Li    def enable_port(self, usb_port):
107*9c5db199SXin Li        """
108*9c5db199SXin Li        Enables the given port on the USB hub.
109*9c5db199SXin Li
110*9c5db199SXin Li        @param usb_port: USB port to be enabled.
111*9c5db199SXin Li
112*9c5db199SXin Li        """
113*9c5db199SXin Li        port = ports[usb_port]
114*9c5db199SXin Li        logging.info('Enable port %s.', port)
115*9c5db199SXin Li        self.mux_setup()
116*9c5db199SXin Li        self.disable_all_ports()
117*9c5db199SXin Li
118*9c5db199SXin Li        logging.info('Set GPIO pins to correct logic levels.')
119*9c5db199SXin Li        self.host.servo.system(SET_GPIO_VALUE % (port[0], MUX_S2))
120*9c5db199SXin Li        self.host.servo.system(SET_GPIO_VALUE % (port[1], MUX_S1))
121*9c5db199SXin Li        self.host.servo.system(SET_GPIO_VALUE % (port[2], MUX_S0))
122*9c5db199SXin Li
123*9c5db199SXin Li        logging.info('Enable USB multiplexer. Appropriate port should now be'
124*9c5db199SXin Li                     'enabled')
125*9c5db199SXin Li        self.host.servo.system(SET_GPIO_VALUE % (ENABLE_MUX, MUX_EN))
126*9c5db199SXin Li
127*9c5db199SXin Li    def disable_all_ports(self):
128*9c5db199SXin Li        """
129*9c5db199SXin Li        Disables all USB ports that are currently enabled.
130*9c5db199SXin Li
131*9c5db199SXin Li        """
132*9c5db199SXin Li        if 'gpio20' in self.host.servo.system_output(LS_GPIO_DIRECTORY):
133*9c5db199SXin Li            logging.info('Disable USB ports.')
134*9c5db199SXin Li            self.host.servo.system(SET_GPIO_VALUE % (DISABLE_MUX, MUX_EN))
135