23 #include <linux/slab.h>
24 #include <linux/module.h>
47 { .temp_C = -40, .ohm = 1747920 },
48 { .temp_C = -35, .ohm = 1245428 },
49 { .temp_C = -30, .ohm = 898485 },
50 { .temp_C = -25, .ohm = 655802 },
51 { .temp_C = -20, .ohm = 483954 },
52 { .temp_C = -15, .ohm = 360850 },
53 { .temp_C = -10, .ohm = 271697 },
54 { .temp_C = -5, .ohm = 206463 },
55 { .temp_C = 0, .ohm = 158214 },
56 { .temp_C = 5, .ohm = 122259 },
57 { .temp_C = 10, .ohm = 95227 },
58 { .temp_C = 15, .ohm = 74730 },
59 { .temp_C = 20, .ohm = 59065 },
60 { .temp_C = 25, .ohm = 47000 },
61 { .temp_C = 30, .ohm = 37643 },
62 { .temp_C = 35, .ohm = 30334 },
63 { .temp_C = 40, .ohm = 24591 },
64 { .temp_C = 45, .ohm = 20048 },
65 { .temp_C = 50, .ohm = 16433 },
66 { .temp_C = 55, .ohm = 13539 },
67 { .temp_C = 60, .ohm = 11209 },
68 { .temp_C = 65, .ohm = 9328 },
69 { .temp_C = 70, .ohm = 7798 },
70 { .temp_C = 75, .ohm = 6544 },
71 { .temp_C = 80, .ohm = 5518 },
72 { .temp_C = 85, .ohm = 4674 },
73 { .temp_C = 90, .ohm = 3972 },
74 { .temp_C = 95, .ohm = 3388 },
75 { .temp_C = 100, .ohm = 2902 },
76 { .temp_C = 105, .ohm = 2494 },
77 { .temp_C = 110, .ohm = 2150 },
78 { .temp_C = 115, .ohm = 1860 },
79 { .temp_C = 120, .ohm = 1615 },
80 { .temp_C = 125, .ohm = 1406 },
83 { .temp_C = -40, .ohm = 1610154 },
84 { .temp_C = -35, .ohm = 1130850 },
85 { .temp_C = -30, .ohm = 802609 },
86 { .temp_C = -25, .ohm = 575385 },
87 { .temp_C = -20, .ohm = 416464 },
88 { .temp_C = -15, .ohm = 304219 },
89 { .temp_C = -10, .ohm = 224193 },
90 { .temp_C = -5, .ohm = 166623 },
91 { .temp_C = 0, .ohm = 124850 },
92 { .temp_C = 5, .ohm = 94287 },
93 { .temp_C = 10, .ohm = 71747 },
94 { .temp_C = 15, .ohm = 54996 },
95 { .temp_C = 20, .ohm = 42455 },
96 { .temp_C = 25, .ohm = 33000 },
97 { .temp_C = 30, .ohm = 25822 },
98 { .temp_C = 35, .ohm = 20335 },
99 { .temp_C = 40, .ohm = 16115 },
100 { .temp_C = 45, .ohm = 12849 },
101 { .temp_C = 50, .ohm = 10306 },
102 { .temp_C = 55, .ohm = 8314 },
103 { .temp_C = 60, .ohm = 6746 },
104 { .temp_C = 65, .ohm = 5503 },
105 { .temp_C = 70, .ohm = 4513 },
106 { .temp_C = 75, .ohm = 3721 },
107 { .temp_C = 80, .ohm = 3084 },
108 { .temp_C = 85, .ohm = 2569 },
109 { .temp_C = 90, .ohm = 2151 },
110 { .temp_C = 95, .ohm = 1809 },
111 { .temp_C = 100, .ohm = 1529 },
112 { .temp_C = 105, .ohm = 1299 },
113 { .temp_C = 110, .ohm = 1108 },
114 { .temp_C = 115, .ohm = 949 },
115 { .temp_C = 120, .ohm = 817 },
116 { .temp_C = 125, .ohm = 707 },
130 if (divisor == 0 && dividend == 0)
134 return div64_u64(dividend, divisor);
137 static int get_ohm_of_thermistor(
struct ntc_data *
data,
unsigned int uV)
156 N = div64_u64_safe(pdO * (pmV - mV), mV);
158 N = div64_u64_safe(puO * mV, pmV - mV);
160 N = div64_u64_safe(pdO * puO * (pmV - mV),
161 puO * mV - pdO * (pmV - mV));
163 N = div64_u64_safe(pdO * puO * mV, pdO * (pmV - mV) - puO * mV);
170 static void lookup_comp(
struct ntc_data *data,
unsigned int ohm,
171 int *i_low,
int *i_high)
182 if (ohm >= data->
comp[0].ohm) {
187 if (ohm <= data->comp[data->
n_comp - 1].ohm) {
188 *i_low = data->
n_comp - 1;
189 *i_high = data->
n_comp - 1;
196 while (start < end) {
197 mid = start + (end -
start) / 2;
207 if (ohm >= data->
comp[mid].ohm) {
217 if (ohm >= data->
comp[start].ohm)
230 if (ohm == data->
comp[end].ohm)
236 static int get_temp_mC(
struct ntc_data *data,
unsigned int ohm)
241 lookup_comp(data, ohm, &low, &high);
244 temp = data->
comp[
low].temp_C * 1000;
246 temp = data->
comp[
low].temp_C * 1000 +
248 1000 * ((
int)ohm - (
int)data->
comp[low].ohm)) /
254 static int ntc_thermistor_get_ohm(
struct ntc_data *data)
258 if (data->
pdata->read_ohm)
259 return data->
pdata->read_ohm();
261 if (data->
pdata->read_uV) {
262 read_uV = data->
pdata->read_uV();
265 return get_ohm_of_thermistor(data, read_uV);
290 ohm = ntc_thermistor_get_ohm(data);
294 return sprintf(buf,
"%d\n", get_temp_mC(data, ohm));
301 static struct attribute *ntc_attributes[] = {
303 &sensor_dev_attr_temp1_type.dev_attr.attr,
304 &sensor_dev_attr_temp1_input.dev_attr.attr,
309 .attrs = ntc_attributes,
319 dev_err(&pdev->
dev,
"No platform init data supplied.\n");
326 "Both read_uV and read_ohm missing. Need either one of the two.\n");
332 "Only one of read_uV and read_ohm is needed; ignoring read_uV.\n");
344 "Required data to use read_uV not supplied.\n");
356 switch (pdev->
id_entry->driver_data) {
366 dev_err(&pdev->
dev,
"Unknown device type: %lu(%s)\n",
372 platform_set_drvdata(pdev, data);
376 dev_err(data->
dev,
"unable to create sysfs files\n");
382 dev_err(data->
dev,
"unable to register as hwmon device.\n");
384 goto err_after_sysfs;
387 dev_info(&pdev->
dev,
"Thermistor %s:%d (type: %s/%lu) successfully probed.\n",
398 struct ntc_data *data = platform_get_drvdata(pdev);
402 platform_set_drvdata(pdev,
NULL);
418 .name =
"ntc-thermistor",
421 .probe = ntc_thermistor_probe,
423 .id_table = ntc_thermistor_id,