blob: 67f0a9065b741e4fd5b65ebe747dddf127f08dc1 [file] [log] [blame]
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +05301/**
Andrew Jeffery30552c92018-05-25 15:36:30 +09302 * Copyright © 2016,2018 IBM Corporation
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +05303 *
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
Andrew Jeffery2332e912018-05-25 15:45:38 +093019#include <cassert>
Alexander Soldatov97ddb722019-04-16 09:10:00 +030020#include <cstdlib>
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053021#include <iostream>
22#include <string>
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053023namespace phosphor
24{
25namespace led
26{
27
28/** @brief Populates key parameters */
29void Physical::setInitialState()
30{
Andrew Jeffery5b1417b2019-03-18 17:20:37 +103031 assert = led.getMaxBrightness();
Andrew Jeffery42e02d32018-05-24 13:34:05 +093032 auto trigger = led.getTrigger();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053033 if (trigger == "timer")
34 {
Andrew Jeffery30552c92018-05-25 15:36:30 +093035 // LED is blinking. Get the on and off delays and derive percent duty
Andrew Jeffery42e02d32018-05-24 13:34:05 +093036 auto delayOn = led.getDelayOn();
tony lee9e500aa2019-04-23 10:10:24 +080037 uint16_t periodMs = delayOn + led.getDelayOff();
Andrew Jefferybf0b0a92018-05-25 15:41:12 +093038 auto percentScale = periodMs / 100;
39 this->dutyOn(delayOn / percentScale);
tony lee9e500aa2019-04-23 10:10:24 +080040 this->period(periodMs);
George Liu001e2a32023-12-01 17:30:30 +080041 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(
42 Action::Blink);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053043 }
44 else
45 {
Andrew Jeffery30552c92018-05-25 15:36:30 +093046 // Cache current LED state
Andrew Jeffery42e02d32018-05-24 13:34:05 +093047 auto brightness = led.getBrightness();
Andrew Jefferye3719f42023-02-06 14:28:04 +103048 if (brightness != 0U && assert != 0U)
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053049 {
Andrew Jeffery30552c92018-05-25 15:36:30 +093050 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093051 Action::On);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053052 }
53 else
54 {
Andrew Jeffery30552c92018-05-25 15:36:30 +093055 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093056 Action::Off);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053057 }
58 }
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053059}
60
Vishwanatha Subbannadb21bc02021-03-26 00:32:46 -050061auto Physical::state() const -> Action
62{
63 return sdbusplus::xyz::openbmc_project::Led::server::Physical::state();
64}
65
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053066auto Physical::state(Action value) -> Action
67{
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093068 auto current =
Andrew Jeffery30552c92018-05-25 15:36:30 +093069 sdbusplus::xyz::openbmc_project::Led::server::Physical::state();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053070
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093071 auto requested =
Andrew Jeffery30552c92018-05-25 15:36:30 +093072 sdbusplus::xyz::openbmc_project::Led::server::Physical::state(value);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053073
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053074 driveLED(current, requested);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053075
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053076 return value;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053077}
78
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053079void Physical::driveLED(Action current, Action request)
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053080{
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053081 if (current == request)
82 {
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053083 return;
84 }
85
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093086 if (request == Action::On || request == Action::Off)
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053087 {
88 return stableStateOperation(request);
89 }
Andrew Jeffery2332e912018-05-25 15:45:38 +093090
91 assert(request == Action::Blink);
92 blinkOperation();
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053093}
94
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053095void Physical::stableStateOperation(Action action)
96{
Andrew Jeffery8e852282023-02-06 19:29:43 +103097 auto value = (action == Action::On) ? assert : deasserted;
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +053098
Andrew Jeffery42e02d32018-05-24 13:34:05 +093099 led.setTrigger("none");
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930100 led.setBrightness(value);
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530101}
102
Vishwanatha Subbanna61675c32016-11-30 15:52:15 +0530103void Physical::blinkOperation()
104{
tony lee9e500aa2019-04-23 10:10:24 +0800105 /*
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 */
Andrew Jeffery7782f0d2023-02-06 14:44:43 +1030115 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
tony lee9e500aa2019-04-23 10:10:24 +0800123 led.setTrigger("timer");
Andrew Jeffery7782f0d2023-02-06 14:44:43 +1030124 led.setDelayOn(p * d / 100UL);
125 led.setDelayOff(p * (100UL - d) / 100UL);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530126}
127
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300128/** @brief set led color property in DBus*/
129void Physical::setLedColor(const std::string& color)
130{
131 static const std::string prefix =
132 "xyz.openbmc_project.Led.Physical.Palette.";
Andrew Jeffery826ba7b2023-02-06 14:57:15 +1030133
Andrew Jeffery263c0562023-02-06 14:56:16 +1030134 if (color.empty())
Andrew Jeffery826ba7b2023-02-06 14:57:15 +1030135 {
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300136 return;
Andrew Jeffery826ba7b2023-02-06 14:57:15 +1030137 }
138
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300139 std::string tmp = color;
Andrew Jefferydce1e202023-02-06 17:55:15 +1030140 tmp[0] = static_cast<char>(toupper(tmp[0]));
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300141 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
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530153} // namespace led
154} // namespace phosphor