Changeset 4331
- Timestamp:
- 02/23/07 15:33:32 (2 years ago)
- Files:
-
- lm-sensors/trunk/CHANGES (modified) (2 diffs)
- lm-sensors/trunk/doc/chips/SUMMARY (modified) (1 diff)
- lm-sensors/trunk/doc/chips/smsc47m1 (modified) (2 diffs)
- lm-sensors/trunk/kernel/chips/smsc47m1.c (modified) (22 diffs)
- lm-sensors/trunk/lib/chips.c (modified) (2 diffs)
- lm-sensors/trunk/lib/chips.h (modified) (1 diff)
- lm-sensors/trunk/prog/sensors/chips.c (modified) (2 diffs)
- lm-sensors/trunk/prog/sensors/main.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lm-sensors/trunk/CHANGES
r4330 r4331 6 6 physical device. This change is required to survive the 7 7 planned struct class_dev removal from future 2.6 kernels. 8 Add support for the SMSC LPC47M292 fans (prefix smsc47m2) 8 9 Man page i2cdetect.8: Scanning range can be restricted 9 10 Module bmcsensors: Fix debugging messages … … 15 16 Module i2c-piix4: Add ATI SB600 support (2.6 backport) 16 17 Module i2c-viapro: Add CX700 support (2.6 backport) 18 Module smsc47m1: Add SMSC LPC47M292 support 17 19 Programs i2cdetect, i2cdump, isadump: Flush output in real time 20 Program sensors: Add smsc47m2 support (fans) 18 21 Program sensors-detect: Only probe relevant I2C addresses 19 22 Drop ARP-capable device detection lm-sensors/trunk/doc/chips/SUMMARY
r4259 r4331 221 221 smsc47m192 - - 2 2 no yes (LPC) 222 222 smsc47m997 - - 2 2 no yes (LPC) 223 (reported as a "smsc47m2") 224 smsc47m292 - - 3 3 no yes (LPC) 223 225 224 226 thmc50 lm-sensors/trunk/doc/chips/smsc47m1
r4218 r4331 17 17 http://www.smsc.com/main/tools/discontinued/47m15x.pdf 18 18 http://www.smsc.com/main/datasheets/47m192.pdf 19 * SMSC LPC47M292 20 Prefix: 'smsc47m2' 21 Addresses scanned: none, address read from Super I/O config space 22 Datasheet: Not public 19 23 * SMSC LPC47M997 20 24 Addresses scanned: none, address read from Super I/O config space … … 42 46 contain monitoring and PWM control circuitry for two fans. 43 47 44 The 47M15x and 47M192 chips contain a full 'hardware monitoring block'45 in addition to the fan monitoring and control. The hardware monitoring 46 block is not supported by the driver.48 The LPC47M15x, LPC47M192 and LPC47M292 chips contain a full 'hardware 49 monitoring block' in addition to the fan monitoring and control. The 50 hardware monitoring block is not supported by the driver. 47 51 48 52 No documentation is available for the 47M997, but it has the same device lm-sensors/trunk/kernel/chips/smsc47m1.c
r4218 r4331 39 39 static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; 40 40 41 SENSORS_INSMOD_1(smsc47m1); 41 SENSORS_INSMOD_2(smsc47m1, smsc47m2); 42 static u8 devid; 42 43 43 44 /* modified from kernel/include/traps.c */ … … 88 89 * The LPC47M997 is undocumented, but seems to be compatible with 89 90 * the LPC47M192, and has the same device id. 91 * The LPC47M292 (device id 0x6B) is somewhat compatible, but it 92 * supports a 3rd fan, and the pin configuration registers are 93 * unfortunately different. 90 94 */ 91 #define SMSC_DEVID_MATCH(id) ((id) == 0x51 || (id) == 0x59 || (id) == 0x5F || (id) == 0x60) 95 #define SMSC_DEVID_MATCH(id) ((id) == 0x51 || (id) == 0x59 || \ 96 (id) == 0x5F || (id) == 0x60 || \ 97 (id) == 0x6B) 92 98 93 99 #define SMSC_ACT_REG 0x30 … … 100 106 #define SMSC47M1_REG_TPIN1 0x34 101 107 #define SMSC47M1_REG_PPIN(nr) (0x37 - (nr)) 102 #define SMSC47M1_REG_PWM(nr) (0x55 + (nr))103 108 #define SMSC47M1_REG_FANDIV 0x58 104 #define SMSC47M1_REG_FAN(nr) (0x58 + (nr)) 105 #define SMSC47M1_REG_FAN_MIN(nr) (0x5a + (nr)) 109 110 static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 }; 111 static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b }; 112 static const u8 SMSC47M1_REG_FAN_MIN[3] = { 0x5b, 0x5c, 0x6c }; 113 114 #define SMSC47M2_REG_ALARM6 0x09 115 #define SMSC47M2_REG_TPIN3 0x2d 116 #define SMSC47M2_REG_TPIN2 0x37 117 #define SMSC47M2_REG_TPIN1 0x38 118 #define SMSC47M2_REG_FANDIV3 0x6a 106 119 107 120 static inline u8 MIN_TO_REG(long rpm, int div) … … 128 141 struct semaphore lock; 129 142 int sysctl_id; 143 enum chips type; 130 144 131 145 struct semaphore update_lock; … … 133 147 unsigned long last_updated; /* In jiffies */ 134 148 135 u8 fan[ 2]; /* Register value */136 u8 fan_min[ 2]; /* Register value */137 u8 fan_div[ 2]; /* Register encoding, shifted right */149 u8 fan[3]; /* Register value */ 150 u8 fan_min[3]; /* Register value */ 151 u8 fan_div[3]; /* Register encoding, shifted right */ 138 152 u8 alarms; /* Register encoding */ 139 u8 pwm[ 2]; /* Register value (bit 0 is disable) */153 u8 pwm[3]; /* Register value (bit 0 is disable) */ 140 154 }; 141 155 … … 173 187 #define SMSC47M1_SYSCTL_FAN1 1101 /* Rotations/min */ 174 188 #define SMSC47M1_SYSCTL_FAN2 1102 189 #define SMSC47M1_SYSCTL_FAN3 1103 175 190 #define SMSC47M1_SYSCTL_PWM1 1401 176 191 #define SMSC47M1_SYSCTL_PWM2 1402 192 #define SMSC47M1_SYSCTL_PWM3 1403 177 193 #define SMSC47M1_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ 178 194 #define SMSC47M1_SYSCTL_ALARMS 2004 /* bitvector */ … … 180 196 #define SMSC47M1_ALARM_FAN1 0x0001 181 197 #define SMSC47M1_ALARM_FAN2 0x0002 198 #define SMSC47M1_ALARM_FAN3 0x0004 182 199 183 200 /* -- SENSORS SYSCTL END -- */ … … 199 216 }; 200 217 218 static ctl_table smsc47m2_dir_table_template[] = { 219 {SMSC47M1_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, 220 &i2c_sysctl_real, NULL, &smsc47m1_fan}, 221 {SMSC47M1_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, 222 &i2c_sysctl_real, NULL, &smsc47m1_fan}, 223 {SMSC47M1_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, 224 &i2c_sysctl_real, NULL, &smsc47m1_fan}, 225 {SMSC47M1_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, 226 &i2c_sysctl_real, NULL, &smsc47m1_fan_div}, 227 {SMSC47M1_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, 228 &i2c_sysctl_real, NULL, &smsc47m1_alarms}, 229 {SMSC47M1_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, 230 &i2c_sysctl_real, NULL, &smsc47m1_pwm}, 231 {SMSC47M1_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, 232 &i2c_sysctl_real, NULL, &smsc47m1_pwm}, 233 {SMSC47M1_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, 234 &i2c_sysctl_real, NULL, &smsc47m1_pwm}, 235 {0} 236 }; 237 201 238 static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) 202 239 { … … 209 246 210 247 superio_enter(); 211 val= superio_inb(DEVID);212 if (!SMSC_DEVID_MATCH( val)) {248 devid = superio_inb(DEVID); 249 if (!SMSC_DEVID_MATCH(devid)) { 213 250 superio_exit(); 214 251 return -ENODEV; … … 238 275 struct smsc47m1_data *data; 239 276 int err = 0; 240 const char *type_name = "smsc47m1";241 const char *client_name = "47M1xx chip";277 const char *type_name; 278 const char *client_name; 242 279 243 280 if (!i2c_is_isa_adapter(adapter)) { … … 264 301 } 265 302 303 switch (devid) { 304 case 0x51: 305 kind = smsc47m1; 306 type_name = "smsc47m1"; 307 client_name = "LPC47B27x chip"; 308 break; 309 case 0x5F: 310 kind = smsc47m1; 311 type_name = "smsc47m1"; 312 client_name = "LPC47M14x chip"; 313 break; 314 case 0x60: 315 kind = smsc47m1; 316 type_name = "smsc47m1"; 317 client_name = "LPC47M192 chip"; 318 break; 319 case 0x6B: 320 kind = smsc47m2; 321 type_name = "smsc47m2"; 322 client_name = "LPC47M292 chip"; 323 break; 324 default: 325 kind = smsc47m1; 326 type_name = "smsc47m1"; 327 client_name = "LPC47M1xx chip"; 328 } 329 266 330 new_client = &data->client; 267 331 new_client->addr = address; … … 274 338 request_region(address, SMSC_EXTENT, "smsc47m1-fans"); 275 339 strcpy(new_client->name, client_name); 340 data->type = kind; 276 341 data->valid = 0; 277 342 init_MUTEX(&data->update_lock); … … 282 347 if ((i = i2c_register_entry((struct i2c_client *) new_client, 283 348 type_name, 284 smsc47m1_dir_table_template, 349 kind == smsc47m2 ? 350 smsc47m2_dir_table_template : 351 smsc47m1_dir_table_template, 285 352 THIS_MODULE)) < 0) { 286 353 err = i; … … 339 406 static void smsc47m1_init_client(struct i2c_client *client) 340 407 { 341 /* configure pins for tach function */ 342 smsc47m1_write_value(client, SMSC47M1_REG_TPIN1, 0x05); 343 smsc47m1_write_value(client, SMSC47M1_REG_TPIN2, 0x05); 408 struct smsc47m1_data *data = client->data; 409 u8 reg; 410 411 switch (data->type) { 412 case smsc47m2: 413 /* For the new LPC47M292 chip, I prefer to play it safe and 414 only report the pin configuration */ 415 reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN1); 416 if ((reg & 0x0d) != 0x09) 417 printk(KERN_NOTICE "smsc47m1: GP35 not configured for " 418 "fan input, ignore fan1 values\n"); 419 reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN2); 420 if ((reg & 0x0d) != 0x09) 421 printk(KERN_NOTICE "smsc47m1: GP34 not configured for " 422 "fan input, ignore fan2 values\n"); 423 reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN3); 424 if ((reg & 0x0d) != 0x0d) 425 printk(KERN_NOTICE "smsc47m1: GP33 not configured for " 426 "fan input, ignore fan3 values\n"); 427 break; 428 default: 429 /* configure pins for tach function */ 430 smsc47m1_write_value(client, SMSC47M1_REG_TPIN1, 0x05); 431 smsc47m1_write_value(client, SMSC47M1_REG_TPIN2, 0x05); 432 } 344 433 } 345 434 … … 347 436 { 348 437 struct smsc47m1_data *data = client->data; 349 int i;350 438 351 439 down(&data->update_lock); … … 353 441 if ((jiffies - data->last_updated > HZ + HZ / 2) || 354 442 (jiffies < data->last_updated) || !data->valid) { 355 for (i = 1; i <= 2; i++) { 356 data->fan[i - 1] = 357 smsc47m1_read_value(client, SMSC47M1_REG_FAN(i)); 358 data->fan_min[i - 1] = 359 smsc47m1_read_value(client, SMSC47M1_REG_FAN_MIN(i)); 360 data->pwm[i - 1] = 361 smsc47m1_read_value(client, SMSC47M1_REG_PWM(i)); 443 int i, fan_nr; 444 fan_nr = data->type == smsc47m2 ? 3 : 2; 445 446 for (i = 0; i < fan_nr; i++) { 447 data->fan[i] = 448 smsc47m1_read_value(client, SMSC47M1_REG_FAN[i]); 449 data->fan_min[i] = 450 smsc47m1_read_value(client, SMSC47M1_REG_FAN_MIN[i]); 451 data->pwm[i] = 452 smsc47m1_read_value(client, SMSC47M1_REG_PWM[i]); 362 453 } 363 454 … … 369 460 if(data->alarms) 370 461 smsc47m1_write_value(client, SMSC47M1_REG_ALARM1, 0xc0); 462 463 if (fan_nr >= 3) { 464 data->fan_div[2] = (smsc47m1_read_value(client, 465 SMSC47M2_REG_FANDIV3) >> 4) & 0x03; 466 data->alarms |= (smsc47m1_read_value(client, 467 SMSC47M2_REG_ALARM6) & 0x40) >> 4; 468 if (data->alarms & 0x04) 469 smsc47m1_write_value(client, 470 SMSC47M2_REG_ALARM6, 471 0x40); 472 } 473 371 474 data->last_updated = jiffies; 372 475 data->valid = 1; … … 381 484 { 382 485 struct smsc47m1_data *data = client->data; 383 int nr = ctl_name - SMSC47M1_SYSCTL_FAN1 + 1;486 int nr = ctl_name - SMSC47M1_SYSCTL_FAN1; 384 487 385 488 if (operation == SENSORS_PROC_REAL_INFO) … … 387 490 else if (operation == SENSORS_PROC_REAL_READ) { 388 491 smsc47m1_update_client(client); 389 results[0] = MIN_FROM_REG(data->fan_min[nr - 1],390 DIV_FROM_REG(data->fan_div[nr - 1]));391 results[1] = FAN_FROM_REG(data->fan[nr - 1],392 DIV_FROM_REG(data->fan_div[nr - 1]),393 data->fan_min[nr - 1]);492 results[0] = MIN_FROM_REG(data->fan_min[nr], 493 DIV_FROM_REG(data->fan_div[nr])); 494 results[1] = FAN_FROM_REG(data->fan[nr], 495 DIV_FROM_REG(data->fan_div[nr]), 496 data->fan_min[nr]); 394 497 *nrels_mag = 2; 395 498 } else if (operation == SENSORS_PROC_REAL_WRITE) { 396 499 if (*nrels_mag >= 1) { 397 data->fan_min[nr - 1] = MIN_TO_REG(results[0], 398 DIV_FROM_REG 399 (data-> 400 fan_div[nr-1])); 401 smsc47m1_write_value(client, SMSC47M1_REG_FAN_MIN(nr), 402 data->fan_min[nr - 1]); 500 data->fan_min[nr] = MIN_TO_REG(results[0], 501 DIV_FROM_REG(data->fan_div[nr])); 502 smsc47m1_write_value(client, SMSC47M1_REG_FAN_MIN[nr], 503 data->fan_min[nr]); 403 504 } 404 505 } … … 434 535 } else if (operation == SENSORS_PROC_REAL_WRITE) { 435 536 old = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); 537 if (*nrels_mag >= 3 && data->type == smsc47m2) { 538 data->fan_div[2] = DIV_TO_REG(results[2]); 539 smsc47m1_write_value(client, SMSC47M2_REG_FANDIV3, 540 (smsc47m1_read_value(client, 541 SMSC47M2_REG_FANDIV3) & 0xcf) 542 | (data->fan_div[2] << 4)); 543 } 436 544 if (*nrels_mag >= 2) { 437 545 data->fan_div[1] = DIV_TO_REG(results[1]); … … 450 558 { 451 559 struct smsc47m1_data *data = client->data; 452 int nr = 1 +ctl_name - SMSC47M1_SYSCTL_PWM1;560 int nr = ctl_name - SMSC47M1_SYSCTL_PWM1; 453 561 454 562 if (operation == SENSORS_PROC_REAL_INFO) … … 456 564 else if (operation == SENSORS_PROC_REAL_READ) { 457 565 smsc47m1_update_client(client); 458 results[0] = PWM_FROM_REG(data->pwm[nr - 1]);459 results[1] = !(data->pwm[nr - 1] & 0x01);566 results[0] = PWM_FROM_REG(data->pwm[nr]); 567 results[1] = !(data->pwm[nr] & 0x01); 460 568 *nrels_mag = 2; 461 569 } else if (operation == SENSORS_PROC_REAL_WRITE) { 462 570 if (*nrels_mag >= 1) { 463 data->pwm[nr - 1] = smsc47m1_read_value(client,464 SMSC47M1_REG_PWM (nr)) & 0x81;465 data->pwm[nr - 1] |= PWM_TO_REG(results[0]);571 data->pwm[nr] = smsc47m1_read_value(client, 572 SMSC47M1_REG_PWM[nr]) & 0x81; 573 data->pwm[nr] |= PWM_TO_REG(results[0]); 466 574 if (*nrels_mag >= 2) { 467 575 if (results[1]) { 468 576 /* enable PWM */ 469 data->pwm[nr - 1] &= 0xfe;577 data->pwm[nr] &= 0xfe; 470 578 } else { 471 579 /* disable PWM */ 472 data->pwm[nr - 1] |= 0x01;580 data->pwm[nr] |= 0x01; 473 581 } 474 582 } 475 smsc47m1_write_value(client, SMSC47M1_REG_PWM (nr),476 data->pwm[nr - 1]);583 smsc47m1_write_value(client, SMSC47M1_REG_PWM[nr], 584 data->pwm[nr]); 477 585 } 478 586 } lm-sensors/trunk/lib/chips.c
r4287 r4331 4665 4665 }; 4666 4666 4667 static sensors_chip_feature smsc47m2_features[] = 4668 { 4669 { { SENSORS_SMSC47M1_FAN1, "fan1", NOMAP, NOMAP, R }, 4670 SMSC47M1_SYSCTL_FAN1, VALUE(2), 0 }, 4671 { { SENSORS_SMSC47M1_FAN2, "fan2", NOMAP, NOMAP, R }, 4672 SMSC47M1_SYSCTL_FAN2, VALUE(2), 0 }, 4673 { { SENSORS_SMSC47M1_FAN3, "fan3", NOMAP, NOMAP, R }, 4674 SMSC47M1_SYSCTL_FAN3, VALUE(2), 0 }, 4675 { { SENSORS_SMSC47M1_FAN1_MIN, "fan1_min", SENSORS_SMSC47M1_FAN1, 4676 SENSORS_SMSC47M1_FAN1, RW }, 4677 SMSC47M1_SYSCTL_FAN1, VALUE(1), 0 }, 4678 { { SENSORS_SMSC47M1_FAN2_MIN, "fan2_min", SENSORS_SMSC47M1_FAN2, 4679 SENSORS_SMSC47M1_FAN2, RW }, 4680 SMSC47M1_SYSCTL_FAN2, VALUE(1), 0 }, 4681 { { SENSORS_SMSC47M1_FAN3_MIN, "fan3_min", SENSORS_SMSC47M1_FAN3, 4682 SENSORS_SMSC47M1_FAN3, RW }, 4683 SMSC47M1_SYSCTL_FAN3, VALUE(1), 0 }, 4684 { { SENSORS_SMSC47M1_FAN1_DIV, "fan1_div", SENSORS_SMSC47M1_FAN1, NOMAP, RW }, 4685 SMSC47M1_SYSCTL_FAN_DIV, VALUE(1), 0 }, 4686 { { SENSORS_SMSC47M1_FAN2_DIV, "fan2_div", SENSORS_SMSC47M1_FAN2, NOMAP, RW }, 4687 SMSC47M1_SYSCTL_FAN_DIV, VALUE(2), 0 }, 4688 { { SENSORS_SMSC47M1_FAN3_DIV, "fan3_div", SENSORS_SMSC47M1_FAN3, NOMAP, RW }, 4689 SMSC47M1_SYSCTL_FAN_DIV, VALUE(3), 0 }, 4690 { { SENSORS_SMSC47M1_ALARMS, "alarms", NOMAP, NOMAP, R }, 4691 SMSC47M1_SYSCTL_ALARMS, VALUE(1), 0 }, 4692 { { 0 }, 0 } 4693 }; 4694 4667 4695 static sensors_chip_feature smsc47m192_features[] = 4668 4696 { … … 6006 6034 { SENSORS_SMSC47M192_PREFIX, smsc47m192_features }, 6007 6035 { SENSORS_SMSC47M1_PREFIX, smsc47m1_features }, 6036 { SENSORS_SMSC47M2_PREFIX, smsc47m2_features }, 6008 6037 { SENSORS_PC87360_PREFIX, pc87360_features }, 6009 6038 { SENSORS_PC87363_PREFIX, pc87360_features }, lm-sensors/trunk/lib/chips.h
r4270 r4331 1835 1835 1836 1836 #define SENSORS_SMSC47M1_PREFIX "smsc47m1" 1837 #define SENSORS_SMSC47M2_PREFIX "smsc47m2" 1837 1838 1838 1839 #define SENSORS_SMSC47M1_FAN1 31 /* R */ 1839 1840 #define SENSORS_SMSC47M1_FAN2 32 /* R */ 1841 #define SENSORS_SMSC47M1_FAN3 33 /* R */ 1840 1842 #define SENSORS_SMSC47M1_FAN1_MIN 41 /* RW */ 1841 1843 #define SENSORS_SMSC47M1_FAN2_MIN 42 /* RW */ 1844 #define SENSORS_SMSC47M1_FAN3_MIN 43 /* RW */ 1842 1845 #define SENSORS_SMSC47M1_FAN1_DIV 75 /* RW */ 1843 1846 #define SENSORS_SMSC47M1_FAN2_DIV 76 /* RW */ 1847 #define SENSORS_SMSC47M1_FAN3_DIV 77 /* RW */ 1844 1848 #define SENSORS_SMSC47M1_ALARMS 81 /* R */ 1845 1849 lm-sensors/trunk/prog/sensors/chips.c
r4291 r4331 4596 4596 double cur, min, div; 4597 4597 int alarms, valid, i; 4598 int is_m2 = !strcmp(name->prefix, "smsc47m2"); 4598 4599 4599 4600 if (!sensors_get_feature(*name,SENSORS_SMSC47M1_ALARMS,&cur)) … … 4604 4605 } 4605 4606 4606 for (i =0; i<2; i++) { /* 2fans */4607 for (i = 0; i < (is_m2 ? 3 : 2); i++) { /* 2 or 3 fans */ 4607 4608 if (!sensors_get_label_and_valid(*name, SENSORS_SMSC47M1_FAN1+i, &label, &valid) 4608 4609 && !sensors_get_feature(*name, SENSORS_SMSC47M1_FAN1+i, &cur) lm-sensors/trunk/prog/sensors/main.c
r4270 r4331 392 392 { "smsc47m192", print_smsc47m192 }, 393 393 { "smsc47m1", print_smsc47m1 }, 394 { "smsc47m2", print_smsc47m1 }, 394 395 { "pc87360", print_pc87360 }, 395 396 { "pc87363", print_pc87360 },
