From b63d97a36edb1aecf8c13e5f5783feff4d64c24b Mon Sep 17 00:00:00 2001 From: Chris D Schimp Date: Mon, 20 Feb 2012 16:59:24 -0500 Subject: hwmon: (max6639) Fix FAN_FROM_REG calculation RPM calculation from tachometer value does not depend on PPR. Also, do not report negative RPM values. Signed-off-by: Chris D Schimp [guenter.roeck@ericsson.com: do not report negative RPM values] Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ Acked-by: Roland Stigge --- drivers/hwmon/max6639.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index e10a092c603c..13e58a1992cf 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -72,8 +72,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; -#define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \ - (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val))) +#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ + 0 : (rpm_ranges[rpm_range] * 30) / (val)) #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) /* @@ -333,7 +333,7 @@ static ssize_t show_fan_input(struct device *dev, return PTR_ERR(data); return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], - data->ppr, data->rpm_range)); + data->rpm_range)); } static ssize_t show_alarm(struct device *dev, -- cgit v1.2.3 From 2f2da1ac0ba5b6cc6e1957c4da5ff20e67d8442b Mon Sep 17 00:00:00 2001 From: Chris D Schimp Date: Mon, 20 Feb 2012 17:44:59 -0500 Subject: hwmon: (max6639) Fix PPR register initialization to set both channels Initialize PPR register for both channels, and set correct PPR register bits. Also remove unnecessary variable initializations. Signed-off-by: Chris D Schimp [guenter.roeck@ericsson.com: Merged two patches into one] Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ Acked-by: Roland Stigge --- drivers/hwmon/max6639.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index 13e58a1992cf..a6760bacd915 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -429,9 +429,9 @@ static int max6639_init_client(struct i2c_client *client) struct max6639_data *data = i2c_get_clientdata(client); struct max6639_platform_data *max6639_info = client->dev.platform_data; - int i = 0; + int i; int rpm_range = 1; /* default: 4000 RPM */ - int err = 0; + int err; /* Reset chip to default values, see below for GCONFIG setup */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, @@ -446,11 +446,6 @@ static int max6639_init_client(struct i2c_client *client) else data->ppr = 2; data->ppr -= 1; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_PPR(i), - data->ppr << 5); - if (err) - goto exit; if (max6639_info) rpm_range = rpm_range_to_reg(max6639_info->rpm_range); @@ -458,6 +453,13 @@ static int max6639_init_client(struct i2c_client *client) for (i = 0; i < 2; i++) { + /* Set Fan pulse per revolution */ + err = i2c_smbus_write_byte_data(client, + MAX6639_REG_FAN_PPR(i), + data->ppr << 6); + if (err) + goto exit; + /* Fans config PWM, RPM */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG1(i), -- cgit v1.2.3 From 363434b5dc352464ac7601547891e5fc9105f124 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 22 Feb 2012 08:13:52 -0800 Subject: hwmon: (ads1015) Fix file leak in probe function An error while creating sysfs attribute files in the driver's probe function results in an error abort, but already created files are not removed. This patch fixes the problem. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ Cc: Dirk Eibach Acked-by: Jean Delvare --- drivers/hwmon/ads1015.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index eedca3cf9968..dd87ae96c262 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -271,7 +271,7 @@ static int ads1015_probe(struct i2c_client *client, continue; err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); if (err) - goto exit_free; + goto exit_remove; } data->hwmon_dev = hwmon_device_register(&client->dev); @@ -285,7 +285,6 @@ static int ads1015_probe(struct i2c_client *client, exit_remove: for (k = 0; k < ADS1015_CHANNELS; ++k) device_remove_file(&client->dev, &ads1015_in[k].dev_attr); -exit_free: kfree(data); exit: return err; -- cgit v1.2.3 From c1c1a3d012fe5e82a9a025fb4b5a4f8ee67a53f6 Mon Sep 17 00:00:00 2001 From: Nikolaus Schulz Date: Wed, 22 Feb 2012 23:18:44 +0100 Subject: hwmon: (f75375s) Fix register write order when setting fans to full speed By hwmon sysfs interface convention, setting pwm_enable to zero sets a fan to full speed. In the f75375s driver, this need be done by enabling manual fan control, plus duty mode for the F875387 chip, and then setting the maximum duty cycle. Fix a bug where the two necessary register writes were swapped, effectively discarding the setting to full-speed. Signed-off-by: Nikolaus Schulz Cc: Riku Voipio Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index f609b5727ba9..6bab2001ef3b 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -340,8 +340,6 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); data->pwm[nr] = 255; - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); break; case 1: /* PWM */ fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); @@ -361,8 +359,6 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) case 0: /* full speed */ fanmode |= (3 << FAN_CTRL_MODE(nr)); data->pwm[nr] = 255; - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); break; case 1: /* PWM */ fanmode |= (3 << FAN_CTRL_MODE(nr)); @@ -377,6 +373,9 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); data->pwm_enable[nr] = val; + if (val == 0) + f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), + data->pwm[nr]); return 0; } -- cgit v1.2.3 From dc91ad8e84593eb49c65cca70537088782b21e08 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 24 Feb 2012 03:44:34 -0800 Subject: hwmon: (max34440) Fix resetting temperature history Temperature history is reset by writing 0x8000 into the peak temperature register, not 0xffff. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/pmbus/max34440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index beaf5a8d9c45..9b97a5b3cf3d 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -82,7 +82,7 @@ static int max34440_write_word_data(struct i2c_client *client, int page, case PMBUS_VIRT_RESET_TEMP_HISTORY: ret = pmbus_write_word_data(client, page, MAX34440_MFR_TEMPERATURE_PEAK, - 0xffff); + 0x8000); break; default: ret = -ENODATA; -- cgit v1.2.3 From 331255d35d6f517020485aee38dbb8b8dfaa1642 Mon Sep 17 00:00:00 2001 From: Nikolaus Schulz Date: Tue, 28 Feb 2012 22:15:51 +0100 Subject: hwmon: (f75375s) Fix writes to the pwm* attribute for the F75387 For the F75387, the register holding the current PWM duty cycle value is r/o; changing it requires writing to the fan expect register instead. Signed-off-by: Nikolaus Schulz [guenter.roeck@ericsson.com: Simplified function parameters] Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 6bab2001ef3b..61cc9c396a98 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -178,6 +178,16 @@ static inline void f75375_write16(struct i2c_client *client, u8 reg, i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); } +static void f75375_write_pwm(struct i2c_client *client, int nr) +{ + struct f75375_data *data = i2c_get_clientdata(client); + if (data->kind == f75387) + f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]); + else + f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), + data->pwm[nr]); +} + static struct f75375_data *f75375_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -309,7 +319,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); + f75375_write_pwm(client, nr); mutex_unlock(&data->update_lock); return count; } @@ -374,8 +384,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); data->pwm_enable[nr] = val; if (val == 0) - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); + f75375_write_pwm(client, nr); return 0; } @@ -759,8 +768,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); for (nr = 0; nr < 2; nr++) { data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); + f75375_write_pwm(client, nr); } } -- cgit v1.2.3 From edeea102857e33b5e9b17a3a2640da390732a693 Mon Sep 17 00:00:00 2001 From: Nikolaus Schulz Date: Tue, 28 Feb 2012 22:15:52 +0100 Subject: hwmon: (f75375s) Make pwm*_mode writable for the F75387 Signed-off-by: Nikolaus Schulz Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 61cc9c396a98..eb648d9c91d6 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -795,7 +795,7 @@ static int f75375_probe(struct i2c_client *client, if (err) goto exit_free; - if (data->kind == f75375) { + if (data->kind != f75373) { err = sysfs_chmod_file(&client->dev.kobj, &sensor_dev_attr_pwm1_mode.dev_attr.attr, S_IRUGO | S_IWUSR); -- cgit v1.2.3 From b17d6561acc16265b65b1e0d27b649829b61a7e3 Mon Sep 17 00:00:00 2001 From: Nikolaus Schulz Date: Tue, 28 Feb 2012 16:15:53 -0500 Subject: hwmon: (f75375s) Properly map the F75387 automatic modes to pwm_enable The F75387 supports automatic fan control using either PWM duty cycle or RPM speed values. Make the driver detect the latter mode, and expose the different modes in sysfs as per pwm_enable, so that the user can switch between them. The interpretation of the pwm_enable attribute for the F75387 is adjusted to be a superset of those values used for similar Fintek chips which do not support automatic duty mode, with 2 mapping to automatic speed mode, and moving automatic duty mode to the new value 4. Toggling the duty mode via pwm_enable is currently denied for the F75387, as the chip then simply reinterprets the fan configuration register values according to the new mode, switching between RPM and PWM units, which makes this a dangerous operation. This patch introduces a new pwm mode into the driver. This is necessary because the new mode (automatic pwm mode, 4) may already be enabled by the BIOS, and the driver should not break existing functionality. This was seen on at least one board. Signed-off-by: Nikolaus Schulz Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index eb648d9c91d6..9ab034a1b4c1 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -264,6 +264,21 @@ static inline u16 rpm_to_reg(int rpm) return 1500000 / rpm; } +static bool duty_mode_enabled(u8 pwm_enable) +{ + switch (pwm_enable) { + case 0: /* Manual, duty mode (full speed) */ + case 1: /* Manual, duty mode */ + case 4: /* Auto, duty mode */ + return true; + case 2: /* Auto, speed mode */ + case 3: /* Manual, speed mode */ + return false; + default: + BUG(); + } +} + static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -337,11 +352,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) struct f75375_data *data = i2c_get_clientdata(client); u8 fanmode; - if (val < 0 || val > 3) + if (val < 0 || val > 4) return -EINVAL; fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); if (data->kind == f75387) { + /* For now, deny dangerous toggling of duty mode */ + if (duty_mode_enabled(data->pwm_enable[nr]) != + duty_mode_enabled(val)) + return -EOPNOTSUPP; /* clear each fanX_mode bit before setting them properly */ fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); @@ -355,12 +374,14 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); break; - case 2: /* AUTOMATIC*/ - fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); + case 2: /* Automatic, speed mode */ break; case 3: /* fan speed */ fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); break; + case 4: /* Automatic, pwm */ + fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); + break; } } else { /* clear each fanX_mode bit before setting them properly */ @@ -378,6 +399,8 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) break; case 3: /* fan speed */ break; + case 4: /* Automatic pwm */ + return -EINVAL; } } @@ -735,14 +758,17 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); - if (manu && duty) - /* speed */ + if (!manu && duty) + /* auto, pwm */ + data->pwm_enable[nr] = 4; + else if (manu && !duty) + /* manual, speed */ data->pwm_enable[nr] = 3; - else if (!manu && duty) - /* automatic */ + else if (!manu && !duty) + /* automatic, speed */ data->pwm_enable[nr] = 2; else - /* manual */ + /* manual, pwm */ data->pwm_enable[nr] = 1; } else { if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) -- cgit v1.2.3 From 15d1ad0cc9d2d3f549afddbcdbc9c3637f0d1331 Mon Sep 17 00:00:00 2001 From: Nikolaus Schulz Date: Tue, 28 Feb 2012 16:15:54 -0500 Subject: hwmon: (f75375s) Catch some attempts to write to r/o registers It makes no sense to attempt to manually configure the fan in auto mode, or set the duty cycle directly in closed loop mode. The corresponding registers are then read-only. If the user tries it nonetheless, error out with EINVAL instead of silently doing nothing. Signed-off-by: Nikolaus Schulz [guenter.roeck@ericsson.com: Minor formatting cleanup] Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 9ab034a1b4c1..6aa5a9fad879 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -279,6 +279,21 @@ static bool duty_mode_enabled(u8 pwm_enable) } } +static bool auto_mode_enabled(u8 pwm_enable) +{ + switch (pwm_enable) { + case 0: /* Manual, duty mode (full speed) */ + case 1: /* Manual, duty mode */ + case 3: /* Manual, speed mode */ + return false; + case 2: /* Auto, speed mode */ + case 4: /* Auto, duty mode */ + return true; + default: + BUG(); + } +} + static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -312,6 +327,11 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr, if (err < 0) return err; + if (auto_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; + if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; + mutex_lock(&data->update_lock); data->fan_target[nr] = rpm_to_reg(val); f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); @@ -332,6 +352,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, if (err < 0) return err; + if (auto_mode_enabled(data->pwm_enable[nr]) || + !duty_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; + mutex_lock(&data->update_lock); data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); f75375_write_pwm(client, nr); @@ -793,6 +817,9 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); for (nr = 0; nr < 2; nr++) { + if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) || + !duty_mode_enabled(f75375s_pdata->pwm_enable[nr])) + continue; data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); f75375_write_pwm(client, nr); } -- cgit v1.2.3 From 4de86126a712ba83fa038d277c8282f7ed466a4b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 5 Mar 2012 08:32:00 -0500 Subject: hwmon: (jc42) Add support for ST Microelectronics STTS2002 and STTS3000 These are fully compatible with Jedec JC 42.4 as far as I can see. Signed-off-by: Jean Delvare Cc: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ Signed-off-by: Guenter Roeck --- drivers/hwmon/Kconfig | 3 ++- drivers/hwmon/jc42.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 02260406b9e4..91a51aff5363 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -498,7 +498,8 @@ config SENSORS_JC42 temperature sensors, which are used on many DDR3 memory modules for mobile devices and servers. Support will include, but not be limited to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, - MCP9843, SE97, SE98, STTS424(E), TSE2002B3, and TS3000B3. + MCP9843, SE97, SE98, STTS424(E), STTS2002, STTS3000, TSE2002B3, and + TS3000B3. This driver can also be built as a module. If so, the module will be called jc42. diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 28c09eead36b..08430ecb306a 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -113,6 +113,12 @@ static const unsigned short normal_i2c[] = { #define STTS424E_DEVID 0x0000 #define STTS424E_DEVID_MASK 0xfffe +#define STTS2002_DEVID 0x0300 +#define STTS2002_DEVID_MASK 0xffff + +#define STTS3000_DEVID 0x0200 +#define STTS3000_DEVID_MASK 0xffff + static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 }; struct jc42_chips { @@ -133,6 +139,8 @@ static struct jc42_chips jc42_chips[] = { { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK }, { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, + { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, + { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, }; /* Each client has this additional data */ @@ -171,6 +179,8 @@ static const struct i2c_device_id jc42_id[] = { { "se97b", 0 }, { "se98", 0 }, { "stts424", 0 }, + { "stts2002", 0 }, + { "stts3000", 0 }, { "tse2002b3", 0 }, { "ts3000b3", 0 }, { } -- cgit v1.2.3 From 7cb3c44fb1f7999e4c53b6a52de6bc25da6de079 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 4 Mar 2012 08:10:57 -0800 Subject: hwmon: (pmbus_core) Fix maximum number of POUT alarm attributes There are up to three POUT alarm attributes, not two, since cap_alarm was added. Reported-by: Michele Petracca Cc: stable@vger.kernel.org # 3.0+ [3.0 will need backport] Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 00460d8d8423..d89b33967a85 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -54,7 +54,8 @@ lcrit_alarm, crit_alarm */ #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, crit_alarm */ -#define PMBUS_POUT_BOOLEANS_PER_PAGE 2 /* alarm, crit_alarm */ +#define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm + */ #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, lcrit_alarm, crit_alarm */ -- cgit v1.2.3 From 7ad6307ad6968ce25cecf209d4822d4c722be030 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 7 Mar 2012 03:58:55 -0800 Subject: hwmon: (zl6100) Maintain delay parameter in driver instance data A global delay parameter has the side effect of being overwritten with 0 if a single ZL2004 or ZL6105 is instantiated. If other chips supported by the same driver are in the system, this will result in access errors for those chips. To solve the problem, keep a per-instance copy of the delay parameter, and do not change the original parameter. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.1+ Acked-by: Jean Delvare --- drivers/hwmon/pmbus/zl6100.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 48c7b4a716ae..880b90cf4d32 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -33,6 +33,7 @@ enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; struct zl6100_data { int id; ktime_t access; /* chip access time */ + int delay; /* Delay between chip accesses in uS */ struct pmbus_driver_info info; }; @@ -52,10 +53,10 @@ MODULE_PARM_DESC(delay, "Delay between chip accesses in uS"); /* Some chips need a delay between accesses */ static inline void zl6100_wait(const struct zl6100_data *data) { - if (delay) { + if (data->delay) { s64 delta = ktime_us_delta(ktime_get(), data->access); - if (delta < delay) - udelay(delay - delta); + if (delta < data->delay) + udelay(data->delay - delta); } } @@ -207,8 +208,9 @@ static int zl6100_probe(struct i2c_client *client, * can be cleared later for additional chips if tests show that it * is not needed (in other words, better be safe than sorry). */ + data->delay = delay; if (data->id == zl2004 || data->id == zl6105) - delay = 0; + data->delay = 0; /* * Since there was a direct I2C device access above, wait before -- cgit v1.2.3 From 1bd612a25855f4cc9345052b53d7da697dba6358 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 5 Mar 2012 11:13:52 -0800 Subject: hwmon: (jc42) Add support for AT30TS00, TS3000GB2, TSE2002GB2, and MCP9804 Also update IDT datasheet locations. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.0+ Acked-by: Jean Delvare --- drivers/hwmon/Kconfig | 6 +++--- drivers/hwmon/jc42.c | 20 ++++++++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 91a51aff5363..dad895fec62a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -497,9 +497,9 @@ config SENSORS_JC42 If you say yes here, you get support for JEDEC JC42.4 compliant temperature sensors, which are used on many DDR3 memory modules for mobile devices and servers. Support will include, but not be limited - to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, - MCP9843, SE97, SE98, STTS424(E), STTS2002, STTS3000, TSE2002B3, and - TS3000B3. + to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, + MCP98242, MCP98243, MCP9843, SE97, SE98, STTS424(E), STTS2002, + STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2. This driver can also be built as a module. If so, the module will be called jc42. diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 08430ecb306a..b927ee5ccdd7 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -64,6 +64,7 @@ static const unsigned short normal_i2c[] = { /* Manufacturer IDs */ #define ADT_MANID 0x11d4 /* Analog Devices */ +#define ATMEL_MANID 0x001f /* Atmel */ #define MAX_MANID 0x004d /* Maxim */ #define IDT_MANID 0x00b3 /* IDT */ #define MCP_MANID 0x0054 /* Microchip */ @@ -77,15 +78,25 @@ static const unsigned short normal_i2c[] = { #define ADT7408_DEVID 0x0801 #define ADT7408_DEVID_MASK 0xffff +/* Atmel */ +#define AT30TS00_DEVID 0x8201 +#define AT30TS00_DEVID_MASK 0xffff + /* IDT */ #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ #define TS3000B3_DEVID_MASK 0xffff +#define TS3000GB2_DEVID 0x2912 /* Also matches TSE2002GB2 */ +#define TS3000GB2_DEVID_MASK 0xffff + /* Maxim */ #define MAX6604_DEVID 0x3e00 #define MAX6604_DEVID_MASK 0xffff /* Microchip */ +#define MCP9804_DEVID 0x0200 +#define MCP9804_DEVID_MASK 0xfffc + #define MCP98242_DEVID 0x2000 #define MCP98242_DEVID_MASK 0xfffc @@ -129,8 +140,11 @@ struct jc42_chips { static struct jc42_chips jc42_chips[] = { { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, + { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, + { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, + { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK }, @@ -167,10 +181,12 @@ static struct jc42_data *jc42_update_device(struct device *dev); static const struct i2c_device_id jc42_id[] = { { "adt7408", 0 }, + { "at30ts00", 0 }, { "cat94ts02", 0 }, { "cat6095", 0 }, { "jc42", 0 }, { "max6604", 0 }, + { "mcp9804", 0 }, { "mcp9805", 0 }, { "mcp98242", 0 }, { "mcp98243", 0 }, @@ -181,8 +197,8 @@ static const struct i2c_device_id jc42_id[] = { { "stts424", 0 }, { "stts2002", 0 }, { "stts3000", 0 }, - { "tse2002b3", 0 }, - { "ts3000b3", 0 }, + { "tse2002", 0 }, + { "ts3000", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, jc42_id); -- cgit v1.2.3