aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:08 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:08 -0400
commit65817ed8d1376afff21019b5c0e0109e5a7d9cc0 (patch)
treec06d100f8f6874fe46465c43b0167c98f36f8296 /drivers/hwmon
parent369932f6f840aedfbc717dd156bba7668a11d916 (diff)
hwmon: (adm1021) Convert to a new-style i2c driver
The new-style adm1021 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/adm1021.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index ecbf69484bf5..b11e06f644b1 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -78,7 +78,6 @@ clearing it. Weird, ey? --Phil */
78 78
79/* Each client has this additional data */ 79/* Each client has this additional data */
80struct adm1021_data { 80struct adm1021_data {
81 struct i2c_client client;
82 struct device *hwmon_dev; 81 struct device *hwmon_dev;
83 enum chips type; 82 enum chips type;
84 83
@@ -98,23 +97,42 @@ struct adm1021_data {
98 u8 remote_temp_offset_prec; 97 u8 remote_temp_offset_prec;
99}; 98};
100 99
101static int adm1021_attach_adapter(struct i2c_adapter *adapter); 100static int adm1021_probe(struct i2c_client *client,
102static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); 101 const struct i2c_device_id *id);
102static int adm1021_detect(struct i2c_client *client, int kind,
103 struct i2c_board_info *info);
103static void adm1021_init_client(struct i2c_client *client); 104static void adm1021_init_client(struct i2c_client *client);
104static int adm1021_detach_client(struct i2c_client *client); 105static int adm1021_remove(struct i2c_client *client);
105static struct adm1021_data *adm1021_update_device(struct device *dev); 106static struct adm1021_data *adm1021_update_device(struct device *dev);
106 107
107/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ 108/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
108static int read_only; 109static int read_only;
109 110
110 111
112static const struct i2c_device_id adm1021_id[] = {
113 { "adm1021", adm1021 },
114 { "adm1023", adm1023 },
115 { "max1617", max1617 },
116 { "max1617a", max1617a },
117 { "thmc10", thmc10 },
118 { "lm84", lm84 },
119 { "gl523sm", gl523sm },
120 { "mc1066", mc1066 },
121 { }
122};
123MODULE_DEVICE_TABLE(i2c, adm1021_id);
124
111/* This is the driver that will be inserted */ 125/* This is the driver that will be inserted */
112static struct i2c_driver adm1021_driver = { 126static struct i2c_driver adm1021_driver = {
127 .class = I2C_CLASS_HWMON,
113 .driver = { 128 .driver = {
114 .name = "adm1021", 129 .name = "adm1021",
115 }, 130 },
116 .attach_adapter = adm1021_attach_adapter, 131 .probe = adm1021_probe,
117 .detach_client = adm1021_detach_client, 132 .remove = adm1021_remove,
133 .id_table = adm1021_id,
134 .detect = adm1021_detect,
135 .address_data = &addr_data,
118}; 136};
119 137
120static ssize_t show_temp(struct device *dev, 138static ssize_t show_temp(struct device *dev,
@@ -216,13 +234,6 @@ static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
216 234
217static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 235static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
218 236
219static int adm1021_attach_adapter(struct i2c_adapter *adapter)
220{
221 if (!(adapter->class & I2C_CLASS_HWMON))
222 return 0;
223 return i2c_probe(adapter, &addr_data, adm1021_detect);
224}
225
226static struct attribute *adm1021_attributes[] = { 237static struct attribute *adm1021_attributes[] = {
227 &sensor_dev_attr_temp1_max.dev_attr.attr, 238 &sensor_dev_attr_temp1_max.dev_attr.attr,
228 &sensor_dev_attr_temp1_min.dev_attr.attr, 239 &sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -243,36 +254,21 @@ static const struct attribute_group adm1021_group = {
243 .attrs = adm1021_attributes, 254 .attrs = adm1021_attributes,
244}; 255};
245 256
246static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) 257/* Return 0 if detection is successful, -ENODEV otherwise */
258static int adm1021_detect(struct i2c_client *client, int kind,
259 struct i2c_board_info *info)
247{ 260{
261 struct i2c_adapter *adapter = client->adapter;
248 int i; 262 int i;
249 struct i2c_client *client;
250 struct adm1021_data *data;
251 int err = 0;
252 const char *type_name = ""; 263 const char *type_name = "";
253 int conv_rate, status, config; 264 int conv_rate, status, config;
254 265
255 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 266 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
256 pr_debug("adm1021: detect failed, " 267 pr_debug("adm1021: detect failed, "
257 "smbus byte data not supported!\n"); 268 "smbus byte data not supported!\n");
258 goto error0; 269 return -ENODEV;
259 }
260
261 /* OK. For now, we presume we have a valid client. We now create the
262 client structure, even though we cannot fill it completely yet.
263 But it allows us to access adm1021 register values. */
264
265 if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
266 pr_debug("adm1021: detect failed, kzalloc failed!\n");
267 err = -ENOMEM;
268 goto error0;
269 } 270 }
270 271
271 client = &data->client;
272 i2c_set_clientdata(client, data);
273 client->addr = address;
274 client->adapter = adapter;
275 client->driver = &adm1021_driver;
276 status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS); 272 status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS);
277 conv_rate = i2c_smbus_read_byte_data(client, 273 conv_rate = i2c_smbus_read_byte_data(client,
278 ADM1021_REG_CONV_RATE_R); 274 ADM1021_REG_CONV_RATE_R);
@@ -284,8 +280,7 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
284 || (conv_rate & 0xF8) != 0x00) { 280 || (conv_rate & 0xF8) != 0x00) {
285 pr_debug("adm1021: detect failed, " 281 pr_debug("adm1021: detect failed, "
286 "chip not detected!\n"); 282 "chip not detected!\n");
287 err = -ENODEV; 283 return -ENODEV;
288 goto error1;
289 } 284 }
290 } 285 }
291 286
@@ -336,24 +331,36 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
336 type_name = "mc1066"; 331 type_name = "mc1066";
337 } 332 }
338 pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", 333 pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
339 type_name, i2c_adapter_id(adapter), address); 334 type_name, i2c_adapter_id(adapter), client->addr);
335 strlcpy(info->type, type_name, I2C_NAME_SIZE);
340 336
341 /* Fill in the remaining client fields */ 337 return 0;
342 strlcpy(client->name, type_name, I2C_NAME_SIZE); 338}
343 data->type = kind;
344 mutex_init(&data->update_lock);
345 339
346 /* Tell the I2C layer a new client has arrived */ 340static int adm1021_probe(struct i2c_client *client,
347 if ((err = i2c_attach_client(client))) 341 const struct i2c_device_id *id)
348 goto error1; 342{
343 struct adm1021_data *data;
344 int err;
345
346 data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL);
347 if (!data) {
348 pr_debug("adm1021: detect failed, kzalloc failed!\n");
349 err = -ENOMEM;
350 goto error0;
351 }
352
353 i2c_set_clientdata(client, data);
354 data->type = id->driver_data;
355 mutex_init(&data->update_lock);
349 356
350 /* Initialize the ADM1021 chip */ 357 /* Initialize the ADM1021 chip */
351 if (kind != lm84 && !read_only) 358 if (data->type != lm84 && !read_only)
352 adm1021_init_client(client); 359 adm1021_init_client(client);
353 360
354 /* Register sysfs hooks */ 361 /* Register sysfs hooks */
355 if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group))) 362 if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
356 goto error2; 363 goto error1;
357 364
358 data->hwmon_dev = hwmon_device_register(&client->dev); 365 data->hwmon_dev = hwmon_device_register(&client->dev);
359 if (IS_ERR(data->hwmon_dev)) { 366 if (IS_ERR(data->hwmon_dev)) {
@@ -365,8 +372,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
365 372
366error3: 373error3:
367 sysfs_remove_group(&client->dev.kobj, &adm1021_group); 374 sysfs_remove_group(&client->dev.kobj, &adm1021_group);
368error2:
369 i2c_detach_client(client);
370error1: 375error1:
371 kfree(data); 376 kfree(data);
372error0: 377error0:
@@ -382,17 +387,13 @@ static void adm1021_init_client(struct i2c_client *client)
382 i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04); 387 i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
383} 388}
384 389
385static int adm1021_detach_client(struct i2c_client *client) 390static int adm1021_remove(struct i2c_client *client)
386{ 391{
387 struct adm1021_data *data = i2c_get_clientdata(client); 392 struct adm1021_data *data = i2c_get_clientdata(client);
388 int err;
389 393
390 hwmon_device_unregister(data->hwmon_dev); 394 hwmon_device_unregister(data->hwmon_dev);
391 sysfs_remove_group(&client->dev.kobj, &adm1021_group); 395 sysfs_remove_group(&client->dev.kobj, &adm1021_group);
392 396
393 if ((err = i2c_detach_client(client)))
394 return err;
395
396 kfree(data); 397 kfree(data);
397 return 0; 398 return 0;
398} 399}