blob: 25a9df81a3f2fe174450402474a33bf4435835af [file] [log] [blame]
Norman Jamese7594922015-08-27 14:25:24 -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 <argp.h>
8#include <sys/stat.h>
9#include <sys/mman.h>
Norman James362a80f2015-09-14 14:04:39 -050010#include "interfaces/openbmc_intf.h"
Norman Jamese7594922015-08-27 14:25:24 -050011#include "gpio.h"
12
13
Norman James32e74e22015-09-15 21:28:06 -050014int gpio_writec(GPIO* gpio, char value)
Norman Jamese7594922015-08-27 14:25:24 -050015{
Norman James65a295a2015-09-26 22:21:10 -050016 g_assert (gpio != NULL);
Norman James32e74e22015-09-15 21:28:06 -050017 int rc = GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -050018 char buf[1];
19 buf[0] = value;
20 if (write(gpio->fd, buf, 1) != 1)
21 {
Norman James32e74e22015-09-15 21:28:06 -050022 rc = GPIO_WRITE_ERROR;
23 }
24 return rc;
Norman Jamese7594922015-08-27 14:25:24 -050025}
26
Norman James32e74e22015-09-15 21:28:06 -050027int gpio_write(GPIO* gpio, uint8_t value)
Norman Jamese7594922015-08-27 14:25:24 -050028{
Norman James65a295a2015-09-26 22:21:10 -050029 g_assert (gpio != NULL);
Norman James32e74e22015-09-15 21:28:06 -050030 int rc = GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -050031 char buf[1];
32 buf[0] = '0';
33 if (value==1)
34 {
35 buf[0]='1';
36 }
37 if (write(gpio->fd, buf, 1) != 1)
38 {
Norman James32e74e22015-09-15 21:28:06 -050039 rc = GPIO_WRITE_ERROR;
40 }
41 return rc;
Norman Jamese7594922015-08-27 14:25:24 -050042}
43
Norman James88872672015-09-21 16:51:35 -050044int gpio_read(GPIO* gpio, uint8_t *value)
Norman Jamese7594922015-08-27 14:25:24 -050045{
Norman James65a295a2015-09-26 22:21:10 -050046 g_assert (gpio != NULL);
Norman Jamese7594922015-08-27 14:25:24 -050047 char buf[1];
Norman James32e74e22015-09-15 21:28:06 -050048 int r = GPIO_OK;
Norman James8abb50c2015-09-16 10:58:16 -050049 if (gpio->fd <= 0)
Norman Jamese7594922015-08-27 14:25:24 -050050 {
Norman James8abb50c2015-09-16 10:58:16 -050051 r = GPIO_ERROR;
52 }
53 else
54 {
55 if (read(gpio->fd,&buf,1) != 1)
56 {
Norman James8abb50c2015-09-16 10:58:16 -050057 r = GPIO_READ_ERROR;
Norman James32e74e22015-09-15 21:28:06 -050058 } else {
Norman James8abb50c2015-09-16 10:58:16 -050059 if (buf[0]=='1') {
60 *value = 1;
61 } else {
62 *value = 0;
63 }
Norman James32e74e22015-09-15 21:28:06 -050064 }
Norman Jamese7594922015-08-27 14:25:24 -050065 }
Norman James32e74e22015-09-15 21:28:06 -050066 return r;
Norman Jamese7594922015-08-27 14:25:24 -050067}
Norman James32e74e22015-09-15 21:28:06 -050068int gpio_clock_cycle(GPIO* gpio, int num_clks) {
Norman James65a295a2015-09-26 22:21:10 -050069 g_assert (gpio != NULL);
Norman Jamese7594922015-08-27 14:25:24 -050070 int i=0;
Norman James32e74e22015-09-15 21:28:06 -050071 int r=GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -050072 for (i=0;i<num_clks;i++) {
Norman James32e74e22015-09-15 21:28:06 -050073 if (gpio_writec(gpio,'0') == -1) {
74 r = GPIO_WRITE_ERROR;
75 break;
76 }
77 if (gpio_writec(gpio,'1') == -1) {
78 r = GPIO_WRITE_ERROR;
79 break;
80 }
Norman Jamese7594922015-08-27 14:25:24 -050081 }
Norman James32e74e22015-09-15 21:28:06 -050082 return r;
Norman Jamese7594922015-08-27 14:25:24 -050083}
84
85// Gets the gpio device path from gpio manager object
Norman James32e74e22015-09-15 21:28:06 -050086int gpio_init(GDBusConnection *connection, GPIO* gpio)
Norman Jamese7594922015-08-27 14:25:24 -050087{
Norman James32e74e22015-09-15 21:28:06 -050088 int rc = GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -050089 GDBusProxy *proxy;
90 GError *error;
91 GVariant *result;
92
93 error = NULL;
94 g_assert_no_error (error);
95 error = NULL;
96 proxy = g_dbus_proxy_new_sync (connection,
97 G_DBUS_PROXY_FLAGS_NONE,
98 NULL, /* GDBusInterfaceInfo */
Norman Jamesddb97382015-08-27 21:31:31 -050099 "org.openbmc.managers.System", /* name */
100 "/org/openbmc/managers/System", /* object path */
101 "org.openbmc.managers.System", /* interface */
Norman Jamese7594922015-08-27 14:25:24 -0500102 NULL, /* GCancellable */
103 &error);
Norman James32e74e22015-09-15 21:28:06 -0500104 if (error != NULL) {
105 return GPIO_LOOKUP_ERROR;
106 }
Norman Jamese7594922015-08-27 14:25:24 -0500107
108 result = g_dbus_proxy_call_sync (proxy,
Norman Jamesddb97382015-08-27 21:31:31 -0500109 "gpioInit",
Norman Jamese7594922015-08-27 14:25:24 -0500110 g_variant_new ("(s)", gpio->name),
111 G_DBUS_CALL_FLAGS_NONE,
112 -1,
113 NULL,
114 &error);
115
Norman James32e74e22015-09-15 21:28:06 -0500116 if (error != NULL) {
117 return GPIO_LOOKUP_ERROR;
118 }
Norman Jamese7594922015-08-27 14:25:24 -0500119 g_assert (result != NULL);
120 g_variant_get (result, "(&si&s)", &gpio->dev,&gpio->num,&gpio->direction);
121 g_print("GPIO Lookup: %s = %d,%s\n",gpio->name,gpio->num,gpio->direction);
122
123 //export and set direction
124 char dev[254];
125 char data[4];
Norman James88872672015-09-21 16:51:35 -0500126 int fd;
Norman James32e74e22015-09-15 21:28:06 -0500127 do {
Norman James88872672015-09-21 16:51:35 -0500128 struct stat st;
129
Norman James5a7cc8d2015-10-06 12:31:06 -0500130 sprintf(dev,"%s/gpio%d/value",gpio->dev,gpio->num);
131 //check if gpio is exported, if not export
Norman James88872672015-09-21 16:51:35 -0500132 int result = stat(dev, &st);
133 if (result)
134 {
135 sprintf(dev,"%s/export",gpio->dev);
136 fd = open(dev, O_WRONLY);
137 if (fd == GPIO_ERROR) {
138 rc = GPIO_OPEN_ERROR;
139 break;
140 }
141 sprintf(data,"%d",gpio->num);
142 rc = write(fd,data,strlen(data));
143 close(fd);
144 if (rc != strlen(data)) {
145 rc = GPIO_WRITE_ERROR;
146 break;
147 }
Norman James32e74e22015-09-15 21:28:06 -0500148 }
Norman James5a7cc8d2015-10-06 12:31:06 -0500149 const char* file = "edge";
150 if (strcmp(gpio->direction,"in")==0 || strcmp(gpio->direction,"out")==0)
151 {
152 file = "direction";
153 }
154 sprintf(dev,"%s/gpio%d/%s",gpio->dev,gpio->num,file);
Norman James32e74e22015-09-15 21:28:06 -0500155 fd = open(dev,O_WRONLY);
156 if (fd == GPIO_ERROR) {
157 rc = GPIO_WRITE_ERROR;
158 break;
159 }
160 rc = write(fd,gpio->direction,strlen(gpio->direction));
Norman James88872672015-09-21 16:51:35 -0500161 if (rc != strlen(gpio->direction)) {
162 rc = GPIO_WRITE_ERROR;
163 break;
164 }
165
Norman James32e74e22015-09-15 21:28:06 -0500166 close(fd);
Norman James5a7cc8d2015-10-06 12:31:06 -0500167 rc = GPIO_OK;
Norman James32e74e22015-09-15 21:28:06 -0500168 } while(0);
Norman Jamese7594922015-08-27 14:25:24 -0500169
Norman James32e74e22015-09-15 21:28:06 -0500170 return rc;
Norman Jamese7594922015-08-27 14:25:24 -0500171}
Norman James5a7cc8d2015-10-06 12:31:06 -0500172
173
174
175
Norman James471ab592015-08-30 22:29:40 -0500176char* get_gpio_dev(GPIO* gpio)
177{
178 char* buf;
179 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
180 return buf;
181}
182
Norman James5a7cc8d2015-10-06 12:31:06 -0500183int gpio_open_interrupt(GPIO* gpio, GIOFunc func, gpointer user_data)
184{
185 int rc = GPIO_OK;
Norman James02b77f32015-10-28 18:59:29 -0500186 char buf[255];
Norman James5a7cc8d2015-10-06 12:31:06 -0500187 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
188 gpio->fd = open(buf, O_RDONLY | O_NONBLOCK );
Norman James02b77f32015-10-28 18:59:29 -0500189 gpio->irq_inited = false;
Norman James5a7cc8d2015-10-06 12:31:06 -0500190 if (gpio->fd == -1)
191 {
192 rc = GPIO_OPEN_ERROR;
193 }
194 else
195 {
Norman James02b77f32015-10-28 18:59:29 -0500196 GIOChannel* channel = g_io_channel_unix_new( gpio->fd);
Norman James5a7cc8d2015-10-06 12:31:06 -0500197 guint id = g_io_add_watch( channel, G_IO_PRI, func, user_data );
198 }
199 return rc;
200}
201
Norman Jamese7594922015-08-27 14:25:24 -0500202int gpio_open(GPIO* gpio)
203{
Norman James65a295a2015-09-26 22:21:10 -0500204 g_assert (gpio != NULL);
Norman Jamese7594922015-08-27 14:25:24 -0500205 // open gpio for writing or reading
206 char buf[254];
Norman James32e74e22015-09-15 21:28:06 -0500207 int rc = 0;
Norman James5a7cc8d2015-10-06 12:31:06 -0500208 gpio->fd = -1;
Norman James65a295a2015-09-26 22:21:10 -0500209 if (gpio->direction == NULL) {
210 return GPIO_OPEN_ERROR;
211 }
Norman Jamese7594922015-08-27 14:25:24 -0500212 if (strcmp(gpio->direction,"in")==0)
213 {
214 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
215 gpio->fd = open(buf, O_RDONLY);
216 }
217 else
218 {
219 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
Norman James25571112015-12-15 09:36:28 -0600220 gpio->fd = open(buf, O_RDWR);
Norman Jamese7594922015-08-27 14:25:24 -0500221
222 }
Norman James88872672015-09-21 16:51:35 -0500223 if (gpio->fd == -1) {
224 return GPIO_OPEN_ERROR;
225 }
226 return GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -0500227}
228
229void gpio_close(GPIO* gpio)
230{
231 close(gpio->fd);
232}