blob: b57ba2169fc67a9431ba507c4bf5364563191e2f [file] [log] [blame]
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +08001#!/usr/bin/env python
2# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3# 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
14import os
15import shutil
16import sys
17import tempfile
18
Hung-Te Linb87193c2011-01-20 18:01:28 +080019
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080020class Gpio(object):
21 '''
22 Utility to access GPIO values.
23
24 Usage:
25 gpio = Gpio()
26 try:
27 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +080028 print gpio.read(gpio.DEVELOPER_SWITCH_CURRENT)
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080029 except:
30 print "gpio failed"
31 '''
32
Hung-Te Linff52cb62011-02-18 18:37:53 +080033 # GPIO property names (by "crossystem"):
34 DEVELOPER_SWITCH_CURRENT = 'devsw_cur'
35 RECOVERY_BUTTON_CURRENT = 'recoverysw_cur'
36 WRITE_PROTECT_CURRENT = 'wpsw_cur'
37
38 DEVELOPER_SWITCH_BOOT = 'devsw_boot'
39 RECOVERY_BUTTON_BOOT = 'recoverysw_boot'
40 WRITE_PROTECT_BOOT = 'wpsw_boot'
41
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080042 def __init__(self, exception_type=IOError):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080043 self._exception_type = exception_type
44
Hung-Te Linff52cb62011-02-18 18:37:53 +080045 # list of property conversions, usually str2int.
46 self._override_map = {
47 self.DEVELOPER_SWITCH_CURRENT: int,
48 self.DEVELOPER_SWITCH_BOOT: int,
49 self.RECOVERY_BUTTON_CURRENT: int,
50 self.RECOVERY_BUTTON_BOOT: int,
51 self.WRITE_PROTECT_CURRENT: int,
52 self.WRITE_PROTECT_BOOT: int,
53 }
54
55 # list of legacy (chromeos_acpi) property names.
56 self._legacy_map = {
57 'developer_switch': self.DEVELOPER_SWITCH_CURRENT,
58 'recovery_button': self.RECOVERY_BUTTON_CURRENT,
59 'write_protect': self.WRITE_PROTECT_CURRENT,
60 }
61
62 def setup(self):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080063 '''Configures system for processing GPIO.
64
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080065 Returns:
66 Raises an exception if gpio_setup execution failed.
67 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080068 # This is the place to do any configuration / system detection.
69 # Currently "crossystem" handles everything so we don't need to do
70 # anything now.
71 pass
Hung-Te Linb87193c2011-01-20 18:01:28 +080072
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080073 def read(self, name):
Hung-Te Linff52cb62011-02-18 18:37:53 +080074 '''Reads a GPIO property value.
75 Check "crossystem" command for the list of available property names.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080076
77 Parameters:
Hung-Te Linff52cb62011-02-18 18:37:53 +080078 name: the name of property to read.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080079
Hung-Te Linff52cb62011-02-18 18:37:53 +080080 Returns: current value, or raise exceptions.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080081 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080082 debug_title = "Gpio.read('%s'): " % name
Hung-Te Linb87193c2011-01-20 18:01:28 +080083
Hung-Te Linff52cb62011-02-18 18:37:53 +080084 # convert legacy names
85 if name in self._legacy_map:
86 name = self._legacy_map[name]
Hung-Te Linb87193c2011-01-20 18:01:28 +080087
Hung-Te Linff52cb62011-02-18 18:37:53 +080088 temp_fd, temp_file = tempfile.mkstemp()
89 os.close(temp_fd)
90 command = "crossystem %s 2>%s" % (name, temp_file)
91 pipe = os.popen(command, 'r')
92 value = pipe.read()
93 exit_status = pipe.close()
94 if exit_status:
95 with open(temp_file, 'r') as temp_handle:
96 debug_info = temp_handle.read()
97 value = value.strip()
98 debug_info = debug_info.strip()
99 if value:
100 debug_info = value + '\n' + debug_info
101 if debug_info:
102 debug_info = '\nInformation: ' + debug_info
103 raise self._exception_type(
104 debug_title + "Command failed (%d): %s%s" %
105 (exit_status, command, debug_info))
106 # convert values
107 if name in self._override_map:
108 try:
109 value = self._override_map[name](value)
110 except:
111 raise self._exception_type(debug_title +
112 'Conversion failed: %s' % value)
Hung-Te Linb87193c2011-01-20 18:01:28 +0800113 return value
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800114
115
116def main():
117 gpio = Gpio()
118 try:
119 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +0800120 print ("developer switch current status: %s" %
121 gpio.read(gpio.DEVELOPER_SWITCH_CURRENT))
122 except Exception, e:
123 print "GPIO failed. %s" % e
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800124 sys.exit(1)
125
126if __name__ == '__main__':
127 main()