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>
 
  45 static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
 
  50 I2C_CLIENT_INSMOD_1(fscpos);
 
  53  * The FSCPOS registers
 
  56 /* chip identification */
 
  57 #define FSCPOS_REG_IDENT_0              0x00
 
  58 #define FSCPOS_REG_IDENT_1              0x01
 
  59 #define FSCPOS_REG_IDENT_2              0x02
 
  60 #define FSCPOS_REG_REVISION             0x03
 
  62 /* global control and status */
 
  63 #define FSCPOS_REG_EVENT_STATE          0x04
 
  64 #define FSCPOS_REG_CONTROL              0x05
 
  67 #define FSCPOS_REG_WDOG_PRESET          0x28
 
  68 #define FSCPOS_REG_WDOG_STATE           0x23
 
  69 #define FSCPOS_REG_WDOG_CONTROL         0x21
 
  72 #define FSCPOS_REG_VOLT_12              0x45
 
  73 #define FSCPOS_REG_VOLT_5               0x42
 
  74 #define FSCPOS_REG_VOLT_BATT            0x48
 
  76 /* fans - the chip does not support minimum speed for fan2 */
 
  77 static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 };
 
  78 static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab };
 
  79 static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 };
 
  80 static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf };
 
  83 static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 };
 
  84 static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
 
  87  * Functions declaration
 
  89 static int fscpos_attach_adapter(struct i2c_adapter *adapter);
 
  90 static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
 
  91 static int fscpos_detach_client(struct i2c_client *client);
 
  93 static int fscpos_read_value(struct i2c_client *client, u8 reg);
 
  94 static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value);
 
  95 static struct fscpos_data *fscpos_update_device(struct device *dev);
 
  96 static void fscpos_init_client(struct i2c_client *client);
 
  98 static void reset_fan_alarm(struct i2c_client *client, int nr);
 
 101  * Driver data (common to all clients)
 
 103 static struct i2c_driver fscpos_driver = {
 
 107         .id             = I2C_DRIVERID_FSCPOS,
 
 108         .attach_adapter = fscpos_attach_adapter,
 
 109         .detach_client  = fscpos_detach_client,
 
 113  * Client data (each client gets its own)
 
 116         struct i2c_client client;
 
 117         struct class_device *class_dev;
 
 118         struct mutex update_lock;
 
 119         char valid;             /* 0 until following fields are valid */
 
 120         unsigned long last_updated;     /* In jiffies */
 
 122         /* register values */
 
 123         u8 revision;            /* revision of chip */
 
 124         u8 global_event;        /* global event status */
 
 125         u8 global_control;      /* global control register */
 
 126         u8 wdog_control;        /* watchdog control */
 
 127         u8 wdog_state;          /* watchdog status */
 
 128         u8 wdog_preset;         /* watchdog preset */
 
 129         u8 volt[3];             /* 12, 5, battery current */
 
 130         u8 temp_act[3];         /* temperature */
 
 131         u8 temp_status[3];      /* status of sensor */
 
 132         u8 fan_act[3];          /* fans revolutions per second */
 
 133         u8 fan_status[3];       /* fan status */
 
 134         u8 pwm[2];              /* fan min value for rps */
 
 135         u8 fan_ripple[3];       /* divider for rps */
 
 139 #define TEMP_FROM_REG(val)      (((val) - 128) * 1000)
 
 141 static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr)
 
 143         return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1]));
 
 146 static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr)
 
 148         /* bits 2..7 reserved => mask with 0x03 */
 
 149         return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03);
 
 152 static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr)
 
 154         return sprintf(buf, "1\n");
 
 157 static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data
 
 158                         *data, const char *buf, size_t count, int nr, int reg)
 
 160         unsigned long v = simple_strtoul(buf, NULL, 10);
 
 162                 dev_err(&client->dev, "temp_reset value %ld not supported. "
 
 163                                         "Use 1 to reset the alarm!\n", v);
 
 167         dev_info(&client->dev, "You used the temp_reset feature which has not "
 
 168                                 "been proplerly tested. Please report your "
 
 169                                 "experience to the module author.\n");
 
 171         /* Supported value: 2 (clears the status) */
 
 172         fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2);
 
 177 #define RPM_FROM_REG(val)       ((val) * 60)
 
 179 static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr)
 
 181         /* bits 0..1, 3..7 reserved => mask with 0x04 */
 
 182         return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04);
 
 185 static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr)
 
 187         return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1]));
 
 190 static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr)
 
 192         /* bits 2..7 reserved => mask with 0x03 */
 
 193         return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03);
 
 196 static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
 
 197                         *data, const char *buf, size_t count, int nr, int reg)
 
 199         /* supported values: 2, 4, 8 */
 
 200         unsigned long v = simple_strtoul(buf, NULL, 10);
 
 203                 case 2: v = 1; break;
 
 204                 case 4: v = 2; break;
 
 205                 case 8: v = 3; break;
 
 207                 dev_err(&client->dev, "fan_ripple value %ld not supported. "
 
 208                                         "Must be one of 2, 4 or 8!\n", v);
 
 212         mutex_lock(&data->update_lock);
 
 213         /* bits 2..7 reserved => mask with 0x03 */
 
 214         data->fan_ripple[nr - 1] &= ~0x03;
 
 215         data->fan_ripple[nr - 1] |= v;
 
 217         fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
 
 218         mutex_unlock(&data->update_lock);
 
 222 static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr)
 
 224         return sprintf(buf, "%u\n", data->pwm[nr - 1]);
 
 227 static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
 
 228                                 const char *buf, size_t count, int nr, int reg)
 
 230         unsigned long v = simple_strtoul(buf, NULL, 10);
 
 234         if (v > 255) v = 255;
 
 236         mutex_lock(&data->update_lock);
 
 237         data->pwm[nr - 1] = v;
 
 238         fscpos_write_value(client, reg, data->pwm[nr - 1]);
 
 239         mutex_unlock(&data->update_lock);
 
 243 static void reset_fan_alarm(struct i2c_client *client, int nr)
 
 245         fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4);
 
 249 #define VOLT_FROM_REG(val, mult)        ((val) * (mult) / 255)
 
 251 static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf)
 
 253         struct fscpos_data *data = fscpos_update_device(dev);
 
 254         return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
 
 257 static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf)
 
 259         struct fscpos_data *data = fscpos_update_device(dev);
 
 260         return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
 
 263 static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf)
 
 265         struct fscpos_data *data = fscpos_update_device(dev);
 
 266         return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
 
 270 static ssize_t show_wdog_control(struct fscpos_data *data, char *buf)
 
 272         /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
 
 273         return sprintf(buf, "%u\n", data->wdog_control & 0xb0);
 
 276 static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
 
 277                                 *data, const char *buf, size_t count, int reg)
 
 279         /* bits 0..3 reserved => mask with 0xf0 */
 
 280         unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
 
 282         mutex_lock(&data->update_lock);
 
 283         data->wdog_control &= ~0xf0;
 
 284         data->wdog_control |= v;
 
 285         fscpos_write_value(client, reg, data->wdog_control);
 
 286         mutex_unlock(&data->update_lock);
 
 290 static ssize_t show_wdog_state(struct fscpos_data *data, char *buf)
 
 292         /* bits 0, 2..7 reserved => mask with 0x02 */
 
 293         return sprintf(buf, "%u\n", data->wdog_state & 0x02);
 
 296 static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
 
 297                                 *data, const char *buf, size_t count, int reg)
 
 299         unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
 
 301         /* Valid values: 2 (clear) */
 
 303                 dev_err(&client->dev, "wdog_state value %ld not supported. "
 
 304                                         "Must be 2 to clear the state!\n", v);
 
 308         mutex_lock(&data->update_lock);
 
 309         data->wdog_state &= ~v;
 
 310         fscpos_write_value(client, reg, v);
 
 311         mutex_unlock(&data->update_lock);
 
 315 static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
 
 317         return sprintf(buf, "%u\n", data->wdog_preset);
 
 320 static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
 
 321                                 *data, const char *buf, size_t count, int reg)
 
 323         unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
 
 325         mutex_lock(&data->update_lock);
 
 326         data->wdog_preset = v;
 
 327         fscpos_write_value(client, reg, data->wdog_preset);
 
 328         mutex_unlock(&data->update_lock);
 
 333 static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf)
 
 335         /* bits 5..7 reserved => mask with 0x1f */
 
 336         struct fscpos_data *data = fscpos_update_device(dev);
 
 337         return sprintf(buf, "%u\n", data->global_event & 0x9b);
 
 343 #define create_getter(kind, sub) \
 
 344         static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
 
 346                 struct fscpos_data *data = fscpos_update_device(dev); \
 
 347                 return show_##kind##sub(data, buf); \
 
 350 #define create_getter_n(kind, offset, sub) \
 
 351         static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
 
 354                 struct fscpos_data *data = fscpos_update_device(dev); \
 
 355                 return show_##kind##sub(data, buf, offset); \
 
 358 #define create_setter(kind, sub, reg) \
 
 359         static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
 
 360                                                         *buf, size_t count) \
 
 362                 struct i2c_client *client = to_i2c_client(dev); \
 
 363                 struct fscpos_data *data = i2c_get_clientdata(client); \
 
 364                 return set_##kind##sub(client, data, buf, count, reg); \
 
 367 #define create_setter_n(kind, offset, sub, reg) \
 
 368         static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
 
 369                                         const char *buf, size_t count) \
 
 371                 struct i2c_client *client = to_i2c_client(dev); \
 
 372                 struct fscpos_data *data = i2c_get_clientdata(client); \
 
 373                 return set_##kind##sub(client, data, buf, count, offset, reg);\
 
 376 #define create_sysfs_device_ro(kind, sub, offset) \
 
 377         static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
 
 378                                         sysfs_show_##kind##offset##sub, NULL);
 
 380 #define create_sysfs_device_rw(kind, sub, offset) \
 
 381         static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
 
 382                 sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
 
 384 #define sysfs_ro_n(kind, sub, offset) \
 
 385         create_getter_n(kind, offset, sub); \
 
 386         create_sysfs_device_ro(kind, sub, offset);
 
 388 #define sysfs_rw_n(kind, sub, offset, reg) \
 
 389         create_getter_n(kind, offset, sub); \
 
 390         create_setter_n(kind, offset, sub, reg); \
 
 391         create_sysfs_device_rw(kind, sub, offset);
 
 393 #define sysfs_rw(kind, sub, reg) \
 
 394         create_getter(kind, sub); \
 
 395         create_setter(kind, sub, reg); \
 
 396         create_sysfs_device_rw(kind, sub,);
 
 398 #define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
 
 399         sysfs_fan(offset, reg_status, reg_ripple); \
 
 400         sysfs_rw_n(pwm,, offset, reg_min);
 
 402 #define sysfs_fan(offset, reg_status, reg_ripple) \
 
 403         sysfs_ro_n(fan, _input, offset); \
 
 404         sysfs_ro_n(fan, _status, offset); \
 
 405         sysfs_rw_n(fan, _ripple, offset, reg_ripple);
 
 407 #define sysfs_temp(offset, reg_status) \
 
 408         sysfs_ro_n(temp, _input, offset); \
 
 409         sysfs_ro_n(temp, _status, offset); \
 
 410         sysfs_rw_n(temp, _reset, offset, reg_status);
 
 412 #define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
 
 413         sysfs_rw(wdog, _control, reg_wdog_control); \
 
 414         sysfs_rw(wdog, _preset, reg_wdog_preset); \
 
 415         sysfs_rw(wdog, _state, reg_wdog_state);
 
 417 sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0],
 
 419 sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1],
 
 421 sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]);
 
 423 sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]);
 
 424 sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]);
 
 425 sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]);
 
 427 sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE,
 
 428                                                 FSCPOS_REG_WDOG_CONTROL);
 
 430 static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
 
 431 static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
 
 432 static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
 
 433 static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
 
 435 static int fscpos_attach_adapter(struct i2c_adapter *adapter)
 
 437         if (!(adapter->class & I2C_CLASS_HWMON))
 
 439         return i2c_probe(adapter, &addr_data, fscpos_detect);
 
 442 static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
 
 444         struct i2c_client *new_client;
 
 445         struct fscpos_data *data;
 
 448         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 
 452          * OK. For now, we presume we have a valid client. We now create the
 
 453          * client structure, even though we cannot fill it completely yet.
 
 454          * But it allows us to access fscpos_{read,write}_value.
 
 457         if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
 
 462         new_client = &data->client;
 
 463         i2c_set_clientdata(new_client, data);
 
 464         new_client->addr = address;
 
 465         new_client->adapter = adapter;
 
 466         new_client->driver = &fscpos_driver;
 
 467         new_client->flags = 0;
 
 469         /* Do the remaining detection unless force or force_fscpos parameter */
 
 471                 if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0)
 
 473                 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1)
 
 475                 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
 
 478                         dev_dbg(&new_client->dev, "fscpos detection failed\n");
 
 483         /* Fill in the remaining client fields and put it in the global list */
 
 484         strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
 
 487         mutex_init(&data->update_lock);
 
 489         /* Tell the I2C layer a new client has arrived */
 
 490         if ((err = i2c_attach_client(new_client)))
 
 493         /* Inizialize the fscpos chip */
 
 494         fscpos_init_client(new_client);
 
 496         /* Announce that the chip was found */
 
 497         dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
 
 499         /* Register sysfs hooks */
 
 500         data->class_dev = hwmon_device_register(&new_client->dev);
 
 501         if (IS_ERR(data->class_dev)) {
 
 502                 err = PTR_ERR(data->class_dev);
 
 506         device_create_file(&new_client->dev, &dev_attr_event);
 
 507         device_create_file(&new_client->dev, &dev_attr_in0_input);
 
 508         device_create_file(&new_client->dev, &dev_attr_in1_input);
 
 509         device_create_file(&new_client->dev, &dev_attr_in2_input);
 
 510         device_create_file(&new_client->dev, &dev_attr_wdog_control);
 
 511         device_create_file(&new_client->dev, &dev_attr_wdog_preset);
 
 512         device_create_file(&new_client->dev, &dev_attr_wdog_state);
 
 513         device_create_file(&new_client->dev, &dev_attr_temp1_input);
 
 514         device_create_file(&new_client->dev, &dev_attr_temp1_status);
 
 515         device_create_file(&new_client->dev, &dev_attr_temp1_reset);
 
 516         device_create_file(&new_client->dev, &dev_attr_temp2_input);
 
 517         device_create_file(&new_client->dev, &dev_attr_temp2_status);
 
 518         device_create_file(&new_client->dev, &dev_attr_temp2_reset);
 
 519         device_create_file(&new_client->dev, &dev_attr_temp3_input);
 
 520         device_create_file(&new_client->dev, &dev_attr_temp3_status);
 
 521         device_create_file(&new_client->dev, &dev_attr_temp3_reset);
 
 522         device_create_file(&new_client->dev, &dev_attr_fan1_input);
 
 523         device_create_file(&new_client->dev, &dev_attr_fan1_status);
 
 524         device_create_file(&new_client->dev, &dev_attr_fan1_ripple);
 
 525         device_create_file(&new_client->dev, &dev_attr_pwm1);
 
 526         device_create_file(&new_client->dev, &dev_attr_fan2_input);
 
 527         device_create_file(&new_client->dev, &dev_attr_fan2_status);
 
 528         device_create_file(&new_client->dev, &dev_attr_fan2_ripple);
 
 529         device_create_file(&new_client->dev, &dev_attr_pwm2);
 
 530         device_create_file(&new_client->dev, &dev_attr_fan3_input);
 
 531         device_create_file(&new_client->dev, &dev_attr_fan3_status);
 
 532         device_create_file(&new_client->dev, &dev_attr_fan3_ripple);
 
 537         i2c_detach_client(new_client);
 
 544 static int fscpos_detach_client(struct i2c_client *client)
 
 546         struct fscpos_data *data = i2c_get_clientdata(client);
 
 549         hwmon_device_unregister(data->class_dev);
 
 551         if ((err = i2c_detach_client(client)))
 
 557 static int fscpos_read_value(struct i2c_client *client, u8 reg)
 
 559         dev_dbg(&client->dev, "Read reg 0x%02x\n", reg);
 
 560         return i2c_smbus_read_byte_data(client, reg);
 
 563 static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
 
 565         dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value);
 
 566         return i2c_smbus_write_byte_data(client, reg, value);
 
 569 /* Called when we have found a new FSCPOS chip */
 
 570 static void fscpos_init_client(struct i2c_client *client)
 
 572         struct fscpos_data *data = i2c_get_clientdata(client);
 
 574         /* read revision from chip */
 
 575         data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION);
 
 578 static struct fscpos_data *fscpos_update_device(struct device *dev)
 
 580         struct i2c_client *client = to_i2c_client(dev);
 
 581         struct fscpos_data *data = i2c_get_clientdata(client);
 
 583         mutex_lock(&data->update_lock);
 
 585         if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
 
 588                 dev_dbg(&client->dev, "Starting fscpos update\n");
 
 590                 for (i = 0; i < 3; i++) {
 
 591                         data->temp_act[i] = fscpos_read_value(client,
 
 592                                                 FSCPOS_REG_TEMP_ACT[i]);
 
 593                         data->temp_status[i] = fscpos_read_value(client,
 
 594                                                 FSCPOS_REG_TEMP_STATE[i]);
 
 595                         data->fan_act[i] = fscpos_read_value(client,
 
 596                                                 FSCPOS_REG_FAN_ACT[i]);
 
 597                         data->fan_status[i] = fscpos_read_value(client,
 
 598                                                 FSCPOS_REG_FAN_STATE[i]);
 
 599                         data->fan_ripple[i] = fscpos_read_value(client,
 
 600                                                 FSCPOS_REG_FAN_RIPPLE[i]);
 
 602                                 /* fan2_min is not supported by the chip */
 
 603                                 data->pwm[i] = fscpos_read_value(client,
 
 606                         /* reset fan status if speed is back to > 0 */
 
 607                         if (data->fan_status[i] != 0 && data->fan_act[i] > 0) {
 
 608                                 reset_fan_alarm(client, i);
 
 612                 data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
 
 613                 data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
 
 614                 data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
 
 616                 data->wdog_preset = fscpos_read_value(client,
 
 617                                                         FSCPOS_REG_WDOG_PRESET);
 
 618                 data->wdog_state = fscpos_read_value(client,
 
 619                                                         FSCPOS_REG_WDOG_STATE);
 
 620                 data->wdog_control = fscpos_read_value(client,
 
 621                                                 FSCPOS_REG_WDOG_CONTROL);
 
 623                 data->global_event = fscpos_read_value(client,
 
 624                                                 FSCPOS_REG_EVENT_STATE);
 
 626                 data->last_updated = jiffies;
 
 629         mutex_unlock(&data->update_lock);
 
 633 static int __init sm_fscpos_init(void)
 
 635         return i2c_add_driver(&fscpos_driver);
 
 638 static void __exit sm_fscpos_exit(void)
 
 640         i2c_del_driver(&fscpos_driver);
 
 643 MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
 
 644                                 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
 
 645                                 " and Philip Edelbrock <phil@netroedge.com>");
 
 646 MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
 
 647 MODULE_LICENSE("GPL");
 
 649 module_init(sm_fscpos_init);
 
 650 module_exit(sm_fscpos_exit);