diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:18 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:18 -0400 |
commit | dc18a4184d6794e2e5c6f05142f3f8aaeeaee506 (patch) | |
tree | 9acb7cf17714a1185cb3e673cf683c3172a9e7c9 /drivers | |
parent | a7f13a6ec40379fe2116c647ac8e569227ba8d4f (diff) |
hwmon: (w83l785ts) Convert to a new-style i2c driver
The new-style w83l785ts 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')
-rw-r--r-- | drivers/hwmon/w83l785ts.c | 117 |
1 files changed, 60 insertions, 57 deletions
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 52e268e25dab..ea295b9fc4f4 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c | |||
@@ -81,10 +81,11 @@ I2C_CLIENT_INSMOD_1(w83l785ts); | |||
81 | * Functions declaration | 81 | * Functions declaration |
82 | */ | 82 | */ |
83 | 83 | ||
84 | static int w83l785ts_attach_adapter(struct i2c_adapter *adapter); | 84 | static int w83l785ts_probe(struct i2c_client *client, |
85 | static int w83l785ts_detect(struct i2c_adapter *adapter, int address, | 85 | const struct i2c_device_id *id); |
86 | int kind); | 86 | static int w83l785ts_detect(struct i2c_client *client, int kind, |
87 | static int w83l785ts_detach_client(struct i2c_client *client); | 87 | struct i2c_board_info *info); |
88 | static int w83l785ts_remove(struct i2c_client *client); | ||
88 | static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval); | 89 | static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval); |
89 | static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); | 90 | static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); |
90 | 91 | ||
@@ -92,12 +93,22 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); | |||
92 | * Driver data (common to all clients) | 93 | * Driver data (common to all clients) |
93 | */ | 94 | */ |
94 | 95 | ||
96 | static const struct i2c_device_id w83l785ts_id[] = { | ||
97 | { "w83l785ts", w83l785ts }, | ||
98 | { } | ||
99 | }; | ||
100 | MODULE_DEVICE_TABLE(i2c, w83l785ts_id); | ||
101 | |||
95 | static struct i2c_driver w83l785ts_driver = { | 102 | static struct i2c_driver w83l785ts_driver = { |
103 | .class = I2C_CLASS_HWMON, | ||
96 | .driver = { | 104 | .driver = { |
97 | .name = "w83l785ts", | 105 | .name = "w83l785ts", |
98 | }, | 106 | }, |
99 | .attach_adapter = w83l785ts_attach_adapter, | 107 | .probe = w83l785ts_probe, |
100 | .detach_client = w83l785ts_detach_client, | 108 | .remove = w83l785ts_remove, |
109 | .id_table = w83l785ts_id, | ||
110 | .detect = w83l785ts_detect, | ||
111 | .address_data = &addr_data, | ||
101 | }; | 112 | }; |
102 | 113 | ||
103 | /* | 114 | /* |
@@ -105,7 +116,6 @@ static struct i2c_driver w83l785ts_driver = { | |||
105 | */ | 116 | */ |
106 | 117 | ||
107 | struct w83l785ts_data { | 118 | struct w83l785ts_data { |
108 | struct i2c_client client; | ||
109 | struct device *hwmon_dev; | 119 | struct device *hwmon_dev; |
110 | struct mutex update_lock; | 120 | struct mutex update_lock; |
111 | char valid; /* zero until following fields are valid */ | 121 | char valid; /* zero until following fields are valid */ |
@@ -135,40 +145,14 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1); | |||
135 | * Real code | 145 | * Real code |
136 | */ | 146 | */ |
137 | 147 | ||
138 | static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) | 148 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
139 | { | 149 | static int w83l785ts_detect(struct i2c_client *new_client, int kind, |
140 | if (!(adapter->class & I2C_CLASS_HWMON)) | 150 | struct i2c_board_info *info) |
141 | return 0; | ||
142 | return i2c_probe(adapter, &addr_data, w83l785ts_detect); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * The following function does more than just detection. If detection | ||
147 | * succeeds, it also registers the new chip. | ||
148 | */ | ||
149 | static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) | ||
150 | { | 151 | { |
151 | struct i2c_client *new_client; | 152 | struct i2c_adapter *adapter = new_client->adapter; |
152 | struct w83l785ts_data *data; | ||
153 | int err = 0; | ||
154 | |||
155 | 153 | ||
156 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 154 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
157 | goto exit; | 155 | return -ENODEV; |
158 | |||
159 | if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) { | ||
160 | err = -ENOMEM; | ||
161 | goto exit; | ||
162 | } | ||
163 | |||
164 | /* The common I2C client data is placed right before the | ||
165 | * W83L785TS-specific data. */ | ||
166 | new_client = &data->client; | ||
167 | i2c_set_clientdata(new_client, data); | ||
168 | new_client->addr = address; | ||
169 | new_client->adapter = adapter; | ||
170 | new_client->driver = &w83l785ts_driver; | ||
171 | new_client->flags = 0; | ||
172 | 156 | ||
173 | /* | 157 | /* |
174 | * Now we do the remaining detection. A negative kind means that | 158 | * Now we do the remaining detection. A negative kind means that |
@@ -188,8 +172,8 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) | |||
188 | W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) { | 172 | W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) { |
189 | dev_dbg(&adapter->dev, | 173 | dev_dbg(&adapter->dev, |
190 | "W83L785TS-S detection failed at 0x%02x.\n", | 174 | "W83L785TS-S detection failed at 0x%02x.\n", |
191 | address); | 175 | new_client->addr); |
192 | goto exit_free; | 176 | return -ENODEV; |
193 | } | 177 | } |
194 | } | 178 | } |
195 | 179 | ||
@@ -214,22 +198,34 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) | |||
214 | dev_info(&adapter->dev, | 198 | dev_info(&adapter->dev, |
215 | "Unsupported chip (man_id=0x%04X, " | 199 | "Unsupported chip (man_id=0x%04X, " |
216 | "chip_id=0x%02X).\n", man_id, chip_id); | 200 | "chip_id=0x%02X).\n", man_id, chip_id); |
217 | goto exit_free; | 201 | return -ENODEV; |
218 | } | 202 | } |
219 | } | 203 | } |
220 | 204 | ||
221 | /* We can fill in the remaining client fields. */ | 205 | strlcpy(info->type, "w83l785ts", I2C_NAME_SIZE); |
222 | strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE); | 206 | |
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int w83l785ts_probe(struct i2c_client *new_client, | ||
211 | const struct i2c_device_id *id) | ||
212 | { | ||
213 | struct w83l785ts_data *data; | ||
214 | int err = 0; | ||
215 | |||
216 | data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL); | ||
217 | if (!data) { | ||
218 | err = -ENOMEM; | ||
219 | goto exit; | ||
220 | } | ||
221 | |||
222 | i2c_set_clientdata(new_client, data); | ||
223 | data->valid = 0; | 223 | data->valid = 0; |
224 | mutex_init(&data->update_lock); | 224 | mutex_init(&data->update_lock); |
225 | 225 | ||
226 | /* Default values in case the first read fails (unlikely). */ | 226 | /* Default values in case the first read fails (unlikely). */ |
227 | data->temp[1] = data->temp[0] = 0; | 227 | data->temp[1] = data->temp[0] = 0; |
228 | 228 | ||
229 | /* Tell the I2C layer a new client has arrived. */ | ||
230 | if ((err = i2c_attach_client(new_client))) | ||
231 | goto exit_free; | ||
232 | |||
233 | /* | 229 | /* |
234 | * Initialize the W83L785TS chip | 230 | * Initialize the W83L785TS chip |
235 | * Nothing yet, assume it is already started. | 231 | * Nothing yet, assume it is already started. |
@@ -259,25 +255,20 @@ exit_remove: | |||
259 | &sensor_dev_attr_temp1_input.dev_attr); | 255 | &sensor_dev_attr_temp1_input.dev_attr); |
260 | device_remove_file(&new_client->dev, | 256 | device_remove_file(&new_client->dev, |
261 | &sensor_dev_attr_temp1_max.dev_attr); | 257 | &sensor_dev_attr_temp1_max.dev_attr); |
262 | i2c_detach_client(new_client); | ||
263 | exit_free: | ||
264 | kfree(data); | 258 | kfree(data); |
265 | exit: | 259 | exit: |
266 | return err; | 260 | return err; |
267 | } | 261 | } |
268 | 262 | ||
269 | static int w83l785ts_detach_client(struct i2c_client *client) | 263 | static int w83l785ts_remove(struct i2c_client *client) |
270 | { | 264 | { |
271 | struct w83l785ts_data *data = i2c_get_clientdata(client); | 265 | struct w83l785ts_data *data = i2c_get_clientdata(client); |
272 | int err; | ||
273 | 266 | ||
274 | hwmon_device_unregister(data->hwmon_dev); | 267 | hwmon_device_unregister(data->hwmon_dev); |
275 | device_remove_file(&client->dev, | 268 | device_remove_file(&client->dev, |
276 | &sensor_dev_attr_temp1_input.dev_attr); | 269 | &sensor_dev_attr_temp1_input.dev_attr); |
277 | device_remove_file(&client->dev, | 270 | device_remove_file(&client->dev, |
278 | &sensor_dev_attr_temp1_max.dev_attr); | 271 | &sensor_dev_attr_temp1_max.dev_attr); |
279 | if ((err = i2c_detach_client(client))) | ||
280 | return err; | ||
281 | 272 | ||
282 | kfree(data); | 273 | kfree(data); |
283 | return 0; | 274 | return 0; |
@@ -286,6 +277,18 @@ static int w83l785ts_detach_client(struct i2c_client *client) | |||
286 | static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) | 277 | static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) |
287 | { | 278 | { |
288 | int value, i; | 279 | int value, i; |
280 | struct device *dev; | ||
281 | const char *prefix; | ||
282 | |||
283 | /* We might be called during detection, at which point the client | ||
284 | isn't yet fully initialized, so we can't use dev_dbg on it */ | ||
285 | if (i2c_get_clientdata(client)) { | ||
286 | dev = &client->dev; | ||
287 | prefix = ""; | ||
288 | } else { | ||
289 | dev = &client->adapter->dev; | ||
290 | prefix = "w83l785ts: "; | ||
291 | } | ||
289 | 292 | ||
290 | /* Frequent read errors have been reported on Asus boards, so we | 293 | /* Frequent read errors have been reported on Asus boards, so we |
291 | * retry on read errors. If it still fails (unlikely), return the | 294 | * retry on read errors. If it still fails (unlikely), return the |
@@ -293,15 +296,15 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) | |||
293 | for (i = 1; i <= MAX_RETRIES; i++) { | 296 | for (i = 1; i <= MAX_RETRIES; i++) { |
294 | value = i2c_smbus_read_byte_data(client, reg); | 297 | value = i2c_smbus_read_byte_data(client, reg); |
295 | if (value >= 0) { | 298 | if (value >= 0) { |
296 | dev_dbg(&client->dev, "Read 0x%02x from register " | 299 | dev_dbg(dev, "%sRead 0x%02x from register 0x%02x.\n", |
297 | "0x%02x.\n", value, reg); | 300 | prefix, value, reg); |
298 | return value; | 301 | return value; |
299 | } | 302 | } |
300 | dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i); | 303 | dev_dbg(dev, "%sRead failed, will retry in %d.\n", prefix, i); |
301 | msleep(i); | 304 | msleep(i); |
302 | } | 305 | } |
303 | 306 | ||
304 | dev_err(&client->dev, "Couldn't read value from register 0x%02x.\n", | 307 | dev_err(dev, "%sCouldn't read value from register 0x%02x.\n", prefix, |
305 | reg); | 308 | reg); |
306 | return defval; | 309 | return defval; |
307 | } | 310 | } |