blob: b838516e8e4cffb62873eaa6621e6646f7aee154 [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
Derek Beckett3fff4b92020-10-20 08:27:06 -070014from __future__ import absolute_import
15from __future__ import division
16from __future__ import print_function
17
barfab@chromium.orgb6d29932012-04-11 09:46:43 +020018import os, shutil, sys, tempfile
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080019
Hung-Te Linb87193c2011-01-20 18:01:28 +080020
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080021class Gpio(object):
22 '''
23 Utility to access GPIO values.
24
25 Usage:
26 gpio = Gpio()
27 try:
28 gpio.setup()
Hung-Te Linff52cb62011-02-18 18:37:53 +080029 print gpio.read(gpio.DEVELOPER_SWITCH_CURRENT)
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080030 except:
31 print "gpio failed"
32 '''
33
Hung-Te Linff52cb62011-02-18 18:37:53 +080034 # GPIO property names (by "crossystem"):
35 DEVELOPER_SWITCH_CURRENT = 'devsw_cur'
36 RECOVERY_BUTTON_CURRENT = 'recoverysw_cur'
37 WRITE_PROTECT_CURRENT = 'wpsw_cur'
38
39 DEVELOPER_SWITCH_BOOT = 'devsw_boot'
40 RECOVERY_BUTTON_BOOT = 'recoverysw_boot'
Hung-Te Linff52cb62011-02-18 18:37:53 +080041
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,
Hung-Te Linff52cb62011-02-18 18:37:53 +080052 }
53
54 # list of legacy (chromeos_acpi) property names.
55 self._legacy_map = {
56 'developer_switch': self.DEVELOPER_SWITCH_CURRENT,
57 'recovery_button': self.RECOVERY_BUTTON_CURRENT,
58 'write_protect': self.WRITE_PROTECT_CURRENT,
59 }
60
61 def setup(self):
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080062 '''Configures system for processing GPIO.
63
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080064 Returns:
65 Raises an exception if gpio_setup execution failed.
66 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080067 # This is the place to do any configuration / system detection.
68 # Currently "crossystem" handles everything so we don't need to do
69 # anything now.
70 pass
Hung-Te Linb87193c2011-01-20 18:01:28 +080071
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080072 def read(self, name):
Hung-Te Linff52cb62011-02-18 18:37:53 +080073 '''Reads a GPIO property value.
74 Check "crossystem" command for the list of available property names.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080075
76 Parameters:
Hung-Te Linff52cb62011-02-18 18:37:53 +080077 name: the name of property to read.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080078
Hung-Te Linff52cb62011-02-18 18:37:53 +080079 Returns: current value, or raise exceptions.
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +080080 '''
Hung-Te Linff52cb62011-02-18 18:37:53 +080081 debug_title = "Gpio.read('%s'): " % name
Hung-Te Linb87193c2011-01-20 18:01:28 +080082
Hung-Te Linff52cb62011-02-18 18:37:53 +080083 # convert legacy names
84 if name in self._legacy_map:
85 name = self._legacy_map[name]
Hung-Te Linb87193c2011-01-20 18:01:28 +080086
Hung-Te Linff52cb62011-02-18 18:37:53 +080087 temp_fd, temp_file = tempfile.mkstemp()
88 os.close(temp_fd)
89 command = "crossystem %s 2>%s" % (name, temp_file)
90 pipe = os.popen(command, 'r')
91 value = pipe.read()
92 exit_status = pipe.close()
93 if exit_status:
94 with open(temp_file, 'r') as temp_handle:
95 debug_info = temp_handle.read()
96 value = value.strip()
97 debug_info = debug_info.strip()
98 if value:
99 debug_info = value + '\n' + debug_info
100 if debug_info:
101 debug_info = '\nInformation: ' + debug_info
102 raise self._exception_type(
103 debug_title + "Command failed (%d): %s%s" %
104 (exit_status, command, debug_info))
105 # convert values
106 if name in self._override_map:
107 try:
108 value = self._override_map[name](value)
109 except:
110 raise self._exception_type(debug_title +
111 'Conversion failed: %s' % value)
Hung-Te Linb87193c2011-01-20 18:01:28 +0800112 return value
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800113
114
115def main():
116 gpio = Gpio()
117 try:
118 gpio.setup()
Derek Beckett3fff4b92020-10-20 08:27:06 -0700119 print("developer switch current status: %s" %
120 gpio.read(gpio.DEVELOPER_SWITCH_CURRENT))
121 except Exception as e:
122 print("GPIO failed. %s" % e)
Hung-Te Linc6b8b2a2011-01-20 17:08:12 +0800123 sys.exit(1)
124
125if __name__ == '__main__':
126 main()