diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:10 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:10 -0400 |
commit | 008f1ca51e4a25ee3e34b8faa901dbeefaf0081a (patch) | |
tree | 9f926c488788902e0522fc0916b66c73fb6754b3 | |
parent | 7347cb388e5aecffc4920bd5ea6a61e4a4690bae (diff) |
hwmon: (adt7470) Convert to a new-style i2c driver
The new-style adt7470 driver implements the optional detect() callback
to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Darrick J. Wong <djwong@us.ibm.com>
-rw-r--r-- | drivers/hwmon/adt7470.c | 100 |
1 files changed, 48 insertions, 52 deletions
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 6b5325f33a2c..d368d8f845e1 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -138,7 +138,6 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
139 | 139 | ||
140 | struct adt7470_data { | 140 | struct adt7470_data { |
141 | struct i2c_client client; | ||
142 | struct device *hwmon_dev; | 141 | struct device *hwmon_dev; |
143 | struct attribute_group attrs; | 142 | struct attribute_group attrs; |
144 | struct mutex lock; | 143 | struct mutex lock; |
@@ -164,16 +163,28 @@ struct adt7470_data { | |||
164 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; | 163 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; |
165 | }; | 164 | }; |
166 | 165 | ||
167 | static int adt7470_attach_adapter(struct i2c_adapter *adapter); | 166 | static int adt7470_probe(struct i2c_client *client, |
168 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind); | 167 | const struct i2c_device_id *id); |
169 | static int adt7470_detach_client(struct i2c_client *client); | 168 | static int adt7470_detect(struct i2c_client *client, int kind, |
169 | struct i2c_board_info *info); | ||
170 | static int adt7470_remove(struct i2c_client *client); | ||
171 | |||
172 | static const struct i2c_device_id adt7470_id[] = { | ||
173 | { "adt7470", adt7470 }, | ||
174 | { } | ||
175 | }; | ||
176 | MODULE_DEVICE_TABLE(i2c, adt7470_id); | ||
170 | 177 | ||
171 | static struct i2c_driver adt7470_driver = { | 178 | static struct i2c_driver adt7470_driver = { |
179 | .class = I2C_CLASS_HWMON, | ||
172 | .driver = { | 180 | .driver = { |
173 | .name = "adt7470", | 181 | .name = "adt7470", |
174 | }, | 182 | }, |
175 | .attach_adapter = adt7470_attach_adapter, | 183 | .probe = adt7470_probe, |
176 | .detach_client = adt7470_detach_client, | 184 | .remove = adt7470_remove, |
185 | .id_table = adt7470_id, | ||
186 | .detect = adt7470_detect, | ||
187 | .address_data = &addr_data, | ||
177 | }; | 188 | }; |
178 | 189 | ||
179 | /* | 190 | /* |
@@ -1004,64 +1015,52 @@ static struct attribute *adt7470_attr[] = | |||
1004 | NULL | 1015 | NULL |
1005 | }; | 1016 | }; |
1006 | 1017 | ||
1007 | static int adt7470_attach_adapter(struct i2c_adapter *adapter) | 1018 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1008 | { | 1019 | static int adt7470_detect(struct i2c_client *client, int kind, |
1009 | if (!(adapter->class & I2C_CLASS_HWMON)) | 1020 | struct i2c_board_info *info) |
1010 | return 0; | ||
1011 | return i2c_probe(adapter, &addr_data, adt7470_detect); | ||
1012 | } | ||
1013 | |||
1014 | static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) | ||
1015 | { | 1021 | { |
1016 | struct i2c_client *client; | 1022 | struct i2c_adapter *adapter = client->adapter; |
1017 | struct adt7470_data *data; | ||
1018 | int err = 0; | ||
1019 | 1023 | ||
1020 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1024 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1021 | goto exit; | 1025 | return -ENODEV; |
1022 | |||
1023 | if (!(data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL))) { | ||
1024 | err = -ENOMEM; | ||
1025 | goto exit; | ||
1026 | } | ||
1027 | |||
1028 | client = &data->client; | ||
1029 | client->addr = address; | ||
1030 | client->adapter = adapter; | ||
1031 | client->driver = &adt7470_driver; | ||
1032 | |||
1033 | i2c_set_clientdata(client, data); | ||
1034 | |||
1035 | mutex_init(&data->lock); | ||
1036 | 1026 | ||
1037 | if (kind <= 0) { | 1027 | if (kind <= 0) { |
1038 | int vendor, device, revision; | 1028 | int vendor, device, revision; |
1039 | 1029 | ||
1040 | vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR); | 1030 | vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR); |
1041 | if (vendor != ADT7470_VENDOR) { | 1031 | if (vendor != ADT7470_VENDOR) |
1042 | err = -ENODEV; | 1032 | return -ENODEV; |
1043 | goto exit_free; | ||
1044 | } | ||
1045 | 1033 | ||
1046 | device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE); | 1034 | device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE); |
1047 | if (device != ADT7470_DEVICE) { | 1035 | if (device != ADT7470_DEVICE) |
1048 | err = -ENODEV; | 1036 | return -ENODEV; |
1049 | goto exit_free; | ||
1050 | } | ||
1051 | 1037 | ||
1052 | revision = i2c_smbus_read_byte_data(client, | 1038 | revision = i2c_smbus_read_byte_data(client, |
1053 | ADT7470_REG_REVISION); | 1039 | ADT7470_REG_REVISION); |
1054 | if (revision != ADT7470_REVISION) { | 1040 | if (revision != ADT7470_REVISION) |
1055 | err = -ENODEV; | 1041 | return -ENODEV; |
1056 | goto exit_free; | ||
1057 | } | ||
1058 | } else | 1042 | } else |
1059 | dev_dbg(&adapter->dev, "detection forced\n"); | 1043 | dev_dbg(&adapter->dev, "detection forced\n"); |
1060 | 1044 | ||
1061 | strlcpy(client->name, "adt7470", I2C_NAME_SIZE); | 1045 | strlcpy(info->type, "adt7470", I2C_NAME_SIZE); |
1062 | 1046 | ||
1063 | if ((err = i2c_attach_client(client))) | 1047 | return 0; |
1064 | goto exit_free; | 1048 | } |
1049 | |||
1050 | static int adt7470_probe(struct i2c_client *client, | ||
1051 | const struct i2c_device_id *id) | ||
1052 | { | ||
1053 | struct adt7470_data *data; | ||
1054 | int err; | ||
1055 | |||
1056 | data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL); | ||
1057 | if (!data) { | ||
1058 | err = -ENOMEM; | ||
1059 | goto exit; | ||
1060 | } | ||
1061 | |||
1062 | i2c_set_clientdata(client, data); | ||
1063 | mutex_init(&data->lock); | ||
1065 | 1064 | ||
1066 | dev_info(&client->dev, "%s chip found\n", client->name); | 1065 | dev_info(&client->dev, "%s chip found\n", client->name); |
1067 | 1066 | ||
@@ -1071,7 +1070,7 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1071 | /* Register sysfs hooks */ | 1070 | /* Register sysfs hooks */ |
1072 | data->attrs.attrs = adt7470_attr; | 1071 | data->attrs.attrs = adt7470_attr; |
1073 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) | 1072 | if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) |
1074 | goto exit_detach; | 1073 | goto exit_free; |
1075 | 1074 | ||
1076 | data->hwmon_dev = hwmon_device_register(&client->dev); | 1075 | data->hwmon_dev = hwmon_device_register(&client->dev); |
1077 | if (IS_ERR(data->hwmon_dev)) { | 1076 | if (IS_ERR(data->hwmon_dev)) { |
@@ -1083,21 +1082,18 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1083 | 1082 | ||
1084 | exit_remove: | 1083 | exit_remove: |
1085 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1084 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1086 | exit_detach: | ||
1087 | i2c_detach_client(client); | ||
1088 | exit_free: | 1085 | exit_free: |
1089 | kfree(data); | 1086 | kfree(data); |
1090 | exit: | 1087 | exit: |
1091 | return err; | 1088 | return err; |
1092 | } | 1089 | } |
1093 | 1090 | ||
1094 | static int adt7470_detach_client(struct i2c_client *client) | 1091 | static int adt7470_remove(struct i2c_client *client) |
1095 | { | 1092 | { |
1096 | struct adt7470_data *data = i2c_get_clientdata(client); | 1093 | struct adt7470_data *data = i2c_get_clientdata(client); |
1097 | 1094 | ||
1098 | hwmon_device_unregister(data->hwmon_dev); | 1095 | hwmon_device_unregister(data->hwmon_dev); |
1099 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1096 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1100 | i2c_detach_client(client); | ||
1101 | kfree(data); | 1097 | kfree(data); |
1102 | return 0; | 1098 | return 0; |
1103 | } | 1099 | } |