aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-01-16 16:51:46 -0500
committerJean Delvare <khali@endymion.delvare>2012-01-16 16:51:46 -0500
commite872c91e726e7f7f74817cf9a81a138bf0d0a583 (patch)
tree5cba7f2c9b5afa53f5e3dad11e2272aed5e1fb2f /drivers/hwmon
parent210961c436d5c552a816ae9c6b38cbc8b993395a (diff)
hwmon: (lm63) Add support for unsigned upper temperature limits
LM96163 supports unsigned upper limits for the external temperature sensor. Add support for it. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/lm63.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 3d882c93b46d..24a96f89d206 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -92,6 +92,8 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
92#define LM63_REG_MAN_ID 0xFE 92#define LM63_REG_MAN_ID 0xFE
93#define LM63_REG_CHIP_ID 0xFF 93#define LM63_REG_CHIP_ID 0xFF
94 94
95#define LM96163_REG_REMOTE_TEMP_U_MSB 0x31
96#define LM96163_REG_REMOTE_TEMP_U_LSB 0x32
95#define LM96163_REG_CONFIG_ENHANCED 0x45 97#define LM96163_REG_CONFIG_ENHANCED 0x45
96 98
97/* 99/*
@@ -120,6 +122,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
120 (val) >= 127875 ? 0x7FE0 : \ 122 (val) >= 127875 ? 0x7FE0 : \
121 (val) < 0 ? ((val) - 62) / 125 * 32 : \ 123 (val) < 0 ? ((val) - 62) / 125 * 32 : \
122 ((val) + 62) / 125 * 32) 124 ((val) + 62) / 125 * 32)
125#define TEMP11U_TO_REG(val) ((val) <= 0 ? 0 : \
126 (val) >= 255875 ? 0xFFE0 : \
127 ((val) + 62) / 125 * 32)
123#define HYST_TO_REG(val) ((val) <= 0 ? 0 : \ 128#define HYST_TO_REG(val) ((val) <= 0 ? 0 : \
124 (val) >= 127000 ? 127 : \ 129 (val) >= 127000 ? 127 : \
125 ((val) + 500) / 1000) 130 ((val) + 500) / 1000)
@@ -188,11 +193,20 @@ struct lm63_data {
188 1: remote low limit 193 1: remote low limit
189 2: remote high limit 194 2: remote high limit
190 3: remote offset */ 195 3: remote offset */
196 u16 temp11u; /* remote input (unsigned) */
191 u8 temp2_crit_hyst; 197 u8 temp2_crit_hyst;
192 u8 alarms; 198 u8 alarms;
193 bool pwm_highres; 199 bool pwm_highres;
200 bool remote_unsigned; /* true if unsigned remote upper limits */
194}; 201};
195 202
203static inline int temp8_from_reg(struct lm63_data *data, int nr)
204{
205 if (data->remote_unsigned)
206 return TEMP8_FROM_REG((u8)data->temp8[nr]);
207 return TEMP8_FROM_REG(data->temp8[nr]);
208}
209
196/* 210/*
197 * Sysfs callback functions and files 211 * Sysfs callback functions and files
198 */ 212 */
@@ -295,7 +309,7 @@ static ssize_t show_remote_temp8(struct device *dev,
295{ 309{
296 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 310 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
297 struct lm63_data *data = lm63_update_device(dev); 311 struct lm63_data *data = lm63_update_device(dev);
298 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]) 312 return sprintf(buf, "%d\n", temp8_from_reg(data, attr->index)
299 + data->temp2_offset); 313 + data->temp2_offset);
300} 314}
301 315
@@ -324,8 +338,25 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
324{ 338{
325 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 339 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
326 struct lm63_data *data = lm63_update_device(dev); 340 struct lm63_data *data = lm63_update_device(dev);
327 return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]) 341 int nr = attr->index;
328 + data->temp2_offset); 342 int temp;
343
344 if (!nr) {
345 /*
346 * Use unsigned temperature unless its value is zero.
347 * If it is zero, use signed temperature.
348 */
349 if (data->temp11u)
350 temp = TEMP11_FROM_REG(data->temp11u);
351 else
352 temp = TEMP11_FROM_REG(data->temp11[nr]);
353 } else {
354 if (data->remote_unsigned && nr == 2)
355 temp = TEMP11_FROM_REG((u16)data->temp11[nr]);
356 else
357 temp = TEMP11_FROM_REG(data->temp11[nr]);
358 }
359 return sprintf(buf, "%d\n", temp + data->temp2_offset);
329} 360}
330 361
331static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, 362static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -352,7 +383,11 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
352 return err; 383 return err;
353 384
354 mutex_lock(&data->update_lock); 385 mutex_lock(&data->update_lock);
355 data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); 386 if (data->remote_unsigned && nr == 2)
387 data->temp11[nr] = TEMP11U_TO_REG(val - data->temp2_offset);
388 else
389 data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset);
390
356 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], 391 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
357 data->temp11[nr] >> 8); 392 data->temp11[nr] >> 8);
358 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], 393 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
@@ -369,7 +404,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev,
369 struct device_attribute *dummy, char *buf) 404 struct device_attribute *dummy, char *buf)
370{ 405{
371 struct lm63_data *data = lm63_update_device(dev); 406 struct lm63_data *data = lm63_update_device(dev);
372 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2]) 407 return sprintf(buf, "%d\n", temp8_from_reg(data, 2)
373 + data->temp2_offset 408 + data->temp2_offset
374 - TEMP8_FROM_REG(data->temp2_crit_hyst)); 409 - TEMP8_FROM_REG(data->temp2_crit_hyst));
375} 410}
@@ -393,7 +428,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev,
393 return err; 428 return err;
394 429
395 mutex_lock(&data->update_lock); 430 mutex_lock(&data->update_lock);
396 hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val; 431 hyst = temp8_from_reg(data, 2) + data->temp2_offset - val;
397 i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, 432 i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
398 HYST_TO_REG(hyst)); 433 HYST_TO_REG(hyst));
399 mutex_unlock(&data->update_lock); 434 mutex_unlock(&data->update_lock);
@@ -620,9 +655,8 @@ static void lm63_init_client(struct i2c_client *client)
620 data->pwm1_freq = 1; 655 data->pwm1_freq = 1;
621 656
622 /* 657 /*
623 * For LM96163, check if high resolution PWM is enabled. 658 * For LM96163, check if high resolution PWM
624 * Also, check if unsigned temperature format is enabled 659 * and unsigned temperature format is enabled.
625 * and display a warning message if it is.
626 */ 660 */
627 if (data->kind == lm96163) { 661 if (data->kind == lm96163) {
628 u8 config_enhanced 662 u8 config_enhanced
@@ -632,8 +666,7 @@ static void lm63_init_client(struct i2c_client *client)
632 && !(data->config_fan & 0x08) && data->pwm1_freq == 8) 666 && !(data->config_fan & 0x08) && data->pwm1_freq == 8)
633 data->pwm_highres = true; 667 data->pwm_highres = true;
634 if (config_enhanced & 0x08) 668 if (config_enhanced & 0x08)
635 dev_warn(&client->dev, 669 data->remote_unsigned = true;
636 "Unsigned format for High and Crit setpoints enabled but not supported by driver\n");
637 } 670 }
638 671
639 /* Show some debug info about the LM63 configuration */ 672 /* Show some debug info about the LM63 configuration */
@@ -709,6 +742,13 @@ static struct lm63_data *lm63_update_device(struct device *dev)
709 LM63_REG_REMOTE_OFFSET_MSB) << 8) 742 LM63_REG_REMOTE_OFFSET_MSB) << 8)
710 | i2c_smbus_read_byte_data(client, 743 | i2c_smbus_read_byte_data(client,
711 LM63_REG_REMOTE_OFFSET_LSB); 744 LM63_REG_REMOTE_OFFSET_LSB);
745
746 if (data->kind == lm96163)
747 data->temp11u = (i2c_smbus_read_byte_data(client,
748 LM96163_REG_REMOTE_TEMP_U_MSB) << 8)
749 | i2c_smbus_read_byte_data(client,
750 LM96163_REG_REMOTE_TEMP_U_LSB);
751
712 data->temp8[2] = i2c_smbus_read_byte_data(client, 752 data->temp8[2] = i2c_smbus_read_byte_data(client,
713 LM63_REG_REMOTE_TCRIT); 753 LM63_REG_REMOTE_TCRIT);
714 data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, 754 data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,