aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/pcf8591.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:06 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:06 -0400
commit8b77e6ac4911a79993e583ece719736a9e035b1d (patch)
tree91019e9effc2ceb173c08c00ed5698057beb4ccf /drivers/i2c/chips/pcf8591.c
parent68be3363740e4ac3b4309faebcdf8fe5bf62ed2f (diff)
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>
Diffstat (limited to 'drivers/i2c/chips/pcf8591.c')
-rw-r--r--drivers/i2c/chips/pcf8591.c94
1 files changed, 40 insertions, 54 deletions
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index db735379f22f..16ce3e193776 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -72,28 +72,15 @@ MODULE_PARM_DESC(input_mode,
72#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg)) 72#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg))
73 73
74struct pcf8591_data { 74struct pcf8591_data {
75 struct i2c_client client;
76 struct mutex update_lock; 75 struct mutex update_lock;
77 76
78 u8 control; 77 u8 control;
79 u8 aout; 78 u8 aout;
80}; 79};
81 80
82static int pcf8591_attach_adapter(struct i2c_adapter *adapter);
83static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind);
84static int pcf8591_detach_client(struct i2c_client *client);
85static void pcf8591_init_client(struct i2c_client *client); 81static void pcf8591_init_client(struct i2c_client *client);
86static int pcf8591_read_channel(struct device *dev, int channel); 82static int pcf8591_read_channel(struct device *dev, int channel);
87 83
88/* This is the driver that will be inserted */
89static 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
97/* following are the sysfs callback functions */ 84/* following are the sysfs callback functions */
98#define show_in_channel(channel) \ 85#define show_in_channel(channel) \
99static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \ 86static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \
@@ -180,58 +167,46 @@ static const struct attribute_group pcf8591_attr_group_opt = {
180/* 167/*
181 * Real code 168 * Real code
182 */ 169 */
183static int pcf8591_attach_adapter(struct i2c_adapter *adapter)
184{
185 return i2c_probe(adapter, &addr_data, pcf8591_detect);
186}
187 170
188/* This function is called by i2c_probe */ 171/* Return 0 if detection is successful, -ENODEV otherwise */
189static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) 172static int pcf8591_detect(struct i2c_client *client, int kind,
173 struct i2c_board_info *info)
190{ 174{
191 struct i2c_client *client; 175 struct i2c_adapter *adapter = client->adapter;
192 struct pcf8591_data *data;
193 int err = 0;
194 176
195 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE 177 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
196 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 178 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
197 goto exit; 179 return -ENODEV;
180
181 /* Now, we would do the remaining detection. But the PCF8591 is plainly
182 impossible to detect! Stupid chip. */
183
184 strlcpy(info->type, "pcf8591", I2C_NAME_SIZE);
185
186 return 0;
187}
188
189static int pcf8591_probe(struct i2c_client *client,
190 const struct i2c_device_id *id)
191{
192 struct pcf8591_data *data;
193 int err;
198 194
199 /* OK. For now, we presume we have a valid client. We now create the
200 client structure, even though we cannot fill it completely yet. */
201 if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { 195 if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
202 err = -ENOMEM; 196 err = -ENOMEM;
203 goto exit; 197 goto exit;
204 } 198 }
205 199
206 client = &data->client;
207 i2c_set_clientdata(client, data); 200 i2c_set_clientdata(client, data);
208 client->addr = address;
209 client->adapter = adapter;
210 client->driver = &pcf8591_driver;
211
212 /* Now, we would do the remaining detection. But the PCF8591 is plainly
213 impossible to detect! Stupid chip. */
214
215 /* Determine the chip type - only one kind supported! */
216 if (kind <= 0)
217 kind = pcf8591;
218
219 /* Fill in the remaining client fields and put it into the global
220 list */
221 strlcpy(client->name, "pcf8591", I2C_NAME_SIZE);
222 mutex_init(&data->update_lock); 201 mutex_init(&data->update_lock);
223 202
224 /* Tell the I2C layer a new client has arrived */
225 if ((err = i2c_attach_client(client)))
226 goto exit_kfree;
227
228 /* Initialize the PCF8591 chip */ 203 /* Initialize the PCF8591 chip */
229 pcf8591_init_client(client); 204 pcf8591_init_client(client);
230 205
231 /* Register sysfs hooks */ 206 /* Register sysfs hooks */
232 err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group); 207 err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);
233 if (err) 208 if (err)
234 goto exit_detach; 209 goto exit_kfree;
235 210
236 /* Register input2 if not in "two differential inputs" mode */ 211 /* Register input2 if not in "two differential inputs" mode */
237 if (input_mode != 3) { 212 if (input_mode != 3) {
@@ -252,24 +227,16 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
252exit_sysfs_remove: 227exit_sysfs_remove:
253 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); 228 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
254 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); 229 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
255exit_detach:
256 i2c_detach_client(client);
257exit_kfree: 230exit_kfree:
258 kfree(data); 231 kfree(data);
259exit: 232exit:
260 return err; 233 return err;
261} 234}
262 235
263static int pcf8591_detach_client(struct i2c_client *client) 236static int pcf8591_remove(struct i2c_client *client)
264{ 237{
265 int err;
266
267 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); 238 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
268 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); 239 sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
269
270 if ((err = i2c_detach_client(client)))
271 return err;
272
273 kfree(i2c_get_clientdata(client)); 240 kfree(i2c_get_clientdata(client));
274 return 0; 241 return 0;
275} 242}
@@ -316,6 +283,25 @@ static int pcf8591_read_channel(struct device *dev, int channel)
316 return (10 * value); 283 return (10 * value);
317} 284}
318 285
286static const struct i2c_device_id pcf8591_id[] = {
287 { "pcf8591", 0 },
288 { }
289};
290MODULE_DEVICE_TABLE(i2c, pcf8591_id);
291
292static struct i2c_driver pcf8591_driver = {
293 .driver = {
294 .name = "pcf8591",
295 },
296 .probe = pcf8591_probe,
297 .remove = pcf8591_remove,
298 .id_table = pcf8591_id,
299
300 .class = I2C_CLASS_HWMON, /* Nearest choice */
301 .detect = pcf8591_detect,
302 .address_data = &addr_data,
303};
304
319static int __init pcf8591_init(void) 305static int __init pcf8591_init(void)
320{ 306{
321 if (input_mode < 0 || input_mode > 3) { 307 if (input_mode < 0 || input_mode > 3) {