blob: 6a9f420e7d32339e0f0fc578009a4c767a21e637 [file] [log] [blame]
Thomas Gleixnerc942fdd2019-05-27 08:55:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Guenter Roeck41082d62014-04-06 08:57:20 -07002/*
3 * nct6683 - Driver for the hardware monitoring functionality of
Jiqi Libfbbbe02021-03-04 18:44:21 +08004 * Nuvoton NCT6683D/NCT6686D/NCT6687D eSIO
Guenter Roeck41082d62014-04-06 08:57:20 -07005 *
6 * Copyright (C) 2013 Guenter Roeck <linux@roeck-us.net>
7 *
8 * Derived from nct6775 driver
9 * Copyright (C) 2012, 2013 Guenter Roeck <linux@roeck-us.net>
10 *
Guenter Roeck41082d62014-04-06 08:57:20 -070011 * Supports the following chips:
12 *
13 * Chip #vin #fan #pwm #temp chip ID
14 * nct6683d 21(1) 16 8 32(1) 0xc730
Jiqi Libfbbbe02021-03-04 18:44:21 +080015 * nct6686d 21(1) 16 8 32(1) 0xd440
David Bartleydaf4fedd2020-12-01 18:50:57 -080016 * nct6687d 21(1) 16 8 32(1) 0xd590
Guenter Roeck41082d62014-04-06 08:57:20 -070017 *
18 * Notes:
19 * (1) Total number of vin and temp inputs is 32.
20 */
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <linux/acpi.h>
Guenter Roeck91918d12015-02-19 09:21:29 -080025#include <linux/delay.h>
Guenter Roeck41082d62014-04-06 08:57:20 -070026#include <linux/err.h>
27#include <linux/init.h>
28#include <linux/io.h>
29#include <linux/jiffies.h>
30#include <linux/hwmon.h>
31#include <linux/hwmon-sysfs.h>
32#include <linux/module.h>
33#include <linux/mutex.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36
Jiqi Libfbbbe02021-03-04 18:44:21 +080037enum kinds { nct6683, nct6686, nct6687 };
Guenter Roeck41082d62014-04-06 08:57:20 -070038
39static bool force;
40module_param(force, bool, 0);
Guenter Roeck91918d12015-02-19 09:21:29 -080041MODULE_PARM_DESC(force, "Set to one to enable support for unknown vendors");
Guenter Roeck41082d62014-04-06 08:57:20 -070042
43static const char * const nct6683_device_names[] = {
44 "nct6683",
Jiqi Libfbbbe02021-03-04 18:44:21 +080045 "nct6686",
David Bartleydaf4fedd2020-12-01 18:50:57 -080046 "nct6687",
Guenter Roeck41082d62014-04-06 08:57:20 -070047};
48
49static const char * const nct6683_chip_names[] = {
50 "NCT6683D",
Jiqi Libfbbbe02021-03-04 18:44:21 +080051 "NCT6686D",
David Bartleydaf4fedd2020-12-01 18:50:57 -080052 "NCT6687D",
Guenter Roeck41082d62014-04-06 08:57:20 -070053};
54
55#define DRVNAME "nct6683"
56
57/*
58 * Super-I/O constants and functions
59 */
60
61#define NCT6683_LD_ACPI 0x0a
62#define NCT6683_LD_HWM 0x0b
63#define NCT6683_LD_VID 0x0d
64
65#define SIO_REG_LDSEL 0x07 /* Logical device select */
66#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
67#define SIO_REG_ENABLE 0x30 /* Logical device enable */
68#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
69
70#define SIO_NCT6681_ID 0xb270 /* for later */
71#define SIO_NCT6683_ID 0xc730
Jiqi Libfbbbe02021-03-04 18:44:21 +080072#define SIO_NCT6686_ID 0xd440
David Bartleydaf4fedd2020-12-01 18:50:57 -080073#define SIO_NCT6687_ID 0xd590
Guenter Roeck41082d62014-04-06 08:57:20 -070074#define SIO_ID_MASK 0xFFF0
75
76static inline void
77superio_outb(int ioreg, int reg, int val)
78{
79 outb(reg, ioreg);
80 outb(val, ioreg + 1);
81}
82
83static inline int
84superio_inb(int ioreg, int reg)
85{
86 outb(reg, ioreg);
87 return inb(ioreg + 1);
88}
89
90static inline void
91superio_select(int ioreg, int ld)
92{
93 outb(SIO_REG_LDSEL, ioreg);
94 outb(ld, ioreg + 1);
95}
96
97static inline int
98superio_enter(int ioreg)
99{
100 /*
101 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
102 */
103 if (!request_muxed_region(ioreg, 2, DRVNAME))
104 return -EBUSY;
105
106 outb(0x87, ioreg);
107 outb(0x87, ioreg);
108
109 return 0;
110}
111
112static inline void
113superio_exit(int ioreg)
114{
115 outb(0xaa, ioreg);
116 outb(0x02, ioreg);
117 outb(0x02, ioreg + 1);
118 release_region(ioreg, 2);
119}
120
121/*
122 * ISA constants
123 */
124
125#define IOREGION_ALIGNMENT (~7)
126#define IOREGION_OFFSET 4 /* Use EC port 1 */
127#define IOREGION_LENGTH 4
128
129#define EC_PAGE_REG 0
130#define EC_INDEX_REG 1
131#define EC_DATA_REG 2
132#define EC_EVENT_REG 3
133
134/* Common and NCT6683 specific data */
135
136#define NCT6683_NUM_REG_MON 32
137#define NCT6683_NUM_REG_FAN 16
138#define NCT6683_NUM_REG_PWM 8
139
140#define NCT6683_REG_MON(x) (0x100 + (x) * 2)
141#define NCT6683_REG_FAN_RPM(x) (0x140 + (x) * 2)
142#define NCT6683_REG_PWM(x) (0x160 + (x))
Guenter Roeck91918d12015-02-19 09:21:29 -0800143#define NCT6683_REG_PWM_WRITE(x) (0xa28 + (x))
Guenter Roeck41082d62014-04-06 08:57:20 -0700144
145#define NCT6683_REG_MON_STS(x) (0x174 + (x))
146#define NCT6683_REG_IDLE(x) (0x178 + (x))
147
148#define NCT6683_REG_FAN_STS(x) (0x17c + (x))
149#define NCT6683_REG_FAN_ERRSTS 0x17e
150#define NCT6683_REG_FAN_INITSTS 0x17f
151
152#define NCT6683_HWM_CFG 0x180
153
154#define NCT6683_REG_MON_CFG(x) (0x1a0 + (x))
155#define NCT6683_REG_FANIN_CFG(x) (0x1c0 + (x))
156#define NCT6683_REG_FANOUT_CFG(x) (0x1d0 + (x))
157
158#define NCT6683_REG_INTEL_TEMP_MAX(x) (0x901 + (x) * 16)
159#define NCT6683_REG_INTEL_TEMP_CRIT(x) (0x90d + (x) * 16)
160
161#define NCT6683_REG_TEMP_HYST(x) (0x330 + (x)) /* 8 bit */
162#define NCT6683_REG_TEMP_MAX(x) (0x350 + (x)) /* 8 bit */
163#define NCT6683_REG_MON_HIGH(x) (0x370 + (x) * 2) /* 8 bit */
164#define NCT6683_REG_MON_LOW(x) (0x371 + (x) * 2) /* 8 bit */
165
166#define NCT6683_REG_FAN_MIN(x) (0x3b8 + (x) * 2) /* 16 bit */
167
Guenter Roeck91918d12015-02-19 09:21:29 -0800168#define NCT6683_REG_FAN_CFG_CTRL 0xa01
169#define NCT6683_FAN_CFG_REQ 0x80
170#define NCT6683_FAN_CFG_DONE 0x40
171
Guenter Roeck41082d62014-04-06 08:57:20 -0700172#define NCT6683_REG_CUSTOMER_ID 0x602
173#define NCT6683_CUSTOMER_ID_INTEL 0x805
Guenter Roeck91918d12015-02-19 09:21:29 -0800174#define NCT6683_CUSTOMER_ID_MITAC 0xa0e
David Bartleydaf4fedd2020-12-01 18:50:57 -0800175#define NCT6683_CUSTOMER_ID_MSI 0x201
Blaž Hrastnikbd433532021-01-19 14:12:41 +0900176#define NCT6683_CUSTOMER_ID_ASROCK 0xe2c
Daniel Dawsond55532f2021-09-21 09:58:59 -0700177#define NCT6683_CUSTOMER_ID_ASROCK2 0xe1b
Guenter Roeck41082d62014-04-06 08:57:20 -0700178
179#define NCT6683_REG_BUILD_YEAR 0x604
180#define NCT6683_REG_BUILD_MONTH 0x605
181#define NCT6683_REG_BUILD_DAY 0x606
182#define NCT6683_REG_SERIAL 0x607
183#define NCT6683_REG_VERSION_HI 0x608
184#define NCT6683_REG_VERSION_LO 0x609
185
186#define NCT6683_REG_CR_CASEOPEN 0xe8
187#define NCT6683_CR_CASEOPEN_MASK (1 << 7)
188
189#define NCT6683_REG_CR_BEEP 0xe0
190#define NCT6683_CR_BEEP_MASK (1 << 6)
191
192static const char *const nct6683_mon_label[] = {
193 NULL, /* disabled */
194 "Local",
195 "Diode 0 (curr)",
196 "Diode 1 (curr)",
197 "Diode 2 (curr)",
198 "Diode 0 (volt)",
199 "Diode 1 (volt)",
200 "Diode 2 (volt)",
201 "Thermistor 14",
202 "Thermistor 15",
203 "Thermistor 16",
204 "Thermistor 0",
205 "Thermistor 1",
206 "Thermistor 2",
207 "Thermistor 3",
208 "Thermistor 4",
209 "Thermistor 5", /* 0x10 */
210 "Thermistor 6",
211 "Thermistor 7",
212 "Thermistor 8",
213 "Thermistor 9",
214 "Thermistor 10",
215 "Thermistor 11",
216 "Thermistor 12",
217 "Thermistor 13",
218 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
219 "PECI 0.0", /* 0x20 */
220 "PECI 1.0",
221 "PECI 2.0",
222 "PECI 3.0",
223 "PECI 0.1",
224 "PECI 1.1",
225 "PECI 2.1",
226 "PECI 3.1",
227 "PECI DIMM 0",
228 "PECI DIMM 1",
229 "PECI DIMM 2",
230 "PECI DIMM 3",
231 NULL, NULL, NULL, NULL,
232 "PCH CPU", /* 0x30 */
233 "PCH CHIP",
234 "PCH CHIP CPU MAX",
235 "PCH MCH",
236 "PCH DIMM 0",
237 "PCH DIMM 1",
238 "PCH DIMM 2",
239 "PCH DIMM 3",
240 "SMBus 0",
241 "SMBus 1",
242 "SMBus 2",
243 "SMBus 3",
244 "SMBus 4",
245 "SMBus 5",
246 "DIMM 0",
247 "DIMM 1",
248 "DIMM 2", /* 0x40 */
249 "DIMM 3",
250 "AMD TSI Addr 90h",
251 "AMD TSI Addr 92h",
252 "AMD TSI Addr 94h",
253 "AMD TSI Addr 96h",
254 "AMD TSI Addr 98h",
255 "AMD TSI Addr 9ah",
256 "AMD TSI Addr 9ch",
257 "AMD TSI Addr 9dh",
258 NULL, NULL, NULL, NULL, NULL, NULL,
259 "Virtual 0", /* 0x50 */
260 "Virtual 1",
261 "Virtual 2",
262 "Virtual 3",
263 "Virtual 4",
264 "Virtual 5",
265 "Virtual 6",
266 "Virtual 7",
267 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
268 "VCC", /* 0x60 voltage sensors */
269 "VSB",
270 "AVSB",
271 "VTT",
272 "VBAT",
273 "VREF",
274 "VIN0",
275 "VIN1",
276 "VIN2",
277 "VIN3",
278 "VIN4",
279 "VIN5",
280 "VIN6",
281 "VIN7",
282 "VIN8",
283 "VIN9",
284 "VIN10",
285 "VIN11",
286 "VIN12",
287 "VIN13",
288 "VIN14",
289 "VIN15",
290 "VIN16",
291};
292
293#define NUM_MON_LABELS ARRAY_SIZE(nct6683_mon_label)
294#define MON_VOLTAGE_START 0x60
295
296/* ------------------------------------------------------- */
297
298struct nct6683_data {
299 int addr; /* IO base of EC space */
300 int sioreg; /* SIO register */
301 enum kinds kind;
302 u16 customer_id;
303
304 struct device *hwmon_dev;
305 const struct attribute_group *groups[6];
306
307 int temp_num; /* number of temperature attributes */
308 u8 temp_index[NCT6683_NUM_REG_MON];
309 u8 temp_src[NCT6683_NUM_REG_MON];
310
311 u8 in_num; /* number of voltage attributes */
312 u8 in_index[NCT6683_NUM_REG_MON];
313 u8 in_src[NCT6683_NUM_REG_MON];
314
315 struct mutex update_lock; /* used to protect sensor updates */
316 bool valid; /* true if following fields are valid */
317 unsigned long last_updated; /* In jiffies */
318
319 /* Voltage attribute values */
320 u8 in[3][NCT6683_NUM_REG_MON]; /* [0]=in, [1]=in_max, [2]=in_min */
321
322 /* Temperature attribute values */
323 s16 temp_in[NCT6683_NUM_REG_MON];
324 s8 temp[4][NCT6683_NUM_REG_MON];/* [0]=min, [1]=max, [2]=hyst,
325 * [3]=crit
326 */
327
328 /* Fan attribute values */
329 unsigned int rpm[NCT6683_NUM_REG_FAN];
330 u16 fan_min[NCT6683_NUM_REG_FAN];
331 u8 fanin_cfg[NCT6683_NUM_REG_FAN];
332 u8 fanout_cfg[NCT6683_NUM_REG_FAN];
333 u16 have_fan; /* some fan inputs can be disabled */
334
335 u8 have_pwm;
336 u8 pwm[NCT6683_NUM_REG_PWM];
337
338#ifdef CONFIG_PM
339 /* Remember extra register values over suspend/resume */
340 u8 hwm_cfg;
341#endif
342};
343
344struct nct6683_sio_data {
345 int sioreg;
346 enum kinds kind;
347};
348
349struct sensor_device_template {
350 struct device_attribute dev_attr;
351 union {
352 struct {
353 u8 nr;
354 u8 index;
355 } s;
356 int index;
357 } u;
358 bool s2; /* true if both index and nr are used */
359};
360
361struct sensor_device_attr_u {
362 union {
363 struct sensor_device_attribute a1;
364 struct sensor_device_attribute_2 a2;
365 } u;
366 char name[32];
367};
368
369#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
370 .attr = {.name = _template, .mode = _mode }, \
371 .show = _show, \
372 .store = _store, \
373}
374
375#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
376 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
377 .u.index = _index, \
378 .s2 = false }
379
380#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
381 _nr, _index) \
382 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
383 .u.s.index = _index, \
384 .u.s.nr = _nr, \
385 .s2 = true }
386
387#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
388static struct sensor_device_template sensor_dev_template_##_name \
389 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
390 _index)
391
392#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
393 _nr, _index) \
394static struct sensor_device_template sensor_dev_template_##_name \
395 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
396 _nr, _index)
397
398struct sensor_template_group {
399 struct sensor_device_template **templates;
400 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
401 int base;
402};
403
404static struct attribute_group *
Julia Lawallc60fdf82015-12-12 17:36:39 +0100405nct6683_create_attr_group(struct device *dev,
406 const struct sensor_template_group *tg,
Guenter Roeck41082d62014-04-06 08:57:20 -0700407 int repeat)
408{
409 struct sensor_device_attribute_2 *a2;
410 struct sensor_device_attribute *a;
411 struct sensor_device_template **t;
412 struct sensor_device_attr_u *su;
413 struct attribute_group *group;
414 struct attribute **attrs;
415 int i, j, count;
416
417 if (repeat <= 0)
418 return ERR_PTR(-EINVAL);
419
420 t = tg->templates;
421 for (count = 0; *t; t++, count++)
422 ;
423
424 if (count == 0)
425 return ERR_PTR(-EINVAL);
426
427 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
428 if (group == NULL)
429 return ERR_PTR(-ENOMEM);
430
Kees Cooka86854d2018-06-12 14:07:58 -0700431 attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs),
Guenter Roeck41082d62014-04-06 08:57:20 -0700432 GFP_KERNEL);
433 if (attrs == NULL)
434 return ERR_PTR(-ENOMEM);
435
Kees Cooka86854d2018-06-12 14:07:58 -0700436 su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)),
Guenter Roeck41082d62014-04-06 08:57:20 -0700437 GFP_KERNEL);
438 if (su == NULL)
439 return ERR_PTR(-ENOMEM);
440
441 group->attrs = attrs;
442 group->is_visible = tg->is_visible;
443
444 for (i = 0; i < repeat; i++) {
445 t = tg->templates;
446 for (j = 0; *t != NULL; j++) {
447 snprintf(su->name, sizeof(su->name),
448 (*t)->dev_attr.attr.name, tg->base + i);
449 if ((*t)->s2) {
450 a2 = &su->u.a2;
Guenter Roeckc7bd6dc2015-05-28 09:12:23 -0700451 sysfs_attr_init(&a2->dev_attr.attr);
Guenter Roeck41082d62014-04-06 08:57:20 -0700452 a2->dev_attr.attr.name = su->name;
453 a2->nr = (*t)->u.s.nr + i;
454 a2->index = (*t)->u.s.index;
455 a2->dev_attr.attr.mode =
456 (*t)->dev_attr.attr.mode;
457 a2->dev_attr.show = (*t)->dev_attr.show;
458 a2->dev_attr.store = (*t)->dev_attr.store;
459 *attrs = &a2->dev_attr.attr;
460 } else {
461 a = &su->u.a1;
Guenter Roeckc7bd6dc2015-05-28 09:12:23 -0700462 sysfs_attr_init(&a->dev_attr.attr);
Guenter Roeck41082d62014-04-06 08:57:20 -0700463 a->dev_attr.attr.name = su->name;
464 a->index = (*t)->u.index + i;
465 a->dev_attr.attr.mode =
466 (*t)->dev_attr.attr.mode;
467 a->dev_attr.show = (*t)->dev_attr.show;
468 a->dev_attr.store = (*t)->dev_attr.store;
469 *attrs = &a->dev_attr.attr;
470 }
471 attrs++;
472 su++;
473 t++;
474 }
475 }
476
477 return group;
478}
479
480/* LSB is 16 mV, except for the following sources, where it is 32 mV */
481#define MON_SRC_VCC 0x60
482#define MON_SRC_VSB 0x61
483#define MON_SRC_AVSB 0x62
484#define MON_SRC_VBAT 0x64
485
486static inline long in_from_reg(u16 reg, u8 src)
487{
488 int scale = 16;
489
490 if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB ||
491 src == MON_SRC_VBAT)
492 scale <<= 1;
493 return reg * scale;
494}
495
Guenter Roeck41082d62014-04-06 08:57:20 -0700496static u16 nct6683_read(struct nct6683_data *data, u16 reg)
497{
498 int res;
499
500 outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */
501 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
502 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
503 res = inb_p(data->addr + EC_DATA_REG);
504 return res;
505}
506
507static u16 nct6683_read16(struct nct6683_data *data, u16 reg)
508{
509 return (nct6683_read(data, reg) << 8) | nct6683_read(data, reg + 1);
510}
511
512static void nct6683_write(struct nct6683_data *data, u16 reg, u16 value)
513{
514 outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */
515 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
516 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
517 outb_p(value & 0xff, data->addr + EC_DATA_REG);
518}
519
520static int get_in_reg(struct nct6683_data *data, int nr, int index)
521{
522 int ch = data->in_index[index];
523 int reg = -EINVAL;
524
525 switch (nr) {
526 case 0:
527 reg = NCT6683_REG_MON(ch);
528 break;
529 case 1:
530 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
531 reg = NCT6683_REG_MON_LOW(ch);
532 break;
533 case 2:
534 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
535 reg = NCT6683_REG_MON_HIGH(ch);
536 break;
537 default:
538 break;
539 }
540 return reg;
541}
542
543static int get_temp_reg(struct nct6683_data *data, int nr, int index)
544{
545 int ch = data->temp_index[index];
546 int reg = -EINVAL;
547
548 switch (data->customer_id) {
549 case NCT6683_CUSTOMER_ID_INTEL:
550 switch (nr) {
551 default:
552 case 1: /* max */
553 reg = NCT6683_REG_INTEL_TEMP_MAX(ch);
554 break;
555 case 3: /* crit */
556 reg = NCT6683_REG_INTEL_TEMP_CRIT(ch);
557 break;
558 }
559 break;
Guenter Roeck91918d12015-02-19 09:21:29 -0800560 case NCT6683_CUSTOMER_ID_MITAC:
Guenter Roeck41082d62014-04-06 08:57:20 -0700561 default:
562 switch (nr) {
563 default:
564 case 0: /* min */
565 reg = NCT6683_REG_MON_LOW(ch);
566 break;
567 case 1: /* max */
568 reg = NCT6683_REG_TEMP_MAX(ch);
569 break;
570 case 2: /* hyst */
571 reg = NCT6683_REG_TEMP_HYST(ch);
572 break;
573 case 3: /* crit */
574 reg = NCT6683_REG_MON_HIGH(ch);
575 break;
576 }
577 break;
578 }
579 return reg;
580}
581
582static void nct6683_update_pwm(struct device *dev)
583{
584 struct nct6683_data *data = dev_get_drvdata(dev);
585 int i;
586
587 for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
588 if (!(data->have_pwm & (1 << i)))
589 continue;
590 data->pwm[i] = nct6683_read(data, NCT6683_REG_PWM(i));
591 }
592}
593
594static struct nct6683_data *nct6683_update_device(struct device *dev)
595{
596 struct nct6683_data *data = dev_get_drvdata(dev);
597 int i, j;
598
599 mutex_lock(&data->update_lock);
600
601 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
602 /* Measured voltages and limits */
603 for (i = 0; i < data->in_num; i++) {
604 for (j = 0; j < 3; j++) {
605 int reg = get_in_reg(data, j, i);
606
607 if (reg >= 0)
608 data->in[j][i] =
609 nct6683_read(data, reg);
610 }
611 }
612
613 /* Measured temperatures and limits */
614 for (i = 0; i < data->temp_num; i++) {
615 u8 ch = data->temp_index[i];
616
617 data->temp_in[i] = nct6683_read16(data,
618 NCT6683_REG_MON(ch));
619 for (j = 0; j < 4; j++) {
620 int reg = get_temp_reg(data, j, i);
621
622 if (reg >= 0)
623 data->temp[j][i] =
624 nct6683_read(data, reg);
625 }
626 }
627
628 /* Measured fan speeds and limits */
629 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
630 if (!(data->have_fan & (1 << i)))
631 continue;
632
633 data->rpm[i] = nct6683_read16(data,
634 NCT6683_REG_FAN_RPM(i));
635 data->fan_min[i] = nct6683_read16(data,
636 NCT6683_REG_FAN_MIN(i));
637 }
638
639 nct6683_update_pwm(dev);
640
641 data->last_updated = jiffies;
642 data->valid = true;
643 }
644
645 mutex_unlock(&data->update_lock);
646 return data;
647}
648
649/*
650 * Sysfs callback functions
651 */
652static ssize_t
653show_in_label(struct device *dev, struct device_attribute *attr, char *buf)
654{
655 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
656 struct nct6683_data *data = nct6683_update_device(dev);
657 int nr = sattr->index;
658
659 return sprintf(buf, "%s\n", nct6683_mon_label[data->in_src[nr]]);
660}
661
662static ssize_t
663show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
664{
665 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
666 struct nct6683_data *data = nct6683_update_device(dev);
667 int index = sattr->index;
668 int nr = sattr->nr;
669
670 return sprintf(buf, "%ld\n",
671 in_from_reg(data->in[index][nr], data->in_index[index]));
672}
673
674static umode_t nct6683_in_is_visible(struct kobject *kobj,
675 struct attribute *attr, int index)
676{
Wang Qing23fd63a2020-06-13 16:06:44 +0800677 struct device *dev = kobj_to_dev(kobj);
Guenter Roeck41082d62014-04-06 08:57:20 -0700678 struct nct6683_data *data = dev_get_drvdata(dev);
679 int nr = index % 4; /* attribute */
680
681 /*
682 * Voltage limits exist for Intel boards,
683 * but register location and encoding is unknown
684 */
685 if ((nr == 2 || nr == 3) &&
686 data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
687 return 0;
688
689 return attr->mode;
690}
691
692SENSOR_TEMPLATE(in_label, "in%d_label", S_IRUGO, show_in_label, NULL, 0);
693SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
694SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IRUGO, show_in_reg, NULL, 0, 1);
695SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IRUGO, show_in_reg, NULL, 0, 2);
696
697static struct sensor_device_template *nct6683_attributes_in_template[] = {
698 &sensor_dev_template_in_label,
699 &sensor_dev_template_in_input,
700 &sensor_dev_template_in_min,
701 &sensor_dev_template_in_max,
702 NULL
703};
704
Julia Lawallc60fdf82015-12-12 17:36:39 +0100705static const struct sensor_template_group nct6683_in_template_group = {
Guenter Roeck41082d62014-04-06 08:57:20 -0700706 .templates = nct6683_attributes_in_template,
707 .is_visible = nct6683_in_is_visible,
708};
709
710static ssize_t
711show_fan(struct device *dev, struct device_attribute *attr, char *buf)
712{
713 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
714 struct nct6683_data *data = nct6683_update_device(dev);
715
716 return sprintf(buf, "%d\n", data->rpm[sattr->index]);
717}
718
719static ssize_t
720show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
721{
722 struct nct6683_data *data = nct6683_update_device(dev);
723 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
724 int nr = sattr->index;
725
726 return sprintf(buf, "%d\n", data->fan_min[nr]);
727}
728
729static ssize_t
730show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
731{
732 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
733 struct nct6683_data *data = nct6683_update_device(dev);
734
735 return sprintf(buf, "%d\n",
736 ((data->fanin_cfg[sattr->index] >> 5) & 0x03) + 1);
737}
738
739static umode_t nct6683_fan_is_visible(struct kobject *kobj,
740 struct attribute *attr, int index)
741{
Wang Qing23fd63a2020-06-13 16:06:44 +0800742 struct device *dev = kobj_to_dev(kobj);
Guenter Roeck41082d62014-04-06 08:57:20 -0700743 struct nct6683_data *data = dev_get_drvdata(dev);
744 int fan = index / 3; /* fan index */
745 int nr = index % 3; /* attribute index */
746
747 if (!(data->have_fan & (1 << fan)))
748 return 0;
749
750 /*
751 * Intel may have minimum fan speed limits,
752 * but register location and encoding are unknown.
753 */
754 if (nr == 2 && data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
755 return 0;
756
757 return attr->mode;
758}
759
760SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
761SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IRUGO, show_fan_pulses, NULL, 0);
762SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IRUGO, show_fan_min, NULL, 0);
763
764/*
765 * nct6683_fan_is_visible uses the index into the following array
766 * to determine if attributes should be created or not.
767 * Any change in order or content must be matched.
768 */
769static struct sensor_device_template *nct6683_attributes_fan_template[] = {
770 &sensor_dev_template_fan_input,
771 &sensor_dev_template_fan_pulses,
772 &sensor_dev_template_fan_min,
773 NULL
774};
775
Julia Lawallc60fdf82015-12-12 17:36:39 +0100776static const struct sensor_template_group nct6683_fan_template_group = {
Guenter Roeck41082d62014-04-06 08:57:20 -0700777 .templates = nct6683_attributes_fan_template,
778 .is_visible = nct6683_fan_is_visible,
779 .base = 1,
780};
781
782static ssize_t
783show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
784{
785 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
786 struct nct6683_data *data = nct6683_update_device(dev);
787 int nr = sattr->index;
788
789 return sprintf(buf, "%s\n", nct6683_mon_label[data->temp_src[nr]]);
790}
791
792static ssize_t
793show_temp8(struct device *dev, struct device_attribute *attr, char *buf)
794{
795 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
796 struct nct6683_data *data = nct6683_update_device(dev);
797 int index = sattr->index;
798 int nr = sattr->nr;
799
800 return sprintf(buf, "%d\n", data->temp[index][nr] * 1000);
801}
802
803static ssize_t
804show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
805{
806 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
807 struct nct6683_data *data = nct6683_update_device(dev);
808 int nr = sattr->index;
809 int temp = data->temp[1][nr] - data->temp[2][nr];
810
811 return sprintf(buf, "%d\n", temp * 1000);
812}
813
814static ssize_t
815show_temp16(struct device *dev, struct device_attribute *attr, char *buf)
816{
817 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
818 struct nct6683_data *data = nct6683_update_device(dev);
819 int index = sattr->index;
820
821 return sprintf(buf, "%d\n", (data->temp_in[index] / 128) * 500);
822}
823
824/*
825 * Temperature sensor type is determined by temperature source
826 * and can not be modified.
827 * 0x02..0x07: Thermal diode
828 * 0x08..0x18: Thermistor
829 * 0x20..0x2b: Intel PECI
830 * 0x42..0x49: AMD TSI
831 * Others are unspecified (not visible)
832 */
833
834static int get_temp_type(u8 src)
835{
836 if (src >= 0x02 && src <= 0x07)
837 return 3; /* thermal diode */
838 else if (src >= 0x08 && src <= 0x18)
839 return 4; /* thermistor */
840 else if (src >= 0x20 && src <= 0x2b)
841 return 6; /* PECI */
842 else if (src >= 0x42 && src <= 0x49)
843 return 5;
844
845 return 0;
846}
847
848static ssize_t
849show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
850{
851 struct nct6683_data *data = nct6683_update_device(dev);
852 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
853 int nr = sattr->index;
854 return sprintf(buf, "%d\n", get_temp_type(data->temp_src[nr]));
855}
856
857static umode_t nct6683_temp_is_visible(struct kobject *kobj,
858 struct attribute *attr, int index)
859{
Wang Qing23fd63a2020-06-13 16:06:44 +0800860 struct device *dev = kobj_to_dev(kobj);
Guenter Roeck41082d62014-04-06 08:57:20 -0700861 struct nct6683_data *data = dev_get_drvdata(dev);
862 int temp = index / 7; /* temp index */
863 int nr = index % 7; /* attribute index */
864
865 /*
866 * Intel does not have low temperature limits or temperature hysteresis
867 * registers, or at least register location and encoding is unknown.
868 */
869 if ((nr == 2 || nr == 4) &&
870 data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
871 return 0;
872
873 if (nr == 6 && get_temp_type(data->temp_src[temp]) == 0)
874 return 0; /* type */
875
876 return attr->mode;
877}
878
879SENSOR_TEMPLATE(temp_input, "temp%d_input", S_IRUGO, show_temp16, NULL, 0);
880SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
881SENSOR_TEMPLATE_2(temp_min, "temp%d_min", S_IRUGO, show_temp8, NULL, 0, 0);
882SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO, show_temp8, NULL, 0, 1);
883SENSOR_TEMPLATE(temp_max_hyst, "temp%d_max_hyst", S_IRUGO, show_temp_hyst, NULL,
884 0);
885SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO, show_temp8, NULL, 0, 3);
886SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO, show_temp_type, NULL, 0);
887
888/*
889 * nct6683_temp_is_visible uses the index into the following array
890 * to determine if attributes should be created or not.
891 * Any change in order or content must be matched.
892 */
893static struct sensor_device_template *nct6683_attributes_temp_template[] = {
894 &sensor_dev_template_temp_input,
895 &sensor_dev_template_temp_label,
896 &sensor_dev_template_temp_min, /* 2 */
897 &sensor_dev_template_temp_max, /* 3 */
898 &sensor_dev_template_temp_max_hyst, /* 4 */
899 &sensor_dev_template_temp_crit, /* 5 */
900 &sensor_dev_template_temp_type, /* 6 */
901 NULL
902};
903
Julia Lawallc60fdf82015-12-12 17:36:39 +0100904static const struct sensor_template_group nct6683_temp_template_group = {
Guenter Roeck41082d62014-04-06 08:57:20 -0700905 .templates = nct6683_attributes_temp_template,
906 .is_visible = nct6683_temp_is_visible,
907 .base = 1,
908};
909
910static ssize_t
911show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
912{
913 struct nct6683_data *data = nct6683_update_device(dev);
914 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
915 int index = sattr->index;
916
917 return sprintf(buf, "%d\n", data->pwm[index]);
918}
919
Guenter Roeck91918d12015-02-19 09:21:29 -0800920static ssize_t
921store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
922 size_t count)
923{
924 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
925 struct nct6683_data *data = dev_get_drvdata(dev);
926 int index = sattr->index;
927 unsigned long val;
928
929 if (kstrtoul(buf, 10, &val) || val > 255)
930 return -EINVAL;
931
932 mutex_lock(&data->update_lock);
933 nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_REQ);
934 usleep_range(1000, 2000);
935 nct6683_write(data, NCT6683_REG_PWM_WRITE(index), val);
936 nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_DONE);
937 mutex_unlock(&data->update_lock);
938
939 return count;
940}
941
942SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, store_pwm, 0);
Guenter Roeck41082d62014-04-06 08:57:20 -0700943
944static umode_t nct6683_pwm_is_visible(struct kobject *kobj,
945 struct attribute *attr, int index)
946{
Wang Qing23fd63a2020-06-13 16:06:44 +0800947 struct device *dev = kobj_to_dev(kobj);
Guenter Roeck41082d62014-04-06 08:57:20 -0700948 struct nct6683_data *data = dev_get_drvdata(dev);
949 int pwm = index; /* pwm index */
950
951 if (!(data->have_pwm & (1 << pwm)))
952 return 0;
953
Guenter Roeck91918d12015-02-19 09:21:29 -0800954 /* Only update pwm values for Mitac boards */
955 if (data->customer_id == NCT6683_CUSTOMER_ID_MITAC)
956 return attr->mode | S_IWUSR;
957
Guenter Roeck41082d62014-04-06 08:57:20 -0700958 return attr->mode;
959}
960
961static struct sensor_device_template *nct6683_attributes_pwm_template[] = {
962 &sensor_dev_template_pwm,
963 NULL
964};
965
Julia Lawallc60fdf82015-12-12 17:36:39 +0100966static const struct sensor_template_group nct6683_pwm_template_group = {
Guenter Roeck41082d62014-04-06 08:57:20 -0700967 .templates = nct6683_attributes_pwm_template,
968 .is_visible = nct6683_pwm_is_visible,
969 .base = 1,
970};
971
972static ssize_t
Julia Lawall1f856172016-12-22 13:05:01 +0100973beep_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
Guenter Roeck41082d62014-04-06 08:57:20 -0700974{
975 struct nct6683_data *data = dev_get_drvdata(dev);
976 int ret;
977 u8 reg;
978
979 mutex_lock(&data->update_lock);
980
981 ret = superio_enter(data->sioreg);
982 if (ret)
983 goto error;
984 superio_select(data->sioreg, NCT6683_LD_HWM);
985 reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
986 superio_exit(data->sioreg);
987
988 mutex_unlock(&data->update_lock);
989
990 return sprintf(buf, "%u\n", !!(reg & NCT6683_CR_BEEP_MASK));
991
992error:
993 mutex_unlock(&data->update_lock);
994 return ret;
995}
996
997static ssize_t
Julia Lawall1f856172016-12-22 13:05:01 +0100998beep_enable_store(struct device *dev, struct device_attribute *attr,
Guenter Roeck41082d62014-04-06 08:57:20 -0700999 const char *buf, size_t count)
1000{
1001 struct nct6683_data *data = dev_get_drvdata(dev);
1002 unsigned long val;
1003 u8 reg;
1004 int ret;
1005
1006 if (kstrtoul(buf, 10, &val) || (val != 0 && val != 1))
1007 return -EINVAL;
1008
1009 mutex_lock(&data->update_lock);
1010
1011 ret = superio_enter(data->sioreg);
1012 if (ret) {
1013 count = ret;
1014 goto error;
1015 }
1016
1017 superio_select(data->sioreg, NCT6683_LD_HWM);
1018 reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
1019 if (val)
1020 reg |= NCT6683_CR_BEEP_MASK;
1021 else
1022 reg &= ~NCT6683_CR_BEEP_MASK;
1023 superio_outb(data->sioreg, NCT6683_REG_CR_BEEP, reg);
1024 superio_exit(data->sioreg);
1025error:
1026 mutex_unlock(&data->update_lock);
1027 return count;
1028}
1029
1030/* Case open detection */
1031
1032static ssize_t
Julia Lawall1f856172016-12-22 13:05:01 +01001033intrusion0_alarm_show(struct device *dev, struct device_attribute *attr,
1034 char *buf)
Guenter Roeck41082d62014-04-06 08:57:20 -07001035{
1036 struct nct6683_data *data = dev_get_drvdata(dev);
1037 int ret;
1038 u8 reg;
1039
1040 mutex_lock(&data->update_lock);
1041
1042 ret = superio_enter(data->sioreg);
1043 if (ret)
1044 goto error;
1045 superio_select(data->sioreg, NCT6683_LD_ACPI);
1046 reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
1047 superio_exit(data->sioreg);
1048
1049 mutex_unlock(&data->update_lock);
1050
1051 return sprintf(buf, "%u\n", !(reg & NCT6683_CR_CASEOPEN_MASK));
1052
1053error:
1054 mutex_unlock(&data->update_lock);
1055 return ret;
1056}
1057
1058static ssize_t
Julia Lawall1f856172016-12-22 13:05:01 +01001059intrusion0_alarm_store(struct device *dev, struct device_attribute *attr,
1060 const char *buf, size_t count)
Guenter Roeck41082d62014-04-06 08:57:20 -07001061{
1062 struct nct6683_data *data = dev_get_drvdata(dev);
1063 unsigned long val;
1064 u8 reg;
1065 int ret;
1066
1067 if (kstrtoul(buf, 10, &val) || val != 0)
1068 return -EINVAL;
1069
1070 mutex_lock(&data->update_lock);
1071
1072 /*
1073 * Use CR registers to clear caseopen status.
1074 * Caseopen is activ low, clear by writing 1 into the register.
1075 */
1076
1077 ret = superio_enter(data->sioreg);
1078 if (ret) {
1079 count = ret;
1080 goto error;
1081 }
1082
1083 superio_select(data->sioreg, NCT6683_LD_ACPI);
1084 reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
1085 reg |= NCT6683_CR_CASEOPEN_MASK;
1086 superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
1087 reg &= ~NCT6683_CR_CASEOPEN_MASK;
1088 superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
1089 superio_exit(data->sioreg);
1090
1091 data->valid = false; /* Force cache refresh */
1092error:
1093 mutex_unlock(&data->update_lock);
1094 return count;
1095}
1096
Julia Lawall1f856172016-12-22 13:05:01 +01001097static DEVICE_ATTR_RW(intrusion0_alarm);
1098static DEVICE_ATTR_RW(beep_enable);
Guenter Roeck41082d62014-04-06 08:57:20 -07001099
1100static struct attribute *nct6683_attributes_other[] = {
1101 &dev_attr_intrusion0_alarm.attr,
1102 &dev_attr_beep_enable.attr,
1103 NULL
1104};
1105
1106static const struct attribute_group nct6683_group_other = {
1107 .attrs = nct6683_attributes_other,
1108};
1109
1110/* Get the monitoring functions started */
1111static inline void nct6683_init_device(struct nct6683_data *data)
1112{
1113 u8 tmp;
1114
1115 /* Start hardware monitoring if needed */
1116 tmp = nct6683_read(data, NCT6683_HWM_CFG);
1117 if (!(tmp & 0x80))
1118 nct6683_write(data, NCT6683_HWM_CFG, tmp | 0x80);
1119}
1120
1121/*
1122 * There are a total of 24 fan inputs. Each can be configured as input
1123 * or as output. A maximum of 16 inputs and 8 outputs is configurable.
1124 */
1125static void
1126nct6683_setup_fans(struct nct6683_data *data)
1127{
1128 int i;
1129 u8 reg;
1130
1131 for (i = 0; i < NCT6683_NUM_REG_FAN; i++) {
1132 reg = nct6683_read(data, NCT6683_REG_FANIN_CFG(i));
1133 if (reg & 0x80)
1134 data->have_fan |= 1 << i;
1135 data->fanin_cfg[i] = reg;
1136 }
1137 for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
1138 reg = nct6683_read(data, NCT6683_REG_FANOUT_CFG(i));
1139 if (reg & 0x80)
1140 data->have_pwm |= 1 << i;
1141 data->fanout_cfg[i] = reg;
1142 }
1143}
1144
1145/*
1146 * Translation from monitoring register to temperature and voltage attributes
1147 * ==========================================================================
1148 *
1149 * There are a total of 32 monitoring registers. Each can be assigned to either
1150 * a temperature or voltage monitoring source.
1151 * NCT6683_REG_MON_CFG(x) defines assignment for each monitoring source.
1152 *
1153 * Temperature and voltage attribute mapping is determined by walking through
1154 * the NCT6683_REG_MON_CFG registers. If the assigned source is
1155 * a temperature, temp_index[n] is set to the monitor register index, and
1156 * temp_src[n] is set to the temperature source. If the assigned source is
1157 * a voltage, the respective values are stored in in_index[] and in_src[],
1158 * respectively.
1159 */
1160
1161static void nct6683_setup_sensors(struct nct6683_data *data)
1162{
1163 u8 reg;
1164 int i;
1165
1166 data->temp_num = 0;
1167 data->in_num = 0;
1168 for (i = 0; i < NCT6683_NUM_REG_MON; i++) {
1169 reg = nct6683_read(data, NCT6683_REG_MON_CFG(i)) & 0x7f;
1170 /* Ignore invalid assignments */
1171 if (reg >= NUM_MON_LABELS)
1172 continue;
1173 /* Skip if disabled or reserved */
1174 if (nct6683_mon_label[reg] == NULL)
1175 continue;
1176 if (reg < MON_VOLTAGE_START) {
1177 data->temp_index[data->temp_num] = i;
1178 data->temp_src[data->temp_num] = reg;
1179 data->temp_num++;
1180 } else {
1181 data->in_index[data->in_num] = i;
1182 data->in_src[data->in_num] = reg;
1183 data->in_num++;
1184 }
1185 }
1186}
1187
1188static int nct6683_probe(struct platform_device *pdev)
1189{
1190 struct device *dev = &pdev->dev;
1191 struct nct6683_sio_data *sio_data = dev->platform_data;
1192 struct attribute_group *group;
1193 struct nct6683_data *data;
1194 struct device *hwmon_dev;
1195 struct resource *res;
1196 int groups = 0;
Guenter Roeck91918d12015-02-19 09:21:29 -08001197 char build[16];
Guenter Roeck41082d62014-04-06 08:57:20 -07001198
1199 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
1200 if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME))
1201 return -EBUSY;
1202
1203 data = devm_kzalloc(dev, sizeof(struct nct6683_data), GFP_KERNEL);
1204 if (!data)
1205 return -ENOMEM;
1206
1207 data->kind = sio_data->kind;
1208 data->sioreg = sio_data->sioreg;
1209 data->addr = res->start;
1210 mutex_init(&data->update_lock);
1211 platform_set_drvdata(pdev, data);
1212
1213 data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID);
1214
Guenter Roeck91918d12015-02-19 09:21:29 -08001215 /* By default only instantiate driver if the customer ID is known */
1216 switch (data->customer_id) {
1217 case NCT6683_CUSTOMER_ID_INTEL:
1218 break;
1219 case NCT6683_CUSTOMER_ID_MITAC:
1220 break;
David Bartleydaf4fedd2020-12-01 18:50:57 -08001221 case NCT6683_CUSTOMER_ID_MSI:
1222 break;
Blaž Hrastnikbd433532021-01-19 14:12:41 +09001223 case NCT6683_CUSTOMER_ID_ASROCK:
1224 break;
Daniel Dawsond55532f2021-09-21 09:58:59 -07001225 case NCT6683_CUSTOMER_ID_ASROCK2:
1226 break;
Guenter Roeck91918d12015-02-19 09:21:29 -08001227 default:
1228 if (!force)
1229 return -ENODEV;
1230 }
1231
Guenter Roeck41082d62014-04-06 08:57:20 -07001232 nct6683_init_device(data);
1233 nct6683_setup_fans(data);
1234 nct6683_setup_sensors(data);
1235
1236 /* Register sysfs hooks */
1237
1238 if (data->have_pwm) {
1239 group = nct6683_create_attr_group(dev,
1240 &nct6683_pwm_template_group,
1241 fls(data->have_pwm));
1242 if (IS_ERR(group))
1243 return PTR_ERR(group);
1244 data->groups[groups++] = group;
1245 }
1246
1247 if (data->in_num) {
1248 group = nct6683_create_attr_group(dev,
1249 &nct6683_in_template_group,
1250 data->in_num);
1251 if (IS_ERR(group))
1252 return PTR_ERR(group);
1253 data->groups[groups++] = group;
1254 }
1255
1256 if (data->have_fan) {
1257 group = nct6683_create_attr_group(dev,
1258 &nct6683_fan_template_group,
1259 fls(data->have_fan));
1260 if (IS_ERR(group))
1261 return PTR_ERR(group);
1262 data->groups[groups++] = group;
1263 }
1264
1265 if (data->temp_num) {
1266 group = nct6683_create_attr_group(dev,
1267 &nct6683_temp_template_group,
1268 data->temp_num);
1269 if (IS_ERR(group))
1270 return PTR_ERR(group);
1271 data->groups[groups++] = group;
1272 }
1273 data->groups[groups++] = &nct6683_group_other;
1274
Guenter Roeck91918d12015-02-19 09:21:29 -08001275 if (data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
1276 scnprintf(build, sizeof(build), "%02x/%02x/%02x",
1277 nct6683_read(data, NCT6683_REG_BUILD_MONTH),
1278 nct6683_read(data, NCT6683_REG_BUILD_DAY),
1279 nct6683_read(data, NCT6683_REG_BUILD_YEAR));
1280 else
1281 scnprintf(build, sizeof(build), "%02d/%02d/%02d",
1282 nct6683_read(data, NCT6683_REG_BUILD_MONTH),
1283 nct6683_read(data, NCT6683_REG_BUILD_DAY),
1284 nct6683_read(data, NCT6683_REG_BUILD_YEAR));
1285
1286 dev_info(dev, "%s EC firmware version %d.%d build %s\n",
Guenter Roeck41082d62014-04-06 08:57:20 -07001287 nct6683_chip_names[data->kind],
1288 nct6683_read(data, NCT6683_REG_VERSION_HI),
1289 nct6683_read(data, NCT6683_REG_VERSION_LO),
Guenter Roeck91918d12015-02-19 09:21:29 -08001290 build);
Guenter Roeck41082d62014-04-06 08:57:20 -07001291
1292 hwmon_dev = devm_hwmon_device_register_with_groups(dev,
1293 nct6683_device_names[data->kind], data, data->groups);
1294 return PTR_ERR_OR_ZERO(hwmon_dev);
1295}
1296
1297#ifdef CONFIG_PM
1298static int nct6683_suspend(struct device *dev)
1299{
1300 struct nct6683_data *data = nct6683_update_device(dev);
1301
1302 mutex_lock(&data->update_lock);
1303 data->hwm_cfg = nct6683_read(data, NCT6683_HWM_CFG);
1304 mutex_unlock(&data->update_lock);
1305
1306 return 0;
1307}
1308
1309static int nct6683_resume(struct device *dev)
1310{
1311 struct nct6683_data *data = dev_get_drvdata(dev);
1312
1313 mutex_lock(&data->update_lock);
1314
1315 nct6683_write(data, NCT6683_HWM_CFG, data->hwm_cfg);
1316
1317 /* Force re-reading all values */
1318 data->valid = false;
1319 mutex_unlock(&data->update_lock);
1320
1321 return 0;
1322}
1323
1324static const struct dev_pm_ops nct6683_dev_pm_ops = {
1325 .suspend = nct6683_suspend,
1326 .resume = nct6683_resume,
1327 .freeze = nct6683_suspend,
1328 .restore = nct6683_resume,
1329};
1330
1331#define NCT6683_DEV_PM_OPS (&nct6683_dev_pm_ops)
1332#else
1333#define NCT6683_DEV_PM_OPS NULL
1334#endif /* CONFIG_PM */
1335
1336static struct platform_driver nct6683_driver = {
1337 .driver = {
Guenter Roeck41082d62014-04-06 08:57:20 -07001338 .name = DRVNAME,
1339 .pm = NCT6683_DEV_PM_OPS,
1340 },
1341 .probe = nct6683_probe,
1342};
1343
1344static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
1345{
Guenter Roeck41082d62014-04-06 08:57:20 -07001346 int addr;
1347 u16 val;
1348 int err;
1349
Guenter Roeck41082d62014-04-06 08:57:20 -07001350 err = superio_enter(sioaddr);
1351 if (err)
1352 return err;
1353
1354 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
1355 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
1356
1357 switch (val & SIO_ID_MASK) {
1358 case SIO_NCT6683_ID:
1359 sio_data->kind = nct6683;
1360 break;
Jiqi Libfbbbe02021-03-04 18:44:21 +08001361 case SIO_NCT6686_ID:
1362 sio_data->kind = nct6686;
1363 break;
David Bartleydaf4fedd2020-12-01 18:50:57 -08001364 case SIO_NCT6687_ID:
1365 sio_data->kind = nct6687;
1366 break;
Guenter Roeck41082d62014-04-06 08:57:20 -07001367 default:
1368 if (val != 0xffff)
1369 pr_debug("unsupported chip ID: 0x%04x\n", val);
1370 goto fail;
1371 }
1372
1373 /* We have a known chip, find the HWM I/O address */
1374 superio_select(sioaddr, NCT6683_LD_HWM);
1375 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
1376 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
1377 addr = val & IOREGION_ALIGNMENT;
1378 if (addr == 0) {
1379 pr_err("EC base I/O port unconfigured\n");
1380 goto fail;
1381 }
1382
1383 /* Activate logical device if needed */
1384 val = superio_inb(sioaddr, SIO_REG_ENABLE);
1385 if (!(val & 0x01)) {
Guenter Roeckdbac00f2018-04-22 18:16:54 -07001386 pr_warn("Forcibly enabling EC access. Data may be unusable.\n");
1387 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
Guenter Roeck41082d62014-04-06 08:57:20 -07001388 }
1389
1390 superio_exit(sioaddr);
1391 pr_info("Found %s or compatible chip at %#x:%#x\n",
1392 nct6683_chip_names[sio_data->kind], sioaddr, addr);
1393 sio_data->sioreg = sioaddr;
1394
1395 return addr;
1396
1397fail:
1398 superio_exit(sioaddr);
1399 return -ENODEV;
1400}
1401
1402/*
1403 * when Super-I/O functions move to a separate file, the Super-I/O
1404 * bus will manage the lifetime of the device and this module will only keep
1405 * track of the nct6683 driver. But since we use platform_device_alloc(), we
1406 * must keep track of the device
1407 */
1408static struct platform_device *pdev[2];
1409
1410static int __init sensors_nct6683_init(void)
1411{
1412 struct nct6683_sio_data sio_data;
1413 int sioaddr[2] = { 0x2e, 0x4e };
1414 struct resource res;
1415 bool found = false;
1416 int address;
1417 int i, err;
1418
1419 err = platform_driver_register(&nct6683_driver);
1420 if (err)
1421 return err;
1422
1423 /*
1424 * initialize sio_data->kind and sio_data->sioreg.
1425 *
1426 * when Super-I/O functions move to a separate file, the Super-I/O
1427 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1428 * nct6683 hardware monitor, and call probe()
1429 */
1430 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1431 address = nct6683_find(sioaddr[i], &sio_data);
1432 if (address <= 0)
1433 continue;
1434
1435 found = true;
1436
1437 pdev[i] = platform_device_alloc(DRVNAME, address);
1438 if (!pdev[i]) {
1439 err = -ENOMEM;
Axel Lin30190c32014-05-24 23:04:22 +08001440 goto exit_device_unregister;
Guenter Roeck41082d62014-04-06 08:57:20 -07001441 }
1442
1443 err = platform_device_add_data(pdev[i], &sio_data,
1444 sizeof(struct nct6683_sio_data));
1445 if (err)
1446 goto exit_device_put;
1447
1448 memset(&res, 0, sizeof(res));
1449 res.name = DRVNAME;
1450 res.start = address + IOREGION_OFFSET;
1451 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1452 res.flags = IORESOURCE_IO;
1453
1454 err = acpi_check_resource_conflict(&res);
1455 if (err) {
1456 platform_device_put(pdev[i]);
1457 pdev[i] = NULL;
1458 continue;
1459 }
1460
1461 err = platform_device_add_resources(pdev[i], &res, 1);
1462 if (err)
1463 goto exit_device_put;
1464
1465 /* platform_device_add calls probe() */
1466 err = platform_device_add(pdev[i]);
1467 if (err)
1468 goto exit_device_put;
1469 }
1470 if (!found) {
1471 err = -ENODEV;
1472 goto exit_unregister;
1473 }
1474
1475 return 0;
1476
1477exit_device_put:
Axel Lin30190c32014-05-24 23:04:22 +08001478 platform_device_put(pdev[i]);
1479exit_device_unregister:
1480 while (--i >= 0) {
Guenter Roeck41082d62014-04-06 08:57:20 -07001481 if (pdev[i])
Axel Lin30190c32014-05-24 23:04:22 +08001482 platform_device_unregister(pdev[i]);
Guenter Roeck41082d62014-04-06 08:57:20 -07001483 }
1484exit_unregister:
1485 platform_driver_unregister(&nct6683_driver);
1486 return err;
1487}
1488
1489static void __exit sensors_nct6683_exit(void)
1490{
1491 int i;
1492
1493 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1494 if (pdev[i])
1495 platform_device_unregister(pdev[i]);
1496 }
1497 platform_driver_unregister(&nct6683_driver);
1498}
1499
1500MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1501MODULE_DESCRIPTION("NCT6683D driver");
1502MODULE_LICENSE("GPL");
1503
1504module_init(sensors_nct6683_init);
1505module_exit(sensors_nct6683_exit);