2 * acpi_lpat.c - LPAT table processing functions
4 * Copyright (C) 2015 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/export.h>
17 #include <linux/acpi.h>
18 #include <acpi/acpi_lpat.h>
21 * acpi_lpat_raw_to_temp(): Return temperature from raw value through
22 * LPAT conversion table
24 * @lpat_table: the temperature_raw mapping table structure
25 * @raw: the raw value, used as a key to get the temerature from the
28 * A positive converted temperature value will be returned on success,
29 * a negative errno will be returned in error cases.
31 int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table
*lpat_table
,
34 int i
, delta_temp
, delta_raw
, temp
;
35 struct acpi_lpat
*lpat
= lpat_table
->lpat
;
37 for (i
= 0; i
< lpat_table
->lpat_count
- 1; i
++) {
38 if ((raw
>= lpat
[i
].raw
&& raw
<= lpat
[i
+1].raw
) ||
39 (raw
<= lpat
[i
].raw
&& raw
>= lpat
[i
+1].raw
))
43 if (i
== lpat_table
->lpat_count
- 1)
46 delta_temp
= lpat
[i
+1].temp
- lpat
[i
].temp
;
47 delta_raw
= lpat
[i
+1].raw
- lpat
[i
].raw
;
48 temp
= lpat
[i
].temp
+ (raw
- lpat
[i
].raw
) * delta_temp
/ delta_raw
;
52 EXPORT_SYMBOL_GPL(acpi_lpat_raw_to_temp
);
55 * acpi_lpat_temp_to_raw(): Return raw value from temperature through
56 * LPAT conversion table
58 * @lpat_table: the temperature_raw mapping table
59 * @temp: the temperature, used as a key to get the raw value from the
62 * The raw value will be returned on success,
63 * a negative errno will be returned in error cases.
65 int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table
*lpat_table
,
68 int i
, delta_temp
, delta_raw
, raw
;
69 struct acpi_lpat
*lpat
= lpat_table
->lpat
;
71 for (i
= 0; i
< lpat_table
->lpat_count
- 1; i
++) {
72 if (temp
>= lpat
[i
].temp
&& temp
<= lpat
[i
+1].temp
)
76 if (i
== lpat_table
->lpat_count
- 1)
79 delta_temp
= lpat
[i
+1].temp
- lpat
[i
].temp
;
80 delta_raw
= lpat
[i
+1].raw
- lpat
[i
].raw
;
81 raw
= lpat
[i
].raw
+ (temp
- lpat
[i
].temp
) * delta_raw
/ delta_temp
;
85 EXPORT_SYMBOL_GPL(acpi_lpat_temp_to_raw
);
88 * acpi_lpat_get_conversion_table(): Parse ACPI LPAT table if present.
90 * @handle: Handle to acpi device
92 * Parse LPAT table to a struct of type acpi_lpat_table. On success
93 * it returns a pointer to newly allocated table. This table must
94 * be freed by the caller when finished processing, using a call to
95 * acpi_lpat_free_conversion_table.
97 struct acpi_lpat_conversion_table
*acpi_lpat_get_conversion_table(acpi_handle
100 struct acpi_lpat_conversion_table
*lpat_table
= NULL
;
101 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
102 union acpi_object
*obj_p
, *obj_e
;
106 status
= acpi_evaluate_object(handle
, "LPAT", NULL
, &buffer
);
107 if (ACPI_FAILURE(status
))
110 obj_p
= (union acpi_object
*)buffer
.pointer
;
111 if (!obj_p
|| (obj_p
->type
!= ACPI_TYPE_PACKAGE
) ||
112 (obj_p
->package
.count
% 2) || (obj_p
->package
.count
< 4))
115 lpat
= kcalloc(obj_p
->package
.count
, sizeof(int), GFP_KERNEL
);
119 for (i
= 0; i
< obj_p
->package
.count
; i
++) {
120 obj_e
= &obj_p
->package
.elements
[i
];
121 if (obj_e
->type
!= ACPI_TYPE_INTEGER
) {
125 lpat
[i
] = (s64
)obj_e
->integer
.value
;
128 lpat_table
= kzalloc(sizeof(*lpat_table
), GFP_KERNEL
);
134 lpat_table
->lpat
= (struct acpi_lpat
*)lpat
;
135 lpat_table
->lpat_count
= obj_p
->package
.count
/ 2;
138 kfree(buffer
.pointer
);
141 EXPORT_SYMBOL_GPL(acpi_lpat_get_conversion_table
);
144 * acpi_lpat_free_conversion_table(): Free LPAT table.
146 * @lpat_table: the temperature_raw mapping table structure
148 * Frees the LPAT table previously allocated by a call to
149 * acpi_lpat_get_conversion_table.
151 void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table
155 kfree(lpat_table
->lpat
);
159 EXPORT_SYMBOL_GPL(acpi_lpat_free_conversion_table
);