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

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

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

Warning: users will now have to use the force module parameter to get
the driver to attach to their device. That's not a bad thing as these
devices can't be detected anyway.

Note that this doesn't change the fact that this driver is deprecated
in favor of gpio/pcf857x.

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

authored by

Jean Delvare and committed by
Jean Delvare
97addff6 833bedb8

+45 -64
+3 -6
Documentation/i2c/chips/pcf8575
··· 40 40 --------- 41 41 42 42 There is no method known to detect whether a chip on a given I2C address is 43 - a PCF8575 or whether it is any other I2C device. So there are two alternatives 44 - to let the driver find the installed PCF8575 devices: 45 - - Load this driver after any other I2C driver for I2C devices with addresses 46 - in the range 0x20 .. 0x27. 47 - - Pass the I2C bus and address of the installed PCF8575 devices explicitly to 48 - the driver at load time via the probe=... or force=... parameters. 43 + a PCF8575 or whether it is any other I2C device, so you have to pass the I2C 44 + bus and address of the installed PCF8575 devices explicitly to the driver at 45 + load time via the force=... parameter. 49 46 50 47 /sys interface 51 48 --------------
+42 -58
drivers/i2c/chips/pcf8575.c
··· 32 32 #include <linux/slab.h> /* kzalloc() */ 33 33 #include <linux/sysfs.h> /* sysfs_create_group() */ 34 34 35 - /* Addresses to scan */ 36 - static const unsigned short normal_i2c[] = { 37 - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 38 - I2C_CLIENT_END 39 - }; 35 + /* Addresses to scan: none, device can't be detected */ 36 + static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; 40 37 41 38 /* Insmod parameters */ 42 39 I2C_CLIENT_INSMOD; ··· 41 44 42 45 /* Each client has this additional data */ 43 46 struct pcf8575_data { 44 - struct i2c_client client; 45 47 int write; /* last written value, or error code */ 46 - }; 47 - 48 - static int pcf8575_attach_adapter(struct i2c_adapter *adapter); 49 - static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind); 50 - static int pcf8575_detach_client(struct i2c_client *client); 51 - 52 - /* This is the driver that will be inserted */ 53 - static struct i2c_driver pcf8575_driver = { 54 - .driver = { 55 - .owner = THIS_MODULE, 56 - .name = "pcf8575", 57 - }, 58 - .attach_adapter = pcf8575_attach_adapter, 59 - .detach_client = pcf8575_detach_client, 60 48 }; 61 49 62 50 /* following are the sysfs callback functions */ ··· 108 126 * Real code 109 127 */ 110 128 111 - static int pcf8575_attach_adapter(struct i2c_adapter *adapter) 129 + /* Return 0 if detection is successful, -ENODEV otherwise */ 130 + static int pcf8575_detect(struct i2c_client *client, int kind, 131 + struct i2c_board_info *info) 112 132 { 113 - return i2c_probe(adapter, &addr_data, pcf8575_detect); 114 - } 115 - 116 - /* This function is called by i2c_probe */ 117 - static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind) 118 - { 119 - struct i2c_client *client; 120 - struct pcf8575_data *data; 121 - int err = 0; 133 + struct i2c_adapter *adapter = client->adapter; 122 134 123 135 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 124 - goto exit; 136 + return -ENODEV; 125 137 126 - /* OK. For now, we presume we have a valid client. We now create the 127 - client structure, even though we cannot fill it completely yet. */ 138 + /* This is the place to detect whether the chip at the specified 139 + address really is a PCF8575 chip. However, there is no method known 140 + to detect whether an I2C chip is a PCF8575 or any other I2C chip. */ 141 + 142 + strlcpy(info->type, "pcf8575", I2C_NAME_SIZE); 143 + 144 + return 0; 145 + } 146 + 147 + static int pcf8575_probe(struct i2c_client *client, 148 + const struct i2c_device_id *id) 149 + { 150 + struct pcf8575_data *data; 151 + int err; 152 + 128 153 data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL); 129 154 if (!data) { 130 155 err = -ENOMEM; 131 156 goto exit; 132 157 } 133 158 134 - client = &data->client; 135 159 i2c_set_clientdata(client, data); 136 - client->addr = address; 137 - client->adapter = adapter; 138 - client->driver = &pcf8575_driver; 139 - strlcpy(client->name, "pcf8575", I2C_NAME_SIZE); 140 160 data->write = -EAGAIN; 141 - 142 - /* This is the place to detect whether the chip at the specified 143 - address really is a PCF8575 chip. However, there is no method known 144 - to detect whether an I2C chip is a PCF8575 or any other I2C chip. */ 145 - 146 - /* Tell the I2C layer a new client has arrived */ 147 - err = i2c_attach_client(client); 148 - if (err) 149 - goto exit_free; 150 161 151 162 /* Register sysfs hooks */ 152 163 err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group); 153 164 if (err) 154 - goto exit_detach; 165 + goto exit_free; 155 166 156 167 return 0; 157 168 158 - exit_detach: 159 - i2c_detach_client(client); 160 169 exit_free: 161 170 kfree(data); 162 171 exit: 163 172 return err; 164 173 } 165 174 166 - static int pcf8575_detach_client(struct i2c_client *client) 175 + static int pcf8575_remove(struct i2c_client *client) 167 176 { 168 - int err; 169 - 170 177 sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group); 171 - 172 - err = i2c_detach_client(client); 173 - if (err) 174 - return err; 175 - 176 178 kfree(i2c_get_clientdata(client)); 177 179 return 0; 178 180 } 181 + 182 + static const struct i2c_device_id pcf8575_id[] = { 183 + { "pcf8575", 0 }, 184 + { } 185 + }; 186 + 187 + static struct i2c_driver pcf8575_driver = { 188 + .driver = { 189 + .owner = THIS_MODULE, 190 + .name = "pcf8575", 191 + }, 192 + .probe = pcf8575_probe, 193 + .remove = pcf8575_remove, 194 + .id_table = pcf8575_id, 195 + 196 + .detect = pcf8575_detect, 197 + .address_data = &addr_data, 198 + }; 179 199 180 200 static int __init pcf8575_init(void) 181 201 {