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