Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.22-rc7 667 lines 20 kB view raw
1/* 2 fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips 3 Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch> 4 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. 9 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. 14 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. 18*/ 19 20/* 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> 24 25 original module based on lm80.c 26 Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 27 and Philip Edelbrock <phil@netroedge.com> 28 29 Thanks to Jean Delvare for reviewing my code and suggesting a lot of 30 improvements. 31*/ 32 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> 42 43/* 44 * Addresses to scan 45 */ 46static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; 47 48/* 49 * Insmod parameters 50 */ 51I2C_CLIENT_INSMOD_1(fscpos); 52 53/* 54 * The FSCPOS registers 55 */ 56 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 62 63/* global control and status */ 64#define FSCPOS_REG_EVENT_STATE 0x04 65#define FSCPOS_REG_CONTROL 0x05 66 67/* watchdog */ 68#define FSCPOS_REG_WDOG_PRESET 0x28 69#define FSCPOS_REG_WDOG_STATE 0x23 70#define FSCPOS_REG_WDOG_CONTROL 0x21 71 72/* voltages */ 73#define FSCPOS_REG_VOLT_12 0x45 74#define FSCPOS_REG_VOLT_5 0x42 75#define FSCPOS_REG_VOLT_BATT 0x48 76 77/* fans - the chip does not support minimum speed for fan2 */ 78static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 }; 79static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab }; 80static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 }; 81static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf }; 82 83/* temperatures */ 84static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 }; 85static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 }; 86 87/* 88 * Functions declaration 89 */ 90static int fscpos_attach_adapter(struct i2c_adapter *adapter); 91static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); 92static int fscpos_detach_client(struct i2c_client *client); 93 94static int fscpos_read_value(struct i2c_client *client, u8 reg); 95static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value); 96static struct fscpos_data *fscpos_update_device(struct device *dev); 97static void fscpos_init_client(struct i2c_client *client); 98 99static void reset_fan_alarm(struct i2c_client *client, int nr); 100 101/* 102 * Driver data (common to all clients) 103 */ 104static struct i2c_driver fscpos_driver = { 105 .driver = { 106 .name = "fscpos", 107 }, 108 .id = I2C_DRIVERID_FSCPOS, 109 .attach_adapter = fscpos_attach_adapter, 110 .detach_client = fscpos_detach_client, 111}; 112 113/* 114 * Client data (each client gets its own) 115 */ 116struct fscpos_data { 117 struct i2c_client client; 118 struct class_device *class_dev; 119 struct mutex update_lock; 120 char valid; /* 0 until following fields are valid */ 121 unsigned long last_updated; /* In jiffies */ 122 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 */ 137}; 138 139/* Temperature */ 140#define TEMP_FROM_REG(val) (((val) - 128) * 1000) 141 142static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr) 143{ 144 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1])); 145} 146 147static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr) 148{ 149 /* bits 2..7 reserved => mask with 0x03 */ 150 return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03); 151} 152 153static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr) 154{ 155 return sprintf(buf, "1\n"); 156} 157 158static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data 159 *data, const char *buf, size_t count, int nr, int reg) 160{ 161 unsigned long v = simple_strtoul(buf, NULL, 10); 162 if (v != 1) { 163 dev_err(&client->dev, "temp_reset value %ld not supported. " 164 "Use 1 to reset the alarm!\n", v); 165 return -EINVAL; 166 } 167 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"); 171 172 /* Supported value: 2 (clears the status) */ 173 fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2); 174 return count; 175} 176 177/* Fans */ 178#define RPM_FROM_REG(val) ((val) * 60) 179 180static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr) 181{ 182 /* bits 0..1, 3..7 reserved => mask with 0x04 */ 183 return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04); 184} 185 186static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr) 187{ 188 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1])); 189} 190 191static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr) 192{ 193 /* bits 2..7 reserved => mask with 0x03 */ 194 return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03); 195} 196 197static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data 198 *data, const char *buf, size_t count, int nr, int reg) 199{ 200 /* supported values: 2, 4, 8 */ 201 unsigned long v = simple_strtoul(buf, NULL, 10); 202 203 switch (v) { 204 case 2: v = 1; break; 205 case 4: v = 2; break; 206 case 8: v = 3; break; 207 default: 208 dev_err(&client->dev, "fan_ripple value %ld not supported. " 209 "Must be one of 2, 4 or 8!\n", v); 210 return -EINVAL; 211 } 212 213 mutex_lock(&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; 217 218 fscpos_write_value(client, reg, data->fan_ripple[nr - 1]); 219 mutex_unlock(&data->update_lock); 220 return count; 221} 222 223static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr) 224{ 225 return sprintf(buf, "%u\n", data->pwm[nr - 1]); 226} 227 228static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data, 229 const char *buf, size_t count, int nr, int reg) 230{ 231 unsigned long v = simple_strtoul(buf, NULL, 10); 232 233 /* Range: 0..255 */ 234 if (v < 0) v = 0; 235 if (v > 255) v = 255; 236 237 mutex_lock(&data->update_lock); 238 data->pwm[nr - 1] = v; 239 fscpos_write_value(client, reg, data->pwm[nr - 1]); 240 mutex_unlock(&data->update_lock); 241 return count; 242} 243 244static void reset_fan_alarm(struct i2c_client *client, int nr) 245{ 246 fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4); 247} 248 249/* Volts */ 250#define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255) 251 252static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf) 253{ 254 struct fscpos_data *data = fscpos_update_device(dev); 255 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200)); 256} 257 258static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf) 259{ 260 struct fscpos_data *data = fscpos_update_device(dev); 261 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600)); 262} 263 264static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf) 265{ 266 struct fscpos_data *data = fscpos_update_device(dev); 267 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300)); 268} 269 270/* Watchdog */ 271static ssize_t show_wdog_control(struct fscpos_data *data, char *buf) 272{ 273 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */ 274 return sprintf(buf, "%u\n", data->wdog_control & 0xb0); 275} 276 277static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data 278 *data, const char *buf, size_t count, int reg) 279{ 280 /* bits 0..3 reserved => mask with 0xf0 */ 281 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; 282 283 mutex_lock(&data->update_lock); 284 data->wdog_control &= ~0xf0; 285 data->wdog_control |= v; 286 fscpos_write_value(client, reg, data->wdog_control); 287 mutex_unlock(&data->update_lock); 288 return count; 289} 290 291static ssize_t show_wdog_state(struct fscpos_data *data, char *buf) 292{ 293 /* bits 0, 2..7 reserved => mask with 0x02 */ 294 return sprintf(buf, "%u\n", data->wdog_state & 0x02); 295} 296 297static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data 298 *data, const char *buf, size_t count, int reg) 299{ 300 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; 301 302 /* Valid values: 2 (clear) */ 303 if (v != 2) { 304 dev_err(&client->dev, "wdog_state value %ld not supported. " 305 "Must be 2 to clear the state!\n", v); 306 return -EINVAL; 307 } 308 309 mutex_lock(&data->update_lock); 310 data->wdog_state &= ~v; 311 fscpos_write_value(client, reg, v); 312 mutex_unlock(&data->update_lock); 313 return count; 314} 315 316static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf) 317{ 318 return sprintf(buf, "%u\n", data->wdog_preset); 319} 320 321static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data 322 *data, const char *buf, size_t count, int reg) 323{ 324 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; 325 326 mutex_lock(&data->update_lock); 327 data->wdog_preset = v; 328 fscpos_write_value(client, reg, data->wdog_preset); 329 mutex_unlock(&data->update_lock); 330 return count; 331} 332 333/* Event */ 334static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf) 335{ 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); 339} 340 341/* 342 * Sysfs stuff 343 */ 344#define create_getter(kind, sub) \ 345 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \ 346 { \ 347 struct fscpos_data *data = fscpos_update_device(dev); \ 348 return show_##kind##sub(data, buf); \ 349 } 350 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\ 353 *buf) \ 354 { \ 355 struct fscpos_data *data = fscpos_update_device(dev); \ 356 return show_##kind##sub(data, buf, offset); \ 357 } 358 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) \ 362 { \ 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); \ 366 } 367 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) \ 371 { \ 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);\ 375 } 376 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); 380 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); 384 385#define sysfs_ro_n(kind, sub, offset) \ 386 create_getter_n(kind, offset, sub); \ 387 create_sysfs_device_ro(kind, sub, offset); 388 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); 393 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,); 398 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); 402 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); 407 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); 412 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); 417 418sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0], 419 FSCPOS_REG_PWM[0]); 420sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1], 421 FSCPOS_REG_PWM[1]); 422sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]); 423 424sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]); 425sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]); 426sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]); 427 428sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE, 429 FSCPOS_REG_WDOG_CONTROL); 430 431static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); 432static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL); 433static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); 434static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); 435 436static struct attribute *fscpos_attributes[] = { 437 &dev_attr_event.attr, 438 &dev_attr_in0_input.attr, 439 &dev_attr_in1_input.attr, 440 &dev_attr_in2_input.attr, 441 442 &dev_attr_wdog_control.attr, 443 &dev_attr_wdog_preset.attr, 444 &dev_attr_wdog_state.attr, 445 446 &dev_attr_temp1_input.attr, 447 &dev_attr_temp1_status.attr, 448 &dev_attr_temp1_reset.attr, 449 &dev_attr_temp2_input.attr, 450 &dev_attr_temp2_status.attr, 451 &dev_attr_temp2_reset.attr, 452 &dev_attr_temp3_input.attr, 453 &dev_attr_temp3_status.attr, 454 &dev_attr_temp3_reset.attr, 455 456 &dev_attr_fan1_input.attr, 457 &dev_attr_fan1_status.attr, 458 &dev_attr_fan1_ripple.attr, 459 &dev_attr_pwm1.attr, 460 &dev_attr_fan2_input.attr, 461 &dev_attr_fan2_status.attr, 462 &dev_attr_fan2_ripple.attr, 463 &dev_attr_pwm2.attr, 464 &dev_attr_fan3_input.attr, 465 &dev_attr_fan3_status.attr, 466 &dev_attr_fan3_ripple.attr, 467 NULL 468}; 469 470static const struct attribute_group fscpos_group = { 471 .attrs = fscpos_attributes, 472}; 473 474static int fscpos_attach_adapter(struct i2c_adapter *adapter) 475{ 476 if (!(adapter->class & I2C_CLASS_HWMON)) 477 return 0; 478 return i2c_probe(adapter, &addr_data, fscpos_detect); 479} 480 481static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) 482{ 483 struct i2c_client *new_client; 484 struct fscpos_data *data; 485 int err = 0; 486 487 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 488 goto exit; 489 490 /* 491 * OK. For now, we presume we have a valid client. We now create the 492 * client structure, even though we cannot fill it completely yet. 493 * But it allows us to access fscpos_{read,write}_value. 494 */ 495 496 if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { 497 err = -ENOMEM; 498 goto exit; 499 } 500 501 new_client = &data->client; 502 i2c_set_clientdata(new_client, data); 503 new_client->addr = address; 504 new_client->adapter = adapter; 505 new_client->driver = &fscpos_driver; 506 new_client->flags = 0; 507 508 /* Do the remaining detection unless force or force_fscpos parameter */ 509 if (kind < 0) { 510 if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) 511 != 0x50) /* 'P' */ 512 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) 513 != 0x45) /* 'E' */ 514 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) 515 != 0x47))/* 'G' */ 516 { 517 dev_dbg(&new_client->dev, "fscpos detection failed\n"); 518 goto exit_free; 519 } 520 } 521 522 /* Fill in the remaining client fields and put it in the global list */ 523 strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE); 524 525 data->valid = 0; 526 mutex_init(&data->update_lock); 527 528 /* Tell the I2C layer a new client has arrived */ 529 if ((err = i2c_attach_client(new_client))) 530 goto exit_free; 531 532 /* Inizialize the fscpos chip */ 533 fscpos_init_client(new_client); 534 535 /* Announce that the chip was found */ 536 dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); 537 538 /* Register sysfs hooks */ 539 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) 540 goto exit_detach; 541 542 data->class_dev = hwmon_device_register(&new_client->dev); 543 if (IS_ERR(data->class_dev)) { 544 err = PTR_ERR(data->class_dev); 545 goto exit_remove_files; 546 } 547 548 return 0; 549 550exit_remove_files: 551 sysfs_remove_group(&new_client->dev.kobj, &fscpos_group); 552exit_detach: 553 i2c_detach_client(new_client); 554exit_free: 555 kfree(data); 556exit: 557 return err; 558} 559 560static int fscpos_detach_client(struct i2c_client *client) 561{ 562 struct fscpos_data *data = i2c_get_clientdata(client); 563 int err; 564 565 hwmon_device_unregister(data->class_dev); 566 sysfs_remove_group(&client->dev.kobj, &fscpos_group); 567 568 if ((err = i2c_detach_client(client))) 569 return err; 570 kfree(data); 571 return 0; 572} 573 574static int fscpos_read_value(struct i2c_client *client, u8 reg) 575{ 576 dev_dbg(&client->dev, "Read reg 0x%02x\n", reg); 577 return i2c_smbus_read_byte_data(client, reg); 578} 579 580static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value) 581{ 582 dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value); 583 return i2c_smbus_write_byte_data(client, reg, value); 584} 585 586/* Called when we have found a new FSCPOS chip */ 587static void fscpos_init_client(struct i2c_client *client) 588{ 589 struct fscpos_data *data = i2c_get_clientdata(client); 590 591 /* read revision from chip */ 592 data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION); 593} 594 595static struct fscpos_data *fscpos_update_device(struct device *dev) 596{ 597 struct i2c_client *client = to_i2c_client(dev); 598 struct fscpos_data *data = i2c_get_clientdata(client); 599 600 mutex_lock(&data->update_lock); 601 602 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { 603 int i; 604 605 dev_dbg(&client->dev, "Starting fscpos update\n"); 606 607 for (i = 0; i < 3; i++) { 608 data->temp_act[i] = fscpos_read_value(client, 609 FSCPOS_REG_TEMP_ACT[i]); 610 data->temp_status[i] = fscpos_read_value(client, 611 FSCPOS_REG_TEMP_STATE[i]); 612 data->fan_act[i] = fscpos_read_value(client, 613 FSCPOS_REG_FAN_ACT[i]); 614 data->fan_status[i] = fscpos_read_value(client, 615 FSCPOS_REG_FAN_STATE[i]); 616 data->fan_ripple[i] = fscpos_read_value(client, 617 FSCPOS_REG_FAN_RIPPLE[i]); 618 if (i < 2) { 619 /* fan2_min is not supported by the chip */ 620 data->pwm[i] = fscpos_read_value(client, 621 FSCPOS_REG_PWM[i]); 622 } 623 /* reset fan status if speed is back to > 0 */ 624 if (data->fan_status[i] != 0 && data->fan_act[i] > 0) { 625 reset_fan_alarm(client, i); 626 } 627 } 628 629 data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12); 630 data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5); 631 data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT); 632 633 data->wdog_preset = fscpos_read_value(client, 634 FSCPOS_REG_WDOG_PRESET); 635 data->wdog_state = fscpos_read_value(client, 636 FSCPOS_REG_WDOG_STATE); 637 data->wdog_control = fscpos_read_value(client, 638 FSCPOS_REG_WDOG_CONTROL); 639 640 data->global_event = fscpos_read_value(client, 641 FSCPOS_REG_EVENT_STATE); 642 643 data->last_updated = jiffies; 644 data->valid = 1; 645 } 646 mutex_unlock(&data->update_lock); 647 return data; 648} 649 650static int __init sm_fscpos_init(void) 651{ 652 return i2c_add_driver(&fscpos_driver); 653} 654 655static void __exit sm_fscpos_exit(void) 656{ 657 i2c_del_driver(&fscpos_driver); 658} 659 660MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung " 661 "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>" 662 " and Philip Edelbrock <phil@netroedge.com>"); 663MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver"); 664MODULE_LICENSE("GPL"); 665 666module_init(sm_fscpos_init); 667module_exit(sm_fscpos_exit);