Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6

* 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6:
  hwmon: needs new maintainer
  hwmon: (lm85) Simplify device initialization function
  hwmon: (lm85) Misc cleanups
  hwmon: (lm85) Don't write back cached values
  hwmon: (lm85) Drop dead code
  hwmon: (lm85) Coding-style cleanups
  hwmon: (lm75) add new-style driver binding
  hwmon: (lm75) cleanup/reorg
  hwmon: (adt7473) clarify an awkward bit of code
  hwmon: (adt7473) Remove unused defines
  hwmon: (dme1737) fix voltage scaling
  hwmon: (dme1737) probe all addresses
  hwmon: (dme1737) demacrofy for readability
This commit is contained in:
Linus Torvalds 2008-08-01 11:33:19 -07:00
commit 6760561324
8 changed files with 690 additions and 619 deletions

View File

@ -22,6 +22,10 @@ Module Parameters
and PWM output control functions. Using this parameter
shouldn't be required since the BIOS usually takes care
of this.
* probe_all_addr: bool Include non-standard LPC addresses 0x162e and 0x164e
when probing for ISA devices. This is required for the
following boards:
- VIA EPIA SN18000
Note that there is no need to use this parameter if the driver loads without
complaining. The driver will say so if it is necessary.

View File

@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has
confirmed this "bug". The ADT7463 is reported to work as described in the
documentation. The current lm85 driver does not show the offset register.
The ADT7463 has a THERM asserted counter. This counter has a 22.76ms
resolution and a range of 5.8 seconds. The driver implements a 32-bit
accumulator of the counter value to extend the range to over a year. The
counter will stay at it's max value until read.
See the vendor datasheets for more information. There is application note
from National (AN-1260) with some additional information about the LM85.
The Analog Devices datasheet is very detailed and describes a procedure for
@ -206,13 +201,15 @@ Configuration choices:
The National LM85's have two vendor specific configuration
features. Tach. mode and Spinup Control. For more details on these,
see the LM85 datasheet or Application Note AN-1260.
see the LM85 datasheet or Application Note AN-1260. These features
are not currently supported by the lm85 driver.
The Analog Devices ADM1027 has several vendor specific enhancements.
The number of pulses-per-rev of the fans can be set, Tach monitoring
can be optimized for PWM operation, and an offset can be applied to
the temperatures to compensate for systemic errors in the
measurements.
measurements. These features are not currently supported by the lm85
driver.
In addition to the ADM1027 features, the ADT7463 also has Tmin control
and THERM asserted counts. Automatic Tmin control acts to adjust the

View File

@ -1878,13 +1878,9 @@ W: http://gigaset307x.sourceforge.net/
S: Maintained
HARDWARE MONITORING
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release
S: Maintained
S: Orphaned
HARDWARE RANDOM NUMBER GENERATOR CORE
S: Orphaned

View File

@ -394,13 +394,24 @@ config SENSORS_LM75
tristate "National Semiconductor LM75 and compatibles"
depends on I2C
help
If you say yes here you get support for National Semiconductor LM75
sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
9-bit precision mode), and TelCom (now Microchip) TCN75.
If you say yes here you get support for one common type of
temperature sensor chip, with models including:
The DS75 and DS1775 in 10- to 12-bit precision modes will require
a force module parameter. The driver will not handle the extra
precision anyhow.
- Dallas Semiconductor DS75 and DS1775
- Maxim MAX6625 and MAX6626
- Microchip MCP980x
- National Semiconductor LM75
- NXP's LM75A
- ST Microelectronics STDS75
- TelCom (now Microchip) TCN75
- Texas Instruments TMP100, TMP101, TMP75, TMP175, TMP275
This driver supports driver model based binding through board
specific I2C device tables.
It also supports the "legacy" style of driver binding. To use
that with some chips which don't replicate LM75 quirks exactly,
you may need the "force" module parameter.
This driver can also be built as a module. If so, the module
will be called lm75.

View File

