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