diff options
| author | Jean Delvare <khali@linux-fr.org> | 2008-10-14 11:30:04 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-14 11:30:04 -0400 |
| commit | 67a37308ae37f8948d3c26f75a18f0ddb77ac198 (patch) | |
| tree | 04c7145e4494f21725741e4a284e560731ffe091 | |
| parent | dbc2bc251e06c83efcc8d39f1e7de12c2b1ff591 (diff) | |
hwmon: (dme1737) Convert to a new-style i2c driver
The new-style dme1737 driver implements the optional detect() callback
to cover the use cases of the legacy driver. I don't actually expect
any new-style device for that driver, but as the old i2c API is going
away soon, we have to switch to the new one.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Juerg Haefliger <juergh@gmail.com>
| -rw-r--r-- | drivers/hwmon/dme1737.c | 106 |
1 files changed, 48 insertions, 58 deletions
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 2bf97e1470c0..27a5d397f9a1 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
| @@ -176,7 +176,6 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
| 176 | * --------------------------------------------------------------------- */ | 176 | * --------------------------------------------------------------------- */ |
| 177 | 177 | ||
| 178 | struct dme1737_data { | 178 | struct dme1737_data { |
| 179 | struct i2c_client _client; /* will go away soon */ | ||
| 180 | struct i2c_client *client; /* for I2C devices only */ | 179 | struct i2c_client *client; /* for I2C devices only */ |
| 181 | struct device *hwmon_dev; | 180 | struct device *hwmon_dev; |
| 182 | const char *name; | 181 | const char *name; |
| @@ -2188,38 +2187,24 @@ exit: | |||
| 2188 | return err; | 2187 | return err; |
| 2189 | } | 2188 | } |
| 2190 | 2189 | ||
| 2191 | static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | 2190 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 2192 | int kind) | 2191 | static int dme1737_i2c_detect(struct i2c_client *client, int kind, |
| 2192 | struct i2c_board_info *info) | ||
| 2193 | { | 2193 | { |
| 2194 | struct i2c_adapter *adapter = client->adapter; | ||
| 2195 | struct device *dev = &adapter->dev; | ||
| 2194 | u8 company, verstep = 0; | 2196 | u8 company, verstep = 0; |
| 2195 | struct i2c_client *client; | ||
| 2196 | struct dme1737_data *data; | ||
| 2197 | struct device *dev; | ||
| 2198 | int err = 0; | ||
| 2199 | const char *name; | 2197 | const char *name; |
| 2200 | 2198 | ||
| 2201 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 2199 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
| 2202 | goto exit; | 2200 | return -ENODEV; |
| 2203 | } | ||
| 2204 | |||
| 2205 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | ||
| 2206 | err = -ENOMEM; | ||
| 2207 | goto exit; | ||
| 2208 | } | 2201 | } |
| 2209 | 2202 | ||
| 2210 | client = &data->_client; | ||
| 2211 | data->client = client; | ||
| 2212 | i2c_set_clientdata(client, data); | ||
| 2213 | client->addr = address; | ||
| 2214 | client->adapter = adapter; | ||
| 2215 | client->driver = &dme1737_i2c_driver; | ||
| 2216 | dev = &client->dev; | ||
| 2217 | |||
| 2218 | /* A negative kind means that the driver was loaded with no force | 2203 | /* A negative kind means that the driver was loaded with no force |
| 2219 | * parameter (default), so we must identify the chip. */ | 2204 | * parameter (default), so we must identify the chip. */ |
| 2220 | if (kind < 0) { | 2205 | if (kind < 0) { |
| 2221 | company = dme1737_read(data, DME1737_REG_COMPANY); | 2206 | company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY); |
| 2222 | verstep = dme1737_read(data, DME1737_REG_VERSTEP); | 2207 | verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP); |
| 2223 | 2208 | ||
| 2224 | if (company == DME1737_COMPANY_SMSC && | 2209 | if (company == DME1737_COMPANY_SMSC && |
| 2225 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { | 2210 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
| @@ -2228,8 +2213,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
| 2228 | verstep == SCH5027_VERSTEP) { | 2213 | verstep == SCH5027_VERSTEP) { |
| 2229 | kind = sch5027; | 2214 | kind = sch5027; |
| 2230 | } else { | 2215 | } else { |
| 2231 | err = -ENODEV; | 2216 | return -ENODEV; |
| 2232 | goto exit_kfree; | ||
| 2233 | } | 2217 | } |
| 2234 | } | 2218 | } |
| 2235 | 2219 | ||
| @@ -2239,33 +2223,44 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
| 2239 | kind = dme1737; | 2223 | kind = dme1737; |
| 2240 | name = "dme1737"; | 2224 | name = "dme1737"; |
| 2241 | } | 2225 | } |
| 2242 | data->type = kind; | ||
| 2243 | |||
| 2244 | /* Fill in the remaining client fields and put it into the global | ||
| 2245 | * list */ | ||
| 2246 | strlcpy(client->name, name, I2C_NAME_SIZE); | ||
| 2247 | data->name = client->name; | ||
| 2248 | mutex_init(&data->update_lock); | ||
| 2249 | |||
| 2250 | /* Tell the I2C layer a new client has arrived */ | ||
| 2251 | if ((err = i2c_attach_client(client))) { | ||
| 2252 | goto exit_kfree; | ||
| 2253 | } | ||
| 2254 | 2226 | ||
| 2255 | dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", | 2227 | dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", |
| 2256 | kind == sch5027 ? "SCH5027" : "DME1737", client->addr, | 2228 | kind == sch5027 ? "SCH5027" : "DME1737", client->addr, |
| 2257 | verstep); | 2229 | verstep); |
| 2230 | strlcpy(info->type, name, I2C_NAME_SIZE); | ||
| 2231 | |||
| 2232 | return 0; | ||
| 2233 | } | ||
| 2234 | |||
| 2235 | static int dme1737_i2c_probe(struct i2c_client *client, | ||
| 2236 | const struct i2c_device_id *id) | ||
| 2237 | { | ||
| 2238 | struct dme1737_data *data; | ||
| 2239 | struct device *dev = &client->dev; | ||
| 2240 | int err; | ||
| 2241 | |||
| 2242 | data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); | ||
| 2243 | if (!data) { | ||
| 2244 | err = -ENOMEM; | ||
| 2245 | goto exit; | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | i2c_set_clientdata(client, data); | ||
| 2249 | data->type = id->driver_data; | ||
| 2250 | data->client = client; | ||
| 2251 | data->name = client->name; | ||
| 2252 | mutex_init(&data->update_lock); | ||
| 2258 | 2253 | ||
| 2259 | /* Initialize the DME1737 chip */ | 2254 | /* Initialize the DME1737 chip */ |
| 2260 | if ((err = dme1737_init_device(dev))) { | 2255 | if ((err = dme1737_init_device(dev))) { |
| 2261 | dev_err(dev, "Failed to initialize device.\n"); | 2256 | dev_err(dev, "Failed to initialize device.\n"); |
| 2262 | goto exit_detach; | 2257 | goto exit_kfree; |
| 2263 | } | 2258 | } |
| 2264 | 2259 | ||
| 2265 | /* Create sysfs files */ | 2260 | /* Create sysfs files */ |
| 2266 | if ((err = dme1737_create_files(dev))) { | 2261 | if ((err = dme1737_create_files(dev))) { |
| 2267 | dev_err(dev, "Failed to create sysfs files.\n"); | 2262 | dev_err(dev, "Failed to create sysfs files.\n"); |
| 2268 | goto exit_detach; | 2263 | goto exit_kfree; |
| 2269 | } | 2264 | } |
| 2270 | 2265 | ||
| 2271 | /* Register device */ | 2266 | /* Register device */ |
| @@ -2280,45 +2275,40 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
| 2280 | 2275 | ||
| 2281 | exit_remove: | 2276 | exit_remove: |
| 2282 | dme1737_remove_files(dev); | 2277 | dme1737_remove_files(dev); |
| 2283 | exit_detach: | ||
| 2284 | i2c_detach_client(client); | ||
| 2285 | exit_kfree: | 2278 | exit_kfree: |
| 2286 | kfree(data); | 2279 | kfree(data); |
| 2287 | exit: | 2280 | exit: |
| 2288 | return err; | 2281 | return err; |
| 2289 | } | 2282 | } |
| 2290 | 2283 | ||
| 2291 | static int dme1737_i2c_attach_adapter(struct i2c_adapter *adapter) | 2284 | static int dme1737_i2c_remove(struct i2c_client *client) |
| 2292 | { | ||
| 2293 | if (!(adapter->class & I2C_CLASS_HWMON)) { | ||
| 2294 | return 0; | ||
| 2295 | } | ||
| 2296 | |||
| 2297 | return i2c_probe(adapter, &addr_data, dme1737_i2c_detect); | ||
| 2298 | } | ||
| 2299 | |||
| 2300 | static int dme1737_i2c_detach_client(struct i2c_client *client) | ||
| 2301 | { | 2285 | { |
| 2302 | struct dme1737_data *data = i2c_get_clientdata(client); | 2286 | struct dme1737_data *data = i2c_get_clientdata(client); |
| 2303 | int err; | ||
| 2304 | 2287 | ||
| 2305 | hwmon_device_unregister(data->hwmon_dev); | 2288 | hwmon_device_unregister(data->hwmon_dev); |
| 2306 | dme1737_remove_files(&client->dev); | 2289 | dme1737_remove_files(&client->dev); |
| 2307 | 2290 | ||
| 2308 | if ((err = i2c_detach_client(client))) { | ||
| 2309 | return err; | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | kfree(data); | 2291 | kfree(data); |
| 2313 | return 0; | 2292 | return 0; |
| 2314 | } | 2293 | } |
| 2315 | 2294 | ||
| 2295 | static const struct i2c_device_id dme1737_id[] = { | ||
| 2296 | { "dme1737", dme1737 }, | ||
| 2297 | { "sch5027", sch5027 }, | ||
| 2298 | { } | ||
| 2299 | }; | ||
| 2300 | MODULE_DEVICE_TABLE(i2c, dme1737_id); | ||
| 2301 | |||
| 2316 | static struct i2c_driver dme1737_i2c_driver = { | 2302 | static struct i2c_driver dme1737_i2c_driver = { |
| 2303 | .class = I2C_CLASS_HWMON, | ||
| 2317 | .driver = { | 2304 | .driver = { |
| 2318 | .name = "dme1737", | 2305 | .name = "dme1737", |
| 2319 | }, | 2306 | }, |
| 2320 | .attach_adapter = dme1737_i2c_attach_adapter, | 2307 | .probe = dme1737_i2c_probe, |
| 2321 | .detach_client = dme1737_i2c_detach_client, | 2308 | .remove = dme1737_i2c_remove, |
| 2309 | .id_table = dme1737_id, | ||
| 2310 | .detect = dme1737_i2c_detect, | ||
| 2311 | .address_data = &addr_data, | ||
| 2322 | }; | 2312 | }; |
| 2323 | 2313 | ||
| 2324 | /* --------------------------------------------------------------------- | 2314 | /* --------------------------------------------------------------------- |
