diff options
Diffstat (limited to 'drivers/hwmon/max6650.c')
-rw-r--r-- | drivers/hwmon/max6650.c | 177 |
1 files changed, 92 insertions, 85 deletions
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 2fc034aeca09..33a8a7f15e18 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -135,8 +135,7 @@ static struct i2c_driver max6650_driver = { | |||
135 | * Client data (each client gets its own) | 135 | * Client data (each client gets its own) |
136 | */ | 136 | */ |
137 | 137 | ||
138 | struct max6650_data | 138 | struct max6650_data { |
139 | { | ||
140 | struct device *hwmon_dev; | 139 | struct device *hwmon_dev; |
141 | struct mutex update_lock; | 140 | struct mutex update_lock; |
142 | int nr_fans; | 141 | int nr_fans; |
@@ -160,13 +159,13 @@ static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, | |||
160 | int rpm; | 159 | int rpm; |
161 | 160 | ||
162 | /* | 161 | /* |
163 | * Calculation details: | 162 | * Calculation details: |
164 | * | 163 | * |
165 | * Each tachometer counts over an interval given by the "count" | 164 | * Each tachometer counts over an interval given by the "count" |
166 | * register (0.25, 0.5, 1 or 2 seconds). This module assumes | 165 | * register (0.25, 0.5, 1 or 2 seconds). This module assumes |
167 | * that the fans produce two pulses per revolution (this seems | 166 | * that the fans produce two pulses per revolution (this seems |
168 | * to be the most common). | 167 | * to be the most common). |
169 | */ | 168 | */ |
170 | 169 | ||
171 | rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); | 170 | rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); |
172 | return sprintf(buf, "%d\n", rpm); | 171 | return sprintf(buf, "%d\n", rpm); |
@@ -220,12 +219,12 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr, | |||
220 | int kscale, ktach, rpm; | 219 | int kscale, ktach, rpm; |
221 | 220 | ||
222 | /* | 221 | /* |
223 | * Use the datasheet equation: | 222 | * Use the datasheet equation: |
224 | * | 223 | * |
225 | * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] | 224 | * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] |
226 | * | 225 | * |
227 | * then multiply by 60 to give rpm. | 226 | * then multiply by 60 to give rpm. |
228 | */ | 227 | */ |
229 | 228 | ||
230 | kscale = DIV_FROM_REG(data->config); | 229 | kscale = DIV_FROM_REG(data->config); |
231 | ktach = data->speed; | 230 | ktach = data->speed; |
@@ -238,17 +237,22 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, | |||
238 | { | 237 | { |
239 | struct i2c_client *client = to_i2c_client(dev); | 238 | struct i2c_client *client = to_i2c_client(dev); |
240 | struct max6650_data *data = i2c_get_clientdata(client); | 239 | struct max6650_data *data = i2c_get_clientdata(client); |
241 | int rpm = simple_strtoul(buf, NULL, 10); | ||
242 | int kscale, ktach; | 240 | int kscale, ktach; |
241 | unsigned long rpm; | ||
242 | int err; | ||
243 | |||
244 | err = kstrtoul(buf, 10, &rpm); | ||
245 | if (err) | ||
246 | return err; | ||
243 | 247 | ||
244 | rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); | 248 | rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); |
245 | 249 | ||
246 | /* | 250 | /* |
247 | * Divide the required speed by 60 to get from rpm to rps, then | 251 | * Divide the required speed by 60 to get from rpm to rps, then |
248 | * use the datasheet equation: | 252 | * use the datasheet equation: |
249 | * | 253 | * |
250 | * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 | 254 | * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 |
251 | */ | 255 | */ |
252 | 256 | ||
253 | mutex_lock(&data->update_lock); | 257 | mutex_lock(&data->update_lock); |
254 | 258 | ||
@@ -282,8 +286,10 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, | |||
282 | int pwm; | 286 | int pwm; |
283 | struct max6650_data *data = max6650_update_device(dev); | 287 | struct max6650_data *data = max6650_update_device(dev); |
284 | 288 | ||
285 | /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. | 289 | /* |
286 | Lower DAC values mean higher speeds. */ | 290 | * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. |
291 | * Lower DAC values mean higher speeds. | ||
292 | */ | ||
287 | if (data->config & MAX6650_CFG_V12) | 293 | if (data->config & MAX6650_CFG_V12) |
288 | pwm = 255 - (255 * (int)data->dac)/180; | 294 | pwm = 255 - (255 * (int)data->dac)/180; |
289 | else | 295 | else |
@@ -300,7 +306,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
300 | { | 306 | { |
301 | struct i2c_client *client = to_i2c_client(dev); | 307 | struct i2c_client *client = to_i2c_client(dev); |
302 | struct max6650_data *data = i2c_get_clientdata(client); | 308 | struct max6650_data *data = i2c_get_clientdata(client); |
303 | int pwm = simple_strtoul(buf, NULL, 10); | 309 | unsigned long pwm; |
310 | int err; | ||
311 | |||
312 | err = kstrtoul(buf, 10, &pwm); | ||
313 | if (err) | ||
314 | return err; | ||
304 | 315 | ||
305 | pwm = SENSORS_LIMIT(pwm, 0, 255); | 316 | pwm = SENSORS_LIMIT(pwm, 0, 255); |
306 | 317 | ||
@@ -341,14 +352,16 @@ static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, | |||
341 | { | 352 | { |
342 | struct i2c_client *client = to_i2c_client(dev); | 353 | struct i2c_client *client = to_i2c_client(dev); |
343 | struct max6650_data *data = i2c_get_clientdata(client); | 354 | struct max6650_data *data = i2c_get_clientdata(client); |
344 | int mode = simple_strtoul(buf, NULL, 10); | ||
345 | int max6650_modes[3] = {0, 3, 2}; | 355 | int max6650_modes[3] = {0, 3, 2}; |
356 | unsigned long mode; | ||
357 | int err; | ||
346 | 358 | ||
347 | if ((mode < 0)||(mode > 2)) { | 359 | err = kstrtoul(buf, 10, &mode); |
348 | dev_err(&client->dev, | 360 | if (err) |
349 | "illegal value for pwm1_enable (%d)\n", mode); | 361 | return err; |
362 | |||
363 | if (mode > 2) | ||
350 | return -EINVAL; | 364 | return -EINVAL; |
351 | } | ||
352 | 365 | ||
353 | mutex_lock(&data->update_lock); | 366 | mutex_lock(&data->update_lock); |
354 | 367 | ||
@@ -389,7 +402,12 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, | |||
389 | { | 402 | { |
390 | struct i2c_client *client = to_i2c_client(dev); | 403 | struct i2c_client *client = to_i2c_client(dev); |
391 | struct max6650_data *data = i2c_get_clientdata(client); | 404 | struct max6650_data *data = i2c_get_clientdata(client); |
392 | int div = simple_strtoul(buf, NULL, 10); | 405 | unsigned long div; |
406 | int err; | ||
407 | |||
408 | err = kstrtoul(buf, 10, &div); | ||
409 | if (err) | ||
410 | return err; | ||
393 | 411 | ||
394 | mutex_lock(&data->update_lock); | 412 | mutex_lock(&data->update_lock); |
395 | switch (div) { | 413 | switch (div) { |
@@ -407,8 +425,6 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, | |||
407 | break; | 425 | break; |
408 | default: | 426 | default: |
409 | mutex_unlock(&data->update_lock); | 427 | mutex_unlock(&data->update_lock); |
410 | dev_err(&client->dev, | ||
411 | "illegal value for fan divider (%d)\n", div); | ||
412 | return -EINVAL; | 428 | return -EINVAL; |
413 | } | 429 | } |
414 | 430 | ||
@@ -529,7 +545,8 @@ static int max6650_probe(struct i2c_client *client, | |||
529 | struct max6650_data *data; | 545 | struct max6650_data *data; |
530 | int err; | 546 | int err; |
531 | 547 | ||
532 | if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { | 548 | data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL); |
549 | if (!data) { | ||
533 | dev_err(&client->dev, "out of memory.\n"); | 550 | dev_err(&client->dev, "out of memory.\n"); |
534 | return -ENOMEM; | 551 | return -ENOMEM; |
535 | } | 552 | } |
@@ -596,55 +613,54 @@ static int max6650_init_client(struct i2c_client *client) | |||
596 | } | 613 | } |
597 | 614 | ||
598 | switch (fan_voltage) { | 615 | switch (fan_voltage) { |
599 | case 0: | 616 | case 0: |
600 | break; | 617 | break; |
601 | case 5: | 618 | case 5: |
602 | config &= ~MAX6650_CFG_V12; | 619 | config &= ~MAX6650_CFG_V12; |
603 | break; | 620 | break; |
604 | case 12: | 621 | case 12: |
605 | config |= MAX6650_CFG_V12; | 622 | config |= MAX6650_CFG_V12; |
606 | break; | 623 | break; |
607 | default: | 624 | default: |
608 | dev_err(&client->dev, | 625 | dev_err(&client->dev, "illegal value for fan_voltage (%d)\n", |
609 | "illegal value for fan_voltage (%d)\n", | 626 | fan_voltage); |
610 | fan_voltage); | ||
611 | } | 627 | } |
612 | 628 | ||
613 | dev_info(&client->dev, "Fan voltage is set to %dV.\n", | 629 | dev_info(&client->dev, "Fan voltage is set to %dV.\n", |
614 | (config & MAX6650_CFG_V12) ? 12 : 5); | 630 | (config & MAX6650_CFG_V12) ? 12 : 5); |
615 | 631 | ||
616 | switch (prescaler) { | 632 | switch (prescaler) { |
617 | case 0: | 633 | case 0: |
618 | break; | 634 | break; |
619 | case 1: | 635 | case 1: |
620 | config &= ~MAX6650_CFG_PRESCALER_MASK; | 636 | config &= ~MAX6650_CFG_PRESCALER_MASK; |
621 | break; | 637 | break; |
622 | case 2: | 638 | case 2: |
623 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) | 639 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) |
624 | | MAX6650_CFG_PRESCALER_2; | 640 | | MAX6650_CFG_PRESCALER_2; |
625 | break; | 641 | break; |
626 | case 4: | 642 | case 4: |
627 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) | 643 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) |
628 | | MAX6650_CFG_PRESCALER_4; | 644 | | MAX6650_CFG_PRESCALER_4; |
629 | break; | 645 | break; |
630 | case 8: | 646 | case 8: |
631 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) | 647 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) |
632 | | MAX6650_CFG_PRESCALER_8; | 648 | | MAX6650_CFG_PRESCALER_8; |
633 | break; | 649 | break; |
634 | case 16: | 650 | case 16: |
635 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) | 651 | config = (config & ~MAX6650_CFG_PRESCALER_MASK) |
636 | | MAX6650_CFG_PRESCALER_16; | 652 | | MAX6650_CFG_PRESCALER_16; |
637 | break; | 653 | break; |
638 | default: | 654 | default: |
639 | dev_err(&client->dev, | 655 | dev_err(&client->dev, "illegal value for prescaler (%d)\n", |
640 | "illegal value for prescaler (%d)\n", | 656 | prescaler); |
641 | prescaler); | ||
642 | } | 657 | } |
643 | 658 | ||
644 | dev_info(&client->dev, "Prescaler is set to %d.\n", | 659 | dev_info(&client->dev, "Prescaler is set to %d.\n", |
645 | 1 << (config & MAX6650_CFG_PRESCALER_MASK)); | 660 | 1 << (config & MAX6650_CFG_PRESCALER_MASK)); |
646 | 661 | ||
647 | /* If mode is set to "full off", we change it to "open loop" and | 662 | /* |
663 | * If mode is set to "full off", we change it to "open loop" and | ||
648 | * set DAC to 255, which has the same effect. We do this because | 664 | * set DAC to 255, which has the same effect. We do this because |
649 | * there's no "full off" mode defined in hwmon specifcations. | 665 | * there's no "full off" mode defined in hwmon specifcations. |
650 | */ | 666 | */ |
@@ -698,9 +714,11 @@ static struct max6650_data *max6650_update_device(struct device *dev) | |||
698 | MAX6650_REG_COUNT); | 714 | MAX6650_REG_COUNT); |
699 | data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); | 715 | data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); |
700 | 716 | ||
701 | /* Alarms are cleared on read in case the condition that | 717 | /* |
718 | * Alarms are cleared on read in case the condition that | ||
702 | * caused the alarm is removed. Keep the value latched here | 719 | * caused the alarm is removed. Keep the value latched here |
703 | * for providing the register through different alarm files. */ | 720 | * for providing the register through different alarm files. |
721 | */ | ||
704 | data->alarm |= i2c_smbus_read_byte_data(client, | 722 | data->alarm |= i2c_smbus_read_byte_data(client, |
705 | MAX6650_REG_ALARM); | 723 | MAX6650_REG_ALARM); |
706 | 724 | ||
@@ -713,19 +731,8 @@ static struct max6650_data *max6650_update_device(struct device *dev) | |||
713 | return data; | 731 | return data; |
714 | } | 732 | } |
715 | 733 | ||
716 | static int __init sensors_max6650_init(void) | 734 | module_i2c_driver(max6650_driver); |
717 | { | ||
718 | return i2c_add_driver(&max6650_driver); | ||
719 | } | ||
720 | |||
721 | static void __exit sensors_max6650_exit(void) | ||
722 | { | ||
723 | i2c_del_driver(&max6650_driver); | ||
724 | } | ||
725 | 735 | ||
726 | MODULE_AUTHOR("Hans J. Koch"); | 736 | MODULE_AUTHOR("Hans J. Koch"); |
727 | MODULE_DESCRIPTION("MAX6650 sensor driver"); | 737 | MODULE_DESCRIPTION("MAX6650 sensor driver"); |
728 | MODULE_LICENSE("GPL"); | 738 | MODULE_LICENSE("GPL"); |
729 | |||
730 | module_init(sensors_max6650_init); | ||
731 | module_exit(sensors_max6650_exit); | ||