| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | * SPDX-FileCopyrightText: Copyright (c) 2022-2024. All rights | 
|  | 3 | * reserved. SPDX-License-Identifier: Apache-2.0 | 
|  | 4 | */ | 
|  | 5 |  | 
|  | 6 | #include "device_presence.hpp" | 
|  | 7 |  | 
|  | 8 | #include <phosphor-logging/lg2.hpp> | 
|  | 9 | #include <sdbusplus/message/native_types.hpp> | 
|  | 10 | #include <xyz/openbmc_project/Configuration/GPIODeviceDetect/client.hpp> | 
|  | 11 | #include <xyz/openbmc_project/Configuration/GPIODeviceDetect/common.hpp> | 
|  | 12 | #include <xyz/openbmc_project/Inventory/Source/DevicePresence/aserver.hpp> | 
|  | 13 |  | 
|  | 14 | #include <string> | 
|  | 15 | #include <vector> | 
|  | 16 |  | 
|  | 17 | PHOSPHOR_LOG2_USING; | 
|  | 18 |  | 
| Alexander Hansen | b0f1571 | 2025-06-18 17:48:23 +0200 | [diff] [blame] | 19 | using DevicePresenceProperties = sdbusplus::common::xyz::openbmc_project:: | 
|  | 20 | inventory::source::DevicePresence::properties_t; | 
|  | 21 |  | 
| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 22 | namespace gpio_presence | 
|  | 23 | { | 
|  | 24 |  | 
|  | 25 | DevicePresence::DevicePresence( | 
|  | 26 | sdbusplus::async::context& ctx, const std::vector<std::string>& gpioNames, | 
|  | 27 | const std::vector<uint64_t>& gpioValues, const std::string& deviceName, | 
|  | 28 | const std::unordered_map<std::string, bool>& gpioState) : | 
|  | 29 | deviceName(deviceName), gpioState(gpioState), ctx(ctx) | 
|  | 30 | { | 
|  | 31 | for (size_t i = 0; i < gpioNames.size(); i++) | 
|  | 32 | { | 
|  | 33 | GPIO_POLARITY polarity = | 
|  | 34 | (gpioValues[i] == 0) ? ACTIVE_LOW : ACTIVE_HIGH; | 
|  | 35 | gpioPolarity[gpioNames[i]] = polarity; | 
|  | 36 | } | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | auto DevicePresence::updateGPIOPresence(const std::string& gpioLine) -> void | 
|  | 40 | { | 
|  | 41 | if (!gpioPolarity.contains(gpioLine)) | 
|  | 42 | { | 
|  | 43 | return; | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | updateDbusInterfaces(); | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | auto DevicePresence::getObjPath() const -> sdbusplus::message::object_path | 
|  | 50 | { | 
|  | 51 | sdbusplus::message::object_path objPathBase( | 
|  | 52 | "/xyz/openbmc_project/GPIODeviceDetected/"); | 
|  | 53 | sdbusplus::message::object_path objPath = objPathBase / deviceName; | 
|  | 54 | return objPath; | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | auto DevicePresence::isPresent() -> bool | 
|  | 58 | { | 
|  | 59 | for (auto& [name, polarity] : gpioPolarity) | 
|  | 60 | { | 
|  | 61 | if (!gpioState.contains(name)) | 
|  | 62 | { | 
|  | 63 | error("GPIO {NAME} not in cached state", "NAME", name); | 
|  | 64 | return false; | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | const bool state = gpioState.at(name); | 
|  | 68 |  | 
|  | 69 | if (state && polarity == ACTIVE_LOW) | 
|  | 70 | { | 
|  | 71 | return false; | 
|  | 72 | } | 
|  | 73 | if (!state && polarity == ACTIVE_HIGH) | 
|  | 74 | { | 
|  | 75 | return false; | 
|  | 76 | } | 
|  | 77 | } | 
|  | 78 |  | 
|  | 79 | return true; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | auto DevicePresence::updateDbusInterfaces() -> void | 
|  | 83 | { | 
|  | 84 | debug("Updating dbus interface for config {OBJPATH}", "OBJPATH", | 
|  | 85 | deviceName); | 
|  | 86 |  | 
|  | 87 | const bool present = isPresent(); | 
|  | 88 | sdbusplus::message::object_path objPath = getObjPath(); | 
|  | 89 |  | 
|  | 90 | if (present && !detectedIface) | 
|  | 91 | { | 
|  | 92 | info("Detected {NAME} as present, adding dbus interface", "NAME", | 
|  | 93 | deviceName); | 
|  | 94 |  | 
| Alexander Hansen | b0f1571 | 2025-06-18 17:48:23 +0200 | [diff] [blame] | 95 | detectedIface = std::make_unique<DevicePresenceInterface>( | 
|  | 96 | ctx, objPath.str.c_str(), DevicePresenceProperties{deviceName}); | 
| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 97 |  | 
|  | 98 | detectedIface->emit_added(); | 
|  | 99 | } | 
|  | 100 |  | 
|  | 101 | if (!present && detectedIface) | 
|  | 102 | { | 
|  | 103 | info("Detected {NAME} as absent, removing dbus interface", "NAME", | 
|  | 104 | deviceName); | 
|  | 105 | detectedIface->emit_removed(); | 
|  | 106 |  | 
|  | 107 | detectedIface.reset(); | 
|  | 108 | } | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | } // namespace gpio_presence |