/******************************************************************************
 *
 * Copyright(c) 2017        Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#include "acpi.h"
#include "iwl-debug.h"
#include "iwl-drv.h"

void* iwl_acpi_get_object(struct device* dev, acpi_string method) {
    acpi_handle root_handle;
    acpi_handle handle;
    struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
    acpi_status status;

    root_handle = ACPI_HANDLE(dev);
    if (!root_handle) {
        IWL_DEBUG_DEV_RADIO(dev, "Could not retrieve root port ACPI handle\n");
        return ERR_PTR(-ENOENT);
    }

    /* Get the method's handle */
    status = acpi_get_handle(root_handle, method, &handle);
    if (ACPI_FAILURE(status)) {
        IWL_DEBUG_DEV_RADIO(dev, "%s method not found\n", method);
        return ERR_PTR(-ENOENT);
    }

    /* Call the method with no arguments */
    status = acpi_evaluate_object(handle, NULL, NULL, &buf);
    if (ACPI_FAILURE(status)) {
        IWL_DEBUG_DEV_RADIO(dev, "%s invocation failed (0x%x)\n", method, status);
        return ERR_PTR(-ENOENT);
    }

    return buf.pointer;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_object);

union acpi_object* iwl_acpi_get_wifi_pkg(struct device* dev, union acpi_object* data,
                                         int data_size) {
    int i;
    union acpi_object* wifi_pkg;

    /*
     * We need at least one entry in the wifi package that
     * describes the domain, and one more entry, otherwise there's
     * no point in reading it.
     */
    if (WARN_ON_ONCE(data_size < 2)) { return ERR_PTR(-EINVAL); }

    /*
     * We need at least two packages, one for the revision and one
     * for the data itself.  Also check that the revision is valid
     * (i.e. it is an integer set to 0).
     */
    if (data->type != ACPI_TYPE_PACKAGE || data->package.count < 2 ||
        data->package.elements[0].type != ACPI_TYPE_INTEGER ||
        data->package.elements[0].integer.value != 0) {
        IWL_DEBUG_DEV_RADIO(dev, "Unsupported packages structure\n");
        return ERR_PTR(-EINVAL);
    }

    /* loop through all the packages to find the one for WiFi */
    for (i = 1; i < data->package.count; i++) {
        union acpi_object* domain;

        wifi_pkg = &data->package.elements[i];

        /* skip entries that are not a package with the right size */
        if (wifi_pkg->type != ACPI_TYPE_PACKAGE || wifi_pkg->package.count != data_size) {
            continue;
        }

        domain = &wifi_pkg->package.elements[0];
        if (domain->type == ACPI_TYPE_INTEGER && domain->integer.value == ACPI_WIFI_DOMAIN) {
            goto found;
        }
    }

    return ERR_PTR(-ENOENT);

found:
    return wifi_pkg;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg);

int iwl_acpi_get_mcc(struct device* dev, char* mcc) {
    union acpi_object *wifi_pkg, *data;
    uint32_t mcc_val;
    int ret;

    data = iwl_acpi_get_object(dev, ACPI_WRDD_METHOD);
    if (IS_ERR(data)) { return PTR_ERR(data); }

    wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE);
    if (IS_ERR(wifi_pkg)) {
        ret = PTR_ERR(wifi_pkg);
        goto out_free;
    }

    if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
        ret = -EINVAL;
        goto out_free;
    }

    mcc_val = wifi_pkg->package.elements[1].integer.value;

    mcc[0] = (mcc_val >> 8) & 0xff;
    mcc[1] = mcc_val & 0xff;
    mcc[2] = '\0';

    ret = 0;
out_free:
    kfree(data);
    return ret;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_mcc);

uint64_t iwl_acpi_get_pwr_limit(struct device* dev) {
    union acpi_object *data, *wifi_pkg;
    uint64_t dflt_pwr_limit;

    data = iwl_acpi_get_object(dev, ACPI_SPLC_METHOD);
    if (IS_ERR(data)) {
        dflt_pwr_limit = 0;
        goto out;
    }

    wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_SPLC_WIFI_DATA_SIZE);
    if (IS_ERR(wifi_pkg) || wifi_pkg->package.elements[1].integer.value != ACPI_TYPE_INTEGER) {
        dflt_pwr_limit = 0;
        goto out_free;
    }

    dflt_pwr_limit = wifi_pkg->package.elements[1].integer.value;
out_free:
    kfree(data);
out:
    return dflt_pwr_limit;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_pwr_limit);
