blob: 38c69b0a669c188d09e6d14c3559c5e9cd5f485b [file] [log] [blame]
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +05301/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <iostream>
18#include <string>
19#include "physical.hpp"
20namespace phosphor
21{
22namespace led
23{
24
25/** @brief Populates key parameters */
26void Physical::setInitialState()
27{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053028 // Control files in /sys/class/leds/<led-name>
29 brightCtrl = path + BRIGHTNESS;
30 blinkCtrl = path + BLINKCTRL;
31
32 delayOnCtrl = path + DELAYON;
33 delayOffCtrl = path + DELAYOFF;
34
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053035 // 1. read /sys/class/leds/name/trigger
36 // 2. If its 'timer', then its blinking.
37 // 2.1: On blink, use delay_on and delay_off into dutyOn
38 // 3. If its 'none', then read brightness. 255 means, its ON, else OFF.
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053039
40 auto trigger = read<std::string>(blinkCtrl);
41 if (trigger == "timer")
42 {
43 // LED is blinking. Get the delay_on and delay_off and compute
44 // DutyCycle. sfsfs values are in strings. Need to convert 'em over to
45 // integer.
46 auto delayOn = std::stoi(read<std::string>(delayOnCtrl));
47 auto delayOff = std::stoi(read<std::string>(delayOffCtrl));
48
49 // Calculate frequency and then percentage ON
50 frequency = delayOn + delayOff;
51 auto factor = frequency / 100;
52 auto dutyOn = delayOn / factor;
53
54 // Update.
55 this->dutyOn(dutyOn);
56 }
57 else
58 {
59 // This is hardcoded for now. This will be changed to this->frequency()
60 // when frequency is implemented.
61 // TODO
62 frequency = 1000;
63
64 // LED is either ON or OFF
65 auto brightness = read<std::string>(brightCtrl);
66 if (brightness == std::string(ASSERT))
67 {
68 // LED is in Solid ON
69 sdbusplus::xyz::openbmc_project::Led::server
70 ::Physical::state(Action::On);
71 }
72 else
73 {
74 // LED is in OFF state
75 sdbusplus::xyz::openbmc_project::Led::server
76 ::Physical::state(Action::Off);
77 }
78 }
79 return;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053080}
81
82/** @brief Overloaded State Property Setter function */
83auto Physical::state(Action value) -> Action
84{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053085 // Obtain current operation
86 auto current = sdbusplus::xyz::openbmc_project::Led::server
87 ::Physical::state();
88
89 // Update requested operation into base class
90 auto requested = sdbusplus::xyz::openbmc_project::Led::server
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053091 ::Physical::state(value);
92
93 // Apply the action.
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053094 driveLED(current, requested);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053095
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053096 return value;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053097}
98
99/** @brief apply action on the LED */
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530100void Physical::driveLED(Action current, Action request)
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530101{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530102 if (current == request)
103 {
104 // Best we can do here is ignore.
105 return;
106 }
107
108 // Transition TO Blinking state
109 if (request == Action::Blink)
110 {
111 return blinkOperation();
112 }
113
114 // Transition TO Stable states.
115 if(request == Action::On || request == Action::Off)
116 {
117 return stableStateOperation(request);
118 }
119 return;
120}
121
122/** @brief Either TurnON -or- TurnOFF */
123void Physical::stableStateOperation(Action action)
124{
125 auto value = (action == Action::On) ? ASSERT : DEASSERT;
126
127 // Write "none" to trigger to clear any previous action
128 write(blinkCtrl, "none");
129
130 // And write the current command
131 write(brightCtrl, value);
132 return;
133}
134
135/** @brief BLINK the LED */
136void Physical::blinkOperation()
137{
138 // Get the latest dutyOn that the user requested
139 auto dutyOn = this->dutyOn();
140
141 // Write "timer" to "trigger" file
142 write(blinkCtrl, "timer");
143
144 // Write DutyON. Value in percentage 1_millisecond.
145 // so 50% input becomes 500. Driver wants string input
146 auto percentage = frequency / 100;
147 write(delayOnCtrl, std::to_string(dutyOn * percentage));
148
149 // Write DutyOFF. Value in milli seconds so 50% input becomes 500.
150 write(delayOffCtrl, std::to_string((100 - dutyOn) * percentage));
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530151 return;
152}
153
154} // namespace led
155} // namespace phosphor