1 #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> 10 #include "interfaces/openbmc_intf.h" 11 #include "gpio.h" 12 13 14 int gpio_writec(GPIO* gpio, char value) 15 { 16 g_assert (gpio != NULL); 17 int rc = GPIO_OK; 18 char buf[1]; 19 buf[0] = value; 20 if (write(gpio->fd, buf, 1) != 1) 21 { 22 rc = GPIO_WRITE_ERROR; 23 } 24 return rc; 25 } 26 27 int gpio_write(GPIO* gpio, uint8_t value) 28 { 29 g_assert (gpio != NULL); 30 int rc = GPIO_OK; 31 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 { 39 rc = GPIO_WRITE_ERROR; 40 } 41 return rc; 42 } 43 44 int gpio_read(GPIO* gpio, uint8_t *value) 45 { 46 g_assert (gpio != NULL); 47 char buf[1]; 48 int r = GPIO_OK; 49 if (gpio->fd <= 0) 50 { 51 r = GPIO_ERROR; 52 } 53 else 54 { 55 if (read(gpio->fd,&buf,1) != 1) 56 { 57 r = GPIO_READ_ERROR; 58 } else { 59 if (buf[0]=='1') { 60 *value = 1; 61 } else { 62 *value = 0; 63 } 64 } 65 } 66 return r; 67 } 68 int gpio_clock_cycle(GPIO* gpio, int num_clks) { 69 g_assert (gpio != NULL); 70 int i=0; 71 int r=GPIO_OK; 72 for (i=0;i<num_clks;i++) { 73 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 } 81 } 82 return r; 83 } 84 85 // Gets the gpio device path from gpio manager object 86 int gpio_init(GDBusConnection *connection, GPIO* gpio) 87 { 88 int rc = GPIO_OK; 89 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 */ 99 "org.openbmc.managers.System", /* name */ 100 "/org/openbmc/managers/System", /* object path */ 101 "org.openbmc.managers.System", /* interface */ 102 NULL, /* GCancellable */ 103 &error); 104 if (error != NULL) { 105 return GPIO_LOOKUP_ERROR; 106 } 107 108 result = g_dbus_proxy_call_sync (proxy, 109 "gpioInit", 110 g_variant_new ("(s)", gpio->name), 111 G_DBUS_CALL_FLAGS_NONE, 112 -1, 113 NULL, 114 &error); 115 116 if (error != NULL) { 117 return GPIO_LOOKUP_ERROR; 118 } 119 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]; 126 int fd; 127 do { 128 struct stat st; 129 130 sprintf(dev,"%s/gpio%d/value",gpio->dev,gpio->num); 131 //check if gpio is exported, if not export 132 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 } 148 } 149 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); 155 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)); 161 if (rc != strlen(gpio->direction)) { 162 rc = GPIO_WRITE_ERROR; 163 break; 164 } 165 166 close(fd); 167 rc = GPIO_OK; 168 } while(0); 169 170 return rc; 171 } 172 173 174 175 176 char* 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 183 int gpio_open_interrupt(GPIO* gpio, GIOFunc func, gpointer user_data) 184 { 185 int rc = GPIO_OK; 186 char buf[255]; 187 sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); 188 gpio->fd = open(buf, O_RDONLY | O_NONBLOCK ); 189 gpio->irq_inited = false; 190 if (gpio->fd == -1) 191 { 192 rc = GPIO_OPEN_ERROR; 193 } 194 else 195 { 196 GIOChannel* channel = g_io_channel_unix_new( gpio->fd); 197 guint id = g_io_add_watch( channel, G_IO_PRI, func, user_data ); 198 } 199 return rc; 200 } 201 202 int gpio_open(GPIO* gpio) 203 { 204 g_assert (gpio != NULL); 205 // open gpio for writing or reading 206 char buf[254]; 207 int rc = 0; 208 gpio->fd = -1; 209 if (gpio->direction == NULL) { 210 return GPIO_OPEN_ERROR; 211 } 212 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); 220 gpio->fd = open(buf, O_RDWR); 221 222 } 223 if (gpio->fd == -1) { 224 return GPIO_OPEN_ERROR; 225 } 226 return GPIO_OK; 227 } 228 229 void gpio_close(GPIO* gpio) 230 { 231 close(gpio->fd); 232 } 233