aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gerhart <oss@extracloud.de>2011-12-13 13:19:58 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2012-01-05 11:19:32 -0500
commitf58c44e698a8362d2ab2d1c966ca80b748ff9ff9 (patch)
treebd60a488afc116ece796fa24238437dea42b55a7
parent5cd3222a9f3742e3da6becbd1a939e1221e030c4 (diff)
hwmon: (f75375s) Add support for F75387SG/RG
Fintek F75387SG/RG is mostly compatible to F75373/F75375. Add support for it to the F75375S driver. Fan support for F75387SG/RG has been implemented but not tested. Cc: Riku Voipio <riku.voipio@iki.fi> Signed-off-by: Bjoern Gerhart <oss@extracloud.de> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/f75375s.c175
2 files changed, 130 insertions, 49 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 91be41f60809..cb351d358387 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -367,11 +367,11 @@ config SENSORS_F71882FG
367 will be called f71882fg. 367 will be called f71882fg.
368 368
369config SENSORS_F75375S 369config SENSORS_F75375S
370 tristate "Fintek F75375S/SP and F75373" 370 tristate "Fintek F75375S/SP, F75373 and F75387"
371 depends on I2C 371 depends on I2C
372 help 372 help
373 If you say yes here you get support for hardware monitoring 373 If you say yes here you get support for hardware monitoring
374 features of the Fintek F75375S/SP and F75373 374 features of the Fintek F75375S/SP, F75373 and F75387
375 375
376 This driver can also be built as a module. If so, the module 376 This driver can also be built as a module. If so, the module
377 will be called f75375s. 377 will be called f75375s.
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 35b570e56ff0..eedf574ab539 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * f75375s.c - driver for the Fintek F75375/SP and F75373 2 * f75375s.c - driver for the Fintek F75375/SP, F75373 and
3 * hardware monitoring features 3 * F75387SG/RG hardware monitoring features
4 * Copyright (C) 2006-2007 Riku Voipio 4 * Copyright (C) 2006-2007 Riku Voipio
5 * 5 *
6 * Datasheets available at: 6 * Datasheets available at:
@@ -11,6 +11,9 @@
11 * f75373: 11 * f75373:
12 * http://www.fintek.com.tw/files/productfiles/F75373_V025P.pdf 12 * http://www.fintek.com.tw/files/productfiles/F75373_V025P.pdf
13 * 13 *
14 * f75387:
15 * http://www.fintek.com.tw/files/productfiles/F75387_V027P.pdf
16 *
14 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or 19 * the Free Software Foundation; either version 2 of the License, or
@@ -40,7 +43,7 @@
40/* Addresses to scan */ 43/* Addresses to scan */
41static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; 44static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
42 45
43enum chips { f75373, f75375 }; 46enum chips { f75373, f75375, f75387 };
44 47
45/* Fintek F75375 registers */ 48/* Fintek F75375 registers */
46#define F75375_REG_CONFIG0 0x0 49#define F75375_REG_CONFIG0 0x0
@@ -59,6 +62,7 @@ enum chips { f75373, f75375 };
59#define F75375_REG_VOLT_LOW(nr) (0x21 + (nr) * 2) 62#define F75375_REG_VOLT_LOW(nr) (0x21 + (nr) * 2)
60 63
61#define F75375_REG_TEMP(nr) (0x14 + (nr)) 64#define F75375_REG_TEMP(nr) (0x14 + (nr))
65#define F75387_REG_TEMP11_LSB(nr) (0x1a + (nr))
62#define F75375_REG_TEMP_HIGH(nr) (0x28 + (nr) * 2) 66#define F75375_REG_TEMP_HIGH(nr) (0x28 + (nr) * 2)
63#define F75375_REG_TEMP_HYST(nr) (0x29 + (nr) * 2) 67#define F75375_REG_TEMP_HYST(nr) (0x29 + (nr) * 2)
64 68
@@ -78,8 +82,11 @@ enum chips { f75373, f75375 };
78#define F75375_REG_PWM1_DROP_DUTY 0x6B 82#define F75375_REG_PWM1_DROP_DUTY 0x6B
79#define F75375_REG_PWM2_DROP_DUTY 0x6C 83#define F75375_REG_PWM2_DROP_DUTY 0x6C
80 84
81#define FAN_CTRL_LINEAR(nr) (4 + nr) 85#define F75375_FAN_CTRL_LINEAR(nr) (4 + nr)
86#define F75387_FAN_CTRL_LINEAR(nr) (1 + ((nr) * 4))
82#define FAN_CTRL_MODE(nr) (4 + ((nr) * 2)) 87#define FAN_CTRL_MODE(nr) (4 + ((nr) * 2))
88#define F75387_FAN_DUTY_MODE(nr) (2 + ((nr) * 4))
89#define F75387_FAN_MANU_MODE(nr) ((nr) * 4)
83 90
84/* 91/*
85 * Data structures and manipulation thereof 92 * Data structures and manipulation thereof
@@ -108,7 +115,12 @@ struct f75375_data {
108 u8 pwm[2]; 115 u8 pwm[2];
109 u8 pwm_mode[2]; 116 u8 pwm_mode[2];
110 u8 pwm_enable[2]; 117 u8 pwm_enable[2];
111 s8 temp[2]; 118 /*
119 * f75387: For remote temperature reading, it uses signed 11-bit
120 * values with LSB = 0.125 degree Celsius, left-justified in 16-bit
121 * registers. For original 8-bit temp readings, the LSB just is 0.
122 */
123 s16 temp11[2];
112 s8 temp_high[2]; 124 s8 temp_high[2];
113 s8 temp_max_hyst[2]; 125 s8 temp_max_hyst[2];
114}; 126};
@@ -122,6 +134,7 @@ static int f75375_remove(struct i2c_client *client);
122static const struct i2c_device_id f75375_id[] = { 134static const struct i2c_device_id f75375_id[] = {
123 { "f75373", f75373 }, 135 { "f75373", f75373 },
124 { "f75375", f75375 }, 136 { "f75375", f75375 },
137 { "f75387", f75387 },
125 { } 138 { }
126}; 139};
127MODULE_DEVICE_TABLE(i2c, f75375_id); 140MODULE_DEVICE_TABLE(i2c, f75375_id);
@@ -205,8 +218,14 @@ static struct f75375_data *f75375_update_device(struct device *dev)
205 if (time_after(jiffies, data->last_updated + 2 * HZ) 218 if (time_after(jiffies, data->last_updated + 2 * HZ)
206 || !data->valid) { 219 || !data->valid) {
207 for (nr = 0; nr < 2; nr++) { 220 for (nr = 0; nr < 2; nr++) {
208 data->temp[nr] = 221 /* assign MSB, therefore shift it by 8 bits */
209 f75375_read8(client, F75375_REG_TEMP(nr)); 222 data->temp11[nr] =
223 f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
224 if (data->kind == f75387)
225 /* merge F75387's temperature LSB (11-bit) */
226 data->temp11[nr] |=
227 f75375_read8(client,
228 F75387_REG_TEMP11_LSB(nr));
210 data->fan[nr] = 229 data->fan[nr] =
211 f75375_read16(client, F75375_REG_FAN(nr)); 230 f75375_read16(client, F75375_REG_FAN(nr));
212 } 231 }
@@ -313,24 +332,50 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
313 return -EINVAL; 332 return -EINVAL;
314 333
315 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); 334 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
316 fanmode &= ~(3 << FAN_CTRL_MODE(nr)); 335 if (data->kind == f75387) {
317 336 /* clear each fanX_mode bit before setting them properly */
318 switch (val) { 337 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
319 case 0: /* Full speed */ 338 fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr));
320 fanmode |= (3 << FAN_CTRL_MODE(nr)); 339 switch (val) {
321 data->pwm[nr] = 255; 340 case 0: /* full speed */
322 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), 341 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
323 data->pwm[nr]); 342 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
324 break; 343 data->pwm[nr] = 255;
325 case 1: /* PWM */ 344 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
326 fanmode |= (3 << FAN_CTRL_MODE(nr)); 345 data->pwm[nr]);
327 break; 346 break;
328 case 2: /* AUTOMATIC*/ 347 case 1: /* PWM */
329 fanmode |= (2 << FAN_CTRL_MODE(nr)); 348 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
330 break; 349 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
331 case 3: /* fan speed */ 350 break;
332 break; 351 case 2: /* AUTOMATIC*/
352 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
353 break;
354 case 3: /* fan speed */
355 fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
356 break;
357 }
358 } else {
359 /* clear each fanX_mode bit before setting them properly */
360 fanmode &= ~(3 << FAN_CTRL_MODE(nr));
361 switch (val) {
362 case 0: /* full speed */
363 fanmode |= (3 << FAN_CTRL_MODE(nr));
364 data->pwm[nr] = 255;
365 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
366 data->pwm[nr]);
367 break;
368 case 1: /* PWM */
369 fanmode |= (3 << FAN_CTRL_MODE(nr));
370 break;
371 case 2: /* AUTOMATIC*/
372 fanmode |= (2 << FAN_CTRL_MODE(nr));
373 break;
374 case 3: /* fan speed */
375 break;
376 }
333 } 377 }
378
334 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); 379 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
335 data->pwm_enable[nr] = val; 380 data->pwm_enable[nr] = val;
336 return 0; 381 return 0;
@@ -364,6 +409,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
364 unsigned long val; 409 unsigned long val;
365 int err; 410 int err;
366 u8 conf; 411 u8 conf;
412 char reg, ctrl;
367 413
368 err = kstrtoul(buf, 10, &val); 414 err = kstrtoul(buf, 10, &val);
369 if (err < 0) 415 if (err < 0)
@@ -376,14 +422,23 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
376 if (data->kind == f75373 && val == 0) 422 if (data->kind == f75373 && val == 0)
377 return -EINVAL; 423 return -EINVAL;
378 424
425 /* take care for different registers */
426 if (data->kind == f75387) {
427 reg = F75375_REG_FAN_TIMER;
428 ctrl = F75387_FAN_CTRL_LINEAR(nr);
429 } else {
430 reg = F75375_REG_CONFIG1;
431 ctrl = F75375_FAN_CTRL_LINEAR(nr);
432 }
433
379 mutex_lock(&data->update_lock); 434 mutex_lock(&data->update_lock);
380 conf = f75375_read8(client, F75375_REG_CONFIG1); 435 conf = f75375_read8(client, reg);
381 conf &= ~(1 << FAN_CTRL_LINEAR(nr)); 436 conf &= ~(1 << ctrl);
382 437
383 if (val == 0) 438 if (val == 0)
384 conf |= (1 << FAN_CTRL_LINEAR(nr)) ; 439 conf |= (1 << ctrl);
385 440
386 f75375_write8(client, F75375_REG_CONFIG1, conf); 441 f75375_write8(client, reg, conf);
387 data->pwm_mode[nr] = val; 442 data->pwm_mode[nr] = val;
388 mutex_unlock(&data->update_lock); 443 mutex_unlock(&data->update_lock);
389 return count; 444 return count;
@@ -475,13 +530,14 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
475} 530}
476#define TEMP_FROM_REG(val) ((val) * 1000) 531#define TEMP_FROM_REG(val) ((val) * 1000)
477#define TEMP_TO_REG(val) ((val) / 1000) 532#define TEMP_TO_REG(val) ((val) / 1000)
533#define TEMP11_FROM_REG(reg) ((reg) / 32 * 125)
478 534
479static ssize_t show_temp(struct device *dev, struct device_attribute *attr, 535static ssize_t show_temp11(struct device *dev, struct device_attribute *attr,
480 char *buf) 536 char *buf)
481{ 537{
482 int nr = to_sensor_dev_attr(attr)->index; 538 int nr = to_sensor_dev_attr(attr)->index;
483 struct f75375_data *data = f75375_update_device(dev); 539 struct f75375_data *data = f75375_update_device(dev);
484 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); 540 return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[nr]));
485} 541}
486 542
487static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, 543static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
@@ -577,12 +633,12 @@ static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO|S_IWUSR,
577 show_in_max, set_in_max, 3); 633 show_in_max, set_in_max, 3);
578static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR, 634static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR,
579 show_in_min, set_in_min, 3); 635 show_in_min, set_in_min, 3);
580static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 636static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 0);
581static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, 637static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR,
582 show_temp_max_hyst, set_temp_max_hyst, 0); 638 show_temp_max_hyst, set_temp_max_hyst, 0);
583static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR, 639static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR,
584 show_temp_max, set_temp_max, 0); 640 show_temp_max, set_temp_max, 0);
585static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); 641static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 1);
586static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, 642static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR,
587 show_temp_max_hyst, set_temp_max_hyst, 1); 643 show_temp_max_hyst, set_temp_max_hyst, 1);
588static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR, 644static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR,
@@ -664,18 +720,38 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
664 conf = f75375_read8(client, F75375_REG_CONFIG1); 720 conf = f75375_read8(client, F75375_REG_CONFIG1);
665 mode = f75375_read8(client, F75375_REG_FAN_TIMER); 721 mode = f75375_read8(client, F75375_REG_FAN_TIMER);
666 for (nr = 0; nr < 2; nr++) { 722 for (nr = 0; nr < 2; nr++) {
667 if (!(conf & (1 << FAN_CTRL_LINEAR(nr)))) 723 if (data->kind == f75387) {
668 data->pwm_mode[nr] = 1; 724 bool manu, duty;
669 switch ((mode >> FAN_CTRL_MODE(nr)) & 3) { 725
670 case 0: /* speed */ 726 if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr))))
671 data->pwm_enable[nr] = 3; 727 data->pwm_mode[nr] = 1;
672 break; 728
673 case 1: /* automatic */ 729 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
674 data->pwm_enable[nr] = 2; 730 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
675 break; 731 if (manu && duty)
676 default: /* manual */ 732 /* speed */
677 data->pwm_enable[nr] = 1; 733 data->pwm_enable[nr] = 3;
678 break; 734 else if (!manu && duty)
735 /* automatic */
736 data->pwm_enable[nr] = 2;
737 else
738 /* manual */
739 data->pwm_enable[nr] = 1;
740 } else {
741 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))
742 data->pwm_mode[nr] = 1;
743
744 switch ((mode >> FAN_CTRL_MODE(nr)) & 3) {
745 case 0: /* speed */
746 data->pwm_enable[nr] = 3;
747 break;
748 case 1: /* automatic */
749 data->pwm_enable[nr] = 2;
750 break;
751 default: /* manual */
752 data->pwm_enable[nr] = 1;
753 break;
754 }
679 } 755 }
680 } 756 }
681 return; 757 return;
@@ -763,10 +839,15 @@ static int f75375_detect(struct i2c_client *client,
763 839
764 vendid = f75375_read16(client, F75375_REG_VENDOR); 840 vendid = f75375_read16(client, F75375_REG_VENDOR);
765 chipid = f75375_read16(client, F75375_CHIP_ID); 841 chipid = f75375_read16(client, F75375_CHIP_ID);
766 if (chipid == 0x0306 && vendid == 0x1934) 842 if (vendid != 0x1934)
843 return -ENODEV;
844
845 if (chipid == 0x0306)
767 name = "f75375"; 846 name = "f75375";
768 else if (chipid == 0x0204 && vendid == 0x1934) 847 else if (chipid == 0x0204)
769 name = "f75373"; 848 name = "f75373";
849 else if (chipid == 0x0410)
850 name = "f75387";
770 else 851 else
771 return -ENODEV; 852 return -ENODEV;
772 853
@@ -789,7 +870,7 @@ static void __exit sensors_f75375_exit(void)
789 870
790MODULE_AUTHOR("Riku Voipio"); 871MODULE_AUTHOR("Riku Voipio");
791MODULE_LICENSE("GPL"); 872MODULE_LICENSE("GPL");
792MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver"); 873MODULE_DESCRIPTION("F75373/F75375/F75387 hardware monitoring driver");
793 874
794module_init(sensors_f75375_init); 875module_init(sensors_f75375_init);
795module_exit(sensors_f75375_exit); 876module_exit(sensors_f75375_exit);