// SPDX-License-Identifier: GPL-2.0-only
/*
 * acpi_lpat.c - LPAT table processing functions
 *
 * Copyright (C) 2015 Intel Corporation. All rights reserved.
 */

#include <linux/export.h>
#include <linux/acpi.h>
#include <acpi/acpi_lpat.h>

/**
 * acpi_lpat_raw_to_temp(): Return temperature from raw value through
 * LPAT conversion table
 *
 * @lpat_table: the temperature_raw mapping table structure
 * @raw: the raw value, used as a key to get the temperature from the
 *       above mapping table
 *
 * A positive converted temperature value will be returned on success,
 * a negative errno will be returned in error cases.
 */
int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table,
			  int raw)
{
	int i, delta_temp, delta_raw, temp;
	struct acpi_lpat *lpat = lpat_table->lpat;

	for (i = 0; i < lpat_table->lpat_count - 1; i++) {
		if ((raw >= lpat[i].raw && raw <= lpat[i+1].raw) ||
		    (raw <= lpat[i].raw && raw >= lpat[i+1].raw))
			break;
	}

	if (i == lpat_table->lpat_count - 1)
		return -ENOENT;

	delta_temp = lpat[i+1].temp - lpat[i].temp;
	delta_raw = lpat[i+1].raw - lpat[i].raw;
	temp = lpat[i].temp + (raw - lpat[i].raw) * delta_temp / delta_raw;

	return temp;
}
EXPORT_SYMBOL_GPL(acpi_lpat_raw_to_temp);

/**
 * acpi_lpat_temp_to_raw(): Return raw value from temperature through
 * LPAT conversion table
 *
 * @lpat_table: the temperature_raw mapping table
 * @temp: the temperature, used as a key to get the raw value from the
 *        above mapping table
 *
 * The raw value will be returned on success,
 * a negative errno will be returned in error cases.
 */
int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table *lpat_table,
			  int temp)
{
	int i, delta_temp, delta_raw, raw;
	struct acpi_lpat *lpat = lpat_table->lpat;

	for (i = 0; i < lpat_table->lpat_count - 1; i++) {
		if (temp >= lpat[i].temp && temp <= lpat[i+1].temp)
			break;
	}

	if (i ==  lpat_table->lpat_count - 1)
		return -ENOENT;

	delta_temp = lpat[i+1].temp - lpat[i].temp;
	delta_raw = lpat[i+1].raw - lpat[i].raw;
	raw = lpat[i].raw + (temp - lpat[i].temp) * delta_raw / delta_temp;

	return raw;
}
EXPORT_SYMBOL_GPL(acpi_lpat_temp_to_raw);

/**
 * acpi_lpat_get_conversion_table(): Parse ACPI LPAT table if present.
 *
 * @handle: Handle to acpi device
 *
 * Parse LPAT table to a struct of type acpi_lpat_table. On success
 * it returns a pointer to newly allocated table. This table must
 * be freed by the caller when finished processing, using a call to
 * acpi_lpat_free_conversion_table.
 */
struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle
								  handle)
{
	struct acpi_lpat_conversion_table *lpat_table = NULL;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj_p, *obj_e;
	int *lpat, i;
	acpi_status status;

	status = acpi_evaluate_object(handle, "LPAT", NULL, &buffer);
	if (ACPI_FAILURE(status))
		return NULL;

	obj_p = (union acpi_object *)buffer.pointer;
	if (!obj_p || (obj_p->type != ACPI_TYPE_PACKAGE) ||
	    (obj_p->package.count % 2) || (obj_p->package.count < 4))
		goto out;

	lpat = kzalloc_objs(int, obj_p->package.count);
	if (!lpat)
		goto out;

	for (i = 0; i < obj_p->package.count; i++) {
		obj_e = &obj_p->package.elements[i];
		if (obj_e->type != ACPI_TYPE_INTEGER) {
			kfree(lpat);
			goto out;
		}
		lpat[i] = (s64)obj_e->integer.value;
	}

	lpat_table = kzalloc_obj(*lpat_table);
	if (!lpat_table) {
		kfree(lpat);
		goto out;
	}

	lpat_table->lpat = (struct acpi_lpat *)lpat;
	lpat_table->lpat_count = obj_p->package.count / 2;

out:
	kfree(buffer.pointer);
	return lpat_table;
}
EXPORT_SYMBOL_GPL(acpi_lpat_get_conversion_table);

/**
 * acpi_lpat_free_conversion_table(): Free LPAT table.
 *
 * @lpat_table: the temperature_raw mapping table structure
 *
 * Frees the LPAT table previously allocated by a call to
 * acpi_lpat_get_conversion_table.
 */
void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table
				     *lpat_table)
{
	if (lpat_table) {
		kfree(lpat_table->lpat);
		kfree(lpat_table);
	}
}
EXPORT_SYMBOL_GPL(acpi_lpat_free_conversion_table);
