diff options
author | Florian Eckert <fe@dev.tdt.de> | 2017-09-01 02:58:17 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2017-09-01 10:24:14 -0400 |
commit | 7074d0a92758603369655ef5d4f49e6caaae0b4e (patch) | |
tree | e3435c06490bbfcadd70fa7f23178c38bfbe65a1 /drivers/hwmon | |
parent | 7a3b68b9075cf9b67692bb97497740bab1dfab41 (diff) |
hwmon: (ltq-cputemp) add cpu temp sensor driver
Add the lantiq cpu temperature sensor support for xrx200.
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/ltq-cputemp.c | 163 |
3 files changed, 171 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5b9a61f766ac..d65431417b17 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -791,6 +791,13 @@ config SENSORS_LTC4261 | |||
791 | This driver can also be built as a module. If so, the module will | 791 | This driver can also be built as a module. If so, the module will |
792 | be called ltc4261. | 792 | be called ltc4261. |
793 | 793 | ||
794 | config SENSORS_LTQ_CPUTEMP | ||
795 | bool "Lantiq cpu temperature sensor driver" | ||
796 | depends on LANTIQ | ||
797 | help | ||
798 | If you say yes here you get support for the temperature | ||
799 | sensor inside your CPU. | ||
800 | |||
794 | config SENSORS_MAX1111 | 801 | config SENSORS_MAX1111 |
795 | tristate "Maxim MAX1111 Serial 8-bit ADC chip and compatibles" | 802 | tristate "Maxim MAX1111 Serial 8-bit ADC chip and compatibles" |
796 | depends on SPI_MASTER | 803 | depends on SPI_MASTER |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d4641a9f16c1..c84d9784be98 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -110,6 +110,7 @@ obj-$(CONFIG_SENSORS_LTC4222) += ltc4222.o | |||
110 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o | 110 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o |
111 | obj-$(CONFIG_SENSORS_LTC4260) += ltc4260.o | 111 | obj-$(CONFIG_SENSORS_LTC4260) += ltc4260.o |
112 | obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o | 112 | obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o |
113 | obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o | ||
113 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o | 114 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o |
114 | obj-$(CONFIG_SENSORS_MAX16065) += max16065.o | 115 | obj-$(CONFIG_SENSORS_MAX16065) += max16065.o |
115 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 116 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
diff --git a/drivers/hwmon/ltq-cputemp.c b/drivers/hwmon/ltq-cputemp.c new file mode 100644 index 000000000000..1d33f94594c1 --- /dev/null +++ b/drivers/hwmon/ltq-cputemp.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* Lantiq cpu temperature sensor driver | ||
2 | * | ||
3 | * Copyright (C) 2017 Florian Eckert <fe@dev.tdt.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version | ||
9 | * | ||
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 | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
17 | */ | ||
18 | |||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/hwmon.h> | ||
22 | #include <linux/hwmon-sysfs.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of_device.h> | ||
26 | |||
27 | #include <lantiq_soc.h> | ||
28 | |||
29 | /* gphy1 configuration register contains cpu temperature */ | ||
30 | #define CGU_GPHY1_CR 0x0040 | ||
31 | #define CGU_TEMP_PD BIT(19) | ||
32 | |||
33 | static void ltq_cputemp_enable(void) | ||
34 | { | ||
35 | ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) | CGU_TEMP_PD, CGU_GPHY1_CR); | ||
36 | } | ||
37 | |||
38 | static void ltq_cputemp_disable(void *data) | ||
39 | { | ||
40 | ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) & ~CGU_TEMP_PD, CGU_GPHY1_CR); | ||
41 | } | ||
42 | |||
43 | static int ltq_read(struct device *dev, enum hwmon_sensor_types type, | ||
44 | u32 attr, int channel, long *temp) | ||
45 | { | ||
46 | int value; | ||
47 | |||
48 | switch (attr) { | ||
49 | case hwmon_temp_input: | ||
50 | /* get the temperature including one decimal place */ | ||
51 | value = (ltq_cgu_r32(CGU_GPHY1_CR) >> 9) & 0x01FF; | ||
52 | value = value * 5; | ||
53 | /* range -38 to +154 °C, register value zero is -38.0 °C */ | ||
54 | value -= 380; | ||
55 | /* scale temp to millidegree */ | ||
56 | value = value * 100; | ||
57 | break; | ||
58 | default: | ||
59 | return -EOPNOTSUPP; | ||
60 | } | ||
61 | |||
62 | *temp = value; | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static umode_t ltq_is_visible(const void *_data, enum hwmon_sensor_types type, | ||
67 | u32 attr, int channel) | ||
68 | { | ||
69 | if (type != hwmon_temp) | ||
70 | return 0; | ||
71 | |||
72 | switch (attr) { | ||
73 | case hwmon_temp_input: | ||
74 | return 0444; | ||
75 | default: | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | static const u32 ltq_chip_config[] = { | ||
81 | HWMON_C_REGISTER_TZ, | ||
82 | 0 | ||
83 | }; | ||
84 | |||
85 | static const struct hwmon_channel_info ltq_chip = { | ||
86 | .type = hwmon_chip, | ||
87 | .config = ltq_chip_config, | ||
88 | }; | ||
89 | |||
90 | static const u32 ltq_temp_config[] = { | ||
91 | HWMON_T_INPUT, | ||
92 | 0 | ||
93 | }; | ||
94 | |||
95 | static const struct hwmon_channel_info ltq_temp = { | ||
96 | .type = hwmon_temp, | ||
97 | .config = ltq_temp_config, | ||
98 | }; | ||
99 | |||
100 | static const struct hwmon_channel_info *ltq_info[] = { | ||
101 | <q_chip, | ||
102 | <q_temp, | ||
103 | NULL | ||
104 | }; | ||
105 | |||
106 | static const struct hwmon_ops ltq_hwmon_ops = { | ||
107 | .is_visible = ltq_is_visible, | ||
108 | .read = ltq_read, | ||
109 | }; | ||
110 | |||
111 | static const struct hwmon_chip_info ltq_chip_info = { | ||
112 | .ops = <q_hwmon_ops, | ||
113 | .info = ltq_info, | ||
114 | }; | ||
115 | |||
116 | static int ltq_cputemp_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct device *hwmon_dev; | ||
119 | int err = 0; | ||
120 | |||
121 | /* available on vr9 v1.2 SoCs only */ | ||
122 | if (ltq_soc_type() != SOC_TYPE_VR9_2) | ||
123 | return -ENODEV; | ||
124 | |||
125 | err = devm_add_action(&pdev->dev, ltq_cputemp_disable, NULL); | ||
126 | if (err) | ||
127 | return err; | ||
128 | |||
129 | ltq_cputemp_enable(); | ||
130 | |||
131 | hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, | ||
132 | "ltq_cputemp", | ||
133 | NULL, | ||
134 | <q_chip_info, | ||
135 | NULL); | ||
136 | |||
137 | if (IS_ERR(hwmon_dev)) { | ||
138 | dev_err(&pdev->dev, "Failed to register as hwmon device"); | ||
139 | return PTR_ERR(hwmon_dev); | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | const struct of_device_id ltq_cputemp_match[] = { | ||
146 | { .compatible = "lantiq,cputemp" }, | ||
147 | {}, | ||
148 | }; | ||
149 | MODULE_DEVICE_TABLE(of, ltq_cputemp_match); | ||
150 | |||
151 | static struct platform_driver ltq_cputemp_driver = { | ||
152 | .probe = ltq_cputemp_probe, | ||
153 | .driver = { | ||
154 | .name = "ltq-cputemp", | ||
155 | .of_match_table = ltq_cputemp_match, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | module_platform_driver(ltq_cputemp_driver); | ||
160 | |||
161 | MODULE_AUTHOR("Florian Eckert <fe@dev.tdt.de>"); | ||
162 | MODULE_DESCRIPTION("Lantiq cpu temperature sensor driver"); | ||
163 | MODULE_LICENSE("GPL"); | ||