aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/max1619.c101
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 7e7267a04544..1ab1cacad598 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -79,23 +79,34 @@ I2C_CLIENT_INSMOD_1(max1619);
79 * Functions declaration 79 * Functions declaration
80 */ 80 */
81 81
82static int max1619_attach_adapter(struct i2c_adapter *adapter); 82static int max1619_probe(struct i2c_client *client,
83static int max1619_detect(struct i2c_adapter *adapter, int address, 83 const struct i2c_device_id *id);
84 int kind); 84static int max1619_detect(struct i2c_client *client, int kind,
85 struct i2c_board_info *info);
85static void max1619_init_client(struct i2c_client *client); 86static void max1619_init_client(struct i2c_client *client);
86static int max1619_detach_client(struct i2c_client *client); 87static int max1619_remove(struct i2c_client *client);
87static struct max1619_data *max1619_update_device(struct device *dev); 88static struct max1619_data *max1619_update_device(struct device *dev);
88 89
89/* 90/*
90 * Driver data (common to all clients) 91 * Driver data (common to all clients)
91 */ 92 */
92 93
94static const struct i2c_device_id max1619_id[] = {
95 { "max1619", max1619 },
96 { }
97};
98MODULE_DEVICE_TABLE(i2c, max1619_id);
99
93static struct i2c_driver max1619_driver = { 100static struct i2c_driver max1619_driver = {
101 .class = I2C_CLASS_HWMON,
94 .driver = { 102 .driver = {
95 .name = "max1619", 103 .name = "max1619",
96 }, 104 },
97 .attach_adapter = max1619_attach_adapter, 105 .probe = max1619_probe,
98 .detach_client = max1619_detach_client, 106 .remove = max1619_remove,
107 .id_table = max1619_id,
108 .detect = max1619_detect,
109 .address_data = &addr_data,
99}; 110};
100 111
101/* 112/*
@@ -103,7 +114,6 @@ static struct i2c_driver max1619_driver = {
103 */ 114 */
104 115
105struct max1619_data { 116struct max1619_data {
106 struct i2c_client client;
107 struct device *hwmon_dev; 117 struct device *hwmon_dev;
108 struct mutex update_lock; 118 struct mutex update_lock;
109 char valid; /* zero until following fields are valid */ 119 char valid; /* zero until following fields are valid */
@@ -208,41 +218,15 @@ static const struct attribute_group max1619_group = {
208 * Real code 218 * Real code
209 */ 219 */
210 220
211static int max1619_attach_adapter(struct i2c_adapter *adapter) 221/* Return 0 if detection is successful, -ENODEV otherwise */
212{ 222static int max1619_detect(struct i2c_client *new_client, int kind,
213 if (!(adapter->class & I2C_CLASS_HWMON)) 223 struct i2c_board_info *info)
214 return 0;
215 return i2c_probe(adapter, &addr_data, max1619_detect);
216}
217
218/*
219 * The following function does more than just detection. If detection
220 * succeeds, it also registers the new chip.
221 */
222static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
223{ 224{
224 struct i2c_client *new_client; 225 struct i2c_adapter *adapter = new_client->adapter;
225 struct max1619_data *data;
226 int err = 0;
227 const char *name = "";
228 u8 reg_config=0, reg_convrate=0, reg_status=0; 226 u8 reg_config=0, reg_convrate=0, reg_status=0;
229 227
230 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 228 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
231 goto exit; 229 return -ENODEV;
232
233 if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
234 err = -ENOMEM;
235 goto exit;
236 }
237
238 /* The common I2C client data is placed right before the
239 MAX1619-specific data. */
240 new_client = &data->client;
241 i2c_set_clientdata(new_client, data);
242 new_client->addr = address;
243 new_client->adapter = adapter;
244 new_client->driver = &max1619_driver;
245 new_client->flags = 0;
246 230
247 /* 231 /*
248 * Now we do the remaining detection. A negative kind means that 232 * Now we do the remaining detection. A negative kind means that
@@ -265,8 +249,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
265 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { 249 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
266 dev_dbg(&adapter->dev, 250 dev_dbg(&adapter->dev,
267 "MAX1619 detection failed at 0x%02x.\n", 251 "MAX1619 detection failed at 0x%02x.\n",
268 address); 252 new_client->addr);
269 goto exit_free; 253 return -ENODEV;
270 } 254 }
271 } 255 }
272 256
@@ -285,28 +269,37 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
285 dev_info(&adapter->dev, 269 dev_info(&adapter->dev,
286 "Unsupported chip (man_id=0x%02X, " 270 "Unsupported chip (man_id=0x%02X, "
287 "chip_id=0x%02X).\n", man_id, chip_id); 271 "chip_id=0x%02X).\n", man_id, chip_id);
288 goto exit_free; 272 return -ENODEV;
289 } 273 }
290 } 274 }
291 275
292 if (kind == max1619) 276 strlcpy(info->type, "max1619", I2C_NAME_SIZE);
293 name = "max1619"; 277
278 return 0;
279}
280
281static int max1619_probe(struct i2c_client *new_client,
282 const struct i2c_device_id *id)
283{
284 struct max1619_data *data;
285 int err;
286
287 data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL);
288 if (!data) {
289 err = -ENOMEM;
290 goto exit;
291 }
294 292
295 /* We can fill in the remaining client fields */ 293 i2c_set_clientdata(new_client, data);
296 strlcpy(new_client->name, name, I2C_NAME_SIZE);
297 data->valid = 0; 294 data->valid = 0;
298 mutex_init(&data->update_lock); 295 mutex_init(&data->update_lock);
299 296
300 /* Tell the I2C layer a new client has arrived */
301 if ((err = i2c_attach_client(new_client)))
302 goto exit_free;
303
304 /* Initialize the MAX1619 chip */ 297 /* Initialize the MAX1619 chip */
305 max1619_init_client(new_client); 298 max1619_init_client(new_client);
306 299
307 /* Register sysfs hooks */ 300 /* Register sysfs hooks */
308 if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) 301 if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group)))
309 goto exit_detach; 302 goto exit_free;
310 303
311 data->hwmon_dev = hwmon_device_register(&new_client->dev); 304 data->hwmon_dev = hwmon_device_register(&new_client->dev);
312 if (IS_ERR(data->hwmon_dev)) { 305 if (IS_ERR(data->hwmon_dev)) {
@@ -318,8 +311,6 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
318 311
319exit_remove_files: 312exit_remove_files:
320 sysfs_remove_group(&new_client->dev.kobj, &max1619_group); 313 sysfs_remove_group(&new_client->dev.kobj, &max1619_group);
321exit_detach:
322 i2c_detach_client(new_client);
323exit_free: 314exit_free:
324 kfree(data); 315 kfree(data);
325exit: 316exit:
@@ -341,17 +332,13 @@ static void max1619_init_client(struct i2c_client *client)
341 config & 0xBF); /* run */ 332 config & 0xBF); /* run */
342} 333}
343 334
344static int max1619_detach_client(struct i2c_client *client) 335static int max1619_remove(struct i2c_client *client)
345{ 336{
346 struct max1619_data *data = i2c_get_clientdata(client); 337 struct max1619_data *data = i2c_get_clientdata(client);
347 int err;
348 338
349 hwmon_device_unregister(data->hwmon_dev); 339 hwmon_device_unregister(data->hwmon_dev);
350 sysfs_remove_group(&client->dev.kobj, &max1619_group); 340 sysfs_remove_group(&client->dev.kobj, &max1619_group);
351 341
352 if ((err = i2c_detach_client(client)))
353 return err;
354
355 kfree(data); 342 kfree(data);
356 return 0; 343 return 0;
357} 344}