0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/export.h>
0009 #include <linux/acpi.h>
0010 #include <acpi/acpi_lpat.h>
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table,
0024 int raw)
0025 {
0026 int i, delta_temp, delta_raw, temp;
0027 struct acpi_lpat *lpat = lpat_table->lpat;
0028
0029 for (i = 0; i < lpat_table->lpat_count - 1; i++) {
0030 if ((raw >= lpat[i].raw && raw <= lpat[i+1].raw) ||
0031 (raw <= lpat[i].raw && raw >= lpat[i+1].raw))
0032 break;
0033 }
0034
0035 if (i == lpat_table->lpat_count - 1)
0036 return -ENOENT;
0037
0038 delta_temp = lpat[i+1].temp - lpat[i].temp;
0039 delta_raw = lpat[i+1].raw - lpat[i].raw;
0040 temp = lpat[i].temp + (raw - lpat[i].raw) * delta_temp / delta_raw;
0041
0042 return temp;
0043 }
0044 EXPORT_SYMBOL_GPL(acpi_lpat_raw_to_temp);
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table *lpat_table,
0058 int temp)
0059 {
0060 int i, delta_temp, delta_raw, raw;
0061 struct acpi_lpat *lpat = lpat_table->lpat;
0062
0063 for (i = 0; i < lpat_table->lpat_count - 1; i++) {
0064 if (temp >= lpat[i].temp && temp <= lpat[i+1].temp)
0065 break;
0066 }
0067
0068 if (i == lpat_table->lpat_count - 1)
0069 return -ENOENT;
0070
0071 delta_temp = lpat[i+1].temp - lpat[i].temp;
0072 delta_raw = lpat[i+1].raw - lpat[i].raw;
0073 raw = lpat[i].raw + (temp - lpat[i].temp) * delta_raw / delta_temp;
0074
0075 return raw;
0076 }
0077 EXPORT_SYMBOL_GPL(acpi_lpat_temp_to_raw);
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle
0090 handle)
0091 {
0092 struct acpi_lpat_conversion_table *lpat_table = NULL;
0093 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0094 union acpi_object *obj_p, *obj_e;
0095 int *lpat, i;
0096 acpi_status status;
0097
0098 status = acpi_evaluate_object(handle, "LPAT", NULL, &buffer);
0099 if (ACPI_FAILURE(status))
0100 return NULL;
0101
0102 obj_p = (union acpi_object *)buffer.pointer;
0103 if (!obj_p || (obj_p->type != ACPI_TYPE_PACKAGE) ||
0104 (obj_p->package.count % 2) || (obj_p->package.count < 4))
0105 goto out;
0106
0107 lpat = kcalloc(obj_p->package.count, sizeof(int), GFP_KERNEL);
0108 if (!lpat)
0109 goto out;
0110
0111 for (i = 0; i < obj_p->package.count; i++) {
0112 obj_e = &obj_p->package.elements[i];
0113 if (obj_e->type != ACPI_TYPE_INTEGER) {
0114 kfree(lpat);
0115 goto out;
0116 }
0117 lpat[i] = (s64)obj_e->integer.value;
0118 }
0119
0120 lpat_table = kzalloc(sizeof(*lpat_table), GFP_KERNEL);
0121 if (!lpat_table) {
0122 kfree(lpat);
0123 goto out;
0124 }
0125
0126 lpat_table->lpat = (struct acpi_lpat *)lpat;
0127 lpat_table->lpat_count = obj_p->package.count / 2;
0128
0129 out:
0130 kfree(buffer.pointer);
0131 return lpat_table;
0132 }
0133 EXPORT_SYMBOL_GPL(acpi_lpat_get_conversion_table);
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table
0144 *lpat_table)
0145 {
0146 if (lpat_table) {
0147 kfree(lpat_table->lpat);
0148 kfree(lpat_table);
0149 }
0150 }
0151 EXPORT_SYMBOL_GPL(acpi_lpat_free_conversion_table);