blob: b269266096596356d4d147d0d62484d798511604 [file] [log] [blame]
Gilad Arnold1ebd8132012-03-05 10:19:29 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_GPIO_HANDLER_H__
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_GPIO_HANDLER_H__
7
8#include <libudev.h>
9
10#include <string>
11
Gilad Arnold4d740eb2012-05-15 08:48:13 -070012#include <base/time.h>
13
14#include "update_engine/file_descriptor.h"
15#include "update_engine/udev_interface.h"
Gilad Arnold1ebd8132012-03-05 10:19:29 -080016
17namespace chromeos_update_engine {
18
Gilad Arnold4d740eb2012-05-15 08:48:13 -070019// An abstract GPIO handler interface. Serves as basic for both concrete and
20// mock implementations.
Gilad Arnold1ebd8132012-03-05 10:19:29 -080021class GpioHandler {
22 public:
Gilad Arnold4d740eb2012-05-15 08:48:13 -070023 GpioHandler() {}
24 virtual ~GpioHandler() {}; // ensure virtual destruction
25
26 // Returns true iff GPIOs have been used to signal an automated test case.
27 // This call may trigger a (deferred) GPIO discovery step prior to engaging in
28 // the signaling protocol; if discovery did not reveal GPIO devices, or the
29 // protocol has terminated prematurely, it will conservatively default to
30 // false.
31 virtual bool IsTestModeSignaled() = 0;
Gilad Arnold1ebd8132012-03-05 10:19:29 -080032
33 private:
Gilad Arnold4d740eb2012-05-15 08:48:13 -070034 DISALLOW_COPY_AND_ASSIGN(GpioHandler);
35};
Gilad Arnold1ebd8132012-03-05 10:19:29 -080036
Gilad Arnold4d740eb2012-05-15 08:48:13 -070037
38// Concrete implementation of GPIO signal handling. Currently, it only utilizes
39// the two Chromebook-specific GPIOs (aka 'dut_flaga' and 'dut_flagb') in
40// deciding whether a lab test mode has been signaled. Internal logic includes
41// detection, setup and reading from / writing to GPIOs. Detection is done via
42// libudev calls. This class should be instantiated at most once to avoid race
43// conditions in communicating over GPIO signals; instantiating a second
44// object will actually cause a runtime error.
45class StandardGpioHandler : public GpioHandler {
46 public:
47 // This constructor accepts a udev interface |udev_iface|. The value of
48 // |is_defer_discovery| determines whether GPIO discovery should be attempted
49 // right away (false) or done lazily, when necessitated by other calls (true).
50 StandardGpioHandler(UdevInterface* udev_iface, bool is_defer_discovery);
51
52 // Free all resources, allow to reinstantiate.
53 virtual ~StandardGpioHandler();
54
55 // Returns true iff GPIOs have been used to signal an automated test case. The
56 // check is performed at most once and the result is cached and returned on
57 // subsequent calls, unless |is_force| is true. This call may trigger a
58 // delayed GPIO discovery prior to engaging in the signaling protocol; if the
59 // delay period has not elapsed, it will conservatively default to false.
60 virtual bool IsTestModeSignaled();
61
62 private:
63 // GPIO identifiers, currently includes only the two dutflags.
64 enum GpioId {
65 kGpioIdDutflaga = 0,
66 kGpioIdDutflagb,
67 kGpioIdMax // marker, do not remove!
Gilad Arnold1ebd8132012-03-05 10:19:29 -080068 };
69
Gilad Arnold4d740eb2012-05-15 08:48:13 -070070 // GPIO direction specifier.
71 enum GpioDir {
72 kGpioDirIn = 0,
73 kGpioDirOut,
74 kGpioDirMax // marker, do not remove!
75 };
Gilad Arnold1ebd8132012-03-05 10:19:29 -080076
Gilad Arnold4d740eb2012-05-15 08:48:13 -070077 // GPIO value.
78 enum GpioVal {
79 kGpioValUp = 0,
80 kGpioValDown,
81 kGpioValMax // marker, do not remove!
82 };
83
84 // GPIO definition data.
85 struct GpioDef {
86 const char* name; // referential name of this GPIO
87 const char* udev_property; // udev property containing the device id
88 };
89
90 // GPIO runtime control structure.
91 struct Gpio {
92 std::string descriptor; // unique GPIO descriptor
93 std::string dev_path; // sysfs device name
94 };
95
96 // Various constants.
97 static const int kServoInputResponseTimeoutInSecs = 3;
98 static const int kServoInputNumChecksPerSec = 5;
99 static const int kServoOutputResponseWaitInSecs = 2;
100
101 // GPIO value/direction conversion tables.
102 static const char* gpio_dirs_[kGpioDirMax];
103 static const char* gpio_vals_[kGpioValMax];
104
105 // GPIO definitions.
106 static const GpioDef gpio_defs_[kGpioIdMax];
107
108 // Udev device enumeration helper classes. First here is an interface
109 // definition, which provides callbacks for enumeration setup and processing.
110 class UdevEnumHelper {
111 public:
112 UdevEnumHelper(StandardGpioHandler* gpio_handler)
113 : gpio_handler_(gpio_handler) {}
114
115 // Setup the enumeration filters.
116 virtual bool SetupEnumFilters(udev_enumerate* udev_enum) = 0;
117
118 // Processes an enumerated device. Returns true upon success, false
119 // otherwise.
120 virtual bool ProcessDev(udev_device* dev) = 0;
121
122 // Finalize the enumeration.
123 virtual bool Finalize() = 0;
124
125 protected:
126 StandardGpioHandler* gpio_handler_;
127
128 private:
129 DISALLOW_COPY_AND_ASSIGN(UdevEnumHelper);
130 };
131
132 // Specialized udev enumerate helper for extracting GPIO descriptors from the
133 // GPIO chip device.
134 class GpioChipUdevEnumHelper : public UdevEnumHelper {
135 public:
136 GpioChipUdevEnumHelper(StandardGpioHandler* gpio_handler)
137 : UdevEnumHelper(gpio_handler), num_gpio_chips_(0) {}
138 virtual bool SetupEnumFilters(udev_enumerate* udev_enum);
139 virtual bool ProcessDev(udev_device* dev);
140 virtual bool Finalize();
141
142 private:
143 // Records the number of times a GPIO chip has been enumerated (should not
144 // exceed 1).
145 int num_gpio_chips_;
146
147 DISALLOW_COPY_AND_ASSIGN(GpioChipUdevEnumHelper);
148 };
149
150 // Specialized udev enumerate helper for extracting a sysfs device path from a
151 // GPIO device.
152 class GpioUdevEnumHelper : public UdevEnumHelper {
153 public:
154 GpioUdevEnumHelper(StandardGpioHandler* gpio_handler, GpioId id)
155 : UdevEnumHelper(gpio_handler), num_gpios_(0), id_(id) {}
156 virtual bool SetupEnumFilters(udev_enumerate* udev_enum);
157 virtual bool ProcessDev(udev_device* dev);
158 virtual bool Finalize();
159
160 private:
161 // Records the number of times a GPIO has been enumerated with a given
162 // descriptor (should not exceed 1).
163 int num_gpios_;
164
165 // The enumerated GPIO identifier.
166 GpioId id_;
167
168 DISALLOW_COPY_AND_ASSIGN(GpioUdevEnumHelper);
169 };
170
171 // Attempt GPIO discovery, at most once. Returns true if discovery process was
172 // successfully completed or already attempted, false otherwise.
173 bool DiscoverGpios();
174
175 // An initialization helper performing udev enumeration. |enum_helper|
176 // implements an enumeration initialization and processing methods. Returns
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800177 // true upon success, false otherwise.
Gilad Arnold4d740eb2012-05-15 08:48:13 -0700178 bool InitUdevEnum(struct udev* udev, UdevEnumHelper* enum_helper);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800179
Gilad Arnold4d740eb2012-05-15 08:48:13 -0700180 // Assigns a copy of the device name of GPIO |id| to |dev_path_p|. Assumes
181 // initialization. Returns true upon success, false otherwise.
182 bool GetGpioDevName(GpioId id, std::string* dev_path_p);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800183
Gilad Arnold4d740eb2012-05-15 08:48:13 -0700184 // Dynamic counter for the number of instances this class has. Used to enforce
185 // that no more than one instance created. Thread-unsafe.
186 static unsigned num_instances_;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800187
Gilad Arnold4d740eb2012-05-15 08:48:13 -0700188 // GPIO control structures.
189 Gpio gpios_[kGpioIdMax];
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800190
Gilad Arnold4d740eb2012-05-15 08:48:13 -0700191 // Udev interface.
192 UdevInterface* const udev_iface_;
193
194 // Indicates whether GPIO discovery was performed.
195 bool is_discovery_attempted_;
196
197 DISALLOW_COPY_AND_ASSIGN(StandardGpioHandler);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800198};
199
200} // namespace chromeos_update_engine
201
202#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_GPIO_HANDLER_H__