提交 67605613 编写于 作者: L Linus Torvalds

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
...@@ -22,6 +22,10 @@ Module Parameters ...@@ -22,6 +22,10 @@ Module Parameters
and PWM output control functions. Using this parameter and PWM output control functions. Using this parameter
shouldn't be required since the BIOS usually takes care shouldn't be required since the BIOS usually takes care
of this. 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 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. complaining. The driver will say so if it is necessary.
......
...@@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has ...@@ -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 confirmed this "bug". The ADT7463 is reported to work as described in the
documentation. The current lm85 driver does not show the offset register. 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 See the vendor datasheets for more information. There is application note
from National (AN-1260) with some additional information about the LM85. from National (AN-1260) with some additional information about the LM85.
The Analog Devices datasheet is very detailed and describes a procedure for The Analog Devices datasheet is very detailed and describes a procedure for
...@@ -206,13 +201,15 @@ Configuration choices: ...@@ -206,13 +201,15 @@ Configuration choices:
The National LM85's have two vendor specific configuration The National LM85's have two vendor specific configuration
features. Tach. mode and Spinup Control. For more details on these, 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 Analog Devices ADM1027 has several vendor specific enhancements.
The number of pulses-per-rev of the fans can be set, Tach monitoring 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 can be optimized for PWM operation, and an offset can be applied to
the temperatures to compensate for systemic errors in the 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 In addition to the ADM1027 features, the ADT7463 also has Tmin control
and THERM asserted counts. Automatic Tmin control acts to adjust the and THERM asserted counts. Automatic Tmin control acts to adjust the
......
...@@ -1878,13 +1878,9 @@ W: http://gigaset307x.sourceforge.net/ ...@@ -1878,13 +1878,9 @@ W: http://gigaset307x.sourceforge.net/
S: Maintained S: Maintained
HARDWARE MONITORING HARDWARE MONITORING
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: lm-sensors@lm-sensors.org L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/ W: http://www.lm-sensors.org/
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing S: Orphaned
T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release
S: Maintained
HARDWARE RANDOM NUMBER GENERATOR CORE HARDWARE RANDOM NUMBER GENERATOR CORE
S: Orphaned S: Orphaned
......
...@@ -394,13 +394,24 @@ config SENSORS_LM75 ...@@ -394,13 +394,24 @@ config SENSORS_LM75
tristate "National Semiconductor LM75 and compatibles" tristate "National Semiconductor LM75 and compatibles"
depends on I2C depends on I2C
help help
If you say yes here you get support for National Semiconductor LM75 If you say yes here you get support for one common type of
sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in temperature sensor chip, with models including:
9-bit precision mode), and TelCom (now Microchip) TCN75.
- Dallas Semiconductor DS75 and DS1775
The DS75 and DS1775 in 10- to 12-bit precision modes will require - Maxim MAX6625 and MAX6626
a force module parameter. The driver will not handle the extra - Microchip MCP980x
precision anyhow. - 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 This driver can also be built as a module. If so, the module
will be called lm75. will be called lm75.
......
...@@ -39,32 +39,20 @@ I2C_CLIENT_INSMOD_1(adt7473); ...@@ -39,32 +39,20 @@ I2C_CLIENT_INSMOD_1(adt7473);
#define ADT7473_REG_BASE_ADDR 0x20 #define ADT7473_REG_BASE_ADDR 0x20
#define ADT7473_REG_VOLT_BASE_ADDR 0x21 #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_BASE_ADDR 0x46
#define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49
#define ADT7473_REG_TEMP_BASE_ADDR 0x25 #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_BASE_ADDR 0x4E
#define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53
#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67 #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_BASE_ADDR 0x6A
#define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C
#define ADT7473_REG_FAN_BASE_ADDR 0x28 #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_BASE_ADDR 0x54
#define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B
#define ADT7473_REG_PWM_BASE_ADDR 0x30 #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_BASE_ADDR 0x64
#define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66
#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38 #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_BASE_ADDR 0x5C
#define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E
#define ADT7473_PWM_BHVR_MASK 0xE0 #define ADT7473_PWM_BHVR_MASK 0xE0
#define ADT7473_PWM_BHVR_SHIFT 5 #define ADT7473_PWM_BHVR_SHIFT 5
...@@ -102,7 +90,6 @@ I2C_CLIENT_INSMOD_1(adt7473); ...@@ -102,7 +90,6 @@ I2C_CLIENT_INSMOD_1(adt7473);
#define ADT7473_FAN4_ALARM 0x20 #define ADT7473_FAN4_ALARM 0x20
#define ADT7473_R1T_SHORT 0x40 #define ADT7473_R1T_SHORT 0x40
#define ADT7473_R2T_SHORT 0x80 #define ADT7473_R2T_SHORT 0x80
#define ADT7473_REG_MAX_ADDR 0x80
#define ALARM2(x) ((x) << 8) #define ALARM2(x) ((x) << 8)
...@@ -583,10 +570,9 @@ static ssize_t set_max_duty_at_crit(struct device *dev, ...@@ -583,10 +570,9 @@ static ssize_t set_max_duty_at_crit(struct device *dev,
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct adt7473_data *data = i2c_get_clientdata(client); struct adt7473_data *data = i2c_get_clientdata(client);
int temp = simple_strtol(buf, NULL, 10); int temp = simple_strtol(buf, NULL, 10);
temp = temp && 0xFF;
mutex_lock(&data->lock); 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); reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
if (temp) if (temp)
reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT; reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;
......
...@@ -48,6 +48,11 @@ static unsigned short force_id; ...@@ -48,6 +48,11 @@ static unsigned short force_id;
module_param(force_id, ushort, 0); module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID"); 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 */ /* Addresses to scan */
static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
...@@ -176,6 +181,7 @@ struct dme1737_data { ...@@ -176,6 +181,7 @@ struct dme1737_data {
int valid; /* !=0 if following fields are valid */ int valid; /* !=0 if following fields are valid */
unsigned long last_update; /* in jiffies */ unsigned long last_update; /* in jiffies */
unsigned long last_vbat; /* in jiffies */ unsigned long last_vbat; /* in jiffies */
enum chips type;
u8 vid; u8 vid;
u8 pwm_rr_en; u8 pwm_rr_en;
...@@ -210,20 +216,27 @@ struct dme1737_data { ...@@ -210,20 +216,27 @@ struct dme1737_data {
}; };
/* Nominal voltage values */ /* 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 input
* Voltage inputs have 16 bits resolution, limit values have 8 bits * Voltage inputs have 16 bits resolution, limit values have 8 bits
* resolution. */ * 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) / return SENSORS_LIMIT((val * 192 + IN_NOMINAL(ix, type) / 2) /
IN_NOMINAL[ix], 0, 255); IN_NOMINAL(ix, type), 0, 255);
} }
/* Temperature input /* Temperature input
...@@ -722,13 +735,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, ...@@ -722,13 +735,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
switch (fn) { switch (fn) {
case SYS_IN_INPUT: 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; break;
case SYS_IN_MIN: 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; break;
case SYS_IN_MAX: 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; break;
case SYS_IN_ALARM: case SYS_IN_ALARM:
res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; 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, ...@@ -755,12 +768,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
switch (fn) { switch (fn) {
case SYS_IN_MIN: 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), dme1737_write(client, DME1737_REG_IN_MIN(ix),
data->in_min[ix]); data->in_min[ix]);
break; break;
case SYS_IN_MAX: 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), dme1737_write(client, DME1737_REG_IN_MAX(ix),
data->in_max[ix]); data->in_max[ix]);
break; break;
...@@ -1501,9 +1514,9 @@ SENSOR_DEVICE_ATTR_PWM_1TO3(3); ...@@ -1501,9 +1514,9 @@ SENSOR_DEVICE_ATTR_PWM_1TO3(3);
/* PWMs 5-6 */ /* PWMs 5-6 */
#define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ #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); \ 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); \ show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \
static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \
show_pwm, NULL, SYS_PWM_ENABLE, ix-1) show_pwm, NULL, SYS_PWM_ENABLE, ix-1)
...@@ -1517,91 +1530,75 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); ...@@ -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(cpu0_vid, S_IRUGO, show_vid, NULL);
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ 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 /* This struct holds all the attributes that are always present and need to be
* created unconditionally. The attributes that need modification of their * created unconditionally. The attributes that need modification of their
* permissions are created read-only and write permissions are added or removed * permissions are created read-only and write permissions are added or removed
* on the fly when required */ * on the fly when required */
static struct attribute *dme1737_attr[] ={ static struct attribute *dme1737_attr[] ={
/* Voltages */ /* Voltages */
SENSOR_DEV_ATTR_IN(0), &sensor_dev_attr_in0_input.dev_attr.attr,
SENSOR_DEV_ATTR_IN(1), &sensor_dev_attr_in0_min.dev_attr.attr,
SENSOR_DEV_ATTR_IN(2), &sensor_dev_attr_in0_max.dev_attr.attr,
SENSOR_DEV_ATTR_IN(3), &sensor_dev_attr_in0_alarm.dev_attr.attr,
SENSOR_DEV_ATTR_IN(4), &sensor_dev_attr_in1_input.dev_attr.attr,
SENSOR_DEV_ATTR_IN(5), &sensor_dev_attr_in1_min.dev_attr.attr,
SENSOR_DEV_ATTR_IN(6), &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 */ /* Temperatures */
SENSOR_DEV_ATTR_TEMP(1), &sensor_dev_attr_temp1_input.dev_attr.attr,
SENSOR_DEV_ATTR_TEMP(2), &sensor_dev_attr_temp1_min.dev_attr.attr,
SENSOR_DEV_ATTR_TEMP(3), &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 */ /* Zones */
SENSOR_DEV_ATTR_ZONE(1), &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
SENSOR_DEV_ATTR_ZONE(2), &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
SENSOR_DEV_ATTR_ZONE(3), &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 */ /* Misc */
&dev_attr_vrm.attr, &dev_attr_vrm.attr,
&dev_attr_cpu0_vid.attr, &dev_attr_cpu0_vid.attr,
...@@ -1616,23 +1613,48 @@ static const struct attribute_group dme1737_group = { ...@@ -1616,23 +1613,48 @@ static const struct attribute_group dme1737_group = {
* Their creation depends on the chip configuration which is determined during * Their creation depends on the chip configuration which is determined during
* module load. */ * module load. */
static struct attribute *dme1737_attr_pwm1[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm2[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm3[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm5[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm6[] = { 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 NULL
}; };
...@@ -1649,27 +1671,45 @@ static const struct attribute_group dme1737_pwm_group[] = { ...@@ -1649,27 +1671,45 @@ static const struct attribute_group dme1737_pwm_group[] = {
* Their creation depends on the chip configuration which is determined during * Their creation depends on the chip configuration which is determined during
* module load. */ * module load. */
static struct attribute *dme1737_attr_fan1[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_fan2[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_fan3[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_fan4[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_fan5[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_fan6[] = { 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 NULL
}; };
...@@ -1686,13 +1726,22 @@ static const struct attribute_group dme1737_fan_group[] = { ...@@ -1686,13 +1726,22 @@ static const struct attribute_group dme1737_fan_group[] = {
* writeable if the chip is *not* locked. Otherwise they stay read-only. */ * writeable if the chip is *not* locked. Otherwise they stay read-only. */
static struct attribute *dme1737_attr_lock[] = { static struct attribute *dme1737_attr_lock[] = {
/* Temperatures */ /* Temperatures */
SENSOR_DEV_ATTR_TEMP_LOCK(1), &sensor_dev_attr_temp1_offset.dev_attr.attr,
SENSOR_DEV_ATTR_TEMP_LOCK(2), &sensor_dev_attr_temp2_offset.dev_attr.attr,
SENSOR_DEV_ATTR_TEMP_LOCK(3), &sensor_dev_attr_temp3_offset.dev_attr.attr,
/* Zones */ /* Zones */
SENSOR_DEV_ATTR_ZONE_LOCK(1), &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
SENSOR_DEV_ATTR_ZONE_LOCK(2), &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
SENSOR_DEV_ATTR_ZONE_LOCK(3), &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 NULL
}; };
...@@ -1704,23 +1753,40 @@ static const struct attribute_group dme1737_lock_group = { ...@@ -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. * writeable if the chip is *not* locked and the respective PWM is available.
* Otherwise they stay read-only. */ * Otherwise they stay read-only. */
static struct attribute *dme1737_attr_pwm1_lock[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm2_lock[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm3_lock[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm5_lock[] = { 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 NULL
}; };
static struct attribute *dme1737_attr_pwm6_lock[] = { 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 NULL
}; };
...@@ -2109,6 +2175,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, ...@@ -2109,6 +2175,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
kind = dme1737; kind = dme1737;
name = "dme1737"; name = "dme1737";
data->type = kind;
/* Fill in the remaining client fields and put it into the global /* Fill in the remaining client fields and put it into the global
* list */ * list */
...@@ -2301,6 +2368,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) ...@@ -2301,6 +2368,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
err = -ENODEV; err = -ENODEV;
goto exit_kfree; goto exit_kfree;
} }
data->type = -1;
/* Fill in the remaining client fields and initialize the mutex */ /* Fill in the remaining client fields and initialize the mutex */
strlcpy(client->name, "sch311x", I2C_NAME_SIZE); strlcpy(client->name, "sch311x", I2C_NAME_SIZE);
...@@ -2377,7 +2445,10 @@ static int __init dme1737_init(void) ...@@ -2377,7 +2445,10 @@ static int __init dme1737_init(void)
} }
if (dme1737_isa_detect(0x2e, &addr) && 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 if we didn't find an ISA device */
return 0; return 0;
} }
......
...@@ -30,14 +30,37 @@ ...@@ -30,14 +30,37 @@
#include "lm75.h" #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, static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Insmod parameters */ /* Insmod parameters (only for legacy style driver binding) */
I2C_CLIENT_INSMOD_1(lm75); I2C_CLIENT_INSMOD_1(lm75);
/* Many LM75 constants specified below */
/* The LM75 registers */ /* The LM75 registers */
#define LM75_REG_CONF 0x01 #define LM75_REG_CONF 0x01
...@@ -49,10 +72,11 @@ static const u8 LM75_REG_TEMP[3] = { ...@@ -49,10 +72,11 @@ static const u8 LM75_REG_TEMP[3] = {
/* Each client has this additional data */ /* Each client has this additional data */
struct lm75_data { struct lm75_data {
struct i2c_client client; struct i2c_client *client;
struct device *hwmon_dev; struct device *hwmon_dev;
struct mutex update_lock; 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 */ unsigned long last_updated; /* In jiffies */
u16 temp[3]; /* Register values, u16 temp[3]; /* Register values,
0 = input 0 = input
...@@ -60,23 +84,14 @@ struct lm75_data { ...@@ -60,23 +84,14 @@ struct lm75_data {
2 = hyst */ 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_read_value(struct i2c_client *client, u8 reg);
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct lm75_data *lm75_update_device(struct device *dev); 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 = { /* sysfs attributes for hwmon */
.name = "lm75",
},
.attach_adapter = lm75_attach_adapter,
.detach_client = lm75_detach_client,
};
static ssize_t show_temp(struct device *dev, struct device_attribute *da, static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf) char *buf)
...@@ -109,13 +124,6 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, ...@@ -109,13 +124,6 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
show_temp, set_temp, 2); show_temp, set_temp, 2);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 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[] = { static struct attribute *lm75_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr,
...@@ -128,32 +136,144 @@ static const struct attribute_group lm75_group = { ...@@ -128,32 +136,144 @@ static const struct attribute_group lm75_group = {
.attrs = lm75_attributes, .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 */ /* This function is called by i2c_probe */
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
int i; int i;
struct i2c_client *new_client; struct i2c_client *new_client;
struct lm75_data *data;
int err = 0; int err = 0;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA)) I2C_FUNC_SMBUS_WORD_DATA))
goto exit; goto exit;
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid address. We create the
client structure, even though we cannot fill it completely yet. client structure, even though there may be no sensor present.
But it allows us to access lm75_{read,write}_value. */ But it allows us to use i2c_smbus_read_*_data() calls. */
if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) { new_client = kzalloc(sizeof *new_client, GFP_KERNEL);
if (!new_client) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
new_client->driver = &lm75_driver; new_client->driver = &lm75_legacy_driver;
new_client->flags = 0; new_client->flags = 0;
/* Now, we do the remaining detection. There is no identification- /* 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) ...@@ -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, 5) != hyst
|| i2c_smbus_read_word_data(new_client, 6) != hyst || i2c_smbus_read_word_data(new_client, 6) != hyst
|| i2c_smbus_read_word_data(new_client, 7) != 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); os = i2c_smbus_read_word_data(new_client, 3);
if (i2c_smbus_read_word_data(new_client, 4) != os 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, 5) != os
|| i2c_smbus_read_word_data(new_client, 6) != os || i2c_smbus_read_word_data(new_client, 6) != os
|| i2c_smbus_read_word_data(new_client, 7) != os) || i2c_smbus_read_word_data(new_client, 7) != os)
goto exit_free; goto exit_free;
/* Unused bits */ /* Unused bits */
if (conf & 0xe0) if (conf & 0xe0)
goto exit_free; goto exit_free;
/* Addresses cycling */ /* Addresses cycling */
for (i = 8; i < 0xff; i += 8) for (i = 8; i < 0xff; i += 8)
...@@ -194,58 +314,57 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -194,58 +314,57 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_free; goto exit_free;
} }
/* Determine the chip type - only one kind supported! */ /* NOTE: we treat "force=..." and "force_lm75=..." the same.
if (kind <= 0) * Only new-style driver binding distinguishes chip types.
kind = lm75; */
strlcpy(new_client->name, "lm75", I2C_NAME_SIZE);
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);
/* Tell the I2C layer a new client has arrived */ /* 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; goto exit_free;
/* Initialize the LM75 chip */ err = lm75_probe(new_client, NULL);
lm75_init_client(new_client); if (err < 0)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group)))
goto exit_detach; 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; return 0;
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm75_group);
exit_detach: exit_detach:
i2c_detach_client(new_client); i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(new_client);
exit: exit:
return err; 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) static int lm75_detach_client(struct i2c_client *client)
{ {
struct lm75_data *data = i2c_get_clientdata(client); lm75_remove(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm75_group);
i2c_detach_client(client); i2c_detach_client(client);
kfree(data); kfree(client);
return 0; 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. /* All registers are word-sized, except for the configuration register.
LM75 uses a high-byte first convention, which is exactly opposite to LM75 uses a high-byte first convention, which is exactly opposite to
the SMBus standard. */ the SMBus standard. */
...@@ -268,16 +387,6 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) ...@@ -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)); 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) static struct lm75_data *lm75_update_device(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
...@@ -309,13 +418,28 @@ static struct lm75_data *lm75_update_device(struct device *dev) ...@@ -309,13 +418,28 @@ static struct lm75_data *lm75_update_device(struct device *dev)
return data; return data;
} }
/*-----------------------------------------------------------------------*/
/* module glue */
static int __init sensors_lm75_init(void) 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) static void __exit sensors_lm75_exit(void)
{ {
i2c_del_driver(&lm75_legacy_driver);
i2c_del_driver(&lm75_driver); i2c_del_driver(&lm75_driver);
} }
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册