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 uint16_t periodMs = delayOn + led->getDelayOff(); 38 auto percentScale = periodMs / 100; 39 this->dutyOn(delayOn / percentScale); 40 this->period(periodMs); 41 sdbusplus::xyz::openbmc_project::Led::server::Physical::state( 42 Action::Blink); 43 } 44 else 45 { 46 // Cache current LED state 47 auto brightness = led->getBrightness(); 48 if (brightness != 0U && assert != 0U) 49 { 50 sdbusplus::xyz::openbmc_project::Led::server::Physical::state( 51 Action::On); 52 } 53 else 54 { 55 sdbusplus::xyz::openbmc_project::Led::server::Physical::state( 56 Action::Off); 57 } 58 } 59 } 60 61 auto Physical::state() const -> Action 62 { 63 return sdbusplus::xyz::openbmc_project::Led::server::Physical::state(); 64 } 65 66 auto Physical::state(Action value) -> Action 67 { 68 auto current = 69 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(); 70 71 auto requested = 72 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(value); 73 74 driveLED(current, requested); 75 76 return value; 77 } 78 79 void Physical::driveLED(Action current, Action request) 80 { 81 if (current == request) 82 { 83 return; 84 } 85 86 if (request == Action::On || request == Action::Off) 87 { 88 return stableStateOperation(request); 89 } 90 91 assert(request == Action::Blink); 92 blinkOperation(); 93 } 94 95 void Physical::stableStateOperation(Action action) 96 { 97 auto value = (action == Action::On) ? assert : deasserted; 98 99 led->setTrigger("none"); 100 led->setBrightness(value); 101 } 102 103 void Physical::blinkOperation() 104 { 105 /* 106 The configuration of the trigger type must precede the configuration of 107 the trigger type properties. From the kernel documentation: 108 "You can change triggers in a similar manner to the way an IO scheduler 109 is chosen (via /sys/class/leds/<device>/trigger). Trigger specific 110 parameters can appear in /sys/class/leds/<device> once a given trigger is 111 selected." 112 Refer: 113 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/leds/leds-class.txt?h=v5.2#n26 114 */ 115 auto d = static_cast<unsigned long>(dutyOn()); 116 if (d > 100) 117 { 118 d = 100; 119 } 120 121 auto p = static_cast<unsigned long>(period()); 122 123 led->setTrigger("timer"); 124 led->setDelayOn(p * d / 100UL); 125 led->setDelayOff(p * (100UL - d) / 100UL); 126 } 127 128 /** @brief set led color property in DBus*/ 129 void Physical::setLedColor(const std::string& color) 130 { 131 static const std::string prefix = 132 "xyz.openbmc_project.Led.Physical.Palette."; 133 134 if (color.empty()) 135 { 136 return; 137 } 138 139 std::string tmp = color; 140 tmp[0] = static_cast<char>(toupper(tmp[0])); 141 try 142 { 143 auto palette = convertPaletteFromString(prefix + tmp); 144 setPropertyByName("Color", palette); 145 } 146 catch (const sdbusplus::exception::InvalidEnumString&) 147 { 148 // if color var contains invalid color, 149 // Color property will have default value 150 } 151 } 152 153 } // namespace led 154 } // namespace phosphor 155