1 /** 2 * Copyright © 2016 Google Inc. 3 * Copyright © 2016 IBM Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include "gpio_configs.h" 19 #include "gpio_json.h" 20 #include <cjson/cJSON.h> 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <glib.h> 26 27 28 /** 29 * Loads the GPIO information into the gpios->power_gpio structure 30 * from the JSON. 31 * 32 * @param gpios - the structure where GpioConfigs.power_gpio will 33 * be filled in. 34 * @param gpio_configs - cJSON pointer to the GPIO JSON 35 */ 36 void read_power_gpios(GpioConfigs* gpios, const cJSON* gpio_configs) 37 { 38 size_t i = 0; 39 40 const cJSON* power_config = cJSON_GetObjectItem( 41 gpio_configs, "power_config"); 42 g_assert(power_config != NULL); 43 44 /* PGOOD - required */ 45 46 const cJSON* pgood = cJSON_GetObjectItem(power_config, "power_good_in"); 47 g_assert(pgood != NULL); 48 49 gpios->power_gpio.power_good_in.name = g_strdup(pgood->valuestring); 50 51 g_print("Power GPIO power good input: %s\n", 52 gpios->power_gpio.power_good_in.name); 53 54 /* Latch out - optional */ 55 56 const cJSON* latch = cJSON_GetObjectItem(power_config, "latch_out"); 57 if (latch != NULL) 58 { 59 gpios->power_gpio.latch_out.name = g_strdup(latch->valuestring); 60 g_print("Power GPIO latch output: %s\n", 61 gpios->power_gpio.latch_out.name); 62 } 63 else 64 { 65 //Must be NULL if not there 66 gpios->power_gpio.latch_out.name = NULL; 67 } 68 69 /* Power Up Outs - required */ 70 71 const cJSON* power_up_outs = cJSON_GetObjectItem( 72 power_config, "power_up_outs"); 73 g_assert(power_up_outs != NULL); 74 75 gpios->power_gpio.num_power_up_outs = cJSON_GetArraySize(power_up_outs); 76 g_print("Power GPIO %zu power_up outputs\n", 77 gpios->power_gpio.num_power_up_outs); 78 79 if (gpios->power_gpio.num_power_up_outs != 0) 80 { 81 gpios->power_gpio.power_up_outs = 82 g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(GPIO)); 83 gpios->power_gpio.power_up_pols = 84 g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(gboolean)); 85 86 const cJSON* power_out; 87 cJSON_ArrayForEach(power_out, power_up_outs) 88 { 89 cJSON* name = cJSON_GetObjectItem(power_out, "name"); 90 g_assert(name != NULL); 91 gpios->power_gpio.power_up_outs[i].name = 92 g_strdup(name->valuestring); 93 94 const cJSON* polarity = cJSON_GetObjectItem(power_out, "polarity"); 95 g_assert(polarity != NULL); 96 gpios->power_gpio.power_up_pols[i] = polarity->valueint; 97 98 g_print("Power GPIO power_up[%d] = %s active %s\n", 99 i, gpios->power_gpio.power_up_outs[i].name, 100 gpios->power_gpio.power_up_pols[i] ? "HIGH" : "LOW"); 101 i++; 102 } 103 } 104 105 /* Resets - optional */ 106 107 const cJSON* reset_outs = cJSON_GetObjectItem(power_config, "reset_outs"); 108 gpios->power_gpio.num_reset_outs = cJSON_GetArraySize(reset_outs); 109 110 g_print("Power GPIO %zu reset outputs\n", 111 gpios->power_gpio.num_reset_outs); 112 113 if (gpios->power_gpio.num_reset_outs != 0) 114 { 115 gpios->power_gpio.reset_outs = 116 g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(GPIO)); 117 gpios->power_gpio.reset_pols = 118 g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(gboolean)); 119 120 i = 0; 121 const cJSON* reset_out; 122 cJSON_ArrayForEach(reset_out, reset_outs) 123 { 124 cJSON* name = cJSON_GetObjectItem(reset_out, "name"); 125 g_assert(name != NULL); 126 gpios->power_gpio.reset_outs[i].name = g_strdup(name->valuestring); 127 128 const cJSON* polarity = cJSON_GetObjectItem(reset_out, "polarity"); 129 g_assert(polarity != NULL); 130 gpios->power_gpio.reset_pols[i] = polarity->valueint; 131 132 g_print("Power GPIO reset[%d] = %s active %s\n", i, 133 gpios->power_gpio.reset_outs[i].name, 134 gpios->power_gpio.reset_pols[i] ? "HIGH" : "LOW"); 135 i++; 136 } 137 } 138 139 /* PCI Resets - optional */ 140 141 const cJSON* pci_reset_outs = cJSON_GetObjectItem( 142 power_config, "pci_reset_outs"); 143 144 gpios->power_gpio.num_pci_reset_outs = 145 cJSON_GetArraySize(pci_reset_outs); 146 147 g_print("Power GPIO %zd pci reset outputs\n", 148 gpios->power_gpio.num_pci_reset_outs); 149 150 if (gpios->power_gpio.num_pci_reset_outs != 0) 151 { 152 gpios->power_gpio.pci_reset_outs = 153 g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(GPIO)); 154 gpios->power_gpio.pci_reset_pols = 155 g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean)); 156 gpios->power_gpio.pci_reset_holds = 157 g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean)); 158 159 i = 0; 160 const cJSON* pci_reset_out; 161 cJSON_ArrayForEach(pci_reset_out, pci_reset_outs) 162 { 163 cJSON* name = cJSON_GetObjectItem(pci_reset_out, "name"); 164 g_assert(name != NULL); 165 gpios->power_gpio.pci_reset_outs[i].name = 166 g_strdup(name->valuestring); 167 168 const cJSON* polarity = cJSON_GetObjectItem( 169 pci_reset_out, "polarity"); 170 g_assert(polarity != NULL); 171 gpios->power_gpio.pci_reset_pols[i] = polarity->valueint; 172 173 const cJSON* hold = cJSON_GetObjectItem(pci_reset_out, "hold"); 174 g_assert(hold != NULL); 175 gpios->power_gpio.pci_reset_holds[i] = polarity->valueint; 176 177 g_print("Power GPIO pci reset[%d] = %s active %s, hold %s\n", i, 178 gpios->power_gpio.pci_reset_outs[i].name, 179 gpios->power_gpio.pci_reset_pols[i] ? "HIGH" : "LOW", 180 gpios->power_gpio.pci_reset_holds[i] ? "Yes" : "No"); 181 i++; 182 } 183 } 184 } 185 186 gboolean read_gpios(GDBusConnection *connection, GpioConfigs *gpios) 187 { 188 cJSON* json = load_json(); 189 if (json == NULL) 190 { 191 return FALSE; 192 } 193 194 const cJSON* configs = cJSON_GetObjectItem(json, "gpio_configs"); 195 g_assert(configs != NULL); 196 197 read_power_gpios(gpios, configs); 198 199 cJSON_Delete(json); 200 return TRUE; 201 } 202 203 void free_gpios(GpioConfigs *gpios) { 204 int i; 205 g_free(gpios->power_gpio.latch_out.name); 206 g_free(gpios->power_gpio.power_good_in.name); 207 for(i = 0; i < gpios->power_gpio.num_power_up_outs; i++) { 208 g_free(gpios->power_gpio.power_up_outs[i].name); 209 } 210 g_free(gpios->power_gpio.power_up_outs); 211 g_free(gpios->power_gpio.power_up_pols); 212 for(i = 0; i < gpios->power_gpio.num_reset_outs; i++) { 213 g_free(gpios->power_gpio.reset_outs[i].name); 214 } 215 g_free(gpios->power_gpio.reset_outs); 216 g_free(gpios->power_gpio.reset_pols); 217 for(i = 0; i < gpios->power_gpio.num_pci_reset_outs; i++) { 218 g_free(gpios->power_gpio.pci_reset_outs[i].name); 219 } 220 g_free(gpios->power_gpio.pci_reset_outs); 221 g_free(gpios->power_gpio.pci_reset_pols); 222 g_free(gpios->power_gpio.pci_reset_holds); 223 224 g_free(gpios->hostctl_gpio.fsi_data.name); 225 g_free(gpios->hostctl_gpio.fsi_clk.name); 226 g_free(gpios->hostctl_gpio.fsi_enable.name); 227 g_free(gpios->hostctl_gpio.cronus_sel.name); 228 for (i = 0; i < gpios->hostctl_gpio.num_optionals; ++i) { 229 g_free(gpios->hostctl_gpio.optionals[i].name); 230 } 231 } 232