blob: 329066174a5b765d289e3c44f1cbea2a992e8675 [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
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093017#include "physical.hpp"
18
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053019#include <iostream>
20#include <string>
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053021namespace phosphor
22{
23namespace led
24{
25
26/** @brief Populates key parameters */
27void Physical::setInitialState()
28{
29 // 1. read /sys/class/leds/name/trigger
30 // 2. If its 'timer', then its blinking.
31 // 2.1: On blink, use delay_on and delay_off into dutyOn
32 // 3. If its 'none', then read brightness. 255 means, its ON, else OFF.
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053033
Andrew Jeffery42e02d32018-05-24 13:34:05 +093034 auto trigger = led.getTrigger();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053035 if (trigger == "timer")
36 {
37 // LED is blinking. Get the delay_on and delay_off and compute
38 // DutyCycle. sfsfs values are in strings. Need to convert 'em over to
39 // integer.
Andrew Jeffery42e02d32018-05-24 13:34:05 +093040 auto delayOn = led.getDelayOn();
41 auto delayOff = led.getDelayOff();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053042
43 // Calculate frequency and then percentage ON
44 frequency = delayOn + delayOff;
45 auto factor = frequency / 100;
46 auto dutyOn = delayOn / factor;
47
48 // Update.
49 this->dutyOn(dutyOn);
50 }
51 else
52 {
53 // This is hardcoded for now. This will be changed to this->frequency()
54 // when frequency is implemented.
55 // TODO
56 frequency = 1000;
57
58 // LED is either ON or OFF
Andrew Jeffery42e02d32018-05-24 13:34:05 +093059 auto brightness = led.getBrightness();
60 if (brightness == ASSERT)
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053061 {
62 // LED is in Solid ON
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093063 sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(
64 Action::On);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053065 }
66 else
67 {
68 // LED is in OFF state
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093069 sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(
70 Action::Off);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053071 }
72 }
73 return;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053074}
75
76/** @brief Overloaded State Property Setter function */
77auto Physical::state(Action value) -> Action
78{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053079 // Obtain current operation
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093080 auto current =
81 sdbusplus::xyz::openbmc_project::Led::server ::Physical::state();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053082
83 // Update requested operation into base class
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093084 auto requested =
85 sdbusplus::xyz::openbmc_project::Led::server ::Physical::state(value);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053086
87 // Apply the action.
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053088 driveLED(current, requested);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053089
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053090 return value;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053091}
92
93/** @brief apply action on the LED */
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053094void Physical::driveLED(Action current, Action request)
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053095{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053096 if (current == request)
97 {
98 // Best we can do here is ignore.
99 return;
100 }
101
102 // Transition TO Blinking state
103 if (request == Action::Blink)
104 {
105 return blinkOperation();
106 }
107
108 // Transition TO Stable states.
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +0930109 if (request == Action::On || request == Action::Off)
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530110 {
111 return stableStateOperation(request);
112 }
113 return;
114}
115
116/** @brief Either TurnON -or- TurnOFF */
117void Physical::stableStateOperation(Action action)
118{
119 auto value = (action == Action::On) ? ASSERT : DEASSERT;
120
121 // Write "none" to trigger to clear any previous action
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930122 led.setTrigger("none");
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530123
124 // And write the current command
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930125 led.setBrightness(value);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530126 return;
127}
128
129/** @brief BLINK the LED */
130void Physical::blinkOperation()
131{
132 // Get the latest dutyOn that the user requested
133 auto dutyOn = this->dutyOn();
134
135 // Write "timer" to "trigger" file
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930136 led.setTrigger("timer");
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530137
138 // Write DutyON. Value in percentage 1_millisecond.
139 // so 50% input becomes 500. Driver wants string input
140 auto percentage = frequency / 100;
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930141 led.setDelayOn(dutyOn * percentage);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530142
143 // Write DutyOFF. Value in milli seconds so 50% input becomes 500.
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930144 led.setDelayOff((100 - dutyOn) * percentage);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530145 return;
146}
147
148} // namespace led
149} // namespace phosphor