]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/hwmon/nct6683.c
hwmon: (ibmaem) constify aem_rw_sensor_template and aem_ro_sensor_template structures
[mirror_ubuntu-bionic-kernel.git] / drivers / hwmon / nct6683.c
CommitLineData
41082d66
GR
1/*
2 * nct6683 - Driver for the hardware monitoring functionality of
3 * Nuvoton NCT6683D eSIO
4 *
5 * Copyright (C) 2013 Guenter Roeck <linux@roeck-us.net>
6 *
7 * Derived from nct6775 driver
8 * Copyright (C) 2012, 2013 Guenter Roeck <linux@roeck-us.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * Supports the following chips:
21 *
22 * Chip #vin #fan #pwm #temp chip ID
23 * nct6683d 21(1) 16 8 32(1) 0xc730
24 *
25 * Notes:
26 * (1) Total number of vin and temp inputs is 32.
27 */
28
29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30
31#include <linux/acpi.h>
32#include <linux/dmi.h>
33#include <linux/err.h>
34#include <linux/init.h>
35#include <linux/io.h>
36#include <linux/jiffies.h>
37#include <linux/hwmon.h>
38#include <linux/hwmon-sysfs.h>
39#include <linux/module.h>
40#include <linux/mutex.h>
41#include <linux/platform_device.h>
42#include <linux/slab.h>
43
44enum kinds { nct6683 };
45
46static bool force;
47module_param(force, bool, 0);
48MODULE_PARM_DESC(force, "Set to one to enable detection on non-Intel boards");
49
50static const char * const nct6683_device_names[] = {
51 "nct6683",
52};
53
54static const char * const nct6683_chip_names[] = {
55 "NCT6683D",
56};
57
58#define DRVNAME "nct6683"
59
60/*
61 * Super-I/O constants and functions
62 */
63
64#define NCT6683_LD_ACPI 0x0a
65#define NCT6683_LD_HWM 0x0b
66#define NCT6683_LD_VID 0x0d
67
68#define SIO_REG_LDSEL 0x07 /* Logical device select */
69#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
70#define SIO_REG_ENABLE 0x30 /* Logical device enable */
71#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
72
73#define SIO_NCT6681_ID 0xb270 /* for later */
74#define SIO_NCT6683_ID 0xc730
75#define SIO_ID_MASK 0xFFF0
76
77static inline void
78superio_outb(int ioreg, int reg, int val)
79{
80 outb(reg, ioreg);
81 outb(val, ioreg + 1);
82}
83
84static inline int
85superio_inb(int ioreg, int reg)
86{
87 outb(reg, ioreg);
88 return inb(ioreg + 1);
89}
90
91static inline void
92superio_select(int ioreg, int ld)
93{
94 outb(SIO_REG_LDSEL, ioreg);
95 outb(ld, ioreg + 1);
96}
97
98static inline int
99superio_enter(int ioreg)
100{
101 /*
102 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
103 */
104 if (!request_muxed_region(ioreg, 2, DRVNAME))
105 return -EBUSY;
106
107 outb(0x87, ioreg);
108 outb(0x87, ioreg);
109
110 return 0;
111}
112
113static inline void
114superio_exit(int ioreg)
115{
116 outb(0xaa, ioreg);
117 outb(0x02, ioreg);
118 outb(0x02, ioreg + 1);
119 release_region(ioreg, 2);
120}
121
122/*
123 * ISA constants
124 */
125
126#define IOREGION_ALIGNMENT (~7)
127#define IOREGION_OFFSET 4 /* Use EC port 1 */
128#define IOREGION_LENGTH 4
129
130#define EC_PAGE_REG 0
131#define EC_INDEX_REG 1
132#define EC_DATA_REG 2
133#define EC_EVENT_REG 3
134
135/* Common and NCT6683 specific data */
136
137#define NCT6683_NUM_REG_MON 32
138#define NCT6683_NUM_REG_FAN 16
139#define NCT6683_NUM_REG_PWM 8
140
141#define NCT6683_REG_MON(x) (0x100 + (x) * 2)
142#define NCT6683_REG_FAN_RPM(x) (0x140 + (x) * 2)
143#define NCT6683_REG_PWM(x) (0x160 + (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_CUSTOMER_ID 0x602
169#define NCT6683_CUSTOMER_ID_INTEL 0x805
170
171#define NCT6683_REG_BUILD_YEAR 0x604
172#define NCT6683_REG_BUILD_MONTH 0x605
173#define NCT6683_REG_BUILD_DAY 0x606
174#define NCT6683_REG_SERIAL 0x607
175#define NCT6683_REG_VERSION_HI 0x608
176#define NCT6683_REG_VERSION_LO 0x609
177
178#define NCT6683_REG_CR_CASEOPEN 0xe8
179#define NCT6683_CR_CASEOPEN_MASK (1 << 7)
180
181#define NCT6683_REG_CR_BEEP 0xe0
182#define NCT6683_CR_BEEP_MASK (1 << 6)
183
184static const char *const nct6683_mon_label[] = {
185 NULL, /* disabled */
186 "Local",
187 "Diode 0 (curr)",
188 "Diode 1 (curr)",
189 "Diode 2 (curr)",
190 "Diode 0 (volt)",
191 "Diode 1 (volt)",
192 "Diode 2 (volt)",
193 "Thermistor 14",
194 "Thermistor 15",
195 "Thermistor 16",
196 "Thermistor 0",
197 "Thermistor 1",
198 "Thermistor 2",
199 "Thermistor 3",
200 "Thermistor 4",
201 "Thermistor 5", /* 0x10 */
202 "Thermistor 6",
203 "Thermistor 7",
204 "Thermistor 8",
205 "Thermistor 9",
206 "Thermistor 10",
207 "Thermistor 11",
208 "Thermistor 12",
209 "Thermistor 13",
210 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
211 "PECI 0.0", /* 0x20 */
212 "PECI 1.0",
213 "PECI 2.0",
214 "PECI 3.0",
215 "PECI 0.1",
216 "PECI 1.1",
217 "PECI 2.1",
218 "PECI 3.1",
219 "PECI DIMM 0",
220 "PECI DIMM 1",
221 "PECI DIMM 2",
222 "PECI DIMM 3",
223 NULL, NULL, NULL, NULL,
224 "PCH CPU", /* 0x30 */
225 "PCH CHIP",
226 "PCH CHIP CPU MAX",
227 "PCH MCH",
228 "PCH DIMM 0",
229 "PCH DIMM 1",
230 "PCH DIMM 2",
231 "PCH DIMM 3",
232 "SMBus 0",
233 "SMBus 1",
234 "SMBus 2",
235 "SMBus 3",
236 "SMBus 4",
237 "SMBus 5",
238 "DIMM 0",
239 "DIMM 1",
240 "DIMM 2", /* 0x40 */
241 "DIMM 3",
242 "AMD TSI Addr 90h",
243 "AMD TSI Addr 92h",
244 "AMD TSI Addr 94h",
245 "AMD TSI Addr 96h",
246 "AMD TSI Addr 98h",
247 "AMD TSI Addr 9ah",
248 "AMD TSI Addr 9ch",
249 "AMD TSI Addr 9dh",
250 NULL, NULL, NULL, NULL, NULL, NULL,
251 "Virtual 0", /* 0x50 */
252 "Virtual 1",
253 "Virtual 2",
254 "Virtual 3",
255 "Virtual 4",
256 "Virtual 5",
257 "Virtual 6",
258 "Virtual 7",
259 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
260 "VCC", /* 0x60 voltage sensors */
261 "VSB",
262 "AVSB",
263 "VTT",
264 "VBAT",
265 "VREF",
266 "VIN0",
267 "VIN1",
268 "VIN2",
269 "VIN3",
270 "VIN4",
271 "VIN5",
272 "VIN6",
273 "VIN7",
274 "VIN8",
275 "VIN9",
276 "VIN10",
277 "VIN11",
278 "VIN12",
279 "VIN13",
280 "VIN14",
281 "VIN15",
282 "VIN16",
283};
284
285#define NUM_MON_LABELS ARRAY_SIZE(nct6683_mon_label)
286#define MON_VOLTAGE_START 0x60
287
288/* ------------------------------------------------------- */
289
290struct nct6683_data {
291 int addr; /* IO base of EC space */
292 int sioreg; /* SIO register */
293 enum kinds kind;
294 u16 customer_id;
295
296 struct device *hwmon_dev;
297 const struct attribute_group *groups[6];
298
299 int temp_num; /* number of temperature attributes */
300 u8 temp_index[NCT6683_NUM_REG_MON];
301 u8 temp_src[NCT6683_NUM_REG_MON];
302
303 u8 in_num; /* number of voltage attributes */
304 u8 in_index[NCT6683_NUM_REG_MON];
305 u8 in_src[NCT6683_NUM_REG_MON];
306
307 struct mutex update_lock; /* used to protect sensor updates */
308 bool valid; /* true if following fields are valid */
309 unsigned long last_updated; /* In jiffies */
310
311 /* Voltage attribute values */
312 u8 in[3][NCT6683_NUM_REG_MON]; /* [0]=in, [1]=in_max, [2]=in_min */
313
314 /* Temperature attribute values */
315 s16 temp_in[NCT6683_NUM_REG_MON];
316 s8 temp[4][NCT6683_NUM_REG_MON];/* [0]=min, [1]=max, [2]=hyst,
317 * [3]=crit
318 */
319
320 /* Fan attribute values */
321 unsigned int rpm[NCT6683_NUM_REG_FAN];
322 u16 fan_min[NCT6683_NUM_REG_FAN];
323 u8 fanin_cfg[NCT6683_NUM_REG_FAN];
324 u8 fanout_cfg[NCT6683_NUM_REG_FAN];
325 u16 have_fan; /* some fan inputs can be disabled */
326
327 u8 have_pwm;
328 u8 pwm[NCT6683_NUM_REG_PWM];
329
330#ifdef CONFIG_PM
331 /* Remember extra register values over suspend/resume */
332 u8 hwm_cfg;
333#endif
334};
335
336struct nct6683_sio_data {
337 int sioreg;
338 enum kinds kind;
339};
340
341struct sensor_device_template {
342 struct device_attribute dev_attr;
343 union {
344 struct {
345 u8 nr;
346 u8 index;
347 } s;
348 int index;
349 } u;
350 bool s2; /* true if both index and nr are used */
351};
352
353struct sensor_device_attr_u {
354 union {
355 struct sensor_device_attribute a1;
356 struct sensor_device_attribute_2 a2;
357 } u;
358 char name[32];
359};
360
361#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
362 .attr = {.name = _template, .mode = _mode }, \
363 .show = _show, \
364 .store = _store, \
365}
366
367#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
368 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
369 .u.index = _index, \
370 .s2 = false }
371
372#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
373 _nr, _index) \
374 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
375 .u.s.index = _index, \
376 .u.s.nr = _nr, \
377 .s2 = true }
378
379#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
380static struct sensor_device_template sensor_dev_template_##_name \
381 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
382 _index)
383
384#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
385 _nr, _index) \
386static struct sensor_device_template sensor_dev_template_##_name \
387 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
388 _nr, _index)
389
390struct sensor_template_group {
391 struct sensor_device_template **templates;
392 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
393 int base;
394};
395
396static struct attribute_group *
c60fdf85
JL
397nct6683_create_attr_group(struct device *dev,
398 const struct sensor_template_group *tg,
41082d66
GR
399 int repeat)
400{
401 struct sensor_device_attribute_2 *a2;
402 struct sensor_device_attribute *a;
403 struct sensor_device_template **t;
404 struct sensor_device_attr_u *su;
405 struct attribute_group *group;
406 struct attribute **attrs;
407 int i, j, count;
408
409 if (repeat <= 0)
410 return ERR_PTR(-EINVAL);
411
412 t = tg->templates;
413 for (count = 0; *t; t++, count++)
414 ;
415
416 if (count == 0)
417 return ERR_PTR(-EINVAL);
418
419 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
420 if (group == NULL)
421 return ERR_PTR(-ENOMEM);
422
423 attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1),
424 GFP_KERNEL);
425 if (attrs == NULL)
426 return ERR_PTR(-ENOMEM);
427
428 su = devm_kzalloc(dev, sizeof(*su) * repeat * count,
429 GFP_KERNEL);
430 if (su == NULL)
431 return ERR_PTR(-ENOMEM);
432
433 group->attrs = attrs;
434 group->is_visible = tg->is_visible;
435
436 for (i = 0; i < repeat; i++) {
437 t = tg->templates;
438 for (j = 0; *t != NULL; j++) {
439 snprintf(su->name, sizeof(su->name),
440 (*t)->dev_attr.attr.name, tg->base + i);
441 if ((*t)->s2) {
442 a2 = &su->u.a2;
c7bd6dc3 443 sysfs_attr_init(&a2->dev_attr.attr);
41082d66
GR
444 a2->dev_attr.attr.name = su->name;
445 a2->nr = (*t)->u.s.nr + i;
446 a2->index = (*t)->u.s.index;
447 a2->dev_attr.attr.mode =
448 (*t)->dev_attr.attr.mode;
449 a2->dev_attr.show = (*t)->dev_attr.show;
450 a2->dev_attr.store = (*t)->dev_attr.store;
451 *attrs = &a2->dev_attr.attr;
452 } else {
453 a = &su->u.a1;
c7bd6dc3 454 sysfs_attr_init(&a->dev_attr.attr);
41082d66
GR
455 a->dev_attr.attr.name = su->name;
456 a->index = (*t)->u.index + i;
457 a->dev_attr.attr.mode =
458 (*t)->dev_attr.attr.mode;
459 a->dev_attr.show = (*t)->dev_attr.show;
460 a->dev_attr.store = (*t)->dev_attr.store;
461 *attrs = &a->dev_attr.attr;
462 }
463 attrs++;
464 su++;
465 t++;
466 }
467 }
468
469 return group;
470}
471
472/* LSB is 16 mV, except for the following sources, where it is 32 mV */
473#define MON_SRC_VCC 0x60
474#define MON_SRC_VSB 0x61
475#define MON_SRC_AVSB 0x62
476#define MON_SRC_VBAT 0x64
477
478static inline long in_from_reg(u16 reg, u8 src)
479{
480 int scale = 16;
481
482 if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB ||
483 src == MON_SRC_VBAT)
484 scale <<= 1;
485 return reg * scale;
486}
487
488static inline u16 in_to_reg(u32 val, 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
496 return clamp_val(DIV_ROUND_CLOSEST(val, scale), 0, 127);
497}
498
499static u16 nct6683_read(struct nct6683_data *data, u16 reg)
500{
501 int res;
502
503 outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */
504 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
505 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
506 res = inb_p(data->addr + EC_DATA_REG);
507 return res;
508}
509
510static u16 nct6683_read16(struct nct6683_data *data, u16 reg)
511{
512 return (nct6683_read(data, reg) << 8) | nct6683_read(data, reg + 1);
513}
514
515static void nct6683_write(struct nct6683_data *data, u16 reg, u16 value)
516{
517 outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */
518 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
519 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
520 outb_p(value & 0xff, data->addr + EC_DATA_REG);
521}
522
523static int get_in_reg(struct nct6683_data *data, int nr, int index)
524{
525 int ch = data->in_index[index];
526 int reg = -EINVAL;
527
528 switch (nr) {
529 case 0:
530 reg = NCT6683_REG_MON(ch);
531 break;
532 case 1:
533 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
534 reg = NCT6683_REG_MON_LOW(ch);
535 break;
536 case 2:
537 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
538 reg = NCT6683_REG_MON_HIGH(ch);
539 break;
540 default:
541 break;
542 }
543 return reg;
544}
545
546static int get_temp_reg(struct nct6683_data *data, int nr, int index)
547{
548 int ch = data->temp_index[index];
549 int reg = -EINVAL;
550
551 switch (data->customer_id) {
552 case NCT6683_CUSTOMER_ID_INTEL:
553 switch (nr) {
554 default:
555 case 1: /* max */
556 reg = NCT6683_REG_INTEL_TEMP_MAX(ch);
557 break;
558 case 3: /* crit */
559 reg = NCT6683_REG_INTEL_TEMP_CRIT(ch);
560 break;
561 }
562 break;
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, j, 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, j, 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(&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, "%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, "%ld\n",
673 in_from_reg(data->in[index][nr], 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 = container_of(kobj, struct device, 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
c60fdf85 707static const struct sensor_template_group nct6683_in_template_group = {
41082d66
GR
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, "%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, "%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, "%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 = container_of(kobj, struct device, 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
c60fdf85 778static const struct sensor_template_group nct6683_fan_template_group = {
41082d66
GR
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, "%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, "%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, "%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, "%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, "%d\n", get_temp_type(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 = container_of(kobj, struct device, 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(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
c60fdf85 906static const struct sensor_template_group nct6683_temp_template_group = {
41082d66
GR
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, "%d\n", data->pwm[index]);
920}
921
922SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, NULL, 0);
923
924static umode_t nct6683_pwm_is_visible(struct kobject *kobj,
925 struct attribute *attr, int index)
926{
927 struct device *dev = container_of(kobj, struct device, kobj);
928 struct nct6683_data *data = dev_get_drvdata(dev);
929 int pwm = index; /* pwm index */
930
931 if (!(data->have_pwm & (1 << pwm)))
932 return 0;
933
934 return attr->mode;
935}
936
937static struct sensor_device_template *nct6683_attributes_pwm_template[] = {
938 &sensor_dev_template_pwm,
939 NULL
940};
941
c60fdf85 942static const struct sensor_template_group nct6683_pwm_template_group = {
41082d66
GR
943 .templates = nct6683_attributes_pwm_template,
944 .is_visible = nct6683_pwm_is_visible,
945 .base = 1,
946};
947
948static ssize_t
949show_global_beep(struct device *dev, struct device_attribute *attr, char *buf)
950{
951 struct nct6683_data *data = dev_get_drvdata(dev);
952 int ret;
953 u8 reg;
954
955 mutex_lock(&data->update_lock);
956
957 ret = superio_enter(data->sioreg);
958 if (ret)
959 goto error;
960 superio_select(data->sioreg, NCT6683_LD_HWM);
961 reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
962 superio_exit(data->sioreg);
963
964 mutex_unlock(&data->update_lock);
965
966 return sprintf(buf, "%u\n", !!(reg & NCT6683_CR_BEEP_MASK));
967
968error:
969 mutex_unlock(&data->update_lock);
970 return ret;
971}
972
973static ssize_t
974store_global_beep(struct device *dev, struct device_attribute *attr,
975 const char *buf, size_t count)
976{
977 struct nct6683_data *data = dev_get_drvdata(dev);
978 unsigned long val;
979 u8 reg;
980 int ret;
981
982 if (kstrtoul(buf, 10, &val) || (val != 0 && val != 1))
983 return -EINVAL;
984
985 mutex_lock(&data->update_lock);
986
987 ret = superio_enter(data->sioreg);
988 if (ret) {
989 count = ret;
990 goto error;
991 }
992
993 superio_select(data->sioreg, NCT6683_LD_HWM);
994 reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
995 if (val)
996 reg |= NCT6683_CR_BEEP_MASK;
997 else
998 reg &= ~NCT6683_CR_BEEP_MASK;
999 superio_outb(data->sioreg, NCT6683_REG_CR_BEEP, reg);
1000 superio_exit(data->sioreg);
1001error:
1002 mutex_unlock(&data->update_lock);
1003 return count;
1004}
1005
1006/* Case open detection */
1007
1008static ssize_t
1009show_caseopen(struct device *dev, struct device_attribute *attr, char *buf)
1010{
1011 struct nct6683_data *data = dev_get_drvdata(dev);
1012 int ret;
1013 u8 reg;
1014
1015 mutex_lock(&data->update_lock);
1016
1017 ret = superio_enter(data->sioreg);
1018 if (ret)
1019 goto error;
1020 superio_select(data->sioreg, NCT6683_LD_ACPI);
1021 reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
1022 superio_exit(data->sioreg);
1023
1024 mutex_unlock(&data->update_lock);
1025
1026 return sprintf(buf, "%u\n", !(reg & NCT6683_CR_CASEOPEN_MASK));
1027
1028error:
1029 mutex_unlock(&data->update_lock);
1030 return ret;
1031}
1032
1033static ssize_t
1034clear_caseopen(struct device *dev, struct device_attribute *attr,
1035 const char *buf, size_t count)
1036{
1037 struct nct6683_data *data = dev_get_drvdata(dev);
1038 unsigned long val;
1039 u8 reg;
1040 int ret;
1041
1042 if (kstrtoul(buf, 10, &val) || val != 0)
1043 return -EINVAL;
1044
1045 mutex_lock(&data->update_lock);
1046
1047 /*
1048 * Use CR registers to clear caseopen status.
1049 * Caseopen is activ low, clear by writing 1 into the register.
1050 */
1051
1052 ret = superio_enter(data->sioreg);
1053 if (ret) {
1054 count = ret;
1055 goto error;
1056 }
1057
1058 superio_select(data->sioreg, NCT6683_LD_ACPI);
1059 reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
1060 reg |= NCT6683_CR_CASEOPEN_MASK;
1061 superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
1062 reg &= ~NCT6683_CR_CASEOPEN_MASK;
1063 superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
1064 superio_exit(data->sioreg);
1065
1066 data->valid = false; /* Force cache refresh */
1067error:
1068 mutex_unlock(&data->update_lock);
1069 return count;
1070}
1071
1072static DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen,
1073 clear_caseopen);
1074static DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_global_beep,
1075 store_global_beep);
1076
1077static struct attribute *nct6683_attributes_other[] = {
1078 &dev_attr_intrusion0_alarm.attr,
1079 &dev_attr_beep_enable.attr,
1080 NULL
1081};
1082
1083static const struct attribute_group nct6683_group_other = {
1084 .attrs = nct6683_attributes_other,
1085};
1086
1087/* Get the monitoring functions started */
1088static inline void nct6683_init_device(struct nct6683_data *data)
1089{
1090 u8 tmp;
1091
1092 /* Start hardware monitoring if needed */
1093 tmp = nct6683_read(data, NCT6683_HWM_CFG);
1094 if (!(tmp & 0x80))
1095 nct6683_write(data, NCT6683_HWM_CFG, tmp | 0x80);
1096}
1097
1098/*
1099 * There are a total of 24 fan inputs. Each can be configured as input
1100 * or as output. A maximum of 16 inputs and 8 outputs is configurable.
1101 */
1102static void
1103nct6683_setup_fans(struct nct6683_data *data)
1104{
1105 int i;
1106 u8 reg;
1107
1108 for (i = 0; i < NCT6683_NUM_REG_FAN; i++) {
1109 reg = nct6683_read(data, NCT6683_REG_FANIN_CFG(i));
1110 if (reg & 0x80)
1111 data->have_fan |= 1 << i;
1112 data->fanin_cfg[i] = reg;
1113 }
1114 for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
1115 reg = nct6683_read(data, NCT6683_REG_FANOUT_CFG(i));
1116 if (reg & 0x80)
1117 data->have_pwm |= 1 << i;
1118 data->fanout_cfg[i] = reg;
1119 }
1120}
1121
1122/*
1123 * Translation from monitoring register to temperature and voltage attributes
1124 * ==========================================================================
1125 *
1126 * There are a total of 32 monitoring registers. Each can be assigned to either
1127 * a temperature or voltage monitoring source.
1128 * NCT6683_REG_MON_CFG(x) defines assignment for each monitoring source.
1129 *
1130 * Temperature and voltage attribute mapping is determined by walking through
1131 * the NCT6683_REG_MON_CFG registers. If the assigned source is
1132 * a temperature, temp_index[n] is set to the monitor register index, and
1133 * temp_src[n] is set to the temperature source. If the assigned source is
1134 * a voltage, the respective values are stored in in_index[] and in_src[],
1135 * respectively.
1136 */
1137
1138static void nct6683_setup_sensors(struct nct6683_data *data)
1139{
1140 u8 reg;
1141 int i;
1142
1143 data->temp_num = 0;
1144 data->in_num = 0;
1145 for (i = 0; i < NCT6683_NUM_REG_MON; i++) {
1146 reg = nct6683_read(data, NCT6683_REG_MON_CFG(i)) & 0x7f;
1147 /* Ignore invalid assignments */
1148 if (reg >= NUM_MON_LABELS)
1149 continue;
1150 /* Skip if disabled or reserved */
1151 if (nct6683_mon_label[reg] == NULL)
1152 continue;
1153 if (reg < MON_VOLTAGE_START) {
1154 data->temp_index[data->temp_num] = i;
1155 data->temp_src[data->temp_num] = reg;
1156 data->temp_num++;
1157 } else {
1158 data->in_index[data->in_num] = i;
1159 data->in_src[data->in_num] = reg;
1160 data->in_num++;
1161 }
1162 }
1163}
1164
1165static int nct6683_probe(struct platform_device *pdev)
1166{
1167 struct device *dev = &pdev->dev;
1168 struct nct6683_sio_data *sio_data = dev->platform_data;
1169 struct attribute_group *group;
1170 struct nct6683_data *data;
1171 struct device *hwmon_dev;
1172 struct resource *res;
1173 int groups = 0;
1174
1175 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
1176 if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME))
1177 return -EBUSY;
1178
1179 data = devm_kzalloc(dev, sizeof(struct nct6683_data), GFP_KERNEL);
1180 if (!data)
1181 return -ENOMEM;
1182
1183 data->kind = sio_data->kind;
1184 data->sioreg = sio_data->sioreg;
1185 data->addr = res->start;
1186 mutex_init(&data->update_lock);
1187 platform_set_drvdata(pdev, data);
1188
1189 data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID);
1190
1191 nct6683_init_device(data);
1192 nct6683_setup_fans(data);
1193 nct6683_setup_sensors(data);
1194
1195 /* Register sysfs hooks */
1196
1197 if (data->have_pwm) {
1198 group = nct6683_create_attr_group(dev,
1199 &nct6683_pwm_template_group,
1200 fls(data->have_pwm));
1201 if (IS_ERR(group))
1202 return PTR_ERR(group);
1203 data->groups[groups++] = group;
1204 }
1205
1206 if (data->in_num) {
1207 group = nct6683_create_attr_group(dev,
1208 &nct6683_in_template_group,
1209 data->in_num);
1210 if (IS_ERR(group))
1211 return PTR_ERR(group);
1212 data->groups[groups++] = group;
1213 }
1214
1215 if (data->have_fan) {
1216 group = nct6683_create_attr_group(dev,
1217 &nct6683_fan_template_group,
1218 fls(data->have_fan));
1219 if (IS_ERR(group))
1220 return PTR_ERR(group);
1221 data->groups[groups++] = group;
1222 }
1223
1224 if (data->temp_num) {
1225 group = nct6683_create_attr_group(dev,
1226 &nct6683_temp_template_group,
1227 data->temp_num);
1228 if (IS_ERR(group))
1229 return PTR_ERR(group);
1230 data->groups[groups++] = group;
1231 }
1232 data->groups[groups++] = &nct6683_group_other;
1233
1234 dev_info(dev, "%s EC firmware version %d.%d build %02x/%02x/%02x\n",
1235 nct6683_chip_names[data->kind],
1236 nct6683_read(data, NCT6683_REG_VERSION_HI),
1237 nct6683_read(data, NCT6683_REG_VERSION_LO),
1238 nct6683_read(data, NCT6683_REG_BUILD_MONTH),
1239 nct6683_read(data, NCT6683_REG_BUILD_DAY),
1240 nct6683_read(data, NCT6683_REG_BUILD_YEAR));
1241
1242 hwmon_dev = devm_hwmon_device_register_with_groups(dev,
1243 nct6683_device_names[data->kind], data, data->groups);
1244 return PTR_ERR_OR_ZERO(hwmon_dev);
1245}
1246
1247#ifdef CONFIG_PM
1248static int nct6683_suspend(struct device *dev)
1249{
1250 struct nct6683_data *data = nct6683_update_device(dev);
1251
1252 mutex_lock(&data->update_lock);
1253 data->hwm_cfg = nct6683_read(data, NCT6683_HWM_CFG);
1254 mutex_unlock(&data->update_lock);
1255
1256 return 0;
1257}
1258
1259static int nct6683_resume(struct device *dev)
1260{
1261 struct nct6683_data *data = dev_get_drvdata(dev);
1262
1263 mutex_lock(&data->update_lock);
1264
1265 nct6683_write(data, NCT6683_HWM_CFG, data->hwm_cfg);
1266
1267 /* Force re-reading all values */
1268 data->valid = false;
1269 mutex_unlock(&data->update_lock);
1270
1271 return 0;
1272}
1273
1274static const struct dev_pm_ops nct6683_dev_pm_ops = {
1275 .suspend = nct6683_suspend,
1276 .resume = nct6683_resume,
1277 .freeze = nct6683_suspend,
1278 .restore = nct6683_resume,
1279};
1280
1281#define NCT6683_DEV_PM_OPS (&nct6683_dev_pm_ops)
1282#else
1283#define NCT6683_DEV_PM_OPS NULL
1284#endif /* CONFIG_PM */
1285
1286static struct platform_driver nct6683_driver = {
1287 .driver = {
41082d66
GR
1288 .name = DRVNAME,
1289 .pm = NCT6683_DEV_PM_OPS,
1290 },
1291 .probe = nct6683_probe,
1292};
1293
1294static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
1295{
1296 const char *board_vendor;
1297 int addr;
1298 u16 val;
1299 int err;
1300
1301 /*
1302 * Only run on Intel boards unless the 'force' module parameter is set
1303 */
1304 if (!force) {
1305 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1306 if (!board_vendor || strcmp(board_vendor, "Intel Corporation"))
1307 return -ENODEV;
1308 }
1309
1310 err = superio_enter(sioaddr);
1311 if (err)
1312 return err;
1313
1314 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
1315 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
1316
1317 switch (val & SIO_ID_MASK) {
1318 case SIO_NCT6683_ID:
1319 sio_data->kind = nct6683;
1320 break;
1321 default:
1322 if (val != 0xffff)
1323 pr_debug("unsupported chip ID: 0x%04x\n", val);
1324 goto fail;
1325 }
1326
1327 /* We have a known chip, find the HWM I/O address */
1328 superio_select(sioaddr, NCT6683_LD_HWM);
1329 val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
1330 | superio_inb(sioaddr, SIO_REG_ADDR + 1);
1331 addr = val & IOREGION_ALIGNMENT;
1332 if (addr == 0) {
1333 pr_err("EC base I/O port unconfigured\n");
1334 goto fail;
1335 }
1336
1337 /* Activate logical device if needed */
1338 val = superio_inb(sioaddr, SIO_REG_ENABLE);
1339 if (!(val & 0x01)) {
1340 pr_err("EC is disabled\n");
1341 goto fail;
1342 }
1343
1344 superio_exit(sioaddr);
1345 pr_info("Found %s or compatible chip at %#x:%#x\n",
1346 nct6683_chip_names[sio_data->kind], sioaddr, addr);
1347 sio_data->sioreg = sioaddr;
1348
1349 return addr;
1350
1351fail:
1352 superio_exit(sioaddr);
1353 return -ENODEV;
1354}
1355
1356/*
1357 * when Super-I/O functions move to a separate file, the Super-I/O
1358 * bus will manage the lifetime of the device and this module will only keep
1359 * track of the nct6683 driver. But since we use platform_device_alloc(), we
1360 * must keep track of the device
1361 */
1362static struct platform_device *pdev[2];
1363
1364static int __init sensors_nct6683_init(void)
1365{
1366 struct nct6683_sio_data sio_data;
1367 int sioaddr[2] = { 0x2e, 0x4e };
1368 struct resource res;
1369 bool found = false;
1370 int address;
1371 int i, err;
1372
1373 err = platform_driver_register(&nct6683_driver);
1374 if (err)
1375 return err;
1376
1377 /*
1378 * initialize sio_data->kind and sio_data->sioreg.
1379 *
1380 * when Super-I/O functions move to a separate file, the Super-I/O
1381 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1382 * nct6683 hardware monitor, and call probe()
1383 */
1384 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1385 address = nct6683_find(sioaddr[i], &sio_data);
1386 if (address <= 0)
1387 continue;
1388
1389 found = true;
1390
1391 pdev[i] = platform_device_alloc(DRVNAME, address);
1392 if (!pdev[i]) {
1393 err = -ENOMEM;
30190c3c 1394 goto exit_device_unregister;
41082d66
GR
1395 }
1396
1397 err = platform_device_add_data(pdev[i], &sio_data,
1398 sizeof(struct nct6683_sio_data));
1399 if (err)
1400 goto exit_device_put;
1401
1402 memset(&res, 0, sizeof(res));
1403 res.name = DRVNAME;
1404 res.start = address + IOREGION_OFFSET;
1405 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1406 res.flags = IORESOURCE_IO;
1407
1408 err = acpi_check_resource_conflict(&res);
1409 if (err) {
1410 platform_device_put(pdev[i]);
1411 pdev[i] = NULL;
1412 continue;
1413 }
1414
1415 err = platform_device_add_resources(pdev[i], &res, 1);
1416 if (err)
1417 goto exit_device_put;
1418
1419 /* platform_device_add calls probe() */
1420 err = platform_device_add(pdev[i]);
1421 if (err)
1422 goto exit_device_put;
1423 }
1424 if (!found) {
1425 err = -ENODEV;
1426 goto exit_unregister;
1427 }
1428
1429 return 0;
1430
1431exit_device_put:
30190c3c
AL
1432 platform_device_put(pdev[i]);
1433exit_device_unregister:
1434 while (--i >= 0) {
41082d66 1435 if (pdev[i])
30190c3c 1436 platform_device_unregister(pdev[i]);
41082d66
GR
1437 }
1438exit_unregister:
1439 platform_driver_unregister(&nct6683_driver);
1440 return err;
1441}
1442
1443static void __exit sensors_nct6683_exit(void)
1444{
1445 int i;
1446
1447 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1448 if (pdev[i])
1449 platform_device_unregister(pdev[i]);
1450 }
1451 platform_driver_unregister(&nct6683_driver);
1452}
1453
1454MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1455MODULE_DESCRIPTION("NCT6683D driver");
1456MODULE_LICENSE("GPL");
1457
1458module_init(sensors_nct6683_init);
1459module_exit(sensors_nct6683_exit);