blob: a6ee8b64da6b1a3a38da88f94571d7b55c330d8e [file] [log] [blame]
/**
* 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);
}