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