]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/i2c/chips/max6875.c
i2c: Convert the max6875 driver to a new-style i2c driver
[linux-2.6-omap-h63xx.git] / drivers / i2c / chips / max6875.c
index 5a0285d8b6f9888f9477d4a1a7284f0dd5a7bee6..033d9d81ec8ae0381f3139f541254d3345b8cae8 100644 (file)
@@ -53,7 +53,7 @@ I2C_CLIENT_INSMOD_1(max6875);
 
 /* Each client has this additional data */
 struct max6875_data {
-       struct i2c_client       client;
+       struct i2c_client       *fake_client;
        struct mutex            update_lock;
 
        u32                     valid;
@@ -61,19 +61,6 @@ struct max6875_data {
        unsigned long           last_updated[USER_EEPROM_SLICES];
 };
 
-static int max6875_attach_adapter(struct i2c_adapter *adapter);
-static int max6875_detect(struct i2c_adapter *adapter, int address, int kind);
-static int max6875_detach_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver max6875_driver = {
-       .driver = {
-               .name   = "max6875",
-       },
-       .attach_adapter = max6875_attach_adapter,
-       .detach_client  = max6875_detach_client,
-};
-
 static void max6875_update_slice(struct i2c_client *client, int slice)
 {
        struct max6875_data *data = i2c_get_clientdata(client);
@@ -159,96 +146,87 @@ static struct bin_attribute user_eeprom_attr = {
        .read = max6875_read,
 };
 
-static int max6875_attach_adapter(struct i2c_adapter *adapter)
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int max6875_detect(struct i2c_client *client, int kind,
+                         struct i2c_board_info *info)
 {
-       return i2c_probe(adapter, &addr_data, max6875_detect);
-}
-
-/* This function is called by i2c_probe */
-static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-       struct i2c_client *real_client;
-       struct i2c_client *fake_client;
-       struct max6875_data *data;
-       int err;
+       struct i2c_adapter *adapter = client->adapter;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
                                     | I2C_FUNC_SMBUS_READ_BYTE))
-               return 0;
+               return -ENODEV;
 
        /* Only check even addresses */
-       if (address & 1)
-               return 0;
+       if (client->addr & 1)
+               return -ENODEV;
+
+       strlcpy(info->type, "max6875", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int max6875_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct max6875_data *data;
+       int err;
 
        if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
                return -ENOMEM;
 
        /* A fake client is created on the odd address */
-       if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+       data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1);
+       if (!data->fake_client) {
                err = -ENOMEM;
-               goto exit_kfree1;
+               goto exit_kfree;
        }
 
        /* Init real i2c_client */
-       real_client = &data->client;
-       i2c_set_clientdata(real_client, data);
-       real_client->addr = address;
-       real_client->adapter = adapter;
-       real_client->driver = &max6875_driver;
-       strlcpy(real_client->name, "max6875", I2C_NAME_SIZE);
+       i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
 
-       /* Init fake client data */
-       i2c_set_clientdata(fake_client, NULL);
-       fake_client->addr = address | 1;
-       fake_client->adapter = adapter;
-       fake_client->driver = &max6875_driver;
-       strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE);
-
-       if ((err = i2c_attach_client(real_client)) != 0)
-               goto exit_kfree2;
-
-       if ((err = i2c_attach_client(fake_client)) != 0)
-               goto exit_detach1;
-
-       err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
+       err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
        if (err)
-               goto exit_detach2;
+               goto exit_remove_fake;
 
        return 0;
 
-exit_detach2:
-       i2c_detach_client(fake_client);
-exit_detach1:
-       i2c_detach_client(real_client);
-exit_kfree2:
-       kfree(fake_client);
-exit_kfree1:
+exit_remove_fake:
+       i2c_unregister_device(data->fake_client);
+exit_kfree:
        kfree(data);
        return err;
 }
 
-/* Will be called for both the real client and the fake client */
-static int max6875_detach_client(struct i2c_client *client)
+static int max6875_remove(struct i2c_client *client)
 {
-       int err;
        struct max6875_data *data = i2c_get_clientdata(client);
 
-       /* data is NULL for the fake client */
-       if (data)
-               sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
+       i2c_unregister_device(data->fake_client);
 
-       err = i2c_detach_client(client);
-       if (err)
-               return err;
+       sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
+       kfree(data);
 
-       if (data)               /* real client */
-               kfree(data);
-       else                    /* fake client */
-               kfree(client);
        return 0;
 }
 
+static const struct i2c_device_id max6875_id[] = {
+       { "max6875", 0 },
+       { }
+};
+
+static struct i2c_driver max6875_driver = {
+       .driver = {
+               .name   = "max6875",
+       },
+       .probe          = max6875_probe,
+       .remove         = max6875_remove,
+       .id_table       = max6875_id,
+
+       .detect         = max6875_detect,
+       .address_data   = &addr_data,
+};
+
 static int __init max6875_init(void)
 {
        return i2c_add_driver(&max6875_driver);