1 // SPDX-License-Identifier: GPL-2.0-only
3 * acpi_lpat.c - LPAT table processing functions
5 * Copyright (C) 2015 Intel Corporation. All rights reserved.
8 #include <linux/export.h>
9 #include <linux/acpi.h>
10 #include <acpi/acpi_lpat.h>
13 * acpi_lpat_raw_to_temp(): Return temperature from raw value through
14 * LPAT conversion table
16 * @lpat_table: the temperature_raw mapping table structure
17 * @raw: the raw value, used as a key to get the temperature from the
20 * A positive converted temperature value will be returned on success,
21 * a negative errno will be returned in error cases.
23 int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table
*lpat_table
,
26 int i
, delta_temp
, delta_raw
, temp
;
27 struct acpi_lpat
*lpat
= lpat_table
->lpat
;
29 for (i
= 0; i
< lpat_table
->lpat_count
- 1; i
++) {
30 if ((raw
>= lpat
[i
].raw
&& raw
<= lpat
[i
+1].raw
) ||
31 (raw
<= lpat
[i
].raw
&& raw
>= lpat
[i
+1].raw
))
35 if (i
== lpat_table
->lpat_count
- 1)
38 delta_temp
= lpat
[i
+1].temp
- lpat
[i
].temp
;
39 delta_raw
= lpat
[i
+1].raw
- lpat
[i
].raw
;
40 temp
= lpat
[i
].temp
+ (raw
- lpat
[i
].raw
) * delta_temp
/ delta_raw
;
44 EXPORT_SYMBOL_GPL(acpi_lpat_raw_to_temp
);
47 * acpi_lpat_temp_to_raw(): Return raw value from temperature through
48 * LPAT conversion table
50 * @lpat_table: the temperature_raw mapping table
51 * @temp: the temperature, used as a key to get the raw value from the
54 * The raw value will be returned on success,
55 * a negative errno will be returned in error cases.
57 int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table
*lpat_table
,
60 int i
, delta_temp
, delta_raw
, raw
;
61 struct acpi_lpat
*lpat
= lpat_table
->lpat
;
63 for (i
= 0; i
< lpat_table
->lpat_count
- 1; i
++) {
64 if (temp
>= lpat
[i
].temp
&& temp
<= lpat
[i
+1].temp
)
68 if (i
== lpat_table
->lpat_count
- 1)
71 delta_temp
= lpat
[i
+1].temp
- lpat
[i
].temp
;
72 delta_raw
= lpat
[i
+1].raw
- lpat
[i
].raw
;
73 raw
= lpat
[i
].raw
+ (temp
- lpat
[i
].temp
) * delta_raw
/ delta_temp
;
77 EXPORT_SYMBOL_GPL(acpi_lpat_temp_to_raw
);
80 * acpi_lpat_get_conversion_table(): Parse ACPI LPAT table if present.
82 * @handle: Handle to acpi device
84 * Parse LPAT table to a struct of type acpi_lpat_table. On success
85 * it returns a pointer to newly allocated table. This table must
86 * be freed by the caller when finished processing, using a call to
87 * acpi_lpat_free_conversion_table.
89 struct acpi_lpat_conversion_table
*acpi_lpat_get_conversion_table(acpi_handle
92 struct acpi_lpat_conversion_table
*lpat_table
= NULL
;
93 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
94 union acpi_object
*obj_p
, *obj_e
;
98 status
= acpi_evaluate_object(handle
, "LPAT", NULL
, &buffer
);
99 if (ACPI_FAILURE(status
))
102 obj_p
= (union acpi_object
*)buffer
.pointer
;
103 if (!obj_p
|| (obj_p
->type
!= ACPI_TYPE_PACKAGE
) ||
104 (obj_p
->package
.count
% 2) || (obj_p
->package
.count
< 4))
107 lpat
= kcalloc(obj_p
->package
.count
, sizeof(int), GFP_KERNEL
);
111 for (i
= 0; i
< obj_p
->package
.count
; i
++) {
112 obj_e
= &obj_p
->package
.elements
[i
];
113 if (obj_e
->type
!= ACPI_TYPE_INTEGER
) {
117 lpat
[i
] = (s64
)obj_e
->integer
.value
;
120 lpat_table
= kzalloc(sizeof(*lpat_table
), GFP_KERNEL
);
126 lpat_table
->lpat
= (struct acpi_lpat
*)lpat
;
127 lpat_table
->lpat_count
= obj_p
->package
.count
/ 2;
130 kfree(buffer
.pointer
);
133 EXPORT_SYMBOL_GPL(acpi_lpat_get_conversion_table
);
136 * acpi_lpat_free_conversion_table(): Free LPAT table.
138 * @lpat_table: the temperature_raw mapping table structure
140 * Frees the LPAT table previously allocated by a call to
141 * acpi_lpat_get_conversion_table.
143 void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table
147 kfree(lpat_table
->lpat
);
151 EXPORT_SYMBOL_GPL(acpi_lpat_free_conversion_table
);