hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/hwmon/ntc_thermistor.c
....@@ -1,23 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * ntc_thermistor.c - NTC Thermistors
34 *
45 * Copyright (C) 2010 Samsung Electronics
56 * MyungJoo Ham <myungjoo.ham@samsung.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
- *
217 */
228
239 #include <linux/slab.h>
....@@ -37,25 +23,40 @@
3723 #include <linux/iio/consumer.h>
3824
3925 #include <linux/hwmon.h>
40
-#include <linux/hwmon-sysfs.h>
41
-#include <linux/thermal.h>
4226
4327 struct ntc_compensation {
4428 int temp_c;
4529 unsigned int ohm;
4630 };
4731
48
-/* Order matters, ntc_match references the entries by index */
32
+/*
33
+ * Used as index in a zero-terminated array, holes not allowed so
34
+ * that NTC_LAST is the first empty array entry.
35
+ */
36
+enum {
37
+ NTC_B57330V2103,
38
+ NTC_B57891S0103,
39
+ NTC_NCP03WB473,
40
+ NTC_NCP03WF104,
41
+ NTC_NCP15WB473,
42
+ NTC_NCP15WL333,
43
+ NTC_NCP15XH103,
44
+ NTC_NCP18WB473,
45
+ NTC_NCP21WB473,
46
+ NTC_LAST,
47
+};
48
+
4949 static const struct platform_device_id ntc_thermistor_id[] = {
50
- { "ncp15wb473", TYPE_NCPXXWB473 },
51
- { "ncp18wb473", TYPE_NCPXXWB473 },
52
- { "ncp21wb473", TYPE_NCPXXWB473 },
53
- { "ncp03wb473", TYPE_NCPXXWB473 },
54
- { "ncp15wl333", TYPE_NCPXXWL333 },
55
- { "b57330v2103", TYPE_B57330V2103},
56
- { "ncp03wf104", TYPE_NCPXXWF104 },
57
- { "ncp15xh103", TYPE_NCPXXXH103 },
58
- { },
50
+ [NTC_B57330V2103] = { "b57330v2103", TYPE_B57330V2103 },
51
+ [NTC_B57891S0103] = { "b57891s0103", TYPE_B57891S0103 },
52
+ [NTC_NCP03WB473] = { "ncp03wb473", TYPE_NCPXXWB473 },
53
+ [NTC_NCP03WF104] = { "ncp03wf104", TYPE_NCPXXWF104 },
54
+ [NTC_NCP15WB473] = { "ncp15wb473", TYPE_NCPXXWB473 },
55
+ [NTC_NCP15WL333] = { "ncp15wl333", TYPE_NCPXXWL333 },
56
+ [NTC_NCP15XH103] = { "ncp15xh103", TYPE_NCPXXXH103 },
57
+ [NTC_NCP18WB473] = { "ncp18wb473", TYPE_NCPXXWB473 },
58
+ [NTC_NCP21WB473] = { "ncp21wb473", TYPE_NCPXXWB473 },
59
+ [NTC_LAST] = { },
5960 };
6061
6162 /*
....@@ -212,8 +213,8 @@
212213 };
213214
214215 /*
215
- * The following compensation table is from the specification of EPCOS NTC
216
- * Thermistors Datasheet
216
+ * The following compensation tables are from the specifications in EPCOS NTC
217
+ * Thermistors Datasheets
217218 */
218219 static const struct ntc_compensation b57330v2103[] = {
219220 { .temp_c = -40, .ohm = 190030 },
....@@ -252,6 +253,69 @@
252253 { .temp_c = 125, .ohm = 531 },
253254 };
254255
256
+static const struct ntc_compensation b57891s0103[] = {
257
+ { .temp_c = -55.0, .ohm = 878900 },
258
+ { .temp_c = -50.0, .ohm = 617590 },
259
+ { .temp_c = -45.0, .ohm = 439340 },
260
+ { .temp_c = -40.0, .ohm = 316180 },
261
+ { .temp_c = -35.0, .ohm = 230060 },
262
+ { .temp_c = -30.0, .ohm = 169150 },
263
+ { .temp_c = -25.0, .ohm = 125550 },
264
+ { .temp_c = -20.0, .ohm = 94143 },
265
+ { .temp_c = -15.0, .ohm = 71172 },
266
+ { .temp_c = -10.0, .ohm = 54308 },
267
+ { .temp_c = -5.0, .ohm = 41505 },
268
+ { .temp_c = 0.0, .ohm = 32014 },
269
+ { .temp_c = 5.0, .ohm = 25011 },
270
+ { .temp_c = 10.0, .ohm = 19691 },
271
+ { .temp_c = 15.0, .ohm = 15618 },
272
+ { .temp_c = 20.0, .ohm = 12474 },
273
+ { .temp_c = 25.0, .ohm = 10000 },
274
+ { .temp_c = 30.0, .ohm = 8080 },
275
+ { .temp_c = 35.0, .ohm = 6569 },
276
+ { .temp_c = 40.0, .ohm = 5372 },
277
+ { .temp_c = 45.0, .ohm = 4424 },
278
+ { .temp_c = 50.0, .ohm = 3661 },
279
+ { .temp_c = 55.0, .ohm = 3039 },
280
+ { .temp_c = 60.0, .ohm = 2536 },
281
+ { .temp_c = 65.0, .ohm = 2128 },
282
+ { .temp_c = 70.0, .ohm = 1794 },
283
+ { .temp_c = 75.0, .ohm = 1518 },
284
+ { .temp_c = 80.0, .ohm = 1290 },
285
+ { .temp_c = 85.0, .ohm = 1100 },
286
+ { .temp_c = 90.0, .ohm = 942 },
287
+ { .temp_c = 95.0, .ohm = 809 },
288
+ { .temp_c = 100.0, .ohm = 697 },
289
+ { .temp_c = 105.0, .ohm = 604 },
290
+ { .temp_c = 110.0, .ohm = 525 },
291
+ { .temp_c = 115.0, .ohm = 457 },
292
+ { .temp_c = 120.0, .ohm = 400 },
293
+ { .temp_c = 125.0, .ohm = 351 },
294
+ { .temp_c = 130.0, .ohm = 308 },
295
+ { .temp_c = 135.0, .ohm = 272 },
296
+ { .temp_c = 140.0, .ohm = 240 },
297
+ { .temp_c = 145.0, .ohm = 213 },
298
+ { .temp_c = 150.0, .ohm = 189 },
299
+ { .temp_c = 155.0, .ohm = 168 },
300
+};
301
+
302
+struct ntc_type {
303
+ const struct ntc_compensation *comp;
304
+ int n_comp;
305
+};
306
+
307
+#define NTC_TYPE(ntc, compensation) \
308
+[(ntc)] = { .comp = (compensation), .n_comp = ARRAY_SIZE(compensation) }
309
+
310
+static const struct ntc_type ntc_type[] = {
311
+ NTC_TYPE(TYPE_B57330V2103, b57330v2103),
312
+ NTC_TYPE(TYPE_B57891S0103, b57891s0103),
313
+ NTC_TYPE(TYPE_NCPXXWB473, ncpXXwb473),
314
+ NTC_TYPE(TYPE_NCPXXWF104, ncpXXwf104),
315
+ NTC_TYPE(TYPE_NCPXXWL333, ncpXXwl333),
316
+ NTC_TYPE(TYPE_NCPXXXH103, ncpXXxh103),
317
+};
318
+
255319 struct ntc_data {
256320 struct ntc_thermistor_platform_data *pdata;
257321 const struct ntc_compensation *comp;
....@@ -280,34 +344,36 @@
280344 }
281345
282346 static const struct of_device_id ntc_match[] = {
283
- { .compatible = "murata,ncp15wb473",
284
- .data = &ntc_thermistor_id[0] },
285
- { .compatible = "murata,ncp18wb473",
286
- .data = &ntc_thermistor_id[1] },
287
- { .compatible = "murata,ncp21wb473",
288
- .data = &ntc_thermistor_id[2] },
289
- { .compatible = "murata,ncp03wb473",
290
- .data = &ntc_thermistor_id[3] },
291
- { .compatible = "murata,ncp15wl333",
292
- .data = &ntc_thermistor_id[4] },
293347 { .compatible = "epcos,b57330v2103",
294
- .data = &ntc_thermistor_id[5]},
348
+ .data = &ntc_thermistor_id[NTC_B57330V2103]},
349
+ { .compatible = "epcos,b57891s0103",
350
+ .data = &ntc_thermistor_id[NTC_B57891S0103] },
351
+ { .compatible = "murata,ncp03wb473",
352
+ .data = &ntc_thermistor_id[NTC_NCP03WB473] },
295353 { .compatible = "murata,ncp03wf104",
296
- .data = &ntc_thermistor_id[6] },
354
+ .data = &ntc_thermistor_id[NTC_NCP03WF104] },
355
+ { .compatible = "murata,ncp15wb473",
356
+ .data = &ntc_thermistor_id[NTC_NCP15WB473] },
357
+ { .compatible = "murata,ncp15wl333",
358
+ .data = &ntc_thermistor_id[NTC_NCP15WL333] },
297359 { .compatible = "murata,ncp15xh103",
298
- .data = &ntc_thermistor_id[7] },
360
+ .data = &ntc_thermistor_id[NTC_NCP15XH103] },
361
+ { .compatible = "murata,ncp18wb473",
362
+ .data = &ntc_thermistor_id[NTC_NCP18WB473] },
363
+ { .compatible = "murata,ncp21wb473",
364
+ .data = &ntc_thermistor_id[NTC_NCP21WB473] },
299365
300366 /* Usage of vendor name "ntc" is deprecated */
301
- { .compatible = "ntc,ncp15wb473",
302
- .data = &ntc_thermistor_id[0] },
303
- { .compatible = "ntc,ncp18wb473",
304
- .data = &ntc_thermistor_id[1] },
305
- { .compatible = "ntc,ncp21wb473",
306
- .data = &ntc_thermistor_id[2] },
307367 { .compatible = "ntc,ncp03wb473",
308
- .data = &ntc_thermistor_id[3] },
368
+ .data = &ntc_thermistor_id[NTC_NCP03WB473] },
369
+ { .compatible = "ntc,ncp15wb473",
370
+ .data = &ntc_thermistor_id[NTC_NCP15WB473] },
309371 { .compatible = "ntc,ncp15wl333",
310
- .data = &ntc_thermistor_id[4] },
372
+ .data = &ntc_thermistor_id[NTC_NCP15WL333] },
373
+ { .compatible = "ntc,ncp18wb473",
374
+ .data = &ntc_thermistor_id[NTC_NCP18WB473] },
375
+ { .compatible = "ntc,ncp21wb473",
376
+ .data = &ntc_thermistor_id[NTC_NCP21WB473] },
311377 { },
312378 };
313379 MODULE_DEVICE_TABLE(of, ntc_match);
....@@ -506,55 +572,67 @@
506572 return -EINVAL;
507573 }
508574
509
-static int ntc_read_temp(void *data, int *temp)
510
-{
511
- int ohm;
512
-
513
- ohm = ntc_thermistor_get_ohm(data);
514
- if (ohm < 0)
515
- return ohm;
516
-
517
- *temp = get_temp_mc(data, ohm);
518
-
519
- return 0;
520
-}
521
-
522
-static ssize_t ntc_show_type(struct device *dev,
523
- struct device_attribute *attr, char *buf)
524
-{
525
- return sprintf(buf, "4\n");
526
-}
527
-
528
-static ssize_t ntc_show_temp(struct device *dev,
529
- struct device_attribute *attr, char *buf)
575
+static int ntc_read(struct device *dev, enum hwmon_sensor_types type,
576
+ u32 attr, int channel, long *val)
530577 {
531578 struct ntc_data *data = dev_get_drvdata(dev);
532579 int ohm;
533580
534
- ohm = ntc_thermistor_get_ohm(data);
535
- if (ohm < 0)
536
- return ohm;
537
-
538
- return sprintf(buf, "%d\n", get_temp_mc(data, ohm));
581
+ switch (type) {
582
+ case hwmon_temp:
583
+ switch (attr) {
584
+ case hwmon_temp_input:
585
+ ohm = ntc_thermistor_get_ohm(data);
586
+ if (ohm < 0)
587
+ return ohm;
588
+ *val = get_temp_mc(data, ohm);
589
+ return 0;
590
+ case hwmon_temp_type:
591
+ *val = 4;
592
+ return 0;
593
+ default:
594
+ break;
595
+ }
596
+ break;
597
+ default:
598
+ break;
599
+ }
600
+ return -EINVAL;
539601 }
540602
541
-static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0);
542
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ntc_show_temp, NULL, 0);
603
+static umode_t ntc_is_visible(const void *data, enum hwmon_sensor_types type,
604
+ u32 attr, int channel)
605
+{
606
+ if (type == hwmon_temp) {
607
+ switch (attr) {
608
+ case hwmon_temp_input:
609
+ case hwmon_temp_type:
610
+ return 0444;
611
+ default:
612
+ break;
613
+ }
614
+ }
615
+ return 0;
616
+}
543617
544
-static struct attribute *ntc_attrs[] = {
545
- &sensor_dev_attr_temp1_type.dev_attr.attr,
546
- &sensor_dev_attr_temp1_input.dev_attr.attr,
547
- NULL,
618
+static const struct hwmon_channel_info *ntc_info[] = {
619
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
620
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_TYPE),
621
+ NULL
548622 };
549
-ATTRIBUTE_GROUPS(ntc);
550623
551
-static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = {
552
- .get_temp = ntc_read_temp,
624
+static const struct hwmon_ops ntc_hwmon_ops = {
625
+ .is_visible = ntc_is_visible,
626
+ .read = ntc_read,
627
+};
628
+
629
+static const struct hwmon_chip_info ntc_chip_info = {
630
+ .ops = &ntc_hwmon_ops,
631
+ .info = ntc_info,
553632 };
554633
555634 static int ntc_thermistor_probe(struct platform_device *pdev)
556635 {
557
- struct thermal_zone_device *tz;
558636 struct device *dev = &pdev->dev;
559637 const struct of_device_id *of_id =
560638 of_match_device(of_match_ptr(ntc_match), dev);
....@@ -606,35 +684,18 @@
606684
607685 data->pdata = pdata;
608686
609
- switch (pdev_id->driver_data) {
610
- case TYPE_NCPXXWB473:
611
- data->comp = ncpXXwb473;
612
- data->n_comp = ARRAY_SIZE(ncpXXwb473);
613
- break;
614
- case TYPE_NCPXXWL333:
615
- data->comp = ncpXXwl333;
616
- data->n_comp = ARRAY_SIZE(ncpXXwl333);
617
- break;
618
- case TYPE_B57330V2103:
619
- data->comp = b57330v2103;
620
- data->n_comp = ARRAY_SIZE(b57330v2103);
621
- break;
622
- case TYPE_NCPXXWF104:
623
- data->comp = ncpXXwf104;
624
- data->n_comp = ARRAY_SIZE(ncpXXwf104);
625
- break;
626
- case TYPE_NCPXXXH103:
627
- data->comp = ncpXXxh103;
628
- data->n_comp = ARRAY_SIZE(ncpXXxh103);
629
- break;
630
- default:
687
+ if (pdev_id->driver_data >= ARRAY_SIZE(ntc_type)) {
631688 dev_err(dev, "Unknown device type: %lu(%s)\n",
632689 pdev_id->driver_data, pdev_id->name);
633690 return -EINVAL;
634691 }
635692
636
- hwmon_dev = devm_hwmon_device_register_with_groups(dev, pdev_id->name,
637
- data, ntc_groups);
693
+ data->comp = ntc_type[pdev_id->driver_data].comp;
694
+ data->n_comp = ntc_type[pdev_id->driver_data].n_comp;
695
+
696
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev_id->name,
697
+ data, &ntc_chip_info,
698
+ NULL);
638699 if (IS_ERR(hwmon_dev)) {
639700 dev_err(dev, "unable to register as hwmon device.\n");
640701 return PTR_ERR(hwmon_dev);
....@@ -642,11 +703,6 @@
642703
643704 dev_info(dev, "Thermistor type: %s successfully probed.\n",
644705 pdev_id->name);
645
-
646
- tz = devm_thermal_zone_of_sensor_register(dev, 0, data,
647
- &ntc_of_thermal_ops);
648
- if (IS_ERR(tz))
649
- dev_dbg(dev, "Failed to register to thermal fw.\n");
650706
651707 return 0;
652708 }