aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 14a5d981be7d..a428a9264195 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
187#define IT87_REG_FAN_MAIN_CTRL 0x13 187#define IT87_REG_FAN_MAIN_CTRL 0x13
188#define IT87_REG_FAN_CTL 0x14 188#define IT87_REG_FAN_CTL 0x14
189#define IT87_REG_PWM(nr) (0x15 + (nr)) 189#define IT87_REG_PWM(nr) (0x15 + (nr))
190#define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8)
190 191
191#define IT87_REG_VIN(nr) (0x20 + (nr)) 192#define IT87_REG_VIN(nr) (0x20 + (nr))
192#define IT87_REG_TEMP(nr) (0x29 + (nr)) 193#define IT87_REG_TEMP(nr) (0x29 + (nr))
@@ -251,12 +252,16 @@ struct it87_data {
251 u8 fan_main_ctrl; /* Register value */ 252 u8 fan_main_ctrl; /* Register value */
252 u8 fan_ctl; /* Register value */ 253 u8 fan_ctl; /* Register value */
253 254
254 /* The following 3 arrays correspond to the same registers. The 255 /* The following 3 arrays correspond to the same registers up to
255 * meaning of bits 6-0 depends on the value of bit 7, and we want 256 * the IT8720F. The meaning of bits 6-0 depends on the value of bit
256 * to preserve settings on mode changes, so we have to track all 257 * 7, and we want to preserve settings on mode changes, so we have
257 * values separately. */ 258 * to track all values separately.
259 * Starting with the IT8721F, the manual PWM duty cycles are stored
260 * in separate registers (8-bit values), so the separate tracking
261 * is no longer needed, but it is still done to keep the driver
262 * simple. */
258 u8 pwm_ctrl[3]; /* Register value */ 263 u8 pwm_ctrl[3]; /* Register value */
259 u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */ 264 u8 pwm_duty[3]; /* Manual PWM value set by user */
260 u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ 265 u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
261 266
262 /* Automatic fan speed control registers */ 267 /* Automatic fan speed control registers */
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev,
832 data->fan_main_ctrl); 837 data->fan_main_ctrl);
833 } else { 838 } else {
834 if (val == 1) /* Manual mode */ 839 if (val == 1) /* Manual mode */
835 data->pwm_ctrl[nr] = data->pwm_duty[nr]; 840 data->pwm_ctrl[nr] = data->type == it8721 ?
841 data->pwm_temp_map[nr] :
842 data->pwm_duty[nr];
836 else /* Automatic mode */ 843 else /* Automatic mode */
837 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; 844 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
838 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); 845 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
858 return -EINVAL; 865 return -EINVAL;
859 866
860 mutex_lock(&data->update_lock); 867 mutex_lock(&data->update_lock);
861 data->pwm_duty[nr] = pwm_to_reg(data, val); 868 if (data->type == it8721) {
862 /* If we are in manual mode, write the duty cycle immediately; 869 /* If we are in automatic mode, the PWM duty cycle register
863 * otherwise, just store it for later use. */ 870 * is read-only so we can't write the value */
864 if (!(data->pwm_ctrl[nr] & 0x80)) { 871 if (data->pwm_ctrl[nr] & 0x80) {
865 data->pwm_ctrl[nr] = data->pwm_duty[nr]; 872 mutex_unlock(&data->update_lock);
866 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); 873 return -EBUSY;
874 }
875 data->pwm_duty[nr] = pwm_to_reg(data, val);
876 it87_write_value(data, IT87_REG_PWM_DUTY(nr),
877 data->pwm_duty[nr]);
878 } else {
879 data->pwm_duty[nr] = pwm_to_reg(data, val);
880 /* If we are in manual mode, write the duty cycle immediately;
881 * otherwise, just store it for later use. */
882 if (!(data->pwm_ctrl[nr] & 0x80)) {
883 data->pwm_ctrl[nr] = data->pwm_duty[nr];
884 it87_write_value(data, IT87_REG_PWM(nr),
885 data->pwm_ctrl[nr]);
886 }
867 } 887 }
868 mutex_unlock(&data->update_lock); 888 mutex_unlock(&data->update_lock);
869 return count; 889 return count;
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1958 * channels to use when later setting to automatic mode later. 1978 * channels to use when later setting to automatic mode later.
1959 * Use a 1:1 mapping by default (we are clueless.) 1979 * Use a 1:1 mapping by default (we are clueless.)
1960 * In both cases, the value can (and should) be changed by the user 1980 * In both cases, the value can (and should) be changed by the user
1961 * prior to switching to a different mode. */ 1981 * prior to switching to a different mode.
1982 * Note that this is no longer needed for the IT8721F and later, as
1983 * these have separate registers for the temperature mapping and the
1984 * manual duty cycle. */
1962 for (i = 0; i < 3; i++) { 1985 for (i = 0; i < 3; i++) {
1963 data->pwm_temp_map[i] = i; 1986 data->pwm_temp_map[i] = i;
1964 data->pwm_duty[i] = 0x7f; /* Full speed */ 1987 data->pwm_duty[i] = 0x7f; /* Full speed */
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev)
2034static void it87_update_pwm_ctrl(struct it87_data *data, int nr) 2057static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
2035{ 2058{
2036 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); 2059 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
2037 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ 2060 if (data->type == it8721) {
2038 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; 2061 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
2039 else /* Manual mode */ 2062 data->pwm_duty[nr] = it87_read_value(data,
2040 data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; 2063 IT87_REG_PWM_DUTY(nr));
2064 } else {
2065 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
2066 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
2067 else /* Manual mode */
2068 data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
2069 }
2041 2070
2042 if (has_old_autopwm(data)) { 2071 if (has_old_autopwm(data)) {
2043 int i; 2072 int i;