Skip to content

Commit

Permalink
hwmon: (dme1737) Add support for in7 for SCH5127
Browse files Browse the repository at this point in the history
Add support for the 1.5V voltage monitoring input (in7) of the
SMSC SCH5127 chip.

Signed-off-by: Juerg Haefliger <juergh@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
  • Loading branch information
Juerg Haefliger authored and Jean Delvare committed Jan 12, 2011
1 parent 7a1b76f commit d4b94e1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 20 deletions.
12 changes: 7 additions & 5 deletions Documentation/hwmon/dme1737
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Description
This driver implements support for the hardware monitoring capabilities of the
SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, SCH311x,
and SCH5127 Super-I/O chips. These chips feature monitoring of 3 temp sensors
temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and
temp[1-3] (2 remote diodes and 1 internal), 8 voltages in[0-7] (7 external and
1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement
up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and
automatically.
Expand Down Expand Up @@ -105,6 +105,7 @@ SCH5127:
in4: V1_IN 0V - 1.5V
in5: VTR (+3.3V standby) 0V - 4.38V
in6: Vbat (+3.0V) 0V - 4.38V
in7: Vtrip (+1.5V) 0V - 1.99V

Each voltage input has associated min and max limits which trigger an alarm
when crossed.
Expand Down Expand Up @@ -217,10 +218,10 @@ cpu0_vid RO CPU core reference voltage in
vrm RW Voltage regulator module version
number.

in[0-6]_input RO Measured voltage in millivolts.
in[0-6]_min RW Low limit for voltage input.
in[0-6]_max RW High limit for voltage input.
in[0-6]_alarm RO Voltage input alarm. Returns 1 if
in[0-7]_input RO Measured voltage in millivolts.
in[0-7]_min RW Low limit for voltage input.
in[0-7]_max RW High limit for voltage input.
in[0-7]_alarm RO Voltage input alarm. Returns 1 if
voltage input is or went outside the
associated min-max range, 0 otherwise.

Expand Down Expand Up @@ -324,3 +325,4 @@ fan5 opt opt
pwm5 opt opt
fan6 opt opt
pwm6 opt opt
in7 yes
68 changes: 53 additions & 15 deletions drivers/hwmon/dme1737.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
* in4 +12V
* in5 VTR (+3.3V stby)
* in6 Vbat
* in7 Vtrip (sch5127 only)
*
* --------------------------------------------------------------------- */

/* Voltages (in) numbered 0-6 (ix) */
#define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) \
: 0x94 + (ix))
/* Voltages (in) numbered 0-7 (ix) */
#define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) : \
(ix) < 7 ? 0x94 + (ix) : \
0x1f)
#define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \
: 0x91 + (ix) * 2)
#define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \
Expand All @@ -101,10 +103,11 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
* IN_TEMP_LSB(1) = [temp3, temp1]
* IN_TEMP_LSB(2) = [in4, temp2]
* IN_TEMP_LSB(3) = [in3, in0]
* IN_TEMP_LSB(4) = [in2, in1] */
* IN_TEMP_LSB(4) = [in2, in1]
* IN_TEMP_LSB(5) = [res, in7] */
#define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix))
static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0};
static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4};
static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5};
static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4};
static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1};
static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};

Expand Down Expand Up @@ -145,7 +148,7 @@ static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
#define DME1737_REG_ALARM1 0x41
#define DME1737_REG_ALARM2 0x42
#define DME1737_REG_ALARM3 0x83
static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17};
static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17, 18};
static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};

Expand Down Expand Up @@ -190,6 +193,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
#define HAS_PWM_MIN (1 << 4) /* bit 4 */
#define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */
#define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */
#define HAS_IN7 (1 << 17) /* bit 17 */