@ -39,32 +39,20 @@ I2C_CLIENT_INSMOD_1(adt7473);
#define ADT7473_REG_BASE_ADDR 0x20
#define ADT7473_REG_VOLT_BASE_ADDR 0x21
#define ADT7473_REG_VOLT_MAX_ADDR 0x22
#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46
#define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49
#define ADT7473_REG_TEMP_BASE_ADDR 0x25
#define ADT7473_REG_TEMP_MAX_ADDR 0x27
#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E
#define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53
#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67
#define ADT7473_REG_TEMP_TMIN_MAX_ADDR 0x69
#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A
#define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C
#define ADT7473_REG_FAN_BASE_ADDR 0x28
#define ADT7473_REG_FAN_MAX_ADDR 0x2F
#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54
#define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B
#define ADT7473_REG_PWM_BASE_ADDR 0x30
#define ADT7473_REG_PWM_MAX_ADDR 0x32
#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64
#define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66
#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38
#define ADT7473_REG_PWM_MAX_MAX_ADDR 0x3A
#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C
#define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E
#define ADT7473_PWM_BHVR_MASK 0xE0
#define ADT7473_PWM_BHVR_SHIFT 5
@ -102,7 +90,6 @@ I2C_CLIENT_INSMOD_1(adt7473);
#define ADT7473_FAN4_ALARM 0x20
#define ADT7473_R1T_SHORT 0x40
#define ADT7473_R2T_SHORT 0x80
#define ADT7473_REG_MAX_ADDR 0x80
#define ALARM2(x) ((x) << 8)
@ -583,10 +570,9 @@ static ssize_t set_max_duty_at_crit(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct adt7473_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10);
temp = temp && 0xFF;
mutex_lock(&data->lock);
data->max_duty_at_overheat = temp;
data->max_duty_at_overheat = !!temp;
reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
if (temp)
reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;

View File

