Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: Convert the pcf8591 driver to a new-style i2c driver

The new-style pcf8591 driver implements the optional detect() callback
to cover the use cases of the legacy driver.

Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

Jean Delvare and committed by
Jean Delvare
8b77e6ac 68be3363

+40 -54
+40 -54
drivers/i2c/chips/pcf8591.c
··· 72 72 #define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg)) 73 73 74 74 struct pcf8591_data { 75 - struct i2c_client client; 76 75 struct mutex update_lock; 77 76 78 77 u8 control; 79 78 u8 aout; 80 79 }; 81 80 82 - static int pcf8591_attach_adapter(struct i2c_adapter *adapter); 83 - static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind); 84 - static int pcf8591_detach_client(struct i2c_client *client); 85 81 static void pcf8591_init_client(struct i2c_client *client); 86 82 static int pcf8591_read_channel(struct device *dev, int channel); 87 - 88 - /* This is the driver that will be inserted */ 89 - static struct i2c_driver pcf8591_driver = { 90 - .driver = { 91 - .name = "pcf8591", 92 - }, 93 - .attach_adapter = pcf8591_attach_adapter, 94 - .detach_client = pcf8591_detach_client, 95 - }; 96 83 97 84 /* following are the sysfs callback functions */ 98 85 #define show_in_channel(channel) \ ··· 167 180 /* 168 181 * Real code 169 182 */ 170 - static int pcf8591_attach_adapter(struct i2c_adapter *adapter) 171 - { 172 - return i2c_probe(adapter, &addr_data, pcf8591_detect); 173 - } 174 183 175 - /* This function is called by i2c_probe */ 176 - static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) 184 + /* Return 0 if detection is successful, -ENODEV otherwise */ 185 + static int pcf8591_detect(struct i2c_client *client, int kind, 186 + struct i2c_board_info *info) 177 187 { 178 - struct i2c_client *client; 179 - struct pcf8591_data *data; 180 - int err = 0; 188 + struct i2c_adapter *adapter = client->adapter; 181 189 182 190 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE 183 191 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 184 - goto exit; 192 + return -ENODEV; 185 193 186 - /* OK. For now, we presume we have a valid client. We now create the 187 - client structure, even though we cannot fill it completely yet. */ 194 + /* Now, we would do the remaining detection. But the PCF8591 is plainly 195 + impossible to detect! Stupid chip. */ 196 + 197 + strlcpy(info->type, "pcf8591", I2C_NAME_SIZE); 198 + 199 + return 0; 200 + } 201 + 202 + static int pcf8591_probe(struct i2c_client *client, 203 + const struct i2c_device_id *id) 204 + { 205 + struct pcf8591_data *data; 206 + int err; 207 + 188 208 if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { 189 209 err = -ENOMEM; 190 210 goto exit; 191 211 } 192 212 193 - client = &data->client; 194 213 i2c_set_clientdata(client, data); 195 - client->addr = address; 196 - client->adapter = adapter; 197 - client->driver = &pcf8591_driver; 198 - 199 - /* Now, we would do the remaining detection. But the PCF8591 is plainly 200 - impossible to detect! Stupid chip. */ 201 - 202 - /* Determine the chip type - only one kind supported! */ 203 - if (kind <= 0) 204 - kind = pcf8591; 205 - 206 - /* Fill in the remaining client fields and put it into the global 207 - list */ 208 - strlcpy(client->name, "pcf8591", I2C_NAME_SIZE); 209 214 mutex_init(&data->update_lock); 210 - 211 - /* Tell the I2C layer a new client has arrived */ 212 - if ((err = i2c_attach_client(client))) 213 - goto exit_kfree; 214 215 215 216 /* Initialize the PCF8591 chip */ 216 217 pcf8591_init_client(client); ··· 206 231 /* Register sysfs hooks */ 207 232 err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group); 208 233 if (err) 209 - goto exit_detach; 234 + goto exit_kfree; 210 235 211 236 /* Register input2 if not in "two differential inputs" mode */ 212 237 if (input_mode != 3) { ··· 227 252 exit_sysfs_remove: 228 253 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); 229 254 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); 230 - exit_detach: 231 - i2c_detach_client(client); 232 255 exit_kfree: 233 256 kfree(data); 234 257 exit: 235 258 return err; 236 259 } 237 260 238 - static int pcf8591_detach_client(struct i2c_client *client) 261 + static int pcf8591_remove(struct i2c_client *client) 239 262 { 240 - int err; 241 - 242 263 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); 243 264 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); 244 - 245 - if ((err = i2c_detach_client(client))) 246 - return err; 247 - 248 265 kfree(i2c_get_clientdata(client)); 249 266 return 0; 250 267 } ··· 282 315 else 283 316 return (10 * value); 284 317 } 318 + 319 + static const struct i2c_device_id pcf8591_id[] = { 320 + { "pcf8591", 0 }, 321 + { } 322 + }; 323 + MODULE_DEVICE_TABLE(i2c, pcf8591_id); 324 + 325 + static struct i2c_driver pcf8591_driver = { 326 + .driver = { 327 + .name = "pcf8591", 328 + }, 329 + .probe = pcf8591_probe, 330 + .remove = pcf8591_remove, 331 + .id_table = pcf8591_id, 332 + 333 + .class = I2C_CLASS_HWMON, /* Nearest choice */ 334 + .detect = pcf8591_detect, 335 + .address_data = &addr_data, 336 + }; 285 337 286 338 static int __init pcf8591_init(void) 287 339 {