xref: /openbmc/entity-manager/src/gpio-presence/device_presence.cpp (revision b0f157189b02902917fa76feca5ce549808b0d56)
18c4b1d99SAlexander Hansen /*
28c4b1d99SAlexander Hansen  * SPDX-FileCopyrightText: Copyright (c) 2022-2024. All rights
38c4b1d99SAlexander Hansen  * reserved. SPDX-License-Identifier: Apache-2.0
48c4b1d99SAlexander Hansen  */
58c4b1d99SAlexander Hansen 
68c4b1d99SAlexander Hansen #include "device_presence.hpp"
78c4b1d99SAlexander Hansen 
88c4b1d99SAlexander Hansen #include <phosphor-logging/lg2.hpp>
98c4b1d99SAlexander Hansen #include <sdbusplus/message/native_types.hpp>
108c4b1d99SAlexander Hansen #include <xyz/openbmc_project/Configuration/GPIODeviceDetect/client.hpp>
118c4b1d99SAlexander Hansen #include <xyz/openbmc_project/Configuration/GPIODeviceDetect/common.hpp>
128c4b1d99SAlexander Hansen #include <xyz/openbmc_project/Inventory/Source/DevicePresence/aserver.hpp>
138c4b1d99SAlexander Hansen 
148c4b1d99SAlexander Hansen #include <string>
158c4b1d99SAlexander Hansen #include <vector>
168c4b1d99SAlexander Hansen 
178c4b1d99SAlexander Hansen PHOSPHOR_LOG2_USING;
188c4b1d99SAlexander Hansen 
19*b0f15718SAlexander Hansen using DevicePresenceProperties = sdbusplus::common::xyz::openbmc_project::
20*b0f15718SAlexander Hansen     inventory::source::DevicePresence::properties_t;
21*b0f15718SAlexander Hansen 
228c4b1d99SAlexander Hansen namespace gpio_presence
238c4b1d99SAlexander Hansen {
248c4b1d99SAlexander Hansen 
DevicePresence(sdbusplus::async::context & ctx,const std::vector<std::string> & gpioNames,const std::vector<uint64_t> & gpioValues,const std::string & deviceName,const std::unordered_map<std::string,bool> & gpioState)258c4b1d99SAlexander Hansen DevicePresence::DevicePresence(
268c4b1d99SAlexander Hansen     sdbusplus::async::context& ctx, const std::vector<std::string>& gpioNames,
278c4b1d99SAlexander Hansen     const std::vector<uint64_t>& gpioValues, const std::string& deviceName,
288c4b1d99SAlexander Hansen     const std::unordered_map<std::string, bool>& gpioState) :
298c4b1d99SAlexander Hansen     deviceName(deviceName), gpioState(gpioState), ctx(ctx)
308c4b1d99SAlexander Hansen {
318c4b1d99SAlexander Hansen     for (size_t i = 0; i < gpioNames.size(); i++)
328c4b1d99SAlexander Hansen     {
338c4b1d99SAlexander Hansen         GPIO_POLARITY polarity =
348c4b1d99SAlexander Hansen             (gpioValues[i] == 0) ? ACTIVE_LOW : ACTIVE_HIGH;
358c4b1d99SAlexander Hansen         gpioPolarity[gpioNames[i]] = polarity;
368c4b1d99SAlexander Hansen     }
378c4b1d99SAlexander Hansen }
388c4b1d99SAlexander Hansen 
updateGPIOPresence(const std::string & gpioLine)398c4b1d99SAlexander Hansen auto DevicePresence::updateGPIOPresence(const std::string& gpioLine) -> void
408c4b1d99SAlexander Hansen {
418c4b1d99SAlexander Hansen     if (!gpioPolarity.contains(gpioLine))
428c4b1d99SAlexander Hansen     {
438c4b1d99SAlexander Hansen         return;
448c4b1d99SAlexander Hansen     }
458c4b1d99SAlexander Hansen 
468c4b1d99SAlexander Hansen     updateDbusInterfaces();
478c4b1d99SAlexander Hansen }
488c4b1d99SAlexander Hansen 
getObjPath() const498c4b1d99SAlexander Hansen auto DevicePresence::getObjPath() const -> sdbusplus::message::object_path
508c4b1d99SAlexander Hansen {
518c4b1d99SAlexander Hansen     sdbusplus::message::object_path objPathBase(
528c4b1d99SAlexander Hansen         "/xyz/openbmc_project/GPIODeviceDetected/");
538c4b1d99SAlexander Hansen     sdbusplus::message::object_path objPath = objPathBase / deviceName;
548c4b1d99SAlexander Hansen     return objPath;
558c4b1d99SAlexander Hansen }
568c4b1d99SAlexander Hansen 
isPresent()578c4b1d99SAlexander Hansen auto DevicePresence::isPresent() -> bool
588c4b1d99SAlexander Hansen {
598c4b1d99SAlexander Hansen     for (auto& [name, polarity] : gpioPolarity)
608c4b1d99SAlexander Hansen     {
618c4b1d99SAlexander Hansen         if (!gpioState.contains(name))
628c4b1d99SAlexander Hansen         {
638c4b1d99SAlexander Hansen             error("GPIO {NAME} not in cached state", "NAME", name);
648c4b1d99SAlexander Hansen             return false;
658c4b1d99SAlexander Hansen         }
668c4b1d99SAlexander Hansen 
678c4b1d99SAlexander Hansen         const bool state = gpioState.at(name);
688c4b1d99SAlexander Hansen 
698c4b1d99SAlexander Hansen         if (state && polarity == ACTIVE_LOW)
708c4b1d99SAlexander Hansen         {
718c4b1d99SAlexander Hansen             return false;
728c4b1d99SAlexander Hansen         }
738c4b1d99SAlexander Hansen         if (!state && polarity == ACTIVE_HIGH)
748c4b1d99SAlexander Hansen         {
758c4b1d99SAlexander Hansen             return false;
768c4b1d99SAlexander Hansen         }
778c4b1d99SAlexander Hansen     }
788c4b1d99SAlexander Hansen 
798c4b1d99SAlexander Hansen     return true;
808c4b1d99SAlexander Hansen }
818c4b1d99SAlexander Hansen 
updateDbusInterfaces()828c4b1d99SAlexander Hansen auto DevicePresence::updateDbusInterfaces() -> void
838c4b1d99SAlexander Hansen {
848c4b1d99SAlexander Hansen     debug("Updating dbus interface for config {OBJPATH}", "OBJPATH",
858c4b1d99SAlexander Hansen           deviceName);
868c4b1d99SAlexander Hansen 
878c4b1d99SAlexander Hansen     const bool present = isPresent();
888c4b1d99SAlexander Hansen     sdbusplus::message::object_path objPath = getObjPath();
898c4b1d99SAlexander Hansen 
908c4b1d99SAlexander Hansen     if (present && !detectedIface)
918c4b1d99SAlexander Hansen     {
928c4b1d99SAlexander Hansen         info("Detected {NAME} as present, adding dbus interface", "NAME",
938c4b1d99SAlexander Hansen              deviceName);
948c4b1d99SAlexander Hansen 
95*b0f15718SAlexander Hansen         detectedIface = std::make_unique<DevicePresenceInterface>(
96*b0f15718SAlexander Hansen             ctx, objPath.str.c_str(), DevicePresenceProperties{deviceName});
978c4b1d99SAlexander Hansen 
988c4b1d99SAlexander Hansen         detectedIface->emit_added();
998c4b1d99SAlexander Hansen     }
1008c4b1d99SAlexander Hansen 
1018c4b1d99SAlexander Hansen     if (!present && detectedIface)
1028c4b1d99SAlexander Hansen     {
1038c4b1d99SAlexander Hansen         info("Detected {NAME} as absent, removing dbus interface", "NAME",
1048c4b1d99SAlexander Hansen              deviceName);
1058c4b1d99SAlexander Hansen         detectedIface->emit_removed();
1068c4b1d99SAlexander Hansen 
1078c4b1d99SAlexander Hansen         detectedIface.reset();
1088c4b1d99SAlexander Hansen     }
1098c4b1d99SAlexander Hansen }
1108c4b1d99SAlexander Hansen 
1118c4b1d99SAlexander Hansen } // namespace gpio_presence
112