Synchronize with upstream version
Also ensure the driver still builds with the latest upstream kernel. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
7
Makefile
7
Makefile
@@ -3,8 +3,8 @@ TARGET := $(shell uname -r)
|
|||||||
# Or specific version
|
# Or specific version
|
||||||
#TARGET := 2.6.33.5
|
#TARGET := 2.6.33.5
|
||||||
KERNEL_MODULES := /lib/modules/$(TARGET)
|
KERNEL_MODULES := /lib/modules/$(TARGET)
|
||||||
KERNEL_BUILD := $(KERNEL_MODULES)/build
|
# KERNEL_BUILD := $(KERNEL_MODULES)/build
|
||||||
# KERNEL_BUILD := /usr/src/linux-headers-$(TARGET)
|
KERNEL_BUILD := /usr/src/linux-headers-$(TARGET)
|
||||||
|
|
||||||
#SYSTEM_MAP := $(KERNEL_BUILD)/System.map
|
#SYSTEM_MAP := $(KERNEL_BUILD)/System.map
|
||||||
SYSTEM_MAP := /boot/System.map-$(TARGET)
|
SYSTEM_MAP := /boot/System.map-$(TARGET)
|
||||||
@@ -15,7 +15,8 @@ DRIVER := it87
|
|||||||
# the module:
|
# the module:
|
||||||
MOD_SUBDIR = drivers/hwmon
|
MOD_SUBDIR = drivers/hwmon
|
||||||
|
|
||||||
obj-m := $(DRIVER).o
|
obj-m := $(patsubst %,%.o,$(DRIVER))
|
||||||
|
obj-ko := $(patsubst %,%.ko,$(DRIVER))
|
||||||
|
|
||||||
MAKEFLAGS += --no-print-directory
|
MAKEFLAGS += --no-print-directory
|
||||||
|
|
||||||
|
4
compat.h
4
compat.h
@@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
#ifndef clamp_val
|
||||||
|
#define clamp_val SENSORS_LIMIT
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef request_muxed_region
|
#ifndef request_muxed_region
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
|
||||||
#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
|
#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
|
||||||
|
204
it87.c
204
it87.c
@@ -10,7 +10,9 @@
|
|||||||
* This driver supports only the Environment Controller in the IT8705F and
|
* This driver supports only the Environment Controller in the IT8705F and
|
||||||
* similar parts. The other devices are supported by different drivers.
|
* similar parts. The other devices are supported by different drivers.
|
||||||
*
|
*
|
||||||
* Supports: IT8705F Super I/O chip w/LPC interface
|
* Supports: IT8603E Super I/O chip w/LPC interface
|
||||||
|
* IT8623E Super I/O chip w/LPC interface
|
||||||
|
* IT8705F Super I/O chip w/LPC interface
|
||||||
* IT8712F Super I/O chip w/LPC interface
|
* IT8712F Super I/O chip w/LPC interface
|
||||||
* IT8716F Super I/O chip w/LPC interface
|
* IT8716F Super I/O chip w/LPC interface
|
||||||
* IT8718F Super I/O chip w/LPC interface
|
* IT8718F Super I/O chip w/LPC interface
|
||||||
@@ -19,12 +21,14 @@
|
|||||||
* IT8726F Super I/O chip w/LPC interface
|
* IT8726F Super I/O chip w/LPC interface
|
||||||
* IT8728F Super I/O chip w/LPC interface
|
* IT8728F Super I/O chip w/LPC interface
|
||||||
* IT8758E Super I/O chip w/LPC interface
|
* IT8758E Super I/O chip w/LPC interface
|
||||||
|
* IT8771E Super I/O chip w/LPC interface
|
||||||
|
* IT8772E Super I/O chip w/LPC interface
|
||||||
* IT8782F Super I/O chip w/LPC interface
|
* IT8782F Super I/O chip w/LPC interface
|
||||||
* IT8783E/F Super I/O chip w/LPC interface
|
* IT8783E/F Super I/O chip w/LPC interface
|
||||||
* Sis950 A clone of the IT8705F
|
* Sis950 A clone of the IT8705F
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001 Chris Gauthron
|
* Copyright (C) 2001 Chris Gauthron
|
||||||
* Copyright (C) 2005-2010 Jean Delvare <khali@linux-fr.org>
|
* Copyright (C) 2005-2010 Jean Delvare <jdelvare@suse.de>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -62,8 +66,8 @@
|
|||||||
|
|
||||||
#define DRVNAME "it87"
|
#define DRVNAME "it87"
|
||||||
|
|
||||||
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8782,
|
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771,
|
||||||
it8783 };
|
it8772, it8782, it8783, it8603 };
|
||||||
|
|
||||||
static unsigned short force_id;
|
static unsigned short force_id;
|
||||||
module_param(force_id, ushort, 0);
|
module_param(force_id, ushort, 0);
|
||||||
@@ -141,8 +145,12 @@ static inline void superio_exit(void)
|
|||||||
#define IT8721F_DEVID 0x8721
|
#define IT8721F_DEVID 0x8721
|
||||||
#define IT8726F_DEVID 0x8726
|
#define IT8726F_DEVID 0x8726
|
||||||
#define IT8728F_DEVID 0x8728
|
#define IT8728F_DEVID 0x8728
|
||||||
|
#define IT8771E_DEVID 0x8771
|
||||||
|
#define IT8772E_DEVID 0x8772
|
||||||
#define IT8782F_DEVID 0x8782
|
#define IT8782F_DEVID 0x8782
|
||||||
#define IT8783E_DEVID 0x8783
|
#define IT8783E_DEVID 0x8783
|
||||||
|
#define IT8603E_DEVID 0x8603
|
||||||
|
#define IT8623E_DEVID 0x8623
|
||||||
#define IT87_ACT_REG 0x30
|
#define IT87_ACT_REG 0x30
|
||||||
#define IT87_BASE_REG 0x60
|
#define IT87_BASE_REG 0x60
|
||||||
|
|
||||||
@@ -282,6 +290,24 @@ static const struct it87_devices it87_devices[] = {
|
|||||||
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
|
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
|
||||||
.peci_mask = 0x07,
|
.peci_mask = 0x07,
|
||||||
},
|
},
|
||||||
|
[it8771] = {
|
||||||
|
.name = "it8771",
|
||||||
|
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
|
||||||
|
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
|
||||||
|
/* PECI: guesswork */
|
||||||
|
/* 12mV ADC (OHM) */
|
||||||
|
/* 16 bit fans (OHM) */
|
||||||
|
.peci_mask = 0x07,
|
||||||
|
},
|
||||||
|
[it8772] = {
|
||||||
|
.name = "it8772",
|
||||||
|
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
|
||||||
|
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
|
||||||
|
/* PECI (coreboot) */
|
||||||
|
/* 12mV ADC (HWSensors4, OHM) */
|
||||||
|
/* 16 bit fans (HWSensors4, OHM) */
|
||||||
|
.peci_mask = 0x07,
|
||||||
|
},
|
||||||
[it8782] = {
|
[it8782] = {
|
||||||
.name = "it8782",
|
.name = "it8782",
|
||||||
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
|
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
|
||||||
@@ -294,6 +320,12 @@ static const struct it87_devices it87_devices[] = {
|
|||||||
| FEAT_TEMP_OLD_PECI,
|
| FEAT_TEMP_OLD_PECI,
|
||||||
.old_peci_mask = 0x4,
|
.old_peci_mask = 0x4,
|
||||||
},
|
},
|
||||||
|
[it8603] = {
|
||||||
|
.name = "it8603",
|
||||||
|
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
|
||||||
|
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
|
||||||
|
.peci_mask = 0x07,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS)
|
#define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS)
|
||||||
@@ -340,7 +372,7 @@ struct it87_data {
|
|||||||
unsigned long last_updated; /* In jiffies */
|
unsigned long last_updated; /* In jiffies */
|
||||||
|
|
||||||
u16 in_scaled; /* Internal voltage sensors are scaled */
|
u16 in_scaled; /* Internal voltage sensors are scaled */
|
||||||
u8 in[9][3]; /* [nr][0]=in, [1]=min, [2]=max */
|
u8 in[10][3]; /* [nr][0]=in, [1]=min, [2]=max */
|
||||||
u8 has_fan; /* Bitfield, fans enabled */
|
u8 has_fan; /* Bitfield, fans enabled */
|
||||||
u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */
|
u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */
|
||||||
u8 has_temp; /* Bitfield, temp sensors enabled */
|
u8 has_temp; /* Bitfield, temp sensors enabled */
|
||||||
@@ -385,7 +417,7 @@ static int adc_lsb(const struct it87_data *data, int nr)
|
|||||||
static u8 in_to_reg(const struct it87_data *data, int nr, long val)
|
static u8 in_to_reg(const struct it87_data *data, int nr, long val)
|
||||||
{
|
{
|
||||||
val = DIV_ROUND_CLOSEST(val, adc_lsb(data, nr));
|
val = DIV_ROUND_CLOSEST(val, adc_lsb(data, nr));
|
||||||
return SENSORS_LIMIT(val, 0, 255);
|
return clamp_val(val, 0, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int in_from_reg(const struct it87_data *data, int nr, int val)
|
static int in_from_reg(const struct it87_data *data, int nr, int val)
|
||||||
@@ -397,16 +429,15 @@ static inline u8 FAN_TO_REG(long rpm, int div)
|
|||||||
{
|
{
|
||||||
if (rpm == 0)
|
if (rpm == 0)
|
||||||
return 255;
|
return 255;
|
||||||
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
|
rpm = clamp_val(rpm, 1, 1000000);
|
||||||
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
|
return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
|
||||||
254);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u16 FAN16_TO_REG(long rpm)
|
static inline u16 FAN16_TO_REG(long rpm)
|
||||||
{
|
{
|
||||||
if (rpm == 0)
|
if (rpm == 0)
|
||||||
return 0xffff;
|
return 0xffff;
|
||||||
return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
|
return clamp_val((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 255 ? 0 : \
|
#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 255 ? 0 : \
|
||||||
@@ -415,8 +446,8 @@ static inline u16 FAN16_TO_REG(long rpm)
|
|||||||
#define FAN16_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
|
#define FAN16_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
|
||||||
1350000 / ((val) * 2))
|
1350000 / ((val) * 2))
|
||||||
|
|
||||||
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (((val) - 500) / 1000) : \
|
#define TEMP_TO_REG(val) (clamp_val(((val) < 0 ? (((val) - 500) / 1000) : \
|
||||||
((val) + 500) / 1000), -128, 127))
|
((val) + 500) / 1000), -128, 127))
|
||||||
#define TEMP_FROM_REG(val) ((val) * 1000)
|
#define TEMP_FROM_REG(val) ((val) * 1000)
|
||||||
|
|
||||||
static u8 pwm_to_reg(const struct it87_data *data, long val)
|
static u8 pwm_to_reg(const struct it87_data *data, long val)
|
||||||
@@ -457,7 +488,7 @@ static const unsigned int pwm_freq[8] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int it87_probe(struct platform_device *pdev);
|
static int it87_probe(struct platform_device *pdev);
|
||||||
static int __devexit it87_remove(struct platform_device *pdev);
|
static int it87_remove(struct platform_device *pdev);
|
||||||
|
|
||||||
static int it87_read_value(struct it87_data *data, u8 reg);
|
static int it87_read_value(struct it87_data *data, u8 reg);
|
||||||
static void it87_write_value(struct it87_data *data, u8 reg, u8 value);
|
static void it87_write_value(struct it87_data *data, u8 reg, u8 value);
|
||||||
@@ -468,11 +499,10 @@ static void it87_init_device(struct platform_device *pdev);
|
|||||||
|
|
||||||
static struct platform_driver it87_driver = {
|
static struct platform_driver it87_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.name = DRVNAME,
|
.name = DRVNAME,
|
||||||
},
|
},
|
||||||
.probe = it87_probe,
|
.probe = it87_probe,
|
||||||
.remove = __devexit_p(it87_remove),
|
.remove = it87_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
|
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
|
||||||
@@ -558,6 +588,7 @@ static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
|
|||||||
7, 2);
|
7, 2);
|
||||||
|
|
||||||
static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
|
static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
|
||||||
|
static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
|
||||||
|
|
||||||
/* 3 temperatures */
|
/* 3 temperatures */
|
||||||
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
|
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
|
||||||
@@ -714,7 +745,7 @@ static int pwm_mode(const struct it87_data *data, int nr)
|
|||||||
{
|
{
|
||||||
int ctrl = data->fan_main_ctrl & (1 << nr);
|
int ctrl = data->fan_main_ctrl & (1 << nr);
|
||||||
|
|
||||||
if (ctrl == 0) /* Full speed */
|
if (ctrl == 0 && data->type != it8603) /* Full speed */
|
||||||
return 0;
|
return 0;
|
||||||
if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
|
if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
|
||||||
return 2;
|
return 2;
|
||||||
@@ -909,6 +940,10 @@ static ssize_t set_pwm_enable(struct device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IT8603E does not have on/off mode */
|
||||||
|
if (val == 0 && data->type == it8603)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
mutex_lock(&data->update_lock);
|
||||||
|
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
@@ -928,10 +963,13 @@ static ssize_t set_pwm_enable(struct device *dev,
|
|||||||
else /* Automatic mode */
|
else /* Automatic mode */
|
||||||
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
|
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
|
||||||
it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
|
it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
|
||||||
/* set SmartGuardian mode */
|
|
||||||
data->fan_main_ctrl |= (1 << nr);
|
if (data->type != it8603) {
|
||||||
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
|
/* set SmartGuardian mode */
|
||||||
data->fan_main_ctrl);
|
data->fan_main_ctrl |= (1 << nr);
|
||||||
|
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
|
||||||
|
data->fan_main_ctrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&data->update_lock);
|
mutex_unlock(&data->update_lock);
|
||||||
@@ -1395,6 +1433,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
|
|||||||
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
|
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
|
||||||
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
|
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
|
||||||
static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
|
static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
|
||||||
|
/* special AVCC3 IT8603E in9 */
|
||||||
|
static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 0);
|
||||||
|
|
||||||
static ssize_t show_name(struct device *dev, struct device_attribute
|
static ssize_t show_name(struct device *dev, struct device_attribute
|
||||||
*devattr, char *buf)
|
*devattr, char *buf)
|
||||||
@@ -1404,7 +1444,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute
|
|||||||
}
|
}
|
||||||
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
|
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
|
||||||
|
|
||||||
static struct attribute *it87_attributes_in[9][5] = {
|
static struct attribute *it87_attributes_in[10][5] = {
|
||||||
{
|
{
|
||||||
&sensor_dev_attr_in0_input.dev_attr.attr,
|
&sensor_dev_attr_in0_input.dev_attr.attr,
|
||||||
&sensor_dev_attr_in0_min.dev_attr.attr,
|
&sensor_dev_attr_in0_min.dev_attr.attr,
|
||||||
@@ -1456,9 +1496,12 @@ static struct attribute *it87_attributes_in[9][5] = {
|
|||||||
}, {
|
}, {
|
||||||
&sensor_dev_attr_in8_input.dev_attr.attr,
|
&sensor_dev_attr_in8_input.dev_attr.attr,
|
||||||
NULL
|
NULL
|
||||||
|
}, {
|
||||||
|
&sensor_dev_attr_in9_input.dev_attr.attr,
|
||||||
|
NULL
|
||||||
} };
|
} };
|
||||||
|
|
||||||
static const struct attribute_group it87_group_in[9] = {
|
static const struct attribute_group it87_group_in[10] = {
|
||||||
{ .attrs = it87_attributes_in[0] },
|
{ .attrs = it87_attributes_in[0] },
|
||||||
{ .attrs = it87_attributes_in[1] },
|
{ .attrs = it87_attributes_in[1] },
|
||||||
{ .attrs = it87_attributes_in[2] },
|
{ .attrs = it87_attributes_in[2] },
|
||||||
@@ -1468,6 +1511,7 @@ static const struct attribute_group it87_group_in[9] = {
|
|||||||
{ .attrs = it87_attributes_in[6] },
|
{ .attrs = it87_attributes_in[6] },
|
||||||
{ .attrs = it87_attributes_in[7] },
|
{ .attrs = it87_attributes_in[7] },
|
||||||
{ .attrs = it87_attributes_in[8] },
|
{ .attrs = it87_attributes_in[8] },
|
||||||
|
{ .attrs = it87_attributes_in[9] },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct attribute *it87_attributes_temp[3][6] = {
|
static struct attribute *it87_attributes_temp[3][6] = {
|
||||||
@@ -1526,7 +1570,8 @@ static struct attribute *it87_attributes_in_beep[] = {
|
|||||||
&sensor_dev_attr_in5_beep.dev_attr.attr,
|
&sensor_dev_attr_in5_beep.dev_attr.attr,
|
||||||
&sensor_dev_attr_in6_beep.dev_attr.attr,
|
&sensor_dev_attr_in6_beep.dev_attr.attr,
|
||||||
&sensor_dev_attr_in7_beep.dev_attr.attr,
|
&sensor_dev_attr_in7_beep.dev_attr.attr,
|
||||||
NULL
|
NULL,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct attribute *it87_attributes_temp_beep[] = {
|
static struct attribute *it87_attributes_temp_beep[] = {
|
||||||
@@ -1665,6 +1710,7 @@ static struct attribute *it87_attributes_label[] = {
|
|||||||
&sensor_dev_attr_in3_label.dev_attr.attr,
|
&sensor_dev_attr_in3_label.dev_attr.attr,
|
||||||
&sensor_dev_attr_in7_label.dev_attr.attr,
|
&sensor_dev_attr_in7_label.dev_attr.attr,
|
||||||
&sensor_dev_attr_in8_label.dev_attr.attr,
|
&sensor_dev_attr_in8_label.dev_attr.attr,
|
||||||
|
&sensor_dev_attr_in9_label.dev_attr.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1710,12 +1756,22 @@ static int __init it87_find(unsigned short *address,
|
|||||||
case IT8728F_DEVID:
|
case IT8728F_DEVID:
|
||||||
sio_data->type = it8728;
|
sio_data->type = it8728;
|
||||||
break;
|
break;
|
||||||
|
case IT8771E_DEVID:
|
||||||
|
sio_data->type = it8771;
|
||||||
|
break;
|
||||||
|
case IT8772E_DEVID:
|
||||||
|
sio_data->type = it8772;
|
||||||
|
break;
|
||||||
case IT8782F_DEVID:
|
case IT8782F_DEVID:
|
||||||
sio_data->type = it8782;
|
sio_data->type = it8782;
|
||||||
break;
|
break;
|
||||||
case IT8783E_DEVID:
|
case IT8783E_DEVID:
|
||||||
sio_data->type = it8783;
|
sio_data->type = it8783;
|
||||||
break;
|
break;
|
||||||
|
case IT8603E_DEVID:
|
||||||
|
case IT8623E_DEVID:
|
||||||
|
sio_data->type = it8603;
|
||||||
|
break;
|
||||||
case 0xffff: /* No device at all */
|
case 0xffff: /* No device at all */
|
||||||
goto exit;
|
goto exit;
|
||||||
default:
|
default:
|
||||||
@@ -1737,11 +1793,16 @@ static int __init it87_find(unsigned short *address,
|
|||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
sio_data->revision = superio_inb(DEVREV) & 0x0f;
|
sio_data->revision = superio_inb(DEVREV) & 0x0f;
|
||||||
pr_info("Found IT%04xF chip at 0x%x, revision %d\n",
|
pr_info("Found IT%04x%c chip at 0x%x, revision %d\n", chip_type,
|
||||||
chip_type, *address, sio_data->revision);
|
chip_type == 0x8771 || chip_type == 0x8772 ||
|
||||||
|
chip_type == 0x8603 ? 'E' : 'F', *address,
|
||||||
|
sio_data->revision);
|
||||||
|
|
||||||
/* in8 (Vbat) is always internal */
|
/* in8 (Vbat) is always internal */
|
||||||
sio_data->internal = (1 << 2);
|
sio_data->internal = (1 << 2);
|
||||||
|
/* Only the IT8603E has in9 */
|
||||||
|
if (sio_data->type != it8603)
|
||||||
|
sio_data->skip_in |= (1 << 9);
|
||||||
|
|
||||||
/* Read GPIO config and VID value from LDN 7 (GPIO) */
|
/* Read GPIO config and VID value from LDN 7 (GPIO) */
|
||||||
if (sio_data->type == it87) {
|
if (sio_data->type == it87) {
|
||||||
@@ -1752,7 +1813,7 @@ static int __init it87_find(unsigned short *address,
|
|||||||
superio_select(5);
|
superio_select(5);
|
||||||
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
||||||
} else if (sio_data->type == it8783) {
|
} else if (sio_data->type == it8783) {
|
||||||
int reg25, reg27, reg2A, reg2C, regEF;
|
int reg25, reg27, reg2a, reg2c, regef;
|
||||||
|
|
||||||
sio_data->skip_vid = 1; /* No VID */
|
sio_data->skip_vid = 1; /* No VID */
|
||||||
|
|
||||||
@@ -1760,15 +1821,15 @@ static int __init it87_find(unsigned short *address,
|
|||||||
|
|
||||||
reg25 = superio_inb(IT87_SIO_GPIO1_REG);
|
reg25 = superio_inb(IT87_SIO_GPIO1_REG);
|
||||||
reg27 = superio_inb(IT87_SIO_GPIO3_REG);
|
reg27 = superio_inb(IT87_SIO_GPIO3_REG);
|
||||||
reg2A = superio_inb(IT87_SIO_PINX1_REG);
|
reg2a = superio_inb(IT87_SIO_PINX1_REG);
|
||||||
reg2C = superio_inb(IT87_SIO_PINX2_REG);
|
reg2c = superio_inb(IT87_SIO_PINX2_REG);
|
||||||
regEF = superio_inb(IT87_SIO_SPI_REG);
|
regef = superio_inb(IT87_SIO_SPI_REG);
|
||||||
|
|
||||||
/* Check if fan3 is there or not */
|
/* Check if fan3 is there or not */
|
||||||
if ((reg27 & (1 << 0)) || !(reg2C & (1 << 2)))
|
if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2)))
|
||||||
sio_data->skip_fan |= (1 << 2);
|
sio_data->skip_fan |= (1 << 2);
|
||||||
if ((reg25 & (1 << 4))
|
if ((reg25 & (1 << 4))
|
||||||
|| (!(reg2A & (1 << 1)) && (regEF & (1 << 0))))
|
|| (!(reg2a & (1 << 1)) && (regef & (1 << 0))))
|
||||||
sio_data->skip_pwm |= (1 << 2);
|
sio_data->skip_pwm |= (1 << 2);
|
||||||
|
|
||||||
/* Check if fan2 is there or not */
|
/* Check if fan2 is there or not */
|
||||||
@@ -1778,7 +1839,7 @@ static int __init it87_find(unsigned short *address,
|
|||||||
sio_data->skip_pwm |= (1 << 1);
|
sio_data->skip_pwm |= (1 << 1);
|
||||||
|
|
||||||
/* VIN5 */
|
/* VIN5 */
|
||||||
if ((reg27 & (1 << 0)) || (reg2C & (1 << 2)))
|
if ((reg27 & (1 << 0)) || (reg2c & (1 << 2)))
|
||||||
sio_data->skip_in |= (1 << 5); /* No VIN5 */
|
sio_data->skip_in |= (1 << 5); /* No VIN5 */
|
||||||
|
|
||||||
/* VIN6 */
|
/* VIN6 */
|
||||||
@@ -1803,22 +1864,53 @@ static int __init it87_find(unsigned short *address,
|
|||||||
* not the case, and ask the user to report if the
|
* not the case, and ask the user to report if the
|
||||||
* resulting voltage is sane.
|
* resulting voltage is sane.
|
||||||
*/
|
*/
|
||||||
if (!(reg2C & (1 << 1))) {
|
if (!(reg2c & (1 << 1))) {
|
||||||
reg2C |= (1 << 1);
|
reg2c |= (1 << 1);
|
||||||
superio_outb(IT87_SIO_PINX2_REG, reg2C);
|
superio_outb(IT87_SIO_PINX2_REG, reg2c);
|
||||||
pr_notice("Routing internal VCCH5V to in7.\n");
|
pr_notice("Routing internal VCCH5V to in7.\n");
|
||||||
}
|
}
|
||||||
pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n");
|
pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n");
|
||||||
pr_notice("Please report if it displays a reasonable voltage.\n");
|
pr_notice("Please report if it displays a reasonable voltage.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg2C & (1 << 0))
|
if (reg2c & (1 << 0))
|
||||||
sio_data->internal |= (1 << 0);
|
sio_data->internal |= (1 << 0);
|
||||||
if (reg2C & (1 << 1))
|
if (reg2c & (1 << 1))
|
||||||
sio_data->internal |= (1 << 1);
|
sio_data->internal |= (1 << 1);
|
||||||
|
|
||||||
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
||||||
|
} else if (sio_data->type == it8603) {
|
||||||
|
int reg27, reg29;
|
||||||
|
|
||||||
|
sio_data->skip_vid = 1; /* No VID */
|
||||||
|
superio_select(GPIO);
|
||||||
|
|
||||||
|
reg27 = superio_inb(IT87_SIO_GPIO3_REG);
|
||||||
|
|
||||||
|
/* Check if fan3 is there or not */
|
||||||
|
if (reg27 & (1 << 6))
|
||||||
|
sio_data->skip_pwm |= (1 << 2);
|
||||||
|
if (reg27 & (1 << 7))
|
||||||
|
sio_data->skip_fan |= (1 << 2);
|
||||||
|
|
||||||
|
/* Check if fan2 is there or not */
|
||||||
|
reg29 = superio_inb(IT87_SIO_GPIO5_REG);
|
||||||
|
if (reg29 & (1 << 1))
|
||||||
|
sio_data->skip_pwm |= (1 << 1);
|
||||||
|
if (reg29 & (1 << 2))
|
||||||
|
sio_data->skip_fan |= (1 << 1);
|
||||||
|
|
||||||
|
sio_data->skip_in |= (1 << 5); /* No VIN5 */
|
||||||
|
sio_data->skip_in |= (1 << 6); /* No VIN6 */
|
||||||
|
|
||||||
|
/* no fan4 */
|
||||||
|
sio_data->skip_pwm |= (1 << 3);
|
||||||
|
sio_data->skip_fan |= (1 << 3);
|
||||||
|
|
||||||
|
sio_data->internal |= (1 << 1); /* in7 is VSB */
|
||||||
|
sio_data->internal |= (1 << 3); /* in9 is AVCC */
|
||||||
|
|
||||||
|
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
||||||
} else {
|
} else {
|
||||||
int reg;
|
int reg;
|
||||||
bool uart6;
|
bool uart6;
|
||||||
@@ -1827,10 +1919,11 @@ static int __init it87_find(unsigned short *address,
|
|||||||
|
|
||||||
reg = superio_inb(IT87_SIO_GPIO3_REG);
|
reg = superio_inb(IT87_SIO_GPIO3_REG);
|
||||||
if (sio_data->type == it8721 || sio_data->type == it8728 ||
|
if (sio_data->type == it8721 || sio_data->type == it8728 ||
|
||||||
|
sio_data->type == it8771 || sio_data->type == it8772 ||
|
||||||
sio_data->type == it8782) {
|
sio_data->type == it8782) {
|
||||||
/*
|
/*
|
||||||
* IT8721F/IT8758E, and IT8782F don't have VID pins
|
* IT8721F/IT8758E, and IT8782F don't have VID pins
|
||||||
* at all, not sure about the IT8728F.
|
* at all, not sure about the IT8728F and compatibles.
|
||||||
*/
|
*/
|
||||||
sio_data->skip_vid = 1;
|
sio_data->skip_vid = 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -1884,7 +1977,9 @@ static int __init it87_find(unsigned short *address,
|
|||||||
if (reg & (1 << 0))
|
if (reg & (1 << 0))
|
||||||
sio_data->internal |= (1 << 0);
|
sio_data->internal |= (1 << 0);
|
||||||
if ((reg & (1 << 1)) || sio_data->type == it8721 ||
|
if ((reg & (1 << 1)) || sio_data->type == it8721 ||
|
||||||
sio_data->type == it8728)
|
sio_data->type == it8728 ||
|
||||||
|
sio_data->type == it8771 ||
|
||||||
|
sio_data->type == it8772)
|
||||||
sio_data->internal |= (1 << 1);
|
sio_data->internal |= (1 << 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1933,11 +2028,11 @@ exit:
|
|||||||
static void it87_remove_files(struct device *dev)
|
static void it87_remove_files(struct device *dev)
|
||||||
{
|
{
|
||||||
struct it87_data *data = platform_get_drvdata(pdev);
|
struct it87_data *data = platform_get_drvdata(pdev);
|
||||||
struct it87_sio_data *sio_data = dev->platform_data;
|
struct it87_sio_data *sio_data = dev_get_platdata(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sysfs_remove_group(&dev->kobj, &it87_group);
|
sysfs_remove_group(&dev->kobj, &it87_group);
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
if (sio_data->skip_in & (1 << i))
|
if (sio_data->skip_in & (1 << i))
|
||||||
continue;
|
continue;
|
||||||
sysfs_remove_group(&dev->kobj, &it87_group_in[i]);
|
sysfs_remove_group(&dev->kobj, &it87_group_in[i]);
|
||||||
@@ -1980,12 +2075,12 @@ static void it87_remove_files(struct device *dev)
|
|||||||
sysfs_remove_group(&dev->kobj, &it87_group_label);
|
sysfs_remove_group(&dev->kobj, &it87_group_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit it87_probe(struct platform_device *pdev)
|
static int it87_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct it87_data *data;
|
struct it87_data *data;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct it87_sio_data *sio_data = dev->platform_data;
|
struct it87_sio_data *sio_data = dev_get_platdata(dev);
|
||||||
int err = 0, i;
|
int err = 0, i;
|
||||||
int enable_pwm_interface;
|
int enable_pwm_interface;
|
||||||
int fan_beep_need_rw;
|
int fan_beep_need_rw;
|
||||||
@@ -2051,6 +2146,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
|||||||
data->in_scaled |= (1 << 7); /* in7 is VSB */
|
data->in_scaled |= (1 << 7); /* in7 is VSB */
|
||||||
if (sio_data->internal & (1 << 2))
|
if (sio_data->internal & (1 << 2))
|
||||||
data->in_scaled |= (1 << 8); /* in8 is Vbat */
|
data->in_scaled |= (1 << 8); /* in8 is Vbat */
|
||||||
|
if (sio_data->internal & (1 << 3))
|
||||||
|
data->in_scaled |= (1 << 9); /* in9 is AVCC */
|
||||||
} else if (sio_data->type == it8782 || sio_data->type == it8783) {
|
} else if (sio_data->type == it8782 || sio_data->type == it8783) {
|
||||||
if (sio_data->internal & (1 << 0))
|
if (sio_data->internal & (1 << 0))
|
||||||
data->in_scaled |= (1 << 3); /* in3 is VCC5V */
|
data->in_scaled |= (1 << 3); /* in3 is VCC5V */
|
||||||
@@ -2073,7 +2170,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
for (i = 0; i < 9; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
if (sio_data->skip_in & (1 << i))
|
if (sio_data->skip_in & (1 << i))
|
||||||
continue;
|
continue;
|
||||||
err = sysfs_create_group(&dev->kobj, &it87_group_in[i]);
|
err = sysfs_create_group(&dev->kobj, &it87_group_in[i]);
|
||||||
@@ -2173,7 +2270,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Export labels for internal sensors */
|
/* Export labels for internal sensors */
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (!(sio_data->internal & (1 << i)))
|
if (!(sio_data->internal & (1 << i)))
|
||||||
continue;
|
continue;
|
||||||
err = sysfs_create_file(&dev->kobj,
|
err = sysfs_create_file(&dev->kobj,
|
||||||
@@ -2195,7 +2292,7 @@ error:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit it87_remove(struct platform_device *pdev)
|
static int it87_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct it87_data *data = platform_get_drvdata(pdev);
|
struct it87_data *data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
@@ -2228,7 +2325,7 @@ static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if and only if the PWM interface is safe to use */
|
/* Return 1 if and only if the PWM interface is safe to use */
|
||||||
static int __devinit it87_check_pwm(struct device *dev)
|
static int it87_check_pwm(struct device *dev)
|
||||||
{
|
{
|
||||||
struct it87_data *data = dev_get_drvdata(dev);
|
struct it87_data *data = dev_get_drvdata(dev);
|
||||||
/*
|
/*
|
||||||
@@ -2285,9 +2382,9 @@ static int __devinit it87_check_pwm(struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Called when we have found a new IT87. */
|
/* Called when we have found a new IT87. */
|
||||||
static void __devinit it87_init_device(struct platform_device *pdev)
|
static void it87_init_device(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct it87_sio_data *sio_data = pdev->dev.platform_data;
|
struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev);
|
||||||
struct it87_data *data = platform_get_drvdata(pdev);
|
struct it87_data *data = platform_get_drvdata(pdev);
|
||||||
int tmp, i;
|
int tmp, i;
|
||||||
u8 mask;
|
u8 mask;
|
||||||
@@ -2354,8 +2451,9 @@ static void __devinit it87_init_device(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
|
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
|
||||||
|
|
||||||
/* Set tachometers to 16-bit mode if needed */
|
/* Set tachometers to 16-bit mode if needed, IT8603E (and IT8728F?)
|
||||||
if (has_16bit_fans(data)) {
|
* has it by default */
|
||||||
|
if (has_16bit_fans(data) && data->type != it8603) {
|
||||||
tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
|
tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
|
||||||
if (~tmp & 0x07 & data->has_fan) {
|
if (~tmp & 0x07 & data->has_fan) {
|
||||||
dev_dbg(&pdev->dev,
|
dev_dbg(&pdev->dev,
|
||||||
@@ -2435,6 +2533,8 @@ static struct it87_data *it87_update_device(struct device *dev)
|
|||||||
}
|
}
|
||||||
/* in8 (battery) has no limit registers */
|
/* in8 (battery) has no limit registers */
|
||||||
data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8));
|
data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8));
|
||||||
|
if (data->type == it8603)
|
||||||
|
data->in[9][0] = it87_read_value(data, 0x2f);
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
/* Skip disabled fans */
|
/* Skip disabled fans */
|
||||||
@@ -2591,7 +2691,7 @@ static void __exit sm_it87_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Chris Gauthron, Jean Delvare <khali@linux-fr.org>");
|
MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>");
|
||||||
MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
|
MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
|
||||||
module_param(update_vbat, bool, 0);
|
module_param(update_vbat, bool, 0);
|
||||||
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
|
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
|
||||||
|
Reference in New Issue
Block a user