#!/usr/bin/env python # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. '''Chrome OS device GPIO library This module provides a convenient way to detect, setup, and access to GPIO values on a Chrome OS compatible device. See help(Gpio) for more information. ''' import os, shutil, sys, tempfile class Gpio(object): ''' Utility to access GPIO values. Usage: gpio = Gpio() try: gpio.setup() print gpio.read(gpio.DEVELOPER_SWITCH_CURRENT) except: print "gpio failed" ''' # GPIO property names (by "crossystem"): DEVELOPER_SWITCH_CURRENT = 'devsw_cur' RECOVERY_BUTTON_CURRENT = 'recoverysw_cur' WRITE_PROTECT_CURRENT = 'wpsw_cur' DEVELOPER_SWITCH_BOOT = 'devsw_boot' RECOVERY_BUTTON_BOOT = 'recoverysw_boot' WRITE_PROTECT_BOOT = 'wpsw_boot' def __init__(self, exception_type=IOError): self._exception_type = exception_type # list of property conversions, usually str2int. self._override_map = { self.DEVELOPER_SWITCH_CURRENT: int, self.DEVELOPER_SWITCH_BOOT: int, self.RECOVERY_BUTTON_CURRENT: int, self.RECOVERY_BUTTON_BOOT: int, self.WRITE_PROTECT_CURRENT: int, self.WRITE_PROTECT_BOOT: int, } # list of legacy (chromeos_acpi) property names. self._legacy_map = { 'developer_switch': self.DEVELOPER_SWITCH_CURRENT, 'recovery_button': self.RECOVERY_BUTTON_CURRENT, 'write_protect': self.WRITE_PROTECT_CURRENT, } def setup(self): '''Configures system for processing GPIO. Returns: Raises an exception if gpio_setup execution failed. ''' # This is the place to do any configuration / system detection. # Currently "crossystem" handles everything so we don't need to do # anything now. pass def read(self, name): '''Reads a GPIO property value. Check "crossystem" command for the list of available property names. Parameters: name: the name of property to read. Returns: current value, or raise exceptions. ''' debug_title = "Gpio.read('%s'): " % name # convert legacy names if name in self._legacy_map: name = self._legacy_map[name] temp_fd, temp_file = tempfile.mkstemp() os.close(temp_fd) command = "crossystem %s 2>%s" % (name, temp_file) pipe = os.popen(command, 'r') value = pipe.read() exit_status = pipe.close() if exit_status: with open(temp_file, 'r') as temp_handle: debug_info = temp_handle.read() value = value.strip() debug_info = debug_info.strip() if value: debug_info = value + '\n' + debug_info if debug_info: debug_info = '\nInformation: ' + debug_info raise self._exception_type( debug_title + "Command failed (%d): %s%s" % (exit_status, command, debug_info)) # convert values if name in self._override_map: try: value = self._override_map[name](value) except: raise self._exception_type(debug_title + 'Conversion failed: %s' % value) return value def main(): gpio = Gpio() try: gpio.setup() print ("developer switch current status: %s" % gpio.read(gpio.DEVELOPER_SWITCH_CURRENT)) except Exception, e: print "GPIO failed. %s" % e sys.exit(1) if __name__ == '__main__': main()