blob: 39c318a35acf68b59e60b82982bc97a0ab223c7a [file] [log] [blame]
Mike Frysingerd03e6b52019-08-03 12:49:01 -04001#!/usr/bin/env python2
barfab@chromium.orgb6d29932012-04-11 09:46:43 +02002# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +08003# 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.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080012'''
13
barfab@chromium.orgb6d29932012-04-11 09:46:43 +020014import os, shutil, sys, tempfile
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080015
Hung-Te Linb87193c2011-01-20 18:01:28 +080016
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080017class Gpio(object):
18 '''
19 Utility to access GPIO values.
20
21 Usage:
22 gpio = Gpio()
23 try:
24 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +080025 print gpio.read(gpio.DEVELOPER_SWITCH_CURRENT)
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080026 except:
27 print "gpio failed"
28 '''
29
Hung-Te Linff52cb62011-02-18 18:37:53 +080030 # 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'
Hung-Te Linff52cb62011-02-18 18:37:53 +080037
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080038 def __init__(self, exception_type=IOError):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080039 self._exception_type = exception_type
40
Hung-Te Linff52cb62011-02-18 18:37:53 +080041 # list of property conversions, usually str2int.
42 self._override_map = {
43 self.DEVELOPER_SWITCH_CURRENT: int,
44 self.DEVELOPER_SWITCH_BOOT: int,
45 self.RECOVERY_BUTTON_CURRENT: int,
46 self.RECOVERY_BUTTON_BOOT: int,
47 self.WRITE_PROTECT_CURRENT: int,
Hung-Te Linff52cb62011-02-18 18:37:53 +080048 }
49
50 # list of legacy (chromeos_acpi) property names.
51 self._legacy_map = {
52 'developer_switch': self.DEVELOPER_SWITCH_CURRENT,
53 'recovery_button': self.RECOVERY_BUTTON_CURRENT,
54 'write_protect': self.WRITE_PROTECT_CURRENT,
55 }
56
57 def setup(self):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080058 '''Configures system for processing GPIO.
59
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080060 Returns:
61 Raises an exception if gpio_setup execution failed.
62 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080063 # This is the place to do any configuration / system detection.
64 # Currently "crossystem" handles everything so we don't need to do
65 # anything now.
66 pass
Hung-Te Linb87193c2011-01-20 18:01:28 +080067
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080068 def read(self, name):
Hung-Te Linff52cb62011-02-18 18:37:53 +080069 '''Reads a GPIO property value.
70 Check "crossystem" command for the list of available property names.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080071
72 Parameters:
Hung-Te Linff52cb62011-02-18 18:37:53 +080073 name: the name of property to read.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080074
Hung-Te Linff52cb62011-02-18 18:37:53 +080075 Returns: current value, or raise exceptions.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080076 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080077 debug_title = "Gpio.read('%s'): " % name
Hung-Te Linb87193c2011-01-20 18:01:28 +080078
Hung-Te Linff52cb62011-02-18 18:37:53 +080079 # convert legacy names
80 if name in self._legacy_map:
81 name = self._legacy_map[name]
Hung-Te Linb87193c2011-01-20 18:01:28 +080082
Hung-Te Linff52cb62011-02-18 18:37:53 +080083 temp_fd, temp_file = tempfile.mkstemp()
84 os.close(temp_fd)
85 command = "crossystem %s 2>%s" % (name, temp_file)
86 pipe = os.popen(command, 'r')
87 value = pipe.read()
88 exit_status = pipe.close()
89 if exit_status:
90 with open(temp_file, 'r') as temp_handle:
91 debug_info = temp_handle.read()
92 value = value.strip()
93 debug_info = debug_info.strip()
94 if value:
95 debug_info = value + '\n' + debug_info
96 if debug_info:
97 debug_info = '\nInformation: ' + debug_info
98 raise self._exception_type(
99 debug_title + "Command failed (%d): %s%s" %
100 (exit_status, command, debug_info))
101 # convert values
102 if name in self._override_map:
103 try:
104 value = self._override_map[name](value)
105 except:
106 raise self._exception_type(debug_title +
107 'Conversion failed: %s' % value)
Hung-Te Linb87193c2011-01-20 18:01:28 +0800108 return value
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800109
110
111def main():
112 gpio = Gpio()
113 try:
114 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +0800115 print ("developer switch current status: %s" %
116 gpio.read(gpio.DEVELOPER_SWITCH_CURRENT))
117 except Exception, e:
118 print "GPIO failed. %s" % e
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800119 sys.exit(1)
120
121if __name__ == '__main__':
122 main()