| /** |
| * Copyright © 2016 Google Inc. |
| * Copyright © 2016 IBM Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "gpio_configs.h" |
| #include "gpio_json.h" |
| #include <cjson/cJSON.h> |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <glib.h> |
| |
| |
| /** |
| * Loads the GPIO information into the gpios->power_gpio structure |
| * from the JSON. |
| * |
| * @param gpios - the structure where GpioConfigs.power_gpio will |
| * be filled in. |
| * @param gpio_configs - cJSON pointer to the GPIO JSON |
| */ |
| void read_power_gpios(GpioConfigs* gpios, const cJSON* gpio_configs) |
| { |
| size_t i = 0; |
| |
| const cJSON* power_config = cJSON_GetObjectItem( |
| gpio_configs, "power_config"); |
| g_assert(power_config != NULL); |
| |
| /* PGOOD - required */ |
| |
| const cJSON* pgood = cJSON_GetObjectItem(power_config, "power_good_in"); |
| g_assert(pgood != NULL); |
| |
| gpios->power_gpio.power_good_in.name = g_strdup(pgood->valuestring); |
| |
| g_print("Power GPIO power good input: %s\n", |
| gpios->power_gpio.power_good_in.name); |
| |
| /* Latch out - optional */ |
| |
| const cJSON* latch = cJSON_GetObjectItem(power_config, "latch_out"); |
| if (latch != NULL) |
| { |
| gpios->power_gpio.latch_out.name = g_strdup(latch->valuestring); |
| g_print("Power GPIO latch output: %s\n", |
| gpios->power_gpio.latch_out.name); |
| } |
| else |
| { |
| //Must be NULL if not there |
| gpios->power_gpio.latch_out.name = NULL; |
| } |
| |
| /* Power Up Outs - required */ |
| |
| const cJSON* power_up_outs = cJSON_GetObjectItem( |
| power_config, "power_up_outs"); |
| g_assert(power_up_outs != NULL); |
| |
| gpios->power_gpio.num_power_up_outs = cJSON_GetArraySize(power_up_outs); |
| g_print("Power GPIO %zu power_up outputs\n", |
| gpios->power_gpio.num_power_up_outs); |
| |
| if (gpios->power_gpio.num_power_up_outs != 0) |
| { |
| gpios->power_gpio.power_up_outs = |
| g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(GPIO)); |
| gpios->power_gpio.power_up_pols = |
| g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(gboolean)); |
| |
| const cJSON* power_out; |
| cJSON_ArrayForEach(power_out, power_up_outs) |
| { |
| cJSON* name = cJSON_GetObjectItem(power_out, "name"); |
| g_assert(name != NULL); |
| gpios->power_gpio.power_up_outs[i].name = |
| g_strdup(name->valuestring); |
| |
| const cJSON* polarity = cJSON_GetObjectItem(power_out, "polarity"); |
| g_assert(polarity != NULL); |
| gpios->power_gpio.power_up_pols[i] = polarity->valueint; |
| |
| g_print("Power GPIO power_up[%d] = %s active %s\n", |
| i, gpios->power_gpio.power_up_outs[i].name, |
| gpios->power_gpio.power_up_pols[i] ? "HIGH" : "LOW"); |
| i++; |
| } |
| } |
| |
| /* Resets - optional */ |
| |
| const cJSON* reset_outs = cJSON_GetObjectItem(power_config, "reset_outs"); |
| gpios->power_gpio.num_reset_outs = cJSON_GetArraySize(reset_outs); |
| |
| g_print("Power GPIO %zu reset outputs\n", |
| gpios->power_gpio.num_reset_outs); |
| |
| if (gpios->power_gpio.num_reset_outs != 0) |
| { |
| gpios->power_gpio.reset_outs = |
| g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(GPIO)); |
| gpios->power_gpio.reset_pols = |
| g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(gboolean)); |
| |
| i = 0; |
| const cJSON* reset_out; |
| cJSON_ArrayForEach(reset_out, reset_outs) |
| { |
| cJSON* name = cJSON_GetObjectItem(reset_out, "name"); |
| g_assert(name != NULL); |
| gpios->power_gpio.reset_outs[i].name = g_strdup(name->valuestring); |
| |
| const cJSON* polarity = cJSON_GetObjectItem(reset_out, "polarity"); |
| g_assert(polarity != NULL); |
| gpios->power_gpio.reset_pols[i] = polarity->valueint; |
| |
| g_print("Power GPIO reset[%d] = %s active %s\n", i, |
| gpios->power_gpio.reset_outs[i].name, |
| gpios->power_gpio.reset_pols[i] ? "HIGH" : "LOW"); |
| i++; |
| } |
| } |
| |
| /* PCI Resets - optional */ |
| |
| const cJSON* pci_reset_outs = cJSON_GetObjectItem( |
| power_config, "pci_reset_outs"); |
| |
| gpios->power_gpio.num_pci_reset_outs = |
| cJSON_GetArraySize(pci_reset_outs); |
| |
| g_print("Power GPIO %zd pci reset outputs\n", |
| gpios->power_gpio.num_pci_reset_outs); |
| |
| if (gpios->power_gpio.num_pci_reset_outs != 0) |
| { |
| gpios->power_gpio.pci_reset_outs = |
| g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(GPIO)); |
| gpios->power_gpio.pci_reset_pols = |
| g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean)); |
| gpios->power_gpio.pci_reset_holds = |
| g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean)); |
| |
| i = 0; |
| const cJSON* pci_reset_out; |
| cJSON_ArrayForEach(pci_reset_out, pci_reset_outs) |
| { |
| cJSON* name = cJSON_GetObjectItem(pci_reset_out, "name"); |
| g_assert(name != NULL); |
| gpios->power_gpio.pci_reset_outs[i].name = |
| g_strdup(name->valuestring); |
| |
| const cJSON* polarity = cJSON_GetObjectItem( |
| pci_reset_out, "polarity"); |
| g_assert(polarity != NULL); |
| gpios->power_gpio.pci_reset_pols[i] = polarity->valueint; |
| |
| const cJSON* hold = cJSON_GetObjectItem(pci_reset_out, "hold"); |
| g_assert(hold != NULL); |
| gpios->power_gpio.pci_reset_holds[i] = polarity->valueint; |
| |
| g_print("Power GPIO pci reset[%d] = %s active %s, hold %s\n", i, |
| gpios->power_gpio.pci_reset_outs[i].name, |
| gpios->power_gpio.pci_reset_pols[i] ? "HIGH" : "LOW", |
| gpios->power_gpio.pci_reset_holds[i] ? "Yes" : "No"); |
| i++; |
| } |
| } |
| } |
| |
| gboolean read_gpios(GDBusConnection *connection, GpioConfigs *gpios) |
| { |
| cJSON* json = load_json(); |
| if (json == NULL) |
| { |
| return FALSE; |
| } |
| |
| const cJSON* configs = cJSON_GetObjectItem(json, "gpio_configs"); |
| g_assert(configs != NULL); |
| |
| read_power_gpios(gpios, configs); |
| |
| cJSON_Delete(json); |
| return TRUE; |
| } |
| |
| void free_gpios(GpioConfigs *gpios) { |
| int i; |
| g_free(gpios->power_gpio.latch_out.name); |
| g_free(gpios->power_gpio.power_good_in.name); |
| for(i = 0; i < gpios->power_gpio.num_power_up_outs; i++) { |
| g_free(gpios->power_gpio.power_up_outs[i].name); |
| } |
| g_free(gpios->power_gpio.power_up_outs); |
| g_free(gpios->power_gpio.power_up_pols); |
| for(i = 0; i < gpios->power_gpio.num_reset_outs; i++) { |
| g_free(gpios->power_gpio.reset_outs[i].name); |
| } |
| g_free(gpios->power_gpio.reset_outs); |
| g_free(gpios->power_gpio.reset_pols); |
| for(i = 0; i < gpios->power_gpio.num_pci_reset_outs; i++) { |
| g_free(gpios->power_gpio.pci_reset_outs[i].name); |
| } |
| g_free(gpios->power_gpio.pci_reset_outs); |
| g_free(gpios->power_gpio.pci_reset_pols); |
| g_free(gpios->power_gpio.pci_reset_holds); |
| } |