aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f75375s.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/f75375s.c')
-rw-r--r--drivers/hwmon/f75375s.c42
1 files changed, 34 insertions, 8 deletions
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)
264 return 1500000 / rpm; 264 return 1500000 / rpm;
265} 265}
266 266
267static bool duty_mode_enabled(u8 pwm_enable)
268{
269 switch (pwm_enable) {
270 case 0: /* Manual, duty mode (full speed) */
271 case 1: /* Manual, duty mode */
272 case 4: /* Auto, duty mode */
273 return true;
274 case 2: /* Auto, speed mode */
275 case 3: /* Manual, speed mode */
276 return false;
277 default:
278 BUG();
279 }
280}
281
267static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 282static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
268 const char *buf, size_t count) 283 const char *buf, size_t count)
269{ 284{
@@ -337,11 +352,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
337 struct f75375_data *data = i2c_get_clientdata(client); 352 struct f75375_data *data = i2c_get_clientdata(client);
338 u8 fanmode; 353 u8 fanmode;
339 354
340 if (val < 0 || val > 3) 355 if (val < 0 || val > 4)
341 return -EINVAL; 356 return -EINVAL;
342 357
343 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); 358 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
344 if (data->kind == f75387) { 359 if (data->kind == f75387) {
360 /* For now, deny dangerous toggling of duty mode */
361 if (duty_mode_enabled(data->pwm_enable[nr]) !=
362 duty_mode_enabled(val))
363 return -EOPNOTSUPP;
345 /* clear each fanX_mode bit before setting them properly */ 364 /* clear each fanX_mode bit before setting them properly */
346 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); 365 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
347 fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); 366 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)
355 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 374 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
356 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 375 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
357 break; 376 break;
358 case 2: /* AUTOMATIC*/ 377 case 2: /* Automatic, speed mode */
359 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
360 break; 378 break;
361 case 3: /* fan speed */ 379 case 3: /* fan speed */
362 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 380 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
363 break; 381 break;
382 case 4: /* Automatic, pwm */
383 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
384 break;
364 } 385 }
365 } else { 386 } else {
366 /* clear each fanX_mode bit before setting them properly */ 387 /* 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)
378 break; 399 break;
379 case 3: /* fan speed */ 400 case 3: /* fan speed */
380 break; 401 break;
402 case 4: /* Automatic pwm */
403 return -EINVAL;
381 } 404 }
382 } 405 }
383 406
@@ -735,14 +758,17 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
735 758
736 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); 759 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
737 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); 760 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
738 if (manu && duty) 761 if (!manu && duty)
739 /* speed */ 762 /* auto, pwm */
763 data->pwm_enable[nr] = 4;
764 else if (manu && !duty)
765 /* manual, speed */
740 data->pwm_enable[nr] = 3; 766 data->pwm_enable[nr] = 3;
741 else if (!manu && duty) 767 else if (!manu && !duty)
742 /* automatic */ 768 /* automatic, speed */
743 data->pwm_enable[nr] = 2; 769 data->pwm_enable[nr] = 2;
744 else 770 else
745 /* manual */ 771 /* manual, pwm */
746 data->pwm_enable[nr] = 1; 772 data->pwm_enable[nr] = 1;
747 } else { 773 } else {
748 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) 774 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))