aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:07 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:07 -0400
commit3d63430a26b91fe3daee0dd933f899c225e66daa (patch)
tree88b10cf9d53c2c84f13eb60db0e6304ad8eff6da
parent97addff6def3f8e228a634fa017589f45c69de5c (diff)
i2c: Convert the pca9539 driver to a new-style i2c driver
The new-style pca9539 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/pca953x. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--Documentation/i2c/chips/pca953910
-rw-r--r--drivers/i2c/chips/pca9539.c109
2 files changed, 42 insertions, 77 deletions
diff --git a/Documentation/i2c/chips/pca9539 b/Documentation/i2c/chips/pca9539
index 1d81c530c4a5..6aff890088b1 100644
--- a/Documentation/i2c/chips/pca9539
+++ b/Documentation/i2c/chips/pca9539
@@ -7,7 +7,7 @@ drivers/gpio/pca9539.c instead.
7Supported chips: 7Supported chips:
8 * Philips PCA9539 8 * Philips PCA9539
9 Prefix: 'pca9539' 9 Prefix: 'pca9539'
10 Addresses scanned: 0x74 - 0x77 10 Addresses scanned: none
11 Datasheet: 11 Datasheet:
12 http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf 12 http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
13 13
@@ -23,6 +23,14 @@ The input sense can also be inverted.
23The 16 lines are split between two bytes. 23The 16 lines are split between two bytes.
24 24
25 25
26Detection
27---------
28
29The PCA9539 is difficult to detect and not commonly found in PC machines,
30so you have to pass the I2C bus and address of the installed PCA9539
31devices explicitly to the driver at load time via the force=... parameter.
32
33
26Sysfs entries 34Sysfs entries
27------------- 35-------------
28 36
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
index 58ab7f26be26..270de4e56a81 100644
--- a/drivers/i2c/chips/pca9539.c
+++ b/drivers/i2c/chips/pca9539.c
@@ -14,8 +14,8 @@
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/hwmon-sysfs.h> 15#include <linux/hwmon-sysfs.h>
16 16
17/* Addresses to scan */ 17/* Addresses to scan: none, device is not autodetected */
18static unsigned short normal_i2c[] = {0x74, 0x75, 0x76, 0x77, I2C_CLIENT_END}; 18static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
19 19
20/* Insmod parameters */ 20/* Insmod parameters */
21I2C_CLIENT_INSMOD_1(pca9539); 21I2C_CLIENT_INSMOD_1(pca9539);
@@ -32,23 +32,6 @@ enum pca9539_cmd
32 PCA9539_DIRECTION_1 = 7, 32 PCA9539_DIRECTION_1 = 7,
33}; 33};
34 34
35static int pca9539_attach_adapter(struct i2c_adapter *adapter);
36static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind);
37static int pca9539_detach_client(struct i2c_client *client);
38
39/* This is the driver that will be inserted */
40static struct i2c_driver pca9539_driver = {
41 .driver = {
42 .name = "pca9539",
43 },
44 .attach_adapter = pca9539_attach_adapter,
45 .detach_client = pca9539_detach_client,
46};
47
48struct pca9539_data {
49 struct i2c_client client;
50};
51
52/* following are the sysfs callback functions */ 35/* following are the sysfs callback functions */
53static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr, 36static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr,
54 char *buf) 37 char *buf)
@@ -105,77 +88,51 @@ static struct attribute_group pca9539_defattr_group = {
105 .attrs = pca9539_attributes, 88 .attrs = pca9539_attributes,
106}; 89};
107 90
108static int pca9539_attach_adapter(struct i2c_adapter *adapter) 91/* Return 0 if detection is successful, -ENODEV otherwise */
92static int pca9539_detect(struct i2c_client *client, int kind,
93 struct i2c_board_info *info)
109{ 94{
110 return i2c_probe(adapter, &addr_data, pca9539_detect); 95 struct i2c_adapter *adapter = client->adapter;
111}
112
113/* This function is called by i2c_probe */
114static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
115{
116 struct i2c_client *client;
117 struct pca9539_data *data;
118 int err = 0;
119 96
120 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 97 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
121 goto exit; 98 return -ENODEV;
122
123 /* OK. For now, we presume we have a valid client. We now create the
124 client structure, even though we cannot fill it completely yet. */
125 if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
126 err = -ENOMEM;
127 goto exit;
128 }
129
130 client = &data->client;
131 i2c_set_clientdata(client, data);
132 client->addr = address;
133 client->adapter = adapter;
134 client->driver = &pca9539_driver;
135
136 if (kind < 0) {
137 /* Detection: the pca9539 only has 8 registers (0-7).
138 A read of 7 should succeed, but a read of 8 should fail. */
139 if ((i2c_smbus_read_byte_data(client, 7) < 0) ||
140 (i2c_smbus_read_byte_data(client, 8) >= 0))
141 goto exit_kfree;
142 }
143
144 strlcpy(client->name, "pca9539", I2C_NAME_SIZE);
145
146 /* Tell the I2C layer a new client has arrived */
147 if ((err = i2c_attach_client(client)))
148 goto exit_kfree;
149 99
150 /* Register sysfs hooks */ 100 strlcpy(info->type, "pca9539", I2C_NAME_SIZE);
151 err = sysfs_create_group(&client->dev.kobj,
152 &pca9539_defattr_group);
153 if (err)
154 goto exit_detach;
155 101
156 return 0; 102 return 0;
157
158exit_detach:
159 i2c_detach_client(client);
160exit_kfree:
161 kfree(data);
162exit:
163 return err;
164} 103}
165 104
166static int pca9539_detach_client(struct i2c_client *client) 105static int pca9539_probe(struct i2c_client *client,
106 const struct i2c_device_id *id)
167{ 107{
168 int err; 108 /* Register sysfs hooks */
109 return sysfs_create_group(&client->dev.kobj,
110 &pca9539_defattr_group);
111}
169 112
113static int pca9539_remove(struct i2c_client *client)
114{
170 sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group); 115 sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
171
172 if ((err = i2c_detach_client(client)))
173 return err;
174
175 kfree(i2c_get_clientdata(client));
176 return 0; 116 return 0;
177} 117}
178 118
119static const struct i2c_device_id pca9539_id[] = {
120 { "pca9539", 0 },
121 { }
122};
123
124static struct i2c_driver pca9539_driver = {
125 .driver = {
126 .name = "pca9539",
127 },
128 .probe = pca9539_probe,
129 .remove = pca9539_remove,
130 .id_table = pca9539_id,
131
132 .detect = pca9539_detect,
133 .address_data = &addr_data,
134};
135
179static int __init pca9539_init(void) 136static int __init pca9539_init(void)
180{ 137{
181 return i2c_add_driver(&pca9539_driver); 138 return i2c_add_driver(&pca9539_driver);