mirror of https://gitee.com/openkylin/linux.git
hwmon: (lm63) Let the user adjust the lookup table
Make the automatic fan speed control lookup table writable. This lets the user tweak the fan speed / temperature response curve. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com> Tested-by: Guenter Roeck <guenter.roeck@ericsson.com>
This commit is contained in:
parent
817c6cc546
commit
af2ef4fc04
|
@ -205,6 +205,15 @@ static inline int lut_temp_from_reg(struct lm63_data *data, int nr)
|
||||||
return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000);
|
return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int lut_temp_to_reg(struct lm63_data *data, long val)
|
||||||
|
{
|
||||||
|
val -= data->temp2_offset;
|
||||||
|
if (data->lut_temp_highres)
|
||||||
|
return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500);
|
||||||
|
else
|
||||||
|
return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the lookup table register cache.
|
* Update the lookup table register cache.
|
||||||
* client->update_lock must be held when calling this function.
|
* client->update_lock must be held when calling this function.
|
||||||
|
@ -387,13 +396,16 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr,
|
||||||
return sprintf(buf, "%d\n", pwm);
|
return sprintf(buf, "%d\n", pwm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
|
static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct lm63_data *data = i2c_get_clientdata(client);
|
struct lm63_data *data = i2c_get_clientdata(client);
|
||||||
|
int nr = attr->index;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int err;
|
int err;
|
||||||
|
u8 reg;
|
||||||
|
|
||||||
if (!(data->config_fan & 0x20)) /* register is read-only */
|
if (!(data->config_fan & 0x20)) /* register is read-only */
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -402,11 +414,13 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE;
|
||||||
val = SENSORS_LIMIT(val, 0, 255);
|
val = SENSORS_LIMIT(val, 0, 255);
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
mutex_lock(&data->update_lock);
|
||||||
data->pwm1[0] = data->pwm_highres ? val :
|
data->pwm1[nr] = data->pwm_highres ? val :
|
||||||
(val * data->pwm1_freq * 2 + 127) / 255;
|
(val * data->pwm1_freq * 2 + 127) / 255;
|
||||||
i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]);
|
i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]);
|
||||||
mutex_unlock(&data->update_lock);
|
mutex_unlock(&data->update_lock);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -495,23 +509,31 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct lm63_data *data = i2c_get_clientdata(client);
|
struct lm63_data *data = i2c_get_clientdata(client);
|
||||||
int nr = attr->index;
|
int nr = attr->index;
|
||||||
int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH;
|
|
||||||
long val;
|
long val;
|
||||||
int err;
|
int err;
|
||||||
int temp;
|
int temp;
|
||||||
|
u8 reg;
|
||||||
|
|
||||||
err = kstrtol(buf, 10, &val);
|
err = kstrtol(buf, 10, &val);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
mutex_lock(&data->update_lock);
|
||||||
if (nr == 2) {
|
switch (nr) {
|
||||||
|
case 2:
|
||||||
|
reg = LM63_REG_REMOTE_TCRIT;
|
||||||
if (data->remote_unsigned)
|
if (data->remote_unsigned)
|
||||||
temp = TEMP8U_TO_REG(val - data->temp2_offset);
|
temp = TEMP8U_TO_REG(val - data->temp2_offset);
|
||||||
else
|
else
|
||||||
temp = TEMP8_TO_REG(val - data->temp2_offset);
|
temp = TEMP8_TO_REG(val - data->temp2_offset);
|
||||||
} else {
|
break;
|
||||||
|
case 1:
|
||||||
|
reg = LM63_REG_LOCAL_HIGH;
|
||||||
temp = TEMP8_TO_REG(val);
|
temp = TEMP8_TO_REG(val);
|
||||||
|
break;
|
||||||
|
default: /* lookup table */
|
||||||
|
reg = LM63_REG_LUT_TEMP(nr - 3);
|
||||||
|
temp = lut_temp_to_reg(data, val);
|
||||||
}
|
}
|
||||||
data->temp8[nr] = temp;
|
data->temp8[nr] = temp;
|
||||||
i2c_smbus_write_byte_data(client, reg, temp);
|
i2c_smbus_write_byte_data(client, reg, temp);
|
||||||
|
@ -743,64 +765,76 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0);
|
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0);
|
||||||
static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
|
static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
|
||||||
show_pwm1_enable, set_pwm1_enable);
|
show_pwm1_enable, set_pwm1_enable);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 1);
|
||||||
show_lut_temp, NULL, 3);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 3);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 3);
|
show_lut_temp_hyst, NULL, 3);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 2);
|
||||||
show_lut_temp, NULL, 4);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 4);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 4);
|
show_lut_temp_hyst, NULL, 4);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 3);
|
||||||
show_lut_temp, NULL, 5);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 5);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 5);
|
show_lut_temp_hyst, NULL, 5);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 4);
|
||||||
show_lut_temp, NULL, 6);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 6);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 6);
|
show_lut_temp_hyst, NULL, 6);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 5);
|
||||||
show_lut_temp, NULL, 7);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 7);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 7);
|
show_lut_temp_hyst, NULL, 7);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 6);
|
||||||
show_lut_temp, NULL, 8);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 8);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 8);
|
show_lut_temp_hyst, NULL, 8);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 7);
|
||||||
show_lut_temp, NULL, 9);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 9);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 9);
|
show_lut_temp_hyst, NULL, 9);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 8);
|
||||||
show_lut_temp, NULL, 10);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 10);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 10);
|
show_lut_temp_hyst, NULL, 10);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 9);
|
||||||
show_lut_temp, NULL, 11);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 11);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 11);
|
show_lut_temp_hyst, NULL, 11);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 10);
|
||||||
show_lut_temp, NULL, 12);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 12);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 12);
|
show_lut_temp_hyst, NULL, 12);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 11);
|
||||||
show_lut_temp, NULL, 13);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 13);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 13);
|
show_lut_temp_hyst, NULL, 13);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IWUSR | S_IRUGO,
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO,
|
show_pwm1, set_pwm1, 12);
|
||||||
show_lut_temp, NULL, 14);
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IWUSR | S_IRUGO,
|
||||||
|
show_lut_temp, set_temp8, 14);
|
||||||
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO,
|
||||||
show_lut_temp_hyst, NULL, 14);
|
show_lut_temp_hyst, NULL, 14);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue