| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 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> | 
| Norman James | 362a80f | 2015-09-14 14:04:39 -0500 | [diff] [blame] | 10 | #include "interfaces/openbmc_intf.h" | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 11 | #include "gpio.h" | 
|  | 12 |  | 
|  | 13 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 14 | int gpio_writec(GPIO* gpio, char value) | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 15 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 16 | int rc = GPIO_OK; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 17 | char buf[1]; | 
|  | 18 | buf[0] = value; | 
|  | 19 | if (write(gpio->fd, buf, 1) != 1) | 
|  | 20 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 21 | rc = GPIO_WRITE_ERROR; | 
|  | 22 | } | 
|  | 23 | return rc; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 24 | } | 
|  | 25 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 26 | int gpio_write(GPIO* gpio, uint8_t value) | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 27 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 28 | int rc = GPIO_OK; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 29 | char buf[1]; | 
|  | 30 | buf[0] = '0'; | 
|  | 31 | if (value==1) | 
|  | 32 | { | 
|  | 33 | buf[0]='1'; | 
|  | 34 | } | 
|  | 35 | if (write(gpio->fd, buf, 1) != 1) | 
|  | 36 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 37 | rc = GPIO_WRITE_ERROR; | 
|  | 38 | } | 
|  | 39 | return rc; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 40 | } | 
|  | 41 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 42 | int gpio_read(GPIO* gpio, uint8_t* value) | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 43 | { | 
|  | 44 | char buf[1]; | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 45 | int r = GPIO_OK; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 46 | if (read(gpio->fd,&buf,1) != 1) | 
|  | 47 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 48 | r = GPIO_READ_ERROR; | 
|  | 49 | } else { | 
|  | 50 | if (buf[0]=='1') { | 
|  | 51 | *value = 1; | 
|  | 52 | } else { | 
|  | 53 | *value = 0; | 
|  | 54 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 55 | } | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 56 | return r; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 57 |  | 
|  | 58 | } | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 59 | int gpio_clock_cycle(GPIO* gpio, int num_clks) { | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 60 | int i=0; | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 61 | int r=GPIO_OK; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 62 | for (i=0;i<num_clks;i++) { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 63 | if (gpio_writec(gpio,'0') == -1) { | 
|  | 64 | r = GPIO_WRITE_ERROR; | 
|  | 65 | break; | 
|  | 66 | } | 
|  | 67 | if (gpio_writec(gpio,'1') == -1) { | 
|  | 68 | r = GPIO_WRITE_ERROR; | 
|  | 69 | break; | 
|  | 70 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 71 | } | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 72 | return r; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 73 | } | 
|  | 74 |  | 
|  | 75 | // Gets the gpio device path from gpio manager object | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 76 | int gpio_init(GDBusConnection *connection, GPIO* gpio) | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 77 | { | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 78 | int rc = GPIO_OK; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 79 | GDBusProxy *proxy; | 
|  | 80 | GError *error; | 
|  | 81 | GVariant *result; | 
|  | 82 |  | 
|  | 83 | error = NULL; | 
|  | 84 | g_assert_no_error (error); | 
|  | 85 | error = NULL; | 
|  | 86 | proxy = g_dbus_proxy_new_sync (connection, | 
|  | 87 | G_DBUS_PROXY_FLAGS_NONE, | 
|  | 88 | NULL,                      /* GDBusInterfaceInfo */ | 
| Norman James | ddb9738 | 2015-08-27 21:31:31 -0500 | [diff] [blame] | 89 | "org.openbmc.managers.System", /* name */ | 
|  | 90 | "/org/openbmc/managers/System", /* object path */ | 
|  | 91 | "org.openbmc.managers.System",        /* interface */ | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 92 | NULL, /* GCancellable */ | 
|  | 93 | &error); | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 94 | if (error != NULL) { | 
|  | 95 | return GPIO_LOOKUP_ERROR; | 
|  | 96 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 97 |  | 
|  | 98 | result = g_dbus_proxy_call_sync (proxy, | 
| Norman James | ddb9738 | 2015-08-27 21:31:31 -0500 | [diff] [blame] | 99 | "gpioInit", | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 100 | g_variant_new ("(s)", gpio->name), | 
|  | 101 | G_DBUS_CALL_FLAGS_NONE, | 
|  | 102 | -1, | 
|  | 103 | NULL, | 
|  | 104 | &error); | 
|  | 105 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 106 | if (error != NULL) { | 
|  | 107 | return GPIO_LOOKUP_ERROR; | 
|  | 108 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 109 | g_assert (result != NULL); | 
|  | 110 | g_variant_get (result, "(&si&s)", &gpio->dev,&gpio->num,&gpio->direction); | 
|  | 111 | g_print("GPIO Lookup:  %s = %d,%s\n",gpio->name,gpio->num,gpio->direction); | 
|  | 112 |  | 
|  | 113 | //export and set direction | 
|  | 114 | char dev[254]; | 
|  | 115 | char data[4]; | 
|  | 116 | sprintf(dev,"%s/export",gpio->dev); | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 117 | do { | 
|  | 118 | int fd = open(dev, O_WRONLY); | 
|  | 119 | if (fd == GPIO_ERROR) { | 
|  | 120 | rc = GPIO_OPEN_ERROR; | 
|  | 121 | break; | 
|  | 122 | } | 
|  | 123 | sprintf(data,"%d",gpio->num); | 
|  | 124 | rc = write(fd,data,strlen(data)); | 
|  | 125 | close(fd); | 
|  | 126 | if (rc == GPIO_ERROR) { | 
|  | 127 | rc = GPIO_WRITE_ERROR; | 
|  | 128 | break; | 
|  | 129 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 130 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 131 | sprintf(dev,"%s/gpio%d/direction",gpio->dev,gpio->num); | 
|  | 132 | fd = open(dev,O_WRONLY); | 
|  | 133 | if (fd == GPIO_ERROR) { | 
|  | 134 | rc = GPIO_WRITE_ERROR; | 
|  | 135 | break; | 
|  | 136 | } | 
|  | 137 | rc = write(fd,gpio->direction,strlen(gpio->direction)); | 
|  | 138 | close(fd); | 
|  | 139 | } while(0); | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 140 |  | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 141 | return rc; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 142 | } | 
| Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 143 | char* get_gpio_dev(GPIO* gpio) | 
|  | 144 | { | 
|  | 145 | char* buf; | 
|  | 146 | sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); | 
|  | 147 | return buf; | 
|  | 148 | } | 
|  | 149 |  | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 150 | int gpio_open(GPIO* gpio) | 
|  | 151 | { | 
|  | 152 | // open gpio for writing or reading | 
|  | 153 | char buf[254]; | 
| Norman James | 32e74e2 | 2015-09-15 21:28:06 -0500 | [diff] [blame^] | 154 | int rc = 0; | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 155 | if (strcmp(gpio->direction,"in")==0) | 
|  | 156 | { | 
|  | 157 | sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); | 
|  | 158 | gpio->fd = open(buf, O_RDONLY); | 
|  | 159 | } | 
|  | 160 | else | 
|  | 161 | { | 
|  | 162 | sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); | 
|  | 163 | gpio->fd = open(buf, O_WRONLY); | 
|  | 164 |  | 
|  | 165 | } | 
| Norman James | e759492 | 2015-08-27 14:25:24 -0500 | [diff] [blame] | 166 | return gpio->fd; | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | void gpio_close(GPIO* gpio) | 
|  | 170 | { | 
|  | 171 | close(gpio->fd); | 
|  | 172 | } |