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/i2c-sensor.h>
38 #include <linux/init.h>
39 #include <linux/hwmon.h>
40 #include <linux/err.h>
45 static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
46 static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
51 SENSORS_INSMOD_1(fscpos);
54 * The FSCPOS registers
57 /* chip identification */
58 #define FSCPOS_REG_IDENT_0 0x00
59 #define FSCPOS_REG_IDENT_1 0x01
60 #define FSCPOS_REG_IDENT_2 0x02
61 #define FSCPOS_REG_REVISION 0x03
63 /* global control and status */
64 #define FSCPOS_REG_EVENT_STATE 0x04
65 #define FSCPOS_REG_CONTROL 0x05
68 #define FSCPOS_REG_WDOG_PRESET 0x28
69 #define FSCPOS_REG_WDOG_STATE 0x23
70 #define FSCPOS_REG_WDOG_CONTROL 0x21
73 #define FSCPOS_REG_VOLT_12 0x45
74 #define FSCPOS_REG_VOLT_5 0x42
75 #define FSCPOS_REG_VOLT_BATT 0x48
77 /* fans - the chip does not support minimum speed for fan2 */
78 static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 };
79 static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab };
80 static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 };
81 static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf };
84 static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 };
85 static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
88 * Functions declaration
90 static int fscpos_attach_adapter(struct i2c_adapter *adapter);
91 static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
92 static int fscpos_detach_client(struct i2c_client *client);
94 static int fscpos_read_value(struct i2c_client *client, u8 register);
95 static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value);
96 static struct fscpos_data *fscpos_update_device(struct device *dev);
97 static void fscpos_init_client(struct i2c_client *client);
99 static void reset_fan_alarm(struct i2c_client *client, int nr);
102 * Driver data (common to all clients)
104 static struct i2c_driver fscpos_driver = {
105 .owner = THIS_MODULE,
107 .id = I2C_DRIVERID_FSCPOS,
108 .flags = I2C_DF_NOTIFY,
109 .attach_adapter = fscpos_attach_adapter,
110 .detach_client = fscpos_detach_client,
114 * Client data (each client gets its own)
117 struct i2c_client client;
118 struct class_device *class_dev;
119 struct semaphore update_lock;
120 char valid; /* 0 until following fields are valid */
121 unsigned long last_updated; /* In jiffies */
123 /* register values */
124 u8 revision; /* revision of chip */
125 u8 global_event; /* global event status */
126 u8 global_control; /* global control register */
127 u8 wdog_control; /* watchdog control */
128 u8 wdog_state; /* watchdog status */
129 u8 wdog_preset; /* watchdog preset */
130 u8 volt[3]; /* 12, 5, battery current */
131 u8 temp_act[3]; /* temperature */
132 u8 temp_status[3]; /* status of sensor */
133 u8 fan_act[3]; /* fans revolutions per second */
134 u8 fan_status[3]; /* fan status */
135 u8 pwm[2]; /* fan min value for rps */
136 u8 fan_ripple[3]; /* divider for rps */
140 #define TEMP_FROM_REG(val) (((val) - 128) * 1000)
142 static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr)
144 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1]));
147 static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr)
149 /* bits 2..7 reserved => mask with 0x03 */
150 return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03);
153 static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr)
155 return sprintf(buf, "1\n");
158 static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data
159 *data, const char *buf, size_t count, int nr, int reg)
161 unsigned long v = simple_strtoul(buf, NULL, 10);
163 dev_err(&client->dev, "temp_reset value %ld not supported. "
164 "Use 1 to reset the alarm!\n", v);
168 dev_info(&client->dev, "You used the temp_reset feature which has not "
169 "been proplerly tested. Please report your "
170 "experience to the module author.\n");
172 /* Supported value: 2 (clears the status) */
173 fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2);
178 #define RPM_FROM_REG(val) ((val) * 60)
180 static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr)
182 /* bits 0..1, 3..7 reserved => mask with 0x04 */
183 return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04);
186 static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr)
188 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1]));
191 static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr)
193 /* bits 2..7 reserved => mask with 0x03 */
194 return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03);
197 static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
198 *data, const char *buf, size_t count, int nr, int reg)
200 /* supported values: 2, 4, 8 */
201 unsigned long v = simple_strtoul(buf, NULL, 10);
204 case 2: v = 1; break;
205 case 4: v = 2; break;
206 case 8: v = 3; break;
208 dev_err(&client->dev, "fan_ripple value %ld not supported. "
209 "Must be one of 2, 4 or 8!\n", v);
213 down(&data->update_lock);
214 /* bits 2..7 reserved => mask with 0x03 */
215 data->fan_ripple[nr - 1] &= ~0x03;
216 data->fan_ripple[nr - 1] |= v;
218 fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
219 up(&data->update_lock);
223 static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr)
225 return sprintf(buf, "%u\n", data->pwm[nr - 1]);
228 static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
229 const char *buf, size_t count, int nr, int reg)
231 unsigned long v = simple_strtoul(buf, NULL, 10);
235 if (v > 255) v = 255;
237 down(&data->update_lock);
238 data->pwm[nr - 1] = v;
239 fscpos_write_value(client, reg, data->pwm[nr - 1]);
240 up(&data->update_lock);
244 static void reset_fan_alarm(struct i2c_client *client, int nr)
246 fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4);
250 #define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255)
252 static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf)
254 struct fscpos_data *data = fscpos_update_device(dev);
255 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
258 static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf)
260 struct fscpos_data *data = fscpos_update_device(dev);
261 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
264 static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf)
266 struct fscpos_data *data = fscpos_update_device(dev);
267 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
271 static ssize_t show_wdog_control(struct fscpos_data *data, char *buf)
273 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
274 return sprintf(buf, "%u\n", data->wdog_control & 0xb0);
277 static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
278 *data, const char *buf, size_t count, int reg)
280 /* bits 0..3 reserved => mask with 0xf0 */
281 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
283 down(&data->update_lock);
284 data->wdog_control &= ~0xf0;
285 data->wdog_control |= v;
286 fscpos_write_value(client, reg, data->wdog_control);
287 up(&data->update_lock);
291 static ssize_t show_wdog_state(struct fscpos_data *data, char *buf)
293 /* bits 0, 2..7 reserved => mask with 0x02 */
294 return sprintf(buf, "%u\n", data->wdog_state & 0x02);
297 static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
298 *data, const char *buf, size_t count, int reg)
300 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
302 /* Valid values: 2 (clear) */
304 dev_err(&client->dev, "wdog_state value %ld not supported. "
305 "Must be 2 to clear the state!\n", v);
309 down(&data->update_lock);
310 data->wdog_state &= ~v;
311 fscpos_write_value(client, reg, v);
312 up(&data->update_lock);
316 static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
318 return sprintf(buf, "%u\n", data->wdog_preset);
321 static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
322 *data, const char *buf, size_t count, int reg)
324 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
326 down(&data->update_lock);
327 data->wdog_preset = v;
328 fscpos_write_value(client, reg, data->wdog_preset);
329 up(&data->update_lock);
334 static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf)
336 /* bits 5..7 reserved => mask with 0x1f */
337 struct fscpos_data *data = fscpos_update_device(dev);
338 return sprintf(buf, "%u\n", data->global_event & 0x9b);
344 #define create_getter(kind, sub) \
345 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
347 struct fscpos_data *data = fscpos_update_device(dev); \
348 return show_##kind##sub(data, buf); \
351 #define create_getter_n(kind, offset, sub) \
352 static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
355 struct fscpos_data *data = fscpos_update_device(dev); \
356 return show_##kind##sub(data, buf, offset); \
359 #define create_setter(kind, sub, reg) \
360 static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
361 *buf, size_t count) \
363 struct i2c_client *client = to_i2c_client(dev); \
364 struct fscpos_data *data = i2c_get_clientdata(client); \
365 return set_##kind##sub(client, data, buf, count, reg); \
368 #define create_setter_n(kind, offset, sub, reg) \
369 static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
370 const char *buf, size_t count) \
372 struct i2c_client *client = to_i2c_client(dev); \
373 struct fscpos_data *data = i2c_get_clientdata(client); \
374 return set_##kind##sub(client, data, buf, count, offset, reg);\
377 #define create_sysfs_device_ro(kind, sub, offset) \
378 static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
379 sysfs_show_##kind##offset##sub, NULL);
381 #define create_sysfs_device_rw(kind, sub, offset) \
382 static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
383 sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
385 #define sysfs_ro_n(kind, sub, offset) \
386 create_getter_n(kind, offset, sub); \
387 create_sysfs_device_ro(kind, sub, offset);
389 #define sysfs_rw_n(kind, sub, offset, reg) \
390 create_getter_n(kind, offset, sub); \
391 create_setter_n(kind, offset, sub, reg); \
392 create_sysfs_device_rw(kind, sub, offset);
394 #define sysfs_rw(kind, sub, reg) \
395 create_getter(kind, sub); \
396 create_setter(kind, sub, reg); \
397 create_sysfs_device_rw(kind, sub,);
399 #define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
400 sysfs_fan(offset, reg_status, reg_ripple); \
401 sysfs_rw_n(pwm,, offset, reg_min);
403 #define sysfs_fan(offset, reg_status, reg_ripple) \
404 sysfs_ro_n(fan, _input, offset); \
405 sysfs_ro_n(fan, _status, offset); \
406 sysfs_rw_n(fan, _ripple, offset, reg_ripple);
408 #define sysfs_temp(offset, reg_status) \
409 sysfs_ro_n(temp, _input, offset); \
410 sysfs_ro_n(temp, _status, offset); \
411 sysfs_rw_n(temp, _reset, offset, reg_status);
413 #define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
414 sysfs_rw(wdog, _control, reg_wdog_control); \
415 sysfs_rw(wdog, _preset, reg_wdog_preset); \
416 sysfs_rw(wdog, _state, reg_wdog_state);
418 sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0],
420 sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1],
422 sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]);
424 sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]);
425 sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]);
426 sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]);
428 sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE,
429 FSCPOS_REG_WDOG_CONTROL);
431 static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
432 static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
433 static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
434 static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
436 static int fscpos_attach_adapter(struct i2c_adapter *adapter)
438 if (!(adapter->class & I2C_CLASS_HWMON))
440 return i2c_detect(adapter, &addr_data, fscpos_detect);
443 int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
445 struct i2c_client *new_client;
446 struct fscpos_data *data;
449 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
453 * OK. For now, we presume we have a valid client. We now create the
454 * client structure, even though we cannot fill it completely yet.
455 * But it allows us to access fscpos_{read,write}_value.
458 if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
462 memset(data, 0, sizeof(struct fscpos_data));
464 new_client = &data->client;
465 i2c_set_clientdata(new_client, data);
466 new_client->addr = address;
467 new_client->adapter = adapter;
468 new_client->driver = &fscpos_driver;
469 new_client->flags = 0;
471 /* Do the remaining detection unless force or force_fscpos parameter */
473 if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0)
475 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1)
477 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
480 dev_dbg(&new_client->dev, "fscpos detection failed\n");
485 /* Fill in the remaining client fields and put it in the global list */
486 strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
489 init_MUTEX(&data->update_lock);
491 /* Tell the I2C layer a new client has arrived */
492 if ((err = i2c_attach_client(new_client)))
495 /* Inizialize the fscpos chip */
496 fscpos_init_client(new_client);
498 /* Announce that the chip was found */
499 dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
501 /* Register sysfs hooks */
502 data->class_dev = hwmon_device_register(&new_client->dev);
503 if (IS_ERR(data->class_dev)) {
504 err = PTR_ERR(data->class_dev);
508 device_create_file(&new_client->dev, &dev_attr_event);
509 device_create_file(&new_client->dev, &dev_attr_in0_input);
510 device_create_file(&new_client->dev, &dev_attr_in1_input);
511 device_create_file(&new_client->dev, &dev_attr_in2_input);
512 device_create_file(&new_client->dev, &dev_attr_wdog_control);
513 device_create_file(&new_client->dev, &dev_attr_wdog_preset);
514 device_create_file(&new_client->dev, &dev_attr_wdog_state);
515 device_create_file(&new_client->dev, &dev_attr_temp1_input);
516 device_create_file(&new_client->dev, &dev_attr_temp1_status);
517 device_create_file(&new_client->dev, &dev_attr_temp1_reset);
518 device_create_file(&new_client->dev, &dev_attr_temp2_input);
519 device_create_file(&new_client->dev, &dev_attr_temp2_status);
520 device_create_file(&new_client->dev, &dev_attr_temp2_reset);
521 device_create_file(&new_client->dev, &dev_attr_temp3_input);
522 device_create_file(&new_client->dev, &dev_attr_temp3_status);
523 device_create_file(&new_client->dev, &dev_attr_temp3_reset);
524 device_create_file(&new_client->dev, &dev_attr_fan1_input);
525 device_create_file(&new_client->dev, &dev_attr_fan1_status);
526 device_create_file(&new_client->dev, &dev_attr_fan1_ripple);
527 device_create_file(&new_client->dev, &dev_attr_pwm1);
528 device_create_file(&new_client->dev, &dev_attr_fan2_input);
529 device_create_file(&new_client->dev, &dev_attr_fan2_status);
530 device_create_file(&new_client->dev, &dev_attr_fan2_ripple);
531 device_create_file(&new_client->dev, &dev_attr_pwm2);
532 device_create_file(&new_client->dev, &dev_attr_fan3_input);
533 device_create_file(&new_client->dev, &dev_attr_fan3_status);
534 device_create_file(&new_client->dev, &dev_attr_fan3_ripple);
539 i2c_detach_client(new_client);
546 static int fscpos_detach_client(struct i2c_client *client)
548 struct fscpos_data *data = i2c_get_clientdata(client);
551 hwmon_device_unregister(data->class_dev);
553 if ((err = i2c_detach_client(client))) {
554 dev_err(&client->dev, "Client deregistration failed, client"
562 static int fscpos_read_value(struct i2c_client *client, u8 reg)
564 dev_dbg(&client->dev, "Read reg 0x%02x\n", reg);
565 return i2c_smbus_read_byte_data(client, reg);
568 static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
570 dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value);
571 return i2c_smbus_write_byte_data(client, reg, value);
574 /* Called when we have found a new FSCPOS chip */
575 static void fscpos_init_client(struct i2c_client *client)
577 struct fscpos_data *data = i2c_get_clientdata(client);
579 /* read revision from chip */
580 data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION);
583 static struct fscpos_data *fscpos_update_device(struct device *dev)
585 struct i2c_client *client = to_i2c_client(dev);
586 struct fscpos_data *data = i2c_get_clientdata(client);
588 down(&data->update_lock);
590 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
593 dev_dbg(&client->dev, "Starting fscpos update\n");
595 for (i = 0; i < 3; i++) {
596 data->temp_act[i] = fscpos_read_value(client,
597 FSCPOS_REG_TEMP_ACT[i]);
598 data->temp_status[i] = fscpos_read_value(client,
599 FSCPOS_REG_TEMP_STATE[i]);
600 data->fan_act[i] = fscpos_read_value(client,
601 FSCPOS_REG_FAN_ACT[i]);
602 data->fan_status[i] = fscpos_read_value(client,
603 FSCPOS_REG_FAN_STATE[i]);
604 data->fan_ripple[i] = fscpos_read_value(client,
605 FSCPOS_REG_FAN_RIPPLE[i]);
607 /* fan2_min is not supported by the chip */
608 data->pwm[i] = fscpos_read_value(client,
611 /* reset fan status if speed is back to > 0 */
612 if (data->fan_status[i] != 0 && data->fan_act[i] > 0) {
613 reset_fan_alarm(client, i);
617 data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
618 data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
619 data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
621 data->wdog_preset = fscpos_read_value(client,
622 FSCPOS_REG_WDOG_PRESET);
623 data->wdog_state = fscpos_read_value(client,
624 FSCPOS_REG_WDOG_STATE);
625 data->wdog_control = fscpos_read_value(client,
626 FSCPOS_REG_WDOG_CONTROL);
628 data->global_event = fscpos_read_value(client,
629 FSCPOS_REG_EVENT_STATE);
631 data->last_updated = jiffies;
634 up(&data->update_lock);
638 static int __init sm_fscpos_init(void)
640 return i2c_add_driver(&fscpos_driver);
643 static void __exit sm_fscpos_exit(void)
645 i2c_del_driver(&fscpos_driver);
648 MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
649 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
650 " and Philip Edelbrock <phil@netroedge.com>");
651 MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
652 MODULE_LICENSE("GPL");
654 module_init(sm_fscpos_init);
655 module_exit(sm_fscpos_exit);