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