• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import time
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.server.cros.faft.cr50_test import Cr50Test
10
11
12class firmware_Cr50DeferredECReset(Cr50Test):
13    """Verify EC_RST_L stays asserted only if all conditions below are True.
14    (1) System got 'Power-On reset'.
15    (2) RDD cable is connected.
16    (3) The power button is held.
17
18    After this, EC_RST_L should be deasserted as soon as the power button
19    gets released.
20    """
21    version = 1
22
23    def initialize(self, host, cmdline_args, full_args):
24        """Initialize the test and check if
25           cr50 is exists,
26           DTS is controllable, and
27           power delivery mode and power button is adjustable.
28        """
29        super(firmware_Cr50DeferredECReset, self).initialize(host, cmdline_args,
30                full_args)
31        if not hasattr(self, 'cr50'):
32            raise error.TestNAError('Test can only be run on devices with '
33                                    'access to the Cr50 console')
34        if not self.cr50.servo_v4_supports_dts_mode():
35            raise error.TestNAError('Need working servo v4 DTS control')
36
37        self.fast_open(enable_testlab=True)
38        if not self.cr50.testlab_is_on():
39            raise error.TestNAError('Cr50 testlab mode needs to be enabled')
40
41        # Test the external power delivery
42        self.servo.set('servo_v4_role', 'snk')
43        time.sleep(3)
44
45        rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip()
46        logging.info(rv)
47        if not 'ac = 0' in rv:
48            raise error.TestFail('Failed in setting servo_v4_role sink')
49
50        # Test stopping the external power delivery
51        self.servo.set('servo_v4_role', 'src')
52        time.sleep(3)
53
54        rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip()
55        logging.info(rv)
56        if not 'ac = 1' in rv:
57            raise error.TestFail('Failed in setting  servo_v4_role source')
58
59        # Test if the power button is adjustable.
60        self.servo.set('pwr_button', 'press')
61        self.servo.set('pwr_button', 'release')
62
63    def check_ecrst_asserted(self, expect_assert):
64        """Ask CR50 whether EC_RST_L is asserted or deasserted.
65
66        Args:
67            expect_assert: True if it is expected asserted.
68                           False otherwise.
69        """
70
71        # If the console is responsive, then the EC is awake.
72        rv = self.cr50.send_command_get_output('ecrst',
73                ['EC_RST_L is \w{0,2}asserted.*>'])[0].strip()
74        logging.info(rv)
75        expecting_txt = ' asserted' if expect_assert else ' deasserted'
76
77        if not expecting_txt in rv:
78            raise error.TestFail(rv)
79
80    def ping_ec(self, expect_response):
81        """Check if EC is running and responding.
82
83        Args:
84            expect_response: True if EC should respond
85                             False otherwise.
86        """
87        try:
88            rv = self.ec.send_command_get_output('time',
89                    ['time.*>'])[0].strip()
90        except error.TestFail as e:
91            logging.info(e)
92            if 'Timeout waiting for response' in str(e):
93                if not expect_response:
94                    return
95            raise e
96        else:
97            if not expect_response:
98                raise error.TestFail(rv)
99
100    def test_deferred_ec_reset(self, power_button_hold, rdd_enable,
101            expect_ec_response):
102        """Do a power-on reset, and check if EC responds.
103
104        Args:
105            power_button_hold: True if it should be pressed on a system reset.
106                               False otherwise.
107            rdd_enable: True if RDD should be detected on a system reset.
108                        False otherwise.
109            expect_ec_response: True if EC should run and response on a system
110                                reset.
111                                False otherwise.
112        """
113        logging.info('Test deferred_ec_reset starts.')
114        logging.info('Power button held: %s', power_button_hold)
115        logging.info('RDD connection   : %s', rdd_enable)
116
117        # Stop power delivery to DUT
118        self.servo.set('servo_v4_role', 'snk')
119        time.sleep(3)
120
121        # Battery Cutoff
122        self.ec.send_command('cutoff')
123        time.sleep(3)
124
125        # EC should not respond
126        self.ping_ec(False)
127
128        # press (or release) the power button
129        power_button_setval = 'press' if power_button_hold else 'release'
130        # call set_nocheck, since power button shall be recognized as pressed
131        # at this point.
132        self.servo.set_nocheck('pwr_button', power_button_setval)
133
134        # enable RDD Connection (or disable)
135        self.servo.set_nocheck('servo_v4_dts_mode',
136                'on' if rdd_enable else 'off')
137        time.sleep(self.cr50.SHORT_WAIT)
138
139        # Enable power delivery to DUT
140        self.servo.set('servo_v4_role', 'src')
141
142        # Wait for a while
143        wait_sec = 30
144        logging.info('waiting for %d seconds', wait_sec)
145        time.sleep(wait_sec)
146
147        # Check if EC_RST_L is asserted (or deasserted) and EC is on (or off).
148        self.check_ecrst_asserted(not expect_ec_response)
149        self.ping_ec(expect_ec_response)
150
151        # Release power button
152        self.servo.set('pwr_button', 'release')
153
154        # Check if EC_RST_L is deasserted and EC is on.
155        self.check_ecrst_asserted(False)
156        self.ping_ec(True)
157
158        # Recover CCD
159        if self.servo.get('servo_v4_dts_mode') == 'off':
160            self.cr50.ccd_enable()
161
162    def run_once(self):
163        """Test deferred EC reset feature. """
164
165        # Release power button and disable RDD on power-on reset.
166        # EC should be running.
167        self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=False,
168            expect_ec_response=True)
169
170        # Release power button but enable RDD on power-on reset.
171        # EC should be running.
172        self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=True,
173            expect_ec_response=True)
174
175        # Hold power button but disable RDD on power-on reset.
176        # EC should be running.
177        self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=False,
178            expect_ec_response=True)
179
180        # Hold power button and enable RDD on power-on reset.
181        # EC should not be running.
182        self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=True,
183            expect_ec_response=False)
184