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>
44 static unsigned short normal_i2c
[] = { 0x73, I2C_CLIENT_END
};
49 I2C_CLIENT_INSMOD_1(fscpos
);
52 * The FSCPOS registers
55 /* chip identification */
56 #define FSCPOS_REG_IDENT_0 0x00
57 #define FSCPOS_REG_IDENT_1 0x01
58 #define FSCPOS_REG_IDENT_2 0x02
59 #define FSCPOS_REG_REVISION 0x03
61 /* global control and status */
62 #define FSCPOS_REG_EVENT_STATE 0x04
63 #define FSCPOS_REG_CONTROL 0x05
66 #define FSCPOS_REG_WDOG_PRESET 0x28
67 #define FSCPOS_REG_WDOG_STATE 0x23
68 #define FSCPOS_REG_WDOG_CONTROL 0x21
71 #define FSCPOS_REG_VOLT_12 0x45
72 #define FSCPOS_REG_VOLT_5 0x42
73 #define FSCPOS_REG_VOLT_BATT 0x48
75 /* fans - the chip does not support minimum speed for fan2 */
76 static u8 FSCPOS_REG_PWM
[] = { 0x55, 0x65 };
77 static u8 FSCPOS_REG_FAN_ACT
[] = { 0x0e, 0x6b, 0xab };
78 static u8 FSCPOS_REG_FAN_STATE
[] = { 0x0d, 0x62, 0xa2 };
79 static u8 FSCPOS_REG_FAN_RIPPLE
[] = { 0x0f, 0x6f, 0xaf };
82 static u8 FSCPOS_REG_TEMP_ACT
[] = { 0x64, 0x32, 0x35 };
83 static u8 FSCPOS_REG_TEMP_STATE
[] = { 0x71, 0x81, 0x91 };
86 * Functions declaration
88 static int fscpos_attach_adapter(struct i2c_adapter
*adapter
);
89 static int fscpos_detect(struct i2c_adapter
*adapter
, int address
, int kind
);
90 static int fscpos_detach_client(struct i2c_client
*client
);
92 static int fscpos_read_value(struct i2c_client
*client
, u8
register);
93 static int fscpos_write_value(struct i2c_client
*client
, u8
register, u8 value
);
94 static struct fscpos_data
*fscpos_update_device(struct device
*dev
);
95 static void fscpos_init_client(struct i2c_client
*client
);
97 static void reset_fan_alarm(struct i2c_client
*client
, int nr
);
100 * Driver data (common to all clients)
102 static struct i2c_driver fscpos_driver
= {
106 .id
= I2C_DRIVERID_FSCPOS
,
107 .attach_adapter
= fscpos_attach_adapter
,
108 .detach_client
= fscpos_detach_client
,
112 * Client data (each client gets its own)
115 struct i2c_client client
;
116 struct class_device
*class_dev
;
117 struct semaphore update_lock
;
118 char valid
; /* 0 until following fields are valid */
119 unsigned long last_updated
; /* In jiffies */
121 /* register values */
122 u8 revision
; /* revision of chip */
123 u8 global_event
; /* global event status */
124 u8 global_control
; /* global control register */
125 u8 wdog_control
; /* watchdog control */
126 u8 wdog_state
; /* watchdog status */
127 u8 wdog_preset
; /* watchdog preset */
128 u8 volt
[3]; /* 12, 5, battery current */
129 u8 temp_act
[3]; /* temperature */
130 u8 temp_status
[3]; /* status of sensor */
131 u8 fan_act
[3]; /* fans revolutions per second */
132 u8 fan_status
[3]; /* fan status */
133 u8 pwm
[2]; /* fan min value for rps */
134 u8 fan_ripple
[3]; /* divider for rps */
138 #define TEMP_FROM_REG(val) (((val) - 128) * 1000)
140 static ssize_t
show_temp_input(struct fscpos_data
*data
, char *buf
, int nr
)
142 return sprintf(buf
, "%d\n", TEMP_FROM_REG(data
->temp_act
[nr
- 1]));
145 static ssize_t
show_temp_status(struct fscpos_data
*data
, char *buf
, int nr
)
147 /* bits 2..7 reserved => mask with 0x03 */
148 return sprintf(buf
, "%u\n", data
->temp_status
[nr
- 1] & 0x03);
151 static ssize_t
show_temp_reset(struct fscpos_data
*data
, char *buf
, int nr
)
153 return sprintf(buf
, "1\n");
156 static ssize_t
set_temp_reset(struct i2c_client
*client
, struct fscpos_data
157 *data
, const char *buf
, size_t count
, int nr
, int reg
)
159 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
161 dev_err(&client
->dev
, "temp_reset value %ld not supported. "
162 "Use 1 to reset the alarm!\n", v
);
166 dev_info(&client
->dev
, "You used the temp_reset feature which has not "
167 "been proplerly tested. Please report your "
168 "experience to the module author.\n");
170 /* Supported value: 2 (clears the status) */
171 fscpos_write_value(client
, FSCPOS_REG_TEMP_STATE
[nr
- 1], 2);
176 #define RPM_FROM_REG(val) ((val) * 60)
178 static ssize_t
show_fan_status(struct fscpos_data
*data
, char *buf
, int nr
)
180 /* bits 0..1, 3..7 reserved => mask with 0x04 */
181 return sprintf(buf
, "%u\n", data
->fan_status
[nr
- 1] & 0x04);
184 static ssize_t
show_fan_input(struct fscpos_data
*data
, char *buf
, int nr
)
186 return sprintf(buf
, "%u\n", RPM_FROM_REG(data
->fan_act
[nr
- 1]));
189 static ssize_t
show_fan_ripple(struct fscpos_data
*data
, char *buf
, int nr
)
191 /* bits 2..7 reserved => mask with 0x03 */
192 return sprintf(buf
, "%u\n", data
->fan_ripple
[nr
- 1] & 0x03);
195 static ssize_t
set_fan_ripple(struct i2c_client
*client
, struct fscpos_data
196 *data
, const char *buf
, size_t count
, int nr
, int reg
)
198 /* supported values: 2, 4, 8 */
199 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
202 case 2: v
= 1; break;
203 case 4: v
= 2; break;
204 case 8: v
= 3; break;
206 dev_err(&client
->dev
, "fan_ripple value %ld not supported. "
207 "Must be one of 2, 4 or 8!\n", v
);
211 down(&data
->update_lock
);
212 /* bits 2..7 reserved => mask with 0x03 */
213 data
->fan_ripple
[nr
- 1] &= ~0x03;
214 data
->fan_ripple
[nr
- 1] |= v
;
216 fscpos_write_value(client
, reg
, data
->fan_ripple
[nr
- 1]);
217 up(&data
->update_lock
);
221 static ssize_t
show_pwm(struct fscpos_data
*data
, char *buf
, int nr
)
223 return sprintf(buf
, "%u\n", data
->pwm
[nr
- 1]);
226 static ssize_t
set_pwm(struct i2c_client
*client
, struct fscpos_data
*data
,
227 const char *buf
, size_t count
, int nr
, int reg
)
229 unsigned long v
= simple_strtoul(buf
, NULL
, 10);
233 if (v
> 255) v
= 255;
235 down(&data
->update_lock
);
236 data
->pwm
[nr
- 1] = v
;
237 fscpos_write_value(client
, reg
, data
->pwm
[nr
- 1]);
238 up(&data
->update_lock
);
242 static void reset_fan_alarm(struct i2c_client
*client
, int nr
)
244 fscpos_write_value(client
, FSCPOS_REG_FAN_STATE
[nr
], 4);
248 #define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255)
250 static ssize_t
show_volt_12(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
252 struct fscpos_data
*data
= fscpos_update_device(dev
);
253 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[0], 14200));
256 static ssize_t
show_volt_5(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
258 struct fscpos_data
*data
= fscpos_update_device(dev
);
259 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[1], 6600));
262 static ssize_t
show_volt_batt(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
264 struct fscpos_data
*data
= fscpos_update_device(dev
);
265 return sprintf(buf
, "%u\n", VOLT_FROM_REG(data
->volt
[2], 3300));
269 static ssize_t
show_wdog_control(struct fscpos_data
*data
, char *buf
)
271 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
272 return sprintf(buf
, "%u\n", data
->wdog_control
& 0xb0);
275 static ssize_t
set_wdog_control(struct i2c_client
*client
, struct fscpos_data
276 *data
, const char *buf
, size_t count
, int reg
)
278 /* bits 0..3 reserved => mask with 0xf0 */
279 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0xf0;
281 down(&data
->update_lock
);
282 data
->wdog_control
&= ~0xf0;
283 data
->wdog_control
|= v
;
284 fscpos_write_value(client
, reg
, data
->wdog_control
);
285 up(&data
->update_lock
);
289 static ssize_t
show_wdog_state(struct fscpos_data
*data
, char *buf
)
291 /* bits 0, 2..7 reserved => mask with 0x02 */
292 return sprintf(buf
, "%u\n", data
->wdog_state
& 0x02);
295 static ssize_t
set_wdog_state(struct i2c_client
*client
, struct fscpos_data
296 *data
, const char *buf
, size_t count
, int reg
)
298 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0x02;
300 /* Valid values: 2 (clear) */
302 dev_err(&client
->dev
, "wdog_state value %ld not supported. "
303 "Must be 2 to clear the state!\n", v
);
307 down(&data
->update_lock
);
308 data
->wdog_state
&= ~v
;
309 fscpos_write_value(client
, reg
, v
);
310 up(&data
->update_lock
);
314 static ssize_t
show_wdog_preset(struct fscpos_data
*data
, char *buf
)
316 return sprintf(buf
, "%u\n", data
->wdog_preset
);
319 static ssize_t
set_wdog_preset(struct i2c_client
*client
, struct fscpos_data
320 *data
, const char *buf
, size_t count
, int reg
)
322 unsigned long v
= simple_strtoul(buf
, NULL
, 10) & 0xff;
324 down(&data
->update_lock
);
325 data
->wdog_preset
= v
;
326 fscpos_write_value(client
, reg
, data
->wdog_preset
);
327 up(&data
->update_lock
);
332 static ssize_t
show_event(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
334 /* bits 5..7 reserved => mask with 0x1f */
335 struct fscpos_data
*data
= fscpos_update_device(dev
);
336 return sprintf(buf
, "%u\n", data
->global_event
& 0x9b);
342 #define create_getter(kind, sub) \
343 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
345 struct fscpos_data *data = fscpos_update_device(dev); \
346 return show_##kind##sub(data, buf); \
349 #define create_getter_n(kind, offset, sub) \
350 static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
353 struct fscpos_data *data = fscpos_update_device(dev); \
354 return show_##kind##sub(data, buf, offset); \
357 #define create_setter(kind, sub, reg) \
358 static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
359 *buf, size_t count) \
361 struct i2c_client *client = to_i2c_client(dev); \
362 struct fscpos_data *data = i2c_get_clientdata(client); \
363 return set_##kind##sub(client, data, buf, count, reg); \
366 #define create_setter_n(kind, offset, sub, reg) \
367 static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
368 const char *buf, size_t count) \
370 struct i2c_client *client = to_i2c_client(dev); \
371 struct fscpos_data *data = i2c_get_clientdata(client); \
372 return set_##kind##sub(client, data, buf, count, offset, reg);\
375 #define create_sysfs_device_ro(kind, sub, offset) \
376 static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
377 sysfs_show_##kind##offset##sub, NULL);
379 #define create_sysfs_device_rw(kind, sub, offset) \
380 static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
381 sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
383 #define sysfs_ro_n(kind, sub, offset) \
384 create_getter_n(kind, offset, sub); \
385 create_sysfs_device_ro(kind, sub, offset);
387 #define sysfs_rw_n(kind, sub, offset, reg) \
388 create_getter_n(kind, offset, sub); \
389 create_setter_n(kind, offset, sub, reg); \
390 create_sysfs_device_rw(kind, sub, offset);
392 #define sysfs_rw(kind, sub, reg) \
393 create_getter(kind, sub); \
394 create_setter(kind, sub, reg); \
395 create_sysfs_device_rw(kind, sub,);
397 #define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
398 sysfs_fan(offset, reg_status, reg_ripple); \
399 sysfs_rw_n(pwm,, offset, reg_min);
401 #define sysfs_fan(offset, reg_status, reg_ripple) \
402 sysfs_ro_n(fan, _input, offset); \
403 sysfs_ro_n(fan, _status, offset); \
404 sysfs_rw_n(fan, _ripple, offset, reg_ripple);
406 #define sysfs_temp(offset, reg_status) \
407 sysfs_ro_n(temp, _input, offset); \
408 sysfs_ro_n(temp, _status, offset); \
409 sysfs_rw_n(temp, _reset, offset, reg_status);
411 #define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
412 sysfs_rw(wdog, _control, reg_wdog_control); \
413 sysfs_rw(wdog, _preset, reg_wdog_preset); \
414 sysfs_rw(wdog, _state, reg_wdog_state);
416 sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE
[0], FSCPOS_REG_FAN_RIPPLE
[0],
418 sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE
[1], FSCPOS_REG_FAN_RIPPLE
[1],
420 sysfs_fan(3, FSCPOS_REG_FAN_STATE
[2], FSCPOS_REG_FAN_RIPPLE
[2]);
422 sysfs_temp(1, FSCPOS_REG_TEMP_STATE
[0]);
423 sysfs_temp(2, FSCPOS_REG_TEMP_STATE
[1]);
424 sysfs_temp(3, FSCPOS_REG_TEMP_STATE
[2]);
426 sysfs_watchdog(FSCPOS_REG_WDOG_PRESET
, FSCPOS_REG_WDOG_STATE
,
427 FSCPOS_REG_WDOG_CONTROL
);
429 static DEVICE_ATTR(event
, S_IRUGO
, show_event
, NULL
);
430 static DEVICE_ATTR(in0_input
, S_IRUGO
, show_volt_12
, NULL
);
431 static DEVICE_ATTR(in1_input
, S_IRUGO
, show_volt_5
, NULL
);
432 static DEVICE_ATTR(in2_input
, S_IRUGO
, show_volt_batt
, NULL
);
434 static int fscpos_attach_adapter(struct i2c_adapter
*adapter
)
436 if (!(adapter
->class & I2C_CLASS_HWMON
))
438 return i2c_probe(adapter
, &addr_data
, fscpos_detect
);
441 static int fscpos_detect(struct i2c_adapter
*adapter
, int address
, int kind
)
443 struct i2c_client
*new_client
;
444 struct fscpos_data
*data
;
447 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
451 * OK. For now, we presume we have a valid client. We now create the
452 * client structure, even though we cannot fill it completely yet.
453 * But it allows us to access fscpos_{read,write}_value.
456 if (!(data
= kzalloc(sizeof(struct fscpos_data
), GFP_KERNEL
))) {
461 new_client
= &data
->client
;
462 i2c_set_clientdata(new_client
, data
);
463 new_client
->addr
= address
;
464 new_client
->adapter
= adapter
;
465 new_client
->driver
= &fscpos_driver
;
466 new_client
->flags
= 0;
468 /* Do the remaining detection unless force or force_fscpos parameter */
470 if ((fscpos_read_value(new_client
, FSCPOS_REG_IDENT_0
)
472 || (fscpos_read_value(new_client
, FSCPOS_REG_IDENT_1
)
474 || (fscpos_read_value(new_client
, FSCPOS_REG_IDENT_2
)
477 dev_dbg(&new_client
->dev
, "fscpos detection failed\n");
482 /* Fill in the remaining client fields and put it in the global list */
483 strlcpy(new_client
->name
, "fscpos", I2C_NAME_SIZE
);
486 init_MUTEX(&data
->update_lock
);
488 /* Tell the I2C layer a new client has arrived */
489 if ((err
= i2c_attach_client(new_client
)))
492 /* Inizialize the fscpos chip */
493 fscpos_init_client(new_client
);
495 /* Announce that the chip was found */
496 dev_info(&new_client
->dev
, "Found fscpos chip, rev %u\n", data
->revision
);
498 /* Register sysfs hooks */
499 data
->class_dev
= hwmon_device_register(&new_client
->dev
);
500 if (IS_ERR(data
->class_dev
)) {
501 err
= PTR_ERR(data
->class_dev
);
505 device_create_file(&new_client
->dev
, &dev_attr_event
);
506 device_create_file(&new_client
->dev
, &dev_attr_in0_input
);
507 device_create_file(&new_client
->dev
, &dev_attr_in1_input
);
508 device_create_file(&new_client
->dev
, &dev_attr_in2_input
);
509 device_create_file(&new_client
->dev
, &dev_attr_wdog_control
);
510 device_create_file(&new_client
->dev
, &dev_attr_wdog_preset
);
511 device_create_file(&new_client
->dev
, &dev_attr_wdog_state
);
512 device_create_file(&new_client
->dev
, &dev_attr_temp1_input
);
513 device_create_file(&new_client
->dev
, &dev_attr_temp1_status
);
514 device_create_file(&new_client
->dev
, &dev_attr_temp1_reset
);
515 device_create_file(&new_client
->dev
, &dev_attr_temp2_input
);
516 device_create_file(&new_client
->dev
, &dev_attr_temp2_status
);
517 device_create_file(&new_client
->dev
, &dev_attr_temp2_reset
);
518 device_create_file(&new_client
->dev
, &dev_attr_temp3_input
);
519 device_create_file(&new_client
->dev
, &dev_attr_temp3_status
);
520 device_create_file(&new_client
->dev
, &dev_attr_temp3_reset
);
521 device_create_file(&new_client
->dev
, &dev_attr_fan1_input
);
522 device_create_file(&new_client
->dev
, &dev_attr_fan1_status
);
523 device_create_file(&new_client
->dev
, &dev_attr_fan1_ripple
);
524 device_create_file(&new_client
->dev
, &dev_attr_pwm1
);
525 device_create_file(&new_client
->dev
, &dev_attr_fan2_input
);
526 device_create_file(&new_client
->dev
, &dev_attr_fan2_status
);
527 device_create_file(&new_client
->dev
, &dev_attr_fan2_ripple
);
528 device_create_file(&new_client
->dev
, &dev_attr_pwm2
);
529 device_create_file(&new_client
->dev
, &dev_attr_fan3_input
);
530 device_create_file(&new_client
->dev
, &dev_attr_fan3_status
);
531 device_create_file(&new_client
->dev
, &dev_attr_fan3_ripple
);
536 i2c_detach_client(new_client
);
543 static int fscpos_detach_client(struct i2c_client
*client
)
545 struct fscpos_data
*data
= i2c_get_clientdata(client
);
548 hwmon_device_unregister(data
->class_dev
);
550 if ((err
= i2c_detach_client(client
)))
556 static int fscpos_read_value(struct i2c_client
*client
, u8 reg
)
558 dev_dbg(&client
->dev
, "Read reg 0x%02x\n", reg
);
559 return i2c_smbus_read_byte_data(client
, reg
);
562 static int fscpos_write_value(struct i2c_client
*client
, u8 reg
, u8 value
)
564 dev_dbg(&client
->dev
, "Write reg 0x%02x, val 0x%02x\n", reg
, value
);
565 return i2c_smbus_write_byte_data(client
, reg
, value
);
568 /* Called when we have found a new FSCPOS chip */
569 static void fscpos_init_client(struct i2c_client
*client
)
571 struct fscpos_data
*data
= i2c_get_clientdata(client
);
573 /* read revision from chip */
574 data
->revision
= fscpos_read_value(client
, FSCPOS_REG_REVISION
);
577 static struct fscpos_data
*fscpos_update_device(struct device
*dev
)
579 struct i2c_client
*client
= to_i2c_client(dev
);
580 struct fscpos_data
*data
= i2c_get_clientdata(client
);
582 down(&data
->update_lock
);
584 if (time_after(jiffies
, data
->last_updated
+ 2 * HZ
) || !data
->valid
) {
587 dev_dbg(&client
->dev
, "Starting fscpos update\n");
589 for (i
= 0; i
< 3; i
++) {
590 data
->temp_act
[i
] = fscpos_read_value(client
,
591 FSCPOS_REG_TEMP_ACT
[i
]);
592 data
->temp_status
[i
] = fscpos_read_value(client
,
593 FSCPOS_REG_TEMP_STATE
[i
]);
594 data
->fan_act
[i
] = fscpos_read_value(client
,
595 FSCPOS_REG_FAN_ACT
[i
]);
596 data
->fan_status
[i
] = fscpos_read_value(client
,
597 FSCPOS_REG_FAN_STATE
[i
]);
598 data
->fan_ripple
[i
] = fscpos_read_value(client
,
599 FSCPOS_REG_FAN_RIPPLE
[i
]);
601 /* fan2_min is not supported by the chip */
602 data
->pwm
[i
] = fscpos_read_value(client
,
605 /* reset fan status if speed is back to > 0 */
606 if (data
->fan_status
[i
] != 0 && data
->fan_act
[i
] > 0) {
607 reset_fan_alarm(client
, i
);
611 data
->volt
[0] = fscpos_read_value(client
, FSCPOS_REG_VOLT_12
);
612 data
->volt
[1] = fscpos_read_value(client
, FSCPOS_REG_VOLT_5
);
613 data
->volt
[2] = fscpos_read_value(client
, FSCPOS_REG_VOLT_BATT
);
615 data
->wdog_preset
= fscpos_read_value(client
,
616 FSCPOS_REG_WDOG_PRESET
);
617 data
->wdog_state
= fscpos_read_value(client
,
618 FSCPOS_REG_WDOG_STATE
);
619 data
->wdog_control
= fscpos_read_value(client
,
620 FSCPOS_REG_WDOG_CONTROL
);
622 data
->global_event
= fscpos_read_value(client
,
623 FSCPOS_REG_EVENT_STATE
);
625 data
->last_updated
= jiffies
;
628 up(&data
->update_lock
);
632 static int __init
sm_fscpos_init(void)
634 return i2c_add_driver(&fscpos_driver
);
637 static void __exit
sm_fscpos_exit(void)
639 i2c_del_driver(&fscpos_driver
);
642 MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
643 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
644 " and Philip Edelbrock <phil@netroedge.com>");
645 MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
646 MODULE_LICENSE("GPL");
648 module_init(sm_fscpos_init
);
649 module_exit(sm_fscpos_exit
);