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