blob: a2906536f8b477c0b7c6119ade12c8ae4e127487 [file] [log] [blame]
Norman James26072c02015-08-25 07:14:29 -05001#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <sys/stat.h>
8#include <sys/mman.h>
Norman Jamese2765102015-08-19 22:00:55 -05009#include "interfaces/power_control.h"
Norman James3f97c5d2015-08-26 17:44:14 -050010#include "objects/openbmc_utilities.h"
Norman Jamese2765102015-08-19 22:00:55 -050011
12/* ---------------------------------------------------------------------------------------------------- */
Norman James26072c02015-08-25 07:14:29 -050013static const gchar* dbus_object_path = "/org/openbmc/control/Power";
14static const gchar* dbus_name = "org.openbmc.control.Power";
15
Norman James3f97c5d2015-08-26 17:44:14 -050016GPIO power_pin = (GPIO){ "POWER_PIN" };
17GPIO pgood = (GPIO){ "PGOOD" };
Norman Jamese2765102015-08-19 22:00:55 -050018
19static GDBusObjectManagerServer *manager = NULL;
Norman James3f97c5d2015-08-26 17:44:14 -050020static ControlPower *control_power = NULL;
Norman Jamese2765102015-08-19 22:00:55 -050021
22static gboolean
Norman James3f97c5d2015-08-26 17:44:14 -050023on_set_power_state (ControlPower *pwr,
Norman Jamese2765102015-08-19 22:00:55 -050024 GDBusMethodInvocation *invocation,
25 guint state,
26 gpointer user_data)
27{
Norman James3f97c5d2015-08-26 17:44:14 -050028 if (state > 1)
29 {
30 g_dbus_method_invocation_return_dbus_error (invocation,
31 "org.openbmc.ControlPower.Error.Failed",
32 "Invalid power state");
33 return TRUE;
34 }
35 if (state == control_power_get_state(pwr))
36 {
37 g_dbus_method_invocation_return_dbus_error (invocation,
38 "org.openbmc.ControlPower.Error.Failed",
39 "Power Control is already at requested state");
40 return TRUE;
41 }
Norman Jamese2765102015-08-19 22:00:55 -050042
Norman James3f97c5d2015-08-26 17:44:14 -050043 //go ahead and return from method call
44 control_power_complete_set_power_state(pwr,invocation);
45
46 g_print("Set power state: %d\n",state);
47 gpio_open(&power_pin);
48 gpio_write(&power_pin,!state);
49 gpio_close(&power_pin);
50
51 control_power_set_state(pwr,state);
52 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -050053}
54
55static gboolean
Norman James3f97c5d2015-08-26 17:44:14 -050056on_get_power_state (ControlPower *pwr,
Norman Jamese2765102015-08-19 22:00:55 -050057 GDBusMethodInvocation *invocation,
58 gpointer user_data)
59{
Norman James3f97c5d2015-08-26 17:44:14 -050060 guint pgood = control_power_get_pgood(pwr);
61 control_power_complete_get_power_state(pwr,invocation,pgood);
62 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -050063}
64
65static void
66on_bus_acquired (GDBusConnection *connection,
67 const gchar *name,
68 gpointer user_data)
69{
Norman James3f97c5d2015-08-26 17:44:14 -050070 ObjectSkeleton *object;
71 g_print ("Acquired a message bus connection: %s\n",name);
Norman Jamese2765102015-08-19 22:00:55 -050072
Norman James3f97c5d2015-08-26 17:44:14 -050073 manager = g_dbus_object_manager_server_new (dbus_object_path);
74 gchar *s;
75 s = g_strdup_printf ("%s/0",dbus_object_path);
76 object = object_skeleton_new (s);
77 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -050078
Norman James3f97c5d2015-08-26 17:44:14 -050079 control_power = control_power_skeleton_new ();
80 object_skeleton_set_control_power (object, control_power);
81 g_object_unref (control_power);
Norman Jamese2765102015-08-19 22:00:55 -050082
Norman James3f97c5d2015-08-26 17:44:14 -050083 //define method callbacks here
84 g_signal_connect (control_power,
Norman Jamese2765102015-08-19 22:00:55 -050085 "handle-set-power-state",
86 G_CALLBACK (on_set_power_state),
87 NULL); /* user_data */
88
Norman James3f97c5d2015-08-26 17:44:14 -050089 g_signal_connect (control_power,
Norman Jamese2765102015-08-19 22:00:55 -050090 "handle-get-power-state",
91 G_CALLBACK (on_get_power_state),
92 NULL); /* user_data */
93
Norman James3f97c5d2015-08-26 17:44:14 -050094 /* Export the object (@manager takes its own reference to @object) */
95 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
96 g_object_unref (object);
Norman Jamese2765102015-08-19 22:00:55 -050097
Norman James3f97c5d2015-08-26 17:44:14 -050098 /* Export all objects */
99 g_dbus_object_manager_server_set_connection (manager, connection);
100
101 // get gpio device paths
102 gpio_init(connection,&power_pin);
103 gpio_init(connection,&pgood);
104 gpio_open(&pgood);
Norman Jamese2765102015-08-19 22:00:55 -0500105}
106
107static void
108on_name_acquired (GDBusConnection *connection,
109 const gchar *name,
110 gpointer user_data)
111{
112 g_print ("Acquired the name %s\n", name);
113}
114
115static void
116on_name_lost (GDBusConnection *connection,
117 const gchar *name,
118 gpointer user_data)
119{
120 g_print ("Lost the name %s\n", name);
121}
122
123static gboolean
124poll_pgood()
125{
Norman James3f97c5d2015-08-26 17:44:14 -0500126 if (pgood.fd >= 0)
127 {
128 uint8_t gpio = gpio_read(&pgood);
Norman Jamese2765102015-08-19 22:00:55 -0500129
Norman James3f97c5d2015-08-26 17:44:14 -0500130 //if changed, set property and emit signal
131 if (gpio != control_power_get_pgood(control_power))
132 {
133 control_power_set_pgood(control_power,gpio);
134 if (gpio==0)
135 {
136 control_power_emit_power_lost(control_power);
137 }
138 else
139 {
140 control_power_emit_power_good(control_power);
141 }
142 }
143 }
144 else
145 {
146 //TODO: error handling
147 printf("Unable to read pgood\n");
148 }
149 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500150}
151
Norman James3f97c5d2015-08-26 17:44:14 -0500152
153
154/*----------------------------------------------------------------*/
155/* Main Event Loop */
156
Norman Jamese2765102015-08-19 22:00:55 -0500157gint
158main (gint argc, gchar *argv[])
159{
160 GMainLoop *loop;
161
162 guint id;
163 //g_type_init ();
164 loop = g_main_loop_new (NULL, FALSE);
165
166 id = g_bus_own_name (G_BUS_TYPE_SESSION,
Norman James26072c02015-08-25 07:14:29 -0500167 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500168 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
169 G_BUS_NAME_OWNER_FLAGS_REPLACE,
170 on_bus_acquired,
171 on_name_acquired,
172 on_name_lost,
173 loop,
174 NULL);
175
176 g_timeout_add(5000, poll_pgood, NULL);
177 g_main_loop_run (loop);
178
179 g_bus_unown_name (id);
180 g_main_loop_unref (loop);
181 return 0;
182}