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.c170
1 files changed, 134 insertions, 36 deletions
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 13a041326a04..6892f76fc18a 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -34,6 +34,7 @@
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/f75375s.h>
37 38
38/* Addresses to scan */ 39/* Addresses to scan */
39static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; 40static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
@@ -86,7 +87,7 @@ I2C_CLIENT_INSMOD_2(f75373, f75375);
86 87
87struct f75375_data { 88struct f75375_data {
88 unsigned short addr; 89 unsigned short addr;
89 struct i2c_client client; 90 struct i2c_client *client;
90 struct device *hwmon_dev; 91 struct device *hwmon_dev;
91 92
92 const char *name; 93 const char *name;
@@ -116,15 +117,25 @@ struct f75375_data {
116static int f75375_attach_adapter(struct i2c_adapter *adapter); 117static int f75375_attach_adapter(struct i2c_adapter *adapter);
117static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); 118static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
118static int f75375_detach_client(struct i2c_client *client); 119static int f75375_detach_client(struct i2c_client *client);
120static int f75375_probe(struct i2c_client *client);
121static int f75375_remove(struct i2c_client *client);
119 122
120static struct i2c_driver f75375_driver = { 123static struct i2c_driver f75375_legacy_driver = {
121 .driver = { 124 .driver = {
122 .name = "f75375", 125 .name = "f75375_legacy",
123 }, 126 },
124 .attach_adapter = f75375_attach_adapter, 127 .attach_adapter = f75375_attach_adapter,
125 .detach_client = f75375_detach_client, 128 .detach_client = f75375_detach_client,
126}; 129};
127 130
131static struct i2c_driver f75375_driver = {
132 .driver = {
133 .name = "f75375",
134 },
135 .probe = f75375_probe,
136 .remove = f75375_remove,
137};
138
128static inline int f75375_read8(struct i2c_client *client, u8 reg) 139static inline int f75375_read8(struct i2c_client *client, u8 reg)
129{ 140{
130 return i2c_smbus_read_byte_data(client, reg); 141 return i2c_smbus_read_byte_data(client, reg);
@@ -276,19 +287,14 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
276 return sprintf(buf, "%d\n", data->pwm_enable[nr]); 287 return sprintf(buf, "%d\n", data->pwm_enable[nr]);
277} 288}
278 289
279static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, 290static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
280 const char *buf, size_t count)
281{ 291{
282 int nr = to_sensor_dev_attr(attr)->index;
283 struct i2c_client *client = to_i2c_client(dev);
284 struct f75375_data *data = i2c_get_clientdata(client); 292 struct f75375_data *data = i2c_get_clientdata(client);
285 int val = simple_strtoul(buf, NULL, 10);
286 u8 fanmode; 293 u8 fanmode;
287 294
288 if (val < 0 || val > 4) 295 if (val < 0 || val > 4)
289 return -EINVAL; 296 return -EINVAL;
290 297
291 mutex_lock(&data->update_lock);
292 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); 298 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
293 fanmode = ~(3 << FAN_CTRL_MODE(nr)); 299 fanmode = ~(3 << FAN_CTRL_MODE(nr));
294 300
@@ -310,8 +316,22 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
310 } 316 }
311 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); 317 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
312 data->pwm_enable[nr] = val; 318 data->pwm_enable[nr] = val;
319 return 0;
320}
321
322static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
323 const char *buf, size_t count)
324{
325 int nr = to_sensor_dev_attr(attr)->index;
326 struct i2c_client *client = to_i2c_client(dev);
327 struct f75375_data *data = i2c_get_clientdata(client);
328 int val = simple_strtoul(buf, NULL, 10);
329 int err = 0;
330
331 mutex_lock(&data->update_lock);
332 err = set_pwm_enable_direct(client, nr, val);
313 mutex_unlock(&data->update_lock); 333 mutex_unlock(&data->update_lock);
314 return count; 334 return err ? err : count;
315} 335}
316 336
317static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, 337static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
@@ -323,7 +343,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
323 int val = simple_strtoul(buf, NULL, 10); 343 int val = simple_strtoul(buf, NULL, 10);
324 u8 conf = 0; 344 u8 conf = 0;
325 345
326 if (val != 0 || val != 1 || data->kind == f75373) 346 if (!(val == 0 || val == 1))
327 return -EINVAL; 347 return -EINVAL;
328 348
329 mutex_lock(&data->update_lock); 349 mutex_lock(&data->update_lock);
@@ -529,13 +549,13 @@ static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR,
529 show_pwm, set_pwm, 0); 549 show_pwm, set_pwm, 0);
530static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, 550static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR,
531 show_pwm_enable, set_pwm_enable, 0); 551 show_pwm_enable, set_pwm_enable, 0);
532static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO|S_IWUSR, 552static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO,
533 show_pwm_mode, set_pwm_mode, 0); 553 show_pwm_mode, set_pwm_mode, 0);
534static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, 554static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR,
535 show_pwm, set_pwm, 1); 555 show_pwm, set_pwm, 1);
536static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, 556static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR,
537 show_pwm_enable, set_pwm_enable, 1); 557 show_pwm_enable, set_pwm_enable, 1);
538static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO|S_IWUSR, 558static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO,
539 show_pwm_mode, set_pwm_mode, 1); 559 show_pwm_mode, set_pwm_mode, 1);
540 560
541static struct attribute *f75375_attributes[] = { 561static struct attribute *f75375_attributes[] = {
@@ -580,12 +600,9 @@ static const struct attribute_group f75375_group = {
580 600
581static int f75375_detach_client(struct i2c_client *client) 601static int f75375_detach_client(struct i2c_client *client)
582{ 602{
583 struct f75375_data *data = i2c_get_clientdata(client);
584 int err; 603 int err;
585 604
586 hwmon_device_unregister(data->hwmon_dev); 605 f75375_remove(client);
587 sysfs_remove_group(&client->dev.kobj, &f75375_group);
588
589 err = i2c_detach_client(client); 606 err = i2c_detach_client(client);
590 if (err) { 607 if (err) {
591 dev_err(&client->dev, 608 dev_err(&client->dev,
@@ -593,7 +610,91 @@ static int f75375_detach_client(struct i2c_client *client)
593 "client not detached.\n"); 610 "client not detached.\n");
594 return err; 611 return err;
595 } 612 }
613 kfree(client);
614 return 0;
615}
616
617static void f75375_init(struct i2c_client *client, struct f75375_data *data,
618 struct f75375s_platform_data *f75375s_pdata)
619{
620 int nr;
621 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
622 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
623 for (nr = 0; nr < 2; nr++) {
624 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
625 f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
626 data->pwm[nr]);
627 }
628
629}
630
631static int f75375_probe(struct i2c_client *client)
632{
633 struct f75375_data *data = i2c_get_clientdata(client);
634 struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
635 int err;
636
637 if (!i2c_check_functionality(client->adapter,
638 I2C_FUNC_SMBUS_BYTE_DATA))
639 return -EIO;
640 if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL)))
641 return -ENOMEM;
642
643 i2c_set_clientdata(client, data);
644 data->client = client;
645 mutex_init(&data->update_lock);
646
647 if (strcmp(client->name, "f75375") == 0)
648 data->kind = f75375;
649 else if (strcmp(client->name, "f75373") == 0)
650 data->kind = f75373;
651 else {
652 dev_err(&client->dev, "Unsupported device: %s\n", client->name);
653 return -ENODEV;
654 }
655
656 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
657 goto exit_free;
658
659 if (data->kind == f75375) {
660 err = sysfs_chmod_file(&client->dev.kobj,
661 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
662 S_IRUGO | S_IWUSR);
663 if (err)
664 goto exit_remove;
665 err = sysfs_chmod_file(&client->dev.kobj,
666 &sensor_dev_attr_pwm2_mode.dev_attr.attr,
667 S_IRUGO | S_IWUSR);
668 if (err)
669 goto exit_remove;
670 }
671
672 data->hwmon_dev = hwmon_device_register(&client->dev);
673 if (IS_ERR(data->hwmon_dev)) {
674 err = PTR_ERR(data->hwmon_dev);
675 goto exit_remove;
676 }
677
678 if (f75375s_pdata != NULL)
679 f75375_init(client, data, f75375s_pdata);
680
681 return 0;
682
683exit_remove:
684 sysfs_remove_group(&client->dev.kobj, &f75375_group);
685exit_free:
596 kfree(data); 686 kfree(data);
687 i2c_set_clientdata(client, NULL);
688 return err;
689}
690
691static int f75375_remove(struct i2c_client *client)
692{
693 struct f75375_data *data = i2c_get_clientdata(client);
694 hwmon_device_unregister(data->hwmon_dev);
695 sysfs_remove_group(&client->dev.kobj, &f75375_group);
696 kfree(data);
697 i2c_set_clientdata(client, NULL);
597 return 0; 698 return 0;
598} 699}
599 700
@@ -608,20 +709,17 @@ static int f75375_attach_adapter(struct i2c_adapter *adapter)
608static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) 709static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
609{ 710{
610 struct i2c_client *client; 711 struct i2c_client *client;
611 struct f75375_data *data;
612 u8 version = 0; 712 u8 version = 0;
613 int err = 0; 713 int err = 0;
614 const char *name = ""; 714 const char *name = "";
615 715
616 if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) { 716 if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
617 err = -ENOMEM; 717 err = -ENOMEM;
618 goto exit; 718 goto exit;
619 } 719 }
620 client = &data->client;
621 i2c_set_clientdata(client, data);
622 client->addr = address; 720 client->addr = address;
623 client->adapter = adapter; 721 client->adapter = adapter;
624 client->driver = &f75375_driver; 722 client->driver = &f75375_legacy_driver;
625 723
626 if (kind < 0) { 724 if (kind < 0) {
627 u16 vendid = f75375_read16(client, F75375_REG_VENDOR); 725 u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
@@ -644,42 +742,42 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
644 } else if (kind == f75373) { 742 } else if (kind == f75373) {
645 name = "f75373"; 743 name = "f75373";
646 } 744 }
647
648 dev_info(&adapter->dev, "found %s version: %02X\n", name, version); 745 dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
649 strlcpy(client->name, name, I2C_NAME_SIZE); 746 strlcpy(client->name, name, I2C_NAME_SIZE);
650 data->kind = kind; 747
651 mutex_init(&data->update_lock);
652 if ((err = i2c_attach_client(client))) 748 if ((err = i2c_attach_client(client)))
653 goto exit_free; 749 goto exit_free;
654 750
655 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) 751 if ((err = f75375_probe(client)) < 0)
656 goto exit_detach; 752 goto exit_detach;
657 753
658 data->hwmon_dev = hwmon_device_register(&client->dev);
659 if (IS_ERR(data->hwmon_dev)) {
660 err = PTR_ERR(data->hwmon_dev);
661 goto exit_remove;
662 }
663
664 return 0; 754 return 0;
665 755
666exit_remove:
667 sysfs_remove_group(&client->dev.kobj, &f75375_group);
668exit_detach: 756exit_detach:
669 i2c_detach_client(client); 757 i2c_detach_client(client);
670exit_free: 758exit_free:
671 kfree(data); 759 kfree(client);
672exit: 760exit:
673 return err; 761 return err;
674} 762}
675 763
676static int __init sensors_f75375_init(void) 764static int __init sensors_f75375_init(void)
677{ 765{
678 return i2c_add_driver(&f75375_driver); 766 int status;
767 status = i2c_add_driver(&f75375_driver);
768 if (status)
769 return status;
770
771 status = i2c_add_driver(&f75375_legacy_driver);
772 if (status)
773 i2c_del_driver(&f75375_driver);
774
775 return status;
679} 776}
680 777
681static void __exit sensors_f75375_exit(void) 778static void __exit sensors_f75375_exit(void)
682{ 779{
780 i2c_del_driver(&f75375_legacy_driver);
683 i2c_del_driver(&f75375_driver); 781 i2c_del_driver(&f75375_driver);
684} 782}
685 783