Commit cea0d767 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  hwmon: (applesmc) Correct sysfs fan error handling
  hwmon: (asc7621) Bug fixes
parents b2464ab2 0559a538
...@@ -195,6 +195,9 @@ static unsigned int applesmc_accelerometer; ...@@ -195,6 +195,9 @@ static unsigned int applesmc_accelerometer;
/* Indicates whether this computer has light sensors and keyboard backlight. */ /* Indicates whether this computer has light sensors and keyboard backlight. */
static unsigned int applesmc_light; static unsigned int applesmc_light;
/* The number of fans handled by the driver */
static unsigned int fans_handled;
/* Indicates which temperature sensors set to use. */ /* Indicates which temperature sensors set to use. */
static unsigned int applesmc_temperature_set; static unsigned int applesmc_temperature_set;
...@@ -1492,39 +1495,24 @@ static int __init applesmc_init(void) ...@@ -1492,39 +1495,24 @@ static int __init applesmc_init(void)
/* create fan files */ /* create fan files */
count = applesmc_get_fan_count(); count = applesmc_get_fan_count();
if (count < 0) { if (count < 0)
printk(KERN_ERR "applesmc: Cannot get the number of fans.\n"); printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
} else { else
printk(KERN_INFO "applesmc: %d fans found.\n", count); printk(KERN_INFO "applesmc: %d fans found.\n", count);
switch (count) { if (count > 4) {
default: count = 4;
printk(KERN_WARNING "applesmc: More than 4 fans found," printk(KERN_WARNING "applesmc: More than 4 fans found,"
" but at most 4 fans are supported" " but at most 4 fans are supported"
" by the driver.\n"); " by the driver.\n");
case 4: }
ret = sysfs_create_group(&pdev->dev.kobj,
&fan_attribute_groups[3]); while (fans_handled < count) {
if (ret)
goto out_key_enumeration;
case 3:
ret = sysfs_create_group(&pdev->dev.kobj,
&fan_attribute_groups[2]);
if (ret)
goto out_key_enumeration;
case 2:
ret = sysfs_create_group(&pdev->dev.kobj,
&fan_attribute_groups[1]);
if (ret)
goto out_key_enumeration;
case 1:
ret = sysfs_create_group(&pdev->dev.kobj, ret = sysfs_create_group(&pdev->dev.kobj,
&fan_attribute_groups[0]); &fan_attribute_groups[fans_handled]);
if (ret) if (ret)
goto out_fan_1; goto out_fans;
case 0: fans_handled++;
;
}
} }
for (i = 0; for (i = 0;
...@@ -1593,10 +1581,10 @@ out_accelerometer: ...@@ -1593,10 +1581,10 @@ out_accelerometer:
applesmc_release_accelerometer(); applesmc_release_accelerometer();
out_temperature: out_temperature:
sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); out_fans:
out_fan_1: while (fans_handled)
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); sysfs_remove_group(&pdev->dev.kobj,
out_key_enumeration: &fan_attribute_groups[--fans_handled]);
sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
out_name: out_name:
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
...@@ -1622,8 +1610,9 @@ static void __exit applesmc_exit(void) ...@@ -1622,8 +1610,9 @@ static void __exit applesmc_exit(void)
if (applesmc_accelerometer) if (applesmc_accelerometer)
applesmc_release_accelerometer(); applesmc_release_accelerometer();
sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); while (fans_handled)
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); sysfs_remove_group(&pdev->dev.kobj,
&fan_attribute_groups[--fans_handled]);
sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
platform_device_unregister(pdev); platform_device_unregister(pdev);
......
...@@ -268,8 +268,11 @@ static ssize_t store_fan16(struct device *dev, ...@@ -268,8 +268,11 @@ static ssize_t store_fan16(struct device *dev,
if (strict_strtol(buf, 10, &reqval)) if (strict_strtol(buf, 10, &reqval))
return -EINVAL; return -EINVAL;
/* If a minimum RPM of zero is requested, then we set the register to
0xffff. This value allows the fan to be stopped completely without
generating an alarm. */
reqval = reqval =
(SENSORS_LIMIT((reqval) <= 0 ? 0 : 5400000 / (reqval), 0, 65534)); (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->reg[param->msb[0]] = (reqval >> 8) & 0xff; data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
...@@ -285,8 +288,9 @@ static ssize_t store_fan16(struct device *dev, ...@@ -285,8 +288,9 @@ static ssize_t store_fan16(struct device *dev,
* Voltages are scaled in the device so that the nominal voltage * Voltages are scaled in the device so that the nominal voltage
* is 3/4ths of the 0-255 range (i.e. 192). * is 3/4ths of the 0-255 range (i.e. 192).
* If all voltages are 'normal' then all voltage registers will * If all voltages are 'normal' then all voltage registers will
* read 0xC0. This doesn't help us if we don't have a point of refernce. * read 0xC0.
* The data sheet however provides us with the full scale value for each *
* The data sheet provides us with the 3/4 scale value for each voltage
* which is stored in in_scaling. The sda->index parameter value provides * which is stored in in_scaling. The sda->index parameter value provides
* the index into in_scaling. * the index into in_scaling.
* *
...@@ -295,7 +299,7 @@ static ssize_t store_fan16(struct device *dev, ...@@ -295,7 +299,7 @@ static ssize_t store_fan16(struct device *dev,
*/ */
static int asc7621_in_scaling[] = { static int asc7621_in_scaling[] = {
3320, 3000, 4380, 6640, 16000 2500, 2250, 3300, 5000, 12000
}; };
static ssize_t show_in10(struct device *dev, struct device_attribute *attr, static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
...@@ -306,19 +310,12 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr, ...@@ -306,19 +310,12 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
u8 nr = sda->index; u8 nr = sda->index;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
regval = (data->reg[param->msb[0]] * asc7621_in_scaling[nr]) / 256; regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
/* The LSB value is a 2-bit scaling of the MSB's LSbit value.
* I.E. If the maximim voltage for this input is 6640 millivolts then
* a MSB register value of 0 = 0mv and 255 = 6640mv.
* A 1 step change therefore represents 25.9mv (6640 / 256).
* The extra 2-bits therefore represent increments of 6.48mv.
*/
regval += ((asc7621_in_scaling[nr] / 256) / 4) *
(data->reg[param->lsb[0]] >> 6);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
/* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
return sprintf(buf, "%u\n", regval); return sprintf(buf, "%u\n", regval);
} }
...@@ -331,7 +328,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr, ...@@ -331,7 +328,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "%u\n", return sprintf(buf, "%u\n",
((data->reg[param->msb[0]] * ((data->reg[param->msb[0]] *
asc7621_in_scaling[nr]) / 256)); asc7621_in_scaling[nr]) / 0xc0));
} }
static ssize_t store_in8(struct device *dev, struct device_attribute *attr, static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
...@@ -344,9 +341,11 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr, ...@@ -344,9 +341,11 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
if (strict_strtol(buf, 10, &reqval)) if (strict_strtol(buf, 10, &reqval))
return -EINVAL; return -EINVAL;
reqval = SENSORS_LIMIT(reqval, 0, asc7621_in_scaling[nr]); reqval = SENSORS_LIMIT(reqval, 0, 0xffff);
reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
reqval = (reqval * 255 + 128) / asc7621_in_scaling[nr]; reqval = SENSORS_LIMIT(reqval, 0, 0xff);
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->reg[param->msb[0]] = reqval; data->reg[param->msb[0]] = reqval;
...@@ -846,11 +845,11 @@ static struct asc7621_param asc7621_params[] = { ...@@ -846,11 +845,11 @@ static struct asc7621_param asc7621_params[] = {
PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8), PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8), PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
PREAD(in0_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 0, bitmask), PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
PREAD(in1_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 1, bitmask), PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
PREAD(in2_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 2, bitmask), PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
PREAD(in3_alarm, 3, PRI_LOW, 0x41, 0, 0x01, 3, bitmask), PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
PREAD(in4_alarm, 4, PRI_LOW, 0x42, 0, 0x01, 0, bitmask), PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16), PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16), PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
...@@ -862,10 +861,10 @@ static struct asc7621_param asc7621_params[] = { ...@@ -862,10 +861,10 @@ static struct asc7621_param asc7621_params[] = {
PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16), PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16), PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
PREAD(fan1_alarm, 0, PRI_LOW, 0x42, 0, 0x01, 0, bitmask), PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
PREAD(fan2_alarm, 1, PRI_LOW, 0x42, 0, 0x01, 1, bitmask), PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
PREAD(fan3_alarm, 2, PRI_LOW, 0x42, 0, 0x01, 2, bitmask), PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
PREAD(fan4_alarm, 3, PRI_LOW, 0x42, 0, 0x01, 3, bitmask), PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10), PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10), PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
...@@ -886,10 +885,10 @@ static struct asc7621_param asc7621_params[] = { ...@@ -886,10 +885,10 @@ static struct asc7621_param asc7621_params[] = {
PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8), PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8), PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
PREAD(temp1_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 4, bitmask), PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
PREAD(temp2_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 5, bitmask), PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
PREAD(temp3_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 6, bitmask), PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
PREAD(temp4_alarm, 3, PRI_LOW, 0x43, 0, 0x01, 0, bitmask), PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask), PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask), PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
...@@ -898,7 +897,7 @@ static struct asc7621_param asc7621_params[] = { ...@@ -898,7 +897,7 @@ static struct asc7621_param asc7621_params[] = {
PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask), PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask), PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x64, 0, 0x01, 3, bitmask), PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask), PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st), PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment