smsc47b397.c (fde0950903ce8cc38a91dd095280decceda2ff82) smsc47b397.c (2d8672c5a6ba0d3f1d8d3ad61ef67868941364f0)
1/*
2 smsc47b397.c - Part of lm_sensors, Linux kernel modules
3 for hardware monitoring
4
5 Supports the SMSC LPC47B397-NC Super-I/O chip.
6
7 Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
8 Copyright (C) 2004 Utilitek Systems, Inc.

--- 18 unchanged lines hidden (view full) ---

27*/
28
29#include <linux/module.h>
30#include <linux/slab.h>
31#include <linux/ioport.h>
32#include <linux/jiffies.h>
33#include <linux/i2c.h>
34#include <linux/i2c-isa.h>
1/*
2 smsc47b397.c - Part of lm_sensors, Linux kernel modules
3 for hardware monitoring
4
5 Supports the SMSC LPC47B397-NC Super-I/O chip.
6
7 Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
8 Copyright (C) 2004 Utilitek Systems, Inc.

--- 18 unchanged lines hidden (view full) ---

27*/
28
29#include <linux/module.h>
30#include <linux/slab.h>
31#include <linux/ioport.h>
32#include <linux/jiffies.h>
33#include <linux/i2c.h>
34#include <linux/i2c-isa.h>
35#include <linux/i2c-sensor.h>
36#include <linux/hwmon.h>
37#include <linux/err.h>
38#include <linux/init.h>
39#include <asm/io.h>
40
35#include <linux/hwmon.h>
36#include <linux/err.h>
37#include <linux/init.h>
38#include <asm/io.h>
39
41static unsigned short normal_i2c[] = { I2C_CLIENT_END };
42/* Address is autodetected, there is no default value */
40/* Address is autodetected, there is no default value */
43static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
44static struct i2c_force_data forces[] = {{NULL}};
41static unsigned short address;
45
42
46enum chips { any_chip, smsc47b397 };
47static struct i2c_address_data addr_data = {
48 .normal_i2c = normal_i2c,
49 .normal_isa = normal_isa,
50 .probe = normal_i2c, /* cheat */
51 .ignore = normal_i2c, /* cheat */
52 .forces = forces,
53};
54
55/* Super-I/0 registers and commands */
56
57#define REG 0x2e /* The register to read/write */
58#define VAL 0x2f /* The value to read/write */
59
60static inline void superio_outb(int reg, int val)
61{
62 outb(reg, REG);

--- 151 unchanged lines hidden (view full) ---

214sysfs_fan(1);
215sysfs_fan(2);
216sysfs_fan(3);
217sysfs_fan(4);
218
219#define device_create_file_fan(client, num) \
220 device_create_file(&client->dev, &dev_attr_fan##num##_input)
221
43/* Super-I/0 registers and commands */
44
45#define REG 0x2e /* The register to read/write */
46#define VAL 0x2f /* The value to read/write */
47
48static inline void superio_outb(int reg, int val)
49{
50 outb(reg, REG);

--- 151 unchanged lines hidden (view full) ---

202sysfs_fan(1);
203sysfs_fan(2);
204sysfs_fan(3);
205sysfs_fan(4);
206
207#define device_create_file_fan(client, num) \
208 device_create_file(&client->dev, &dev_attr_fan##num##_input)
209
222static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind);
223
224static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
225{
226 if (!(adapter->class & I2C_CLASS_HWMON))
227 return 0;
228 return i2c_detect(adapter, &addr_data, smsc47b397_detect);
229}
230
231static int smsc47b397_detach_client(struct i2c_client *client)
232{
233 struct smsc47b397_data *data = i2c_get_clientdata(client);
234 int err;
235
236 hwmon_device_unregister(data->class_dev);
237
238 if ((err = i2c_detach_client(client))) {
239 dev_err(&client->dev, "Client deregistration failed, "
240 "client not detached.\n");
241 return err;
242 }
243
244 release_region(client->addr, SMSC_EXTENT);
245 kfree(data);
246
247 return 0;
248}
249
210static int smsc47b397_detach_client(struct i2c_client *client)
211{
212 struct smsc47b397_data *data = i2c_get_clientdata(client);
213 int err;
214
215 hwmon_device_unregister(data->class_dev);
216
217 if ((err = i2c_detach_client(client))) {
218 dev_err(&client->dev, "Client deregistration failed, "
219 "client not detached.\n");
220 return err;
221 }
222
223 release_region(client->addr, SMSC_EXTENT);
224 kfree(data);
225
226 return 0;
227}
228
229static int smsc47b397_detect(struct i2c_adapter *adapter);
230
250static struct i2c_driver smsc47b397_driver = {
251 .owner = THIS_MODULE,
252 .name = "smsc47b397",
231static struct i2c_driver smsc47b397_driver = {
232 .owner = THIS_MODULE,
233 .name = "smsc47b397",
253 .id = I2C_DRIVERID_SMSC47B397,
254 .flags = I2C_DF_NOTIFY,
255 .attach_adapter = smsc47b397_attach_adapter,
234 .attach_adapter = smsc47b397_detect,
256 .detach_client = smsc47b397_detach_client,
257};
258
235 .detach_client = smsc47b397_detach_client,
236};
237
259static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
238static int smsc47b397_detect(struct i2c_adapter *adapter)
260{
261 struct i2c_client *new_client;
262 struct smsc47b397_data *data;
263 int err = 0;
264
239{
240 struct i2c_client *new_client;
241 struct smsc47b397_data *data;
242 int err = 0;
243
265 if (!i2c_is_isa_adapter(adapter)) {
266 return 0;
267 }
268
269 if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) {
270 dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr);
244 if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) {
245 dev_err(&adapter->dev, "Region 0x%x already in use!\n",
246 address);
271 return -EBUSY;
272 }
273
274 if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
275 err = -ENOMEM;
276 goto error_release;
277 }
278 memset(data, 0x00, sizeof(struct smsc47b397_data));
279
280 new_client = &data->client;
281 i2c_set_clientdata(new_client, data);
247 return -EBUSY;
248 }
249
250 if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
251 err = -ENOMEM;
252 goto error_release;
253 }
254 memset(data, 0x00, sizeof(struct smsc47b397_data));
255
256 new_client = &data->client;
257 i2c_set_clientdata(new_client, data);
282 new_client->addr = addr;
258 new_client->addr = address;
283 init_MUTEX(&data->lock);
284 new_client->adapter = adapter;
285 new_client->driver = &smsc47b397_driver;
286 new_client->flags = 0;
287
288 strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
289
290 init_MUTEX(&data->update_lock);

