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 <cstdlib> 21 #include <iostream> 22 #include <string> 23 namespace phosphor 24 { 25 namespace led 26 { 27 28 /** @brief Populates key parameters */ 29 void Physical::setInitialState() 30 { 31 assert = led.getMaxBrightness(); 32 auto trigger = led.getTrigger(); 33 if (trigger == "timer") 34 { 35 // LED is blinking. Get the on and off delays and derive percent duty 36 auto delayOn = led.getDelayOn(); 37 periodMs = delayOn + led.getDelayOff(); 38 auto percentScale = periodMs / 100; 39 this->dutyOn(delayOn / percentScale); 40 } 41 else 42 { 43 // TODO: Periodicity is hardcoded for now. This will be changed to 44 // this->period() when configurable periodicity is implemented. 45 periodMs = 1000; 46 47 // Cache current LED state 48 auto brightness = led.getBrightness(); 49 if (brightness == assert) 50 { 51 sdbusplus::xyz::openbmc_project::Led::server::Physical::state( 52 Action::On); 53 } 54 else 55 { 56 sdbusplus::xyz::openbmc_project::Led::server::Physical::state( 57 Action::Off); 58 } 59 } 60 return; 61 } 62 63 auto Physical::state(Action value) -> Action 64 { 65 auto current = 66 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(); 67 68 auto requested = 69 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(value); 70 71 driveLED(current, requested); 72 73 return value; 74 } 75 76 void Physical::driveLED(Action current, Action request) 77 { 78 if (current == request) 79 { 80 return; 81 } 82 83 if (request == Action::On || request == Action::Off) 84 { 85 return stableStateOperation(request); 86 } 87 88 assert(request == Action::Blink); 89 blinkOperation(); 90 } 91 92 void Physical::stableStateOperation(Action action) 93 { 94 auto value = (action == Action::On) ? assert : DEASSERT; 95 96 led.setTrigger("none"); 97 led.setBrightness(value); 98 return; 99 } 100 101 void Physical::blinkOperation() 102 { 103 auto dutyOn = this->dutyOn(); 104 105 // Convert percent duty to milliseconds for sysfs interface 106 auto factor = periodMs / 100; 107 led.setDelayOn(dutyOn * factor); 108 led.setDelayOff((100 - dutyOn) * factor); 109 110 led.setTrigger("timer"); 111 return; 112 } 113 114 /** @brief set led color property in DBus*/ 115 void Physical::setLedColor(const std::string& color) 116 { 117 static const std::string prefix = 118 "xyz.openbmc_project.Led.Physical.Palette."; 119 if (!color.length()) 120 return; 121 std::string tmp = color; 122 tmp[0] = toupper(tmp[0]); 123 try 124 { 125 auto palette = convertPaletteFromString(prefix + tmp); 126 setPropertyByName("Color", palette); 127 } 128 catch (const sdbusplus::exception::InvalidEnumString&) 129 { 130 // if color var contains invalid color, 131 // Color property will have default value 132 } 133 } 134 135 } // namespace led 136 } // namespace phosphor 137