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.c103
1 files changed, 81 insertions, 22 deletions
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index eedf574ab539..6aa5a9fad879 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -172,12 +172,22 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg,
172static inline void f75375_write16(struct i2c_client *client, u8 reg, 172static inline void f75375_write16(struct i2c_client *client, u8 reg,
173 u16 value) 173 u16 value)
174{ 174{
175 int err = i2c_smbus_write_byte_data(client, reg, (value << 8)); 175 int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
176 if (err) 176 if (err)
177 return; 177 return;
178 i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); 178 i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
179} 179}
180 180
181static void f75375_write_pwm(struct i2c_client *client, int nr)
182{
183 struct f75375_data *data = i2c_get_clientdata(client);
184 if (data->kind == f75387)
185 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]);
186 else
187 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
188 data->pwm[nr]);
189}
190
181static struct f75375_data *f75375_update_device(struct device *dev) 191static struct f75375_data *f75375_update_device(struct device *dev)
182{ 192{
183 struct i2c_client *client = to_i2c_client(dev); 193 struct i2c_client *client = to_i2c_client(dev);
@@ -200,9 +210,6 @@ static struct f75375_data *f75375_update_device(struct device *dev)
200 f75375_read16(client, F75375_REG_FAN_MIN(nr)); 210 f75375_read16(client, F75375_REG_FAN_MIN(nr));
201 data->fan_target[nr] = 211 data->fan_target[nr] =
202 f75375_read16(client, F75375_REG_FAN_EXP(nr)); 212 f75375_read16(client, F75375_REG_FAN_EXP(nr));
203 data->pwm[nr] = f75375_read8(client,
204 F75375_REG_FAN_PWM_DUTY(nr));
205
206 } 213 }
207 for (nr = 0; nr < 4; nr++) { 214 for (nr = 0; nr < 4; nr++) {
208 data->in_max[nr] = 215 data->in_max[nr] =
@@ -218,6 +225,8 @@ static struct f75375_data *f75375_update_device(struct device *dev)
218 if (time_after(jiffies, data->last_updated + 2 * HZ) 225 if (time_after(jiffies, data->last_updated + 2 * HZ)
219 || !data->valid) { 226 || !data->valid) {
220 for (nr = 0; nr < 2; nr++) { 227 for (nr = 0; nr < 2; nr++) {
228 data->pwm[nr] = f75375_read8(client,
229 F75375_REG_FAN_PWM_DUTY(nr));
221 /* assign MSB, therefore shift it by 8 bits */ 230 /* assign MSB, therefore shift it by 8 bits */
222 data->temp11[nr] = 231 data->temp11[nr] =
223 f75375_read8(client, F75375_REG_TEMP(nr)) << 8; 232 f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
@@ -255,6 +264,36 @@ static inline u16 rpm_to_reg(int rpm)
255 return 1500000 / rpm; 264 return 1500000 / rpm;
256} 265}
257 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
282static bool auto_mode_enabled(u8 pwm_enable)
283{
284 switch (pwm_enable) {
285 case 0: /* Manual, duty mode (full speed) */
286 case 1: /* Manual, duty mode */
287 case 3: /* Manual, speed mode */
288 return false;
289 case 2: /* Auto, speed mode */
290 case 4: /* Auto, duty mode */
291 return true;
292 default:
293 BUG();
294 }
295}
296
258static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 297static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
259 const char *buf, size_t count) 298 const char *buf, size_t count)
260{ 299{
@@ -288,6 +327,11 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr,
288 if (err < 0) 327 if (err < 0)
289 return err; 328 return err;
290 329
330 if (auto_mode_enabled(data->pwm_enable[nr]))
331 return -EINVAL;
332 if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr]))
333 return -EINVAL;
334
291 mutex_lock(&data->update_lock); 335 mutex_lock(&data->update_lock);
292 data->fan_target[nr] = rpm_to_reg(val); 336 data->fan_target[nr] = rpm_to_reg(val);
293 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); 337 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]);
@@ -308,9 +352,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
308 if (err < 0) 352 if (err < 0)
309 return err; 353 return err;
310 354
355 if (auto_mode_enabled(data->pwm_enable[nr]) ||
356 !duty_mode_enabled(data->pwm_enable[nr]))
357 return -EINVAL;
358
311 mutex_lock(&data->update_lock); 359 mutex_lock(&data->update_lock);
312 data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); 360 data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
313 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); 361 f75375_write_pwm(client, nr);
314 mutex_unlock(&data->update_lock); 362 mutex_unlock(&data->update_lock);
315 return count; 363 return count;
316} 364}
@@ -328,11 +376,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
328 struct f75375_data *data = i2c_get_clientdata(client); 376 struct f75375_data *data = i2c_get_clientdata(client);
329 u8 fanmode; 377 u8 fanmode;
330 378
331 if (val < 0 || val > 3) 379 if (val < 0 || val > 4)
332 return -EINVAL; 380 return -EINVAL;
333 381
334 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); 382 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
335 if (data->kind == f75387) { 383 if (data->kind == f75387) {
384 /* For now, deny dangerous toggling of duty mode */
385 if (duty_mode_enabled(data->pwm_enable[nr]) !=
386 duty_mode_enabled(val))
387 return -EOPNOTSUPP;
336 /* clear each fanX_mode bit before setting them properly */ 388 /* clear each fanX_mode bit before setting them properly */
337 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); 389 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
338 fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); 390 fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr));
@@ -341,19 +393,19 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
341 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 393 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
342 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 394 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
343 data->pwm[nr] = 255; 395 data->pwm[nr] = 255;
344 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
345 data->pwm[nr]);
346 break; 396 break;
347 case 1: /* PWM */ 397 case 1: /* PWM */
348 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 398 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
349 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 399 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
350 break; 400 break;
351 case 2: /* AUTOMATIC*/ 401 case 2: /* Automatic, speed mode */
352 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
353 break; 402 break;
354 case 3: /* fan speed */ 403 case 3: /* fan speed */
355 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 404 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
356 break; 405 break;
406 case 4: /* Automatic, pwm */
407 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
408 break;
357 } 409 }
358 } else { 410 } else {
359 /* clear each fanX_mode bit before setting them properly */ 411 /* clear each fanX_mode bit before setting them properly */
@@ -362,22 +414,24 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
362 case 0: /* full speed */ 414 case 0: /* full speed */
363 fanmode |= (3 << FAN_CTRL_MODE(nr)); 415 fanmode |= (3 << FAN_CTRL_MODE(nr));
364 data->pwm[nr] = 255; 416 data->pwm[nr] = 255;
365 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
366 data->pwm[nr]);
367 break; 417 break;
368 case 1: /* PWM */ 418 case 1: /* PWM */
369 fanmode |= (3 << FAN_CTRL_MODE(nr)); 419 fanmode |= (3 << FAN_CTRL_MODE(nr));
370 break; 420 break;
371 case 2: /* AUTOMATIC*/ 421 case 2: /* AUTOMATIC*/
372 fanmode |= (2 << FAN_CTRL_MODE(nr)); 422 fanmode |= (1 << FAN_CTRL_MODE(nr));
373 break; 423 break;
374 case 3: /* fan speed */ 424 case 3: /* fan speed */
375 break; 425 break;
426 case 4: /* Automatic pwm */
427 return -EINVAL;
376 } 428 }
377 } 429 }
378 430
379 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); 431 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
380 data->pwm_enable[nr] = val; 432 data->pwm_enable[nr] = val;
433 if (val == 0)
434 f75375_write_pwm(client, nr);
381 return 0; 435 return 0;
382} 436}
383 437
@@ -723,19 +777,22 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
723 if (data->kind == f75387) { 777 if (data->kind == f75387) {
724 bool manu, duty; 778 bool manu, duty;
725 779
726 if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr)))) 780 if (!(mode & (1 << F75387_FAN_CTRL_LINEAR(nr))))
727 data->pwm_mode[nr] = 1; 781 data->pwm_mode[nr] = 1;
728 782
729 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); 783 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
730 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); 784 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
731 if (manu && duty) 785 if (!manu && duty)
732 /* speed */ 786 /* auto, pwm */
787 data->pwm_enable[nr] = 4;
788 else if (manu && !duty)
789 /* manual, speed */
733 data->pwm_enable[nr] = 3; 790 data->pwm_enable[nr] = 3;
734 else if (!manu && duty) 791 else if (!manu && !duty)
735 /* automatic */ 792 /* automatic, speed */
736 data->pwm_enable[nr] = 2; 793 data->pwm_enable[nr] = 2;
737 else 794 else
738 /* manual */ 795 /* manual, pwm */
739 data->pwm_enable[nr] = 1; 796 data->pwm_enable[nr] = 1;
740 } else { 797 } else {
741 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) 798 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))
@@ -760,9 +817,11 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
760 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); 817 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
761 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); 818 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
762 for (nr = 0; nr < 2; nr++) { 819 for (nr = 0; nr < 2; nr++) {
820 if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) ||
821 !duty_mode_enabled(f75375s_pdata->pwm_enable[nr]))
822 continue;
763 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); 823 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
764 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), 824 f75375_write_pwm(client, nr);
765 data->pwm[nr]);
766 } 825 }
767 826
768} 827}
@@ -789,7 +848,7 @@ static int f75375_probe(struct i2c_client *client,
789 if (err) 848 if (err)
790 goto exit_free; 849 goto exit_free;
791 850
792 if (data->kind == f75375) { 851 if (data->kind != f75373) {
793 err = sysfs_chmod_file(&client->dev.kobj, 852 err = sysfs_chmod_file(&client->dev.kobj,
794 &sensor_dev_attr_pwm1_mode.dev_attr.attr, 853 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
795 S_IRUGO | S_IWUSR); 854 S_IRUGO | S_IWUSR);