@ -48,6 +48,11 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
static int probe_all_addr;
module_param(probe_all_addr, bool, 0);
MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC "
"addresses");
/* Addresses to scan */
static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
@ -176,6 +181,7 @@ struct dme1737_data {
int valid; /* !=0 if following fields are valid */
unsigned long last_update; /* in jiffies */
unsigned long last_vbat; /* in jiffies */
enum chips type;
u8 vid;
u8 pwm_rr_en;
@ -210,20 +216,27 @@ struct dme1737_data {
};
/* Nominal voltage values */
static const int IN_NOMINAL[] = {5000, 2250, 3300, 5000, 12000, 3300, 3300};
static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300,
3300};
static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
3300};
#define IN_NOMINAL(ix, type) (((type) == dme1737) ? \
IN_NOMINAL_DME1737[(ix)] : \
IN_NOMINAL_SCH311x[(ix)])
/* Voltage input
* Voltage inputs have 16 bits resolution, limit values have 8 bits
* resolution. */
static inline int IN_FROM_REG(int reg, int ix, int res)
static inline int IN_FROM_REG(int reg, int ix, int res, int type)
{
return (reg * IN_NOMINAL[ix] + (3 << (res - 3))) / (3 << (res - 2));
return (reg * IN_NOMINAL(ix, type) + (3 << (res - 3))) /
(3 << (res - 2));
}
static inline int IN_TO_REG(int val, int ix)
static inline int IN_TO_REG(int val, int ix, int type)
{
return SENSORS_LIMIT((val * 192 + IN_NOMINAL[ix] / 2) /
IN_NOMINAL[ix], 0, 255);
return SENSORS_LIMIT((val * 192 + IN_NOMINAL(ix, type) / 2) /
IN_NOMINAL(ix, type), 0, 255);
}
/* Temperature input
@ -722,13 +735,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
switch (fn) {
case SYS_IN_INPUT:
res = IN_FROM_REG(data->in[ix], ix, 16);
res = IN_FROM_REG(data->in[ix], ix, 16, data->type);
break;
case SYS_IN_MIN:
res = IN_FROM_REG(data->in_min[ix], ix, 8);
res = IN_FROM_REG(data->in_min[ix], ix, 8, data->type);
break;
case SYS_IN_MAX:
res = IN_FROM_REG(data->in_max[ix], ix, 8);
res = IN_FROM_REG(data->in_max[ix], ix, 8, data->type);
break;
case SYS_IN_ALARM:
res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01;
@ -755,12 +768,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->update_lock);
switch (fn) {
case SYS_IN_MIN:
data->in_min[ix] = IN_TO_REG(val, ix);
data->in_min[ix] = IN_TO_REG(val, ix, data->type);
dme1737_write(client, DME1737_REG_IN_MIN(ix),
data->in_min[ix]);
break;
case SYS_IN_MAX:
data->in_max[ix] = IN_TO_REG(val, ix);
data->in_max[ix] = IN_TO_REG(val, ix, data->type);
dme1737_write(client, DME1737_REG_IN_MAX(ix),
data->in_max[ix]);
break;
@ -1501,9 +1514,9 @@ SENSOR_DEVICE_ATTR_PWM_1TO3(3);
/* PWMs 5-6 */
#define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \
static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \
static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \
show_pwm, set_pwm, SYS_PWM, ix-1); \
static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \
static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \
show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
show_pwm, NULL, SYS_PWM_ENABLE, ix-1)
@ -1517,91 +1530,75 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */
#define SENSOR_DEV_ATTR_IN(ix) \
&sensor_dev_attr_in##ix##_input.dev_attr.attr, \
&sensor_dev_attr_in##ix##_min.dev_attr.attr, \
&sensor_dev_attr_in##ix##_max.dev_attr.attr, \
&sensor_dev_attr_in##ix##_alarm.dev_attr.attr
/* These attributes are read-writeable only if the chip is *not* locked */
#define SENSOR_DEV_ATTR_TEMP_LOCK(ix) \
&sensor_dev_attr_temp##ix##_offset.dev_attr.attr
#define SENSOR_DEV_ATTR_TEMP(ix) \
SENSOR_DEV_ATTR_TEMP_LOCK(ix), \
&sensor_dev_attr_temp##ix##_input.dev_attr.attr, \
&sensor_dev_attr_temp##ix##_min.dev_attr.attr, \
&sensor_dev_attr_temp##ix##_max.dev_attr.attr, \
&sensor_dev_attr_temp##ix##_alarm.dev_attr.attr, \
&sensor_dev_attr_temp##ix##_fault.dev_attr.attr
/* These attributes are read-writeable only if the chip is *not* locked */
#define SENSOR_DEV_ATTR_ZONE_LOCK(ix) \
&sensor_dev_attr_zone##ix##_auto_point1_temp_hyst.dev_attr.attr, \
&sensor_dev_attr_zone##ix##_auto_point1_temp.dev_attr.attr, \
&sensor_dev_attr_zone##ix##_auto_point2_temp.dev_attr.attr, \
&sensor_dev_attr_zone##ix##_auto_point3_temp.dev_attr.attr
#define SENSOR_DEV_ATTR_ZONE(ix) \
SENSOR_DEV_ATTR_ZONE_LOCK(ix), \
&sensor_dev_attr_zone##ix##_auto_channels_temp.dev_attr.attr
#define SENSOR_DEV_ATTR_FAN_1TO4(ix) \
&sensor_dev_attr_fan##ix##_input.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_min.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_type.dev_attr.attr
#define SENSOR_DEV_ATTR_FAN_5TO6(ix) \
&sensor_dev_attr_fan##ix##_input.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_min.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \
&sensor_dev_attr_fan##ix##_max.dev_attr.attr
/* These attributes are read-writeable only if the chip is *not* locked */
#define SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix) \
&sensor_dev_attr_pwm##ix##_freq.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_enable.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_ramp_rate.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_auto_channels_zone.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_auto_pwm_min.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_auto_point1_pwm.dev_attr.attr
#define SENSOR_DEV_ATTR_PWM_1TO3(ix) \
SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix), \
&sensor_dev_attr_pwm##ix.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_auto_point2_pwm.dev_attr.attr
/* These attributes are read-writeable only if the chip is *not* locked */
#define SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix) \
&sensor_dev_attr_pwm##ix.dev_attr.attr, \
&sensor_dev_attr_pwm##ix##_freq.dev_attr.attr
#define SENSOR_DEV_ATTR_PWM_5TO6(ix) \
SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix), \
&sensor_dev_attr_pwm##ix##_enable.dev_attr.attr
/* This struct holds all the attributes that are always present and need to be
* created unconditionally. The attributes that need modification of their
* permissions are created read-only and write permissions are added or removed
* on the fly when required */
static struct attribute *dme1737_attr[] ={
/* Voltages */
SENSOR_DEV_ATTR_IN(0),
SENSOR_DEV_ATTR_IN(1),
SENSOR_DEV_ATTR_IN(2),
SENSOR_DEV_ATTR_IN(3),
SENSOR_DEV_ATTR_IN(4),
SENSOR_DEV_ATTR_IN(5),
SENSOR_DEV_ATTR_IN(6),
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
&sensor_dev_attr_in0_alarm.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
&sensor_dev_attr_in1_max.dev_attr.attr,
&sensor_dev_attr_in1_alarm.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_in2_min.dev_attr.attr,
&sensor_dev_attr_in2_max.dev_attr.attr,
&sensor_dev_attr_in2_alarm.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_in3_min.dev_attr.attr,
&sensor_dev_attr_in3_max.dev_attr.attr,
&sensor_dev_attr_in3_alarm.dev_attr.attr,
&sensor_dev_attr_in4_input.dev_attr.attr,
&sensor_dev_attr_in4_min.dev_attr.attr,
&sensor_dev_attr_in4_max.dev_attr.attr,
&sensor_dev_attr_in4_alarm.dev_attr.attr,
&sensor_dev_attr_in5_input.dev_attr.attr,
&sensor_dev_attr_in5_min.dev_attr.attr,
&sensor_dev_attr_in5_max.dev_attr.attr,
&sensor_dev_attr_in5_alarm.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
&sensor_dev_attr_in6_min.dev_attr.attr,
&sensor_dev_attr_in6_max.dev_attr.attr,
&sensor_dev_attr_in6_alarm.dev_attr.attr,
/* Temperatures */
SENSOR_DEV_ATTR_TEMP(1),
SENSOR_DEV_ATTR_TEMP(2),
SENSOR_DEV_ATTR_TEMP(3),
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_fault.dev_attr.attr,
&sensor_dev_attr_temp1_offset.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_min.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp2_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp2_offset.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_min.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
&sensor_dev_attr_temp3_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp3_offset.dev_attr.attr,
/* Zones */
SENSOR_DEV_ATTR_ZONE(1),
SENSOR_DEV_ATTR_ZONE(2),
SENSOR_DEV_ATTR_ZONE(3),
&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr,
/* Misc */
&dev_attr_vrm.attr,
&dev_attr_cpu0_vid.attr,
@ -1616,23 +1613,48 @@ static const struct attribute_group dme1737_group = {
* Their creation depends on the chip configuration which is determined during
* module load. */
static struct attribute *dme1737_attr_pwm1[] = {
SENSOR_DEV_ATTR_PWM_1TO3(1),
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm1_freq.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm2[] = {
SENSOR_DEV_ATTR_PWM_1TO3(2),
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm2_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm3[] = {
SENSOR_DEV_ATTR_PWM_1TO3(3),
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm5[] = {
SENSOR_DEV_ATTR_PWM_5TO6(5),
&sensor_dev_attr_pwm5.dev_attr.attr,
&sensor_dev_attr_pwm5_freq.dev_attr.attr,
&sensor_dev_attr_pwm5_enable.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm6[] = {
SENSOR_DEV_ATTR_PWM_5TO6(6),
&sensor_dev_attr_pwm6.dev_attr.attr,
&sensor_dev_attr_pwm6_freq.dev_attr.attr,
&sensor_dev_attr_pwm6_enable.dev_attr.attr,
NULL
};
@ -1649,27 +1671,45 @@ static const struct attribute_group dme1737_pwm_group[] = {
* Their creation depends on the chip configuration which is determined during
* module load. */
static struct attribute *dme1737_attr_fan1[] = {
SENSOR_DEV_ATTR_FAN_1TO4(1),
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_min.dev_attr.attr,
&sensor_dev_attr_fan1_alarm.dev_attr.attr,
&sensor_dev_attr_fan1_type.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_fan2[] = {
SENSOR_DEV_ATTR_FAN_1TO4(2),
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan2_min.dev_attr.attr,
&sensor_dev_attr_fan2_alarm.dev_attr.attr,
&sensor_dev_attr_fan2_type.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_fan3[] = {
SENSOR_DEV_ATTR_FAN_1TO4(3),
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan3_min.dev_attr.attr,
&sensor_dev_attr_fan3_alarm.dev_attr.attr,
&sensor_dev_attr_fan3_type.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_fan4[] = {
SENSOR_DEV_ATTR_FAN_1TO4(4),
&sensor_dev_attr_fan4_input.dev_attr.attr,
&sensor_dev_attr_fan4_min.dev_attr.attr,
&sensor_dev_attr_fan4_alarm.dev_attr.attr,
&sensor_dev_attr_fan4_type.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_fan5[] = {
SENSOR_DEV_ATTR_FAN_5TO6(5),
&sensor_dev_attr_fan5_input.dev_attr.attr,
&sensor_dev_attr_fan5_min.dev_attr.attr,
&sensor_dev_attr_fan5_alarm.dev_attr.attr,
&sensor_dev_attr_fan5_max.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_fan6[] = {
SENSOR_DEV_ATTR_FAN_5TO6(6),
&sensor_dev_attr_fan6_input.dev_attr.attr,
&sensor_dev_attr_fan6_min.dev_attr.attr,
&sensor_dev_attr_fan6_alarm.dev_attr.attr,
&sensor_dev_attr_fan6_max.dev_attr.attr,
NULL
};
@ -1686,13 +1726,22 @@ static const struct attribute_group dme1737_fan_group[] = {
* writeable if the chip is *not* locked. Otherwise they stay read-only. */
static struct attribute *dme1737_attr_lock[] = {
/* Temperatures */
SENSOR_DEV_ATTR_TEMP_LOCK(1),
SENSOR_DEV_ATTR_TEMP_LOCK(2),
SENSOR_DEV_ATTR_TEMP_LOCK(3),
&sensor_dev_attr_temp1_offset.dev_attr.attr,
&sensor_dev_attr_temp2_offset.dev_attr.attr,
&sensor_dev_attr_temp3_offset.dev_attr.attr,
/* Zones */
SENSOR_DEV_ATTR_ZONE_LOCK(1),
SENSOR_DEV_ATTR_ZONE_LOCK(2),
SENSOR_DEV_ATTR_ZONE_LOCK(3),
&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
&sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
NULL
};
@ -1704,23 +1753,40 @@ static const struct attribute_group dme1737_lock_group = {
* writeable if the chip is *not* locked and the respective PWM is available.
* Otherwise they stay read-only. */
static struct attribute *dme1737_attr_pwm1_lock[] = {
SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1),
&sensor_dev_attr_pwm1_freq.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm2_lock[] = {
SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2),
&sensor_dev_attr_pwm2_freq.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm3_lock[] = {
SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3),
&sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm5_lock[] = {
SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5),
&sensor_dev_attr_pwm5.dev_attr.attr,
&sensor_dev_attr_pwm5_freq.dev_attr.attr,
NULL
};
static struct attribute *dme1737_attr_pwm6_lock[] = {
SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6),
&sensor_dev_attr_pwm6.dev_attr.attr,
&sensor_dev_attr_pwm6_freq.dev_attr.attr,
NULL
};
@ -2109,6 +2175,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
kind = dme1737;
name = "dme1737";
data->type = kind;
/* Fill in the remaining client fields and put it into the global
* list */
@ -2301,6 +2368,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
err = -ENODEV;
goto exit_kfree;
}
data->type = -1;
/* Fill in the remaining client fields and initialize the mutex */
strlcpy(client->name, "sch311x", I2C_NAME_SIZE);
@ -2377,7 +2445,10 @@ static int __init dme1737_init(void)
}
if (dme1737_isa_detect(0x2e, &addr) &&
dme1737_isa_detect(0x4e, &addr)) {
dme1737_isa_detect(0x4e, &addr) &&
(!probe_all_addr ||
(dme1737_isa_detect(0x162e, &addr) &&
dme1737_isa_detect(0x164e, &addr)))) {
/* Return 0 if we didn't find an ISA device */
return 0;
}

View File

@ -30,14 +30,37 @@
#include "lm75.h"
/* Addresses to scan */
/*
* This driver handles the LM75 and compatible digital temperature sensors.
* Only types which are _not_ listed in I2C_CLIENT_INSMOD_*() need to be
* listed here. We start at 9 since I2C_CLIENT_INSMOD_*() currently allow
* definition of up to 8 chip types (plus zero).
*/
enum lm75_type { /* keep sorted in alphabetical order */
ds1775 = 9,
ds75,
/* lm75 -- in I2C_CLIENT_INSMOD_1() */
lm75a,
max6625,
max6626,
mcp980x,
stds75,
tcn75,
tmp100,
tmp101,
tmp175,
tmp275,
tmp75,
};
/* Addresses scanned by legacy style driver binding */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Insmod parameters */
/* Insmod parameters (only for legacy style driver binding) */
I2C_CLIENT_INSMOD_1(lm75);
/* Many LM75 constants specified below */
/* The LM75 registers */
#define LM75_REG_CONF 0x01
@ -49,10 +72,11 @@ static const u8 LM75_REG_TEMP[3] = {
/* Each client has this additional data */
struct lm75_data {
struct i2c_client client;
struct device *hwmon_dev;
struct i2c_client *client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
u8 orig_conf;
char valid; /* !=0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u16 temp[3]; /* Register values,
0 = input
@ -60,23 +84,14 @@ struct lm75_data {
2 = hyst */
};
static int lm75_attach_adapter(struct i2c_adapter *adapter);
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind);
static void lm75_init_client(struct i2c_client *client);
static int lm75_detach_client(struct i2c_client *client);
static int lm75_read_value(struct i2c_client *client, u8 reg);
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct lm75_data *lm75_update_device(struct device *dev);
/* This is the driver that will be inserted */
static struct i2c_driver lm75_driver = {
.driver = {
.name = "lm75",
},
.attach_adapter = lm75_attach_adapter,
.detach_client = lm75_detach_client,
};
/*-----------------------------------------------------------------------*/
/* sysfs attributes for hwmon */
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf)
@ -109,13 +124,6 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
show_temp, set_temp, 2);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
static int lm75_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm75_detect);
}
static struct attribute *lm75_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@ -128,32 +136,144 @@ static const struct attribute_group lm75_group = {
.attrs = lm75_attributes,
};
/*-----------------------------------------------------------------------*/
/* "New style" I2C driver binding -- following the driver model */
static int
lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct lm75_data *data;
int status;
u8 set_mask, clr_mask;
int new;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -EIO;
data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
* Then tweak to be more precise when appropriate.
*/
set_mask = 0;
clr_mask = (1 << 0) /* continuous conversions */
| (1 << 6) | (1 << 5); /* 9-bit mode */
/* configure as specified */
status = lm75_read_value(client, LM75_REG_CONF);
if (status < 0) {
dev_dbg(&client->dev, "Can't read config? %d\n", status);
goto exit_free;
}
data->orig_conf = status;
new = status & ~clr_mask;
new |= set_mask;
if (status != new)
lm75_write_value(client, LM75_REG_CONF, new);
dev_dbg(&client->dev, "Config %02x\n", new);
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &lm75_group);
if (status)
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: sensor '%s'\n",
data->hwmon_dev->bus_id, client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &lm75_group);
exit_free:
i2c_set_clientdata(client, NULL);
kfree(data);
return status;
}
static int lm75_remove(struct i2c_client *client)
{
struct lm75_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm75_group);
lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
i2c_set_clientdata(client, NULL);
kfree(data);
return 0;
}
static const struct i2c_device_id lm75_ids[] = {
{ "ds1775", ds1775, },
{ "ds75", ds75, },
{ "lm75", lm75, },
{ "lm75a", lm75a, },
{ "max6625", max6625, },
{ "max6626", max6626, },
{ "mcp980x", mcp980x, },
{ "stds75", stds75, },
{ "tcn75", tcn75, },
{ "tmp100", tmp100, },
{ "tmp101", tmp101, },
{ "tmp175", tmp175, },
{ "tmp275", tmp275, },
{ "tmp75", tmp75, },
{ /* LIST END */ }
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);
static struct i2c_driver lm75_driver = {
.driver = {
.name = "lm75",
},
.probe = lm75_probe,
.remove = lm75_remove,
.id_table = lm75_ids,
};
/*-----------------------------------------------------------------------*/
/* "Legacy" I2C driver binding */
static struct i2c_driver lm75_legacy_driver;
/* This function is called by i2c_probe */
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
{
int i;
struct i2c_client *new_client;
struct lm75_data *data;
int err = 0;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm75_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
/* OK. For now, we presume we have a valid address. We create the
client structure, even though there may be no sensor present.
But it allows us to use i2c_smbus_read_*_data() calls. */
new_client = kzalloc(sizeof *new_client, GFP_KERNEL);
if (!new_client) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm75_driver;
new_client->driver = &lm75_legacy_driver;
new_client->flags = 0;
/* Now, we do the remaining detection. There is no identification-
@ -174,17 +294,17 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
|| i2c_smbus_read_word_data(new_client, 5) != hyst
|| i2c_smbus_read_word_data(new_client, 6) != hyst
|| i2c_smbus_read_word_data(new_client, 7) != hyst)
goto exit_free;
goto exit_free;
os = i2c_smbus_read_word_data(new_client, 3);
if (i2c_smbus_read_word_data(new_client, 4) != os
|| i2c_smbus_read_word_data(new_client, 5) != os
|| i2c_smbus_read_word_data(new_client, 6) != os
|| i2c_smbus_read_word_data(new_client, 7) != os)
goto exit_free;
goto exit_free;
/* Unused bits */
if (conf & 0xe0)
goto exit_free;
goto exit_free;
/* Addresses cycling */
for (i = 8; i < 0xff; i += 8)
@ -194,58 +314,57 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_free;
}
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = lm75;
if (kind == lm75) {
name = "lm75";
}
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
mutex_init(&data->update_lock);
/* NOTE: we treat "force=..." and "force_lm75=..." the same.
* Only new-style driver binding distinguishes chip types.
*/
strlcpy(new_client->name, "lm75", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
err = i2c_attach_client(new_client);
if (err)
goto exit_free;
/* Initialize the LM75 chip */
lm75_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group)))
err = lm75_probe(new_client, NULL);
if (err < 0)
goto exit_detach;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm75_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
kfree(new_client);
exit:
return err;
}
static int lm75_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm75_detect);
}
static int lm75_detach_client(struct i2c_client *client)
{
struct lm75_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm75_group);
lm75_remove(client);
i2c_detach_client(client);
kfree(data);
kfree(client);
return 0;
}
static struct i2c_driver lm75_legacy_driver = {
.driver = {
.name = "lm75_legacy",
},
.attach_adapter = lm75_attach_adapter,
.detach_client = lm75_detach_client,
};
/*-----------------------------------------------------------------------*/
/* register access */
/* All registers are word-sized, except for the configuration register.
LM75 uses a high-byte first convention, which is exactly opposite to
the SMBus standard. */
@ -268,16 +387,6 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
return i2c_smbus_write_word_data(client, reg, swab16(value));
}
static void lm75_init_client(struct i2c_client *client)
{
int reg;
/* Enable if in shutdown mode */
reg = lm75_read_value(client, LM75_REG_CONF);
if (reg >= 0 && (reg & 0x01))
lm75_write_value(client, LM75_REG_CONF, reg & 0xfe);
}
static struct lm75_data *lm75_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@ -309,13 +418,28 @@ static struct lm75_data *lm75_update_device(struct device *dev)
return data;
}
/*-----------------------------------------------------------------------*/
/* module glue */
static int __init sensors_lm75_init(void)
{
return i2c_add_driver(&lm75_driver);
int status;
status = i2c_add_driver(&lm75_driver);
if (status < 0)
return status;
status = i2c_add_driver(&lm75_legacy_driver);
if (status < 0)
i2c_del_driver(&lm75_driver);
return status;
}
static void __exit sensors_lm75_exit(void)
{
i2c_del_driver(&lm75_legacy_driver);
i2c_del_driver(&lm75_driver);
}

File diff suppressed because it is too large Load Diff