0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0023
0024 #include <linux/acpi.h>
0025 #include <linux/delay.h>
0026 #include <linux/err.h>
0027 #include <linux/init.h>
0028 #include <linux/io.h>
0029 #include <linux/jiffies.h>
0030 #include <linux/hwmon.h>
0031 #include <linux/hwmon-sysfs.h>
0032 #include <linux/module.h>
0033 #include <linux/mutex.h>
0034 #include <linux/platform_device.h>
0035 #include <linux/slab.h>
0036
0037 enum kinds { nct6683, nct6686, nct6687 };
0038
0039 static bool force;
0040 module_param(force, bool, 0);
0041 MODULE_PARM_DESC(force, "Set to one to enable support for unknown vendors");
0042
0043 static const char * const nct6683_device_names[] = {
0044 "nct6683",
0045 "nct6686",
0046 "nct6687",
0047 };
0048
0049 static const char * const nct6683_chip_names[] = {
0050 "NCT6683D",
0051 "NCT6686D",
0052 "NCT6687D",
0053 };
0054
0055 #define DRVNAME "nct6683"
0056
0057
0058
0059
0060
0061 #define NCT6683_LD_ACPI 0x0a
0062 #define NCT6683_LD_HWM 0x0b
0063 #define NCT6683_LD_VID 0x0d
0064
0065 #define SIO_REG_LDSEL 0x07
0066 #define SIO_REG_DEVID 0x20
0067 #define SIO_REG_ENABLE 0x30
0068 #define SIO_REG_ADDR 0x60
0069
0070 #define SIO_NCT6681_ID 0xb270
0071 #define SIO_NCT6683_ID 0xc730
0072 #define SIO_NCT6686_ID 0xd440
0073 #define SIO_NCT6687_ID 0xd590
0074 #define SIO_ID_MASK 0xFFF0
0075
0076 static inline void
0077 superio_outb(int ioreg, int reg, int val)
0078 {
0079 outb(reg, ioreg);
0080 outb(val, ioreg + 1);
0081 }
0082
0083 static inline int
0084 superio_inb(int ioreg, int reg)
0085 {
0086 outb(reg, ioreg);
0087 return inb(ioreg + 1);
0088 }
0089
0090 static inline void
0091 superio_select(int ioreg, int ld)
0092 {
0093 outb(SIO_REG_LDSEL, ioreg);
0094 outb(ld, ioreg + 1);
0095 }
0096
0097 static inline int
0098 superio_enter(int ioreg)
0099 {
0100
0101
0102
0103 if (!request_muxed_region(ioreg, 2, DRVNAME))
0104 return -EBUSY;
0105
0106 outb(0x87, ioreg);
0107 outb(0x87, ioreg);
0108
0109 return 0;
0110 }
0111
0112 static inline void
0113 superio_exit(int ioreg)
0114 {
0115 outb(0xaa, ioreg);
0116 outb(0x02, ioreg);
0117 outb(0x02, ioreg + 1);
0118 release_region(ioreg, 2);
0119 }
0120
0121
0122
0123
0124
0125 #define IOREGION_ALIGNMENT (~7)
0126 #define IOREGION_OFFSET 4
0127 #define IOREGION_LENGTH 4
0128
0129 #define EC_PAGE_REG 0
0130 #define EC_INDEX_REG 1
0131 #define EC_DATA_REG 2
0132 #define EC_EVENT_REG 3
0133
0134
0135
0136 #define NCT6683_NUM_REG_MON 32
0137 #define NCT6683_NUM_REG_FAN 16
0138 #define NCT6683_NUM_REG_PWM 8
0139
0140 #define NCT6683_REG_MON(x) (0x100 + (x) * 2)
0141 #define NCT6683_REG_FAN_RPM(x) (0x140 + (x) * 2)
0142 #define NCT6683_REG_PWM(x) (0x160 + (x))
0143 #define NCT6683_REG_PWM_WRITE(x) (0xa28 + (x))
0144
0145 #define NCT6683_REG_MON_STS(x) (0x174 + (x))
0146 #define NCT6683_REG_IDLE(x) (0x178 + (x))
0147
0148 #define NCT6683_REG_FAN_STS(x) (0x17c + (x))
0149 #define NCT6683_REG_FAN_ERRSTS 0x17e
0150 #define NCT6683_REG_FAN_INITSTS 0x17f
0151
0152 #define NCT6683_HWM_CFG 0x180
0153
0154 #define NCT6683_REG_MON_CFG(x) (0x1a0 + (x))
0155 #define NCT6683_REG_FANIN_CFG(x) (0x1c0 + (x))
0156 #define NCT6683_REG_FANOUT_CFG(x) (0x1d0 + (x))
0157
0158 #define NCT6683_REG_INTEL_TEMP_MAX(x) (0x901 + (x) * 16)
0159 #define NCT6683_REG_INTEL_TEMP_CRIT(x) (0x90d + (x) * 16)
0160
0161 #define NCT6683_REG_TEMP_HYST(x) (0x330 + (x))
0162 #define NCT6683_REG_TEMP_MAX(x) (0x350 + (x))
0163 #define NCT6683_REG_MON_HIGH(x) (0x370 + (x) * 2)
0164 #define NCT6683_REG_MON_LOW(x) (0x371 + (x) * 2)
0165
0166 #define NCT6683_REG_FAN_MIN(x) (0x3b8 + (x) * 2)
0167
0168 #define NCT6683_REG_FAN_CFG_CTRL 0xa01
0169 #define NCT6683_FAN_CFG_REQ 0x80
0170 #define NCT6683_FAN_CFG_DONE 0x40
0171
0172 #define NCT6683_REG_CUSTOMER_ID 0x602
0173 #define NCT6683_CUSTOMER_ID_INTEL 0x805
0174 #define NCT6683_CUSTOMER_ID_MITAC 0xa0e
0175 #define NCT6683_CUSTOMER_ID_MSI 0x201
0176 #define NCT6683_CUSTOMER_ID_ASROCK 0xe2c
0177 #define NCT6683_CUSTOMER_ID_ASROCK2 0xe1b
0178
0179 #define NCT6683_REG_BUILD_YEAR 0x604
0180 #define NCT6683_REG_BUILD_MONTH 0x605
0181 #define NCT6683_REG_BUILD_DAY 0x606
0182 #define NCT6683_REG_SERIAL 0x607
0183 #define NCT6683_REG_VERSION_HI 0x608
0184 #define NCT6683_REG_VERSION_LO 0x609
0185
0186 #define NCT6683_REG_CR_CASEOPEN 0xe8
0187 #define NCT6683_CR_CASEOPEN_MASK (1 << 7)
0188
0189 #define NCT6683_REG_CR_BEEP 0xe0
0190 #define NCT6683_CR_BEEP_MASK (1 << 6)
0191
0192 static const char *const nct6683_mon_label[] = {
0193 NULL,
0194 "Local",
0195 "Diode 0 (curr)",
0196 "Diode 1 (curr)",
0197 "Diode 2 (curr)",
0198 "Diode 0 (volt)",
0199 "Diode 1 (volt)",
0200 "Diode 2 (volt)",
0201 "Thermistor 14",
0202 "Thermistor 15",
0203 "Thermistor 16",
0204 "Thermistor 0",
0205 "Thermistor 1",
0206 "Thermistor 2",
0207 "Thermistor 3",
0208 "Thermistor 4",
0209 "Thermistor 5",
0210 "Thermistor 6",
0211 "Thermistor 7",
0212 "Thermistor 8",
0213 "Thermistor 9",
0214 "Thermistor 10",
0215 "Thermistor 11",
0216 "Thermistor 12",
0217 "Thermistor 13",
0218 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0219 "PECI 0.0",
0220 "PECI 1.0",
0221 "PECI 2.0",
0222 "PECI 3.0",
0223 "PECI 0.1",
0224 "PECI 1.1",
0225 "PECI 2.1",
0226 "PECI 3.1",
0227 "PECI DIMM 0",
0228 "PECI DIMM 1",
0229 "PECI DIMM 2",
0230 "PECI DIMM 3",
0231 NULL, NULL, NULL, NULL,
0232 "PCH CPU",
0233 "PCH CHIP",
0234 "PCH CHIP CPU MAX",
0235 "PCH MCH",
0236 "PCH DIMM 0",
0237 "PCH DIMM 1",
0238 "PCH DIMM 2",
0239 "PCH DIMM 3",
0240 "SMBus 0",
0241 "SMBus 1",
0242 "SMBus 2",
0243 "SMBus 3",
0244 "SMBus 4",
0245 "SMBus 5",
0246 "DIMM 0",
0247 "DIMM 1",
0248 "DIMM 2",
0249 "DIMM 3",
0250 "AMD TSI Addr 90h",
0251 "AMD TSI Addr 92h",
0252 "AMD TSI Addr 94h",
0253 "AMD TSI Addr 96h",
0254 "AMD TSI Addr 98h",
0255 "AMD TSI Addr 9ah",
0256 "AMD TSI Addr 9ch",
0257 "AMD TSI Addr 9dh",
0258 NULL, NULL, NULL, NULL, NULL, NULL,
0259 "Virtual 0",
0260 "Virtual 1",
0261 "Virtual 2",
0262 "Virtual 3",
0263 "Virtual 4",
0264 "Virtual 5",
0265 "Virtual 6",
0266 "Virtual 7",
0267 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0268 "VCC",
0269 "VSB",
0270 "AVSB",
0271 "VTT",
0272 "VBAT",
0273 "VREF",
0274 "VIN0",
0275 "VIN1",
0276 "VIN2",
0277 "VIN3",
0278 "VIN4",
0279 "VIN5",
0280 "VIN6",
0281 "VIN7",
0282 "VIN8",
0283 "VIN9",
0284 "VIN10",
0285 "VIN11",
0286 "VIN12",
0287 "VIN13",
0288 "VIN14",
0289 "VIN15",
0290 "VIN16",
0291 };
0292
0293 #define NUM_MON_LABELS ARRAY_SIZE(nct6683_mon_label)
0294 #define MON_VOLTAGE_START 0x60
0295
0296
0297
0298 struct nct6683_data {
0299 int addr;
0300 int sioreg;
0301 enum kinds kind;
0302 u16 customer_id;
0303
0304 struct device *hwmon_dev;
0305 const struct attribute_group *groups[6];
0306
0307 int temp_num;
0308 u8 temp_index[NCT6683_NUM_REG_MON];
0309 u8 temp_src[NCT6683_NUM_REG_MON];
0310
0311 u8 in_num;
0312 u8 in_index[NCT6683_NUM_REG_MON];
0313 u8 in_src[NCT6683_NUM_REG_MON];
0314
0315 struct mutex update_lock;
0316 bool valid;
0317 unsigned long last_updated;
0318
0319
0320 u8 in[3][NCT6683_NUM_REG_MON];
0321
0322
0323 s16 temp_in[NCT6683_NUM_REG_MON];
0324 s8 temp[4][NCT6683_NUM_REG_MON];
0325
0326
0327
0328
0329 unsigned int rpm[NCT6683_NUM_REG_FAN];
0330 u16 fan_min[NCT6683_NUM_REG_FAN];
0331 u8 fanin_cfg[NCT6683_NUM_REG_FAN];
0332 u8 fanout_cfg[NCT6683_NUM_REG_FAN];
0333 u16 have_fan;
0334
0335 u8 have_pwm;
0336 u8 pwm[NCT6683_NUM_REG_PWM];
0337
0338 #ifdef CONFIG_PM
0339
0340 u8 hwm_cfg;
0341 #endif
0342 };
0343
0344 struct nct6683_sio_data {
0345 int sioreg;
0346 enum kinds kind;
0347 };
0348
0349 struct sensor_device_template {
0350 struct device_attribute dev_attr;
0351 union {
0352 struct {
0353 u8 nr;
0354 u8 index;
0355 } s;
0356 int index;
0357 } u;
0358 bool s2;
0359 };
0360
0361 struct sensor_device_attr_u {
0362 union {
0363 struct sensor_device_attribute a1;
0364 struct sensor_device_attribute_2 a2;
0365 } u;
0366 char name[32];
0367 };
0368
0369 #define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
0370 .attr = {.name = _template, .mode = _mode }, \
0371 .show = _show, \
0372 .store = _store, \
0373 }
0374
0375 #define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
0376 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
0377 .u.index = _index, \
0378 .s2 = false }
0379
0380 #define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
0381 _nr, _index) \
0382 { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
0383 .u.s.index = _index, \
0384 .u.s.nr = _nr, \
0385 .s2 = true }
0386
0387 #define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
0388 static struct sensor_device_template sensor_dev_template_##_name \
0389 = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
0390 _index)
0391
0392 #define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
0393 _nr, _index) \
0394 static struct sensor_device_template sensor_dev_template_##_name \
0395 = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
0396 _nr, _index)
0397
0398 struct sensor_template_group {
0399 struct sensor_device_template **templates;
0400 umode_t (*is_visible)(struct kobject *, struct attribute *, int);
0401 int base;
0402 };
0403
0404 static struct attribute_group *
0405 nct6683_create_attr_group(struct device *dev,
0406 const struct sensor_template_group *tg,
0407 int repeat)
0408 {
0409 struct sensor_device_attribute_2 *a2;
0410 struct sensor_device_attribute *a;
0411 struct sensor_device_template **t;
0412 struct sensor_device_attr_u *su;
0413 struct attribute_group *group;
0414 struct attribute **attrs;
0415 int i, j, count;
0416
0417 if (repeat <= 0)
0418 return ERR_PTR(-EINVAL);
0419
0420 t = tg->templates;
0421 for (count = 0; *t; t++, count++)
0422 ;
0423
0424 if (count == 0)
0425 return ERR_PTR(-EINVAL);
0426
0427 group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
0428 if (group == NULL)
0429 return ERR_PTR(-ENOMEM);
0430
0431 attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs),
0432 GFP_KERNEL);
0433 if (attrs == NULL)
0434 return ERR_PTR(-ENOMEM);
0435
0436 su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)),
0437 GFP_KERNEL);
0438 if (su == NULL)
0439 return ERR_PTR(-ENOMEM);
0440
0441 group->attrs = attrs;
0442 group->is_visible = tg->is_visible;
0443
0444 for (i = 0; i < repeat; i++) {
0445 t = tg->templates;
0446 for (j = 0; *t != NULL; j++) {
0447 snprintf(su->name, sizeof(su->name),
0448 (*t)->dev_attr.attr.name, tg->base + i);
0449 if ((*t)->s2) {
0450 a2 = &su->u.a2;
0451 sysfs_attr_init(&a2->dev_attr.attr);
0452 a2->dev_attr.attr.name = su->name;
0453 a2->nr = (*t)->u.s.nr + i;
0454 a2->index = (*t)->u.s.index;
0455 a2->dev_attr.attr.mode =
0456 (*t)->dev_attr.attr.mode;
0457 a2->dev_attr.show = (*t)->dev_attr.show;
0458 a2->dev_attr.store = (*t)->dev_attr.store;
0459 *attrs = &a2->dev_attr.attr;
0460 } else {
0461 a = &su->u.a1;
0462 sysfs_attr_init(&a->dev_attr.attr);
0463 a->dev_attr.attr.name = su->name;
0464 a->index = (*t)->u.index + i;
0465 a->dev_attr.attr.mode =
0466 (*t)->dev_attr.attr.mode;
0467 a->dev_attr.show = (*t)->dev_attr.show;
0468 a->dev_attr.store = (*t)->dev_attr.store;
0469 *attrs = &a->dev_attr.attr;
0470 }
0471 attrs++;
0472 su++;
0473 t++;
0474 }
0475 }
0476
0477 return group;
0478 }
0479
0480
0481 #define MON_SRC_VCC 0x60
0482 #define MON_SRC_VSB 0x61
0483 #define MON_SRC_AVSB 0x62
0484 #define MON_SRC_VBAT 0x64
0485
0486 static inline long in_from_reg(u16 reg, u8 src)
0487 {
0488 int scale = 16;
0489
0490 if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB ||
0491 src == MON_SRC_VBAT)
0492 scale <<= 1;
0493 return reg * scale;
0494 }
0495
0496 static u16 nct6683_read(struct nct6683_data *data, u16 reg)
0497 {
0498 int res;
0499
0500 outb_p(0xff, data->addr + EC_PAGE_REG);
0501 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
0502 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
0503 res = inb_p(data->addr + EC_DATA_REG);
0504 return res;
0505 }
0506
0507 static u16 nct6683_read16(struct nct6683_data *data, u16 reg)
0508 {
0509 return (nct6683_read(data, reg) << 8) | nct6683_read(data, reg + 1);
0510 }
0511
0512 static void nct6683_write(struct nct6683_data *data, u16 reg, u16 value)
0513 {
0514 outb_p(0xff, data->addr + EC_PAGE_REG);
0515 outb_p(reg >> 8, data->addr + EC_PAGE_REG);
0516 outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
0517 outb_p(value & 0xff, data->addr + EC_DATA_REG);
0518 }
0519
0520 static int get_in_reg(struct nct6683_data *data, int nr, int index)
0521 {
0522 int ch = data->in_index[index];
0523 int reg = -EINVAL;
0524
0525 switch (nr) {
0526 case 0:
0527 reg = NCT6683_REG_MON(ch);
0528 break;
0529 case 1:
0530 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
0531 reg = NCT6683_REG_MON_LOW(ch);
0532 break;
0533 case 2:
0534 if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
0535 reg = NCT6683_REG_MON_HIGH(ch);
0536 break;
0537 default:
0538 break;
0539 }
0540 return reg;
0541 }
0542
0543 static int get_temp_reg(struct nct6683_data *data, int nr, int index)
0544 {
0545 int ch = data->temp_index[index];
0546 int reg = -EINVAL;
0547
0548 switch (data->customer_id) {
0549 case NCT6683_CUSTOMER_ID_INTEL:
0550 switch (nr) {
0551 default:
0552 case 1:
0553 reg = NCT6683_REG_INTEL_TEMP_MAX(ch);
0554 break;
0555 case 3:
0556 reg = NCT6683_REG_INTEL_TEMP_CRIT(ch);
0557 break;
0558 }
0559 break;
0560 case NCT6683_CUSTOMER_ID_MITAC:
0561 default:
0562 switch (nr) {
0563 default:
0564 case 0:
0565 reg = NCT6683_REG_MON_LOW(ch);
0566 break;
0567 case 1:
0568 reg = NCT6683_REG_TEMP_MAX(ch);
0569 break;
0570 case 2:
0571 reg = NCT6683_REG_TEMP_HYST(ch);
0572 break;
0573 case 3:
0574 reg = NCT6683_REG_MON_HIGH(ch);
0575 break;
0576 }
0577 break;
0578 }
0579 return reg;
0580 }
0581
0582 static void nct6683_update_pwm(struct device *dev)
0583 {
0584 struct nct6683_data *data = dev_get_drvdata(dev);
0585 int i;
0586
0587 for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
0588 if (!(data->have_pwm & (1 << i)))
0589 continue;
0590 data->pwm[i] = nct6683_read(data, NCT6683_REG_PWM(i));
0591 }
0592 }
0593
0594 static struct nct6683_data *nct6683_update_device(struct device *dev)
0595 {
0596 struct nct6683_data *data = dev_get_drvdata(dev);
0597 int i, j;
0598
0599 mutex_lock(&data->update_lock);
0600
0601 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
0602
0603 for (i = 0; i < data->in_num; i++) {
0604 for (j = 0; j < 3; j++) {
0605 int reg = get_in_reg(data, j, i);
0606
0607 if (reg >= 0)
0608 data->in[j][i] =
0609 nct6683_read(data, reg);
0610 }
0611 }
0612
0613
0614 for (i = 0; i < data->temp_num; i++) {
0615 u8 ch = data->temp_index[i];
0616
0617 data->temp_in[i] = nct6683_read16(data,
0618 NCT6683_REG_MON(ch));
0619 for (j = 0; j < 4; j++) {
0620 int reg = get_temp_reg(data, j, i);
0621
0622 if (reg >= 0)
0623 data->temp[j][i] =
0624 nct6683_read(data, reg);
0625 }
0626 }
0627
0628
0629 for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
0630 if (!(data->have_fan & (1 << i)))
0631 continue;
0632
0633 data->rpm[i] = nct6683_read16(data,
0634 NCT6683_REG_FAN_RPM(i));
0635 data->fan_min[i] = nct6683_read16(data,
0636 NCT6683_REG_FAN_MIN(i));
0637 }
0638
0639 nct6683_update_pwm(dev);
0640
0641 data->last_updated = jiffies;
0642 data->valid = true;
0643 }
0644
0645 mutex_unlock(&data->update_lock);
0646 return data;
0647 }
0648
0649
0650
0651
0652 static ssize_t
0653 show_in_label(struct device *dev, struct device_attribute *attr, char *buf)
0654 {
0655 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0656 struct nct6683_data *data = nct6683_update_device(dev);
0657 int nr = sattr->index;
0658
0659 return sprintf(buf, "%s\n", nct6683_mon_label[data->in_src[nr]]);
0660 }
0661
0662 static ssize_t
0663 show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
0664 {
0665 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
0666 struct nct6683_data *data = nct6683_update_device(dev);
0667 int index = sattr->index;
0668 int nr = sattr->nr;
0669
0670 return sprintf(buf, "%ld\n",
0671 in_from_reg(data->in[index][nr], data->in_index[index]));
0672 }
0673
0674 static umode_t nct6683_in_is_visible(struct kobject *kobj,
0675 struct attribute *attr, int index)
0676 {
0677 struct device *dev = kobj_to_dev(kobj);
0678 struct nct6683_data *data = dev_get_drvdata(dev);
0679 int nr = index % 4;
0680
0681
0682
0683
0684
0685 if ((nr == 2 || nr == 3) &&
0686 data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
0687 return 0;
0688
0689 return attr->mode;
0690 }
0691
0692 SENSOR_TEMPLATE(in_label, "in%d_label", S_IRUGO, show_in_label, NULL, 0);
0693 SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
0694 SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IRUGO, show_in_reg, NULL, 0, 1);
0695 SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IRUGO, show_in_reg, NULL, 0, 2);
0696
0697 static struct sensor_device_template *nct6683_attributes_in_template[] = {
0698 &sensor_dev_template_in_label,
0699 &sensor_dev_template_in_input,
0700 &sensor_dev_template_in_min,
0701 &sensor_dev_template_in_max,
0702 NULL
0703 };
0704
0705 static const struct sensor_template_group nct6683_in_template_group = {
0706 .templates = nct6683_attributes_in_template,
0707 .is_visible = nct6683_in_is_visible,
0708 };
0709
0710 static ssize_t
0711 show_fan(struct device *dev, struct device_attribute *attr, char *buf)
0712 {
0713 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0714 struct nct6683_data *data = nct6683_update_device(dev);
0715
0716 return sprintf(buf, "%d\n", data->rpm[sattr->index]);
0717 }
0718
0719 static ssize_t
0720 show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
0721 {
0722 struct nct6683_data *data = nct6683_update_device(dev);
0723 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0724 int nr = sattr->index;
0725
0726 return sprintf(buf, "%d\n", data->fan_min[nr]);
0727 }
0728
0729 static ssize_t
0730 show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
0731 {
0732 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0733 struct nct6683_data *data = nct6683_update_device(dev);
0734
0735 return sprintf(buf, "%d\n",
0736 ((data->fanin_cfg[sattr->index] >> 5) & 0x03) + 1);
0737 }
0738
0739 static umode_t nct6683_fan_is_visible(struct kobject *kobj,
0740 struct attribute *attr, int index)
0741 {
0742 struct device *dev = kobj_to_dev(kobj);
0743 struct nct6683_data *data = dev_get_drvdata(dev);
0744 int fan = index / 3;
0745 int nr = index % 3;
0746
0747 if (!(data->have_fan & (1 << fan)))
0748 return 0;
0749
0750
0751
0752
0753
0754 if (nr == 2 && data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
0755 return 0;
0756
0757 return attr->mode;
0758 }
0759
0760 SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
0761 SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IRUGO, show_fan_pulses, NULL, 0);
0762 SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IRUGO, show_fan_min, NULL, 0);
0763
0764
0765
0766
0767
0768
0769 static struct sensor_device_template *nct6683_attributes_fan_template[] = {
0770 &sensor_dev_template_fan_input,
0771 &sensor_dev_template_fan_pulses,
0772 &sensor_dev_template_fan_min,
0773 NULL
0774 };
0775
0776 static const struct sensor_template_group nct6683_fan_template_group = {
0777 .templates = nct6683_attributes_fan_template,
0778 .is_visible = nct6683_fan_is_visible,
0779 .base = 1,
0780 };
0781
0782 static ssize_t
0783 show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
0784 {
0785 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0786 struct nct6683_data *data = nct6683_update_device(dev);
0787 int nr = sattr->index;
0788
0789 return sprintf(buf, "%s\n", nct6683_mon_label[data->temp_src[nr]]);
0790 }
0791
0792 static ssize_t
0793 show_temp8(struct device *dev, struct device_attribute *attr, char *buf)
0794 {
0795 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
0796 struct nct6683_data *data = nct6683_update_device(dev);
0797 int index = sattr->index;
0798 int nr = sattr->nr;
0799
0800 return sprintf(buf, "%d\n", data->temp[index][nr] * 1000);
0801 }
0802
0803 static ssize_t
0804 show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
0805 {
0806 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0807 struct nct6683_data *data = nct6683_update_device(dev);
0808 int nr = sattr->index;
0809 int temp = data->temp[1][nr] - data->temp[2][nr];
0810
0811 return sprintf(buf, "%d\n", temp * 1000);
0812 }
0813
0814 static ssize_t
0815 show_temp16(struct device *dev, struct device_attribute *attr, char *buf)
0816 {
0817 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0818 struct nct6683_data *data = nct6683_update_device(dev);
0819 int index = sattr->index;
0820
0821 return sprintf(buf, "%d\n", (data->temp_in[index] / 128) * 500);
0822 }
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834 static int get_temp_type(u8 src)
0835 {
0836 if (src >= 0x02 && src <= 0x07)
0837 return 3;
0838 else if (src >= 0x08 && src <= 0x18)
0839 return 4;
0840 else if (src >= 0x20 && src <= 0x2b)
0841 return 6;
0842 else if (src >= 0x42 && src <= 0x49)
0843 return 5;
0844
0845 return 0;
0846 }
0847
0848 static ssize_t
0849 show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
0850 {
0851 struct nct6683_data *data = nct6683_update_device(dev);
0852 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
0853 int nr = sattr->index;
0854 return sprintf(buf, "%d\n", get_temp_type(data->temp_src[nr]));
0855 }
0856
0857 static umode_t nct6683_temp_is_visible(struct kobject *kobj,
0858 struct attribute *attr, int index)
0859 {
0860 struct device *dev = kobj_to_dev(kobj);
0861 struct nct6683_data *data = dev_get_drvdata(dev);
0862 int temp = index / 7;
0863 int nr = index % 7;
0864
0865
0866
0867
0868
0869 if ((nr == 2 || nr == 4) &&
0870 data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
0871 return 0;
0872
0873 if (nr == 6 && get_temp_type(data->temp_src[temp]) == 0)
0874 return 0;
0875
0876 return attr->mode;
0877 }
0878
0879 SENSOR_TEMPLATE(temp_input, "temp%d_input", S_IRUGO, show_temp16, NULL, 0);
0880 SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
0881 SENSOR_TEMPLATE_2(temp_min, "temp%d_min", S_IRUGO, show_temp8, NULL, 0, 0);
0882 SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO, show_temp8, NULL, 0, 1);
0883 SENSOR_TEMPLATE(temp_max_hyst, "temp%d_max_hyst", S_IRUGO, show_temp_hyst, NULL,
0884 0);
0885 SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO, show_temp8, NULL, 0, 3);
0886 SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO, show_temp_type, NULL, 0);
0887
0888
0889
0890
0891
0892
0893 static struct sensor_device_template *nct6683_attributes_temp_template[] = {
0894 &sensor_dev_template_temp_input,
0895 &sensor_dev_template_temp_label,
0896 &sensor_dev_template_temp_min,
0897 &sensor_dev_template_temp_max,
0898 &sensor_dev_template_temp_max_hyst,
0899 &sensor_dev_template_temp_crit,
0900 &sensor_dev_template_temp_type,
0901 NULL
0902 };
0903
0904 static const struct sensor_template_group nct6683_temp_template_group = {
0905 .templates = nct6683_attributes_temp_template,
0906 .is_visible = nct6683_temp_is_visible,
0907 .base = 1,
0908 };
0909
0910 static ssize_t
0911 show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
0912 {
0913 struct nct6683_data *data = nct6683_update_device(dev);
0914 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
0915 int index = sattr->index;
0916
0917 return sprintf(buf, "%d\n", data->pwm[index]);
0918 }
0919
0920 static ssize_t
0921 store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
0922 size_t count)
0923 {
0924 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
0925 struct nct6683_data *data = dev_get_drvdata(dev);
0926 int index = sattr->index;
0927 unsigned long val;
0928
0929 if (kstrtoul(buf, 10, &val) || val > 255)
0930 return -EINVAL;
0931
0932 mutex_lock(&data->update_lock);
0933 nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_REQ);
0934 usleep_range(1000, 2000);
0935 nct6683_write(data, NCT6683_REG_PWM_WRITE(index), val);
0936 nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_DONE);
0937 mutex_unlock(&data->update_lock);
0938
0939 return count;
0940 }
0941
0942 SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, store_pwm, 0);
0943
0944 static umode_t nct6683_pwm_is_visible(struct kobject *kobj,
0945 struct attribute *attr, int index)
0946 {
0947 struct device *dev = kobj_to_dev(kobj);
0948 struct nct6683_data *data = dev_get_drvdata(dev);
0949 int pwm = index;
0950
0951 if (!(data->have_pwm & (1 << pwm)))
0952 return 0;
0953
0954
0955 if (data->customer_id == NCT6683_CUSTOMER_ID_MITAC)
0956 return attr->mode | S_IWUSR;
0957
0958 return attr->mode;
0959 }
0960
0961 static struct sensor_device_template *nct6683_attributes_pwm_template[] = {
0962 &sensor_dev_template_pwm,
0963 NULL
0964 };
0965
0966 static const struct sensor_template_group nct6683_pwm_template_group = {
0967 .templates = nct6683_attributes_pwm_template,
0968 .is_visible = nct6683_pwm_is_visible,
0969 .base = 1,
0970 };
0971
0972 static ssize_t
0973 beep_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
0974 {
0975 struct nct6683_data *data = dev_get_drvdata(dev);
0976 int ret;
0977 u8 reg;
0978
0979 mutex_lock(&data->update_lock);
0980
0981 ret = superio_enter(data->sioreg);
0982 if (ret)
0983 goto error;
0984 superio_select(data->sioreg, NCT6683_LD_HWM);
0985 reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
0986 superio_exit(data->sioreg);
0987
0988 mutex_unlock(&data->update_lock);
0989
0990 return sprintf(buf, "%u\n", !!(reg & NCT6683_CR_BEEP_MASK));
0991
0992 error:
0993 mutex_unlock(&data->update_lock);
0994 return ret;
0995 }
0996
0997 static ssize_t
0998 beep_enable_store(struct device *dev, struct device_attribute *attr,
0999 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);
1025 error:
1026 mutex_unlock(&data->update_lock);
1027 return count;
1028 }
1029
1030
1031
1032 static ssize_t
1033 intrusion0_alarm_show(struct device *dev, struct device_attribute *attr,
1034 char *buf)
1035 {
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
1053 error:
1054 mutex_unlock(&data->update_lock);
1055 return ret;
1056 }
1057
1058 static ssize_t
1059 intrusion0_alarm_store(struct device *dev, struct device_attribute *attr,
1060 const char *buf, size_t count)
1061 {
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
1074
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;
1092 error:
1093 mutex_unlock(&data->update_lock);
1094 return count;
1095 }
1096
1097 static DEVICE_ATTR_RW(intrusion0_alarm);
1098 static DEVICE_ATTR_RW(beep_enable);
1099
1100 static struct attribute *nct6683_attributes_other[] = {
1101 &dev_attr_intrusion0_alarm.attr,
1102 &dev_attr_beep_enable.attr,
1103 NULL
1104 };
1105
1106 static const struct attribute_group nct6683_group_other = {
1107 .attrs = nct6683_attributes_other,
1108 };
1109
1110
1111 static inline void nct6683_init_device(struct nct6683_data *data)
1112 {
1113 u8 tmp;
1114
1115
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
1123
1124
1125 static void
1126 nct6683_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
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161 static 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
1171 if (reg >= NUM_MON_LABELS)
1172 continue;
1173
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
1188 static 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;
1197 char build[16];
1198
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
1215
1216 switch (data->customer_id) {
1217 case NCT6683_CUSTOMER_ID_INTEL:
1218 break;
1219 case NCT6683_CUSTOMER_ID_MITAC:
1220 break;
1221 case NCT6683_CUSTOMER_ID_MSI:
1222 break;
1223 case NCT6683_CUSTOMER_ID_ASROCK:
1224 break;
1225 case NCT6683_CUSTOMER_ID_ASROCK2:
1226 break;
1227 default:
1228 if (!force)
1229 return -ENODEV;
1230 }
1231
1232 nct6683_init_device(data);
1233 nct6683_setup_fans(data);
1234 nct6683_setup_sensors(data);
1235
1236
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
1275 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",
1287 nct6683_chip_names[data->kind],
1288 nct6683_read(data, NCT6683_REG_VERSION_HI),
1289 nct6683_read(data, NCT6683_REG_VERSION_LO),
1290 build);
1291
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
1298 static 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
1309 static 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
1318 data->valid = false;
1319 mutex_unlock(&data->update_lock);
1320
1321 return 0;
1322 }
1323
1324 static 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
1335
1336 static struct platform_driver nct6683_driver = {
1337 .driver = {
1338 .name = DRVNAME,
1339 .pm = NCT6683_DEV_PM_OPS,
1340 },
1341 .probe = nct6683_probe,
1342 };
1343
1344 static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
1345 {
1346 int addr;
1347 u16 val;
1348 int err;
1349
1350 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;
1361 case SIO_NCT6686_ID:
1362 sio_data->kind = nct6686;
1363 break;
1364 case SIO_NCT6687_ID:
1365 sio_data->kind = nct6687;
1366 break;
1367 default:
1368 if (val != 0xffff)
1369 pr_debug("unsupported chip ID: 0x%04x\n", val);
1370 goto fail;
1371 }
1372
1373
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
1384 val = superio_inb(sioaddr, SIO_REG_ENABLE);
1385 if (!(val & 0x01)) {
1386 pr_warn("Forcibly enabling EC access. Data may be unusable.\n");
1387 superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
1388 }
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
1397 fail:
1398 superio_exit(sioaddr);
1399 return -ENODEV;
1400 }
1401
1402
1403
1404
1405
1406
1407
1408 static struct platform_device *pdev[2];
1409
1410 static 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
1425
1426
1427
1428
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;
1440 goto exit_device_unregister;
1441 }
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
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
1477 exit_device_put:
1478 platform_device_put(pdev[i]);
1479 exit_device_unregister:
1480 while (--i >= 0) {
1481 if (pdev[i])
1482 platform_device_unregister(pdev[i]);
1483 }
1484 exit_unregister:
1485 platform_driver_unregister(&nct6683_driver);
1486 return err;
1487 }
1488
1489 static 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
1500 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1501 MODULE_DESCRIPTION("NCT6683D driver");
1502 MODULE_LICENSE("GPL");
1503
1504 module_init(sensors_nct6683_init);
1505 module_exit(sensors_nct6683_exit);