Commit 210961c436d5c552a816ae9c6b38cbc8b993395a

Authored by Guenter Roeck
Committed by Jean Delvare
1 parent 786375f729

hwmon: (lm63) Add support for LM96163

LM96163 is an enhanced version of LM63 with improved PWM resolution. Add chip
detection code as well as support for improved PWM resolution if the chip is
configured to use it.

Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Jean Delvare <khali@linux-fr.org>

Showing 3 changed files with 46 additions and 7 deletions Side-by-side Diff

Documentation/hwmon/lm63
... ... @@ -12,6 +12,11 @@
12 12 Addresses scanned: I2C 0x18 and 0x4e
13 13 Datasheet: Publicly available at the National Semiconductor website
14 14 http://www.national.com/pf/LM/LM64.html
  15 + * National Semiconductor LM96163
  16 + Prefix: 'lm96163'
  17 + Addresses scanned: I2C 0x4c
  18 + Datasheet: Publicly available at the National Semiconductor website
  19 + http://www.national.com/pf/LM/LM96163.html
15 20  
16 21 Author: Jean Delvare <khali@linux-fr.org>
17 22  
... ... @@ -62,4 +67,7 @@
62 67  
63 68 The LM64 is effectively an LM63 with GPIO lines. The driver does not
64 69 support these GPIO lines at present.
  70 +
  71 +The LM96163 is an enhanced version of LM63 with improved temperature accuracy
  72 +and better PWM resolution.
drivers/hwmon/Kconfig
... ... @@ -515,11 +515,11 @@
515 515 will be called lineage-pem.
516 516  
517 517 config SENSORS_LM63
518   - tristate "National Semiconductor LM63 and LM64"
  518 + tristate "National Semiconductor LM63 and compatibles"
519 519 depends on I2C
520 520 help
521 521 If you say yes here you get support for the National
522   - Semiconductor LM63 and LM64 remote diode digital temperature
  522 + Semiconductor LM63, LM64, and LM96163 remote diode digital temperature
523 523 sensors with integrated fan control. Such chips are found
524 524 on the Tyan S4882 (Thunder K8QS Pro) motherboard, among
525 525 others.
drivers/hwmon/lm63.c
... ... @@ -47,6 +47,7 @@
47 47 #include <linux/err.h>
48 48 #include <linux/mutex.h>
49 49 #include <linux/sysfs.h>
  50 +#include <linux/types.h>
50 51  
51 52 /*
52 53 * Addresses to scan
... ... @@ -91,6 +92,8 @@
91 92 #define LM63_REG_MAN_ID 0xFE
92 93 #define LM63_REG_CHIP_ID 0xFF
93 94  
  95 +#define LM96163_REG_CONFIG_ENHANCED 0x45
  96 +
94 97 /*
95 98 * Conversions and various macros
96 99 * For tachometer counts, the LM63 uses 16-bit values.
... ... @@ -134,7 +137,7 @@
134 137 static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info);
135 138 static void lm63_init_client(struct i2c_client *client);
136 139  
137   -enum chips { lm63, lm64 };
  140 +enum chips { lm63, lm64, lm96163 };
138 141  
139 142 /*
140 143 * Driver data (common to all clients)
... ... @@ -143,6 +146,7 @@
143 146 static const struct i2c_device_id lm63_id[] = {
144 147 { "lm63", lm63 },
145 148 { "lm64", lm64 },
  149 + { "lm96163", lm96163 },
146 150 { }
147 151 };
148 152 MODULE_DEVICE_TABLE(i2c, lm63_id);
... ... @@ -186,6 +190,7 @@
186 190 3: remote offset */
187 191 u8 temp2_crit_hyst;
188 192 u8 alarms;
  193 + bool pwm_highres;
189 194 };
190 195  
191 196 /*
192 197  
... ... @@ -226,9 +231,16 @@
226 231 char *buf)
227 232 {
228 233 struct lm63_data *data = lm63_update_device(dev);
229   - return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
  234 + int pwm;
  235 +
  236 + if (data->pwm_highres)
  237 + pwm = data->pwm1_value;
  238 + else
  239 + pwm = data->pwm1_value >= 2 * data->pwm1_freq ?
230 240 255 : (data->pwm1_value * 255 + data->pwm1_freq) /
231   - (2 * data->pwm1_freq));
  241 + (2 * data->pwm1_freq);
  242 +
  243 + return sprintf(buf, "%d\n", pwm);
232 244 }
233 245  
234 246 static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
235 247  
... ... @@ -246,9 +258,9 @@
246 258 if (err)
247 259 return err;
248 260  
  261 + val = SENSORS_LIMIT(val, 0, 255);
249 262 mutex_lock(&data->update_lock);
250   - data->pwm1_value = val <= 0 ? 0 :
251   - val >= 255 ? 2 * data->pwm1_freq :
  263 + data->pwm1_value = data->pwm_highres ? val :
252 264 (val * data->pwm1_freq * 2 + 127) / 255;
253 265 i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
254 266 mutex_unlock(&data->update_lock);
... ... @@ -522,6 +534,8 @@
522 534 strlcpy(info->type, "lm63", I2C_NAME_SIZE);
523 535 else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e))
524 536 strlcpy(info->type, "lm64", I2C_NAME_SIZE);
  537 + else if (chip_id == 0x49 && address == 0x4c)
  538 + strlcpy(info->type, "lm96163", I2C_NAME_SIZE);
525 539 else
526 540 return -ENODEV;
527 541  
... ... @@ -604,6 +618,23 @@
604 618 data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
605 619 if (data->pwm1_freq == 0)
606 620 data->pwm1_freq = 1;
  621 +
  622 + /*
  623 + * For LM96163, check if high resolution PWM is enabled.
  624 + * Also, check if unsigned temperature format is enabled
  625 + * and display a warning message if it is.
  626 + */
  627 + if (data->kind == lm96163) {
  628 + u8 config_enhanced
  629 + = i2c_smbus_read_byte_data(client,
  630 + LM96163_REG_CONFIG_ENHANCED);
  631 + if ((config_enhanced & 0x10)
  632 + && !(data->config_fan & 0x08) && data->pwm1_freq == 8)
  633 + data->pwm_highres = true;
  634 + if (config_enhanced & 0x08)
  635 + dev_warn(&client->dev,
  636 + "Unsigned format for High and Crit setpoints enabled but not supported by driver\n");
  637 + }
607 638  
608 639 /* Show some debug info about the LM63 configuration */
609 640 dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",