xref: /aosp_15_r20/external/autotest/client/cros/gpio.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#!/usr/bin/env python3
2*9c5db199SXin Li# Copyright (c) 2012 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 Li'''ChromeOS device GPIO library
7*9c5db199SXin Li
8*9c5db199SXin LiThis module provides a convenient way to detect, setup, and access to GPIO
9*9c5db199SXin Livalues on a ChromeOS compatible device.
10*9c5db199SXin Li
11*9c5db199SXin LiSee help(Gpio) for more information.
12*9c5db199SXin Li'''
13*9c5db199SXin Li
14*9c5db199SXin Lifrom __future__ import absolute_import
15*9c5db199SXin Lifrom __future__ import division
16*9c5db199SXin Lifrom __future__ import print_function
17*9c5db199SXin Li
18*9c5db199SXin Liimport os, shutil, sys, tempfile
19*9c5db199SXin Li
20*9c5db199SXin Li
21*9c5db199SXin Liclass Gpio(object):
22*9c5db199SXin Li    '''
23*9c5db199SXin Li    Utility to access GPIO values.
24*9c5db199SXin Li
25*9c5db199SXin Li    Usage:
26*9c5db199SXin Li        gpio = Gpio()
27*9c5db199SXin Li        try:
28*9c5db199SXin Li            gpio.setup()
29*9c5db199SXin Li            print gpio.read(gpio.DEVELOPER_SWITCH_CURRENT)
30*9c5db199SXin Li        except:
31*9c5db199SXin Li            print "gpio failed"
32*9c5db199SXin Li    '''
33*9c5db199SXin Li
34*9c5db199SXin Li    # GPIO property names (by "crossystem"):
35*9c5db199SXin Li    DEVELOPER_SWITCH_CURRENT = 'devsw_cur'
36*9c5db199SXin Li    RECOVERY_BUTTON_CURRENT = 'recoverysw_cur'
37*9c5db199SXin Li    WRITE_PROTECT_CURRENT = 'wpsw_cur'
38*9c5db199SXin Li
39*9c5db199SXin Li    DEVELOPER_SWITCH_BOOT = 'devsw_boot'
40*9c5db199SXin Li    RECOVERY_BUTTON_BOOT = 'recoverysw_boot'
41*9c5db199SXin Li
42*9c5db199SXin Li    def __init__(self, exception_type=IOError):
43*9c5db199SXin Li        self._exception_type = exception_type
44*9c5db199SXin Li
45*9c5db199SXin Li        # list of property conversions, usually str2int.
46*9c5db199SXin Li        self._override_map = {
47*9c5db199SXin Li                self.DEVELOPER_SWITCH_CURRENT: int,
48*9c5db199SXin Li                self.DEVELOPER_SWITCH_BOOT: int,
49*9c5db199SXin Li                self.RECOVERY_BUTTON_CURRENT: int,
50*9c5db199SXin Li                self.RECOVERY_BUTTON_BOOT: int,
51*9c5db199SXin Li                self.WRITE_PROTECT_CURRENT: int,
52*9c5db199SXin Li        }
53*9c5db199SXin Li
54*9c5db199SXin Li        # list of legacy (chromeos_acpi) property names.
55*9c5db199SXin Li        self._legacy_map = {
56*9c5db199SXin Li                'developer_switch': self.DEVELOPER_SWITCH_CURRENT,
57*9c5db199SXin Li                'recovery_button': self.RECOVERY_BUTTON_CURRENT,
58*9c5db199SXin Li                'write_protect': self.WRITE_PROTECT_CURRENT,
59*9c5db199SXin Li        }
60*9c5db199SXin Li
61*9c5db199SXin Li    def setup(self):
62*9c5db199SXin Li        '''Configures system for processing GPIO.
63*9c5db199SXin Li
64*9c5db199SXin Li        Returns:
65*9c5db199SXin Li            Raises an exception if gpio_setup execution failed.
66*9c5db199SXin Li        '''
67*9c5db199SXin Li        # This is the place to do any configuration / system detection.
68*9c5db199SXin Li        # Currently "crossystem" handles everything so we don't need to do
69*9c5db199SXin Li        # anything now.
70*9c5db199SXin Li        pass
71*9c5db199SXin Li
72*9c5db199SXin Li    def read(self, name):
73*9c5db199SXin Li        '''Reads a GPIO property value.
74*9c5db199SXin Li           Check "crossystem" command for the list of available property names.
75*9c5db199SXin Li
76*9c5db199SXin Li        Parameters:
77*9c5db199SXin Li            name: the name of property to read.
78*9c5db199SXin Li
79*9c5db199SXin Li        Returns: current value, or raise exceptions.
80*9c5db199SXin Li        '''
81*9c5db199SXin Li        debug_title = "Gpio.read('%s'): " % name
82*9c5db199SXin Li
83*9c5db199SXin Li        # convert legacy names
84*9c5db199SXin Li        if name in self._legacy_map:
85*9c5db199SXin Li            name = self._legacy_map[name]
86*9c5db199SXin Li
87*9c5db199SXin Li        temp_fd, temp_file = tempfile.mkstemp()
88*9c5db199SXin Li        os.close(temp_fd)
89*9c5db199SXin Li        command = "crossystem %s 2>%s" % (name, temp_file)
90*9c5db199SXin Li        pipe = os.popen(command, 'r')
91*9c5db199SXin Li        value = pipe.read()
92*9c5db199SXin Li        exit_status = pipe.close()
93*9c5db199SXin Li        if exit_status:
94*9c5db199SXin Li            with open(temp_file, 'r') as temp_handle:
95*9c5db199SXin Li                debug_info = temp_handle.read()
96*9c5db199SXin Li            value = value.strip()
97*9c5db199SXin Li            debug_info = debug_info.strip()
98*9c5db199SXin Li            if value:
99*9c5db199SXin Li                debug_info = value + '\n' + debug_info
100*9c5db199SXin Li            if debug_info:
101*9c5db199SXin Li                debug_info = '\nInformation: ' + debug_info
102*9c5db199SXin Li            raise self._exception_type(
103*9c5db199SXin Li                    debug_title + "Command failed (%d): %s%s" %
104*9c5db199SXin Li                    (exit_status, command, debug_info))
105*9c5db199SXin Li        # convert values
106*9c5db199SXin Li        if name in self._override_map:
107*9c5db199SXin Li            try:
108*9c5db199SXin Li                value = self._override_map[name](value)
109*9c5db199SXin Li            except:
110*9c5db199SXin Li                raise self._exception_type(debug_title +
111*9c5db199SXin Li                                           'Conversion failed: %s' % value)
112*9c5db199SXin Li        return value
113*9c5db199SXin Li
114*9c5db199SXin Li
115*9c5db199SXin Lidef main():
116*9c5db199SXin Li    gpio = Gpio()
117*9c5db199SXin Li    try:
118*9c5db199SXin Li        gpio.setup()
119*9c5db199SXin Li        print("developer switch current status: %s" %
120*9c5db199SXin Li              gpio.read(gpio.DEVELOPER_SWITCH_CURRENT))
121*9c5db199SXin Li    except Exception as e:
122*9c5db199SXin Li        print("GPIO failed. %s" % e)
123*9c5db199SXin Li        sys.exit(1)
124*9c5db199SXin Li
125*9c5db199SXin Liif __name__ == '__main__':
126*9c5db199SXin Li    main()
127