| 113 | |
| 114 | TRY(s_instance->initialize_impl()); |
| 115 | |
| 116 | return {}; |
| 117 | } |
| 118 | |
| 119 | BatterySystem::BatterySystem(AML::Namespace& acpi_namespace) |
| 120 | : m_acpi_namespace(acpi_namespace) |
| 121 | { } |
| 122 | |
| 123 | BAN::ErrorOr<void> BatterySystem::initialize_impl() |
| 124 | { |
| 125 | auto base_inode = TRY(TmpDirectoryInode::create_new(DevFileSystem::get(), 0555, 0, 0, static_cast<TmpInode&>(*DevFileSystem::get().root_inode()))); |
| 126 | DevFileSystem::get().add_inode("batteries", base_inode); |
| 127 | |
| 128 | auto batteries = TRY(m_acpi_namespace.find_device_with_eisa_id("PNP0C0A"_sv)); |
| 129 | for (const auto& battery : batteries) |
| 130 | { |
| 131 | auto [_0, sta_ref] = TRY(m_acpi_namespace.find_named_object(battery, TRY(AML::NameString::from_string("_STA"_sv)))); |
| 132 | if (sta_ref != nullptr) |
| 133 | { |
| 134 | auto sta_result = AML::evaluate_node(_0, sta_ref->node); |
| 135 | if (sta_result.is_error() || sta_result.value().type != AML::Node::Type::Integer) |
| 136 | continue; |
| 137 | // "battery is present" |
| 138 | if (!(sta_result.value().as.integer.value & 0x10)) |
| 139 | continue; |
| 140 | } |
| 141 | |
| 142 | auto [_1, bif_ref] = TRY(m_acpi_namespace.find_named_object(battery, TRY(AML::NameString::from_string("_BIF"_sv)))); |
| 143 | if (!bif_ref || bif_ref->node.type != AML::Node::Type::Method || bif_ref->node.as.method.arg_count != 0) |
| 144 | { |
| 145 | dwarnln("Battery {} does not have _BIF or it is invalid", battery); |
| 146 | continue; |
| 147 | } |
| 148 | |
| 149 | auto [_2, bst_ref] = TRY(m_acpi_namespace.find_named_object(battery, TRY(AML::NameString::from_string("_BST"_sv)))); |
| 150 | if (!bst_ref || bst_ref->node.type != AML::Node::Type::Method || bst_ref->node.as.method.arg_count != 0) |
| 151 | { |
| 152 | dwarnln("Battery {} does not have _BST or it is invalid", battery); |
| 153 | continue; |
| 154 | } |
| 155 | |
| 156 | auto battery_name = BAN::StringView(reinterpret_cast<const char*>(&battery.parts.back()), 4); |
| 157 | auto battery_inode = TRY(TmpDirectoryInode::create_new(DevFileSystem::get(), 0555, 0, 0, *base_inode)); |
| 158 | TRY(base_inode->link_inode(*battery_inode, battery_name)); |
| 159 | |
| 160 | auto cap_full_inode = TRY(BatteryInfoInode::create_new(m_acpi_namespace, battery, "_BIF"_sv, 2, 0444, 0, 0)); |
| 161 | TRY(battery_inode->link_inode(*cap_full_inode, "capacity_full"_sv)); |
| 162 | |
| 163 | auto cap_now_inode = TRY(BatteryInfoInode::create_new(m_acpi_namespace, battery, "_BST"_sv, 2, 0444, 0, 0)); |
no test coverage detected