aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83627hf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 17:24:57 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 17:24:57 -0400
commit40b42f1ebf653cd72c32eb1a1a0b9fea2dfbfd7d (patch)
tree6a2adfcd8412189932a372ce25def8611e287b5c /drivers/hwmon/w83627hf.c
parent5a021e9ffd56c22700133ebc37d607f95be8f7bd (diff)
parente24b8cb4fa2bb779bdf48656152366b6f52f748f (diff)
Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6
* 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6: (44 commits) i2c: Delete the i2c-isa pseudo bus driver hwmon: refuse to load abituguru driver on non-Abit boards hwmon: fix Abit Uguru3 driver detection on some motherboards hwmon/w83627ehf: Be quiet when no chip is found hwmon/w83627ehf: No need to initialize fan_min hwmon/w83627ehf: Export the thermal sensor types hwmon/w83627ehf: Enable VBAT monitoring hwmon/w83627ehf: Add support for the VID inputs hwmon/w83627ehf: Fix timing issues hwmon/w83627ehf: Add error messages for two error cases hwmon/w83627ehf: Convert to a platform driver hwmon/w83627ehf: Update the Kconfig entry make coretemp_device_remove() static hwmon: Add LM93 support hwmon: Improve the pwmN_enable documentation hwmon/smsc47b397: Don't report missing fans as spinning at 82 RPM hwmon: Add support for newer uGuru's hwmon/f71805f: Add temperature-tracking fan control mode hwmon/w83627ehf: Preserve speed reading when changing fan min hwmon: fix detection of abituguru volt inputs ... Manual fixup of trivial conflict in MAINTAINERS file
Diffstat (limited to 'drivers/hwmon/w83627hf.c')
-rw-r--r--drivers/hwmon/w83627hf.c153
1 files changed, 145 insertions, 8 deletions
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 12cb40a975de..1ce78179b005 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -220,6 +220,18 @@ static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
220#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ 220#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \
221 regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) 221 regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1])
222 222
223#define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */
224
225#define W83637HF_REG_PWM_FREQ1 0x00 /* 697HF/687THF too */
226#define W83637HF_REG_PWM_FREQ2 0x02 /* 697HF/687THF too */
227#define W83637HF_REG_PWM_FREQ3 0x10 /* 687THF too */
228
229static const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1,
230 W83637HF_REG_PWM_FREQ2,
231 W83637HF_REG_PWM_FREQ3 };
232
233#define W83627HF_BASE_PWM_FREQ 46870
234
223#define W83781D_REG_I2C_ADDR 0x48 235#define W83781D_REG_I2C_ADDR 0x48
224#define W83781D_REG_I2C_SUBADDR 0x4A 236#define W83781D_REG_I2C_SUBADDR 0x4A
225 237
@@ -267,6 +279,49 @@ static int TEMP_FROM_REG(u8 reg)
267 279
268#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) 280#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
269 281
282static inline unsigned long pwm_freq_from_reg_627hf(u8 reg)
283{
284 unsigned long freq;
285 freq = W83627HF_BASE_PWM_FREQ >> reg;
286 return freq;
287}
288static inline u8 pwm_freq_to_reg_627hf(unsigned long val)
289{
290 u8 i;
291 /* Only 5 dividers (1 2 4 8 16)
292 Search for the nearest available frequency */
293 for (i = 0; i < 4; i++) {
294 if (val > (((W83627HF_BASE_PWM_FREQ >> i) +
295 (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2))
296 break;
297 }
298 return i;
299}
300
301static inline unsigned long pwm_freq_from_reg(u8 reg)
302{
303 /* Clock bit 8 -> 180 kHz or 24 MHz */
304 unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL;
305
306 reg &= 0x7f;
307 /* This should not happen but anyway... */
308 if (reg == 0)
309 reg++;
310 return (clock / (reg << 8));
311}
312static inline u8 pwm_freq_to_reg(unsigned long val)
313{
314 /* Minimum divider value is 0x01 and maximum is 0x7F */
315 if (val >= 93750) /* The highest we can do */
316 return 0x01;
317 if (val >= 720) /* Use 24 MHz clock */
318 return (24000000UL / (val << 8));
319 if (val < 6) /* The lowest we can do */
320 return 0xFF;
321 else /* Use 180 kHz clock */
322 return (0x80 | (180000UL / (val << 8)));
323}
324
270#define BEEP_MASK_FROM_REG(val) (val) 325#define BEEP_MASK_FROM_REG(val) (val)
271#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) 326#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff)
272#define BEEP_ENABLE_TO_REG(val) ((val)?1:0) 327#define BEEP_ENABLE_TO_REG(val) ((val)?1:0)
@@ -316,6 +371,7 @@ struct w83627hf_data {
316 u32 beep_mask; /* Register encoding, combined */ 371 u32 beep_mask; /* Register encoding, combined */
317 u8 beep_enable; /* Boolean */ 372 u8 beep_enable; /* Boolean */
318 u8 pwm[3]; /* Register value */ 373 u8 pwm[3]; /* Register value */
374 u8 pwm_freq[3]; /* Register value */
319 u16 sens[3]; /* 782D/783S only. 375 u16 sens[3]; /* 782D/783S only.
320 1 = pentium diode; 2 = 3904 diode; 376 1 = pentium diode; 2 = 3904 diode;
321 3000-5000 = thermistor beta. 377 3000-5000 = thermistor beta.
@@ -852,6 +908,64 @@ sysfs_pwm(2);
852sysfs_pwm(3); 908sysfs_pwm(3);
853 909
854static ssize_t 910static ssize_t
911show_pwm_freq_reg(struct device *dev, char *buf, int nr)
912{
913 struct w83627hf_data *data = w83627hf_update_device(dev);
914 if (data->type == w83627hf)
915 return sprintf(buf, "%ld\n",
916 pwm_freq_from_reg_627hf(data->pwm_freq[nr - 1]));
917 else
918 return sprintf(buf, "%ld\n",
919 pwm_freq_from_reg(data->pwm_freq[nr - 1]));
920}
921
922static ssize_t
923store_pwm_freq_reg(struct device *dev, const char *buf, size_t count, int nr)
924{
925 struct w83627hf_data *data = dev_get_drvdata(dev);
926 static const u8 mask[]={0xF8, 0x8F};
927 u32 val;
928
929 val = simple_strtoul(buf, NULL, 10);
930
931 mutex_lock(&data->update_lock);
932
933 if (data->type == w83627hf) {
934 data->pwm_freq[nr - 1] = pwm_freq_to_reg_627hf(val);
935 w83627hf_write_value(data, W83627HF_REG_PWM_FREQ,
936 (data->pwm_freq[nr - 1] << ((nr - 1)*4)) |
937 (w83627hf_read_value(data,
938 W83627HF_REG_PWM_FREQ) & mask[nr - 1]));
939 } else {
940 data->pwm_freq[nr - 1] = pwm_freq_to_reg(val);
941 w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr - 1],
942 data->pwm_freq[nr - 1]);
943 }
944
945 mutex_unlock(&data->update_lock);
946 return count;
947}
948
949#define sysfs_pwm_freq(offset) \
950static ssize_t show_regs_pwm_freq_##offset(struct device *dev, \
951 struct device_attribute *attr, char *buf) \
952{ \
953 return show_pwm_freq_reg(dev, buf, offset); \
954} \
955static ssize_t \
956store_regs_pwm_freq_##offset(struct device *dev, \
957 struct device_attribute *attr, const char *buf, size_t count) \
958{ \
959 return store_pwm_freq_reg(dev, buf, count, offset); \
960} \
961static DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \
962 show_regs_pwm_freq_##offset, store_regs_pwm_freq_##offset);
963
964sysfs_pwm_freq(1);
965sysfs_pwm_freq(2);
966sysfs_pwm_freq(3);
967
968static ssize_t
855show_sensor_reg(struct device *dev, char *buf, int nr) 969show_sensor_reg(struct device *dev, char *buf, int nr)
856{ 970{
857 struct w83627hf_data *data = w83627hf_update_device(dev); 971 struct w83627hf_data *data = w83627hf_update_device(dev);
@@ -1077,6 +1191,9 @@ static struct attribute *w83627hf_attributes_opt[] = {
1077 1191
1078 &dev_attr_pwm3.attr, 1192 &dev_attr_pwm3.attr,
1079 1193
1194 &dev_attr_pwm1_freq.attr,
1195 &dev_attr_pwm2_freq.attr,
1196 &dev_attr_pwm3_freq.attr,
1080 NULL 1197 NULL
1081}; 1198};
1082 1199
@@ -1139,7 +1256,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
1139 || (err = device_create_file(dev, &dev_attr_in5_max)) 1256 || (err = device_create_file(dev, &dev_attr_in5_max))
1140 || (err = device_create_file(dev, &dev_attr_in6_input)) 1257 || (err = device_create_file(dev, &dev_attr_in6_input))
1141 || (err = device_create_file(dev, &dev_attr_in6_min)) 1258 || (err = device_create_file(dev, &dev_attr_in6_min))
1142 || (err = device_create_file(dev, &dev_attr_in6_max))) 1259 || (err = device_create_file(dev, &dev_attr_in6_max))
1260 || (err = device_create_file(dev, &dev_attr_pwm1_freq))
1261 || (err = device_create_file(dev, &dev_attr_pwm2_freq)))
1143 goto ERROR4; 1262 goto ERROR4;
1144 1263
1145 if (data->type != w83697hf) 1264 if (data->type != w83697hf)
@@ -1169,6 +1288,12 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
1169 if ((err = device_create_file(dev, &dev_attr_pwm3))) 1288 if ((err = device_create_file(dev, &dev_attr_pwm3)))
1170 goto ERROR4; 1289 goto ERROR4;
1171 1290
1291 if (data->type == w83637hf || data->type == w83687thf)
1292 if ((err = device_create_file(dev, &dev_attr_pwm1_freq))
1293 || (err = device_create_file(dev, &dev_attr_pwm2_freq))
1294 || (err = device_create_file(dev, &dev_attr_pwm3_freq)))
1295 goto ERROR4;
1296
1172 data->class_dev = hwmon_device_register(dev); 1297 data->class_dev = hwmon_device_register(dev);
1173 if (IS_ERR(data->class_dev)) { 1298 if (IS_ERR(data->class_dev)) {
1174 err = PTR_ERR(data->class_dev); 1299 err = PTR_ERR(data->class_dev);
@@ -1181,6 +1306,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
1181 sysfs_remove_group(&dev->kobj, &w83627hf_group); 1306 sysfs_remove_group(&dev->kobj, &w83627hf_group);
1182 sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); 1307 sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);
1183 ERROR3: 1308 ERROR3:
1309 platform_set_drvdata(pdev, NULL);
1184 kfree(data); 1310 kfree(data);
1185 ERROR1: 1311 ERROR1:
1186 release_region(res->start, WINB_REGION_SIZE); 1312 release_region(res->start, WINB_REGION_SIZE);
@@ -1193,11 +1319,11 @@ static int __devexit w83627hf_remove(struct platform_device *pdev)
1193 struct w83627hf_data *data = platform_get_drvdata(pdev); 1319 struct w83627hf_data *data = platform_get_drvdata(pdev);
1194 struct resource *res; 1320 struct resource *res;
1195 1321
1196 platform_set_drvdata(pdev, NULL);
1197 hwmon_device_unregister(data->class_dev); 1322 hwmon_device_unregister(data->class_dev);
1198 1323
1199 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); 1324 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
1200 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); 1325 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt);
1326 platform_set_drvdata(pdev, NULL);
1201 kfree(data); 1327 kfree(data);
1202 1328
1203 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1329 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1472,6 +1598,20 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1472 (data->type == w83627hf || data->type == w83697hf)) 1598 (data->type == w83627hf || data->type == w83697hf))
1473 break; 1599 break;
1474 } 1600 }
1601 if (data->type == w83627hf) {
1602 u8 tmp = w83627hf_read_value(data,
1603 W83627HF_REG_PWM_FREQ);
1604 data->pwm_freq[0] = tmp & 0x07;
1605 data->pwm_freq[1] = (tmp >> 4) & 0x07;
1606 } else if (data->type != w83627thf) {
1607 for (i = 1; i <= 3; i++) {
1608 data->pwm_freq[i - 1] =
1609 w83627hf_read_value(data,
1610 W83637HF_REG_PWM_FREQ[i - 1]);
1611 if (i == 2 && (data->type == w83697hf))
1612 break;
1613 }
1614 }
1475 1615
1476 data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); 1616 data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1));
1477 data->temp_max = 1617 data->temp_max =
@@ -1548,15 +1688,12 @@ static int __init w83627hf_device_add(unsigned short address,
1548 goto exit_device_put; 1688 goto exit_device_put;
1549 } 1689 }
1550 1690
1551 pdev->dev.platform_data = kmalloc(sizeof(struct w83627hf_sio_data), 1691 err = platform_device_add_data(pdev, sio_data,
1552 GFP_KERNEL); 1692 sizeof(struct w83627hf_sio_data));
1553 if (!pdev->dev.platform_data) { 1693 if (err) {
1554 err = -ENOMEM;
1555 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); 1694 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1556 goto exit_device_put; 1695 goto exit_device_put;
1557 } 1696 }
1558 memcpy(pdev->dev.platform_data, sio_data,
1559 sizeof(struct w83627hf_sio_data));
1560 1697
1561 err = platform_device_add(pdev); 1698 err = platform_device_add(pdev);
1562 if (err) { 1699 if (err) {