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

source code of linux/drivers/hwmon/nct6683.c