diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 19:30:08 +0200 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 19:30:08 +0200 |
commit | 57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1 (patch) | |
tree | 9a62d8e2f2370e8d6b01f469c67e70e787515b32 /drivers/hwmon/adm1026.c | |
parent | 7dbafe021ba360bf25674a7e290d3e4a5c953981 (diff) | |
download | lwn-57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1.tar.gz lwn-57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1.zip |
hwmon: (adm1026) Convert to a new-style i2c driver
The new-style adm1026 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/adm1026.c')
-rw-r--r-- | drivers/hwmon/adm1026.c | 109 |
1 files changed, 44 insertions, 65 deletions
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 904c6ce9d83f..7fe2441fc845 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -259,7 +259,6 @@ struct pwm_data { }; struct adm1026_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; @@ -293,10 +292,11 @@ struct adm1026_data { u8 config3; /* Register value */ }; -static int adm1026_attach_adapter(struct i2c_adapter *adapter); -static int adm1026_detect(struct i2c_adapter *adapter, int address, - int kind); -static int adm1026_detach_client(struct i2c_client *client); +static int adm1026_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1026_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int adm1026_remove(struct i2c_client *client); static int adm1026_read_value(struct i2c_client *client, u8 reg); static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); static void adm1026_print_gpio(struct i2c_client *client); @@ -305,22 +305,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev); static void adm1026_init_client(struct i2c_client *client); +static const struct i2c_device_id adm1026_id[] = { + { "adm1026", adm1026 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1026_id); + static struct i2c_driver adm1026_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1026", }, - .attach_adapter = adm1026_attach_adapter, - .detach_client = adm1026_detach_client, + .probe = adm1026_probe, + .remove = adm1026_remove, + .id_table = adm1026_id, + .detect = adm1026_detect, + .address_data = &addr_data, }; -static int adm1026_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) { - return 0; - } - return i2c_probe(adapter, &addr_data, adm1026_detect); -} - static int adm1026_read_value(struct i2c_client *client, u8 reg) { int res; @@ -1647,48 +1649,32 @@ static const struct attribute_group adm1026_group_in8_9 = { .attrs = adm1026_attributes_in8_9, }; -static int adm1026_detect(struct i2c_adapter *adapter, int address, - int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1026_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; + int address = client->addr; int company, verstep; - struct i2c_client *client; - struct adm1026_data *data; - int err = 0; - const char *type_name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { /* We need to be able to do byte I/O */ - goto exit; + return -ENODEV; }; - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access adm1026_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1026_driver; - /* Now, we do the remaining detection. */ company = adm1026_read_value(client, ADM1026_REG_COMPANY); verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); - dev_dbg(&client->dev, "Detecting device at %d,0x%02x with" + dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", i2c_adapter_id(client->adapter), client->addr, company, verstep); /* If auto-detecting, Determine the chip type. */ if (kind <= 0) { - dev_dbg(&client->dev, "Autodetecting device at %d,0x%02x " + dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x " "...\n", i2c_adapter_id(adapter), address); if (company == ADM1026_COMPANY_ANALOG_DEV && verstep == ADM1026_VERSTEP_ADM1026) { @@ -1704,7 +1690,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, verstep); kind = any_chip; } else { - dev_dbg(&client->dev, ": Autodetection " + dev_dbg(&adapter->dev, ": Autodetection " "failed\n"); /* Not an ADM1026 ... */ if (kind == 0) { /* User used force=x,y */ @@ -1713,33 +1699,29 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, "force_adm1026.\n", i2c_adapter_id(adapter), address); } - goto exitfree; + return -ENODEV; } } + strlcpy(info->type, "adm1026", I2C_NAME_SIZE); - /* Fill in the chip specific driver values */ - switch (kind) { - case any_chip : - type_name = "adm1026"; - break; - case adm1026 : - type_name = "adm1026"; - break; - default : - dev_err(&adapter->dev, ": Internal error, invalid " - "kind (%d)!\n", kind); - err = -EFAULT; - goto exitfree; + return 0; +} + +static int adm1026_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1026_data *data; + int err; + + data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } - strlcpy(client->name, type_name, I2C_NAME_SIZE); - /* Fill in the remaining client fields */ + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exitfree; - /* Set the VRM version */ data->vrm = vid_which_vrm(); @@ -1748,7 +1730,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) - goto exitdetach; + goto exitfree; if (data->config1 & CFG1_AIN8_9) err = sysfs_create_group(&client->dev.kobj, &adm1026_group_in8_9); @@ -1773,15 +1755,13 @@ exitremove: sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); -exitdetach: - i2c_detach_client(client); exitfree: kfree(data); exit: return err; } -static int adm1026_detach_client(struct i2c_client *client) +static int adm1026_remove(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); @@ -1790,7 +1770,6 @@ static int adm1026_detach_client(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); - i2c_detach_client(client); kfree(data); return 0; } |