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