2 fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips
3 Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 fujitsu siemens poseidon chip,
22 module based on the old fscpos module by Hermann Jung <hej@odn.de> and
23 the fscher module by Reinhard Nissl <rnissl@gmx.de>
25 original module based on lm80.c
26 Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
27 and Philip Edelbrock <phil@netroedge.com>
29 Thanks to Jean Delvare for reviewing my code and suggesting a lot of
33 #include <linux/module.h>
34 #include <linux/slab.h>
35 #include <linux/jiffies.h>
36 #include <linux/i2c.h>
37 #include <linux/init.h>
38 #include <linux/hwmon.h>
39 #include <linux/err.h>
40 #include <linux/mutex.h>
41 #include <linux/sysfs.h>
46 <<<<<<< HEAD
:drivers
/hwmon
/fscpos
.c
47 static unsigned short normal_i2c
[] = { 0x73, I2C_CLIENT_END
};
49 static const unsigned short normal_i2c
[] = { 0x73, I2C_CLIENT_END
};
50 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a
:drivers
/hwmon
/fscpos
.c
55 I2C_CLIENT_INSMOD_1(fscpos
);
58 * The FSCPOS registers
61 /* chip identification */
62 #define FSCPOS_REG_IDENT_0 0x00
63 #define FSCPOS_REG_IDENT_1 0x01
64 #define FSCPOS_REG_IDENT_2 0x02
65 #define FSCPOS_REG_REVISION 0x03
67 /* global control and status */
68 #define FSCPOS_REG_EVENT_STATE 0x04
69 #define FSCPOS_REG_CONTROL 0x05
72 #define FSCPOS_REG_WDOG_PRESET 0x28
73 #define FSCPOS_REG_WDOG_STATE 0x23
74 #define FSCPOS_REG_WDOG_CONTROL 0x21
77 #define FSCPOS_REG_VOLT_12 0x45
78 #define FSCPOS_REG_VOLT_5 0x42
79 #define FSCPOS_REG_VOLT_BATT 0x48
81 /* fans - the chip does not support minimum speed for fan2 */
82 static u8 FSCPOS_REG_PWM
[] = { 0x55, 0x65 };
83 static u8 FSCPOS_REG_FAN_ACT
[] = { 0x0e, 0x6b, 0xab };
84 static u8 FSCPOS_REG_FAN_STATE
[] = { 0x0d, 0x62, 0xa2 };
85 static u8 FSCPOS_REG_FAN_RIPPLE
[] = { 0x0f, 0x6f, 0xaf };
88 static u8 FSCPOS_REG_TEMP_ACT
[] = { 0x64, 0x32, 0x35 };
89 static u8 FSCPOS_REG_TEMP_STATE
[] = { 0x71, 0x81, 0x91 };
92 * Functions declaration
94 static int fscpos_attach_adapter(struct i2c_adapter
*adapter
);
95 static int fscpos_detect(struct i2c_adapter
*adapter
, int address
, int kind
);
96 static int fscpos_detach_client(struct i2c_client
*client
);
98 static int fscpos_read_value(struct i2c_client
*client
, u8 reg
);
99 static int fscpos_write_value(struct i2c_client
*client
, u8 reg
, u8 value
);
100 static struct fscpos_data
*fscpos_update_device(struct device
*dev
);
101 static void fscpos_init_client(struct i2c_client
*client
);
103 static void reset_fan_alarm(struct i2c_client
*client
, int nr
);
106 * Driver data (common to all clients)
108 static struct i2c_driver fscpos_driver
= {
112 .attach_adapter
= fscpos_attach_adapter
,
113 .detach_client
= fscpos_detach_client
,
117 * Client data (each client gets its own)
120 struct i2c_client client
;
121 struct device
*hwmon_dev
;
122 struct mutex update_lock
;
123 char valid
; /* 0 until following fields are valid */
124 unsigned long last_updated
; /* In jiffies */
126 /* register values */
127 u8 revision
; /* revision of chip */
128 u8 global_event
; /* global event status */
129 u8 global_control
; /* global control register */
130 u8 wdog_control
; /* watchdog control */
131 u8 wdog_state
; /* watchdog status */
132 u8 wdog_preset
; /* watchdog preset */
133 u8 volt
[3]; /* 12, 5, battery current */
134 u8 temp_act
[3]; /* temperature */
135 u8 temp_status
[3]; /* status of sensor */
136 u8 fan_act
[3]; /* fans revolutions per second */
137 u8 fan_status
[3]; /* fan status */
138 u8 pwm
[2]; /* fan min value for rps */
139 u8 fan_ripple
[3]; /* divider for rps */
143 #define TEMP_FROM_REG(val) (((val) - 128) * 1000)
145 static ssize_t
show_temp_input(struct fscpos_data
*data
, char *buf
, int nr
)
147 return sprintf(buf
, "%d\n", TEMP_FROM_REG(data
->temp_act
[nr
- 1]));
150 static ssize_t
show_temp_status(struct fscpos_data
*data
, char *buf
, int nr
)
152 /* bits 2..7 reserved => mask with 0x03 */
153 return sprintf(buf
, "%u\n", data
->temp_status
[nr
- 1] & 0x03);
156 static ssize_t
show_temp_reset(struct fscpos_data
*data
, char *buf
, int nr
)
158 return sprintf(buf
, "1\n");
161 static ssize_t
set_temp_reset(struct i2c_client
*client
, struct fscpos_data
162 *data
, const char *buf
, size_t count
, int nr
, int reg
)
164 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
166 dev_err(&client
->dev
, "temp_reset value %ld not supported. "
167 "Use 1 to reset the alarm!\n", v
);
171 dev_info(&client
->dev
, "You used the temp_reset feature which has not "
172 "been proplerly tested. Please report your "
173 "experience to the module author.\n");
175 /* Supported value: 2 (clears the status) */
176 fscpos_write_value(client
, FSCPOS_REG_TEMP_STATE
[nr
- 1], 2);
181 #define RPM_FROM_REG(val) ((val) * 60)
183 static ssize_t
show_fan_status(struct fscpos_data
*data
, char *buf
, int nr
)
185 /* bits 0..1, 3..7 reserved => mask with 0x04 */
186 return sprintf(buf
, "%u\n", data
->fan_status
[nr
- 1] & 0x04);
189 static ssize_t
show_fan_input(struct fscpos_data
*data
, char *buf
, int nr
)
191 return sprintf(buf
, "%u\n", RPM_FROM_REG(data
->fan_act
[nr
- 1]));
194 static ssize_t
show_fan_ripple(struct fscpos_data
*data
, char *buf
, int nr
)
196 /* bits 2..7 reserved => mask with 0x03 */
197 return sprintf(buf
, "%u\n", data
->fan_ripple
[nr
- 1] & 0x03);
200 static ssize_t
set_fan_ripple(struct i2c_client
*client
, struct fscpos_data
201 *data
, const char *buf
, size_t count
, int nr
, int reg
)
203 /* supported values: 2, 4, 8 */
204 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
207 case 2: v
= 1; break;
208 case 4: v
= 2; break;
209 case 8: v
= 3; break;
211 dev_err(&client
->dev
, "fan_ripple value %ld not supported. "
212 "Must be one of 2, 4 or 8!\n", v
);
216 mutex_lock(&data
->update_lock
);
217 /* bits 2..7 reserved => mask with 0x03 */
218 data
->fan_ripple
[nr
- 1] &= ~0x03;
219 data
->fan_ripple
[nr
- 1] |= v
;
221 fscpos_write_value(client
, reg
, data
->fan_ripple
[nr
- 1]);
222 mutex_unlock(&data
->update_lock
);
226 static ssize_t
show_pwm(struct fscpos_data
*data
, char *buf
, int nr
)
228 return sprintf(buf
, "%u\n", data
->pwm
[nr
- 1]);
231 static ssize_t
set_pwm(struct i2c_client
*client
, struct fscpos_data
*data
,
232 const char *buf
, size_t count
, int nr
, int reg
)
234 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
238 if (v
> 255) v
= 255;
240 mutex_lock(&data
->update_lock
);
241 data
->pwm
[nr
- 1] = v
;
242 fscpos_write_value(client
, reg
, data
->pwm
[nr
- 1]);
243 mutex_unlock(&data
->update_lock
);
247 static void reset_fan_alarm(struct i2c_client
*client
, int nr
)
249 fscpos_write_value(client
, FSCPOS_REG_FAN_STATE
[nr
], 4);
253 #define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255)
255 static ssize_t
show_volt_12(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
257 struct fscpos_data
*data
= fscpos_update_device(dev
);
258 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[0], 14200));
261 static ssize_t
show_volt_5(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
263 struct fscpos_data
*data
= fscpos_update_device(dev
);
264 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[1], 6600));
267 static ssize_t
show_volt_batt(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
269 struct fscpos_data
*data
= fscpos_update_device(dev
);
270 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[2], 3300));
274 static ssize_t
show_wdog_control(struct fscpos_data
*data
, char *buf
)
276 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
277 return sprintf(buf
, "%u\n", data
->wdog_control
& 0xb0);
280 static ssize_t
set_wdog_control(struct i2c_client
*client
, struct fscpos_data
281 *data
, const char *buf
, size_t count
, int reg
)
283 /* bits 0..3 reserved => mask with 0xf0 */
284 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0xf0;
286 mutex_lock(&data
->update_lock
);
287 data
->wdog_control
&= ~0xf0;
288 data
->wdog_control
|= v
;
289 fscpos_write_value(client
, reg
, data
->wdog_control
);
290 mutex_unlock(&data
->update_lock
);
294 static ssize_t
show_wdog_state(struct fscpos_data
*data
, char *buf
)
296 /* bits 0, 2..7 reserved => mask with 0x02 */
297 return sprintf(buf
, "%u\n", data
->wdog_state
& 0x02);
300 static ssize_t
set_wdog_state(struct i2c_client
*client
, struct fscpos_data
301 *data
, const char *buf
, size_t count
, int reg
)
303 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0x02;
305 /* Valid values: 2 (clear) */
307 dev_err(&client
->dev
, "wdog_state value %ld not supported. "
308 "Must be 2 to clear the state!\n", v
);
312 mutex_lock(&data
->update_lock
);
313 data
->wdog_state
&= ~v
;
314 fscpos_write_value(client
, reg
, v
);
315 mutex_unlock(&data
->update_lock
);
319 static ssize_t
show_wdog_preset(struct fscpos_data
*data
, char *buf
)
321 return sprintf(buf
, "%u\n", data
->wdog_preset
);
324 static ssize_t
set_wdog_preset(struct i2c_client
*client
, struct fscpos_data
325 *data
, const char *buf
, size_t count
, int reg
)
327 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0xff;
329 mutex_lock(&data
->update_lock
);
330 data
->wdog_preset
= v
;
331 fscpos_write_value(client
, reg
, data
->wdog_preset
);
332 mutex_unlock(&data
->update_lock
);
337 static ssize_t
show_event(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
339 /* bits 5..7 reserved => mask with 0x1f */
340 struct fscpos_data
*data
= fscpos_update_device(dev
);
341 return sprintf(buf
, "%u\n", data
->global_event
& 0x9b);
347 #define create_getter(kind, sub) \
348 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
350 struct fscpos_data *data = fscpos_update_device(dev); \
351 return show_##kind##sub(data, buf); \
354 #define create_getter_n(kind, offset, sub) \
355 static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
358 struct fscpos_data *data = fscpos_update_device(dev); \
359 return show_##kind##sub(data, buf, offset); \
362 #define create_setter(kind, sub, reg) \
363 static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
364 *buf, size_t count) \
366 struct i2c_client *client = to_i2c_client(dev); \
367 struct fscpos_data *data = i2c_get_clientdata(client); \
368 return set_##kind##sub(client, data, buf, count, reg); \
371 #define create_setter_n(kind, offset, sub, reg) \
372 static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
373 const char *buf, size_t count) \
375 struct i2c_client *client = to_i2c_client(dev); \
376 struct fscpos_data *data = i2c_get_clientdata(client); \
377 return set_##kind##sub(client, data, buf, count, offset, reg);\
380 #define create_sysfs_device_ro(kind, sub, offset) \
381 static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
382 sysfs_show_##kind##offset##sub, NULL);
384 #define create_sysfs_device_rw(kind, sub, offset) \
385 static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
386 sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
388 #define sysfs_ro_n(kind, sub, offset) \
389 create_getter_n(kind, offset, sub); \
390 create_sysfs_device_ro(kind, sub, offset);
392 #define sysfs_rw_n(kind, sub, offset, reg) \
393 create_getter_n(kind, offset, sub); \
394 create_setter_n(kind, offset, sub, reg); \
395 create_sysfs_device_rw(kind, sub, offset);
397 #define sysfs_rw(kind, sub, reg) \
398 create_getter(kind, sub); \
399 create_setter(kind, sub, reg); \
400 create_sysfs_device_rw(kind, sub,);
402 #define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
403 sysfs_fan(offset, reg_status, reg_ripple); \
404 sysfs_rw_n(pwm,, offset, reg_min);
406 #define sysfs_fan(offset, reg_status, reg_ripple) \
407 sysfs_ro_n(fan, _input, offset); \
408 sysfs_ro_n(fan, _status, offset); \
409 sysfs_rw_n(fan, _ripple, offset, reg_ripple);
411 #define sysfs_temp(offset, reg_status) \
412 sysfs_ro_n(temp, _input, offset); \
413 sysfs_ro_n(temp, _status, offset); \
414 sysfs_rw_n(temp, _reset, offset, reg_status);
416 #define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
417 sysfs_rw(wdog, _control, reg_wdog_control); \
418 sysfs_rw(wdog, _preset, reg_wdog_preset); \
419 sysfs_rw(wdog, _state, reg_wdog_state);
421 sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE
[0], FSCPOS_REG_FAN_RIPPLE
[0],
423 sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE
[1], FSCPOS_REG_FAN_RIPPLE
[1],
425 sysfs_fan(3, FSCPOS_REG_FAN_STATE
[2], FSCPOS_REG_FAN_RIPPLE
[2]);
427 sysfs_temp(1, FSCPOS_REG_TEMP_STATE
[0]);
428 sysfs_temp(2, FSCPOS_REG_TEMP_STATE
[1]);
429 sysfs_temp(3, FSCPOS_REG_TEMP_STATE
[2]);
431 sysfs_watchdog(FSCPOS_REG_WDOG_PRESET
, FSCPOS_REG_WDOG_STATE
,
432 FSCPOS_REG_WDOG_CONTROL
);
434 static DEVICE_ATTR(event
, S_IRUGO
, show_event
, NULL
);
435 static DEVICE_ATTR(in0_input
, S_IRUGO
, show_volt_12
, NULL
);
436 static DEVICE_ATTR(in1_input
, S_IRUGO
, show_volt_5
, NULL
);
437 static DEVICE_ATTR(in2_input
, S_IRUGO
, show_volt_batt
, NULL
);
439 static struct attribute
*fscpos_attributes
[] = {
440 &dev_attr_event
.attr
,
441 &dev_attr_in0_input
.attr
,
442 &dev_attr_in1_input
.attr
,
443 &dev_attr_in2_input
.attr
,
445 &dev_attr_wdog_control
.attr
,
446 &dev_attr_wdog_preset
.attr
,
447 &dev_attr_wdog_state
.attr
,
449 &dev_attr_temp1_input
.attr
,
450 &dev_attr_temp1_status
.attr
,
451 &dev_attr_temp1_reset
.attr
,
452 &dev_attr_temp2_input
.attr
,
453 &dev_attr_temp2_status
.attr
,
454 &dev_attr_temp2_reset
.attr
,
455 &dev_attr_temp3_input
.attr
,
456 &dev_attr_temp3_status
.attr
,
457 &dev_attr_temp3_reset
.attr
,
459 &dev_attr_fan1_input
.attr
,
460 &dev_attr_fan1_status
.attr
,
461 &dev_attr_fan1_ripple
.attr
,
463 &dev_attr_fan2_input
.attr
,
464 &dev_attr_fan2_status
.attr
,
465 &dev_attr_fan2_ripple
.attr
,
467 &dev_attr_fan3_input
.attr
,
468 &dev_attr_fan3_status
.attr
,
469 &dev_attr_fan3_ripple
.attr
,
473 static const struct attribute_group fscpos_group
= {
474 .attrs
= fscpos_attributes
,
477 static int fscpos_attach_adapter(struct i2c_adapter
*adapter
)
479 if (!(adapter
->class & I2C_CLASS_HWMON
))
481 return i2c_probe(adapter
, &addr_data
, fscpos_detect
);
484 static int fscpos_detect(struct i2c_adapter
*adapter
, int address
, int kind
)
486 struct i2c_client
*new_client
;
487 struct fscpos_data
*data
;
490 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
494 * OK. For now, we presume we have a valid client. We now create the
495 * client structure, even though we cannot fill it completely yet.
496 * But it allows us to access fscpos_{read,write}_value.
499 if (!(data
= kzalloc(sizeof(struct fscpos_data
), GFP_KERNEL
))) {
504 new_client
= &data
->client
;
505 i2c_set_clientdata(new_client
, data
);
506 new_client
->addr
= address
;
507 new_client
->adapter
= adapter
;
508 new_client
->driver
= &fscpos_driver
;
509 new_client
->flags
= 0;
511 /* Do the remaining detection unless force or force_fscpos parameter */
513 if ((fscpos_read_value(new_client
, FSCPOS_REG_IDENT_0
)
515 || (fscpos_read_value(new_client
, FSCPOS_REG_IDENT_1
)
517 || (fscpos_read_value(new_client
, FSCPOS_REG_IDENT_2
)
520 dev_dbg(&new_client
->dev
, "fscpos detection failed\n");
525 /* Fill in the remaining client fields and put it in the global list */
526 strlcpy(new_client
->name
, "fscpos", I2C_NAME_SIZE
);
529 mutex_init(&data
->update_lock
);
531 /* Tell the I2C layer a new client has arrived */
532 if ((err
= i2c_attach_client(new_client
)))
535 /* Inizialize the fscpos chip */
536 fscpos_init_client(new_client
);
538 /* Announce that the chip was found */
539 dev_info(&new_client
->dev
, "Found fscpos chip, rev %u\n", data
->revision
);
541 /* Register sysfs hooks */
542 if ((err
= sysfs_create_group(&new_client
->dev
.kobj
, &fscpos_group
)))
545 data
->hwmon_dev
= hwmon_device_register(&new_client
->dev
);
546 if (IS_ERR(data
->hwmon_dev
)) {
547 err
= PTR_ERR(data
->hwmon_dev
);
548 goto exit_remove_files
;
554 sysfs_remove_group(&new_client
->dev
.kobj
, &fscpos_group
);
556 i2c_detach_client(new_client
);
563 static int fscpos_detach_client(struct i2c_client
*client
)
565 struct fscpos_data
*data
= i2c_get_clientdata(client
);
568 hwmon_device_unregister(data
->hwmon_dev
);
569 sysfs_remove_group(&client
->dev
.kobj
, &fscpos_group
);
571 if ((err
= i2c_detach_client(client
)))
577 static int fscpos_read_value(struct i2c_client
*client
, u8 reg
)
579 dev_dbg(&client
->dev
, "Read reg 0x%02x\n", reg
);
580 return i2c_smbus_read_byte_data(client
, reg
);
583 static int fscpos_write_value(struct i2c_client
*client
, u8 reg
, u8 value
)
585 dev_dbg(&client
->dev
, "Write reg 0x%02x, val 0x%02x\n", reg
, value
);
586 return i2c_smbus_write_byte_data(client
, reg
, value
);
589 /* Called when we have found a new FSCPOS chip */
590 static void fscpos_init_client(struct i2c_client
*client
)
592 struct fscpos_data
*data
= i2c_get_clientdata(client
);
594 /* read revision from chip */
595 data
->revision
= fscpos_read_value(client
, FSCPOS_REG_REVISION
);
598 static struct fscpos_data
*fscpos_update_device(struct device
*dev
)
600 struct i2c_client
*client
= to_i2c_client(dev
);
601 struct fscpos_data
*data
= i2c_get_clientdata(client
);
603 mutex_lock(&data
->update_lock
);
605 if (time_after(jiffies
, data
->last_updated
+ 2 * HZ
) || !data
->valid
) {
608 dev_dbg(&client
->dev
, "Starting fscpos update\n");
610 for (i
= 0; i
< 3; i
++) {
611 data
->temp_act
[i
] = fscpos_read_value(client
,
612 FSCPOS_REG_TEMP_ACT
[i
]);
613 data
->temp_status
[i
] = fscpos_read_value(client
,
614 FSCPOS_REG_TEMP_STATE
[i
]);
615 data
->fan_act
[i
] = fscpos_read_value(client
,
616 FSCPOS_REG_FAN_ACT
[i
]);
617 data
->fan_status
[i
] = fscpos_read_value(client
,
618 FSCPOS_REG_FAN_STATE
[i
]);
619 data
->fan_ripple
[i
] = fscpos_read_value(client
,
620 FSCPOS_REG_FAN_RIPPLE
[i
]);
622 /* fan2_min is not supported by the chip */
623 data
->pwm
[i
] = fscpos_read_value(client
,
626 /* reset fan status if speed is back to > 0 */
627 if (data
->fan_status
[i
] != 0 && data
->fan_act
[i
] > 0) {
628 reset_fan_alarm(client
, i
);
632 data
->volt
[0] = fscpos_read_value(client
, FSCPOS_REG_VOLT_12
);
633 data
->volt
[1] = fscpos_read_value(client
, FSCPOS_REG_VOLT_5
);
634 data
->volt
[2] = fscpos_read_value(client
, FSCPOS_REG_VOLT_BATT
);
636 data
->wdog_preset
= fscpos_read_value(client
,
637 FSCPOS_REG_WDOG_PRESET
);
638 data
->wdog_state
= fscpos_read_value(client
,
639 FSCPOS_REG_WDOG_STATE
);
640 data
->wdog_control
= fscpos_read_value(client
,
641 FSCPOS_REG_WDOG_CONTROL
);
643 data
->global_event
= fscpos_read_value(client
,
644 FSCPOS_REG_EVENT_STATE
);
646 data
->last_updated
= jiffies
;
649 mutex_unlock(&data
->update_lock
);
653 static int __init
sm_fscpos_init(void)
655 return i2c_add_driver(&fscpos_driver
);
658 static void __exit
sm_fscpos_exit(void)
660 i2c_del_driver(&fscpos_driver
);
663 MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
664 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
665 " and Philip Edelbrock <phil@netroedge.com>");
666 MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
667 MODULE_LICENSE("GPL");
669 module_init(sm_fscpos_init
);
670 module_exit(sm_fscpos_exit
);