blob: b4b6139fcc1b76c3dccd68a2c0f26fdec746263d [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
130 sprintf(dev,"%s/gpio%d/direction",gpio->dev,gpio->num);
131 int result = stat(dev, &st);
132 if (result)
133 {
134 sprintf(dev,"%s/export",gpio->dev);
135 fd = open(dev, O_WRONLY);
136 if (fd == GPIO_ERROR) {
137 rc = GPIO_OPEN_ERROR;
138 break;
139 }
140 sprintf(data,"%d",gpio->num);
141 rc = write(fd,data,strlen(data));
142 close(fd);
143 if (rc != strlen(data)) {
144 rc = GPIO_WRITE_ERROR;
145 break;
146 }
Norman James32e74e22015-09-15 21:28:06 -0500147 }
Norman James32e74e22015-09-15 21:28:06 -0500148 sprintf(dev,"%s/gpio%d/direction",gpio->dev,gpio->num);
149 fd = open(dev,O_WRONLY);
150 if (fd == GPIO_ERROR) {
151 rc = GPIO_WRITE_ERROR;
152 break;
153 }
154 rc = write(fd,gpio->direction,strlen(gpio->direction));
Norman James88872672015-09-21 16:51:35 -0500155 if (rc != strlen(gpio->direction)) {
156 rc = GPIO_WRITE_ERROR;
157 break;
158 }
159
Norman James32e74e22015-09-15 21:28:06 -0500160 close(fd);
Norman James88872672015-09-21 16:51:35 -0500161 rc = 0;
Norman James32e74e22015-09-15 21:28:06 -0500162 } while(0);
Norman Jamese7594922015-08-27 14:25:24 -0500163
Norman James32e74e22015-09-15 21:28:06 -0500164 return rc;
Norman Jamese7594922015-08-27 14:25:24 -0500165}
Norman James471ab592015-08-30 22:29:40 -0500166char* get_gpio_dev(GPIO* gpio)
167{
168 char* buf;
169 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
170 return buf;
171}
172
Norman Jamese7594922015-08-27 14:25:24 -0500173int gpio_open(GPIO* gpio)
174{
Norman James65a295a2015-09-26 22:21:10 -0500175 g_assert (gpio != NULL);
Norman Jamese7594922015-08-27 14:25:24 -0500176 // open gpio for writing or reading
177 char buf[254];
Norman James32e74e22015-09-15 21:28:06 -0500178 int rc = 0;
Norman James65a295a2015-09-26 22:21:10 -0500179 if (gpio->direction == NULL) {
180 return GPIO_OPEN_ERROR;
181 }
Norman Jamese7594922015-08-27 14:25:24 -0500182 if (strcmp(gpio->direction,"in")==0)
183 {
184 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
185 gpio->fd = open(buf, O_RDONLY);
186 }
187 else
188 {
189 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num);
190 gpio->fd = open(buf, O_WRONLY);
191
192 }
Norman James88872672015-09-21 16:51:35 -0500193 if (gpio->fd == -1) {
194 return GPIO_OPEN_ERROR;
195 }
196 return GPIO_OK;
Norman Jamese7594922015-08-27 14:25:24 -0500197}
198
199void gpio_close(GPIO* gpio)
200{
201 close(gpio->fd);
202}