xref: /linux/drivers/hwmon/nct7904.c (revision 3bdab16c55f57a24245c97d707241dd9b48d1a91)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * nct7904.c - driver for Nuvoton NCT7904D.
4  *
5  * Copyright (c) 2015 Kontron
6  * Author: Vadim V. Vlasov <vvlasov@dev.rtsoft.ru>
7  */
8 
9 #include <linux/module.h>
10 #include <linux/device.h>
11 #include <linux/init.h>
12 #include <linux/i2c.h>
13 #include <linux/mutex.h>
14 #include <linux/hwmon.h>
15 
16 #define VENDOR_ID_REG		0x7A	/* Any bank */
17 #define NUVOTON_ID		0x50
18 #define CHIP_ID_REG		0x7B	/* Any bank */
19 #define NCT7904_ID		0xC5
20 #define DEVICE_ID_REG		0x7C	/* Any bank */
21 
22 #define BANK_SEL_REG		0xFF
23 #define BANK_0			0x00
24 #define BANK_1			0x01
25 #define BANK_2			0x02
26 #define BANK_3			0x03
27 #define BANK_4			0x04
28 #define BANK_MAX		0x04
29 
30 #define FANIN_MAX		12	/* Counted from 1 */
31 #define VSEN_MAX		21	/* VSEN1..14, 3VDD, VBAT, V3VSB,
32 					   LTD (not a voltage), VSEN17..19 */
33 #define FANCTL_MAX		4	/* Counted from 1 */
34 #define TCPU_MAX		8	/* Counted from 1 */
35 #define TEMP_MAX		4	/* Counted from 1 */
36 
37 #define VT_ADC_CTRL0_REG	0x20	/* Bank 0 */
38 #define VT_ADC_CTRL1_REG	0x21	/* Bank 0 */
39 #define VT_ADC_CTRL2_REG	0x22	/* Bank 0 */
40 #define FANIN_CTRL0_REG		0x24
41 #define FANIN_CTRL1_REG		0x25
42 #define DTS_T_CTRL0_REG		0x26
43 #define DTS_T_CTRL1_REG		0x27
44 #define VT_ADC_MD_REG		0x2E
45 
46 #define VSEN1_HV_REG		0x40	/* Bank 0; 2 regs (HV/LV) per sensor */
47 #define TEMP_CH1_HV_REG		0x42	/* Bank 0; same as VSEN2_HV */
48 #define LTD_HV_REG		0x62	/* Bank 0; 2 regs in VSEN range */
49 #define FANIN1_HV_REG		0x80	/* Bank 0; 2 regs (HV/LV) per sensor */
50 #define T_CPU1_HV_REG		0xA0	/* Bank 0; 2 regs (HV/LV) per sensor */
51 
52 #define PRTS_REG		0x03	/* Bank 2 */
53 #define FANCTL1_FMR_REG		0x00	/* Bank 3; 1 reg per channel */
54 #define FANCTL1_OUT_REG		0x10	/* Bank 3; 1 reg per channel */
55 
56 static const unsigned short normal_i2c[] = {
57 	0x2d, 0x2e, I2C_CLIENT_END
58 };
59 
60 struct nct7904_data {
61 	struct i2c_client *client;
62 	struct mutex bank_lock;
63 	int bank_sel;
64 	u32 fanin_mask;
65 	u32 vsen_mask;
66 	u32 tcpu_mask;
67 	u8 fan_mode[FANCTL_MAX];
68 };
69 
70 /* Access functions */
71 static int nct7904_bank_lock(struct nct7904_data *data, unsigned int bank)
72 {
73 	int ret;
74 
75 	mutex_lock(&data->bank_lock);
76 	if (data->bank_sel == bank)
77 		return 0;
78 	ret = i2c_smbus_write_byte_data(data->client, BANK_SEL_REG, bank);
79 	if (ret == 0)
80 		data->bank_sel = bank;
81 	else
82 		data->bank_sel = -1;
83 	return ret;
84 }
85 
86 static inline void nct7904_bank_release(struct nct7904_data *data)
87 {
88 	mutex_unlock(&data->bank_lock);
89 }
90 
91 /* Read 1-byte register. Returns unsigned reg or -ERRNO on error. */
92 static int nct7904_read_reg(struct nct7904_data *data,
93 			    unsigned int bank, unsigned int reg)
94 {
95 	struct i2c_client *client = data->client;
96 	int ret;
97 
98 	ret = nct7904_bank_lock(data, bank);
99 	if (ret == 0)
100 		ret = i2c_smbus_read_byte_data(client, reg);
101 
102 	nct7904_bank_release(data);
103 	return ret;
104 }
105 
106 /*
107  * Read 2-byte register. Returns register in big-endian format or
108  * -ERRNO on error.
109  */
110 static int nct7904_read_reg16(struct nct7904_data *data,
111 			      unsigned int bank, unsigned int reg)
112 {
113 	struct i2c_client *client = data->client;
114 	int ret, hi;
115 
116 	ret = nct7904_bank_lock(data, bank);
117 	if (ret == 0) {
118 		ret = i2c_smbus_read_byte_data(client, reg);
119 		if (ret >= 0) {
120 			hi = ret;
121 			ret = i2c_smbus_read_byte_data(client, reg + 1);
122 			if (ret >= 0)
123 				ret |= hi << 8;
124 		}
125 	}
126 
127 	nct7904_bank_release(data);
128 	return ret;
129 }
130 
131 /* Write 1-byte register. Returns 0 or -ERRNO on error. */
132 static int nct7904_write_reg(struct nct7904_data *data,
133 			     unsigned int bank, unsigned int reg, u8 val)
134 {
135 	struct i2c_client *client = data->client;
136 	int ret;
137 
138 	ret = nct7904_bank_lock(data, bank);
139 	if (ret == 0)
140 		ret = i2c_smbus_write_byte_data(client, reg, val);
141 
142 	nct7904_bank_release(data);
143 	return ret;
144 }
145 
146 static int nct7904_read_fan(struct device *dev, u32 attr, int channel,
147 			    long *val)
148 {
149 	struct nct7904_data *data = dev_get_drvdata(dev);
150 	unsigned int cnt, rpm;
151 	int ret;
152 
153 	switch (attr) {
154 	case hwmon_fan_input:
155 		ret = nct7904_read_reg16(data, BANK_0,
156 					 FANIN1_HV_REG + channel * 2);
157 		if (ret < 0)
158 			return ret;
159 		cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
160 		if (cnt == 0x1fff)
161 			rpm = 0;
162 		else
163 			rpm = 1350000 / cnt;
164 		*val = rpm;
165 		return 0;
166 	default:
167 		return -EOPNOTSUPP;
168 	}
169 }
170 
171 static umode_t nct7904_fan_is_visible(const void *_data, u32 attr, int channel)
172 {
173 	const struct nct7904_data *data = _data;
174 
175 	if (attr == hwmon_fan_input && data->fanin_mask & (1 << channel))
176 		return 0444;
177 	return 0;
178 }
179 
180 static u8 nct7904_chan_to_index[] = {
181 	0,	/* Not used */
182 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
183 	18, 19, 20, 16
184 };
185 
186 static int nct7904_read_in(struct device *dev, u32 attr, int channel,
187 			   long *val)
188 {
189 	struct nct7904_data *data = dev_get_drvdata(dev);
190 	int ret, volt, index;
191 
192 	index = nct7904_chan_to_index[channel];
193 
194 	switch (attr) {
195 	case hwmon_in_input:
196 		ret = nct7904_read_reg16(data, BANK_0,
197 					 VSEN1_HV_REG + index * 2);
198 		if (ret < 0)
199 			return ret;
200 		volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
201 		if (index < 14)
202 			volt *= 2; /* 0.002V scale */
203 		else
204 			volt *= 6; /* 0.006V scale */
205 		*val = volt;
206 		return 0;
207 	default:
208 		return -EOPNOTSUPP;
209 	}
210 }
211 
212 static umode_t nct7904_in_is_visible(const void *_data, u32 attr, int channel)
213 {
214 	const struct nct7904_data *data = _data;
215 	int index = nct7904_chan_to_index[channel];
216 
217 	if (channel > 0 && attr == hwmon_in_input &&
218 	    (data->vsen_mask & BIT(index)))
219 		return 0444;
220 
221 	return 0;
222 }
223 
224 static int nct7904_read_temp(struct device *dev, u32 attr, int channel,
225 			     long *val)
226 {
227 	struct nct7904_data *data = dev_get_drvdata(dev);
228 	int ret, temp;
229 
230 	switch (attr) {
231 	case hwmon_temp_input:
232 		if (channel == 0)
233 			ret = nct7904_read_reg16(data, BANK_0, LTD_HV_REG);
234 		else
235 			ret = nct7904_read_reg16(data, BANK_0,
236 					T_CPU1_HV_REG + (channel - 1) * 2);
237 		if (ret < 0)
238 			return ret;
239 		temp = ((ret & 0xff00) >> 5) | (ret & 0x7);
240 		*val = sign_extend32(temp, 10) * 125;
241 		return 0;
242 	default:
243 		return -EOPNOTSUPP;
244 	}
245 }
246 
247 static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel)
248 {
249 	const struct nct7904_data *data = _data;
250 
251 	if (attr == hwmon_temp_input) {
252 		if (channel == 0) {
253 			if (data->vsen_mask & BIT(17))
254 				return 0444;
255 		} else {
256 			if (data->tcpu_mask & BIT(channel - 1))
257 				return 0444;
258 		}
259 	}
260 
261 	return 0;
262 }
263 
264 static int nct7904_read_pwm(struct device *dev, u32 attr, int channel,
265 			    long *val)
266 {
267 	struct nct7904_data *data = dev_get_drvdata(dev);
268 	int ret;
269 
270 	switch (attr) {
271 	case hwmon_pwm_input:
272 		ret = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + channel);
273 		if (ret < 0)
274 			return ret;
275 		*val = ret;
276 		return 0;
277 	case hwmon_pwm_enable:
278 		ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + channel);
279 		if (ret < 0)
280 			return ret;
281 
282 		*val = ret ? 2 : 1;
283 		return 0;
284 	default:
285 		return -EOPNOTSUPP;
286 	}
287 }
288 
289 static int nct7904_write_pwm(struct device *dev, u32 attr, int channel,
290 			     long val)
291 {
292 	struct nct7904_data *data = dev_get_drvdata(dev);
293 	int ret;
294 
295 	switch (attr) {
296 	case hwmon_pwm_input:
297 		if (val < 0 || val > 255)
298 			return -EINVAL;
299 		ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + channel,
300 					val);
301 		return ret;
302 	case hwmon_pwm_enable:
303 		if (val < 1 || val > 2 ||
304 		    (val == 2 && !data->fan_mode[channel]))
305 			return -EINVAL;
306 		ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + channel,
307 					val == 2 ? data->fan_mode[channel] : 0);
308 		return ret;
309 	default:
310 		return -EOPNOTSUPP;
311 	}
312 }
313 
314 static umode_t nct7904_pwm_is_visible(const void *_data, u32 attr, int channel)
315 {
316 	switch (attr) {
317 	case hwmon_pwm_input:
318 	case hwmon_pwm_enable:
319 		return 0644;
320 	default:
321 		return 0;
322 	}
323 }
324 
325 static int nct7904_read(struct device *dev, enum hwmon_sensor_types type,
326 			u32 attr, int channel, long *val)
327 {
328 	switch (type) {
329 	case hwmon_in:
330 		return nct7904_read_in(dev, attr, channel, val);
331 	case hwmon_fan:
332 		return nct7904_read_fan(dev, attr, channel, val);
333 	case hwmon_pwm:
334 		return nct7904_read_pwm(dev, attr, channel, val);
335 	case hwmon_temp:
336 		return nct7904_read_temp(dev, attr, channel, val);
337 	default:
338 		return -EOPNOTSUPP;
339 	}
340 }
341 
342 static int nct7904_write(struct device *dev, enum hwmon_sensor_types type,
343 			 u32 attr, int channel, long val)
344 {
345 	switch (type) {
346 	case hwmon_pwm:
347 		return nct7904_write_pwm(dev, attr, channel, val);
348 	default:
349 		return -EOPNOTSUPP;
350 	}
351 }
352 
353 static umode_t nct7904_is_visible(const void *data,
354 				  enum hwmon_sensor_types type,
355 				  u32 attr, int channel)
356 {
357 	switch (type) {
358 	case hwmon_in:
359 		return nct7904_in_is_visible(data, attr, channel);
360 	case hwmon_fan:
361 		return nct7904_fan_is_visible(data, attr, channel);
362 	case hwmon_pwm:
363 		return nct7904_pwm_is_visible(data, attr, channel);
364 	case hwmon_temp:
365 		return nct7904_temp_is_visible(data, attr, channel);
366 	default:
367 		return 0;
368 	}
369 }
370 
371 /* Return 0 if detection is successful, -ENODEV otherwise */
372 static int nct7904_detect(struct i2c_client *client,
373 			  struct i2c_board_info *info)
374 {
375 	struct i2c_adapter *adapter = client->adapter;
376 
377 	if (!i2c_check_functionality(adapter,
378 				     I2C_FUNC_SMBUS_READ_BYTE |
379 				     I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
380 		return -ENODEV;
381 
382 	/* Determine the chip type. */
383 	if (i2c_smbus_read_byte_data(client, VENDOR_ID_REG) != NUVOTON_ID ||
384 	    i2c_smbus_read_byte_data(client, CHIP_ID_REG) != NCT7904_ID ||
385 	    (i2c_smbus_read_byte_data(client, DEVICE_ID_REG) & 0xf0) != 0x50 ||
386 	    (i2c_smbus_read_byte_data(client, BANK_SEL_REG) & 0xf8) != 0x00)
387 		return -ENODEV;
388 
389 	strlcpy(info->type, "nct7904", I2C_NAME_SIZE);
390 
391 	return 0;
392 }
393 
394 static const struct hwmon_channel_info *nct7904_info[] = {
395 	HWMON_CHANNEL_INFO(in,
396 			   HWMON_I_INPUT, /* dummy, skipped in is_visible */
397 			   HWMON_I_INPUT,
398 			   HWMON_I_INPUT,
399 			   HWMON_I_INPUT,
400 			   HWMON_I_INPUT,
401 			   HWMON_I_INPUT,
402 			   HWMON_I_INPUT,
403 			   HWMON_I_INPUT,
404 			   HWMON_I_INPUT,
405 			   HWMON_I_INPUT,
406 			   HWMON_I_INPUT,
407 			   HWMON_I_INPUT,
408 			   HWMON_I_INPUT,
409 			   HWMON_I_INPUT,
410 			   HWMON_I_INPUT,
411 			   HWMON_I_INPUT,
412 			   HWMON_I_INPUT,
413 			   HWMON_I_INPUT,
414 			   HWMON_I_INPUT,
415 			   HWMON_I_INPUT,
416 			   HWMON_I_INPUT),
417 	HWMON_CHANNEL_INFO(fan,
418 			   HWMON_F_INPUT,
419 			   HWMON_F_INPUT,
420 			   HWMON_F_INPUT,
421 			   HWMON_F_INPUT,
422 			   HWMON_F_INPUT,
423 			   HWMON_F_INPUT,
424 			   HWMON_F_INPUT,
425 			   HWMON_F_INPUT),
426 	HWMON_CHANNEL_INFO(pwm,
427 			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
428 			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
429 			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
430 			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
431 	HWMON_CHANNEL_INFO(temp,
432 			   HWMON_T_INPUT,
433 			   HWMON_T_INPUT,
434 			   HWMON_T_INPUT,
435 			   HWMON_T_INPUT,
436 			   HWMON_T_INPUT,
437 			   HWMON_T_INPUT,
438 			   HWMON_T_INPUT,
439 			   HWMON_T_INPUT,
440 			   HWMON_T_INPUT),
441 	NULL
442 };
443 
444 static const struct hwmon_ops nct7904_hwmon_ops = {
445 	.is_visible = nct7904_is_visible,
446 	.read = nct7904_read,
447 	.write = nct7904_write,
448 };
449 
450 static const struct hwmon_chip_info nct7904_chip_info = {
451 	.ops = &nct7904_hwmon_ops,
452 	.info = nct7904_info,
453 };
454 
455 static int nct7904_probe(struct i2c_client *client,
456 			 const struct i2c_device_id *id)
457 {
458 	struct nct7904_data *data;
459 	struct device *hwmon_dev;
460 	struct device *dev = &client->dev;
461 	int ret, i;
462 	u32 mask;
463 
464 	data = devm_kzalloc(dev, sizeof(struct nct7904_data), GFP_KERNEL);
465 	if (!data)
466 		return -ENOMEM;
467 
468 	data->client = client;
469 	mutex_init(&data->bank_lock);
470 	data->bank_sel = -1;
471 
472 	/* Setup sensor groups. */
473 	/* FANIN attributes */
474 	ret = nct7904_read_reg16(data, BANK_0, FANIN_CTRL0_REG);
475 	if (ret < 0)
476 		return ret;
477 	data->fanin_mask = (ret >> 8) | ((ret & 0xff) << 8);
478 
479 	/*
480 	 * VSEN attributes
481 	 *
482 	 * Note: voltage sensors overlap with external temperature
483 	 * sensors. So, if we ever decide to support the latter
484 	 * we will have to adjust 'vsen_mask' accordingly.
485 	 */
486 	mask = 0;
487 	ret = nct7904_read_reg16(data, BANK_0, VT_ADC_CTRL0_REG);
488 	if (ret >= 0)
489 		mask = (ret >> 8) | ((ret & 0xff) << 8);
490 	ret = nct7904_read_reg(data, BANK_0, VT_ADC_CTRL2_REG);
491 	if (ret >= 0)
492 		mask |= (ret << 16);
493 	data->vsen_mask = mask;
494 
495 	/* CPU_TEMP attributes */
496 	ret = nct7904_read_reg16(data, BANK_0, DTS_T_CTRL0_REG);
497 	if (ret < 0)
498 		return ret;
499 	data->tcpu_mask = ((ret >> 8) & 0xf) | ((ret & 0xf) << 4);
500 
501 	for (i = 0; i < FANCTL_MAX; i++) {
502 		ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + i);
503 		if (ret < 0)
504 			return ret;
505 		data->fan_mode[i] = ret;
506 	}
507 
508 	hwmon_dev =
509 		devm_hwmon_device_register_with_info(dev, client->name, data,
510 						     &nct7904_chip_info, NULL);
511 	return PTR_ERR_OR_ZERO(hwmon_dev);
512 }
513 
514 static const struct i2c_device_id nct7904_id[] = {
515 	{"nct7904", 0},
516 	{}
517 };
518 MODULE_DEVICE_TABLE(i2c, nct7904_id);
519 
520 static struct i2c_driver nct7904_driver = {
521 	.class = I2C_CLASS_HWMON,
522 	.driver = {
523 		.name = "nct7904",
524 	},
525 	.probe = nct7904_probe,
526 	.id_table = nct7904_id,
527 	.detect = nct7904_detect,
528 	.address_list = normal_i2c,
529 };
530 
531 module_i2c_driver(nct7904_driver);
532 
533 MODULE_AUTHOR("Vadim V. Vlasov <vvlasov@dev.rtsoft.ru>");
534 MODULE_DESCRIPTION("Hwmon driver for NUVOTON NCT7904");
535 MODULE_LICENSE("GPL");
536