| #!/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() |