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