blob: 754dfb43c457c001099b2a82ffaf5c8cad2aae24 [file] [log] [blame]
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +08001#!/usr/bin/env python
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'
37 WRITE_PROTECT_BOOT = 'wpsw_boot'
38
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080039 def __init__(self, exception_type=IOError):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080040 self._exception_type = exception_type
41
Hung-Te Linff52cb62011-02-18 18:37:53 +080042 # list of property conversions, usually str2int.
43 self._override_map = {
44 self.DEVELOPER_SWITCH_CURRENT: int,
45 self.DEVELOPER_SWITCH_BOOT: int,
46 self.RECOVERY_BUTTON_CURRENT: int,
47 self.RECOVERY_BUTTON_BOOT: int,
48 self.WRITE_PROTECT_CURRENT: int,
49 self.WRITE_PROTECT_BOOT: int,
50 }
51
52 # list of legacy (chromeos_acpi) property names.
53 self._legacy_map = {
54 'developer_switch': self.DEVELOPER_SWITCH_CURRENT,
55 'recovery_button': self.RECOVERY_BUTTON_CURRENT,
56 'write_protect': self.WRITE_PROTECT_CURRENT,
57 }
58
59 def setup(self):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080060 '''Configures system for processing GPIO.
61
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080062 Returns:
63 Raises an exception if gpio_setup execution failed.
64 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080065 # This is the place to do any configuration / system detection.
66 # Currently "crossystem" handles everything so we don't need to do
67 # anything now.
68 pass
Hung-Te Linb87193c2011-01-20 18:01:28 +080069
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080070 def read(self, name):
Hung-Te Linff52cb62011-02-18 18:37:53 +080071 '''Reads a GPIO property value.
72 Check "crossystem" command for the list of available property names.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080073
74 Parameters:
Hung-Te Linff52cb62011-02-18 18:37:53 +080075 name: the name of property to read.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080076
Hung-Te Linff52cb62011-02-18 18:37:53 +080077 Returns: current value, or raise exceptions.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080078 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080079 debug_title = "Gpio.read('%s'): " % name
Hung-Te Linb87193c2011-01-20 18:01:28 +080080
Hung-Te Linff52cb62011-02-18 18:37:53 +080081 # convert legacy names
82 if name in self._legacy_map:
83 name = self._legacy_map[name]
Hung-Te Linb87193c2011-01-20 18:01:28 +080084
Hung-Te Linff52cb62011-02-18 18:37:53 +080085 temp_fd, temp_file = tempfile.mkstemp()
86 os.close(temp_fd)
87 command = "crossystem %s 2>%s" % (name, temp_file)
88 pipe = os.popen(command, 'r')
89 value = pipe.read()
90 exit_status = pipe.close()
91 if exit_status:
92 with open(temp_file, 'r') as temp_handle:
93 debug_info = temp_handle.read()
94 value = value.strip()
95 debug_info = debug_info.strip()
96 if value:
97 debug_info = value + '\n' + debug_info
98 if debug_info:
99 debug_info = '\nInformation: ' + debug_info
100 raise self._exception_type(
101 debug_title + "Command failed (%d): %s%s" %
102 (exit_status, command, debug_info))
103 # convert values
104 if name in self._override_map:
105 try:
106 value = self._override_map[name](value)
107 except:
108 raise self._exception_type(debug_title +
109 'Conversion failed: %s' % value)
Hung-Te Linb87193c2011-01-20 18:01:28 +0800110 return value
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800111
112
113def main():
114 gpio = Gpio()
115 try:
116 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +0800117 print ("developer switch current status: %s" %
118 gpio.read(gpio.DEVELOPER_SWITCH_CURRENT))
119 except Exception, e:
120 print "GPIO failed. %s" % e
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800121 sys.exit(1)
122
123if __name__ == '__main__':
124 main()