xref: /openbmc/phosphor-led-sysfs/physical.cpp (revision 2332e91ff6b0758026ce68f049a74cda6e13b702)
1 /**
2  * Copyright © 2016,2018 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 "physical.hpp"
18 
19 #include <cassert>
20 #include <iostream>
21 #include <string>
22 namespace phosphor
23 {
24 namespace led
25 {
26 
27 /** @brief Populates key parameters */
28 void Physical::setInitialState()
29 {
30     auto trigger = led.getTrigger();
31     if (trigger == "timer")
32     {
33         // LED is blinking. Get the on and off delays and derive percent duty
34         auto delayOn = led.getDelayOn();
35         periodMs = delayOn + led.getDelayOff();
36         auto percentScale = periodMs / 100;
37         this->dutyOn(delayOn / percentScale);
38     }
39     else
40     {
41         // TODO: Periodicity is hardcoded for now. This will be changed to
42         // this->period() when configurable periodicity is implemented.
43         periodMs = 1000;
44 
45         // Cache current LED state
46         auto brightness = led.getBrightness();
47         if (brightness == ASSERT)
48         {
49             sdbusplus::xyz::openbmc_project::Led::server::Physical::state(
50                 Action::On);
51         }
52         else
53         {
54             sdbusplus::xyz::openbmc_project::Led::server::Physical::state(
55                 Action::Off);
56         }
57     }
58     return;
59 }
60 
61 auto Physical::state(Action value) -> Action
62 {
63     auto current =
64         sdbusplus::xyz::openbmc_project::Led::server::Physical::state();
65 
66     auto requested =
67         sdbusplus::xyz::openbmc_project::Led::server::Physical::state(value);
68 
69     driveLED(current, requested);
70 
71     return value;
72 }
73 
74 void Physical::driveLED(Action current, Action request)
75 {
76     if (current == request)
77     {
78         return;
79     }
80 
81     if (request == Action::On || request == Action::Off)
82     {
83         return stableStateOperation(request);
84     }
85 
86     assert(request == Action::Blink);
87     blinkOperation();
88 }
89 
90 void Physical::stableStateOperation(Action action)
91 {
92     auto value = (action == Action::On) ? ASSERT : DEASSERT;
93 
94     led.setTrigger("none");
95     led.setBrightness(value);
96     return;
97 }
98 
99 void Physical::blinkOperation()
100 {
101     auto dutyOn = this->dutyOn();
102 
103     // Convert percent duty to milliseconds for sysfs interface
104     auto factor = periodMs / 100;
105     led.setDelayOn(dutyOn * factor);
106     led.setDelayOff((100 - dutyOn) * factor);
107 
108     led.setTrigger("timer");
109     return;
110 }
111 
112 } // namespace led
113 } // namespace phosphor
114