Re: [PATCH v2 4/9] hwmon: (it87) Introduce support for tempX_offset sysfs attribute

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Guenter,

On Sun, 28 Oct 2012 11:19:56 -0700, Guenter Roeck wrote:
> Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx>
> ---
> v2: The macro to calculate IT87_REG_TEMP_OFFSET was broken. Use array instead.
>     When writing the temperature offset attribute, set the flag to enable it.
>     Add documentation describing the new attributes.
> 
>  Documentation/hwmon/it87 |    9 +++++++++
>  drivers/hwmon/it87.c     |   25 ++++++++++++++++++++++---
>  2 files changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
> index 87850d8..92ce617 100644
> --- a/Documentation/hwmon/it87
> +++ b/Documentation/hwmon/it87
> @@ -209,3 +209,12 @@ doesn't use CPU cycles.
>  Trip points must be set properly before switching to automatic fan speed
>  control mode. The driver will perform basic integrity checks before
>  actually switching to automatic control mode.
> +
> +
> +Temperature offset attributes
> +-----------------------------
> +
> +The driver supports temp[1-3]_offset sysfs attributes to adjust the reported
> +temperature for thermal diodes or diode connected thermal transistors.

diode-connected

> +If a temperature sensor is configured for thermistors, the attribute values
> +are ignored.
> diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
> index 82f7924..fe2cdd4 100644
> --- a/drivers/hwmon/it87.c
> +++ b/drivers/hwmon/it87.c
> @@ -203,6 +203,8 @@ static const u8 IT87_REG_FAN[]		= { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
>  static const u8 IT87_REG_FAN_MIN[]	= { 0x10, 0x11, 0x12, 0x84, 0x86 };
>  static const u8 IT87_REG_FANX[]		= { 0x18, 0x19, 0x1a, 0x81, 0x83 };
>  static const u8 IT87_REG_FANX_MIN[]	= { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
> +static const u8 IT87_REG_TEMP_OFFSET[]	= { 0x56, 0x57, 0x59 };

Not all supported chips have these registers. For example, the IT8712F
rev. D doesn't have registers at 0x56 and 0x57, and register 0x59
apparently adjusts the offset for all 3 temperature channels. Also the
value is expressed as a reference voltage, not an offset in degrees C:

"Thermal Diode Zero Degree Voltage value (default: 0.664V 156h)."

(I don't quite understand how they can make 156h fit in an 8-bit
register, but that a different problem.)

So you will have to check all chips and revisions for support and only
create the sysfs attributes if the chip supports per-channel, degree C
offsets. A quick grep suggests that even the latest IT8705F and IT8712F
chip revisons had a voltage value in these registers, so support would
start with the IT8716F.

> +
>  #define IT87_REG_FAN_MAIN_CTRL 0x13
>  #define IT87_REG_FAN_CTL       0x14
>  #define IT87_REG_PWM(nr)       (0x15 + (nr))
> @@ -263,7 +265,7 @@ struct it87_data {
>  	u16 fan[5];		/* Register values, possibly combined */
>  	u16 fan_min[5];		/* Register values, possibly combined */
>  	u8 has_temp;		/* Bitfield, temp sensors enabled */
> -	s8 temp[3][3];		/* [nr][0]=temp, [1]=min, [2]=max */
> +	s8 temp[3][4];		/* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
>  	u8 sensor;		/* Register value */
>  	u8 fan_div[3];		/* Register encoding, shifted right */
>  	u8 vid;			/* Register encoding, combined */
> @@ -538,10 +540,19 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
>  
>  	mutex_lock(&data->update_lock);
>  	data->temp[nr][index] = TEMP_TO_REG(val);
> +	if (index == 3) {
> +		u8 reg = it87_read_value(data, IT87_REG_BEEP_ENABLE);
> +		if (!(reg & 0x80)) {
> +			reg |= 0x80;
> +			it87_write_value(data, IT87_REG_BEEP_ENABLE, reg);
> +		}
> +	}
>  	it87_write_value(data,
>  			 index == 1 ? IT87_REG_TEMP_LOW(nr)
> -				    : IT87_REG_TEMP_HIGH(nr),
> +				    : index == 2 ? IT87_REG_TEMP_HIGH(nr)
> +						 : IT87_REG_TEMP_OFFSET[nr],

This starts being a little difficult to read. Plus you have more tests
on the index value than you could have. What about introducing a local
variable in which you would store the register number, and use that
later in the code? You can use a switch/case for that, this will be a
lot more indentation-friendly.

>  			 data->temp[nr][index]);
> +	data->valid = 0;

I see no reason for doing that unconditionally. This is only needed
when changing an offset, not a limit, right?

>  	mutex_unlock(&data->update_lock);
>  	return count;
>  }
> @@ -549,12 +560,15 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
>  static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
>  static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGOWU, show_temp, set_temp, 0, 1);
>  static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGOWU, show_temp, set_temp, 0, 2);
> +static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGOWU, show_temp, set_temp, 0, 3);
>  static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
>  static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGOWU, show_temp, set_temp, 1, 1);
>  static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGOWU, show_temp, set_temp, 1, 2);
> +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGOWU, show_temp, set_temp, 1, 3);
>  static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
>  static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGOWU, show_temp, set_temp, 2, 1);
>  static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGOWU, show_temp, set_temp, 2, 2);
> +static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGOWU, show_temp, set_temp, 2, 3);
>  
>  static ssize_t show_type(struct device *dev, struct device_attribute *attr,
>  			 char *buf)
> @@ -1376,11 +1390,12 @@ static const struct attribute_group it87_group_in[9] = {
>  	{ .attrs = it87_attributes_in[8] },
>  };
>  
> -static struct attribute *it87_attributes_temp[3][6] = {
> +static struct attribute *it87_attributes_temp[3][7] = {
>  {
>  	&sensor_dev_attr_temp1_input.dev_attr.attr,
>  	&sensor_dev_attr_temp1_max.dev_attr.attr,
>  	&sensor_dev_attr_temp1_min.dev_attr.attr,
> +	&sensor_dev_attr_temp1_offset.dev_attr.attr,
>  	&sensor_dev_attr_temp1_type.dev_attr.attr,
>  	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
>  	NULL
> @@ -1388,6 +1403,7 @@ static struct attribute *it87_attributes_temp[3][6] = {
>  	&sensor_dev_attr_temp2_input.dev_attr.attr,
>  	&sensor_dev_attr_temp2_max.dev_attr.attr,
>  	&sensor_dev_attr_temp2_min.dev_attr.attr,
> +	&sensor_dev_attr_temp2_offset.dev_attr.attr,
>  	&sensor_dev_attr_temp2_type.dev_attr.attr,
>  	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
>  	NULL
> @@ -1395,6 +1411,7 @@ static struct attribute *it87_attributes_temp[3][6] = {
>  	&sensor_dev_attr_temp3_input.dev_attr.attr,
>  	&sensor_dev_attr_temp3_max.dev_attr.attr,
>  	&sensor_dev_attr_temp3_min.dev_attr.attr,
> +	&sensor_dev_attr_temp3_offset.dev_attr.attr,
>  	&sensor_dev_attr_temp3_type.dev_attr.attr,
>  	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
>  	NULL

As creation of these attributes will be conditional, you'll have to
move them to their own array I'm afraid.

> @@ -2360,6 +2377,8 @@ static struct it87_data *it87_update_device(struct device *dev)
>  				it87_read_value(data, IT87_REG_TEMP_LOW(i));
>  			data->temp[i][2] =
>  				it87_read_value(data, IT87_REG_TEMP_HIGH(i));
> +			data->temp[i][3] =
> +				it87_read_value(data, IT87_REG_TEMP_OFFSET[i]);

Ideally this would be conditional too.

>  		}
>  
>  		/* Newer chips don't have clock dividers */


-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux