xref: /openbmc/linux/drivers/hwmon/lan966x-hwmon.c (revision 7fc96d71)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include <linux/bitfield.h>
4 #include <linux/clk.h>
5 #include <linux/hwmon.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/platform_device.h>
10 #include <linux/polynomial.h>
11 #include <linux/regmap.h>
12 
13 /*
14  * The original translation formulae of the temperature (in degrees of Celsius)
15  * are as follows:
16  *
17  *   T = -3.4627e-11*(N^4) + 1.1023e-7*(N^3) + -1.9165e-4*(N^2) +
18  *       3.0604e-1*(N^1) + -5.6197e1
19  *
20  * where [-56.197, 136.402]C and N = [0, 1023].
21  *
22  * They must be accordingly altered to be suitable for the integer arithmetics.
23  * The technique is called 'factor redistribution', which just makes sure the
24  * multiplications and divisions are made so to have a result of the operations
25  * within the integer numbers limit. In addition we need to translate the
26  * formulae to accept millidegrees of Celsius. Here what it looks like after
27  * the alterations:
28  *
29  *   T = -34627e-12*(N^4) + 110230e-9*(N^3) + -191650e-6*(N^2) +
30  *       306040e-3*(N^1) + -56197
31  *
32  * where T = [-56197, 136402]mC and N = [0, 1023].
33  */
34 
35 static const struct polynomial poly_N_to_temp = {
36 	.terms = {
37 		{4,  -34627, 1000, 1},
38 		{3,  110230, 1000, 1},
39 		{2, -191650, 1000, 1},
40 		{1,  306040, 1000, 1},
41 		{0,  -56197,    1, 1}
42 	}
43 };
44 
45 #define PVT_SENSOR_CTRL		0x0 /* unused */
46 #define PVT_SENSOR_CFG		0x4
47 #define   SENSOR_CFG_CLK_CFG		GENMASK(27, 20)
48 #define   SENSOR_CFG_TRIM_VAL		GENMASK(13, 9)
49 #define   SENSOR_CFG_SAMPLE_ENA		BIT(8)
50 #define   SENSOR_CFG_START_CAPTURE	BIT(7)
51 #define   SENSOR_CFG_CONTINIOUS_MODE	BIT(6)
52 #define   SENSOR_CFG_PSAMPLE_ENA	GENMASK(1, 0)
53 #define PVT_SENSOR_STAT		0x8
54 #define   SENSOR_STAT_DATA_VALID	BIT(10)
55 #define   SENSOR_STAT_DATA		GENMASK(9, 0)
56 
57 #define FAN_CFG			0x0
58 #define   FAN_CFG_DUTY_CYCLE		GENMASK(23, 16)
59 #define   INV_POL			BIT(3)
60 #define   GATE_ENA			BIT(2)
61 #define   PWM_OPEN_COL_ENA		BIT(1)
62 #define   FAN_STAT_CFG			BIT(0)
63 #define FAN_PWM_FREQ		0x4
64 #define   FAN_PWM_CYC_10US		GENMASK(25, 15)
65 #define   FAN_PWM_FREQ_FREQ		GENMASK(14, 0)
66 #define FAN_CNT			0xc
67 #define   FAN_CNT_DATA			GENMASK(15, 0)
68 
69 #define LAN966X_PVT_CLK		1200000 /* 1.2 MHz */
70 
71 struct lan966x_hwmon {
72 	struct regmap *regmap_pvt;
73 	struct regmap *regmap_fan;
74 	struct clk *clk;
75 	unsigned long clk_rate;
76 };
77 
78 static int lan966x_hwmon_read_temp(struct device *dev, long *val)
79 {
80 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
81 	unsigned int data;
82 	int ret;
83 
84 	ret = regmap_read(hwmon->regmap_pvt, PVT_SENSOR_STAT, &data);
85 	if (ret < 0)
86 		return ret;
87 
88 	if (!(data & SENSOR_STAT_DATA_VALID))
89 		return -ENODATA;
90 
91 	*val = polynomial_calc(&poly_N_to_temp,
92 			       FIELD_GET(SENSOR_STAT_DATA, data));
93 
94 	return 0;
95 }
96 
97 static int lan966x_hwmon_read_fan(struct device *dev, long *val)
98 {
99 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
100 	unsigned int data;
101 	int ret;
102 
103 	ret = regmap_read(hwmon->regmap_fan, FAN_CNT, &data);
104 	if (ret < 0)
105 		return ret;
106 
107 	/*
108 	 * Data is given in pulses per second. Assume two pulses
109 	 * per revolution.
110 	 */
111 	*val = FIELD_GET(FAN_CNT_DATA, data) * 60 / 2;
112 
113 	return 0;
114 }
115 
116 static int lan966x_hwmon_read_pwm(struct device *dev, long *val)
117 {
118 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
119 	unsigned int data;
120 	int ret;
121 
122 	ret = regmap_read(hwmon->regmap_fan, FAN_CFG, &data);
123 	if (ret < 0)
124 		return ret;
125 
126 	*val = FIELD_GET(FAN_CFG_DUTY_CYCLE, data);
127 
128 	return 0;
129 }
130 
131 static int lan966x_hwmon_read_pwm_freq(struct device *dev, long *val)
132 {
133 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
134 	unsigned long tmp;
135 	unsigned int data;
136 	int ret;
137 
138 	ret = regmap_read(hwmon->regmap_fan, FAN_PWM_FREQ, &data);
139 	if (ret < 0)
140 		return ret;
141 
142 	/*
143 	 * Datasheet says it is sys_clk / 256 / pwm_freq. But in reality
144 	 * it is sys_clk / 256 / (pwm_freq + 1).
145 	 */
146 	data = FIELD_GET(FAN_PWM_FREQ_FREQ, data) + 1;
147 	tmp = DIV_ROUND_CLOSEST(hwmon->clk_rate, 256);
148 	*val = DIV_ROUND_CLOSEST(tmp, data);
149 
150 	return 0;
151 }
152 
153 static int lan966x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
154 			      u32 attr, int channel, long *val)
155 {
156 	switch (type) {
157 	case hwmon_temp:
158 		return lan966x_hwmon_read_temp(dev, val);
159 	case hwmon_fan:
160 		return lan966x_hwmon_read_fan(dev, val);
161 	case hwmon_pwm:
162 		switch (attr) {
163 		case hwmon_pwm_input:
164 			return lan966x_hwmon_read_pwm(dev, val);
165 		case hwmon_pwm_freq:
166 			return lan966x_hwmon_read_pwm_freq(dev, val);
167 		default:
168 			return -EOPNOTSUPP;
169 		}
170 	default:
171 		return -EOPNOTSUPP;
172 	}
173 }
174 
175 static int lan966x_hwmon_write_pwm(struct device *dev, long val)
176 {
177 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
178 
179 	if (val < 0 || val > 255)
180 		return -EINVAL;
181 
182 	return regmap_update_bits(hwmon->regmap_fan, FAN_CFG,
183 				  FAN_CFG_DUTY_CYCLE,
184 				  FIELD_PREP(FAN_CFG_DUTY_CYCLE, val));
185 }
186 
187 static int lan966x_hwmon_write_pwm_freq(struct device *dev, long val)
188 {
189 	struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
190 
191 	if (val <= 0)
192 		return -EINVAL;
193 
194 	val = DIV_ROUND_CLOSEST(hwmon->clk_rate, val);
195 	val = DIV_ROUND_CLOSEST(val, 256) - 1;
196 	val = clamp_val(val, 0, FAN_PWM_FREQ_FREQ);
197 
198 	return regmap_update_bits(hwmon->regmap_fan, FAN_PWM_FREQ,
199 				  FAN_PWM_FREQ_FREQ,
200 				  FIELD_PREP(FAN_PWM_FREQ_FREQ, val));
201 }
202 
203 static int lan966x_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
204 			       u32 attr, int channel, long val)
205 {
206 	switch (type) {
207 	case hwmon_pwm:
208 		switch (attr) {
209 		case hwmon_pwm_input:
210 			return lan966x_hwmon_write_pwm(dev, val);
211 		case hwmon_pwm_freq:
212 			return lan966x_hwmon_write_pwm_freq(dev, val);
213 		default:
214 			return -EOPNOTSUPP;
215 		}
216 	default:
217 		return -EOPNOTSUPP;
218 	}
219 }
220 
221 static umode_t lan966x_hwmon_is_visible(const void *data,
222 					enum hwmon_sensor_types type,
223 					u32 attr, int channel)
224 {
225 	umode_t mode = 0;
226 
227 	switch (type) {
228 	case hwmon_temp:
229 		switch (attr) {
230 		case hwmon_temp_input:
231 			mode = 0444;
232 			break;
233 		default:
234 			break;
235 		}
236 		break;
237 	case hwmon_fan:
238 		switch (attr) {
239 		case hwmon_fan_input:
240 			mode = 0444;
241 			break;
242 		default:
243 			break;
244 		}
245 		break;
246 	case hwmon_pwm:
247 		switch (attr) {
248 		case hwmon_pwm_input:
249 		case hwmon_pwm_freq:
250 			mode = 0644;
251 			break;
252 		default:
253 			break;
254 		}
255 		break;
256 	default:
257 		break;
258 	}
259 
260 	return mode;
261 }
262 
263 static const struct hwmon_channel_info *lan966x_hwmon_info[] = {
264 	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
265 	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
266 	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT),
267 	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_FREQ),
268 	NULL
269 };
270 
271 static const struct hwmon_ops lan966x_hwmon_ops = {
272 	.is_visible = lan966x_hwmon_is_visible,
273 	.read = lan966x_hwmon_read,
274 	.write = lan966x_hwmon_write,
275 };
276 
277 static const struct hwmon_chip_info lan966x_hwmon_chip_info = {
278 	.ops = &lan966x_hwmon_ops,
279 	.info = lan966x_hwmon_info,
280 };
281 
282 static void lan966x_hwmon_disable(void *data)
283 {
284 	struct lan966x_hwmon *hwmon = data;
285 
286 	regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG,
287 			   SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE,
288 			   0);
289 }
290 
291 static int lan966x_hwmon_enable(struct device *dev,
292 				struct lan966x_hwmon *hwmon)
293 {
294 	unsigned int mask = SENSOR_CFG_CLK_CFG |
295 			    SENSOR_CFG_SAMPLE_ENA |
296 			    SENSOR_CFG_START_CAPTURE |
297 			    SENSOR_CFG_CONTINIOUS_MODE |
298 			    SENSOR_CFG_PSAMPLE_ENA;
299 	unsigned int val;
300 	unsigned int div;
301 	int ret;
302 
303 	/* enable continuous mode */
304 	val = SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE;
305 
306 	/* set PVT clock to be between 1.15 and 1.25 MHz */
307 	div = DIV_ROUND_CLOSEST(hwmon->clk_rate, LAN966X_PVT_CLK);
308 	val |= FIELD_PREP(SENSOR_CFG_CLK_CFG, div);
309 
310 	ret = regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG,
311 				 mask, val);
312 	if (ret)
313 		return ret;
314 
315 	return devm_add_action_or_reset(dev, lan966x_hwmon_disable, hwmon);
316 }
317 
318 static struct regmap *lan966x_init_regmap(struct platform_device *pdev,
319 					  const char *name)
320 {
321 	struct regmap_config regmap_config = {
322 		.reg_bits = 32,
323 		.reg_stride = 4,
324 		.val_bits = 32,
325 	};
326 	void __iomem *base;
327 
328 	base = devm_platform_ioremap_resource_byname(pdev, name);
329 	if (IS_ERR(base))
330 		return ERR_CAST(base);
331 
332 	regmap_config.name = name;
333 
334 	return devm_regmap_init_mmio(&pdev->dev, base, &regmap_config);
335 }
336 
337 static void lan966x_clk_disable(void *data)
338 {
339 	struct lan966x_hwmon *hwmon = data;
340 
341 	clk_disable_unprepare(hwmon->clk);
342 }
343 
344 static int lan966x_clk_enable(struct device *dev, struct lan966x_hwmon *hwmon)
345 {
346 	int ret;
347 
348 	ret = clk_prepare_enable(hwmon->clk);
349 	if (ret)
350 		return ret;
351 
352 	return devm_add_action_or_reset(dev, lan966x_clk_disable, hwmon);
353 }
354 
355 static int lan966x_hwmon_probe(struct platform_device *pdev)
356 {
357 	struct device *dev = &pdev->dev;
358 	struct lan966x_hwmon *hwmon;
359 	struct device *hwmon_dev;
360 	int ret;
361 
362 	hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
363 	if (!hwmon)
364 		return -ENOMEM;
365 
366 	hwmon->clk = devm_clk_get(dev, NULL);
367 	if (IS_ERR(hwmon->clk))
368 		return dev_err_probe(dev, PTR_ERR(hwmon->clk),
369 				     "failed to get clock\n");
370 
371 	ret = lan966x_clk_enable(dev, hwmon);
372 	if (ret)
373 		return dev_err_probe(dev, ret, "failed to enable clock\n");
374 
375 	hwmon->clk_rate = clk_get_rate(hwmon->clk);
376 
377 	hwmon->regmap_pvt = lan966x_init_regmap(pdev, "pvt");
378 	if (IS_ERR(hwmon->regmap_pvt))
379 		return dev_err_probe(dev, PTR_ERR(hwmon->regmap_pvt),
380 				     "failed to get regmap for PVT registers\n");
381 
382 	hwmon->regmap_fan = lan966x_init_regmap(pdev, "fan");
383 	if (IS_ERR(hwmon->regmap_fan))
384 		return dev_err_probe(dev, PTR_ERR(hwmon->regmap_fan),
385 				     "failed to get regmap for fan registers\n");
386 
387 	ret = lan966x_hwmon_enable(dev, hwmon);
388 	if (ret)
389 		return dev_err_probe(dev, ret, "failed to enable sensor\n");
390 
391 	hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
392 				"lan966x_hwmon", hwmon,
393 				&lan966x_hwmon_chip_info, NULL);
394 	if (IS_ERR(hwmon_dev))
395 		return dev_err_probe(dev, PTR_ERR(hwmon_dev),
396 				     "failed to register hwmon device\n");
397 
398 	return 0;
399 }
400 
401 static const struct of_device_id lan966x_hwmon_of_match[] = {
402 	{ .compatible = "microchip,lan9668-hwmon" },
403 	{}
404 };
405 MODULE_DEVICE_TABLE(of, lan966x_hwmon_of_match);
406 
407 static struct platform_driver lan966x_hwmon_driver = {
408 	.probe = lan966x_hwmon_probe,
409 	.driver = {
410 		.name = "lan966x-hwmon",
411 		.of_match_table = lan966x_hwmon_of_match,
412 	},
413 };
414 module_platform_driver(lan966x_hwmon_driver);
415 
416 MODULE_DESCRIPTION("LAN966x Hardware Monitoring Driver");
417 MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
418 MODULE_LICENSE("GPL");
419