blob: 1326451ef054e549610f526158bbca1105205a9b [file] [log] [blame]
Matt Spinlere2b25cb2017-04-10 14:33:35 -05001/**
2 * Copyright © 2017 IBM Corporation
3 *
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#include <phosphor-logging/log.hpp>
Dinesh Chinari618027a2017-06-26 23:26:50 -050017#include <phosphor-logging/elog.hpp>
18#include <phosphor-logging/elog-errors.hpp>
19#include <xyz/openbmc_project/Common/error.hpp>
Matt Spinlere2b25cb2017-04-10 14:33:35 -050020#include <string>
21#include "fan.hpp"
22#include "utility.hpp"
Matthew Barth2b3db612017-10-25 10:56:51 -050023#include "sdbusplus.hpp"
Matt Spinlere2b25cb2017-04-10 14:33:35 -050024
25namespace phosphor
26{
27namespace fan
28{
29namespace control
30{
31
Dinesh Chinari618027a2017-06-26 23:26:50 -050032// For throwing exception
33using namespace phosphor::logging;
34using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
35 Error::InternalFailure;
36
Matt Spinlere2b25cb2017-04-10 14:33:35 -050037constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
38constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
39constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed";
40constexpr auto FAN_TARGET_PROPERTY = "Target";
41
42
43Fan::Fan(sdbusplus::bus::bus& bus, const FanDefinition& def):
44 _bus(bus),
45 _name(std::get<fanNamePos>(def))
46{
Matthew Barth2b3db612017-10-25 10:56:51 -050047 std::string path;
Matt Spinlere2b25cb2017-04-10 14:33:35 -050048 auto sensors = std::get<sensorListPos>(def);
49 for (auto& s : sensors)
50 {
Matthew Barth2b3db612017-10-25 10:56:51 -050051 path = FAN_SENSOR_PATH + s;
52 _sensors.emplace_back(path);
53 }
54 // All sensors associated with this fan are set to same target speed,
55 // so only need to read target property from one.
56 if (!path.empty())
57 {
58 _targetSpeed = util::SDBusPlus::getProperty<uint64_t>(
59 bus,
60 path,
61 FAN_SENSOR_CONTROL_INTF,
62 FAN_TARGET_PROPERTY);
Matt Spinlere2b25cb2017-04-10 14:33:35 -050063 }
64}
65
66
67//TODO openbmc/openbmc#1524 Can cache this value when
68//openbmc/openbmc#1496 is resolved.
69std::string Fan::getService(const std::string& sensor)
70{
71 return phosphor::fan::util::getService(sensor,
72 FAN_SENSOR_CONTROL_INTF,
73 _bus);
74}
75
76
77void Fan::setSpeed(uint64_t speed)
78{
79 sdbusplus::message::variant<uint64_t> value = speed;
80 std::string property{FAN_TARGET_PROPERTY};
81
82 for (auto& sensor : _sensors)
83 {
Dinesh Chinari618027a2017-06-26 23:26:50 -050084 auto service = getService(sensor);
Matt Spinlere2b25cb2017-04-10 14:33:35 -050085
Dinesh Chinari618027a2017-06-26 23:26:50 -050086 auto method = _bus.new_method_call(service.c_str(),
Matt Spinlere2b25cb2017-04-10 14:33:35 -050087 sensor.c_str(),
88 PROPERTY_INTERFACE,
89 "Set");
Dinesh Chinari618027a2017-06-26 23:26:50 -050090 method.append(FAN_SENSOR_CONTROL_INTF, property, value);
Matt Spinlere2b25cb2017-04-10 14:33:35 -050091
Dinesh Chinari618027a2017-06-26 23:26:50 -050092 auto response = _bus.call(method);
93 if (response.is_method_error())
Matt Spinlere2b25cb2017-04-10 14:33:35 -050094 {
Dinesh Chinari618027a2017-06-26 23:26:50 -050095 log<level::ERR>(
96 "Failed call to set fan speed ", entry("SENSOR=%s", sensor));
97 elog<InternalFailure>();
Matt Spinlere2b25cb2017-04-10 14:33:35 -050098 }
99 }
Matthew Barth2b3db612017-10-25 10:56:51 -0500100
101 _targetSpeed = speed;
Matt Spinlere2b25cb2017-04-10 14:33:35 -0500102}
103
104}
105}
106}