diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/ad7414.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/adm1026.c | 20 | ||||
-rw-r--r-- | drivers/hwmon/adt7470.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/amc6821.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/gpio-fan.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/i5k_amb.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 61 | ||||
-rw-r--r-- | drivers/hwmon/lis3lv02d_i2c.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/lm93.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/lm95241.c | 19 | ||||
-rw-r--r-- | drivers/hwmon/ltc4215.c | 4 | ||||
-rw-r--r-- | drivers/hwmon/ltc4261.c | 5 | ||||
-rw-r--r-- | drivers/hwmon/max6650.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83795.c | 207 |
14 files changed, 268 insertions, 86 deletions
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index 1e4c21fc1a89..86d822aa9bbf 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c | |||
@@ -178,11 +178,13 @@ static int ad7414_probe(struct i2c_client *client, | |||
178 | { | 178 | { |
179 | struct ad7414_data *data; | 179 | struct ad7414_data *data; |
180 | int conf; | 180 | int conf; |
181 | int err = 0; | 181 | int err; |
182 | 182 | ||
183 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 183 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
184 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | 184 | I2C_FUNC_SMBUS_READ_WORD_DATA)) { |
185 | err = -EOPNOTSUPP; | ||
185 | goto exit; | 186 | goto exit; |
187 | } | ||
186 | 188 | ||
187 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); | 189 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); |
188 | if (!data) { | 190 | if (!data) { |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4bf969c0a32b..be0fdd58aa29 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
916 | int nr = sensor_attr->index; | 916 | int nr = sensor_attr->index; |
917 | struct i2c_client *client = to_i2c_client(dev); | 917 | struct i2c_client *client = to_i2c_client(dev); |
918 | struct adm1026_data *data = i2c_get_clientdata(client); | 918 | struct adm1026_data *data = i2c_get_clientdata(client); |
919 | int val, orig_div, new_div, shift; | 919 | int val, orig_div, new_div; |
920 | 920 | ||
921 | val = simple_strtol(buf, NULL, 10); | 921 | val = simple_strtol(buf, NULL, 10); |
922 | new_div = DIV_TO_REG(val); | 922 | new_div = DIV_TO_REG(val); |
923 | if (new_div == 0) { | 923 | |
924 | return -EINVAL; | ||
925 | } | ||
926 | mutex_lock(&data->update_lock); | 924 | mutex_lock(&data->update_lock); |
927 | orig_div = data->fan_div[nr]; | 925 | orig_div = data->fan_div[nr]; |
928 | data->fan_div[nr] = DIV_FROM_REG(new_div); | 926 | data->fan_div[nr] = DIV_FROM_REG(new_div); |
929 | 927 | ||
930 | if (nr < 4) { /* 0 <= nr < 4 */ | 928 | if (nr < 4) { /* 0 <= nr < 4 */ |
931 | shift = 2 * nr; | ||
932 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, | 929 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, |
933 | ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | | 930 | (DIV_TO_REG(data->fan_div[0]) << 0) | |
934 | (new_div << shift))); | 931 | (DIV_TO_REG(data->fan_div[1]) << 2) | |
932 | (DIV_TO_REG(data->fan_div[2]) << 4) | | ||
933 | (DIV_TO_REG(data->fan_div[3]) << 6)); | ||
935 | } else { /* 3 < nr < 8 */ | 934 | } else { /* 3 < nr < 8 */ |
936 | shift = 2 * (nr - 4); | ||
937 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, | 935 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, |
938 | ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | | 936 | (DIV_TO_REG(data->fan_div[4]) << 0) | |
939 | (new_div << shift))); | 937 | (DIV_TO_REG(data->fan_div[5]) << 2) | |
938 | (DIV_TO_REG(data->fan_div[6]) << 4) | | ||
939 | (DIV_TO_REG(data->fan_div[7]) << 6)); | ||
940 | } | 940 | } |
941 | 941 | ||
942 | if (data->fan_div[nr] != orig_div) { | 942 | if (data->fan_div[nr] != orig_div) { |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 9e775717abb7..87d92a56a939 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -1286,8 +1286,10 @@ static int adt7470_probe(struct i2c_client *client, | |||
1286 | init_completion(&data->auto_update_stop); | 1286 | init_completion(&data->auto_update_stop); |
1287 | data->auto_update = kthread_run(adt7470_update_thread, client, | 1287 | data->auto_update = kthread_run(adt7470_update_thread, client, |
1288 | dev_name(data->hwmon_dev)); | 1288 | dev_name(data->hwmon_dev)); |
1289 | if (IS_ERR(data->auto_update)) | 1289 | if (IS_ERR(data->auto_update)) { |
1290 | err = PTR_ERR(data->auto_update); | ||
1290 | goto exit_unregister; | 1291 | goto exit_unregister; |
1292 | } | ||
1291 | 1293 | ||
1292 | return 0; | 1294 | return 0; |
1293 | 1295 | ||
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index fa9708c2d723..4033974d1bb3 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c | |||
@@ -4,7 +4,7 @@ | |||
4 | Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> | 4 | Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> |
5 | 5 | ||
6 | Based on max6650.c: | 6 | Based on max6650.c: |
7 | Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de> | 7 | Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index aa701a183707..f141a1de519c 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -376,10 +376,6 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | ||
380 | if (err) | ||
381 | goto err_free_gpio; | ||
382 | |||
383 | fan_data->num_ctrl = num_ctrl; | 379 | fan_data->num_ctrl = num_ctrl; |
384 | fan_data->ctrl = ctrl; | 380 | fan_data->ctrl = ctrl; |
385 | fan_data->num_speed = pdata->num_speed; | 381 | fan_data->num_speed = pdata->num_speed; |
@@ -391,6 +387,10 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
391 | goto err_free_gpio; | 387 | goto err_free_gpio; |
392 | } | 388 | } |
393 | 389 | ||
390 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | ||
391 | if (err) | ||
392 | goto err_free_gpio; | ||
393 | |||
394 | return 0; | 394 | return 0; |
395 | 395 | ||
396 | err_free_gpio: | 396 | err_free_gpio: |
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 937983407e2a..c4c40be0edbf 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
@@ -497,12 +497,14 @@ static unsigned long chipset_ids[] = { | |||
497 | 0 | 497 | 0 |
498 | }; | 498 | }; |
499 | 499 | ||
500 | #ifdef MODULE | ||
500 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { | 501 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { |
501 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, | 502 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, |
502 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, | 503 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, |
503 | { 0, } | 504 | { 0, } |
504 | }; | 505 | }; |
505 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); | 506 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); |
507 | #endif | ||
506 | 508 | ||
507 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | 509 | static int __devinit i5k_amb_probe(struct platform_device *pdev) |
508 | { | 510 | { |
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) | |||
2034 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2057 | static 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; |
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index 9f4bae07f719..8853afce85ce 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c | |||
@@ -186,7 +186,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM_SLEEP |
190 | static int lis3lv02d_i2c_suspend(struct device *dev) | 190 | static int lis3lv02d_i2c_suspend(struct device *dev) |
191 | { | 191 | { |
192 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | 192 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
@@ -213,12 +213,9 @@ static int lis3lv02d_i2c_resume(struct device *dev) | |||
213 | 213 | ||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
216 | #else | 216 | #endif /* CONFIG_PM_SLEEP */ |
217 | #define lis3lv02d_i2c_suspend NULL | ||
218 | #define lis3lv02d_i2c_resume NULL | ||
219 | #define lis3lv02d_i2c_shutdown NULL | ||
220 | #endif | ||
221 | 217 | ||
218 | #ifdef CONFIG_PM_RUNTIME | ||
222 | static int lis3_i2c_runtime_suspend(struct device *dev) | 219 | static int lis3_i2c_runtime_suspend(struct device *dev) |
223 | { | 220 | { |
224 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | 221 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
@@ -236,6 +233,7 @@ static int lis3_i2c_runtime_resume(struct device *dev) | |||
236 | lis3lv02d_poweron(lis3); | 233 | lis3lv02d_poweron(lis3); |
237 | return 0; | 234 | return 0; |
238 | } | 235 | } |
236 | #endif /* CONFIG_PM_RUNTIME */ | ||
239 | 237 | ||
240 | static const struct i2c_device_id lis3lv02d_id[] = { | 238 | static const struct i2c_device_id lis3lv02d_id[] = { |
241 | {"lis3lv02d", 0 }, | 239 | {"lis3lv02d", 0 }, |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 6669255aadcf..c9ed14eba5a6 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
@@ -20,7 +20,7 @@ | |||
20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> | 20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> |
21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab | 21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab |
22 | 22 | ||
23 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | 23 | Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de> |
24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH | 24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH |
25 | 25 | ||
26 | This program is free software; you can redistribute it and/or modify | 26 | This program is free software; you can redistribute it and/or modify |
@@ -2629,7 +2629,7 @@ static void __exit lm93_exit(void) | |||
2629 | } | 2629 | } |
2630 | 2630 | ||
2631 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " | 2631 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " |
2632 | "Hans J. Koch <hjk@linutronix.de"); | 2632 | "Hans J. Koch <hjk@hansjkoch.de>"); |
2633 | MODULE_DESCRIPTION("LM93 driver"); | 2633 | MODULE_DESCRIPTION("LM93 driver"); |
2634 | MODULE_LICENSE("GPL"); | 2634 | MODULE_LICENSE("GPL"); |
2635 | 2635 | ||
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 464340f25496..4546d82f024a 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
@@ -128,9 +128,12 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr, | |||
128 | { | 128 | { |
129 | struct i2c_client *client = to_i2c_client(dev); | 129 | struct i2c_client *client = to_i2c_client(dev); |
130 | struct lm95241_data *data = i2c_get_clientdata(client); | 130 | struct lm95241_data *data = i2c_get_clientdata(client); |
131 | unsigned long val; | ||
131 | 132 | ||
132 | strict_strtol(buf, 10, &data->interval); | 133 | if (strict_strtoul(buf, 10, &val) < 0) |
133 | data->interval = data->interval * HZ / 1000; | 134 | return -EINVAL; |
135 | |||
136 | data->interval = val * HZ / 1000; | ||
134 | 137 | ||
135 | return count; | 138 | return count; |
136 | } | 139 | } |
@@ -188,7 +191,9 @@ static ssize_t set_type##flag(struct device *dev, \ | |||
188 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 191 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
189 | \ | 192 | \ |
190 | long val; \ | 193 | long val; \ |
191 | strict_strtol(buf, 10, &val); \ | 194 | \ |
195 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
196 | return -EINVAL; \ | ||
192 | \ | 197 | \ |
193 | if ((val == 1) || (val == 2)) { \ | 198 | if ((val == 1) || (val == 2)) { \ |
194 | \ | 199 | \ |
@@ -227,7 +232,9 @@ static ssize_t set_min##flag(struct device *dev, \ | |||
227 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 232 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
228 | \ | 233 | \ |
229 | long val; \ | 234 | long val; \ |
230 | strict_strtol(buf, 10, &val); \ | 235 | \ |
236 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
237 | return -EINVAL;\ | ||
231 | \ | 238 | \ |
232 | mutex_lock(&data->update_lock); \ | 239 | mutex_lock(&data->update_lock); \ |
233 | \ | 240 | \ |
@@ -256,7 +263,9 @@ static ssize_t set_max##flag(struct device *dev, \ | |||
256 | struct lm95241_data *data = i2c_get_clientdata(client); \ | 263 | struct lm95241_data *data = i2c_get_clientdata(client); \ |
257 | \ | 264 | \ |
258 | long val; \ | 265 | long val; \ |
259 | strict_strtol(buf, 10, &val); \ | 266 | \ |
267 | if (strict_strtol(buf, 10, &val) < 0) \ | ||
268 | return -EINVAL; \ | ||
260 | \ | 269 | \ |
261 | mutex_lock(&data->update_lock); \ | 270 | mutex_lock(&data->update_lock); \ |
262 | \ | 271 | \ |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 00d975eb5b83..c7e6d8e81656 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); | |||
205 | 205 | ||
206 | /* Power (virtual) */ | 206 | /* Power (virtual) */ |
207 | LTC4215_POWER(power1_input); | 207 | LTC4215_POWER(power1_input); |
208 | LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); | ||
209 | 208 | ||
210 | /* Input Voltage */ | 209 | /* Input Voltage */ |
211 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); | 210 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); |
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); | |||
214 | 213 | ||
215 | /* Output Voltage */ | 214 | /* Output Voltage */ |
216 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); | 215 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); |
216 | LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); | ||
217 | 217 | ||
218 | /* Finally, construct an array of pointers to members of the above objects, | 218 | /* Finally, construct an array of pointers to members of the above objects, |
219 | * as required for sysfs_create_group() | 219 | * as required for sysfs_create_group() |
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = { | |||
223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, | 223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, |
224 | 224 | ||
225 | &sensor_dev_attr_power1_input.dev_attr.attr, | 225 | &sensor_dev_attr_power1_input.dev_attr.attr, |
226 | &sensor_dev_attr_power1_alarm.dev_attr.attr, | ||
227 | 226 | ||
228 | &sensor_dev_attr_in1_input.dev_attr.attr, | 227 | &sensor_dev_attr_in1_input.dev_attr.attr, |
229 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, | 228 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, |
230 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, | 229 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, |
231 | 230 | ||
232 | &sensor_dev_attr_in2_input.dev_attr.attr, | 231 | &sensor_dev_attr_in2_input.dev_attr.attr, |
232 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, | ||
233 | 233 | ||
234 | NULL, | 234 | NULL, |
235 | }; | 235 | }; |
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 267626178678..4b50601027d3 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c | |||
@@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) | |||
82 | val = i2c_smbus_read_byte_data(client, i); | 82 | val = i2c_smbus_read_byte_data(client, i); |
83 | if (unlikely(val < 0)) { | 83 | if (unlikely(val < 0)) { |
84 | dev_dbg(dev, | 84 | dev_dbg(dev, |
85 | "Failed to read ADC value: error %d", | 85 | "Failed to read ADC value: error %d\n", |
86 | val); | 86 | val); |
87 | ret = ERR_PTR(val); | 87 | ret = ERR_PTR(val); |
88 | goto abort; | 88 | goto abort; |
@@ -230,8 +230,7 @@ static int ltc4261_probe(struct i2c_client *client, | |||
230 | return -ENODEV; | 230 | return -ENODEV; |
231 | 231 | ||
232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { | 232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { |
233 | dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n", | 233 | dev_err(&client->dev, "Failed to read status register\n"); |
234 | adapter->id, client->addr, LTC4261_STATUS); | ||
235 | return -ENODEV; | 234 | return -ENODEV; |
236 | } | 235 | } |
237 | 236 | ||
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index a0160ee5caef..9a11532ecae8 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | * monitoring. | 3 | * monitoring. |
4 | * | 4 | * |
5 | * (C) 2007 by Hans J. Koch <hjk@linutronix.de> | 5 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> |
6 | * | 6 | * |
7 | * based on code written by John Morris <john.morris@spirentcom.com> | 7 | * based on code written by John Morris <john.morris@spirentcom.com> |
8 | * Copyright (c) 2003 Spirent Communications | 8 | * Copyright (c) 2003 Spirent Communications |
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index 1d840aa83782..cdbc7448491e 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -165,10 +165,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { | |||
165 | 165 | ||
166 | #define W83795_REG_VID_CTRL 0x6A | 166 | #define W83795_REG_VID_CTRL 0x6A |
167 | 167 | ||
168 | #define W83795_REG_ALARM_CTRL 0x40 | ||
169 | #define ALARM_CTRL_RTSACS (1 << 7) | ||
168 | #define W83795_REG_ALARM(index) (0x41 + (index)) | 170 | #define W83795_REG_ALARM(index) (0x41 + (index)) |
171 | #define W83795_REG_CLR_CHASSIS 0x4D | ||
169 | #define W83795_REG_BEEP(index) (0x50 + (index)) | 172 | #define W83795_REG_BEEP(index) (0x50 + (index)) |
170 | 173 | ||
171 | #define W83795_REG_CLR_CHASSIS 0x4D | 174 | #define W83795_REG_OVT_CFG 0x58 |
175 | #define OVT_CFG_SEL (1 << 7) | ||
172 | 176 | ||
173 | 177 | ||
174 | #define W83795_REG_FCMS1 0x201 | 178 | #define W83795_REG_FCMS1 0x201 |
@@ -178,6 +182,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { | |||
178 | 182 | ||
179 | #define W83795_REG_TSS(index) (0x209 + (index)) | 183 | #define W83795_REG_TSS(index) (0x209 + (index)) |
180 | 184 | ||
185 | #define TSS_MAP_RESERVED 0xff | ||
186 | static const u8 tss_map[4][6] = { | ||
187 | { 0, 1, 2, 3, 4, 5}, | ||
188 | { 6, 7, 8, 9, 0, 1}, | ||
189 | {10, 11, 12, 13, 2, 3}, | ||
190 | { 4, 5, 4, 5, TSS_MAP_RESERVED, TSS_MAP_RESERVED}, | ||
191 | }; | ||
192 | |||
181 | #define PWM_OUTPUT 0 | 193 | #define PWM_OUTPUT 0 |
182 | #define PWM_FREQ 1 | 194 | #define PWM_FREQ 1 |
183 | #define PWM_START 2 | 195 | #define PWM_START 2 |
@@ -369,6 +381,7 @@ struct w83795_data { | |||
369 | u8 setup_pwm[3]; /* Register value */ | 381 | u8 setup_pwm[3]; /* Register value */ |
370 | 382 | ||
371 | u8 alarms[6]; /* Register value */ | 383 | u8 alarms[6]; /* Register value */ |
384 | u8 enable_beep; | ||
372 | u8 beeps[6]; /* Register value */ | 385 | u8 beeps[6]; /* Register value */ |
373 | 386 | ||
374 | char valid; | 387 | char valid; |
@@ -499,8 +512,11 @@ static void w83795_update_limits(struct i2c_client *client) | |||
499 | } | 512 | } |
500 | 513 | ||
501 | /* Read beep settings */ | 514 | /* Read beep settings */ |
502 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) | 515 | if (data->enable_beep) { |
503 | data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i)); | 516 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) |
517 | data->beeps[i] = | ||
518 | w83795_read(client, W83795_REG_BEEP(i)); | ||
519 | } | ||
504 | 520 | ||
505 | data->valid_limits = 1; | 521 | data->valid_limits = 1; |
506 | } | 522 | } |
@@ -577,6 +593,7 @@ static struct w83795_data *w83795_update_device(struct device *dev) | |||
577 | struct i2c_client *client = to_i2c_client(dev); | 593 | struct i2c_client *client = to_i2c_client(dev); |
578 | struct w83795_data *data = i2c_get_clientdata(client); | 594 | struct w83795_data *data = i2c_get_clientdata(client); |
579 | u16 tmp; | 595 | u16 tmp; |
596 | u8 intrusion; | ||
580 | int i; | 597 | int i; |
581 | 598 | ||
582 | mutex_lock(&data->update_lock); | 599 | mutex_lock(&data->update_lock); |
@@ -648,9 +665,24 @@ static struct w83795_data *w83795_update_device(struct device *dev) | |||
648 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); | 665 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); |
649 | } | 666 | } |
650 | 667 | ||
651 | /* update alarm */ | 668 | /* Update intrusion and alarms |
669 | * It is important to read intrusion first, because reading from | ||
670 | * register SMI STS6 clears the interrupt status temporarily. */ | ||
671 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); | ||
672 | /* Switch to interrupt status for intrusion if needed */ | ||
673 | if (tmp & ALARM_CTRL_RTSACS) | ||
674 | w83795_write(client, W83795_REG_ALARM_CTRL, | ||
675 | tmp & ~ALARM_CTRL_RTSACS); | ||
676 | intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); | ||
677 | /* Switch to real-time alarms */ | ||
678 | w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); | ||
652 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) | 679 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) |
653 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); | 680 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); |
681 | data->alarms[5] |= intrusion; | ||
682 | /* Restore original configuration if needed */ | ||
683 | if (!(tmp & ALARM_CTRL_RTSACS)) | ||
684 | w83795_write(client, W83795_REG_ALARM_CTRL, | ||
685 | tmp & ~ALARM_CTRL_RTSACS); | ||
654 | 686 | ||
655 | data->last_updated = jiffies; | 687 | data->last_updated = jiffies; |
656 | data->valid = 1; | 688 | data->valid = 1; |
@@ -730,6 +762,10 @@ store_chassis_clear(struct device *dev, | |||
730 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); | 762 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); |
731 | val |= 0x80; | 763 | val |= 0x80; |
732 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); | 764 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); |
765 | |||
766 | /* Clear status and force cache refresh */ | ||
767 | w83795_read(client, W83795_REG_ALARM(5)); | ||
768 | data->valid = 0; | ||
733 | mutex_unlock(&data->update_lock); | 769 | mutex_unlock(&data->update_lock); |
734 | return count; | 770 | return count; |
735 | } | 771 | } |
@@ -857,20 +893,20 @@ show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) | |||
857 | int index = sensor_attr->index; | 893 | int index = sensor_attr->index; |
858 | u8 tmp; | 894 | u8 tmp; |
859 | 895 | ||
860 | if (1 == (data->pwm_fcms[0] & (1 << index))) { | 896 | /* Speed cruise mode */ |
897 | if (data->pwm_fcms[0] & (1 << index)) { | ||
861 | tmp = 2; | 898 | tmp = 2; |
862 | goto out; | 899 | goto out; |
863 | } | 900 | } |
901 | /* Thermal cruise or SmartFan IV mode */ | ||
864 | for (tmp = 0; tmp < 6; tmp++) { | 902 | for (tmp = 0; tmp < 6; tmp++) { |
865 | if (data->pwm_tfmr[tmp] & (1 << index)) { | 903 | if (data->pwm_tfmr[tmp] & (1 << index)) { |
866 | tmp = 3; | 904 | tmp = 3; |
867 | goto out; | 905 | goto out; |
868 | } | 906 | } |
869 | } | 907 | } |
870 | if (data->pwm_fomc & (1 << index)) | 908 | /* Manual mode */ |
871 | tmp = 0; | 909 | tmp = 1; |
872 | else | ||
873 | tmp = 1; | ||
874 | 910 | ||
875 | out: | 911 | out: |
876 | return sprintf(buf, "%u\n", tmp); | 912 | return sprintf(buf, "%u\n", tmp); |
@@ -890,23 +926,21 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
890 | 926 | ||
891 | if (strict_strtoul(buf, 10, &val) < 0) | 927 | if (strict_strtoul(buf, 10, &val) < 0) |
892 | return -EINVAL; | 928 | return -EINVAL; |
893 | if (val > 2) | 929 | if (val < 1 || val > 2) |
894 | return -EINVAL; | 930 | return -EINVAL; |
895 | 931 | ||
896 | mutex_lock(&data->update_lock); | 932 | mutex_lock(&data->update_lock); |
897 | switch (val) { | 933 | switch (val) { |
898 | case 0: | ||
899 | case 1: | 934 | case 1: |
935 | /* Clear speed cruise mode bits */ | ||
900 | data->pwm_fcms[0] &= ~(1 << index); | 936 | data->pwm_fcms[0] &= ~(1 << index); |
901 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); | 937 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); |
938 | /* Clear thermal cruise mode bits */ | ||
902 | for (i = 0; i < 6; i++) { | 939 | for (i = 0; i < 6; i++) { |
903 | data->pwm_tfmr[i] &= ~(1 << index); | 940 | data->pwm_tfmr[i] &= ~(1 << index); |
904 | w83795_write(client, W83795_REG_TFMR(i), | 941 | w83795_write(client, W83795_REG_TFMR(i), |
905 | data->pwm_tfmr[i]); | 942 | data->pwm_tfmr[i]); |
906 | } | 943 | } |
907 | data->pwm_fomc |= 1 << index; | ||
908 | data->pwm_fomc ^= val << index; | ||
909 | w83795_write(client, W83795_REG_FOMC, data->pwm_fomc); | ||
910 | break; | 944 | break; |
911 | case 2: | 945 | case 2: |
912 | data->pwm_fcms[0] |= (1 << index); | 946 | data->pwm_fcms[0] |= (1 << index); |
@@ -918,23 +952,60 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
918 | } | 952 | } |
919 | 953 | ||
920 | static ssize_t | 954 | static ssize_t |
955 | show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) | ||
956 | { | ||
957 | struct w83795_data *data = w83795_update_pwm_config(dev); | ||
958 | int index = to_sensor_dev_attr_2(attr)->index; | ||
959 | unsigned int mode; | ||
960 | |||
961 | if (data->pwm_fomc & (1 << index)) | ||
962 | mode = 0; /* DC */ | ||
963 | else | ||
964 | mode = 1; /* PWM */ | ||
965 | |||
966 | return sprintf(buf, "%u\n", mode); | ||
967 | } | ||
968 | |||
969 | /* | ||
970 | * Check whether a given temperature source can ever be useful. | ||
971 | * Returns the number of selectable temperature channels which are | ||
972 | * enabled. | ||
973 | */ | ||
974 | static int w83795_tss_useful(const struct w83795_data *data, int tsrc) | ||
975 | { | ||
976 | int useful = 0, i; | ||
977 | |||
978 | for (i = 0; i < 4; i++) { | ||
979 | if (tss_map[i][tsrc] == TSS_MAP_RESERVED) | ||
980 | continue; | ||
981 | if (tss_map[i][tsrc] < 6) /* Analog */ | ||
982 | useful += (data->has_temp >> tss_map[i][tsrc]) & 1; | ||
983 | else /* Digital */ | ||
984 | useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1; | ||
985 | } | ||
986 | |||
987 | return useful; | ||
988 | } | ||
989 | |||
990 | static ssize_t | ||
921 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) | 991 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) |
922 | { | 992 | { |
923 | struct sensor_device_attribute_2 *sensor_attr = | 993 | struct sensor_device_attribute_2 *sensor_attr = |
924 | to_sensor_dev_attr_2(attr); | 994 | to_sensor_dev_attr_2(attr); |
925 | struct w83795_data *data = w83795_update_pwm_config(dev); | 995 | struct w83795_data *data = w83795_update_pwm_config(dev); |
926 | int index = sensor_attr->index; | 996 | int index = sensor_attr->index; |
927 | u8 val = index / 2; | 997 | u8 tmp = data->temp_src[index / 2]; |
928 | u8 tmp = data->temp_src[val]; | ||
929 | 998 | ||
930 | if (index & 1) | 999 | if (index & 1) |
931 | val = 4; | 1000 | tmp >>= 4; /* Pick high nibble */ |
932 | else | 1001 | else |
933 | val = 0; | 1002 | tmp &= 0x0f; /* Pick low nibble */ |
934 | tmp >>= val; | ||
935 | tmp &= 0x0f; | ||
936 | 1003 | ||
937 | return sprintf(buf, "%u\n", tmp); | 1004 | /* Look-up the actual temperature channel number */ |
1005 | if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED) | ||
1006 | return -EINVAL; /* Shouldn't happen */ | ||
1007 | |||
1008 | return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1); | ||
938 | } | 1009 | } |
939 | 1010 | ||
940 | static ssize_t | 1011 | static ssize_t |
@@ -946,12 +1017,21 @@ store_temp_src(struct device *dev, struct device_attribute *attr, | |||
946 | struct sensor_device_attribute_2 *sensor_attr = | 1017 | struct sensor_device_attribute_2 *sensor_attr = |
947 | to_sensor_dev_attr_2(attr); | 1018 | to_sensor_dev_attr_2(attr); |
948 | int index = sensor_attr->index; | 1019 | int index = sensor_attr->index; |
949 | unsigned long tmp; | 1020 | int tmp; |
1021 | unsigned long channel; | ||
950 | u8 val = index / 2; | 1022 | u8 val = index / 2; |
951 | 1023 | ||
952 | if (strict_strtoul(buf, 10, &tmp) < 0) | 1024 | if (strict_strtoul(buf, 10, &channel) < 0 || |
1025 | channel < 1 || channel > 14) | ||
1026 | return -EINVAL; | ||
1027 | |||
1028 | /* Check if request can be fulfilled */ | ||
1029 | for (tmp = 0; tmp < 4; tmp++) { | ||
1030 | if (tss_map[tmp][index] == channel - 1) | ||
1031 | break; | ||
1032 | } | ||
1033 | if (tmp == 4) /* No match */ | ||
953 | return -EINVAL; | 1034 | return -EINVAL; |
954 | tmp = SENSORS_LIMIT(tmp, 0, 15); | ||
955 | 1035 | ||
956 | mutex_lock(&data->update_lock); | 1036 | mutex_lock(&data->update_lock); |
957 | if (index & 1) { | 1037 | if (index & 1) { |
@@ -1515,7 +1595,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1515 | 1595 | ||
1516 | #define NOT_USED -1 | 1596 | #define NOT_USED -1 |
1517 | 1597 | ||
1518 | /* Don't change the attribute order, _max and _min are accessed by index | 1598 | /* Don't change the attribute order, _max, _min and _beep are accessed by index |
1519 | * somewhere else in the code */ | 1599 | * somewhere else in the code */ |
1520 | #define SENSOR_ATTR_IN(index) { \ | 1600 | #define SENSOR_ATTR_IN(index) { \ |
1521 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ | 1601 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ |
@@ -1530,6 +1610,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1530 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1610 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1531 | index + ((index > 14) ? 1 : 0)) } | 1611 | index + ((index > 14) ? 1 : 0)) } |
1532 | 1612 | ||
1613 | /* Don't change the attribute order, _beep is accessed by index | ||
1614 | * somewhere else in the code */ | ||
1533 | #define SENSOR_ATTR_FAN(index) { \ | 1615 | #define SENSOR_ATTR_FAN(index) { \ |
1534 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ | 1616 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ |
1535 | NULL, FAN_INPUT, index - 1), \ | 1617 | NULL, FAN_INPUT, index - 1), \ |
@@ -1553,9 +1635,13 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1553 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ | 1635 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ |
1554 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ | 1636 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ |
1555 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ | 1637 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ |
1638 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ | ||
1639 | show_pwm_mode, NULL, NOT_USED, index - 1), \ | ||
1556 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ | 1640 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ |
1557 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } | 1641 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } |
1558 | 1642 | ||
1643 | /* Don't change the attribute order, _beep is accessed by index | ||
1644 | * somewhere else in the code */ | ||
1559 | #define SENSOR_ATTR_DTS(index) { \ | 1645 | #define SENSOR_ATTR_DTS(index) { \ |
1560 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ | 1646 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ |
1561 | show_dts_mode, NULL, NOT_USED, index - 7), \ | 1647 | show_dts_mode, NULL, NOT_USED, index - 7), \ |
@@ -1574,6 +1660,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1574 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1660 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1575 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } | 1661 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } |
1576 | 1662 | ||
1663 | /* Don't change the attribute order, _beep is accessed by index | ||
1664 | * somewhere else in the code */ | ||
1577 | #define SENSOR_ATTR_TEMP(index) { \ | 1665 | #define SENSOR_ATTR_TEMP(index) { \ |
1578 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ | 1666 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ |
1579 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ | 1667 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ |
@@ -1593,8 +1681,6 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1593 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1681 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1594 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1682 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1595 | index + (index > 4 ? 11 : 17)), \ | 1683 | index + (index > 4 ? 11 : 17)), \ |
1596 | SENSOR_ATTR_2(temp##index##_source_sel, S_IWUSR | S_IRUGO, \ | ||
1597 | show_temp_src, store_temp_src, NOT_USED, index - 1), \ | ||
1598 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ | 1684 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ |
1599 | show_temp_pwm_enable, store_temp_pwm_enable, \ | 1685 | show_temp_pwm_enable, store_temp_pwm_enable, \ |
1600 | TEMP_PWM_ENABLE, index - 1), \ | 1686 | TEMP_PWM_ENABLE, index - 1), \ |
@@ -1680,7 +1766,7 @@ static const struct sensor_device_attribute_2 w83795_fan[][4] = { | |||
1680 | SENSOR_ATTR_FAN(14), | 1766 | SENSOR_ATTR_FAN(14), |
1681 | }; | 1767 | }; |
1682 | 1768 | ||
1683 | static const struct sensor_device_attribute_2 w83795_temp[][29] = { | 1769 | static const struct sensor_device_attribute_2 w83795_temp[][28] = { |
1684 | SENSOR_ATTR_TEMP(1), | 1770 | SENSOR_ATTR_TEMP(1), |
1685 | SENSOR_ATTR_TEMP(2), | 1771 | SENSOR_ATTR_TEMP(2), |
1686 | SENSOR_ATTR_TEMP(3), | 1772 | SENSOR_ATTR_TEMP(3), |
@@ -1700,7 +1786,7 @@ static const struct sensor_device_attribute_2 w83795_dts[][8] = { | |||
1700 | SENSOR_ATTR_DTS(14), | 1786 | SENSOR_ATTR_DTS(14), |
1701 | }; | 1787 | }; |
1702 | 1788 | ||
1703 | static const struct sensor_device_attribute_2 w83795_pwm[][7] = { | 1789 | static const struct sensor_device_attribute_2 w83795_pwm[][8] = { |
1704 | SENSOR_ATTR_PWM(1), | 1790 | SENSOR_ATTR_PWM(1), |
1705 | SENSOR_ATTR_PWM(2), | 1791 | SENSOR_ATTR_PWM(2), |
1706 | SENSOR_ATTR_PWM(3), | 1792 | SENSOR_ATTR_PWM(3), |
@@ -1711,13 +1797,24 @@ static const struct sensor_device_attribute_2 w83795_pwm[][7] = { | |||
1711 | SENSOR_ATTR_PWM(8), | 1797 | SENSOR_ATTR_PWM(8), |
1712 | }; | 1798 | }; |
1713 | 1799 | ||
1800 | static const struct sensor_device_attribute_2 w83795_tss[6] = { | ||
1801 | SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO, | ||
1802 | show_temp_src, store_temp_src, NOT_USED, 0), | ||
1803 | SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO, | ||
1804 | show_temp_src, store_temp_src, NOT_USED, 1), | ||
1805 | SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO, | ||
1806 | show_temp_src, store_temp_src, NOT_USED, 2), | ||
1807 | SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO, | ||
1808 | show_temp_src, store_temp_src, NOT_USED, 3), | ||
1809 | SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO, | ||
1810 | show_temp_src, store_temp_src, NOT_USED, 4), | ||
1811 | SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO, | ||
1812 | show_temp_src, store_temp_src, NOT_USED, 5), | ||
1813 | }; | ||
1814 | |||
1714 | static const struct sensor_device_attribute_2 sda_single_files[] = { | 1815 | static const struct sensor_device_attribute_2 sda_single_files[] = { |
1715 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | 1816 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, |
1716 | store_chassis_clear, ALARM_STATUS, 46), | 1817 | store_chassis_clear, ALARM_STATUS, 46), |
1717 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1718 | store_beep, BEEP_ENABLE, 46), | ||
1719 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1720 | store_beep, BEEP_ENABLE, 47), | ||
1721 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1818 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1722 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, | 1819 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, |
1723 | store_fanin, FANIN_TOL, NOT_USED), | 1820 | store_fanin, FANIN_TOL, NOT_USED), |
@@ -1730,6 +1827,13 @@ static const struct sensor_device_attribute_2 sda_single_files[] = { | |||
1730 | #endif | 1827 | #endif |
1731 | }; | 1828 | }; |
1732 | 1829 | ||
1830 | static const struct sensor_device_attribute_2 sda_beep_files[] = { | ||
1831 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1832 | store_beep, BEEP_ENABLE, 46), | ||
1833 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1834 | store_beep, BEEP_ENABLE, 47), | ||
1835 | }; | ||
1836 | |||
1733 | /* | 1837 | /* |
1734 | * Driver interface | 1838 | * Driver interface |
1735 | */ | 1839 | */ |
@@ -1859,6 +1963,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1859 | if (!(data->has_in & (1 << i))) | 1963 | if (!(data->has_in & (1 << i))) |
1860 | continue; | 1964 | continue; |
1861 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { | 1965 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { |
1966 | if (j == 4 && !data->enable_beep) | ||
1967 | continue; | ||
1862 | err = fn(dev, &w83795_in[i][j].dev_attr); | 1968 | err = fn(dev, &w83795_in[i][j].dev_attr); |
1863 | if (err) | 1969 | if (err) |
1864 | return err; | 1970 | return err; |
@@ -1869,18 +1975,37 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1869 | if (!(data->has_fan & (1 << i))) | 1975 | if (!(data->has_fan & (1 << i))) |
1870 | continue; | 1976 | continue; |
1871 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { | 1977 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { |
1978 | if (j == 3 && !data->enable_beep) | ||
1979 | continue; | ||
1872 | err = fn(dev, &w83795_fan[i][j].dev_attr); | 1980 | err = fn(dev, &w83795_fan[i][j].dev_attr); |
1873 | if (err) | 1981 | if (err) |
1874 | return err; | 1982 | return err; |
1875 | } | 1983 | } |
1876 | } | 1984 | } |
1877 | 1985 | ||
1986 | for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) { | ||
1987 | j = w83795_tss_useful(data, i); | ||
1988 | if (!j) | ||
1989 | continue; | ||
1990 | err = fn(dev, &w83795_tss[i].dev_attr); | ||
1991 | if (err) | ||
1992 | return err; | ||
1993 | } | ||
1994 | |||
1878 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { | 1995 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { |
1879 | err = fn(dev, &sda_single_files[i].dev_attr); | 1996 | err = fn(dev, &sda_single_files[i].dev_attr); |
1880 | if (err) | 1997 | if (err) |
1881 | return err; | 1998 | return err; |
1882 | } | 1999 | } |
1883 | 2000 | ||
2001 | if (data->enable_beep) { | ||
2002 | for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { | ||
2003 | err = fn(dev, &sda_beep_files[i].dev_attr); | ||
2004 | if (err) | ||
2005 | return err; | ||
2006 | } | ||
2007 | } | ||
2008 | |||
1884 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 2009 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1885 | for (i = 0; i < data->has_pwm; i++) { | 2010 | for (i = 0; i < data->has_pwm; i++) { |
1886 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { | 2011 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { |
@@ -1899,6 +2024,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1899 | #else | 2024 | #else |
1900 | for (j = 0; j < 8; j++) { | 2025 | for (j = 0; j < 8; j++) { |
1901 | #endif | 2026 | #endif |
2027 | if (j == 7 && !data->enable_beep) | ||
2028 | continue; | ||
1902 | err = fn(dev, &w83795_temp[i][j].dev_attr); | 2029 | err = fn(dev, &w83795_temp[i][j].dev_attr); |
1903 | if (err) | 2030 | if (err) |
1904 | return err; | 2031 | return err; |
@@ -1910,6 +2037,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1910 | if (!(data->has_dts & (1 << i))) | 2037 | if (!(data->has_dts & (1 << i))) |
1911 | continue; | 2038 | continue; |
1912 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { | 2039 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { |
2040 | if (j == 7 && !data->enable_beep) | ||
2041 | continue; | ||
1913 | err = fn(dev, &w83795_dts[i][j].dev_attr); | 2042 | err = fn(dev, &w83795_dts[i][j].dev_attr); |
1914 | if (err) | 2043 | if (err) |
1915 | return err; | 2044 | return err; |
@@ -2049,6 +2178,18 @@ static int w83795_probe(struct i2c_client *client, | |||
2049 | else | 2178 | else |
2050 | data->has_pwm = 2; | 2179 | data->has_pwm = 2; |
2051 | 2180 | ||
2181 | /* Check if BEEP pin is available */ | ||
2182 | if (data->chip_type == w83795g) { | ||
2183 | /* The W83795G has a dedicated BEEP pin */ | ||
2184 | data->enable_beep = 1; | ||
2185 | } else { | ||
2186 | /* The W83795ADG has a shared pin for OVT# and BEEP, so you | ||
2187 | * can't have both */ | ||
2188 | tmp = w83795_read(client, W83795_REG_OVT_CFG); | ||
2189 | if ((tmp & OVT_CFG_SEL) == 0) | ||
2190 | data->enable_beep = 1; | ||
2191 | } | ||
2192 | |||
2052 | err = w83795_handle_files(dev, device_create_file); | 2193 | err = w83795_handle_files(dev, device_create_file); |
2053 | if (err) | 2194 | if (err) |
2054 | goto exit_remove; | 2195 | goto exit_remove; |