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.14 650 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 41/* 42 * Addresses to scan 43 */ 44static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; 45 46/* 47 * Insmod parameters 48 */ 49I2C_CLIENT_INSMOD_1(fscpos); 50 51/* 52 * The FSCPOS registers 53 */ 54 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 60 61/* global control and status */ 62#define FSCPOS_REG_EVENT_STATE 0x04 63#define FSCPOS_REG_CONTROL 0x05 64 65/* watchdog */ 66#define FSCPOS_REG_WDOG_PRESET 0x28 67#define FSCPOS_REG_WDOG_STATE 0x23 68#define FSCPOS_REG_WDOG_CONTROL 0x21 69 70/* voltages */ 71#define FSCPOS_REG_VOLT_12 0x45 72#define FSCPOS_REG_VOLT_5 0x42 73#define FSCPOS_REG_VOLT_BATT 0x48 74 75/* fans - the chip does not support minimum speed for fan2 */ 76static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 }; 77static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab }; 78static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 }; 79static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf }; 80 81/* temperatures */ 82static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 }; 83static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 }; 84 85/* 86 * Functions declaration 87 */ 88static int fscpos_attach_adapter(struct i2c_adapter *adapter); 89static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); 90static int fscpos_detach_client(struct i2c_client *client); 91 92static int fscpos_read_value(struct i2c_client *client, u8 register); 93static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value); 94static struct fscpos_data *fscpos_update_device(struct device *dev); 95static void fscpos_init_client(struct i2c_client *client); 96 97static void reset_fan_alarm(struct i2c_client *client, int nr); 98 99/* 100 * Driver data (common to all clients) 101 */ 102static struct i2c_driver fscpos_driver = { 103 .owner = THIS_MODULE, 104 .name = "fscpos", 105 .id = I2C_DRIVERID_FSCPOS, 106 .flags = I2C_DF_NOTIFY, 107 .attach_adapter = fscpos_attach_adapter, 108 .detach_client = fscpos_detach_client, 109}; 110 111/* 112 * Client data (each client gets its own) 113 */ 114struct fscpos_data { 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 */ 120 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 */ 135}; 136 137/* Temperature */ 138#define TEMP_FROM_REG(val) (((val) - 128) * 1000) 139 140static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr) 141{ 142 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1])); 143} 144 145static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr) 146{ 147 /* bits 2..7 reserved => mask with 0x03 */ 148 return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03); 149} 150 151static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr) 152{ 153 return sprintf(buf, "1\n"); 154} 155 156static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data 157 *data, const char *buf, size_t count, int nr, int reg) 158{ 159 unsigned long v = simple_strtoul(buf, NULL, 10); 160 if (v != 1) { 161 dev_err(&client->dev, "temp_reset value %ld not supported. " 162 "Use 1 to reset the alarm!\n", v); 163 return -EINVAL; 164 } 165 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"); 169 170 /* Supported value: 2 (clears the status) */ 171 fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2); 172 return count; 173} 174 175/* Fans */ 176#define RPM_FROM_REG(val) ((val) * 60) 177 178static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr) 179{ 180 /* bits 0..1, 3..7 reserved => mask with 0x04 */ 181 return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04); 182} 183 184static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr) 185{ 186 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1])); 187} 188 189static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr) 190{ 191 /* bits 2..7 reserved => mask with 0x03 */ 192 return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03); 193} 194 195static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data 196 *data, const char *buf, size_t count, int nr, int reg) 197{ 198 /* supported values: 2, 4, 8 */ 199 unsigned long v = simple_strtoul(buf, NULL, 10); 200 201 switch (v) { 202 case 2: v = 1; break; 203 case 4: v = 2; break; 204 case 8: v = 3; break; 205 default: 206 dev_err(&client->dev, "fan_ripple value %ld not supported. " 207 "Must be one of 2, 4 or 8!\n", v); 208 return -EINVAL; 209 } 210 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; 215 216 fscpos_write_value(client, reg, data->fan_ripple[nr - 1]); 217 up(&data->update_lock); 218 return count; 219} 220 221static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr) 222{ 223 return sprintf(buf, "%u\n", data->pwm[nr - 1]); 224} 225 226static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data, 227 const char *buf, size_t count, int nr, int reg) 228{ 229 unsigned long v = simple_strtoul(buf, NULL, 10); 230 231 /* Range: 0..255 */ 232 if (v < 0) v = 0; 233 if (v > 255) v = 255; 234 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); 239 return count; 240} 241 242static void reset_fan_alarm(struct i2c_client *client, int nr) 243{ 244 fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4); 245} 246 247/* Volts */ 248#define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255) 249 250static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf) 251{ 252 struct fscpos_data *data = fscpos_update_device(dev); 253 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200)); 254} 255 256static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf) 257{ 258 struct fscpos_data *data = fscpos_update_device(dev); 259 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600)); 260} 261 262static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf) 263{ 264 struct fscpos_data *data = fscpos_update_device(dev); 265 return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300)); 266} 267 268/* Watchdog */ 269static ssize_t show_wdog_control(struct fscpos_data *data, char *buf) 270{ 271 /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */ 272 return sprintf(buf, "%u\n", data->wdog_control & 0xb0); 273} 274 275static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data 276 *data, const char *buf, size_t count, int reg) 277{ 278 /* bits 0..3 reserved => mask with 0xf0 */ 279 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; 280 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); 286 return count; 287} 288 289static ssize_t show_wdog_state(struct fscpos_data *data, char *buf) 290{ 291 /* bits 0, 2..7 reserved => mask with 0x02 */ 292 return sprintf(buf, "%u\n", data->wdog_state & 0x02); 293} 294 295static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data 296 *data, const char *buf, size_t count, int reg) 297{ 298 unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; 299 300 /* Valid values: 2 (clear) */ 301 if (v != 2) { 302 dev_err(&client->dev, "wdog_state value %ld not supported. " 303 "Must be 2 to clear the state!\n", v); 304 return -EINVAL; 305 } 306 307 down(&data->update_lock); 308 data->wdog_state &= ~v; 309 fscpos_write_value(client, reg, v); 310 up(&data->update_lock); 311 return count; 312} 313 314static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf) 315{ 316 return sprintf(buf, "%u\n", data->wdog_preset); 317} 318 319static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data 320 *data, const char *buf, size_t count, int reg) 321{ 322 unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; 323 324 down(&data->update_lock); 325 data->wdog_preset = v; 326 fscpos_write_value(client, reg, data->wdog_preset); 327 up(&data->update_lock); 328 return count; 329} 330 331/* Event */ 332static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf) 333{ 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); 337} 338 339/* 340 * Sysfs stuff 341 */ 342#define create_getter(kind, sub) \ 343 static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \ 344 { \ 345 struct fscpos_data *data = fscpos_update_device(dev); \ 346 return show_##kind##sub(data, buf); \ 347 } 348 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\ 351 *buf) \ 352 { \ 353 struct fscpos_data *data = fscpos_update_device(dev); \ 354 return show_##kind##sub(data, buf, offset); \ 355 } 356 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) \ 360 { \ 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); \ 364 } 365 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) \ 369 { \ 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);\ 373 } 374 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); 378 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); 382 383#define sysfs_ro_n(kind, sub, offset) \ 384 create_getter_n(kind, offset, sub); \ 385 create_sysfs_device_ro(kind, sub, offset); 386 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); 391 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,); 396 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); 400 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); 405 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); 410 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); 415 416sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0], 417 FSCPOS_REG_PWM[0]); 418sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1], 419 FSCPOS_REG_PWM[1]); 420sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]); 421 422sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]); 423sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]); 424sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]); 425 426sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE, 427 FSCPOS_REG_WDOG_CONTROL); 428 429static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); 430static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL); 431static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); 432static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); 433 434static int fscpos_attach_adapter(struct i2c_adapter *adapter) 435{ 436 if (!(adapter->class & I2C_CLASS_HWMON)) 437 return 0; 438 return i2c_probe(adapter, &addr_data, fscpos_detect); 439} 440 441int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) 442{ 443 struct i2c_client *new_client; 444 struct fscpos_data *data; 445 int err = 0; 446 447 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 448 goto exit; 449 450 /* 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. 454 */ 455 456 if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { 457 err = -ENOMEM; 458 goto exit; 459 } 460 memset(data, 0, sizeof(struct fscpos_data)); 461 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; 468 469 /* Do the remaining detection unless force or force_fscpos parameter */ 470 if (kind < 0) { 471 if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) 472 != 0x50) /* 'P' */ 473 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) 474 != 0x45) /* 'E' */ 475 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) 476 != 0x47))/* 'G' */ 477 { 478 dev_dbg(&new_client->dev, "fscpos detection failed\n"); 479 goto exit_free; 480 } 481 } 482 483 /* Fill in the remaining client fields and put it in the global list */ 484 strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE); 485 486 data->valid = 0; 487 init_MUTEX(&data->update_lock); 488 489 /* Tell the I2C layer a new client has arrived */ 490 if ((err = i2c_attach_client(new_client))) 491 goto exit_free; 492 493 /* Inizialize the fscpos chip */ 494 fscpos_init_client(new_client); 495 496 /* Announce that the chip was found */ 497 dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); 498 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); 503 goto exit_detach; 504 } 505 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); 533 534 return 0; 535 536exit_detach: 537 i2c_detach_client(new_client); 538exit_free: 539 kfree(data); 540exit: 541 return err; 542} 543 544static int fscpos_detach_client(struct i2c_client *client) 545{ 546 struct fscpos_data *data = i2c_get_clientdata(client); 547 int err; 548 549 hwmon_device_unregister(data->class_dev); 550 551 if ((err = i2c_detach_client(client))) 552 return err; 553 kfree(data); 554 return 0; 555} 556 557static int fscpos_read_value(struct i2c_client *client, u8 reg) 558{ 559 dev_dbg(&client->dev, "Read reg 0x%02x\n", reg); 560 return i2c_smbus_read_byte_data(client, reg); 561} 562 563static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value) 564{ 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); 567} 568 569/* Called when we have found a new FSCPOS chip */ 570static void fscpos_init_client(struct i2c_client *client) 571{ 572 struct fscpos_data *data = i2c_get_clientdata(client); 573 574 /* read revision from chip */ 575 data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION); 576} 577 578static struct fscpos_data *fscpos_update_device(struct device *dev) 579{ 580 struct i2c_client *client = to_i2c_client(dev); 581 struct fscpos_data *data = i2c_get_clientdata(client); 582 583 down(&data->update_lock); 584 585 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { 586 int i; 587 588 dev_dbg(&client->dev, "Starting fscpos update\n"); 589 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]); 601 if (i < 2) { 602 /* fan2_min is not supported by the chip */ 603 data->pwm[i] = fscpos_read_value(client, 604 FSCPOS_REG_PWM[i]); 605 } 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); 609 } 610 } 611 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); 615 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); 622 623 data->global_event = fscpos_read_value(client, 624 FSCPOS_REG_EVENT_STATE); 625 626 data->last_updated = jiffies; 627 data->valid = 1; 628 } 629 up(&data->update_lock); 630 return data; 631} 632 633static int __init sm_fscpos_init(void) 634{ 635 return i2c_add_driver(&fscpos_driver); 636} 637 638static void __exit sm_fscpos_exit(void) 639{ 640 i2c_del_driver(&fscpos_driver); 641} 642 643MODULE_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>"); 646MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver"); 647MODULE_LICENSE("GPL"); 648 649module_init(sm_fscpos_init); 650module_exit(sm_fscpos_exit);