/* ---------------------------------------------------------------------
* Data structures and manipulation thereof
Expand All @@ -213,9 +217,9 @@ struct dme1737_data {
u32 has_features;

/* Register values */
u16 in[7];
u8 in_min[7];
u8 in_max[7];
u16 in[8];
u8 in_min[8];
u8 in_max[8];
s16 temp[3];
s8 temp_min[3];
s8 temp_max[3];
Expand Down Expand Up @@ -247,7 +251,7 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
3300};
static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
3300};
3300, 1500};
#define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \
(type) == sch5027 ? IN_NOMINAL_SCH5027 : \
(type) == sch5127 ? IN_NOMINAL_SCH5127 : \
Expand Down Expand Up @@ -580,7 +584,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
{
struct dme1737_data *data = dev_get_drvdata(dev);
int ix;
u8 lsb[5];
u8 lsb[6];

mutex_lock(&data->update_lock);

Expand All @@ -603,6 +607,9 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
/* Voltage inputs are stored as 16 bit values even
* though they have only 12 bits resolution. This is
* to make it consistent with the temp inputs. */
if (ix == 7 && !(data->has_features & HAS_IN7)) {
continue;
}
data->in[ix] = dme1737_read(data,
DME1737_REG_IN(ix)) << 8;
data->in_min[ix] = dme1737_read(data,
Expand Down Expand Up @@ -635,10 +642,16 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
* which the registers are read (MSB first, then LSB) is
* important! */
for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
if (ix == 5 && !(data->has_features & HAS_IN7)) {
continue;
}
lsb[ix] = dme1737_read(data,
DME1737_REG_IN_TEMP_LSB(ix));
}
for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
if (ix == 7 && !(data->has_features & HAS_IN7)) {
continue;
}
data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
}
Expand Down Expand Up @@ -762,7 +775,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)

/* ---------------------------------------------------------------------
* Voltage sysfs attributes
* ix = [0-5]
* ix = [0-7]
* --------------------------------------------------------------------- */

#define SYS_IN_INPUT 0
Expand Down Expand Up @@ -1439,7 +1452,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr,
* Sysfs device attribute defines and structs
* --------------------------------------------------------------------- */

/* Voltages 0-6 */
/* Voltages 0-7 */

#define SENSOR_DEVICE_ATTR_IN(ix) \
static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \
Expand All @@ -1458,6 +1471,7 @@ SENSOR_DEVICE_ATTR_IN(3);
SENSOR_DEVICE_ATTR_IN(4);
SENSOR_DEVICE_ATTR_IN(5);
SENSOR_DEVICE_ATTR_IN(6);
SENSOR_DEVICE_ATTR_IN(7);

/* Temperatures 1-3 */

Expand Down Expand Up @@ -1695,6 +1709,21 @@ static const struct attribute_group dme1737_zone_hyst_group = {
.attrs = dme1737_zone_hyst_attr,
};

/* The following struct holds voltage in7 related attributes, which
* are not available in all chips. The following chips support them:
* SCH5127 */
static struct attribute *dme1737_in7_attr[] = {
&sensor_dev_attr_in7_input.dev_attr.attr,
&sensor_dev_attr_in7_min.dev_attr.attr,
&sensor_dev_attr_in7_max.dev_attr.attr,
&sensor_dev_attr_in7_alarm.dev_attr.attr,
NULL
};

static const struct attribute_group dme1737_in7_group = {
.attrs = dme1737_in7_attr,
};

/* The following structs hold the PWM attributes, some of which are optional.
* Their creation depends on the chip configuration which is determined during
* module load. */
Expand Down Expand Up @@ -1986,6 +2015,9 @@ static void dme1737_remove_files(struct device *dev)
if (data->has_features & HAS_ZONE_HYST) {
sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
}
if (data->has_features & HAS_IN7) {
sysfs_remove_group(&dev->kobj, &dme1737_in7_group);
}
sysfs_remove_group(&dev->kobj, &dme1737_group);

if (!data->client) {
Expand Down Expand Up @@ -2030,6 +2062,12 @@ static int dme1737_create_files(struct device *dev)
&dme1737_zone_hyst_group))) {
goto exit_remove;
}
if (data->has_features & HAS_IN7) {
err = sysfs_create_group(&dev->kobj, &dme1737_in7_group);
if (err) {
goto exit_remove;
}
}

/* Create fan sysfs attributes */
for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
Expand Down Expand Up @@ -2188,7 +2226,7 @@ static int dme1737_init_device(struct device *dev)
data->has_features |= HAS_ZONE3;
break;
case sch5127:
data->has_features |= HAS_FAN(2) | HAS_PWM(2);
data->has_features |= HAS_FAN(2) | HAS_PWM(2) | HAS_IN7;
break;
default:
break;
Expand Down

0 comments on commit d4b94e1

Please sign in to comment.