blob: 5acde7c2c9139c01e7ee435ae4cd24af1b3c01f0 [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};
Norman Jamesaf915f12015-11-20 09:19:43 -060036bool is_hwmon_valid(HWMON* hwmon)
Norman James5236a8f2015-11-05 20:39:31 -060037{
Norman Jamesaf915f12015-11-20 09:19:43 -060038 int fd = open(hwmon->filename, O_RDONLY);
39 if (fd == -1)
40 {
41 g_print("ERROR hwmon is not valid: %s\n",hwmon->filename);
42 return false;
Norman James5236a8f2015-11-05 20:39:31 -060043 }
Norman Jamesaf915f12015-11-20 09:19:43 -060044 close(fd);
45 return true;
46}
Norman James5236a8f2015-11-05 20:39:31 -060047
48static gboolean poll_hwmon(gpointer user_data)
49{
50 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
51 SensorValue *sensor = object_get_sensor_value((Object*)user_data);
52 const gchar* filename = hwmon_get_sysfs_path(hwmon);
53
54 int fd = open(filename, O_RDONLY);
55 if (fd != -1)
56 {
57 char buf[255];
58 if (read(fd,&buf,255) == -1)
59 {
60 g_print("ERROR: Unable to read value: %s\n",filename);
61 } else {
Norman Jamesd396b372015-11-17 13:10:58 -060062 guint32 scale = hwmon_get_scale(hwmon);
63 if (scale == 0)
64 {
65 g_print("ERROR: Invalid scale value of 0\n");
66 scale = 1;
67
68 }
69 guint32 value = atoi(buf)/scale;
Norman James5236a8f2015-11-05 20:39:31 -060070 GVariant* v = NEW_VARIANT_U(value);
Norman Jamesd396b372015-11-17 13:10:58 -060071 GVariant* old_value = sensor_value_get_value(sensor);
72 bool do_set = false;
73 if (old_value == NULL)
74 {
75 do_set = true;
76 }
77 else
78 {
79 if (GET_VARIANT_U(old_value) != value) { do_set = true; }
80 }
81 if (do_set)
82 {
83 g_print("Sensor changed: %s,%d\n",filename,value);
84 GVariant* v = NEW_VARIANT_U(value);
85 const gchar* units = sensor_value_get_units(sensor);
86 sensor_value_set_value(sensor,v);
87 sensor_value_emit_changed(sensor,v,units);
88 }
Norman James5236a8f2015-11-05 20:39:31 -060089 }
90 close(fd);
Norman James5e2f46a2015-11-06 02:21:53 -060091 } else {
92 g_print("ERROR - hwmons: File %s doesn't exist\n",filename);
Norman James5236a8f2015-11-05 20:39:31 -060093 }
94
95 return TRUE;
96}
97static gboolean
98on_set_value (SensorValue *sensor,
99 GDBusMethodInvocation *invocation,
100 GVariant* v_value,
101 gpointer user_data)
102{
103 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
104 const gchar* filename = hwmon_get_sysfs_path(hwmon);
105
106 int fd = open(filename, O_WRONLY);
107 if (fd != -1)
108 {
109 char buf[255];
110 guint32 value = GET_VARIANT_U(v_value);
111 sprintf(buf,"%d",value);
112 if (write(fd, buf, 255) == -1)
113 {
114 g_print("ERROR: Unable to read value: %s\n",filename);
115 }
116 close(fd);
117 }
118 sensor_value_complete_set_value(sensor,invocation);
119 return TRUE;
120}
121
122
123
124static void
125on_bus_acquired (GDBusConnection *connection,
126 const gchar *name,
127 gpointer user_data)
128{
129 ObjectSkeleton *object;
130
131 cmdline *cmd = user_data;
132
133
134 manager = g_dbus_object_manager_server_new (dbus_object_path);
135 int i = 0;
136 for (i=0;i<NUM_HWMONS;i++)
137 {
Norman Jamesaf915f12015-11-20 09:19:43 -0600138 if (!is_hwmon_valid(&hwmons[i])) { continue; }
Norman James5236a8f2015-11-05 20:39:31 -0600139 gchar *s;
140 s = g_strdup_printf ("%s/%s",dbus_object_path,hwmons[i].name);
141 object = object_skeleton_new (s);
142 g_free (s);
143
144 Hwmon *hwmon = hwmon_skeleton_new ();
145 object_skeleton_set_hwmon (object, hwmon);
146 g_object_unref (hwmon);
147
148 SensorValue *sensor = sensor_value_skeleton_new ();
149 object_skeleton_set_sensor_value (object, sensor);
150 g_object_unref (sensor);
151
152 ObjectMapper* mapper = object_mapper_skeleton_new ();
153 object_skeleton_set_object_mapper (object, mapper);
154 g_object_unref (mapper);
155
156 hwmon_set_sysfs_path(hwmon,hwmons[i].filename);
Norman Jamesd396b372015-11-17 13:10:58 -0600157 hwmon_set_scale(hwmon,hwmons[i].scale);
158 sensor_value_set_units(sensor,hwmons[i].units);
Norman James5236a8f2015-11-05 20:39:31 -0600159
160 //define method callbacks here
161 g_signal_connect (sensor,
162 "handle-set-value",
163 G_CALLBACK (on_set_value),
164 object); /* user_data */
165
166
167 if (hwmons[i].poll_interval > 0) {
168 g_timeout_add(hwmons[i].poll_interval, poll_hwmon, object);
169 }
170 /* Export the object (@manager takes its own reference to @object) */
171 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
172 g_object_unref (object);
173 }
174 /* Export all objects */
175 g_dbus_object_manager_server_set_connection (manager, connection);
176 emit_object_added((GDBusObjectManager*)manager);
177}
178
179
180static void
181on_name_acquired (GDBusConnection *connection,
182 const gchar *name,
183 gpointer user_data)
184{
185}
186
187static void
188on_name_lost (GDBusConnection *connection,
189 const gchar *name,
190 gpointer user_data)
191{
192}
193
194
195gint
196main (gint argc, gchar *argv[])
197{
198 GMainLoop *loop;
199 cmdline cmd;
200 cmd.argc = argc;
201 cmd.argv = argv;
202
203 guint id;
204 loop = g_main_loop_new (NULL, FALSE);
205
206 id = g_bus_own_name (DBUS_TYPE,
207 dbus_name,
208 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
209 G_BUS_NAME_OWNER_FLAGS_REPLACE,
210 on_bus_acquired,
211 on_name_acquired,
212 on_name_lost,
213 &cmd,
214 NULL);
215
216 g_main_loop_run (loop);
217
218 g_bus_unown_name (id);
219 g_main_loop_unref (loop);
220 return 0;
221}