xref: /linux/drivers/hwmon/kfan.c (revision e78f70bad29c5ae1e1076698b690b15794e9b81e) !
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2025 KEBA Industrial Automation GmbH
4  *
5  * Driver for KEBA fan controller FPGA IP core
6  *
7  */
8 
9 #include <linux/hwmon.h>
10 #include <linux/io.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/auxiliary_bus.h>
14 #include <linux/misc/keba.h>
15 
16 #define KFAN "kfan"
17 
18 #define KFAN_CONTROL_REG	0x04
19 
20 #define KFAN_STATUS_REG		0x08
21 #define   KFAN_STATUS_PRESENT	0x01
22 #define   KFAN_STATUS_REGULABLE	0x02
23 #define   KFAN_STATUS_TACHO	0x04
24 #define   KFAN_STATUS_BLOCKED	0x08
25 
26 #define KFAN_TACHO_REG		0x0c
27 
28 #define KFAN_DEFAULT_DIV	2
29 
30 struct kfan {
31 	void __iomem *base;
32 	bool tacho;
33 	bool regulable;
34 
35 	/* hwmon API configuration */
36 	u32 fan_channel_config[2];
37 	struct hwmon_channel_info fan_info;
38 	u32 pwm_channel_config[2];
39 	struct hwmon_channel_info pwm_info;
40 	const struct hwmon_channel_info *info[3];
41 	struct hwmon_chip_info chip;
42 };
43 
44 static bool kfan_get_fault(struct kfan *kfan)
45 {
46 	u8 status = ioread8(kfan->base + KFAN_STATUS_REG);
47 
48 	if (!(status & KFAN_STATUS_PRESENT))
49 		return true;
50 
51 	if (!kfan->tacho && (status & KFAN_STATUS_BLOCKED))
52 		return true;
53 
54 	return false;
55 }
56 
57 static unsigned int kfan_count_to_rpm(u16 count)
58 {
59 	if (count == 0 || count == 0xffff)
60 		return 0;
61 
62 	return 5000000UL / (KFAN_DEFAULT_DIV * count);
63 }
64 
65 static unsigned int kfan_get_rpm(struct kfan *kfan)
66 {
67 	unsigned int rpm;
68 	u16 count;
69 
70 	count = ioread16(kfan->base + KFAN_TACHO_REG);
71 	rpm = kfan_count_to_rpm(count);
72 
73 	return rpm;
74 }
75 
76 static unsigned int kfan_get_pwm(struct kfan *kfan)
77 {
78 	return ioread8(kfan->base + KFAN_CONTROL_REG);
79 }
80 
81 static int kfan_set_pwm(struct kfan *kfan, long val)
82 {
83 	if (val < 0 || val > 0xff)
84 		return -EINVAL;
85 
86 	/* if none-regulable, then only 0 or 0xff can be written */
87 	if (!kfan->regulable && val > 0)
88 		val = 0xff;
89 
90 	iowrite8(val, kfan->base + KFAN_CONTROL_REG);
91 
92 	return 0;
93 }
94 
95 static int kfan_write(struct device *dev, enum hwmon_sensor_types type,
96 		      u32 attr, int channel, long val)
97 {
98 	struct kfan *kfan = dev_get_drvdata(dev);
99 
100 	switch (type) {
101 	case hwmon_pwm:
102 		switch (attr) {
103 		case hwmon_pwm_input:
104 			return kfan_set_pwm(kfan, val);
105 		default:
106 			break;
107 		}
108 		break;
109 	default:
110 		break;
111 	}
112 
113 	return -EOPNOTSUPP;
114 }
115 
116 static int kfan_read(struct device *dev, enum hwmon_sensor_types type,
117 		     u32 attr, int channel, long *val)
118 {
119 	struct kfan *kfan = dev_get_drvdata(dev);
120 
121 	switch (type) {
122 	case hwmon_fan:
123 		switch (attr) {
124 		case hwmon_fan_fault:
125 			*val = kfan_get_fault(kfan);
126 			return 0;
127 		case hwmon_fan_input:
128 			*val = kfan_get_rpm(kfan);
129 			return 0;
130 		default:
131 			break;
132 		}
133 		break;
134 	case hwmon_pwm:
135 		switch (attr) {
136 		case hwmon_pwm_input:
137 			*val = kfan_get_pwm(kfan);
138 			return 0;
139 		default:
140 			break;
141 		}
142 		break;
143 	default:
144 		break;
145 	}
146 
147 	return -EOPNOTSUPP;
148 }
149 
150 static umode_t kfan_is_visible(const void *data, enum hwmon_sensor_types type,
151 			       u32 attr, int channel)
152 {
153 	switch (type) {
154 	case hwmon_fan:
155 		switch (attr) {
156 		case hwmon_fan_input:
157 			return 0444;
158 		case hwmon_fan_fault:
159 			return 0444;
160 		default:
161 			break;
162 		}
163 		break;
164 	case hwmon_pwm:
165 		switch (attr) {
166 		case hwmon_pwm_input:
167 			return 0644;
168 		default:
169 			break;
170 		}
171 		break;
172 	default:
173 		break;
174 	}
175 
176 	return 0;
177 }
178 
179 static const struct hwmon_ops kfan_hwmon_ops = {
180 	.is_visible = kfan_is_visible,
181 	.read = kfan_read,
182 	.write = kfan_write,
183 };
184 
185 static int kfan_probe(struct auxiliary_device *auxdev,
186 		      const struct auxiliary_device_id *id)
187 {
188 	struct keba_fan_auxdev *kfan_auxdev =
189 		container_of(auxdev, struct keba_fan_auxdev, auxdev);
190 	struct device *dev = &auxdev->dev;
191 	struct device *hwmon_dev;
192 	struct kfan *kfan;
193 	u8 status;
194 
195 	kfan = devm_kzalloc(dev, sizeof(*kfan), GFP_KERNEL);
196 	if (!kfan)
197 		return -ENOMEM;
198 
199 	kfan->base = devm_ioremap_resource(dev, &kfan_auxdev->io);
200 	if (IS_ERR(kfan->base))
201 		return PTR_ERR(kfan->base);
202 
203 	status = ioread8(kfan->base + KFAN_STATUS_REG);
204 	if (status & KFAN_STATUS_REGULABLE)
205 		kfan->regulable = true;
206 	if (status & KFAN_STATUS_TACHO)
207 		kfan->tacho = true;
208 
209 	/* fan */
210 	kfan->fan_channel_config[0] = HWMON_F_FAULT;
211 	if (kfan->tacho)
212 		kfan->fan_channel_config[0] |= HWMON_F_INPUT;
213 	kfan->fan_info.type = hwmon_fan;
214 	kfan->fan_info.config = kfan->fan_channel_config;
215 	kfan->info[0] = &kfan->fan_info;
216 
217 	/* PWM */
218 	kfan->pwm_channel_config[0] = HWMON_PWM_INPUT;
219 	kfan->pwm_info.type = hwmon_pwm;
220 	kfan->pwm_info.config = kfan->pwm_channel_config;
221 	kfan->info[1] = &kfan->pwm_info;
222 
223 	kfan->chip.ops = &kfan_hwmon_ops;
224 	kfan->chip.info = kfan->info;
225 	hwmon_dev = devm_hwmon_device_register_with_info(dev, KFAN, kfan,
226 							 &kfan->chip, NULL);
227 	return PTR_ERR_OR_ZERO(hwmon_dev);
228 }
229 
230 static const struct auxiliary_device_id kfan_devtype_aux[] = {
231 	{ .name = "keba.fan" },
232 	{}
233 };
234 MODULE_DEVICE_TABLE(auxiliary, kfan_devtype_aux);
235 
236 static struct auxiliary_driver kfan_driver_aux = {
237 	.name = KFAN,
238 	.id_table = kfan_devtype_aux,
239 	.probe = kfan_probe,
240 };
241 module_auxiliary_driver(kfan_driver_aux);
242 
243 MODULE_AUTHOR("Petar Bojanic <boja@keba.com>");
244 MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>");
245 MODULE_DESCRIPTION("KEBA fan controller driver");
246 MODULE_LICENSE("GPL");
247