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 */
read_power_gpios(GpioConfigs * gpios,const cJSON * gpio_configs)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[%zd] = %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[%zd] = %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[%zd] = %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
read_gpios(GpioConfigs * gpios)186 gboolean read_gpios(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
free_gpios(GpioConfigs * gpios)203 void free_gpios(GpioConfigs *gpios) {
204 size_t 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