Changeset 759
- Timestamp:
- 03/07/00 16:25:20 (9 years ago)
- Files:
-
- lm-sensors/trunk/kernel/chips/via686a.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lm-sensors/trunk/kernel/chips/via686a.c
r756 r759 94 94 #define VIA686A_REG_TEMP_OVER(nr) (regover[(nr) - 1]) 95 95 #define VIA686A_REG_TEMP_HYST(nr) (reghyst[(nr) - 1]) 96 #define VIA686A_REG_TEMP_LOW1 0x4b 97 #define VIA686A_REG_TEMP_LOW23 0x49 96 #define VIA686A_REG_TEMP_LOW1 0x4b // bits 7-6 97 #define VIA686A_REG_TEMP_LOW23 0x49 // 2 = bits 5-4, 3 = bits 7-6 98 98 99 99 #define VIA686A_REG_ALARM1 0x41 … … 102 102 #define VIA686A_REG_CONFIG 0x40 103 103 104 #define ROUND_INT(val) ((val)<0?((val)-0.5):((val)+0.5))105 106 104 /* Conversions. Rounding and limit checking is only done on the TO_REG 107 105 variants. */ … … 109 107 /********* VOLTAGE CONVERSIONS (Bob Dougherty) ********/ 110 108 // From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew): 111 // voltagefactor[0]=1.25/2628; // Vccp112 // voltagefactor[1]=1.25/2628; // +2.5V113 // voltagefactor[2]=1.67/2628; // +3.3V114 // voltagefactor[3]=2.6/2628; // +5V115 // voltagefactor[4]=6.3/2628; // +12V109 // voltagefactor[0]=1.25/2628; (2628/1.25=2102.4) // Vccp 110 // voltagefactor[1]=1.25/2628; (2628/1.25=2102.4) // +2.5V 111 // voltagefactor[2]=1.67/2628; (2628/1.67=1573.7) // +3.3V 112 // voltagefactor[3]=2.6/2628; (2628/2.60=1010.8) // +5V 113 // voltagefactor[4]=6.3/2628; (2628/6.30=417.14) // +12V 116 114 // in[i]=(data[i+2]*25.0+133)*voltagefactor[i]; 115 // That is: 116 // volts = (25*regVal+133)*factor 117 // regVal = (volts/factor-133)/25 117 118 // 118 119 // These get us close, but they don't completely agree with what my BIOS says- … … 120 121 extern inline u8 IN_TO_REG(long val, int inNum) 121 122 { 122 // there's an extra /100 hidden in the conversion factors here 123 // to avoid floating point, we multiply everything by 100. 124 // val is guaranteed to be positive, so we can achieve the effect of rounding 125 // by adding 0.5. Or, to avoid fp math, we do (...*10+5)/10. 126 // (note that the *10 is hidden in the /250 rather than /2500 127 // At the end, we need to /100 because we *100 everything and we need 128 // to /10 because of the rounding thing, so we /1000 123 129 if (inNum<=1) 124 return (u8)SENSORS_LIMIT( ROUND_INT(0.04*(val/0.047565-133)),0,255);130 return (u8)SENSORS_LIMIT(((val*210240-13300)/250+5)/1000,0,255); 125 131 else if (inNum==2) 126 return (u8)SENSORS_LIMIT( ROUND_INT(0.04*(val/0.063546-133)),0,255);132 return (u8)SENSORS_LIMIT(((val*157370-13300)/250+5)/1000,0,255); 127 133 else if (inNum==3) 128 return (u8)SENSORS_LIMIT( ROUND_INT(0.04*(val/0.098935-133)),0,255);134 return (u8)SENSORS_LIMIT(((val*101080-13300)/250+5)/1000,0,255); 129 135 else 130 return (u8)SENSORS_LIMIT( ROUND_INT(0.04*(val/0.23973-133)),0,255);136 return (u8)SENSORS_LIMIT(((val*41714-13300)/250+5)/1000,0,255); 131 137 } 132 138 extern inline long IN_FROM_REG(u8 val, int inNum) 133 139 { 134 // use 2500.0 instead of 25.0 because we nneed to multiply val by 100 140 // to avoid floating point, we multiply everything by 100. 141 // val is guaranteed to be positive, so we can achieve the effect of rounding 142 // by adding 0.5. Or, to avoid fp math, we do (...*10+5)/10. 143 // Since we need to scale up by 100 anyway, we don't need to /100 at the end. 135 144 if (inNum<=1) 136 return (long) ROUND_INT((2500.0*val+133)*0.00047565);145 return (long)(((250000*val+13300)/210240*10+5)/10); // was 210240, 205240 works better 137 146 else if (inNum==2) 138 return (long) ROUND_INT((2500.0*val+133)*0.00063546);147 return (long)(((250000*val+13300)/157370*10+5)/10); // was 157370, 154370 works better 139 148 else if (inNum==3) 140 return (long) ROUND_INT((2500.0*val+133)*0.00098935);149 return (long)(((250000*val+13300)/101080*10+5)/10); 141 150 else 142 return (long) ROUND_INT((2500.0*val+133)*0.0023973);151 return (long)(((250000*val+13300)/41714*10+5)/10); 143 152 } 144 153 … … 148 157 return 255; 149 158 rpm = SENSORS_LIMIT(rpm, 1, 1000000); 150 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 151 254); 159 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); 152 160 } 153 161 … … 168 176 // temp = 6.500371171990e-09*val^5 +-4.006529810457e-06*val^4 +9.830610857874e-04*val^3 + 169 177 // -1.187047495730e-01*val^2 +8.700574403605e+00*val +-2.836026823804e+02 170 // 171 // Alas, neither work well because of precision limits in our math (?!?), so 172 // I came up with a pretty good piecewise-2nd-order: 173 // 174 // For 8-bit readings: 175 // 0-59: -0.00831398*val*val + 1.46882437*val - 63.66742250 176 // 60:179: 0.00056874*val*val + 0.29665581*val - 23.7538571 177 // 180-255: 0.01275451*val*val - 4.39034916*val + 428.14343750 178 // 179 // For 10-bit readings: 180 // 0-283: -0.00051962*val*val + 0.36720609*val - 63.6674225 181 // 284:763: 0.00004141*val*val + 0.06853503*val + -22.48959243 182 // 764-1023: 0.00087626*val*val + -1.23656143*val + 488.97355989 183 // 184 // To convert the other way (temp to 8-bit reg val): 185 // <0: 0.01864022*val*val + 2.12242751*val + 290.16637347 186 // 0-55: -0.00714790*val*val + 2.60844692*val + 70.67197155 187 // >55: -0.00991559*val*val + 2.48774551*val + 85.21011594 178 // 179 // None of the elegant function-fit solutions will work because we aren't allowed 180 // to use floating point in the kernel, so we'll do boring-old look-up table stuff. 181 // Here are the unofficial data (provided by Alex van Kaam <darkside@chello.nl>). 182 // Note that t is the temp at via register values 12-240 (8-bit), 48-960 (10-bit). 183 static const u8 tempLUT[] = {-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,\ 184 -30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,-15,-14,\ 185 -14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,-3,-2,-2,-1,-1,0,0,\ 186 1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,12,12,13,13,13,14,14,15,15,16,\ 187 16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,22,23,23,24,24,25,25,26,26,26,27,27,27,28,\ 188 28,29,29,30,30,30,31,31,32,32,33,33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,\ 189 42,42,43,43,44,44,45,45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,\ 190 59,59,60,61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,85,\ 191 86,88,89,91,92,94,96,97,99,101,103,105,107,109,110}; 192 193 // Here's the reverse LUT. I got it by doing a 6-th order poly fit to the data and then 194 // solving for each temp value from -50 to 110. (n=161) 195 static const u16 viaLUT[] = {12,12,13,14,14,15,16,16,17,18,18,19,20,20,21,22,23,23,24,\ 196 25,26,27,28,29,30,31,32,33,35,36,37,39,40,41,43,45,46,48,49,51,53,55,57,59,60,62,64,66,\ 197 69,71,73,75,77,79,82,84,86,88,91,93,95,98,100,103,105,107,110,112,115,117,119,122,124,\ 198 126,129,131,134,136,138,140,143,145,147,150,152,154,156,158,160,162,164,166,168,170,\ 199 172,174,176,178,180,182,183,185,187,188,190,192,193,195,196,198,199,200,202,203,204,\ 200 205,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,222,223,224,225,\ 201 226,226,227,228,228,229,230,230,231,232,232,233,233,234,235,235,236,236,237,237,238,\ 202 238,239,239,240}; 188 203 189 204 // Converting temps to register values 190 205 extern inline u8 TEMP_TO_REG(long val) 191 206 { 192 val /= 10; 193 if (val<0x00) // val<0 194 return (u8)SENSORS_LIMIT(ROUND_INT(0.01864022*val*val + 2.12242751*val + 72.54159337),0,255); 195 else if (val<0x37) // val<55 196 return (u8)SENSORS_LIMIT(ROUND_INT(-0.00714790*val*val + 2.60844692*val + 70.67197155),0,255); 197 else 198 return (u8)SENSORS_LIMIT(ROUND_INT(-0.00991559*val*val + 2.48774551*val + 85.21011594),0,255); 199 207 // No interpolation here. 208 if (val<=-500) return (u8)SENSORS_LIMIT(viaLUT[0],0,255); 209 if (val>=1100) return (u8)SENSORS_LIMIT(viaLUT[160],0,255); 210 // the +5 effective rounds it off properly 211 return (u8)SENSORS_LIMIT(viaLUT[(val+5)/10+50],0,255); 200 212 } 201 213 … … 203 215 extern inline long TEMP_FROM_REG(u8 val) 204 216 { 205 if (val<0x47) // val<71 206 return (long)ROUND_INT(10.0*(-0.00831398*val*val + 1.46882437*val - 63.66742250)); 207 else if (val<0xbf) // val<191 208 return (long)ROUND_INT(10.0*(0.00056874*val*val + 0.29665581*val - 23.7538571)); 209 else 210 return (long)ROUND_INT(10.0*(0.01275451*val*val - 4.39034916*val + 428.14343750)); 217 // the LUT starts at 12 (not 0) and ends at 240 (not 255), so that's why we do what we do here. 218 return (long)(tempLUT[(val<11)?(0):((val>240)?(228):(val-12))]*10); 211 219 } 212 220 … … 214 222 extern inline long TEMP_FROM_REG10(u16 val) 215 223 { 216 if (val<0x011c) // val<284 217 return (long)ROUND_INT(10.0*(-0.00051962*val*val + 0.36720609*val - 63.6674225)); 218 else if (val<0x02fc) //val<764 219 return (long)ROUND_INT(10.0*(0.00004141*val*val + 0.06853503*val + -22.48959243)); 220 else 221 return (long)ROUND_INT(10.0*(0.00087626*val*val + -1.23656143*val + 488.97355989)); 222 224 u16 eightBits = val>>2; 225 u16 twoBits = val&3; 226 227 if (val<=48) return (long)tempLUT[0]*10; // via8bit<=12 228 if (val>=960) return (long)tempLUT[228]*10; // via8bit>=240 229 230 if (twoBits==0) 231 return (long)tempLUT[eightBits-12]*10; 232 else { 233 // do some interpolation by multipying the lower and uppers bounds by 25, 50 or 75 234 // (depending on which it's closer to), then /100. But since we need to *10 anyway, we only /10 235 // ***FIX THIS*** we should properly round this off 236 return (long)(((25*(4-twoBits))*tempLUT[eightBits-12] + (25*twoBits)*tempLUT[eightBits-11])/10); 237 } 223 238 } 224 239 … … 572 587 via686a_write_value(client, VIA686A_REG_FAN_MIN(2), 573 588 FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2)); 574 for(i = 1; i < 3; i++) {589 for(i = 1; i <= 3; i++) { 575 590 via686a_write_value(client, VIA686A_REG_TEMP_OVER(i), 576 591 TEMP_TO_REG(VIA686A_INIT_TEMP_OVER)); … … 615 630 VIA686A_REG_TEMP_HYST(i)); 616 631 } 617 /* add in lower 2 bits */ 632 /* add in lower 2 bits 633 temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1 634 temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 635 temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 636 */ 618 637 data->temp[0] |= (via686a_read_value(client, 619 638 VIA686A_REG_TEMP_LOW1) & 0xc0) >> 6;
