blob: 9f260704955ccc35db2cccd78b5dfa668e9ea6b6 [file] [log] [blame]
Norman James5236a8f2015-11-05 20:39:31 -06001#include "interfaces/openbmc_intf.h"
2#include <stdio.h>
3#include <fcntl.h>
4#include "openbmc.h"
5#include "gpio.h"
6#include "object_mapper.h"
7
8/* ---------------------------------------------------------------------------------------------------- */
9static const gchar* dbus_object_path = "/org/openbmc/sensors";
10static const gchar* dbus_name = "org.openbmc.sensors.hwmon";
11
12static GDBusObjectManagerServer *manager = NULL;
13
14typedef struct {
Norman Jamesd396b372015-11-17 13:10:58 -060015 const gchar* filename;
16 const gchar* name;
Norman James5236a8f2015-11-05 20:39:31 -060017 int poll_interval;
Norman Jamesd396b372015-11-17 13:10:58 -060018 const gchar* units;
19 int scale;
Norman James5236a8f2015-11-05 20:39:31 -060020 int fd;
21} HWMON;
22
Norman James5e2f46a2015-11-06 02:21:53 -060023#define NUM_HWMONS 7
Norman James5236a8f2015-11-05 20:39:31 -060024
Norman James5e2f46a2015-11-06 02:21:53 -060025// TODO: Don't hardcode
26//Hardcoded for barreleye
Norman James5236a8f2015-11-05 20:39:31 -060027HWMON hwmons[NUM_HWMONS] = {
Norman Jamesd396b372015-11-17 13:10:58 -060028 (HWMON){"/sys/class/hwmon/hwmon0/temp1_input","temperature/ambient",3000,"C",1000},
29 (HWMON){"/sys/class/hwmon/hwmon1/pwm1","speed/fan0",30000,"",1},
30 (HWMON){"/sys/class/hwmon/hwmon1/pwm2","speed/fan1",30000,"",1},
31 (HWMON){"/sys/class/hwmon/hwmon1/pwm3","speed/fan2",30000,"",1},
32 (HWMON){"/sys/class/hwmon/hwmon2/pwm1","speed/fan3",30000,"",1},
33 (HWMON){"/sys/class/hwmon/hwmon2/pwm2","speed/fan4",30000,"",1},
34 (HWMON){"/sys/class/hwmon/hwmon2/pwm3","speed/fan5",30000,"",1},
Norman James5236a8f2015-11-05 20:39:31 -060035};
36
37// Gets the gpio device path from gpio manager object
38int hwmon_init(GDBusConnection *connection, HWMON* hwmon)
39{
40 int rc = GPIO_OK;
41 GDBusProxy *proxy;
42 GError *error;
43 GVariant *result;
44
45 error = NULL;
46 g_assert_no_error (error);
47 error = NULL;
48
49 proxy = g_dbus_proxy_new_sync (connection,
50 G_DBUS_PROXY_FLAGS_NONE,
51 NULL, /* GDBusInterfaceInfo */
52 "org.openbmc.managers.System", /* name */
53 "/org/openbmc/managers/System", /* object path */
54 "org.openbmc.managers.System", /* interface */
55 NULL, /* GCancellable */
56 &error);
57 if (error != NULL) {
58 return 1;
59 }
60
61 result = g_dbus_proxy_call_sync (proxy,
62 "hwmonInit",
63 g_variant_new ("(s)", hwmon->filename),
64 G_DBUS_CALL_FLAGS_NONE,
65 -1,
66 NULL,
67 &error);
68
69 if (error != NULL) {
70 return 1;
71 }
72 g_assert (result != NULL);
73 g_variant_get (result, "(&si)", &hwmon->name,&hwmon->poll_interval);
74 g_print("HWMON Lookup: %s = %s,%d\n",hwmon->filename,hwmon->name,hwmon->poll_interval);
75}
76
77static gboolean poll_hwmon(gpointer user_data)
78{
79 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
80 SensorValue *sensor = object_get_sensor_value((Object*)user_data);
81 const gchar* filename = hwmon_get_sysfs_path(hwmon);
82
83 int fd = open(filename, O_RDONLY);
84 if (fd != -1)
85 {
86 char buf[255];
87 if (read(fd,&buf,255) == -1)
88 {
89 g_print("ERROR: Unable to read value: %s\n",filename);
90 } else {
Norman Jamesd396b372015-11-17 13:10:58 -060091 guint32 scale = hwmon_get_scale(hwmon);
92 if (scale == 0)
93 {
94 g_print("ERROR: Invalid scale value of 0\n");
95 scale = 1;
96
97 }
98 guint32 value = atoi(buf)/scale;
Norman James5236a8f2015-11-05 20:39:31 -060099 GVariant* v = NEW_VARIANT_U(value);
Norman Jamesd396b372015-11-17 13:10:58 -0600100 GVariant* old_value = sensor_value_get_value(sensor);
101 bool do_set = false;
102 if (old_value == NULL)
103 {
104 do_set = true;
105 }
106 else
107 {
108 if (GET_VARIANT_U(old_value) != value) { do_set = true; }
109 }
110 if (do_set)
111 {
112 g_print("Sensor changed: %s,%d\n",filename,value);
113 GVariant* v = NEW_VARIANT_U(value);
114 const gchar* units = sensor_value_get_units(sensor);
115 sensor_value_set_value(sensor,v);
116 sensor_value_emit_changed(sensor,v,units);
117 }
Norman James5236a8f2015-11-05 20:39:31 -0600118 }
119 close(fd);
Norman James5e2f46a2015-11-06 02:21:53 -0600120 } else {
121 g_print("ERROR - hwmons: File %s doesn't exist\n",filename);
Norman James5236a8f2015-11-05 20:39:31 -0600122 }
123
124 return TRUE;
125}
126static gboolean
127on_set_value (SensorValue *sensor,
128 GDBusMethodInvocation *invocation,
129 GVariant* v_value,
130 gpointer user_data)
131{
132 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
133 const gchar* filename = hwmon_get_sysfs_path(hwmon);
134
135 int fd = open(filename, O_WRONLY);
136 if (fd != -1)
137 {
138 char buf[255];
139 guint32 value = GET_VARIANT_U(v_value);
140 sprintf(buf,"%d",value);
141 if (write(fd, buf, 255) == -1)
142 {
143 g_print("ERROR: Unable to read value: %s\n",filename);
144 }
145 close(fd);
146 }
147 sensor_value_complete_set_value(sensor,invocation);
148 return TRUE;
149}
150
151
152
153static void
154on_bus_acquired (GDBusConnection *connection,
155 const gchar *name,
156 gpointer user_data)
157{
158 ObjectSkeleton *object;
159
160 cmdline *cmd = user_data;
161
162
163 manager = g_dbus_object_manager_server_new (dbus_object_path);
164 int i = 0;
165 for (i=0;i<NUM_HWMONS;i++)
166 {
Norman James5236a8f2015-11-05 20:39:31 -0600167 gchar *s;
168 s = g_strdup_printf ("%s/%s",dbus_object_path,hwmons[i].name);
169 object = object_skeleton_new (s);
170 g_free (s);
171
172 Hwmon *hwmon = hwmon_skeleton_new ();
173 object_skeleton_set_hwmon (object, hwmon);
174 g_object_unref (hwmon);
175
176 SensorValue *sensor = sensor_value_skeleton_new ();
177 object_skeleton_set_sensor_value (object, sensor);
178 g_object_unref (sensor);
179
180 ObjectMapper* mapper = object_mapper_skeleton_new ();
181 object_skeleton_set_object_mapper (object, mapper);
182 g_object_unref (mapper);
183
184 hwmon_set_sysfs_path(hwmon,hwmons[i].filename);
Norman Jamesd396b372015-11-17 13:10:58 -0600185 hwmon_set_scale(hwmon,hwmons[i].scale);
186 sensor_value_set_units(sensor,hwmons[i].units);
Norman James5236a8f2015-11-05 20:39:31 -0600187
188 //define method callbacks here
189 g_signal_connect (sensor,
190 "handle-set-value",
191 G_CALLBACK (on_set_value),
192 object); /* user_data */
193
194
195 if (hwmons[i].poll_interval > 0) {
196 g_timeout_add(hwmons[i].poll_interval, poll_hwmon, object);
197 }
198 /* Export the object (@manager takes its own reference to @object) */
199 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
200 g_object_unref (object);
201 }
202 /* Export all objects */
203 g_dbus_object_manager_server_set_connection (manager, connection);
204 emit_object_added((GDBusObjectManager*)manager);
205}
206
207
208static void
209on_name_acquired (GDBusConnection *connection,
210 const gchar *name,
211 gpointer user_data)
212{
213}
214
215static void
216on_name_lost (GDBusConnection *connection,
217 const gchar *name,
218 gpointer user_data)
219{
220}
221
222
223gint
224main (gint argc, gchar *argv[])
225{
226 GMainLoop *loop;
227 cmdline cmd;
228 cmd.argc = argc;
229 cmd.argv = argv;
230
231 guint id;
232 loop = g_main_loop_new (NULL, FALSE);
233
234 id = g_bus_own_name (DBUS_TYPE,
235 dbus_name,
236 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
237 G_BUS_NAME_OWNER_FLAGS_REPLACE,
238 on_bus_acquired,
239 on_name_acquired,
240 on_name_lost,
241 &cmd,
242 NULL);
243
244 g_main_loop_run (loop);
245
246 g_bus_unown_name (id);
247 g_main_loop_unref (loop);
248 return 0;
249}