11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f22aaaa7SDonggeun Kim /*
3f22aaaa7SDonggeun Kim * ntc_thermistor.c - NTC Thermistors
4f22aaaa7SDonggeun Kim *
5f22aaaa7SDonggeun Kim * Copyright (C) 2010 Samsung Electronics
6f22aaaa7SDonggeun Kim * MyungJoo Ham <myungjoo.ham@samsung.com>
7f22aaaa7SDonggeun Kim */
8f22aaaa7SDonggeun Kim
9f22aaaa7SDonggeun Kim #include <linux/slab.h>
10f22aaaa7SDonggeun Kim #include <linux/module.h>
11f22aaaa7SDonggeun Kim #include <linux/math64.h>
1270760e80SLinus Walleij #include <linux/mod_devicetable.h>
13f22aaaa7SDonggeun Kim #include <linux/platform_device.h>
1470760e80SLinus Walleij #include <linux/property.h>
15f22aaaa7SDonggeun Kim #include <linux/err.h>
16bd56c1e9SLinus Walleij #include <linux/fixp-arith.h>
179e8269deSNaveen Krishna Chatradhi #include <linux/iio/consumer.h>
18f22aaaa7SDonggeun Kim #include <linux/hwmon.h>
19f22aaaa7SDonggeun Kim
2011a24ca7SLinus Walleij enum ntc_thermistor_type {
2111a24ca7SLinus Walleij TYPE_B57330V2103,
2211a24ca7SLinus Walleij TYPE_B57891S0103,
2311a24ca7SLinus Walleij TYPE_NCPXXWB473,
2411a24ca7SLinus Walleij TYPE_NCPXXWF104,
2511a24ca7SLinus Walleij TYPE_NCPXXWL333,
2611a24ca7SLinus Walleij TYPE_NCPXXXH103,
2711a24ca7SLinus Walleij };
2811a24ca7SLinus Walleij
29f22aaaa7SDonggeun Kim struct ntc_compensation {
30088ce2acSGuenter Roeck int temp_c;
31f22aaaa7SDonggeun Kim unsigned int ohm;
32f22aaaa7SDonggeun Kim };
33f22aaaa7SDonggeun Kim
34e056fe25SPeter Rosin /*
35e056fe25SPeter Rosin * Used as index in a zero-terminated array, holes not allowed so
36e056fe25SPeter Rosin * that NTC_LAST is the first empty array entry.
37e056fe25SPeter Rosin */
38e056fe25SPeter Rosin enum {
39e056fe25SPeter Rosin NTC_B57330V2103,
40e056fe25SPeter Rosin NTC_B57891S0103,
41e056fe25SPeter Rosin NTC_NCP03WB473,
42e056fe25SPeter Rosin NTC_NCP03WF104,
43e056fe25SPeter Rosin NTC_NCP15WB473,
44e056fe25SPeter Rosin NTC_NCP15WL333,
45e056fe25SPeter Rosin NTC_NCP15XH103,
46e056fe25SPeter Rosin NTC_NCP18WB473,
47e056fe25SPeter Rosin NTC_NCP21WB473,
48e13e979bSLinus Walleij NTC_SSG1404001221,
49e056fe25SPeter Rosin NTC_LAST,
50e056fe25SPeter Rosin };
51e056fe25SPeter Rosin
529e8269deSNaveen Krishna Chatradhi static const struct platform_device_id ntc_thermistor_id[] = {
53e056fe25SPeter Rosin [NTC_B57330V2103] = { "b57330v2103", TYPE_B57330V2103 },
54e056fe25SPeter Rosin [NTC_B57891S0103] = { "b57891s0103", TYPE_B57891S0103 },
55e056fe25SPeter Rosin [NTC_NCP03WB473] = { "ncp03wb473", TYPE_NCPXXWB473 },
56e056fe25SPeter Rosin [NTC_NCP03WF104] = { "ncp03wf104", TYPE_NCPXXWF104 },
57e056fe25SPeter Rosin [NTC_NCP15WB473] = { "ncp15wb473", TYPE_NCPXXWB473 },
58e056fe25SPeter Rosin [NTC_NCP15WL333] = { "ncp15wl333", TYPE_NCPXXWL333 },
59e056fe25SPeter Rosin [NTC_NCP15XH103] = { "ncp15xh103", TYPE_NCPXXXH103 },
60e056fe25SPeter Rosin [NTC_NCP18WB473] = { "ncp18wb473", TYPE_NCPXXWB473 },
61e056fe25SPeter Rosin [NTC_NCP21WB473] = { "ncp21wb473", TYPE_NCPXXWB473 },
62e23e40fdSLinus Walleij [NTC_SSG1404001221] = { "ssg1404_001221", TYPE_NCPXXWB473 },
63e056fe25SPeter Rosin [NTC_LAST] = { },
649e8269deSNaveen Krishna Chatradhi };
65cbb2313eSYuntao Liu MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
669e8269deSNaveen Krishna Chatradhi
67f22aaaa7SDonggeun Kim /*
68f22aaaa7SDonggeun Kim * A compensation table should be sorted by the values of .ohm
69f22aaaa7SDonggeun Kim * in descending order.
70f22aaaa7SDonggeun Kim * The following compensation tables are from the specification of Murata NTC
71f22aaaa7SDonggeun Kim * Thermistors Datasheet
72f22aaaa7SDonggeun Kim */
734626dcffSSachin Kamat static const struct ntc_compensation ncpXXwb473[] = {
74088ce2acSGuenter Roeck { .temp_c = -40, .ohm = 1747920 },
75088ce2acSGuenter Roeck { .temp_c = -35, .ohm = 1245428 },
76088ce2acSGuenter Roeck { .temp_c = -30, .ohm = 898485 },
77088ce2acSGuenter Roeck { .temp_c = -25, .ohm = 655802 },
78088ce2acSGuenter Roeck { .temp_c = -20, .ohm = 483954 },
79088ce2acSGuenter Roeck { .temp_c = -15, .ohm = 360850 },
80088ce2acSGuenter Roeck { .temp_c = -10, .ohm = 271697 },
81088ce2acSGuenter Roeck { .temp_c = -5, .ohm = 206463 },
82088ce2acSGuenter Roeck { .temp_c = 0, .ohm = 158214 },
83088ce2acSGuenter Roeck { .temp_c = 5, .ohm = 122259 },
84088ce2acSGuenter Roeck { .temp_c = 10, .ohm = 95227 },
85088ce2acSGuenter Roeck { .temp_c = 15, .ohm = 74730 },
86088ce2acSGuenter Roeck { .temp_c = 20, .ohm = 59065 },
87088ce2acSGuenter Roeck { .temp_c = 25, .ohm = 47000 },
88088ce2acSGuenter Roeck { .temp_c = 30, .ohm = 37643 },
89088ce2acSGuenter Roeck { .temp_c = 35, .ohm = 30334 },
90088ce2acSGuenter Roeck { .temp_c = 40, .ohm = 24591 },
91088ce2acSGuenter Roeck { .temp_c = 45, .ohm = 20048 },
92088ce2acSGuenter Roeck { .temp_c = 50, .ohm = 16433 },
93088ce2acSGuenter Roeck { .temp_c = 55, .ohm = 13539 },
94088ce2acSGuenter Roeck { .temp_c = 60, .ohm = 11209 },
95088ce2acSGuenter Roeck { .temp_c = 65, .ohm = 9328 },
96088ce2acSGuenter Roeck { .temp_c = 70, .ohm = 7798 },
97088ce2acSGuenter Roeck { .temp_c = 75, .ohm = 6544 },
98088ce2acSGuenter Roeck { .temp_c = 80, .ohm = 5518 },
99088ce2acSGuenter Roeck { .temp_c = 85, .ohm = 4674 },
100088ce2acSGuenter Roeck { .temp_c = 90, .ohm = 3972 },
101088ce2acSGuenter Roeck { .temp_c = 95, .ohm = 3388 },
102088ce2acSGuenter Roeck { .temp_c = 100, .ohm = 2902 },
103088ce2acSGuenter Roeck { .temp_c = 105, .ohm = 2494 },
104088ce2acSGuenter Roeck { .temp_c = 110, .ohm = 2150 },
105088ce2acSGuenter Roeck { .temp_c = 115, .ohm = 1860 },
106088ce2acSGuenter Roeck { .temp_c = 120, .ohm = 1615 },
107088ce2acSGuenter Roeck { .temp_c = 125, .ohm = 1406 },
108f22aaaa7SDonggeun Kim };
1094626dcffSSachin Kamat static const struct ntc_compensation ncpXXwl333[] = {
110088ce2acSGuenter Roeck { .temp_c = -40, .ohm = 1610154 },
111088ce2acSGuenter Roeck { .temp_c = -35, .ohm = 1130850 },
112088ce2acSGuenter Roeck { .temp_c = -30, .ohm = 802609 },
113088ce2acSGuenter Roeck { .temp_c = -25, .ohm = 575385 },
114088ce2acSGuenter Roeck { .temp_c = -20, .ohm = 416464 },
115088ce2acSGuenter Roeck { .temp_c = -15, .ohm = 304219 },
116088ce2acSGuenter Roeck { .temp_c = -10, .ohm = 224193 },
117088ce2acSGuenter Roeck { .temp_c = -5, .ohm = 166623 },
118088ce2acSGuenter Roeck { .temp_c = 0, .ohm = 124850 },
119088ce2acSGuenter Roeck { .temp_c = 5, .ohm = 94287 },
120088ce2acSGuenter Roeck { .temp_c = 10, .ohm = 71747 },
121088ce2acSGuenter Roeck { .temp_c = 15, .ohm = 54996 },
122088ce2acSGuenter Roeck { .temp_c = 20, .ohm = 42455 },
123088ce2acSGuenter Roeck { .temp_c = 25, .ohm = 33000 },
124088ce2acSGuenter Roeck { .temp_c = 30, .ohm = 25822 },
125088ce2acSGuenter Roeck { .temp_c = 35, .ohm = 20335 },
126088ce2acSGuenter Roeck { .temp_c = 40, .ohm = 16115 },
127088ce2acSGuenter Roeck { .temp_c = 45, .ohm = 12849 },
128088ce2acSGuenter Roeck { .temp_c = 50, .ohm = 10306 },
129088ce2acSGuenter Roeck { .temp_c = 55, .ohm = 8314 },
130088ce2acSGuenter Roeck { .temp_c = 60, .ohm = 6746 },
131088ce2acSGuenter Roeck { .temp_c = 65, .ohm = 5503 },
132088ce2acSGuenter Roeck { .temp_c = 70, .ohm = 4513 },
133088ce2acSGuenter Roeck { .temp_c = 75, .ohm = 3721 },
134088ce2acSGuenter Roeck { .temp_c = 80, .ohm = 3084 },
135088ce2acSGuenter Roeck { .temp_c = 85, .ohm = 2569 },
136088ce2acSGuenter Roeck { .temp_c = 90, .ohm = 2151 },
137088ce2acSGuenter Roeck { .temp_c = 95, .ohm = 1809 },
138088ce2acSGuenter Roeck { .temp_c = 100, .ohm = 1529 },
139088ce2acSGuenter Roeck { .temp_c = 105, .ohm = 1299 },
140088ce2acSGuenter Roeck { .temp_c = 110, .ohm = 1108 },
141088ce2acSGuenter Roeck { .temp_c = 115, .ohm = 949 },
142088ce2acSGuenter Roeck { .temp_c = 120, .ohm = 817 },
143088ce2acSGuenter Roeck { .temp_c = 125, .ohm = 707 },
144f22aaaa7SDonggeun Kim };
145f22aaaa7SDonggeun Kim
146887ee434SBeomho Seo static const struct ntc_compensation ncpXXwf104[] = {
147887ee434SBeomho Seo { .temp_c = -40, .ohm = 4397119 },
148887ee434SBeomho Seo { .temp_c = -35, .ohm = 3088599 },
149887ee434SBeomho Seo { .temp_c = -30, .ohm = 2197225 },
150887ee434SBeomho Seo { .temp_c = -25, .ohm = 1581881 },
151887ee434SBeomho Seo { .temp_c = -20, .ohm = 1151037 },
152887ee434SBeomho Seo { .temp_c = -15, .ohm = 846579 },
153887ee434SBeomho Seo { .temp_c = -10, .ohm = 628988 },
154887ee434SBeomho Seo { .temp_c = -5, .ohm = 471632 },
155887ee434SBeomho Seo { .temp_c = 0, .ohm = 357012 },
156887ee434SBeomho Seo { .temp_c = 5, .ohm = 272500 },
157887ee434SBeomho Seo { .temp_c = 10, .ohm = 209710 },
158887ee434SBeomho Seo { .temp_c = 15, .ohm = 162651 },
159887ee434SBeomho Seo { .temp_c = 20, .ohm = 127080 },
160887ee434SBeomho Seo { .temp_c = 25, .ohm = 100000 },
161887ee434SBeomho Seo { .temp_c = 30, .ohm = 79222 },
162887ee434SBeomho Seo { .temp_c = 35, .ohm = 63167 },
163887ee434SBeomho Seo { .temp_c = 40, .ohm = 50677 },
164887ee434SBeomho Seo { .temp_c = 45, .ohm = 40904 },
165887ee434SBeomho Seo { .temp_c = 50, .ohm = 33195 },
166887ee434SBeomho Seo { .temp_c = 55, .ohm = 27091 },
167887ee434SBeomho Seo { .temp_c = 60, .ohm = 22224 },
168887ee434SBeomho Seo { .temp_c = 65, .ohm = 18323 },
169887ee434SBeomho Seo { .temp_c = 70, .ohm = 15184 },
170887ee434SBeomho Seo { .temp_c = 75, .ohm = 12635 },
171887ee434SBeomho Seo { .temp_c = 80, .ohm = 10566 },
172887ee434SBeomho Seo { .temp_c = 85, .ohm = 8873 },
173887ee434SBeomho Seo { .temp_c = 90, .ohm = 7481 },
174887ee434SBeomho Seo { .temp_c = 95, .ohm = 6337 },
175887ee434SBeomho Seo { .temp_c = 100, .ohm = 5384 },
176887ee434SBeomho Seo { .temp_c = 105, .ohm = 4594 },
177887ee434SBeomho Seo { .temp_c = 110, .ohm = 3934 },
178887ee434SBeomho Seo { .temp_c = 115, .ohm = 3380 },
179887ee434SBeomho Seo { .temp_c = 120, .ohm = 2916 },
180887ee434SBeomho Seo { .temp_c = 125, .ohm = 2522 },
181887ee434SBeomho Seo };
182887ee434SBeomho Seo
18354ce3a0dSJoseph McNally static const struct ntc_compensation ncpXXxh103[] = {
184*b5cc1496SMaud Spierings { .temp_c = -40, .ohm = 195652 },
185*b5cc1496SMaud Spierings { .temp_c = -35, .ohm = 148171 },
186*b5cc1496SMaud Spierings { .temp_c = -30, .ohm = 113347 },
187*b5cc1496SMaud Spierings { .temp_c = -25, .ohm = 87559 },
188*b5cc1496SMaud Spierings { .temp_c = -20, .ohm = 68237 },
189*b5cc1496SMaud Spierings { .temp_c = -15, .ohm = 53650 },
190*b5cc1496SMaud Spierings { .temp_c = -10, .ohm = 42506 },
191*b5cc1496SMaud Spierings { .temp_c = -5, .ohm = 33892 },
192*b5cc1496SMaud Spierings { .temp_c = 0, .ohm = 27219 },
193*b5cc1496SMaud Spierings { .temp_c = 5, .ohm = 22021 },
194*b5cc1496SMaud Spierings { .temp_c = 10, .ohm = 17926 },
195*b5cc1496SMaud Spierings { .temp_c = 15, .ohm = 14674 },
196*b5cc1496SMaud Spierings { .temp_c = 20, .ohm = 12081 },
19754ce3a0dSJoseph McNally { .temp_c = 25, .ohm = 10000 },
198*b5cc1496SMaud Spierings { .temp_c = 30, .ohm = 8315 },
199*b5cc1496SMaud Spierings { .temp_c = 35, .ohm = 6948 },
200*b5cc1496SMaud Spierings { .temp_c = 40, .ohm = 5834 },
201*b5cc1496SMaud Spierings { .temp_c = 45, .ohm = 4917 },
202*b5cc1496SMaud Spierings { .temp_c = 50, .ohm = 4161 },
203*b5cc1496SMaud Spierings { .temp_c = 55, .ohm = 3535 },
204*b5cc1496SMaud Spierings { .temp_c = 60, .ohm = 3014 },
205*b5cc1496SMaud Spierings { .temp_c = 65, .ohm = 2586 },
206*b5cc1496SMaud Spierings { .temp_c = 70, .ohm = 2228 },
207*b5cc1496SMaud Spierings { .temp_c = 75, .ohm = 1925 },
208*b5cc1496SMaud Spierings { .temp_c = 80, .ohm = 1669 },
209*b5cc1496SMaud Spierings { .temp_c = 85, .ohm = 1452 },
210*b5cc1496SMaud Spierings { .temp_c = 90, .ohm = 1268 },
211*b5cc1496SMaud Spierings { .temp_c = 95, .ohm = 1110 },
212*b5cc1496SMaud Spierings { .temp_c = 100, .ohm = 974 },
213*b5cc1496SMaud Spierings { .temp_c = 105, .ohm = 858 },
214*b5cc1496SMaud Spierings { .temp_c = 110, .ohm = 758 },
215*b5cc1496SMaud Spierings { .temp_c = 115, .ohm = 672 },
216*b5cc1496SMaud Spierings { .temp_c = 120, .ohm = 596 },
217*b5cc1496SMaud Spierings { .temp_c = 125, .ohm = 531 },
21854ce3a0dSJoseph McNally };
21954ce3a0dSJoseph McNally
220ed67f087SJohannes Pointner /*
221e8fda2c8SPeter Rosin * The following compensation tables are from the specifications in EPCOS NTC
222e8fda2c8SPeter Rosin * Thermistors Datasheets
223ed67f087SJohannes Pointner */
224ed67f087SJohannes Pointner static const struct ntc_compensation b57330v2103[] = {
225ed67f087SJohannes Pointner { .temp_c = -40, .ohm = 190030 },
226ed67f087SJohannes Pointner { .temp_c = -35, .ohm = 145360 },
227ed67f087SJohannes Pointner { .temp_c = -30, .ohm = 112060 },
228ed67f087SJohannes Pointner { .temp_c = -25, .ohm = 87041 },
229ed67f087SJohannes Pointner { .temp_c = -20, .ohm = 68104 },
230ed67f087SJohannes Pointner { .temp_c = -15, .ohm = 53665 },
231ed67f087SJohannes Pointner { .temp_c = -10, .ohm = 42576 },
232ed67f087SJohannes Pointner { .temp_c = -5, .ohm = 34001 },
233ed67f087SJohannes Pointner { .temp_c = 0, .ohm = 27326 },
234ed67f087SJohannes Pointner { .temp_c = 5, .ohm = 22096 },
235ed67f087SJohannes Pointner { .temp_c = 10, .ohm = 17973 },
236ed67f087SJohannes Pointner { .temp_c = 15, .ohm = 14703 },
237ed67f087SJohannes Pointner { .temp_c = 20, .ohm = 12090 },
238ed67f087SJohannes Pointner { .temp_c = 25, .ohm = 10000 },
239ed67f087SJohannes Pointner { .temp_c = 30, .ohm = 8311 },
240ed67f087SJohannes Pointner { .temp_c = 35, .ohm = 6941 },
241ed67f087SJohannes Pointner { .temp_c = 40, .ohm = 5825 },
242ed67f087SJohannes Pointner { .temp_c = 45, .ohm = 4911 },
243ed67f087SJohannes Pointner { .temp_c = 50, .ohm = 4158 },
244ed67f087SJohannes Pointner { .temp_c = 55, .ohm = 3536 },
245ed67f087SJohannes Pointner { .temp_c = 60, .ohm = 3019 },
246ed67f087SJohannes Pointner { .temp_c = 65, .ohm = 2588 },
247ed67f087SJohannes Pointner { .temp_c = 70, .ohm = 2227 },
248ed67f087SJohannes Pointner { .temp_c = 75, .ohm = 1924 },
249ed67f087SJohannes Pointner { .temp_c = 80, .ohm = 1668 },
250ed67f087SJohannes Pointner { .temp_c = 85, .ohm = 1451 },
251ed67f087SJohannes Pointner { .temp_c = 90, .ohm = 1266 },
252ed67f087SJohannes Pointner { .temp_c = 95, .ohm = 1108 },
253ed67f087SJohannes Pointner { .temp_c = 100, .ohm = 973 },
254ed67f087SJohannes Pointner { .temp_c = 105, .ohm = 857 },
255ed67f087SJohannes Pointner { .temp_c = 110, .ohm = 757 },
256ed67f087SJohannes Pointner { .temp_c = 115, .ohm = 671 },
257ed67f087SJohannes Pointner { .temp_c = 120, .ohm = 596 },
258ed67f087SJohannes Pointner { .temp_c = 125, .ohm = 531 },
259ed67f087SJohannes Pointner };
260ed67f087SJohannes Pointner
261e8fda2c8SPeter Rosin static const struct ntc_compensation b57891s0103[] = {
262e8fda2c8SPeter Rosin { .temp_c = -55.0, .ohm = 878900 },
263e8fda2c8SPeter Rosin { .temp_c = -50.0, .ohm = 617590 },
264e8fda2c8SPeter Rosin { .temp_c = -45.0, .ohm = 439340 },
265e8fda2c8SPeter Rosin { .temp_c = -40.0, .ohm = 316180 },
266e8fda2c8SPeter Rosin { .temp_c = -35.0, .ohm = 230060 },
267e8fda2c8SPeter Rosin { .temp_c = -30.0, .ohm = 169150 },
268e8fda2c8SPeter Rosin { .temp_c = -25.0, .ohm = 125550 },
269e8fda2c8SPeter Rosin { .temp_c = -20.0, .ohm = 94143 },
270e8fda2c8SPeter Rosin { .temp_c = -15.0, .ohm = 71172 },
271e8fda2c8SPeter Rosin { .temp_c = -10.0, .ohm = 54308 },
272e8fda2c8SPeter Rosin { .temp_c = -5.0, .ohm = 41505 },
273e8fda2c8SPeter Rosin { .temp_c = 0.0, .ohm = 32014 },
274e8fda2c8SPeter Rosin { .temp_c = 5.0, .ohm = 25011 },
275e8fda2c8SPeter Rosin { .temp_c = 10.0, .ohm = 19691 },
276e8fda2c8SPeter Rosin { .temp_c = 15.0, .ohm = 15618 },
277e8fda2c8SPeter Rosin { .temp_c = 20.0, .ohm = 12474 },
278e8fda2c8SPeter Rosin { .temp_c = 25.0, .ohm = 10000 },
279e8fda2c8SPeter Rosin { .temp_c = 30.0, .ohm = 8080 },
280e8fda2c8SPeter Rosin { .temp_c = 35.0, .ohm = 6569 },
281e8fda2c8SPeter Rosin { .temp_c = 40.0, .ohm = 5372 },
282e8fda2c8SPeter Rosin { .temp_c = 45.0, .ohm = 4424 },
283e8fda2c8SPeter Rosin { .temp_c = 50.0, .ohm = 3661 },
284e8fda2c8SPeter Rosin { .temp_c = 55.0, .ohm = 3039 },
285e8fda2c8SPeter Rosin { .temp_c = 60.0, .ohm = 2536 },
286e8fda2c8SPeter Rosin { .temp_c = 65.0, .ohm = 2128 },
287e8fda2c8SPeter Rosin { .temp_c = 70.0, .ohm = 1794 },
288e8fda2c8SPeter Rosin { .temp_c = 75.0, .ohm = 1518 },
289e8fda2c8SPeter Rosin { .temp_c = 80.0, .ohm = 1290 },
290e8fda2c8SPeter Rosin { .temp_c = 85.0, .ohm = 1100 },
291e8fda2c8SPeter Rosin { .temp_c = 90.0, .ohm = 942 },
292e8fda2c8SPeter Rosin { .temp_c = 95.0, .ohm = 809 },
293e8fda2c8SPeter Rosin { .temp_c = 100.0, .ohm = 697 },
294e8fda2c8SPeter Rosin { .temp_c = 105.0, .ohm = 604 },
295e8fda2c8SPeter Rosin { .temp_c = 110.0, .ohm = 525 },
296e8fda2c8SPeter Rosin { .temp_c = 115.0, .ohm = 457 },
297e8fda2c8SPeter Rosin { .temp_c = 120.0, .ohm = 400 },
298e8fda2c8SPeter Rosin { .temp_c = 125.0, .ohm = 351 },
299e8fda2c8SPeter Rosin { .temp_c = 130.0, .ohm = 308 },
300e8fda2c8SPeter Rosin { .temp_c = 135.0, .ohm = 272 },
301e8fda2c8SPeter Rosin { .temp_c = 140.0, .ohm = 240 },
302e8fda2c8SPeter Rosin { .temp_c = 145.0, .ohm = 213 },
303e8fda2c8SPeter Rosin { .temp_c = 150.0, .ohm = 189 },
304e8fda2c8SPeter Rosin { .temp_c = 155.0, .ohm = 168 },
305e8fda2c8SPeter Rosin };
306e8fda2c8SPeter Rosin
307737c086eSPeter Rosin struct ntc_type {
308737c086eSPeter Rosin const struct ntc_compensation *comp;
309737c086eSPeter Rosin int n_comp;
310737c086eSPeter Rosin };
311737c086eSPeter Rosin
312737c086eSPeter Rosin #define NTC_TYPE(ntc, compensation) \
313737c086eSPeter Rosin [(ntc)] = { .comp = (compensation), .n_comp = ARRAY_SIZE(compensation) }
314737c086eSPeter Rosin
315737c086eSPeter Rosin static const struct ntc_type ntc_type[] = {
316737c086eSPeter Rosin NTC_TYPE(TYPE_B57330V2103, b57330v2103),
317737c086eSPeter Rosin NTC_TYPE(TYPE_B57891S0103, b57891s0103),
318737c086eSPeter Rosin NTC_TYPE(TYPE_NCPXXWB473, ncpXXwb473),
319737c086eSPeter Rosin NTC_TYPE(TYPE_NCPXXWF104, ncpXXwf104),
320737c086eSPeter Rosin NTC_TYPE(TYPE_NCPXXWL333, ncpXXwl333),
321737c086eSPeter Rosin NTC_TYPE(TYPE_NCPXXXH103, ncpXXxh103),
322737c086eSPeter Rosin };
323737c086eSPeter Rosin
324e380095bSLinus Walleij /*
325e380095bSLinus Walleij * pullup_uV, pullup_ohm, pulldown_ohm, and connect are required.
326e380095bSLinus Walleij *
327e380095bSLinus Walleij * How to setup pullup_ohm, pulldown_ohm, and connect is
328e380095bSLinus Walleij * described at Documentation/hwmon/ntc_thermistor.rst
329e380095bSLinus Walleij *
330e380095bSLinus Walleij * pullup/down_ohm: 0 for infinite / not-connected
331e380095bSLinus Walleij *
332e380095bSLinus Walleij * chan: iio_channel pointer to communicate with the ADC which the
333e380095bSLinus Walleij * thermistor is using for conversion of the analog values.
334e380095bSLinus Walleij */
335f22aaaa7SDonggeun Kim struct ntc_data {
336f22aaaa7SDonggeun Kim const struct ntc_compensation *comp;
337f22aaaa7SDonggeun Kim int n_comp;
338e380095bSLinus Walleij unsigned int pullup_uv;
339e380095bSLinus Walleij unsigned int pullup_ohm;
340e380095bSLinus Walleij unsigned int pulldown_ohm;
341e380095bSLinus Walleij enum { NTC_CONNECTED_POSITIVE, NTC_CONNECTED_GROUND } connect;
342e380095bSLinus Walleij struct iio_channel *chan;
343f22aaaa7SDonggeun Kim };
344f22aaaa7SDonggeun Kim
ntc_adc_iio_read(struct ntc_data * data)345e380095bSLinus Walleij static int ntc_adc_iio_read(struct ntc_data *data)
3469e8269deSNaveen Krishna Chatradhi {
347e380095bSLinus Walleij struct iio_channel *channel = data->chan;
3484f2d9cceSLinus Walleij int uv, ret;
3499e8269deSNaveen Krishna Chatradhi
3504f2d9cceSLinus Walleij ret = iio_read_channel_processed_scale(channel, &uv, 1000);
3514f2d9cceSLinus Walleij if (ret < 0) {
3524f2d9cceSLinus Walleij int raw;
3534f2d9cceSLinus Walleij
3544f2d9cceSLinus Walleij /*
3554f2d9cceSLinus Walleij * This fallback uses a raw read and then
3564f2d9cceSLinus Walleij * assumes the ADC is 12 bits, scaling with
3574f2d9cceSLinus Walleij * a factor 1000 to get to microvolts.
3584f2d9cceSLinus Walleij */
3590315253bSChris Lesiak ret = iio_read_channel_raw(channel, &raw);
3609e8269deSNaveen Krishna Chatradhi if (ret < 0) {
3619e8269deSNaveen Krishna Chatradhi pr_err("read channel() error: %d\n", ret);
3629e8269deSNaveen Krishna Chatradhi return ret;
3639e8269deSNaveen Krishna Chatradhi }
3640315253bSChris Lesiak ret = iio_convert_raw_to_processed(channel, raw, &uv, 1000);
3650315253bSChris Lesiak if (ret < 0) {
3660315253bSChris Lesiak /* Assume 12 bit ADC with vref at pullup_uv */
367e380095bSLinus Walleij uv = (data->pullup_uv * (s64)raw) >> 12;
3680315253bSChris Lesiak }
3694f2d9cceSLinus Walleij }
3709e8269deSNaveen Krishna Chatradhi
3710315253bSChris Lesiak return uv;
3729e8269deSNaveen Krishna Chatradhi }
3739e8269deSNaveen Krishna Chatradhi
div64_u64_safe(u64 dividend,u64 divisor)374f22aaaa7SDonggeun Kim static inline u64 div64_u64_safe(u64 dividend, u64 divisor)
375f22aaaa7SDonggeun Kim {
376f22aaaa7SDonggeun Kim if (divisor == 0 && dividend == 0)
377f22aaaa7SDonggeun Kim return 0;
378f22aaaa7SDonggeun Kim if (divisor == 0)
379f22aaaa7SDonggeun Kim return UINT_MAX;
380f22aaaa7SDonggeun Kim return div64_u64(dividend, divisor);
381f22aaaa7SDonggeun Kim }
382f22aaaa7SDonggeun Kim
get_ohm_of_thermistor(struct ntc_data * data,unsigned int uv)383088ce2acSGuenter Roeck static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv)
384f22aaaa7SDonggeun Kim {
385e380095bSLinus Walleij u32 puv = data->pullup_uv;
386088ce2acSGuenter Roeck u64 n, puo, pdo;
387e380095bSLinus Walleij puo = data->pullup_ohm;
388e380095bSLinus Walleij pdo = data->pulldown_ohm;
389f22aaaa7SDonggeun Kim
390f6725ae2SChris Lesiak if (uv == 0)
391e380095bSLinus Walleij return (data->connect == NTC_CONNECTED_POSITIVE) ?
392f6725ae2SChris Lesiak INT_MAX : 0;
393f6725ae2SChris Lesiak if (uv >= puv)
394e380095bSLinus Walleij return (data->connect == NTC_CONNECTED_POSITIVE) ?
395dbe43a62SGuenter Roeck 0 : INT_MAX;
396f22aaaa7SDonggeun Kim
397e380095bSLinus Walleij if (data->connect == NTC_CONNECTED_POSITIVE && puo == 0)
398f6725ae2SChris Lesiak n = div_u64(pdo * (puv - uv), uv);
399e380095bSLinus Walleij else if (data->connect == NTC_CONNECTED_GROUND && pdo == 0)
400f6725ae2SChris Lesiak n = div_u64(puo * uv, puv - uv);
401e380095bSLinus Walleij else if (data->connect == NTC_CONNECTED_POSITIVE)
402f6725ae2SChris Lesiak n = div64_u64_safe(pdo * puo * (puv - uv),
403f6725ae2SChris Lesiak puo * uv - pdo * (puv - uv));
404f22aaaa7SDonggeun Kim else
405f6725ae2SChris Lesiak n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv);
406f22aaaa7SDonggeun Kim
407088ce2acSGuenter Roeck if (n > INT_MAX)
408088ce2acSGuenter Roeck n = INT_MAX;
409088ce2acSGuenter Roeck return n;
410f22aaaa7SDonggeun Kim }
411f22aaaa7SDonggeun Kim
lookup_comp(struct ntc_data * data,unsigned int ohm,int * i_low,int * i_high)412dbe43a62SGuenter Roeck static void lookup_comp(struct ntc_data *data, unsigned int ohm,
413dbe43a62SGuenter Roeck int *i_low, int *i_high)
414f22aaaa7SDonggeun Kim {
415dbe43a62SGuenter Roeck int start, end, mid;
416dbe43a62SGuenter Roeck
417dbe43a62SGuenter Roeck /*
418dbe43a62SGuenter Roeck * Handle special cases: Resistance is higher than or equal to
419dbe43a62SGuenter Roeck * resistance in first table entry, or resistance is lower or equal
420dbe43a62SGuenter Roeck * to resistance in last table entry.
421dbe43a62SGuenter Roeck * In these cases, return i_low == i_high, either pointing to the
422dbe43a62SGuenter Roeck * beginning or to the end of the table depending on the condition.
423dbe43a62SGuenter Roeck */
424dbe43a62SGuenter Roeck if (ohm >= data->comp[0].ohm) {
425dbe43a62SGuenter Roeck *i_low = 0;
426dbe43a62SGuenter Roeck *i_high = 0;
427dbe43a62SGuenter Roeck return;
428dbe43a62SGuenter Roeck }
429dbe43a62SGuenter Roeck if (ohm <= data->comp[data->n_comp - 1].ohm) {
430dbe43a62SGuenter Roeck *i_low = data->n_comp - 1;
431dbe43a62SGuenter Roeck *i_high = data->n_comp - 1;
432dbe43a62SGuenter Roeck return;
433dbe43a62SGuenter Roeck }
434f22aaaa7SDonggeun Kim
435f22aaaa7SDonggeun Kim /* Do a binary search on compensation table */
436f22aaaa7SDonggeun Kim start = 0;
437f22aaaa7SDonggeun Kim end = data->n_comp;
438dbe43a62SGuenter Roeck while (start < end) {
439f22aaaa7SDonggeun Kim mid = start + (end - start) / 2;
440dbe43a62SGuenter Roeck /*
441dbe43a62SGuenter Roeck * start <= mid < end
442dbe43a62SGuenter Roeck * data->comp[start].ohm > ohm >= data->comp[end].ohm
443dbe43a62SGuenter Roeck *
444dbe43a62SGuenter Roeck * We could check for "ohm == data->comp[mid].ohm" here, but
445dbe43a62SGuenter Roeck * that is a quite unlikely condition, and we would have to
446dbe43a62SGuenter Roeck * check again after updating start. Check it at the end instead
447dbe43a62SGuenter Roeck * for simplicity.
448dbe43a62SGuenter Roeck */
449dbe43a62SGuenter Roeck if (ohm >= data->comp[mid].ohm) {
450f22aaaa7SDonggeun Kim end = mid;
451dbe43a62SGuenter Roeck } else {
452f22aaaa7SDonggeun Kim start = mid + 1;
453dbe43a62SGuenter Roeck /*
454dbe43a62SGuenter Roeck * ohm >= data->comp[start].ohm might be true here,
455dbe43a62SGuenter Roeck * since we set start to mid + 1. In that case, we are
456dbe43a62SGuenter Roeck * done. We could keep going, but the condition is quite
457dbe43a62SGuenter Roeck * likely to occur, so it is worth checking for it.
458dbe43a62SGuenter Roeck */
459dbe43a62SGuenter Roeck if (ohm >= data->comp[start].ohm)
460dbe43a62SGuenter Roeck end = start;
461dbe43a62SGuenter Roeck }
462dbe43a62SGuenter Roeck /*
463dbe43a62SGuenter Roeck * start <= end
464dbe43a62SGuenter Roeck * data->comp[start].ohm >= ohm >= data->comp[end].ohm
465dbe43a62SGuenter Roeck */
466dbe43a62SGuenter Roeck }
467dbe43a62SGuenter Roeck /*
468dbe43a62SGuenter Roeck * start == end
469dbe43a62SGuenter Roeck * ohm >= data->comp[end].ohm
470dbe43a62SGuenter Roeck */
471dbe43a62SGuenter Roeck *i_low = end;
472dbe43a62SGuenter Roeck if (ohm == data->comp[end].ohm)
473dbe43a62SGuenter Roeck *i_high = end;
474f22aaaa7SDonggeun Kim else
475dbe43a62SGuenter Roeck *i_high = end - 1;
476f22aaaa7SDonggeun Kim }
477f22aaaa7SDonggeun Kim
get_temp_mc(struct ntc_data * data,unsigned int ohm)478088ce2acSGuenter Roeck static int get_temp_mc(struct ntc_data *data, unsigned int ohm)
479f22aaaa7SDonggeun Kim {
480f22aaaa7SDonggeun Kim int low, high;
481dbe43a62SGuenter Roeck int temp;
482f22aaaa7SDonggeun Kim
483dbe43a62SGuenter Roeck lookup_comp(data, ohm, &low, &high);
484bd56c1e9SLinus Walleij /*
485bd56c1e9SLinus Walleij * First multiplying the table temperatures with 1000 to get to
486bd56c1e9SLinus Walleij * millicentigrades (which is what we want) and then interpolating
487bd56c1e9SLinus Walleij * will give the best precision.
488bd56c1e9SLinus Walleij */
489bd56c1e9SLinus Walleij temp = fixp_linear_interpolate(data->comp[low].ohm,
490bd56c1e9SLinus Walleij data->comp[low].temp_c * 1000,
491bd56c1e9SLinus Walleij data->comp[high].ohm,
492bd56c1e9SLinus Walleij data->comp[high].temp_c * 1000,
493bd56c1e9SLinus Walleij ohm);
494dbe43a62SGuenter Roeck return temp;
495f22aaaa7SDonggeun Kim }
496f22aaaa7SDonggeun Kim
ntc_thermistor_get_ohm(struct ntc_data * data)497dbe43a62SGuenter Roeck static int ntc_thermistor_get_ohm(struct ntc_data *data)
498f22aaaa7SDonggeun Kim {
499088ce2acSGuenter Roeck int read_uv;
500f22aaaa7SDonggeun Kim
501e380095bSLinus Walleij read_uv = ntc_adc_iio_read(data);
502088ce2acSGuenter Roeck if (read_uv < 0)
503088ce2acSGuenter Roeck return read_uv;
504088ce2acSGuenter Roeck return get_ohm_of_thermistor(data, read_uv);
505f22aaaa7SDonggeun Kim }
506f22aaaa7SDonggeun Kim
ntc_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)5077cc7de93SGuenter Roeck static int ntc_read(struct device *dev, enum hwmon_sensor_types type,
5087cc7de93SGuenter Roeck u32 attr, int channel, long *val)
509f22aaaa7SDonggeun Kim {
510f22aaaa7SDonggeun Kim struct ntc_data *data = dev_get_drvdata(dev);
511dbe43a62SGuenter Roeck int ohm;
512f22aaaa7SDonggeun Kim
5137cc7de93SGuenter Roeck switch (type) {
5147cc7de93SGuenter Roeck case hwmon_temp:
5157cc7de93SGuenter Roeck switch (attr) {
5167cc7de93SGuenter Roeck case hwmon_temp_input:
517dbe43a62SGuenter Roeck ohm = ntc_thermistor_get_ohm(data);
518dbe43a62SGuenter Roeck if (ohm < 0)
519dbe43a62SGuenter Roeck return ohm;
5207cc7de93SGuenter Roeck *val = get_temp_mc(data, ohm);
5217cc7de93SGuenter Roeck return 0;
5227cc7de93SGuenter Roeck case hwmon_temp_type:
5237cc7de93SGuenter Roeck *val = 4;
5247cc7de93SGuenter Roeck return 0;
5257cc7de93SGuenter Roeck default:
5267cc7de93SGuenter Roeck break;
5277cc7de93SGuenter Roeck }
5287cc7de93SGuenter Roeck break;
5297cc7de93SGuenter Roeck default:
5307cc7de93SGuenter Roeck break;
5317cc7de93SGuenter Roeck }
5327cc7de93SGuenter Roeck return -EINVAL;
533f22aaaa7SDonggeun Kim }
534f22aaaa7SDonggeun Kim
ntc_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)5357cc7de93SGuenter Roeck static umode_t ntc_is_visible(const void *data, enum hwmon_sensor_types type,
5367cc7de93SGuenter Roeck u32 attr, int channel)
5377cc7de93SGuenter Roeck {
5387cc7de93SGuenter Roeck if (type == hwmon_temp) {
5397cc7de93SGuenter Roeck switch (attr) {
5407cc7de93SGuenter Roeck case hwmon_temp_input:
5417cc7de93SGuenter Roeck case hwmon_temp_type:
5427cc7de93SGuenter Roeck return 0444;
5437cc7de93SGuenter Roeck default:
5447cc7de93SGuenter Roeck break;
5457cc7de93SGuenter Roeck }
5467cc7de93SGuenter Roeck }
5477cc7de93SGuenter Roeck return 0;
5487cc7de93SGuenter Roeck }
549f22aaaa7SDonggeun Kim
5509add51f2SKrzysztof Kozlowski static const struct hwmon_channel_info * const ntc_info[] = {
5510ddca577SGuenter Roeck HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
5520ddca577SGuenter Roeck HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_TYPE),
5537cc7de93SGuenter Roeck NULL
5547cc7de93SGuenter Roeck };
5557cc7de93SGuenter Roeck
5567cc7de93SGuenter Roeck static const struct hwmon_ops ntc_hwmon_ops = {
5577cc7de93SGuenter Roeck .is_visible = ntc_is_visible,
5587cc7de93SGuenter Roeck .read = ntc_read,
5597cc7de93SGuenter Roeck };
5607cc7de93SGuenter Roeck
5617cc7de93SGuenter Roeck static const struct hwmon_chip_info ntc_chip_info = {
5627cc7de93SGuenter Roeck .ops = &ntc_hwmon_ops,
5637cc7de93SGuenter Roeck .info = ntc_info,
5642251aef6SEduardo Valentin };
5652251aef6SEduardo Valentin
ntc_thermistor_parse_props(struct device * dev,struct ntc_data * data)56670760e80SLinus Walleij static int ntc_thermistor_parse_props(struct device *dev,
567e0149eebSLinus Walleij struct ntc_data *data)
568e0149eebSLinus Walleij {
569e0149eebSLinus Walleij struct iio_channel *chan;
570e0149eebSLinus Walleij enum iio_chan_type type;
571e0149eebSLinus Walleij int ret;
572e0149eebSLinus Walleij
573e0149eebSLinus Walleij chan = devm_iio_channel_get(dev, NULL);
574e0149eebSLinus Walleij if (IS_ERR(chan))
575e0149eebSLinus Walleij return PTR_ERR(chan);
576e0149eebSLinus Walleij
577e0149eebSLinus Walleij ret = iio_get_channel_type(chan, &type);
578e0149eebSLinus Walleij if (ret < 0)
579e0149eebSLinus Walleij return ret;
580e0149eebSLinus Walleij
581e0149eebSLinus Walleij if (type != IIO_VOLTAGE)
582e0149eebSLinus Walleij return -EINVAL;
583e0149eebSLinus Walleij
58470760e80SLinus Walleij ret = device_property_read_u32(dev, "pullup-uv", &data->pullup_uv);
58570760e80SLinus Walleij if (ret)
58670760e80SLinus Walleij return dev_err_probe(dev, ret, "pullup-uv not specified\n");
587e0149eebSLinus Walleij
58870760e80SLinus Walleij ret = device_property_read_u32(dev, "pullup-ohm", &data->pullup_ohm);
58970760e80SLinus Walleij if (ret)
59070760e80SLinus Walleij return dev_err_probe(dev, ret, "pullup-ohm not specified\n");
59170760e80SLinus Walleij
59270760e80SLinus Walleij ret = device_property_read_u32(dev, "pulldown-ohm", &data->pulldown_ohm);
59370760e80SLinus Walleij if (ret)
59470760e80SLinus Walleij return dev_err_probe(dev, ret, "pulldown-ohm not specified\n");
59570760e80SLinus Walleij
59670760e80SLinus Walleij if (device_property_read_bool(dev, "connected-positive"))
597e0149eebSLinus Walleij data->connect = NTC_CONNECTED_POSITIVE;
598e0149eebSLinus Walleij else /* status change should be possible if not always on. */
599e0149eebSLinus Walleij data->connect = NTC_CONNECTED_GROUND;
600e0149eebSLinus Walleij
601e0149eebSLinus Walleij data->chan = chan;
602e0149eebSLinus Walleij
603e0149eebSLinus Walleij return 0;
604e0149eebSLinus Walleij }
605e0149eebSLinus Walleij
ntc_thermistor_probe(struct platform_device * pdev)6066c931ae1SBill Pemberton static int ntc_thermistor_probe(struct platform_device *pdev)
607f22aaaa7SDonggeun Kim {
60848001525SGuenter Roeck struct device *dev = &pdev->dev;
6099e8269deSNaveen Krishna Chatradhi const struct platform_device_id *pdev_id;
6105e7f5994SGuenter Roeck struct device *hwmon_dev;
611f22aaaa7SDonggeun Kim struct ntc_data *data;
612e0149eebSLinus Walleij int ret;
6139e8269deSNaveen Krishna Chatradhi
614e0149eebSLinus Walleij data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
615e0149eebSLinus Walleij if (!data)
616e0149eebSLinus Walleij return -ENOMEM;
617f22aaaa7SDonggeun Kim
61870760e80SLinus Walleij ret = ntc_thermistor_parse_props(dev, data);
619e0149eebSLinus Walleij if (ret)
620e0149eebSLinus Walleij return ret;
621f22aaaa7SDonggeun Kim
622e380095bSLinus Walleij if (data->pullup_uv == 0 ||
623e380095bSLinus Walleij (data->pullup_ohm == 0 && data->connect ==
624f22aaaa7SDonggeun Kim NTC_CONNECTED_GROUND) ||
625e380095bSLinus Walleij (data->pulldown_ohm == 0 && data->connect ==
626f22aaaa7SDonggeun Kim NTC_CONNECTED_POSITIVE) ||
627e380095bSLinus Walleij (data->connect != NTC_CONNECTED_POSITIVE &&
628e380095bSLinus Walleij data->connect != NTC_CONNECTED_GROUND)) {
629209218efSLinus Walleij dev_err(dev, "Required data to use NTC driver not supplied.\n");
630f22aaaa7SDonggeun Kim return -EINVAL;
631f22aaaa7SDonggeun Kim }
632f22aaaa7SDonggeun Kim
63370760e80SLinus Walleij pdev_id = device_get_match_data(dev);
6349e8269deSNaveen Krishna Chatradhi
635737c086eSPeter Rosin if (pdev_id->driver_data >= ARRAY_SIZE(ntc_type)) {
63648001525SGuenter Roeck dev_err(dev, "Unknown device type: %lu(%s)\n",
6379e8269deSNaveen Krishna Chatradhi pdev_id->driver_data, pdev_id->name);
63841141e64SGuenter Roeck return -EINVAL;
639f22aaaa7SDonggeun Kim }
640f22aaaa7SDonggeun Kim
641737c086eSPeter Rosin data->comp = ntc_type[pdev_id->driver_data].comp;
642737c086eSPeter Rosin data->n_comp = ntc_type[pdev_id->driver_data].n_comp;
643737c086eSPeter Rosin
6447cc7de93SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev_id->name,
6457cc7de93SGuenter Roeck data, &ntc_chip_info,
6467cc7de93SGuenter Roeck NULL);
6475e7f5994SGuenter Roeck if (IS_ERR(hwmon_dev)) {
64848001525SGuenter Roeck dev_err(dev, "unable to register as hwmon device.\n");
6495e7f5994SGuenter Roeck return PTR_ERR(hwmon_dev);
650f22aaaa7SDonggeun Kim }
651f22aaaa7SDonggeun Kim
65248001525SGuenter Roeck dev_info(dev, "Thermistor type: %s successfully probed.\n",
65393a88ef3SNaveen Krishna Chatradhi pdev_id->name);
6549e8269deSNaveen Krishna Chatradhi
655f22aaaa7SDonggeun Kim return 0;
656f22aaaa7SDonggeun Kim }
657f22aaaa7SDonggeun Kim
6589f448e79SLinus Walleij static const struct of_device_id ntc_match[] = {
6599f448e79SLinus Walleij { .compatible = "epcos,b57330v2103",
6609f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_B57330V2103]},
6619f448e79SLinus Walleij { .compatible = "epcos,b57891s0103",
6629f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_B57891S0103] },
6639f448e79SLinus Walleij { .compatible = "murata,ncp03wb473",
6649f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP03WB473] },
6659f448e79SLinus Walleij { .compatible = "murata,ncp03wf104",
6669f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP03WF104] },
6679f448e79SLinus Walleij { .compatible = "murata,ncp15wb473",
6689f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP15WB473] },
6699f448e79SLinus Walleij { .compatible = "murata,ncp15wl333",
6709f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP15WL333] },
6719f448e79SLinus Walleij { .compatible = "murata,ncp15xh103",
6729f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP15XH103] },
6739f448e79SLinus Walleij { .compatible = "murata,ncp18wb473",
6749f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP18WB473] },
6759f448e79SLinus Walleij { .compatible = "murata,ncp21wb473",
6769f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP21WB473] },
677e13e979bSLinus Walleij { .compatible = "samsung,1404-001221",
678e13e979bSLinus Walleij .data = &ntc_thermistor_id[NTC_SSG1404001221] },
6799f448e79SLinus Walleij
6809f448e79SLinus Walleij /* Usage of vendor name "ntc" is deprecated */
6819f448e79SLinus Walleij { .compatible = "ntc,ncp03wb473",
6829f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP03WB473] },
6839f448e79SLinus Walleij { .compatible = "ntc,ncp15wb473",
6849f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP15WB473] },
6859f448e79SLinus Walleij { .compatible = "ntc,ncp15wl333",
6869f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP15WL333] },
6879f448e79SLinus Walleij { .compatible = "ntc,ncp18wb473",
6889f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP18WB473] },
6899f448e79SLinus Walleij { .compatible = "ntc,ncp21wb473",
6909f448e79SLinus Walleij .data = &ntc_thermistor_id[NTC_NCP21WB473] },
6919f448e79SLinus Walleij { },
6929f448e79SLinus Walleij };
6939f448e79SLinus Walleij MODULE_DEVICE_TABLE(of, ntc_match);
6949f448e79SLinus Walleij
695f22aaaa7SDonggeun Kim static struct platform_driver ntc_thermistor_driver = {
696f22aaaa7SDonggeun Kim .driver = {
697f22aaaa7SDonggeun Kim .name = "ntc-thermistor",
69870760e80SLinus Walleij .of_match_table = ntc_match,
699f22aaaa7SDonggeun Kim },
700f22aaaa7SDonggeun Kim .probe = ntc_thermistor_probe,
701f22aaaa7SDonggeun Kim .id_table = ntc_thermistor_id,
702f22aaaa7SDonggeun Kim };
703f22aaaa7SDonggeun Kim
70425a236a5SAxel Lin module_platform_driver(ntc_thermistor_driver);
705f22aaaa7SDonggeun Kim
706ed67f087SJohannes Pointner MODULE_DESCRIPTION("NTC Thermistor Driver");
707f22aaaa7SDonggeun Kim MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
708f22aaaa7SDonggeun Kim MODULE_LICENSE("GPL");
709f22aaaa7SDonggeun Kim MODULE_ALIAS("platform:ntc-thermistor");
710