Changeset 121
- Timestamp:
- 12/26/98 02:18:58 (14 years ago)
- Location:
- lm-sensors/trunk
- Files:
-
- 5 modified
-
kernel/chips/w83781d.c (modified) (20 diffs)
-
kernel/include/sensors.h (modified) (2 diffs)
-
prog/sensors/chips.c (modified) (1 diff)
-
src/sensors.h (modified) (2 diffs)
-
src/w83781d.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lm-sensors/trunk/kernel/chips/w83781d.c
r96 r121 1 2 1 /* 3 2 w83781d.c - Part of lm_sensors, Linux kernel modules for hardware … … 53 52 #define W83781D_REG_FAN(nr) (0x27 + (nr)) 54 53 55 #define W83781D_REG_TEMP23 0x50 56 #define W83781D_REG_TEMP_HYST23 0x53 57 #define W83781D_REG_TEMP_CONFIG23 0x52 58 #define W83781D_REG_TEMP_OVER23 0x55 54 #define W83781D_REG_TEMP2 0x0150 55 #define W83781D_REG_TEMP3 0x0250 56 #define W83781D_REG_TEMP2_HYST 0x153 57 #define W83781D_REG_TEMP3_HYST 0x253 58 #define W83781D_REG_TEMP2_CONFIG 0x152 59 #define W83781D_REG_TEMP3_CONFIG 0x252 60 #define W83781D_REG_TEMP2_OVER 0x155 61 #define W83781D_REG_TEMP3_OVER 0x255 62 59 63 #define W83781D_REG_TEMP 0x27 60 64 #define W83781D_REG_TEMP_OVER 0x39 61 65 #define W83781D_REG_TEMP_HYST 0x3A 62 66 #define W83781D_REG_TEMP_CONFIG 0x52 63 #define W83781D_REG_ TEMP_SEL0x4E67 #define W83781D_REG_BANK 0x4E 64 68 65 69 #define W83781D_REG_CONFIG 0x40 … … 73 77 #define W83781D_REG_VID_FANDIV 0x47 74 78 75 #define W83781D_REG_CHIPID 0x58 79 #define W83781D_REG_CHIPID 0x49 80 #define W83781D_REG_WCHIPID 0x58 76 81 #define W83781D_REG_CHIPMAN 0x4F 82 #define W83781D_REG_PIN 0x4B 77 83 78 84 79 85 /* Conversions. Rounding is only done on the TO_REG variants. */ 80 static int w83781d_in_conv[7] = {10000, 10000, 10000, 16892, 38000, 81 -34768, -15050 }; 82 #define IN_TO_REG(val,nr) (((((val) * 100000 / w83781d_in_conv[nr]) + 8) / 16) \ 83 & 0xff) 84 #define IN_FROM_REG(val,nr) (((val) * 16 * w83781d_in_conv[nr]) / 100000) 85 86 #define FAN_TO_REG(val) ((val)==0?255:((1350000+(val))/((val)*2)) & 0xff) 87 #define FAN_FROM_REG(val) ((val)==0?-1:(val)==255?0:1350000/((val)*2)) 86 #define IN_TO_REG(val,nr) (((val) * 10 + 8)/16) 87 #define IN_FROM_REG(val,nr) (((val) * 16) / 10) 88 89 #define FAN_TO_REG(val,div) ((val)==0?255:((1350000+(val))/\ 90 ((val)*2*(div))) & 0xff) 91 #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*2*(div))) 88 92 89 93 #define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff) 90 94 #define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) 95 96 #define TEMP_ADD_TO_REG(val) (((((val) + 2) / 5) << 7) & 0xff80) 97 #define TEMP_ADD_FROM_REG(val) (((val) >> 7) * 5) 91 98 92 99 #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ 93 100 (val)>=0x06?0:205-(val)*5) 94 101 #define ALARMS_FROM_REG(val) (val) 102 #define BEEPS_FROM_REG(val) (val) 103 #define BEEPS_TO_REG(val) ((val) & 0xffff) 104 105 #define BEEP_ENABLE_TO_REG(val) (val) 106 #define BEEP_ENABLE_FROM_REG(val) ((val)?1:0) 95 107 96 108 #define DIV_FROM_REG(val) (1 << (val)) … … 101 113 #define W83781D_INIT_IN_1 (vid==350?280:vid) 102 114 #define W83781D_INIT_IN_2 330 103 #define W83781D_INIT_IN_3 500104 #define W83781D_INIT_IN_4 1200105 #define W83781D_INIT_IN_5 -1200106 #define W83781D_INIT_IN_6 -500115 #define W83781D_INIT_IN_3 (((500) * 100)/168) 116 #define W83781D_INIT_IN_4 (((1200) * 10)/38) 117 #define W83781D_INIT_IN_5 (((-1200) * -604)/2100) 118 #define W83781D_INIT_IN_6 (((-500) * -604)/909) 107 119 108 120 #define W83781D_INIT_IN_PERCENTAGE 10 109 121 110 122 #define W83781D_INIT_IN_MIN_0 \ 111 (W83781D_INIT_IN_0 - W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE / 100) 123 (W83781D_INIT_IN_0 - W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \ 124 / 100) 112 125 #define W83781D_INIT_IN_MAX_0 \ 113 (W83781D_INIT_IN_0 + W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE / 100) 126 (W83781D_INIT_IN_0 + W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \ 127 / 100) 114 128 #define W83781D_INIT_IN_MIN_1 \ 115 (W83781D_INIT_IN_1 - W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE / 100) 129 (W83781D_INIT_IN_1 - W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \ 130 / 100) 116 131 #define W83781D_INIT_IN_MAX_1 \ 117 (W83781D_INIT_IN_1 + W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE / 100) 132 (W83781D_INIT_IN_1 + W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \ 133 / 100) 118 134 #define W83781D_INIT_IN_MIN_2 \ 119 (W83781D_INIT_IN_2 - W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE / 100) 135 (W83781D_INIT_IN_2 - W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \ 136 / 100) 120 137 #define W83781D_INIT_IN_MAX_2 \ 121 (W83781D_INIT_IN_2 + W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE / 100) 138 (W83781D_INIT_IN_2 + W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \ 139 / 100) 122 140 #define W83781D_INIT_IN_MIN_3 \ 123 (W83781D_INIT_IN_3 - W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE / 100) 141 (W83781D_INIT_IN_3 - W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \ 142 / 100) 124 143 #define W83781D_INIT_IN_MAX_3 \ 125 (W83781D_INIT_IN_3 + W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE / 100) 144 (W83781D_INIT_IN_3 + W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \ 145 / 100) 126 146 #define W83781D_INIT_IN_MIN_4 \ 127 (W83781D_INIT_IN_4 - W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE / 100) 147 (W83781D_INIT_IN_4 - W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \ 148 / 100) 128 149 #define W83781D_INIT_IN_MAX_4 \ 129 (W83781D_INIT_IN_4 + W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE / 100) 150 (W83781D_INIT_IN_4 + W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \ 151 / 100) 130 152 #define W83781D_INIT_IN_MIN_5 \ 131 (W83781D_INIT_IN_5 - W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE / 100) 153 (W83781D_INIT_IN_5 - W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \ 154 / 100) 132 155 #define W83781D_INIT_IN_MAX_5 \ 133 (W83781D_INIT_IN_5 + W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE / 100) 156 (W83781D_INIT_IN_5 + W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \ 157 / 100) 134 158 #define W83781D_INIT_IN_MIN_6 \ 135 (W83781D_INIT_IN_6 - W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE / 100) 159 (W83781D_INIT_IN_6 - W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \ 160 / 100) 136 161 #define W83781D_INIT_IN_MAX_6 \ 137 (W83781D_INIT_IN_6 + W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE / 100) 162 (W83781D_INIT_IN_6 + W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \ 163 / 100) 138 164 139 165 #define W83781D_INIT_FAN_MIN_1 3000 … … 181 207 u8 fan[3]; /* Register value */ 182 208 u8 fan_min[3]; /* Register value */ 183 u8 temp[3]; /* Register value */ 184 u8 temp_over[3]; /* Register value */ 185 u8 temp_hyst[3]; /* Register value */ 186 u8 fan_div[2]; /* Register encoding, shifted right */ 209 u8 temp; 210 u8 temp_over; /* Register value */ 211 u8 temp_hyst; /* Register value */ 212 u8 temp_add[2]; /* Register value */ 213 u16 temp_add_over[2]; /* Register value */ 214 u16 temp_add_hyst[2]; /* Register value */ 215 u8 fan_div[3]; /* Register encoding, shifted right */ 187 216 u8 vid; /* Register encoding, combined */ 188 217 u16 alarms; /* Register encoding, combined */ 189 u8 beep[3]; /* Register value of config and interrupt masks */ 218 u16 beeps; /* Register encoding, combined */ 219 u8 beep_enable; /* Boolean */ 190 220 }; 191 221 … … 208 238 static void w83781d_dec_use (struct i2c_client *client); 209 239 210 static int w83781d_read_value(struct i2c_client *client, u8 register); 211 static int w83781d_write_value(struct i2c_client *client, u8 register, u8 value); 240 static int w83781d_read_value(struct i2c_client *client, u16 register); 241 static int w83781d_write_value(struct i2c_client *client, u16 register, 242 u16 value); 212 243 static void w83781d_update_client(struct i2c_client *client); 213 244 static void w83781d_init_client(struct i2c_client *client); … … 218 249 static void w83781d_fan(struct i2c_client *client, int operation, int ctl_name, 219 250 int *nrels_mag, long *results); 220 static void w83781d_temp(struct i2c_client *client, int operation, int ctl_name, 221 int *nrels_mag, long *results,int tempnum); 222 static void w83781d_temp1(struct i2c_client *client, int operation, int ctl_name, 223 int *nrels_mag, long *results); 224 static void w83781d_temp2(struct i2c_client *client, int operation, int ctl_name, 225 int *nrels_mag, long *results); 226 static void w83781d_temp3(struct i2c_client *client, int operation, int ctl_name, 227 int *nrels_mag, long *results); 251 static void w83781d_temp(struct i2c_client *client, int operation, 252 int ctl_name, int *nrels_mag, long *results); 253 static void w83781d_temp_add(struct i2c_client *client, int operation, 254 int ctl_name, int *nrels_mag, long *results); 228 255 static void w83781d_vid(struct i2c_client *client, int operation, int ctl_name, 229 int *nrels_mag, long *results);230 static void w83781d_alarms(struct i2c_client *client, int operation, int ctl_name,231 int *nrels_mag, long *results);256 int *nrels_mag, long *results); 257 static void w83781d_alarms(struct i2c_client *client, int operation, 258 int ctl_name, int *nrels_mag, long *results); 232 259 static void w83781d_beep(struct i2c_client *client, int operation, int ctl_name, 233 260 int *nrels_mag, long *results); 234 static void w83781d_fan_div(struct i2c_client *client, int operation, int ctl_name,235 int *nrels_mag, long *results);261 static void w83781d_fan_div(struct i2c_client *client, int operation, 262 int ctl_name, int *nrels_mag, long *results); 236 263 237 264 /* I choose here for semi-static W83781D allocation. Complete dynamic … … 284 311 { W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real, 285 312 &sensors_sysctl_real, NULL, &w83781d_fan }, 286 { W83781D_SYSCTL_TEMP , "temp", NULL, 0, 0644, NULL, &sensors_proc_real,287 &sensors_sysctl_real, NULL, &w83781d_temp 1},313 { W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &sensors_proc_real, 314 &sensors_sysctl_real, NULL, &w83781d_temp }, 288 315 { W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &sensors_proc_real, 289 &sensors_sysctl_real, NULL, &w83781d_temp 2},316 &sensors_sysctl_real, NULL, &w83781d_temp_add }, 290 317 { W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &sensors_proc_real, 291 &sensors_sysctl_real, NULL, &w83781d_temp 3},318 &sensors_sysctl_real, NULL, &w83781d_temp_add }, 292 319 { W83781D_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real, 293 320 &sensors_sysctl_real, NULL, &w83781d_vid }, … … 355 382 /* Real detection code goes here */ 356 383 357 outb_p(W83781D_REG_CHIPID,address + W83781D_ADDR_REG_OFFSET); 384 /* The Winbond may be stuck in bank 1 or 2. This should reset it. 385 We really need some nifty detection code, because this can lead 386 to a lot of problems if there is no Winbond present! */ 387 outb_p(W83781D_REG_BANK,address + W83781D_ADDR_REG_OFFSET); 388 outb_p(0x00,address + W83781D_DATA_REG_OFFSET); 389 390 outb_p(W83781D_REG_WCHIPID,address + W83781D_ADDR_REG_OFFSET); 358 391 err = inb_p(address + W83781D_DATA_REG_OFFSET) & 0xfe; 359 392 … … 461 494 continue; 462 495 463 err = smbus_read_byte_data(adapter,address,W83781D_REG_CHIPID); 496 smbus_write_byte_data(adapter,address,W83781D_REG_BANK,0x00); 497 498 err = smbus_read_byte_data(adapter,address,W83781D_REG_WCHIPID); 464 499 465 500 if (err == 0x20) { … … 600 635 601 636 602 /* The SMBus locks itself, but ISA access must be locked explicitely! 637 /* The SMBus locks itself, usually, but nothing may access the Winbond between 638 bank switches. ISA access must always be locked explicitely! 603 639 We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, 604 640 would slow down the W83781D access and should not be necessary. 605 641 There are some ugly typecasts here, but the good new is - they should 606 642 nowhere else be necessary! */ 607 int w83781d_read_value(struct i2c_client *client, u8 reg) 608 { 609 int res; 643 int w83781d_read_value(struct i2c_client *client, u16 reg) 644 { 645 int res,word_sized; 646 647 word_sized = (reg & 0x0ff) && (((reg && 0x00ff) == 0x50) || 648 ((reg && 0x00ff) == 0x53) || 649 ((reg && 0x00ff) == 0x55)); 650 down((struct semaphore *) (client->data)); 610 651 if (i2c_is_isa_client(client)) { 611 down((struct semaphore *) (client->data)); 612 outb_p(reg,(((struct isa_client *) client)->isa_addr) + 613 W83781D_ADDR_REG_OFFSET); 614 res = inb_p((((struct isa_client *) client)->isa_addr) + 652 if (reg & 0xff00) { 653 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 654 W83781D_ADDR_REG_OFFSET); 655 outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) + 656 W83781D_DATA_REG_OFFSET); 657 } 658 outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) + 659 W83781D_ADDR_REG_OFFSET); 660 res = inb_p((((struct isa_client *) client)->isa_addr) + 615 661 W83781D_DATA_REG_OFFSET); 616 up((struct semaphore *) (client->data)); 617 return res; 618 } else 619 return smbus_read_byte_data(client->adapter,client->addr, reg); 620 } 621 622 /* The SMBus locks itself, but ISA access muse be locked explicitely! 662 if (word_sized) { 663 outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) + 664 W83781D_ADDR_REG_OFFSET); 665 res = (res << 8) + inb_p((((struct isa_client *) client)->isa_addr) + 666 W83781D_DATA_REG_OFFSET); 667 } 668 if (reg & 0xff00) { 669 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 670 W83781D_ADDR_REG_OFFSET); 671 outb_p(0,(((struct isa_client *) client)->isa_addr) + 672 W83781D_DATA_REG_OFFSET); 673 } 674 } else { 675 if (reg & 0xff00) 676 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK, 677 reg >> 8); 678 res = smbus_read_byte_data(client->adapter,client->addr, reg); 679 if (word_sized) 680 res = (res << 8) + smbus_read_byte_data(client->adapter,client->addr, 681 reg); 682 if (reg & 0xff00) 683 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0); 684 } 685 up((struct semaphore *) (client->data)); 686 return res; 687 } 688 689 /* The SMBus locks itself, usually, but nothing may access the Winbond between 690 bank switches. ISA access must always be locked explicitely! 623 691 We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, 624 692 would slow down the W83781D access and should not be necessary. 625 693 There are some ugly typecasts here, but the good new is - they should 626 694 nowhere else be necessary! */ 627 int w83781d_write_value(struct i2c_client *client, u8 reg, u8 value) 628 { 695 int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) 696 { 697 int word_sized; 698 699 word_sized = (reg & 0x0ff) && (((reg && 0x00ff) == 0x50) || 700 ((reg && 0x00ff) == 0x53) || 701 ((reg && 0x00ff) == 0x55)); 702 down((struct semaphore *) (client->data)); 629 703 if (i2c_is_isa_client(client)) { 630 down((struct semaphore *) (client->data)); 631 outb_p(reg,((struct isa_client *) client)->isa_addr + W83781D_ADDR_REG_OFFSET); 632 outb_p(value,((struct isa_client *) client)->isa_addr + W83781D_DATA_REG_OFFSET); 633 up((struct semaphore *) (client->data)); 634 return 0; 635 } else 636 return smbus_write_byte_data(client->adapter, client->addr, reg,value); 704 if (reg & 0xff00) { 705 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 706 W83781D_ADDR_REG_OFFSET); 707 outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) + 708 W83781D_DATA_REG_OFFSET); 709 } 710 outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) + 711 W83781D_ADDR_REG_OFFSET); 712 if (word_sized) { 713 outb_p(value >> 8,(((struct isa_client *) client)->isa_addr) + 714 W83781D_DATA_REG_OFFSET); 715 outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) + 716 W83781D_ADDR_REG_OFFSET); 717 } 718 outb_p(value &0xff,(((struct isa_client *) client)->isa_addr) + 719 W83781D_DATA_REG_OFFSET); 720 if (reg & 0xff00) { 721 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 722 W83781D_ADDR_REG_OFFSET); 723 outb_p(0,(((struct isa_client *) client)->isa_addr) + 724 W83781D_DATA_REG_OFFSET); 725 } 726 } else { 727 if (reg & 0xff00) 728 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK, 729 reg >> 8); 730 if (word_sized) { 731 smbus_write_byte_data(client->adapter,client->addr, reg, value >> 8); 732 smbus_write_byte_data(client->adapter,client->addr, reg+1, value &0xff); 733 } else 734 smbus_write_byte_data(client->adapter,client->addr, reg, value &0xff); 735 if (reg & 0xff00) 736 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0); 737 } 738 up((struct semaphore *) (client->data)); 739 return 0; 637 740 } 638 741 … … 650 753 vid = VID_FROM_REG(vid); 651 754 652 w83781d_write_value(client,W83781D_REG_IN_MIN(0),IN_TO_REG(W83781D_INIT_IN_MIN_0,0)); 653 w83781d_write_value(client,W83781D_REG_IN_MAX(0),IN_TO_REG(W83781D_INIT_IN_MAX_0,0)); 654 w83781d_write_value(client,W83781D_REG_IN_MIN(1),IN_TO_REG(W83781D_INIT_IN_MIN_1,1)); 655 w83781d_write_value(client,W83781D_REG_IN_MAX(1),IN_TO_REG(W83781D_INIT_IN_MAX_1,1)); 656 w83781d_write_value(client,W83781D_REG_IN_MIN(2),IN_TO_REG(W83781D_INIT_IN_MIN_2,2)); 657 w83781d_write_value(client,W83781D_REG_IN_MAX(2),IN_TO_REG(W83781D_INIT_IN_MAX_2,2)); 658 w83781d_write_value(client,W83781D_REG_IN_MIN(3),IN_TO_REG(W83781D_INIT_IN_MIN_3,3)); 659 w83781d_write_value(client,W83781D_REG_IN_MAX(3),IN_TO_REG(W83781D_INIT_IN_MAX_3,3)); 660 w83781d_write_value(client,W83781D_REG_IN_MIN(4),IN_TO_REG(W83781D_INIT_IN_MIN_4,4)); 661 w83781d_write_value(client,W83781D_REG_IN_MAX(4),IN_TO_REG(W83781D_INIT_IN_MAX_4,4)); 662 w83781d_write_value(client,W83781D_REG_IN_MIN(5),IN_TO_REG(W83781D_INIT_IN_MIN_5,5)); 663 w83781d_write_value(client,W83781D_REG_IN_MAX(5),IN_TO_REG(W83781D_INIT_IN_MAX_5,5)); 664 w83781d_write_value(client,W83781D_REG_IN_MIN(6),IN_TO_REG(W83781D_INIT_IN_MIN_6,6)); 665 w83781d_write_value(client,W83781D_REG_IN_MAX(6),IN_TO_REG(W83781D_INIT_IN_MAX_6,6)); 666 w83781d_write_value(client,W83781D_REG_FAN_MIN(1),FAN_TO_REG(W83781D_INIT_FAN_MIN_1)); 667 w83781d_write_value(client,W83781D_REG_FAN_MIN(2),FAN_TO_REG(W83781D_INIT_FAN_MIN_2)); 668 w83781d_write_value(client,W83781D_REG_FAN_MIN(3),FAN_TO_REG(W83781D_INIT_FAN_MIN_3)); 669 /* Init Temp Sensor1 */ 670 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x00);/* Switch Banks! */ 671 w83781d_write_value(client,W83781D_REG_TEMP_OVER,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 672 w83781d_write_value(client,W83781D_REG_TEMP_HYST,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 755 w83781d_write_value(client,W83781D_REG_IN_MIN(0), 756 IN_TO_REG(W83781D_INIT_IN_MIN_0,0)); 757 w83781d_write_value(client,W83781D_REG_IN_MAX(0), 758 IN_TO_REG(W83781D_INIT_IN_MAX_0,0)); 759 w83781d_write_value(client,W83781D_REG_IN_MIN(1), 760 IN_TO_REG(W83781D_INIT_IN_MIN_1,1)); 761 w83781d_write_value(client,W83781D_REG_IN_MAX(1), 762 IN_TO_REG(W83781D_INIT_IN_MAX_1,1)); 763 w83781d_write_value(client,W83781D_REG_IN_MIN(2), 764 IN_TO_REG(W83781D_INIT_IN_MIN_2,2)); 765 w83781d_write_value(client,W83781D_REG_IN_MAX(2), 766 IN_TO_REG(W83781D_INIT_IN_MAX_2,2)); 767 w83781d_write_value(client,W83781D_REG_IN_MIN(3), 768 IN_TO_REG(W83781D_INIT_IN_MIN_3,3)); 769 w83781d_write_value(client,W83781D_REG_IN_MAX(3), 770 IN_TO_REG(W83781D_INIT_IN_MAX_3,3)); 771 w83781d_write_value(client,W83781D_REG_IN_MIN(4), 772 IN_TO_REG(W83781D_INIT_IN_MIN_4,4)); 773 w83781d_write_value(client,W83781D_REG_IN_MAX(4), 774 IN_TO_REG(W83781D_INIT_IN_MAX_4,4)); 775 w83781d_write_value(client,W83781D_REG_IN_MIN(5), 776 IN_TO_REG(W83781D_INIT_IN_MIN_5,5)); 777 w83781d_write_value(client,W83781D_REG_IN_MAX(5), 778 IN_TO_REG(W83781D_INIT_IN_MAX_5,5)); 779 w83781d_write_value(client,W83781D_REG_IN_MIN(6), 780 IN_TO_REG(W83781D_INIT_IN_MIN_6,6)); 781 w83781d_write_value(client,W83781D_REG_IN_MAX(6), 782 IN_TO_REG(W83781D_INIT_IN_MAX_6,6)); 783 w83781d_write_value(client,W83781D_REG_FAN_MIN(1), 784 FAN_TO_REG(W83781D_INIT_FAN_MIN_1,2)); 785 w83781d_write_value(client,W83781D_REG_FAN_MIN(2), 786 FAN_TO_REG(W83781D_INIT_FAN_MIN_2,2)); 787 w83781d_write_value(client,W83781D_REG_FAN_MIN(3), 788 FAN_TO_REG(W83781D_INIT_FAN_MIN_3,2)); 789 790 w83781d_write_value(client,W83781D_REG_TEMP_OVER, 791 TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 792 w83781d_write_value(client,W83781D_REG_TEMP_HYST, 793 TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 673 794 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG,0x00); 674 /* Init Temp Sensor2 */ 675 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x01);/* Switch Banks! */ 676 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 677 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 678 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 679 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 680 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG23,0x00); 681 /* Init Temp Sensor3 */ 682 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x02);/* Switch Banks! */ 683 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 684 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 685 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 686 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 687 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG23,0x00); 688 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x00);/* Switch Banks! */ 795 796 w83781d_write_value(client,W83781D_REG_TEMP2_OVER, 797 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_OVER)); 798 w83781d_write_value(client,W83781D_REG_TEMP2_HYST, 799 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_HYST)); 800 w83781d_write_value(client,W83781D_REG_TEMP2_CONFIG,0x00); 801 802 w83781d_write_value(client,W83781D_REG_TEMP3_OVER, 803 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_OVER)); 804 w83781d_write_value(client,W83781D_REG_TEMP3_HYST, 805 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_HYST)); 806 w83781d_write_value(client,W83781D_REG_TEMP3_CONFIG,0x00); 689 807 690 808 /* Start monitoring */ 691 809 w83781d_write_value(client,W83781D_REG_CONFIG, 692 (w83781d_read_value(client, W83781D_REG_CONFIG) & 0xf7) | 0x01);693 810 (w83781d_read_value(client, 811 W83781D_REG_CONFIG) & 0xf7) | 0x01); 694 812 } 695 813 … … 716 834 data->fan_min[i-1] = w83781d_read_value(client,W83781D_REG_FAN_MIN(i)); 717 835 } 718 data->temp[0] = w83781d_read_value(client,W83781D_REG_TEMP); 719 data->temp_over[0] = w83781d_read_value(client,W83781D_REG_TEMP_OVER); 720 data->temp_hyst[0] = w83781d_read_value(client,W83781D_REG_TEMP_HYST); 721 w83781d_write_value(client,W83781D_REG_TEMP_SEL,1);/* Switch Banks!! */ 722 data->temp[1] = w83781d_read_value(client,W83781D_REG_TEMP23); 723 data->temp_over[1] = w83781d_read_value(client,W83781D_REG_TEMP_OVER23); 724 data->temp_hyst[1] = w83781d_read_value(client,W83781D_REG_TEMP_HYST23); 725 w83781d_write_value(client,W83781D_REG_TEMP_SEL,2);/* Switch Banks!! */ 726 data->temp[2] = w83781d_read_value(client,W83781D_REG_TEMP23); 727 data->temp_over[2] = w83781d_read_value(client,W83781D_REG_TEMP_OVER23); 728 data->temp_hyst[2] = w83781d_read_value(client,W83781D_REG_TEMP_HYST23); 729 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0);/* Switch Banks!! */ 836 data->temp = w83781d_read_value(client,W83781D_REG_TEMP); 837 data->temp_over = w83781d_read_value(client,W83781D_REG_TEMP_OVER); 838 data->temp_hyst = w83781d_read_value(client,W83781D_REG_TEMP_HYST); 839 data->temp_add[0] = w83781d_read_value(client,W83781D_REG_TEMP2); 840 data->temp_add_over[0] = w83781d_read_value(client,W83781D_REG_TEMP2_OVER); 841 data->temp_add_hyst[0] = w83781d_read_value(client,W83781D_REG_TEMP2_HYST); 842 data->temp_add[1] = w83781d_read_value(client,W83781D_REG_TEMP3); 843 data->temp_add_over[1] = w83781d_read_value(client,W83781D_REG_TEMP3_OVER); 844 data->temp_add_hyst[1] = w83781d_read_value(client,W83781D_REG_TEMP3_HYST); 730 845 i = w83781d_read_value(client,W83781D_REG_VID_FANDIV); 731 846 data->vid = i & 0x0f; … … 733 848 data->fan_div[0] = (i >> 4) & 0x03; 734 849 data->fan_div[1] = i >> 6; 850 data->fan_div[2] = (w83781d_read_value(client,W83781D_REG_PIN) >> 6) & 0x03; 735 851 data->alarms = w83781d_read_value(client,W83781D_REG_ALARM1) + 736 (w83781d_read_value(client,W83781D_REG_ALARM2) >> 8); 737 data->beep[0] = w83781d_read_value(client,W83781D_REG_BEEP_CONFIG); 738 data->beep[1] = w83781d_read_value(client,W83781D_REG_BEEP_INTS1); 739 data->beep[2] = w83781d_read_value(client,W83781D_REG_BEEP_INTS2); 852 (w83781d_read_value(client,W83781D_REG_ALARM2) << 8); 853 i = w83781d_read_value(client,W83781D_REG_BEEP_INTS2); 854 data->beep_enable = i >> 7; 855 data->beeps = ((i & 0x7f) << 8) + 856 w83781d_read_value(client,W83781D_REG_BEEP_INTS1); 740 857 data->last_updated = jiffies; 741 858 data->valid = 1; … … 795 912 else if (operation == SENSORS_PROC_REAL_READ) { 796 913 w83781d_update_client(client); 797 results[0] = FAN_FROM_REG(data->fan_min[nr-1] );798 results[1] = FAN_FROM_REG(data->fan[nr-1] );914 results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]); 915 results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]); 799 916 *nrels_mag = 2; 800 917 } else if (operation == SENSORS_PROC_REAL_WRITE) { 801 918 if (*nrels_mag >= 1) { 802 data->fan_min[nr-1] = FAN_TO_REG(results[0] );919 data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]); 803 920 w83781d_write_value(client,W83781D_REG_FAN_MIN(nr),data->fan_min[nr-1]); 804 921 } … … 808 925 809 926 void w83781d_temp(struct i2c_client *client, int operation, int ctl_name, 810 int *nrels_mag, long *results ,int tempnum)927 int *nrels_mag, long *results) 811 928 { 812 929 struct w83781d_data *data = client->data; … … 815 932 else if (operation == SENSORS_PROC_REAL_READ) { 816 933 w83781d_update_client(client); 817 results[0] = TEMP_FROM_REG(data->temp_over [tempnum - 1]);818 results[1] = TEMP_FROM_REG(data->temp_hyst [tempnum - 1]);819 results[2] = TEMP_FROM_REG(data->temp [tempnum - 1]);934 results[0] = TEMP_FROM_REG(data->temp_over); 935 results[1] = TEMP_FROM_REG(data->temp_hyst); 936 results[2] = TEMP_FROM_REG(data->temp); 820 937 *nrels_mag = 3; 821 938 } else if (operation == SENSORS_PROC_REAL_WRITE) { 822 if (tempnum == 3) { 823 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x02);/* Switch Banks!! */ 824 if (*nrels_mag >= 1) { 825 data->temp_over[2] = TEMP_TO_REG(results[0]); 826 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,data->temp_over[2]); 827 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 828 } 829 if (*nrels_mag >= 2) { 830 data->temp_hyst[2] = TEMP_TO_REG(results[1]); 831 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,data->temp_hyst[2]); 832 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 833 } 834 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x0);/* Switch Banks!! */ 835 } else if (tempnum == 2) { 836 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x01);/* Switch Banks!! */ 837 if (*nrels_mag >= 1) { 838 data->temp_over[1] = TEMP_TO_REG(results[0]); 839 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,data->temp_over[1]); 840 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 841 } 842 if (*nrels_mag >= 2) { 843 data->temp_hyst[1] = TEMP_TO_REG(results[1]); 844 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,data->temp_hyst[1]); 845 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 846 } 847 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x0);/* Switch Banks!! */ 848 } else { 849 if (*nrels_mag >= 1) { 850 data->temp_over[0] = TEMP_TO_REG(results[0]); 851 w83781d_write_value(client,W83781D_REG_TEMP_OVER,data->temp_over[0]); 852 } 853 if (*nrels_mag >= 2) { 854 data->temp_hyst[0] = TEMP_TO_REG(results[1]); 855 w83781d_write_value(client,W83781D_REG_TEMP_HYST,data->temp_hyst[0]); 856 } 857 } 858 } 859 } 860 861 862 void w83781d_temp1(struct i2c_client *client, int operation, int ctl_name, 863 int *nrels_mag, long *results) { 864 865 w83781d_temp(client,operation,ctl_name,nrels_mag,results,1); 866 } 867 868 869 void w83781d_temp2(struct i2c_client *client, int operation, int ctl_name, 870 int *nrels_mag, long *results) { 871 872 w83781d_temp(client,operation,ctl_name,nrels_mag,results,2); 873 } 874 875 876 void w83781d_temp3(struct i2c_client *client, int operation, int ctl_name, 877 int *nrels_mag, long *results) { 878 879 w83781d_temp(client,operation,ctl_name,nrels_mag,results,3); 939 if (*nrels_mag >= 1) { 940 data->temp_over = TEMP_TO_REG(results[0]); 941 w83781d_write_value(client,W83781D_REG_TEMP_OVER,data->temp_over); 942 } 943 if (*nrels_mag >= 2) { 944 data->temp_hyst = TEMP_TO_REG(results[1]); 945 w83781d_write_value(client,W83781D_REG_TEMP_HYST,data->temp_hyst); 946 } 947 } 948 } 949 950 951 void w83781d_temp_add(struct i2c_client *client, int operation, int ctl_name, 952 int *nrels_mag, long *results) 953 { 954 struct w83781d_data *data = client->data; 955 int nr = ctl_name - W83781D_SYSCTL_TEMP2; 956 957 if (operation == SENSORS_PROC_REAL_INFO) 958 *nrels_mag = 1; 959 else if (operation == SENSORS_PROC_REAL_READ) { 960 w83781d_update_client(client); 961 results[0] = TEMP_ADD_FROM_REG(data->temp_add_over[nr]); 962 results[1] = TEMP_ADD_FROM_REG(data->temp_add_hyst[nr]); 963 results[2] = TEMP_ADD_FROM_REG(data->temp_add[nr]); 964 *nrels_mag = 3; 965 } else if (operation == SENSORS_PROC_REAL_WRITE) { 966 if (*nrels_mag >= 1) { 967 data->temp_add_over[nr] = TEMP_ADD_TO_REG(results[0]); 968 w83781d_write_value(client, 969 nr?W83781D_REG_TEMP3_OVER:W83781D_REG_TEMP2_OVER, 970 data->temp_add_over[nr]); 971 } 972 if (*nrels_mag >= 2) { 973 data->temp_add_hyst[nr] = TEMP_ADD_TO_REG(results[1]); 974 w83781d_write_value(client, 975 nr?W83781D_REG_TEMP3_HYST:W83781D_REG_TEMP2_HYST, 976 data->temp_add_hyst[nr]); 977 } 978 } 880 979 } 881 980 … … 911 1010 { 912 1011 struct w83781d_data *data = client->data; 1012 int val; 1013 913 1014 if (operation == SENSORS_PROC_REAL_INFO) 914 1015 *nrels_mag = 0; 915 1016 else if (operation == SENSORS_PROC_REAL_READ) { 916 1017 w83781d_update_client(client); 917 results[0] = data->beep[0]; 918 results[1] = data->beep[1]; 919 results[2] = data->beep[2]; 920 *nrels_mag = 3; 1018 results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); 1019 results[1] = BEEPS_FROM_REG(data->beeps); 1020 *nrels_mag = 2; 921 1021 } else if (operation == SENSORS_PROC_REAL_WRITE) { 922 data->beep[0] = results[0]; 923 w83781d_write_value(client,W83781D_REG_BEEP_CONFIG,data->beep[0]); 924 data->beep[1] = results[1]; 925 w83781d_write_value(client,W83781D_REG_BEEP_INTS1,data->beep[1]); 926 data->beep[2] = results[2]; 927 w83781d_write_value(client,W83781D_REG_BEEP_INTS2,data->beep[2]); 1022 if (*nrels_mag >= 2) { 1023 data->beeps = BEEPS_TO_REG(results[1]); 1024 w83781d_write_value(client,W83781D_REG_BEEP_INTS1,data->beeps & 0xff); 1025 val = data->beeps >> 8; 1026 } else if (*nrels_mag >= 1) 1027 val = w83781d_read_value(client,W83781D_REG_BEEP_INTS1) & 0x7f; 1028 if (*nrels_mag >= 1) { 1029 data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); 1030 w83781d_write_value(client,W83781D_REG_BEEP_INTS2, 1031 val | data->beep_enable << 7); 1032 } 928 1033 } 929 1034 } … … 941 1046 results[0] = DIV_FROM_REG(data->fan_div[0]); 942 1047 results[1] = DIV_FROM_REG(data->fan_div[1]); 943 results[2] = 2;1048 results[2] = DIV_FROM_REG(data->fan_div[2]); 944 1049 *nrels_mag = 3; 945 1050 } else if (operation == SENSORS_PROC_REAL_WRITE) { … … 954 1059 w83781d_write_value(client,W83781D_REG_VID_FANDIV,old); 955 1060 } 1061 if (*nrels_mag >= 3) { 1062 data->fan_div[2] = DIV_TO_REG(results[2]); 1063 w83781d_write_value(client,W83781D_REG_PIN, 1064 w83781d_read_value(client,W83781D_REG_PIN)); 1065 } 956 1066 } 957 1067 } -
lm-sensors/trunk/kernel/include/sensors.h
r115 r121 145 145 #define W83781D_SYSCTL_FAN2 1102 146 146 #define W83781D_SYSCTL_FAN3 1103 147 #define W83781D_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */147 #define W83781D_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ 148 148 #define W83781D_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ 149 149 #define W83781D_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ … … 163 163 #define W83781D_ALARM_FAN2 0x0080 164 164 #define W83781D_ALARM_FAN3 0x0800 165 #define W83781D_ALARM_TEMP 0x0010166 #define W83781D_ALARM_ BTI0x0020165 #define W83781D_ALARM_TEMP1 0x0010 166 #define W83781D_ALARM_TEMP23 0x0020 167 167 #define W83781D_ALARM_CHAS 0x1000 168 #define W83781D_ALARM_FIFO 0x2000169 #define W83781D_ALARM_SMI_IN 0x4000170 168 171 169 #define LM75_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ -
lm-sensors/trunk/prog/sensors/chips.c
r117 r121 509 509 !sensors_get_feature(*name,SENSORS_LM80_TEMP_OS_MAX,&max2)) { 510 510 print_label(label,10); 511 printf("%+3. 0f C (hot:limit = %+3.0f C, hysteris = %+3.0f C) %s\n",511 printf("%+3.2f C (hot:limit = %+3.0f C, hysteris = %+3.0f C) %s\n", 512 512 cur,max,min, alarms&LM80_ALARM_TEMP_HOT?"ALARM":""); 513 513 printf(" (os: limit = %+3.0f C, hysteris = %+3.0f C) %s\n", -
lm-sensors/trunk/src/sensors.h
r115 r121 145 145 #define W83781D_SYSCTL_FAN2 1102 146 146 #define W83781D_SYSCTL_FAN3 1103 147 #define W83781D_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */147 #define W83781D_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ 148 148 #define W83781D_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ 149 149 #define W83781D_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ … … 163 163 #define W83781D_ALARM_FAN2 0x0080 164 164 #define W83781D_ALARM_FAN3 0x0800 165 #define W83781D_ALARM_TEMP 0x0010166 #define W83781D_ALARM_ BTI0x0020165 #define W83781D_ALARM_TEMP1 0x0010 166 #define W83781D_ALARM_TEMP23 0x0020 167 167 #define W83781D_ALARM_CHAS 0x1000 168 #define W83781D_ALARM_FIFO 0x2000169 #define W83781D_ALARM_SMI_IN 0x4000170 168 171 169 #define LM75_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ -
lm-sensors/trunk/src/w83781d.c
r96 r121 1 2 1 /* 3 2 w83781d.c - Part of lm_sensors, Linux kernel modules for hardware … … 53 52 #define W83781D_REG_FAN(nr) (0x27 + (nr)) 54 53 55 #define W83781D_REG_TEMP23 0x50 56 #define W83781D_REG_TEMP_HYST23 0x53 57 #define W83781D_REG_TEMP_CONFIG23 0x52 58 #define W83781D_REG_TEMP_OVER23 0x55 54 #define W83781D_REG_TEMP2 0x0150 55 #define W83781D_REG_TEMP3 0x0250 56 #define W83781D_REG_TEMP2_HYST 0x153 57 #define W83781D_REG_TEMP3_HYST 0x253 58 #define W83781D_REG_TEMP2_CONFIG 0x152 59 #define W83781D_REG_TEMP3_CONFIG 0x252 60 #define W83781D_REG_TEMP2_OVER 0x155 61 #define W83781D_REG_TEMP3_OVER 0x255 62 59 63 #define W83781D_REG_TEMP 0x27 60 64 #define W83781D_REG_TEMP_OVER 0x39 61 65 #define W83781D_REG_TEMP_HYST 0x3A 62 66 #define W83781D_REG_TEMP_CONFIG 0x52 63 #define W83781D_REG_ TEMP_SEL0x4E67 #define W83781D_REG_BANK 0x4E 64 68 65 69 #define W83781D_REG_CONFIG 0x40 … … 73 77 #define W83781D_REG_VID_FANDIV 0x47 74 78 75 #define W83781D_REG_CHIPID 0x58 79 #define W83781D_REG_CHIPID 0x49 80 #define W83781D_REG_WCHIPID 0x58 76 81 #define W83781D_REG_CHIPMAN 0x4F 82 #define W83781D_REG_PIN 0x4B 77 83 78 84 79 85 /* Conversions. Rounding is only done on the TO_REG variants. */ 80 static int w83781d_in_conv[7] = {10000, 10000, 10000, 16892, 38000, 81 -34768, -15050 }; 82 #define IN_TO_REG(val,nr) (((((val) * 100000 / w83781d_in_conv[nr]) + 8) / 16) \ 83 & 0xff) 84 #define IN_FROM_REG(val,nr) (((val) * 16 * w83781d_in_conv[nr]) / 100000) 85 86 #define FAN_TO_REG(val) ((val)==0?255:((1350000+(val))/((val)*2)) & 0xff) 87 #define FAN_FROM_REG(val) ((val)==0?-1:(val)==255?0:1350000/((val)*2)) 86 #define IN_TO_REG(val,nr) (((val) * 10 + 8)/16) 87 #define IN_FROM_REG(val,nr) (((val) * 16) / 10) 88 89 #define FAN_TO_REG(val,div) ((val)==0?255:((1350000+(val))/\ 90 ((val)*2*(div))) & 0xff) 91 #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*2*(div))) 88 92 89 93 #define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff) 90 94 #define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) 95 96 #define TEMP_ADD_TO_REG(val) (((((val) + 2) / 5) << 7) & 0xff80) 97 #define TEMP_ADD_FROM_REG(val) (((val) >> 7) * 5) 91 98 92 99 #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ 93 100 (val)>=0x06?0:205-(val)*5) 94 101 #define ALARMS_FROM_REG(val) (val) 102 #define BEEPS_FROM_REG(val) (val) 103 #define BEEPS_TO_REG(val) ((val) & 0xffff) 104 105 #define BEEP_ENABLE_TO_REG(val) (val) 106 #define BEEP_ENABLE_FROM_REG(val) ((val)?1:0) 95 107 96 108 #define DIV_FROM_REG(val) (1 << (val)) … … 101 113 #define W83781D_INIT_IN_1 (vid==350?280:vid) 102 114 #define W83781D_INIT_IN_2 330 103 #define W83781D_INIT_IN_3 500104 #define W83781D_INIT_IN_4 1200105 #define W83781D_INIT_IN_5 -1200106 #define W83781D_INIT_IN_6 -500115 #define W83781D_INIT_IN_3 (((500) * 100)/168) 116 #define W83781D_INIT_IN_4 (((1200) * 10)/38) 117 #define W83781D_INIT_IN_5 (((-1200) * -604)/2100) 118 #define W83781D_INIT_IN_6 (((-500) * -604)/909) 107 119 108 120 #define W83781D_INIT_IN_PERCENTAGE 10 109 121 110 122 #define W83781D_INIT_IN_MIN_0 \ 111 (W83781D_INIT_IN_0 - W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE / 100) 123 (W83781D_INIT_IN_0 - W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \ 124 / 100) 112 125 #define W83781D_INIT_IN_MAX_0 \ 113 (W83781D_INIT_IN_0 + W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE / 100) 126 (W83781D_INIT_IN_0 + W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \ 127 / 100) 114 128 #define W83781D_INIT_IN_MIN_1 \ 115 (W83781D_INIT_IN_1 - W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE / 100) 129 (W83781D_INIT_IN_1 - W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \ 130 / 100) 116 131 #define W83781D_INIT_IN_MAX_1 \ 117 (W83781D_INIT_IN_1 + W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE / 100) 132 (W83781D_INIT_IN_1 + W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \ 133 / 100) 118 134 #define W83781D_INIT_IN_MIN_2 \ 119 (W83781D_INIT_IN_2 - W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE / 100) 135 (W83781D_INIT_IN_2 - W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \ 136 / 100) 120 137 #define W83781D_INIT_IN_MAX_2 \ 121 (W83781D_INIT_IN_2 + W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE / 100) 138 (W83781D_INIT_IN_2 + W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \ 139 / 100) 122 140 #define W83781D_INIT_IN_MIN_3 \ 123 (W83781D_INIT_IN_3 - W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE / 100) 141 (W83781D_INIT_IN_3 - W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \ 142 / 100) 124 143 #define W83781D_INIT_IN_MAX_3 \ 125 (W83781D_INIT_IN_3 + W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE / 100) 144 (W83781D_INIT_IN_3 + W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \ 145 / 100) 126 146 #define W83781D_INIT_IN_MIN_4 \ 127 (W83781D_INIT_IN_4 - W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE / 100) 147 (W83781D_INIT_IN_4 - W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \ 148 / 100) 128 149 #define W83781D_INIT_IN_MAX_4 \ 129 (W83781D_INIT_IN_4 + W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE / 100) 150 (W83781D_INIT_IN_4 + W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \ 151 / 100) 130 152 #define W83781D_INIT_IN_MIN_5 \ 131 (W83781D_INIT_IN_5 - W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE / 100) 153 (W83781D_INIT_IN_5 - W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \ 154 / 100) 132 155 #define W83781D_INIT_IN_MAX_5 \ 133 (W83781D_INIT_IN_5 + W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE / 100) 156 (W83781D_INIT_IN_5 + W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \ 157 / 100) 134 158 #define W83781D_INIT_IN_MIN_6 \ 135 (W83781D_INIT_IN_6 - W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE / 100) 159 (W83781D_INIT_IN_6 - W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \ 160 / 100) 136 161 #define W83781D_INIT_IN_MAX_6 \ 137 (W83781D_INIT_IN_6 + W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE / 100) 162 (W83781D_INIT_IN_6 + W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \ 163 / 100) 138 164 139 165 #define W83781D_INIT_FAN_MIN_1 3000 … … 181 207 u8 fan[3]; /* Register value */ 182 208 u8 fan_min[3]; /* Register value */ 183 u8 temp[3]; /* Register value */ 184 u8 temp_over[3]; /* Register value */ 185 u8 temp_hyst[3]; /* Register value */ 186 u8 fan_div[2]; /* Register encoding, shifted right */ 209 u8 temp; 210 u8 temp_over; /* Register value */ 211 u8 temp_hyst; /* Register value */ 212 u8 temp_add[2]; /* Register value */ 213 u16 temp_add_over[2]; /* Register value */ 214 u16 temp_add_hyst[2]; /* Register value */ 215 u8 fan_div[3]; /* Register encoding, shifted right */ 187 216 u8 vid; /* Register encoding, combined */ 188 217 u16 alarms; /* Register encoding, combined */ 189 u8 beep[3]; /* Register value of config and interrupt masks */ 218 u16 beeps; /* Register encoding, combined */ 219 u8 beep_enable; /* Boolean */ 190 220 }; 191 221 … … 208 238 static void w83781d_dec_use (struct i2c_client *client); 209 239 210 static int w83781d_read_value(struct i2c_client *client, u8 register); 211 static int w83781d_write_value(struct i2c_client *client, u8 register, u8 value); 240 static int w83781d_read_value(struct i2c_client *client, u16 register); 241 static int w83781d_write_value(struct i2c_client *client, u16 register, 242 u16 value); 212 243 static void w83781d_update_client(struct i2c_client *client); 213 244 static void w83781d_init_client(struct i2c_client *client); … … 218 249 static void w83781d_fan(struct i2c_client *client, int operation, int ctl_name, 219 250 int *nrels_mag, long *results); 220 static void w83781d_temp(struct i2c_client *client, int operation, int ctl_name, 221 int *nrels_mag, long *results,int tempnum); 222 static void w83781d_temp1(struct i2c_client *client, int operation, int ctl_name, 223 int *nrels_mag, long *results); 224 static void w83781d_temp2(struct i2c_client *client, int operation, int ctl_name, 225 int *nrels_mag, long *results); 226 static void w83781d_temp3(struct i2c_client *client, int operation, int ctl_name, 227 int *nrels_mag, long *results); 251 static void w83781d_temp(struct i2c_client *client, int operation, 252 int ctl_name, int *nrels_mag, long *results); 253 static void w83781d_temp_add(struct i2c_client *client, int operation, 254 int ctl_name, int *nrels_mag, long *results); 228 255 static void w83781d_vid(struct i2c_client *client, int operation, int ctl_name, 229 int *nrels_mag, long *results);230 static void w83781d_alarms(struct i2c_client *client, int operation, int ctl_name,231 int *nrels_mag, long *results);256 int *nrels_mag, long *results); 257 static void w83781d_alarms(struct i2c_client *client, int operation, 258 int ctl_name, int *nrels_mag, long *results); 232 259 static void w83781d_beep(struct i2c_client *client, int operation, int ctl_name, 233 260 int *nrels_mag, long *results); 234 static void w83781d_fan_div(struct i2c_client *client, int operation, int ctl_name,235 int *nrels_mag, long *results);261 static void w83781d_fan_div(struct i2c_client *client, int operation, 262 int ctl_name, int *nrels_mag, long *results); 236 263 237 264 /* I choose here for semi-static W83781D allocation. Complete dynamic … … 284 311 { W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real, 285 312 &sensors_sysctl_real, NULL, &w83781d_fan }, 286 { W83781D_SYSCTL_TEMP , "temp", NULL, 0, 0644, NULL, &sensors_proc_real,287 &sensors_sysctl_real, NULL, &w83781d_temp 1},313 { W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &sensors_proc_real, 314 &sensors_sysctl_real, NULL, &w83781d_temp }, 288 315 { W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &sensors_proc_real, 289 &sensors_sysctl_real, NULL, &w83781d_temp 2},316 &sensors_sysctl_real, NULL, &w83781d_temp_add }, 290 317 { W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &sensors_proc_real, 291 &sensors_sysctl_real, NULL, &w83781d_temp 3},318 &sensors_sysctl_real, NULL, &w83781d_temp_add }, 292 319 { W83781D_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real, 293 320 &sensors_sysctl_real, NULL, &w83781d_vid }, … … 355 382 /* Real detection code goes here */ 356 383 357 outb_p(W83781D_REG_CHIPID,address + W83781D_ADDR_REG_OFFSET); 384 /* The Winbond may be stuck in bank 1 or 2. This should reset it. 385 We really need some nifty detection code, because this can lead 386 to a lot of problems if there is no Winbond present! */ 387 outb_p(W83781D_REG_BANK,address + W83781D_ADDR_REG_OFFSET); 388 outb_p(0x00,address + W83781D_DATA_REG_OFFSET); 389 390 outb_p(W83781D_REG_WCHIPID,address + W83781D_ADDR_REG_OFFSET); 358 391 err = inb_p(address + W83781D_DATA_REG_OFFSET) & 0xfe; 359 392 … … 461 494 continue; 462 495 463 err = smbus_read_byte_data(adapter,address,W83781D_REG_CHIPID); 496 smbus_write_byte_data(adapter,address,W83781D_REG_BANK,0x00); 497 498 err = smbus_read_byte_data(adapter,address,W83781D_REG_WCHIPID); 464 499 465 500 if (err == 0x20) { … … 600 635 601 636 602 /* The SMBus locks itself, but ISA access must be locked explicitely! 637 /* The SMBus locks itself, usually, but nothing may access the Winbond between 638 bank switches. ISA access must always be locked explicitely! 603 639 We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, 604 640 would slow down the W83781D access and should not be necessary. 605 641 There are some ugly typecasts here, but the good new is - they should 606 642 nowhere else be necessary! */ 607 int w83781d_read_value(struct i2c_client *client, u8 reg) 608 { 609 int res; 643 int w83781d_read_value(struct i2c_client *client, u16 reg) 644 { 645 int res,word_sized; 646 647 word_sized = (reg & 0x0ff) && (((reg && 0x00ff) == 0x50) || 648 ((reg && 0x00ff) == 0x53) || 649 ((reg && 0x00ff) == 0x55)); 650 down((struct semaphore *) (client->data)); 610 651 if (i2c_is_isa_client(client)) { 611 down((struct semaphore *) (client->data)); 612 outb_p(reg,(((struct isa_client *) client)->isa_addr) + 613 W83781D_ADDR_REG_OFFSET); 614 res = inb_p((((struct isa_client *) client)->isa_addr) + 652 if (reg & 0xff00) { 653 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 654 W83781D_ADDR_REG_OFFSET); 655 outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) + 656 W83781D_DATA_REG_OFFSET); 657 } 658 outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) + 659 W83781D_ADDR_REG_OFFSET); 660 res = inb_p((((struct isa_client *) client)->isa_addr) + 615 661 W83781D_DATA_REG_OFFSET); 616 up((struct semaphore *) (client->data)); 617 return res; 618 } else 619 return smbus_read_byte_data(client->adapter,client->addr, reg); 620 } 621 622 /* The SMBus locks itself, but ISA access muse be locked explicitely! 662 if (word_sized) { 663 outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) + 664 W83781D_ADDR_REG_OFFSET); 665 res = (res << 8) + inb_p((((struct isa_client *) client)->isa_addr) + 666 W83781D_DATA_REG_OFFSET); 667 } 668 if (reg & 0xff00) { 669 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 670 W83781D_ADDR_REG_OFFSET); 671 outb_p(0,(((struct isa_client *) client)->isa_addr) + 672 W83781D_DATA_REG_OFFSET); 673 } 674 } else { 675 if (reg & 0xff00) 676 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK, 677 reg >> 8); 678 res = smbus_read_byte_data(client->adapter,client->addr, reg); 679 if (word_sized) 680 res = (res << 8) + smbus_read_byte_data(client->adapter,client->addr, 681 reg); 682 if (reg & 0xff00) 683 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0); 684 } 685 up((struct semaphore *) (client->data)); 686 return res; 687 } 688 689 /* The SMBus locks itself, usually, but nothing may access the Winbond between 690 bank switches. ISA access must always be locked explicitely! 623 691 We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, 624 692 would slow down the W83781D access and should not be necessary. 625 693 There are some ugly typecasts here, but the good new is - they should 626 694 nowhere else be necessary! */ 627 int w83781d_write_value(struct i2c_client *client, u8 reg, u8 value) 628 { 695 int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) 696 { 697 int word_sized; 698 699 word_sized = (reg & 0x0ff) && (((reg && 0x00ff) == 0x50) || 700 ((reg && 0x00ff) == 0x53) || 701 ((reg && 0x00ff) == 0x55)); 702 down((struct semaphore *) (client->data)); 629 703 if (i2c_is_isa_client(client)) { 630 down((struct semaphore *) (client->data)); 631 outb_p(reg,((struct isa_client *) client)->isa_addr + W83781D_ADDR_REG_OFFSET); 632 outb_p(value,((struct isa_client *) client)->isa_addr + W83781D_DATA_REG_OFFSET); 633 up((struct semaphore *) (client->data)); 634 return 0; 635 } else 636 return smbus_write_byte_data(client->adapter, client->addr, reg,value); 704 if (reg & 0xff00) { 705 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 706 W83781D_ADDR_REG_OFFSET); 707 outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) + 708 W83781D_DATA_REG_OFFSET); 709 } 710 outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) + 711 W83781D_ADDR_REG_OFFSET); 712 if (word_sized) { 713 outb_p(value >> 8,(((struct isa_client *) client)->isa_addr) + 714 W83781D_DATA_REG_OFFSET); 715 outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) + 716 W83781D_ADDR_REG_OFFSET); 717 } 718 outb_p(value &0xff,(((struct isa_client *) client)->isa_addr) + 719 W83781D_DATA_REG_OFFSET); 720 if (reg & 0xff00) { 721 outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) + 722 W83781D_ADDR_REG_OFFSET); 723 outb_p(0,(((struct isa_client *) client)->isa_addr) + 724 W83781D_DATA_REG_OFFSET); 725 } 726 } else { 727 if (reg & 0xff00) 728 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK, 729 reg >> 8); 730 if (word_sized) { 731 smbus_write_byte_data(client->adapter,client->addr, reg, value >> 8); 732 smbus_write_byte_data(client->adapter,client->addr, reg+1, value &0xff); 733 } else 734 smbus_write_byte_data(client->adapter,client->addr, reg, value &0xff); 735 if (reg & 0xff00) 736 smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0); 737 } 738 up((struct semaphore *) (client->data)); 739 return 0; 637 740 } 638 741 … … 650 753 vid = VID_FROM_REG(vid); 651 754 652 w83781d_write_value(client,W83781D_REG_IN_MIN(0),IN_TO_REG(W83781D_INIT_IN_MIN_0,0)); 653 w83781d_write_value(client,W83781D_REG_IN_MAX(0),IN_TO_REG(W83781D_INIT_IN_MAX_0,0)); 654 w83781d_write_value(client,W83781D_REG_IN_MIN(1),IN_TO_REG(W83781D_INIT_IN_MIN_1,1)); 655 w83781d_write_value(client,W83781D_REG_IN_MAX(1),IN_TO_REG(W83781D_INIT_IN_MAX_1,1)); 656 w83781d_write_value(client,W83781D_REG_IN_MIN(2),IN_TO_REG(W83781D_INIT_IN_MIN_2,2)); 657 w83781d_write_value(client,W83781D_REG_IN_MAX(2),IN_TO_REG(W83781D_INIT_IN_MAX_2,2)); 658 w83781d_write_value(client,W83781D_REG_IN_MIN(3),IN_TO_REG(W83781D_INIT_IN_MIN_3,3)); 659 w83781d_write_value(client,W83781D_REG_IN_MAX(3),IN_TO_REG(W83781D_INIT_IN_MAX_3,3)); 660 w83781d_write_value(client,W83781D_REG_IN_MIN(4),IN_TO_REG(W83781D_INIT_IN_MIN_4,4)); 661 w83781d_write_value(client,W83781D_REG_IN_MAX(4),IN_TO_REG(W83781D_INIT_IN_MAX_4,4)); 662 w83781d_write_value(client,W83781D_REG_IN_MIN(5),IN_TO_REG(W83781D_INIT_IN_MIN_5,5)); 663 w83781d_write_value(client,W83781D_REG_IN_MAX(5),IN_TO_REG(W83781D_INIT_IN_MAX_5,5)); 664 w83781d_write_value(client,W83781D_REG_IN_MIN(6),IN_TO_REG(W83781D_INIT_IN_MIN_6,6)); 665 w83781d_write_value(client,W83781D_REG_IN_MAX(6),IN_TO_REG(W83781D_INIT_IN_MAX_6,6)); 666 w83781d_write_value(client,W83781D_REG_FAN_MIN(1),FAN_TO_REG(W83781D_INIT_FAN_MIN_1)); 667 w83781d_write_value(client,W83781D_REG_FAN_MIN(2),FAN_TO_REG(W83781D_INIT_FAN_MIN_2)); 668 w83781d_write_value(client,W83781D_REG_FAN_MIN(3),FAN_TO_REG(W83781D_INIT_FAN_MIN_3)); 669 /* Init Temp Sensor1 */ 670 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x00);/* Switch Banks! */ 671 w83781d_write_value(client,W83781D_REG_TEMP_OVER,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 672 w83781d_write_value(client,W83781D_REG_TEMP_HYST,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 755 w83781d_write_value(client,W83781D_REG_IN_MIN(0), 756 IN_TO_REG(W83781D_INIT_IN_MIN_0,0)); 757 w83781d_write_value(client,W83781D_REG_IN_MAX(0), 758 IN_TO_REG(W83781D_INIT_IN_MAX_0,0)); 759 w83781d_write_value(client,W83781D_REG_IN_MIN(1), 760 IN_TO_REG(W83781D_INIT_IN_MIN_1,1)); 761 w83781d_write_value(client,W83781D_REG_IN_MAX(1), 762 IN_TO_REG(W83781D_INIT_IN_MAX_1,1)); 763 w83781d_write_value(client,W83781D_REG_IN_MIN(2), 764 IN_TO_REG(W83781D_INIT_IN_MIN_2,2)); 765 w83781d_write_value(client,W83781D_REG_IN_MAX(2), 766 IN_TO_REG(W83781D_INIT_IN_MAX_2,2)); 767 w83781d_write_value(client,W83781D_REG_IN_MIN(3), 768 IN_TO_REG(W83781D_INIT_IN_MIN_3,3)); 769 w83781d_write_value(client,W83781D_REG_IN_MAX(3), 770 IN_TO_REG(W83781D_INIT_IN_MAX_3,3)); 771 w83781d_write_value(client,W83781D_REG_IN_MIN(4), 772 IN_TO_REG(W83781D_INIT_IN_MIN_4,4)); 773 w83781d_write_value(client,W83781D_REG_IN_MAX(4), 774 IN_TO_REG(W83781D_INIT_IN_MAX_4,4)); 775 w83781d_write_value(client,W83781D_REG_IN_MIN(5), 776 IN_TO_REG(W83781D_INIT_IN_MIN_5,5)); 777 w83781d_write_value(client,W83781D_REG_IN_MAX(5), 778 IN_TO_REG(W83781D_INIT_IN_MAX_5,5)); 779 w83781d_write_value(client,W83781D_REG_IN_MIN(6), 780 IN_TO_REG(W83781D_INIT_IN_MIN_6,6)); 781 w83781d_write_value(client,W83781D_REG_IN_MAX(6), 782 IN_TO_REG(W83781D_INIT_IN_MAX_6,6)); 783 w83781d_write_value(client,W83781D_REG_FAN_MIN(1), 784 FAN_TO_REG(W83781D_INIT_FAN_MIN_1,2)); 785 w83781d_write_value(client,W83781D_REG_FAN_MIN(2), 786 FAN_TO_REG(W83781D_INIT_FAN_MIN_2,2)); 787 w83781d_write_value(client,W83781D_REG_FAN_MIN(3), 788 FAN_TO_REG(W83781D_INIT_FAN_MIN_3,2)); 789 790 w83781d_write_value(client,W83781D_REG_TEMP_OVER, 791 TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 792 w83781d_write_value(client,W83781D_REG_TEMP_HYST, 793 TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 673 794 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG,0x00); 674 /* Init Temp Sensor2 */ 675 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x01);/* Switch Banks! */ 676 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 677 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 678 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 679 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 680 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG23,0x00); 681 /* Init Temp Sensor3 */ 682 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x02);/* Switch Banks! */ 683 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,TEMP_TO_REG(W83781D_INIT_TEMP_OVER)); 684 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 685 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,TEMP_TO_REG(W83781D_INIT_TEMP_HYST)); 686 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 687 w83781d_write_value(client,W83781D_REG_TEMP_CONFIG23,0x00); 688 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x00);/* Switch Banks! */ 795 796 w83781d_write_value(client,W83781D_REG_TEMP2_OVER, 797 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_OVER)); 798 w83781d_write_value(client,W83781D_REG_TEMP2_HYST, 799 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_HYST)); 800 w83781d_write_value(client,W83781D_REG_TEMP2_CONFIG,0x00); 801 802 w83781d_write_value(client,W83781D_REG_TEMP3_OVER, 803 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_OVER)); 804 w83781d_write_value(client,W83781D_REG_TEMP3_HYST, 805 TEMP_ADD_TO_REG(W83781D_INIT_TEMP_HYST)); 806 w83781d_write_value(client,W83781D_REG_TEMP3_CONFIG,0x00); 689 807 690 808 /* Start monitoring */ 691 809 w83781d_write_value(client,W83781D_REG_CONFIG, 692 (w83781d_read_value(client, W83781D_REG_CONFIG) & 0xf7) | 0x01);693 810 (w83781d_read_value(client, 811 W83781D_REG_CONFIG) & 0xf7) | 0x01); 694 812 } 695 813 … … 716 834 data->fan_min[i-1] = w83781d_read_value(client,W83781D_REG_FAN_MIN(i)); 717 835 } 718 data->temp[0] = w83781d_read_value(client,W83781D_REG_TEMP); 719 data->temp_over[0] = w83781d_read_value(client,W83781D_REG_TEMP_OVER); 720 data->temp_hyst[0] = w83781d_read_value(client,W83781D_REG_TEMP_HYST); 721 w83781d_write_value(client,W83781D_REG_TEMP_SEL,1);/* Switch Banks!! */ 722 data->temp[1] = w83781d_read_value(client,W83781D_REG_TEMP23); 723 data->temp_over[1] = w83781d_read_value(client,W83781D_REG_TEMP_OVER23); 724 data->temp_hyst[1] = w83781d_read_value(client,W83781D_REG_TEMP_HYST23); 725 w83781d_write_value(client,W83781D_REG_TEMP_SEL,2);/* Switch Banks!! */ 726 data->temp[2] = w83781d_read_value(client,W83781D_REG_TEMP23); 727 data->temp_over[2] = w83781d_read_value(client,W83781D_REG_TEMP_OVER23); 728 data->temp_hyst[2] = w83781d_read_value(client,W83781D_REG_TEMP_HYST23); 729 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0);/* Switch Banks!! */ 836 data->temp = w83781d_read_value(client,W83781D_REG_TEMP); 837 data->temp_over = w83781d_read_value(client,W83781D_REG_TEMP_OVER); 838 data->temp_hyst = w83781d_read_value(client,W83781D_REG_TEMP_HYST); 839 data->temp_add[0] = w83781d_read_value(client,W83781D_REG_TEMP2); 840 data->temp_add_over[0] = w83781d_read_value(client,W83781D_REG_TEMP2_OVER); 841 data->temp_add_hyst[0] = w83781d_read_value(client,W83781D_REG_TEMP2_HYST); 842 data->temp_add[1] = w83781d_read_value(client,W83781D_REG_TEMP3); 843 data->temp_add_over[1] = w83781d_read_value(client,W83781D_REG_TEMP3_OVER); 844 data->temp_add_hyst[1] = w83781d_read_value(client,W83781D_REG_TEMP3_HYST); 730 845 i = w83781d_read_value(client,W83781D_REG_VID_FANDIV); 731 846 data->vid = i & 0x0f; … … 733 848 data->fan_div[0] = (i >> 4) & 0x03; 734 849 data->fan_div[1] = i >> 6; 850 data->fan_div[2] = (w83781d_read_value(client,W83781D_REG_PIN) >> 6) & 0x03; 735 851 data->alarms = w83781d_read_value(client,W83781D_REG_ALARM1) + 736 (w83781d_read_value(client,W83781D_REG_ALARM2) >> 8); 737 data->beep[0] = w83781d_read_value(client,W83781D_REG_BEEP_CONFIG); 738 data->beep[1] = w83781d_read_value(client,W83781D_REG_BEEP_INTS1); 739 data->beep[2] = w83781d_read_value(client,W83781D_REG_BEEP_INTS2); 852 (w83781d_read_value(client,W83781D_REG_ALARM2) << 8); 853 i = w83781d_read_value(client,W83781D_REG_BEEP_INTS2); 854 data->beep_enable = i >> 7; 855 data->beeps = ((i & 0x7f) << 8) + 856 w83781d_read_value(client,W83781D_REG_BEEP_INTS1); 740 857 data->last_updated = jiffies; 741 858 data->valid = 1; … … 795 912 else if (operation == SENSORS_PROC_REAL_READ) { 796 913 w83781d_update_client(client); 797 results[0] = FAN_FROM_REG(data->fan_min[nr-1] );798 results[1] = FAN_FROM_REG(data->fan[nr-1] );914 results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]); 915 results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]); 799 916 *nrels_mag = 2; 800 917 } else if (operation == SENSORS_PROC_REAL_WRITE) { 801 918 if (*nrels_mag >= 1) { 802 data->fan_min[nr-1] = FAN_TO_REG(results[0] );919 data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]); 803 920 w83781d_write_value(client,W83781D_REG_FAN_MIN(nr),data->fan_min[nr-1]); 804 921 } … … 808 925 809 926 void w83781d_temp(struct i2c_client *client, int operation, int ctl_name, 810 int *nrels_mag, long *results ,int tempnum)927 int *nrels_mag, long *results) 811 928 { 812 929 struct w83781d_data *data = client->data; … … 815 932 else if (operation == SENSORS_PROC_REAL_READ) { 816 933 w83781d_update_client(client); 817 results[0] = TEMP_FROM_REG(data->temp_over [tempnum - 1]);818 results[1] = TEMP_FROM_REG(data->temp_hyst [tempnum - 1]);819 results[2] = TEMP_FROM_REG(data->temp [tempnum - 1]);934 results[0] = TEMP_FROM_REG(data->temp_over); 935 results[1] = TEMP_FROM_REG(data->temp_hyst); 936 results[2] = TEMP_FROM_REG(data->temp); 820 937 *nrels_mag = 3; 821 938 } else if (operation == SENSORS_PROC_REAL_WRITE) { 822 if (tempnum == 3) { 823 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x02);/* Switch Banks!! */ 824 if (*nrels_mag >= 1) { 825 data->temp_over[2] = TEMP_TO_REG(results[0]); 826 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,data->temp_over[2]); 827 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 828 } 829 if (*nrels_mag >= 2) { 830 data->temp_hyst[2] = TEMP_TO_REG(results[1]); 831 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,data->temp_hyst[2]); 832 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 833 } 834 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x0);/* Switch Banks!! */ 835 } else if (tempnum == 2) { 836 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x01);/* Switch Banks!! */ 837 if (*nrels_mag >= 1) { 838 data->temp_over[1] = TEMP_TO_REG(results[0]); 839 w83781d_write_value(client,W83781D_REG_TEMP_OVER23,data->temp_over[1]); 840 w83781d_write_value(client,W83781D_REG_TEMP_OVER23 + 1,0); 841 } 842 if (*nrels_mag >= 2) { 843 data->temp_hyst[1] = TEMP_TO_REG(results[1]); 844 w83781d_write_value(client,W83781D_REG_TEMP_HYST23,data->temp_hyst[1]); 845 w83781d_write_value(client,W83781D_REG_TEMP_HYST23 + 1,0); 846 } 847 w83781d_write_value(client,W83781D_REG_TEMP_SEL,0x0);/* Switch Banks!! */ 848 } else { 849 if (*nrels_mag >= 1) { 850 data->temp_over[0] = TEMP_TO_REG(results[0]); 851 w83781d_write_value(client,W83781D_REG_TEMP_OVER,data->temp_over[0]); 852 } 853 if (*nrels_mag >= 2) { 854 data->temp_hyst[0] = TEMP_TO_REG(results[1]); 855 w83781d_write_value(client,W83781D_REG_TEMP_HYST,data->temp_hyst[0]); 856 } 857 } 858 } 859 } 860 861 862 void w83781d_temp1(struct i2c_client *client, int operation, int ctl_name, 863 int *nrels_mag, long *results) { 864 865 w83781d_temp(client,operation,ctl_name,nrels_mag,results,1); 866 } 867 868 869 void w83781d_temp2(struct i2c_client *client, int operation, int ctl_name, 870 int *nrels_mag, long *results) { 871 872 w83781d_temp(client,operation,ctl_name,nrels_mag,results,2); 873 } 874 875 876 void w83781d_temp3(struct i2c_client *client, int operation, int ctl_name, 877 int *nrels_mag, long *results) { 878 879 w83781d_temp(client,operation,ctl_name,nrels_mag,results,3); 939 if (*nrels_mag >= 1) { 940 data->temp_over = TEMP_TO_REG(results[0]); 941 w83781d_write_value(client,W83781D_REG_TEMP_OVER,data->temp_over); 942 } 943 if (*nrels_mag >= 2) { 944 data->temp_hyst = TEMP_TO_REG(results[1]); 945 w83781d_write_value(client,W83781D_REG_TEMP_HYST,data->temp_hyst); 946 } 947 } 948 } 949 950 951 void w83781d_temp_add(struct i2c_client *client, int operation, int ctl_name, 952 int *nrels_mag, long *results) 953 { 954 struct w83781d_data *data = client->data; 955 int nr = ctl_name - W83781D_SYSCTL_TEMP2; 956 957 if (operation == SENSORS_PROC_REAL_INFO) 958 *nrels_mag = 1; 959 else if (operation == SENSORS_PROC_REAL_READ) { 960 w83781d_update_client(client); 961 results[0] = TEMP_ADD_FROM_REG(data->temp_add_over[nr]); 962 results[1] = TEMP_ADD_FROM_REG(data->temp_add_hyst[nr]); 963 results[2] = TEMP_ADD_FROM_REG(data->temp_add[nr]); 964 *nrels_mag = 3; 965 } else if (operation == SENSORS_PROC_REAL_WRITE) { 966 if (*nrels_mag >= 1) { 967 data->temp_add_over[nr] = TEMP_ADD_TO_REG(results[0]); 968 w83781d_write_value(client, 969 nr?W83781D_REG_TEMP3_OVER:W83781D_REG_TEMP2_OVER, 970 data->temp_add_over[nr]); 971 } 972 if (*nrels_mag >= 2) { 973 data->temp_add_hyst[nr] = TEMP_ADD_TO_REG(results[1]); 974 w83781d_write_value(client, 975 nr?W83781D_REG_TEMP3_HYST:W83781D_REG_TEMP2_HYST, 976 data->temp_add_hyst[nr]); 977 } 978 } 880 979 } 881 980 … … 911 1010 { 912 1011 struct w83781d_data *data = client->data; 1012 int val; 1013 913 1014 if (operation == SENSORS_PROC_REAL_INFO) 914 1015 *nrels_mag = 0; 915 1016 else if (operation == SENSORS_PROC_REAL_READ) { 916 1017 w83781d_update_client(client); 917 results[0] = data->beep[0]; 918 results[1] = data->beep[1]; 919 results[2] = data->beep[2]; 920 *nrels_mag = 3; 1018 results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); 1019 results[1] = BEEPS_FROM_REG(data->beeps); 1020 *nrels_mag = 2; 921 1021 } else if (operation == SENSORS_PROC_REAL_WRITE) { 922 data->beep[0] = results[0]; 923 w83781d_write_value(client,W83781D_REG_BEEP_CONFIG,data->beep[0]); 924 data->beep[1] = results[1]; 925 w83781d_write_value(client,W83781D_REG_BEEP_INTS1,data->beep[1]); 926 data->beep[2] = results[2]; 927 w83781d_write_value(client,W83781D_REG_BEEP_INTS2,data->beep[2]); 1022 if (*nrels_mag >= 2) { 1023 data->beeps = BEEPS_TO_REG(results[1]); 1024 w83781d_write_value(client,W83781D_REG_BEEP_INTS1,data->beeps & 0xff); 1025 val = data->beeps >> 8; 1026 } else if (*nrels_mag >= 1) 1027 val = w83781d_read_value(client,W83781D_REG_BEEP_INTS1) & 0x7f; 1028 if (*nrels_mag >= 1) { 1029 data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); 1030 w83781d_write_value(client,W83781D_REG_BEEP_INTS2, 1031 val | data->beep_enable << 7); 1032 } 928 1033 } 929 1034 } … … 941 1046 results[0] = DIV_FROM_REG(data->fan_div[0]); 942 1047 results[1] = DIV_FROM_REG(data->fan_div[1]); 943 results[2] = 2;1048 results[2] = DIV_FROM_REG(data->fan_div[2]); 944 1049 *nrels_mag = 3; 945 1050 } else if (operation == SENSORS_PROC_REAL_WRITE) { … … 954 1059 w83781d_write_value(client,W83781D_REG_VID_FANDIV,old); 955 1060 } 1061 if (*nrels_mag >= 3) { 1062 data->fan_div[2] = DIV_TO_REG(results[2]); 1063 w83781d_write_value(client,W83781D_REG_PIN, 1064 w83781d_read_value(client,W83781D_REG_PIN)); 1065 } 956 1066 } 957 1067 }
