blob: 5d3315f910b19e2a45ffa298cd2d68d02bd4746b [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 James10ff6a32015-08-27 14:24:17 -050010#include "openbmc.h"
11#include "gpio.h"
Norman Jamese2765102015-08-19 22:00:55 -050012
13/* ---------------------------------------------------------------------------------------------------- */
Norman James26072c02015-08-25 07:14:29 -050014static const gchar* dbus_object_path = "/org/openbmc/control/Power";
15static const gchar* dbus_name = "org.openbmc.control.Power";
16
Norman James3f97c5d2015-08-26 17:44:14 -050017GPIO power_pin = (GPIO){ "POWER_PIN" };
18GPIO pgood = (GPIO){ "PGOOD" };
Norman Jamese2765102015-08-19 22:00:55 -050019
20static GDBusObjectManagerServer *manager = 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 James10ff6a32015-08-27 14:24:17 -050072 cmdline *cmd = user_data;
73 if (cmd->argc < 2)
74 {
75 g_print("No objects created. Put object name(s) on command line\n");
76 return;
77 }
78 manager = g_dbus_object_manager_server_new (dbus_object_path);
79 int i=0;
80 for (i=1;i<cmd->argc;i++)
81 {
82 gchar *s;
83 s = g_strdup_printf ("%s/%s",dbus_object_path,cmd->argv[i]);
84 object = object_skeleton_new (s);
85 g_free (s);
Norman Jamese2765102015-08-19 22:00:55 -050086
Norman James10ff6a32015-08-27 14:24:17 -050087 ControlPower* control_power = control_power_skeleton_new ();
88 object_skeleton_set_control_power (object, control_power);
89 g_object_unref (control_power);
Norman Jamese2765102015-08-19 22:00:55 -050090
Norman James10ff6a32015-08-27 14:24:17 -050091 //define method callbacks here
92 g_signal_connect (control_power,
93 "handle-set-power-state",
94 G_CALLBACK (on_set_power_state),
95 NULL); /* user_data */
Norman Jamese2765102015-08-19 22:00:55 -050096
Norman James10ff6a32015-08-27 14:24:17 -050097 g_signal_connect (control_power,
98 "handle-get-power-state",
99 G_CALLBACK (on_get_power_state),
100 NULL); /* user_data */
Norman Jamese2765102015-08-19 22:00:55 -0500101
Norman James10ff6a32015-08-27 14:24:17 -0500102 /* Export the object (@manager takes its own reference to @object) */
103 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
104 g_object_unref (object);
105 }
Norman James3f97c5d2015-08-26 17:44:14 -0500106 /* Export all objects */
107 g_dbus_object_manager_server_set_connection (manager, connection);
108
109 // get gpio device paths
110 gpio_init(connection,&power_pin);
111 gpio_init(connection,&pgood);
112 gpio_open(&pgood);
Norman Jamese2765102015-08-19 22:00:55 -0500113}
114
115static void
116on_name_acquired (GDBusConnection *connection,
117 const gchar *name,
118 gpointer user_data)
119{
120 g_print ("Acquired the name %s\n", name);
121}
122
123static void
124on_name_lost (GDBusConnection *connection,
125 const gchar *name,
126 gpointer user_data)
127{
128 g_print ("Lost the name %s\n", name);
129}
130
Norman James10ff6a32015-08-27 14:24:17 -0500131static gboolean poll_pgood(gpointer user_data)
Norman Jamese2765102015-08-19 22:00:55 -0500132{
Norman James10ff6a32015-08-27 14:24:17 -0500133 ControlPower *control_power = object_get_control_power((Object*)user_data);
134
Norman James3f97c5d2015-08-26 17:44:14 -0500135 if (pgood.fd >= 0)
136 {
137 uint8_t gpio = gpio_read(&pgood);
Norman Jamese2765102015-08-19 22:00:55 -0500138
Norman James3f97c5d2015-08-26 17:44:14 -0500139 //if changed, set property and emit signal
140 if (gpio != control_power_get_pgood(control_power))
141 {
142 control_power_set_pgood(control_power,gpio);
143 if (gpio==0)
144 {
145 control_power_emit_power_lost(control_power);
146 }
147 else
148 {
149 control_power_emit_power_good(control_power);
150 }
151 }
152 }
153 else
154 {
155 //TODO: error handling
156 printf("Unable to read pgood\n");
157 }
158 return TRUE;
Norman Jamese2765102015-08-19 22:00:55 -0500159}
160
Norman James3f97c5d2015-08-26 17:44:14 -0500161
162
163/*----------------------------------------------------------------*/
164/* Main Event Loop */
165
Norman Jamese2765102015-08-19 22:00:55 -0500166gint
167main (gint argc, gchar *argv[])
168{
169 GMainLoop *loop;
Norman James90caa3c2015-08-27 21:28:48 -0500170 cmdline cmd;
171 cmd.argc = argc;
172 cmd.argv = argv;
Norman Jamese2765102015-08-19 22:00:55 -0500173
174 guint id;
Norman Jamese2765102015-08-19 22:00:55 -0500175 loop = g_main_loop_new (NULL, FALSE);
176
177 id = g_bus_own_name (G_BUS_TYPE_SESSION,
Norman James26072c02015-08-25 07:14:29 -0500178 dbus_name,
Norman Jamese2765102015-08-19 22:00:55 -0500179 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
180 G_BUS_NAME_OWNER_FLAGS_REPLACE,
181 on_bus_acquired,
182 on_name_acquired,
183 on_name_lost,
Norman James90caa3c2015-08-27 21:28:48 -0500184 &cmd,
Norman Jamese2765102015-08-19 22:00:55 -0500185 NULL);
186
187 g_timeout_add(5000, poll_pgood, NULL);
188 g_main_loop_run (loop);
189
190 g_bus_unown_name (id);
191 g_main_loop_unref (loop);
192 return 0;
193}