--- 19 unchanged lines hidden (view full) ---

310
311 return 0;
312
313error_detach:
314 i2c_detach_client(new_client);
315error_free:
316 kfree(data);
317error_release:
259 init_MUTEX(&data->lock);
260 new_client->adapter = adapter;
261 new_client->driver = &smsc47b397_driver;
262 new_client->flags = 0;
263
264 strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
265
266 init_MUTEX(&data->update_lock);

--- 19 unchanged lines hidden (view full) ---

286
287 return 0;
288
289error_detach:
290 i2c_detach_client(new_client);
291error_free:
292 kfree(data);
293error_release:
318 release_region(addr, SMSC_EXTENT);
294 release_region(address, SMSC_EXTENT);
319 return err;
320}
321
295 return err;
296}
297
322static int __init smsc47b397_find(unsigned int *addr)
298static int __init smsc47b397_find(unsigned short *addr)
323{
324 u8 id, rev;
325
326 superio_enter();
327 id = superio_inb(SUPERIO_REG_DEVID);
328
329 if (id != 0x6f) {
330 superio_exit();

--- 12 unchanged lines hidden (view full) ---

343 superio_exit();
344 return 0;
345}
346
347static int __init smsc47b397_init(void)
348{
349 int ret;
350
299{
300 u8 id, rev;
301
302 superio_enter();
303 id = superio_inb(SUPERIO_REG_DEVID);
304
305 if (id != 0x6f) {
306 superio_exit();

--- 12 unchanged lines hidden (view full) ---

319 superio_exit();
320 return 0;
321}
322
323static int __init smsc47b397_init(void)
324{
325 int ret;
326
351 if ((ret = smsc47b397_find(normal_isa)))
327 if ((ret = smsc47b397_find(&address)))
352 return ret;
353
354 return i2c_isa_add_driver(&smsc47b397_driver);
355}
356
357static void __exit smsc47b397_exit(void)
358{
359 i2c_isa_del_driver(&smsc47b397_driver);
360}
361
362MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
363MODULE_DESCRIPTION("SMSC LPC47B397 driver");
364MODULE_LICENSE("GPL");
365
366module_init(smsc47b397_init);
367module_exit(smsc47b397_exit);
328 return ret;
329
330 return i2c_isa_add_driver(&smsc47b397_driver);
331}
332
333static void __exit smsc47b397_exit(void)
334{
335 i2c_isa_del_driver(&smsc47b397_driver);
336}
337
338MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
339MODULE_DESCRIPTION("SMSC LPC47B397 driver");
340MODULE_LICENSE("GPL");
341
342module_init(smsc47b397_init);
343module_exit(smsc47b397_exit);