15c7cc545SPatrick Venture /** 25c7cc545SPatrick Venture * Copyright 2017 Google Inc. 35c7cc545SPatrick Venture * 45c7cc545SPatrick Venture * Licensed under the Apache License, Version 2.0 (the "License"); 55c7cc545SPatrick Venture * you may not use this file except in compliance with the License. 65c7cc545SPatrick Venture * You may obtain a copy of the License at 75c7cc545SPatrick Venture * 85c7cc545SPatrick Venture * http://www.apache.org/licenses/LICENSE-2.0 95c7cc545SPatrick Venture * 105c7cc545SPatrick Venture * Unless required by applicable law or agreed to in writing, software 115c7cc545SPatrick Venture * distributed under the License is distributed on an "AS IS" BASIS, 125c7cc545SPatrick Venture * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c7cc545SPatrick Venture * See the License for the specific language governing permissions and 145c7cc545SPatrick Venture * limitations under the License. 155c7cc545SPatrick Venture */ 165c7cc545SPatrick Venture 175c7cc545SPatrick Venture #include "pid/builder.hpp" 185c7cc545SPatrick Venture 19da4a5dd1SPatrick Venture #include "conf.hpp" 2022c257abSJames Feist #include "pid/controller.hpp" 21da4a5dd1SPatrick Venture #include "pid/fancontroller.hpp" 2222c257abSJames Feist #include "pid/stepwisecontroller.hpp" 23da4a5dd1SPatrick Venture #include "pid/thermalcontroller.hpp" 247a98c19aSPatrick Venture #include "pid/zone.hpp" 257a98c19aSPatrick Venture #include "pid/zone_interface.hpp" 26da4a5dd1SPatrick Venture 27a83a3eccSPatrick Venture #include <sdbusplus/bus.hpp> 28a83a3eccSPatrick Venture 29b748b68cSPatrick Venture #include <cstdint> 305c7cc545SPatrick Venture #include <iostream> 315c7cc545SPatrick Venture #include <memory> 32b748b68cSPatrick Venture #include <string> 335c7cc545SPatrick Venture #include <unordered_map> 34b748b68cSPatrick Venture #include <vector> 355c7cc545SPatrick Venture 36a076487aSPatrick Venture namespace pid_control 37a076487aSPatrick Venture { 38a076487aSPatrick Venture 395c7cc545SPatrick Venture static constexpr bool deferSignals = true; 405c7cc545SPatrick Venture static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone"; 415c7cc545SPatrick Venture 427af157b1SPatrick Venture static std::string getControlPath(int64_t zone) 435c7cc545SPatrick Venture { 445c7cc545SPatrick Venture return std::string(objectPath) + std::to_string(zone); 455c7cc545SPatrick Venture } 465c7cc545SPatrick Venture 475301aae3SJohnathan Mantey std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> 487e3f8abeSPatrick Venture buildZones(const std::map<int64_t, conf::PIDConf>& zonePids, 49*1df9e879SPatrick Venture std::map<int64_t, conf::ZoneConfig>& zoneConfigs, 50f3252315SPatrick Venture SensorManager& mgr, sdbusplus::bus::bus& modeControlBus) 515c7cc545SPatrick Venture { 525301aae3SJohnathan Mantey std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> zones; 535c7cc545SPatrick Venture 542a50eda8SPatrick Venture for (const auto& [zoneId, pidConfig] : zonePids) 555c7cc545SPatrick Venture { 565c7cc545SPatrick Venture /* The above shouldn't be necessary but is, and I am having trouble 575c7cc545SPatrick Venture * locating my notes on why. If I recall correctly it was casting it 585c7cc545SPatrick Venture * down to a byte in at least some cases causing weird behaviors. 595c7cc545SPatrick Venture */ 605c7cc545SPatrick Venture auto zoneConf = zoneConfigs.find(zoneId); 615c7cc545SPatrick Venture if (zoneConf == zoneConfigs.end()) 625c7cc545SPatrick Venture { 635c7cc545SPatrick Venture /* The Zone doesn't have a configuration, bail. */ 645c7cc545SPatrick Venture static constexpr auto err = 655c7cc545SPatrick Venture "Bailing during load, missing Zone Configuration"; 665c7cc545SPatrick Venture std::cerr << err << std::endl; 675c7cc545SPatrick Venture throw std::runtime_error(err); 685c7cc545SPatrick Venture } 695c7cc545SPatrick Venture 705301aae3SJohnathan Mantey auto zone = std::make_shared<DbusPidZone>( 713484bedaSJames Feist zoneId, zoneConf->second.minThermalOutput, 728e2fdb34SPatrick Venture zoneConf->second.failsafePercent, mgr, modeControlBus, 732a50eda8SPatrick Venture getControlPath(zoneId).c_str(), deferSignals); 745c7cc545SPatrick Venture 750bbeaf84SPatrick Venture std::cerr << "Zone Id: " << zone->getZoneID() << "\n"; 765c7cc545SPatrick Venture 775c7cc545SPatrick Venture // For each PID create a Controller and a Sensor. 782a50eda8SPatrick Venture for (const auto& [name, info] : pidConfig) 795c7cc545SPatrick Venture { 805c7cc545SPatrick Venture std::vector<std::string> inputs; 815c7cc545SPatrick Venture std::cerr << "PID name: " << name << "\n"; 825c7cc545SPatrick Venture 835c7cc545SPatrick Venture /* 845c7cc545SPatrick Venture * TODO(venture): Need to check if input is known to the 855c7cc545SPatrick Venture * SensorManager. 865c7cc545SPatrick Venture */ 872a50eda8SPatrick Venture if (info.type == "fan") 885c7cc545SPatrick Venture { 892a50eda8SPatrick Venture for (const auto& i : info.inputs) 905c7cc545SPatrick Venture { 915c7cc545SPatrick Venture inputs.push_back(i); 925c7cc545SPatrick Venture zone->addFanInput(i); 935c7cc545SPatrick Venture } 945c7cc545SPatrick Venture 95563a356fSPatrick Venture auto pid = FanController::createFanPid(zone.get(), name, inputs, 962a50eda8SPatrick Venture info.pidInfo); 975c7cc545SPatrick Venture zone->addFanPID(std::move(pid)); 985c7cc545SPatrick Venture } 992a50eda8SPatrick Venture else if (isThermalType(info.type)) 1005c7cc545SPatrick Venture { 1012a50eda8SPatrick Venture for (const auto& i : info.inputs) 1025c7cc545SPatrick Venture { 1035c7cc545SPatrick Venture inputs.push_back(i); 1045c7cc545SPatrick Venture zone->addThermalInput(i); 1055c7cc545SPatrick Venture } 1065c7cc545SPatrick Venture 107563a356fSPatrick Venture auto pid = ThermalController::createThermalPid( 1082a50eda8SPatrick Venture zone.get(), name, inputs, info.setpoint, info.pidInfo, 1092a50eda8SPatrick Venture getThermalType(info.type)); 11022c257abSJames Feist 1115c7cc545SPatrick Venture zone->addThermalPID(std::move(pid)); 1125c7cc545SPatrick Venture } 1132a50eda8SPatrick Venture else if (info.type == "stepwise") 11422c257abSJames Feist { 1152a50eda8SPatrick Venture for (const auto& i : info.inputs) 11622c257abSJames Feist { 11722c257abSJames Feist inputs.push_back(i); 11822c257abSJames Feist zone->addThermalInput(i); 11922c257abSJames Feist } 120563a356fSPatrick Venture auto stepwise = StepwiseController::createStepwiseController( 1212a50eda8SPatrick Venture zone.get(), name, inputs, info.stepwiseInfo); 12222c257abSJames Feist zone->addThermalPID(std::move(stepwise)); 12322c257abSJames Feist } 1245c7cc545SPatrick Venture 1255c7cc545SPatrick Venture std::cerr << "inputs: "; 1264a2dc4d8SPatrick Venture for (const auto& i : inputs) 1275c7cc545SPatrick Venture { 1285c7cc545SPatrick Venture std::cerr << i << ", "; 1295c7cc545SPatrick Venture } 1305c7cc545SPatrick Venture std::cerr << "\n"; 1315c7cc545SPatrick Venture } 1325c7cc545SPatrick Venture 1335c7cc545SPatrick Venture zone->emit_object_added(); 1345c7cc545SPatrick Venture zones[zoneId] = std::move(zone); 1355c7cc545SPatrick Venture } 1365c7cc545SPatrick Venture 1375c7cc545SPatrick Venture return zones; 1385c7cc545SPatrick Venture } 139a076487aSPatrick Venture 140a076487aSPatrick Venture } // namespace pid_control 141