/**
 * Copyright © 2017 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.hpp"

#include <fcntl.h>
#include <sys/ioctl.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <cassert>

namespace phosphor
{
namespace gpio
{

using namespace phosphor::logging;

using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

Value GPIO::read()
{
    assert(direction == Direction::input);

    requestLine();

    gpiohandle_data data{};

    auto rc = ioctl(lineFD(), GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);

    if (rc < 0)
    {
        auto e = errno;
        lg2::error("Failed GET_LINE_VALUES ioctl ERRNO={ERRNO}", "ERRNO", e);
        elog<InternalFailure>();
    }

    return (data.values[0] == 0) ? Value::low : Value::high;
}

void GPIO::set(Value value)
{
    assert(direction == Direction::output);

    requestLine(value);

    gpiohandle_data data{};
    data.values[0] = static_cast<gpioValue_t>(value);

    auto rc = ioctl(lineFD(), GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    if (rc == -1)
    {
        auto e = errno;
        lg2::error("Failed SET_LINE_VALUES ioctl ERRNO={ERRNO}", "ERRNO", e);
        elog<InternalFailure>();
    }
}

void GPIO::requestLine(Value defaultValue)
{
    // Only need to do this once
    if (lineFD)
    {
        return;
    }

    power::util::FileDescriptor fd{open(device.c_str(), 0)};
    if (fd() == -1)
    {
        auto e = errno;
        lg2::error("Failed opening GPIO device DEVICE={DEVICE} ERRNO={ERRNO}",
                   "DEVICE", device, "ERRNO", e);
        elog<InternalFailure>();
    }

    // Make an ioctl call to request the GPIO line, which will
    // return the descriptor to use to access it.
    gpiohandle_request request{};
    strncpy(request.consumer_label, "phosphor-power",
            sizeof(request.consumer_label));

    request.flags = (direction == Direction::input) ? GPIOHANDLE_REQUEST_INPUT
                                                    : GPIOHANDLE_REQUEST_OUTPUT;

    request.lineoffsets[0] = gpio;
    request.lines = 1;

    if (direction == Direction::output)
    {
        request.default_values[0] = static_cast<gpioValue_t>(defaultValue);
    }

    auto rc = ioctl(fd(), GPIO_GET_LINEHANDLE_IOCTL, &request);
    if (rc == -1)
    {
        auto e = errno;
        lg2::error("Failed GET_LINEHANDLE ioctl GPIO={GPIO} ERRNO={ERRNO}",
                   "GPIO", gpio, "ERRNO", e);
        elog<InternalFailure>();
    }

    lineFD.set(request.fd);
}

} // namespace gpio
} // namespace phosphor
