root/lm-sensors/trunk/prog/pwm/pwmconfig @ 2187

Revision 2187, 14.4 KB (checked in by mds, 9 years ago)

initial 2.6 support

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/bin/bash
2#
3# pwmconfig v0.7
4# Tests the pwm outputs of sensors and configures fancontrol
5#
6#    Warning!!! This program will stop your fans, one at a time,
7#    for approximately 3 seconds each!!!
8#    This may cause your processor temperature to rise!!!
9#    Verify that all fans are running at normal speed after this
10#    program has exited!!!
11#
12#    Copyright 2003 The lm_sensors project <sensors@stimpy.netroedge.com>
13#
14#    This program is free software; you can redistribute it and/or modify
15#    it under the terms of the GNU General Public License as published by
16#    the Free Software Foundation; either version 2 of the License, or
17#    (at your option) any later version.
18#
19#    This program is distributed in the hope that it will be useful,
20#    but WITHOUT ANY WARRANTY; without even the implied warranty of
21#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22#    GNU General Public License for more details.
23#
24#    You should have received a copy of the GNU General Public License
25#    along with this program; if not, write to the Free Software
26#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27#
28#
29echo 'This program will search your sensors for pulse width modulation (pwm)'
30echo 'controls, and test each one to see if it controls a fan on'
31echo 'your motherboard. Note that many motherboards do not have pwm'
32echo 'circuitry installed, even if your sensor chip supports pwm.'
33echo
34echo 'We will attempt to briefly stop each fan using the pwm controls.'
35echo 'The program will attempt to restore each fan to full speed'
36echo 'after testing. However, it is ** very important ** that you'
37echo 'physically verify that the fans have been to full speed'
38echo 'after the program has completed.'
39echo
40
41DELAY=5 # 3 seconds delay is too short for large fans, thus I increased it to 5
42MAX=255
43
44DIR=/proc/sys/dev/sensors
45SDIR=/sys/bus/i2c/devices
46if [ ! -d $DIR ]
47then
48        if [ ! -d $SDIR ]
49        then
50                echo $0: 'No sensors found! (modprobe sensor modules?)'
51                exit 1
52        else
53                SYSFS=1
54                DIR=$SDIR
55        fi     
56fi
57
58cd $DIR
59DRIVERS=`echo *-*`
60if [ "*-*" = "$DRIVERS" ]
61then
62        echo $0: 'No sensors found! (modprobe sensor modules?)'
63        exit 1
64fi
65
66PWM=`echo */pwm[1-9]`
67if [ "*/pwm[1-9]" = "$PWM" ]
68then
69        echo $0: 'There are no pwm-capable sensor modules installed'
70        exit 1
71fi
72
73if [ "$SYSFS" = "1" ]
74then
75        MATCH='*/fan_input[1-9]'
76else
77        MATCH='*/fan[1-9]'
78fi
79FAN=`echo $MATCH`
80if [ "$MATCH" = "$FAN" ]
81then
82        echo $0: 'There are no fan-capable sensor modules installed'
83        exit 1
84fi
85
86function pwmdisable()
87{
88        if [ "$SYSFS" = "1" ]
89        then
90                echo $MAX > $1
91                ENABLE=${1/pwm/pwm_enable}
92                if [ -f $ENABLE ]
93                then
94                        echo 0 > $ENABLE
95                fi
96        else
97                echo $MAX 0 > $1
98        fi
99}
100
101function pwmenable()
102{
103        if [ "$SYSFS" = "1" ]
104        then
105                ENABLE=${1/pwm/pwm_enable}
106                if [ -f $ENABLE ]
107                then
108                        echo 1 > $ENABLE
109                fi
110        else
111                echo $MAX 1 > $1
112        fi
113}
114
115function pwmset()
116{
117        echo $2 > $1
118}
119
120echo 'Found the following PWM controls:'
121for i in $PWM
122do
123        echo "   $i"
124        if [ -w $i ]
125        then
126                pwmdisable $i
127        else
128                NOTROOT=1
129        fi
130done
131
132echo
133echo 'Found the following fan sensors:'
134for i in $FAN
135do
136        # this will return the first field if there's only one (sysfs)
137        S=`cat $i | cut -d' ' -f2`
138        if [ "$S" = "0" -o "$S" = "-1" ]
139        then
140                echo "   $i     current speed: 0 ... skipping!"
141        else
142                echo "   $i     current speed: $S RPM"
143                if [ "$GOODFAN" = "" ]
144                then
145                        GOODFAN=$i
146                        SPEEDS=$S
147                else
148                        GOODFAN="$GOODFAN $i"
149                        SPEEDS="$SPEEDS $S"
150                fi
151        fi
152done
153echo
154
155if [ "$GOODFAN" = "" ]
156then
157        echo 'There are no working fan sensors, all readings are 0.'
158        echo 'Make sure you have a 3-wire fan connected.'
159        echo 'You may also need to increase the fan divisors.'
160        echo 'See doc/fan-divisors for more information.'
161        exit 1
162fi
163
164if [ "$NOTROOT" = "1" ]
165then
166        echo 'As you are not root, we cannot write the PWM settings.'
167        echo 'Please run as root to continue.'
168        exit 1
169fi
170
171echo 'Warning!!! This program will stop your fans, one at a time,'
172echo "for approximately $DELAY seconds each!!!"
173echo 'This may cause your processor temperature to rise!!!'
174echo 'If you do not want to do this hit control-C now!!!'
175echo -n 'Hit return to continue: '
176read X
177echo
178
179PLOTTER=gnuplot
180STEP=15
181PDELAY=2
182
183function pwmdetail()
184{
185        P=$1
186        F=$2
187        PLOT=
188
189        type $PLOTTER > /dev/null 2>&1
190        if [ $? -eq 0 ]
191        then
192                echo -n "Would you like to generate a graphical plot using $PLOTTER (y)? "
193                read X
194                if [ "$X" = "y" -o "$X" = "Y" -o "$X" = "" ]
195                then
196                        PLOT=y         
197                fi
198        fi
199
200        if [ "$PLOT" = "y" ]
201        then
202                TMP1=/usr/tmp/pwmtest$$.1
203                TMP2=/usr/tmp/pwmtest$$.2
204                echo "set xlabel \"PWM: $P\"" > $TMP1
205                echo "set ylabel \"FAN: $F (RPM)\"" >> $TMP1
206                echo 'set nokey' >> $TMP1
207                echo 'set xrange [0:255]' >> $TMP1
208                echo "plot \"$TMP2\" with lines" >> $TMP1
209                echo 'pause -1 "    Hit return to continue..."' >> $TMP1
210                > $TMP2
211        fi
212
213        let pwm=$MAX
214        pwmenable $P
215        while [ $pwm -ge 0 ]
216        do
217                pwmset $P $pwm 
218                sleep $PDELAY
219                if [ $? -ne 0 ]
220                then
221                        pwmdisable $P   
222                        echo '^C received, aborting...'
223                        rm -f $TMP1 $TMP2
224                        exit 1
225                fi             
226                # this will return the first field if there's only one (sysfs)
227                S=`cat $F | cut -d' ' -f2`
228                echo "    PWM $pwm FAN $S"
229                if [ "$PLOT" = "y" ]
230                then
231                        echo "$pwm $S" >> $TMP2
232                fi
233                if [ "$S" = "0" -o "S" = "-1" ]
234                then
235                        pwmdisable $P   
236                        echo "    Fan Stopped at PWM = $pwm"
237                        if [ $pwm -eq $MAX ]
238                        then
239                                echo "    This fan appears to stop when the PWM is enabled;"
240                                echo "    perhaps the fan input shares a pin with the PWM output"
241                                echo "    on the sensor chip."
242                                echo "    You cannot control this fan with this PWM output."
243                                rm -f $TMP1 $TMP2
244                                echo
245                                return 0
246                        fi
247                        break
248                fi
249                let pwm=$pwm-$STEP
250        done
251        pwmdisable $P   
252        if [ "$PLOT" = "y" ]
253        then
254                $PLOTTER  $TMP1
255                rm -f $TMP1 $TMP2
256        fi
257        echo
258}
259
260for i in $PWM
261do
262        echo Testing pwm control $i ...
263        pwmenable $i
264        pwmset $i 0
265        sleep $DELAY
266        if [ $? -ne 0 ]
267        then
268                pwmdisable $i
269                echo '^C received, restoring PWM and aborting...'
270                exit 1
271        fi             
272        let pwmactivecount=0
273        let count=1
274        for j in $GOODFAN
275        do
276                OS=`echo $SPEEDS | cut -d' ' -f$count`
277                # this will return the first field if there's only one (sysfs)
278                S=`cat $j | cut -d' ' -f2`
279                echo "  $j ... speed was $OS now $S"
280                pwmdisable $i
281                let threshold=2*$OS/3
282                if [ $S -lt $threshold ]
283                then
284                        echo "    It appears that fan $j"
285                        echo "    is controlled by pwm $i"
286#
287# a PWM can control more than one fan....
288#
289                        if [ $pwmactivecount -eq 0 ]
290                        then
291                                let pwmactivecount=1
292                                pwmactive="$i ${pwmactive}"
293                        fi
294                        sleep $DELAY
295                        if [ $? -ne 0 ]
296                        then
297                                echo '^C received, aborting...'
298                                exit 1
299                        fi             
300                        # this will return the first field if there's only one (sysfs)
301                        S=`cat $j | cut -d' ' -f2`
302                        if [ $S -lt $threshold ]
303                        then
304                                echo "    Fan $j has not returned to speed, please investigate!"
305                        else
306                                echo -n "Would you like to generate a detailed correlation (y)? "
307                                read X
308                                if [ "$X" = "y" -o "$X" = "Y" -o "$X" = "" ]
309                                then
310                                        pwmdetail $i $j
311                                fi
312                        fi
313                else
314                        echo "    no correlation"
315                fi
316                let count=count+1
317        done
318        echo
319        if [ "$pwmactivecount" = "0" ]
320        then
321                echo "No correlations were detected."
322                echo "There is either no fan connected to the output of $i,"
323                echo "or the connected fan has no rpm-signal connected to one of"
324                echo "the tested fan sensors. (Note: not all motherboards have"
325                echo "the pwm outputs connected to the fan connectors,"
326                echo "check out the hardware database on http://www.almico.com/forumindex.php)"
327                echo
328                echo -n "Did you see/hear a fan stopping during the above test (n)? "
329                read X
330                if [ "$X" = "y" -o "$X" = "Y" ]
331                then
332                        pwmactive="$i ${pwmactive}"
333                fi
334                echo
335        fi
336done
337
338
339echo 'Testing is complete.'
340echo 'Please verify that all fans have returned to their normal speed.'
341echo
342echo 'The fancontrol script can automatically respond to temperature changes'
343echo 'of your system by changing fanspeeds.'
344echo -n 'Do you want to set up its configuration file now (y)? '
345
346read X
347if [ "$X" = "n" -o "$X" = "N" ]
348then
349        exit
350fi
351
352if [ "$SYSFS" = "1" ]
353then
354        MATCH='*/temp_input[1-9]'
355else
356        MATCH='*/temp[1-9]'
357fi
358TEMPS=`echo $MATCH`
359if [ "$MATCH" = "$TEMPS" ]
360then
361        echo $0: 'There are no temperature-capable sensor modules installed'
362        exit 1
363fi
364
365function AskPath {
366        echo -n 'What should be the path to your fancontrol config file (/etc/fancontrol)? '
367
368        read X
369        if [ "$X" = "y" -o "$X" = "Y" -o "$X" = "" ]
370        then
371                X=/etc/fancontrol
372        fi
373        if [ -f $X ]
374        then
375                FCCONFIG=$X
376        else
377                echo -n "$X does not exist, shall I create it now (y)? "
378                read Y
379                if [ "$Y" = "y" -o "$Y" = "Y" -o "$Y" = "" ]
380                then
381                        touch $X
382                        chmod 0660 $X
383                        chown root.root $X
384                        FCCONFIG=$X
385                else
386                        AskPath
387                fi
388        fi
389}
390
391AskPath
392
393function LoadConfig {
394        echo "Loading configuration from $1 ..."
395        INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'`
396        FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'`
397        MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'`
398        MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'`
399        MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'`
400        MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'`
401}
402
403LoadConfig $FCCONFIG
404
405function TestMinStart {
406        echo
407        echo 'Now we increase the PWM value in 10-unit-steps.'
408        echo 'Let the fan stop completely, then press return until the'
409        echo "fan starts spinning. Then enter 'y'."
410        echo 'We will use this value +20 as the starting speed.'
411        let fanok=0
412        let fanval=0
413        until [ "$fanok" = "1" ]
414        do
415                let fanval=fanval+10
416                if [ $fanval -gt 240 ] ; then let fanval=$MAX ; let fanok=1 ; fi
417                echo -n "Setting $pwms to $fanval..."
418                echo $fanval > $pwms
419                read FANTEST
420                if [ "$FANTEST" != "" ] ; then let fanok=1 ; fi
421        done
422        let fanval=fanval+20
423        if [ $fanval -gt 240 ] ; then let fanval=$MAX ; fi
424        echo "OK, using $fanval"
425        echo $MAX > $pwms
426}
427
428function TestMinStop {
429        echo
430        echo 'Now we decrease the PWM value in 10-unit-steps.'
431        echo 'Let the fan reach full speed, then press return until the'
432        echo "fan stops spinning. Then enter 'y'."
433        echo 'We will use this value +20 as the minimum speed.'
434        let fanok=0
435        let fanval=$MAX
436        until [ "$fanok" = "1" ]
437        do
438                let fanval=fanval-10
439                if [ $fanval -lt 0 ] ; then let fanval=0 ; let fanok=1 ; fi
440                echo -n "Setting $pwms to $fanval..."
441                echo $fanval > $pwms
442                read FANTEST
443                if [ "$FANTEST" != "" ] ; then let fanok=1 ; fi
444        done
445        let fanval=fanval+20
446        if [ $fanval -gt $MAX ] ; then let fanval=$MAX ; fi
447        echo "OK, using $fanval"
448        echo $MAX > $pwms
449}
450
451function SaveConfig {
452        echo
453        echo "Saving configuration to $FCCONFIG..."
454        egrep -v '(INTERVAL|FCTEMPS|MAXTEMP|MINTEMP|MINSTART|MINSTOP)' /etc/fancontrol >/tmp/fancontrol
455        echo -e "INTERVAL=$INTERVAL\nFCTEMPS=$FCTEMPS\nMINTEMP=$MINTEMP\nMAXTEMP=$MAXTEMP\nMINSTART=$MINSTART\nMINSTOP=$MINSTOP" >>/tmp/fancontrol
456        mv /tmp/fancontrol /etc/fancontrol
457        #check if file was written correctly
458        echo 'Configuration saved'
459}
460
461#function LoadConfig {
462#}
463
464INTERVAL=10
465PS3='select (1-n): '
466DEFMINTEMP=0
467DEFMAXTEMP=60
468DEFMINSTART=150
469DEFMINSTOP=100
470
471#the section below has a high potential for usability improvements
472echo
473echo 'Select fan output to configure, or other action:'
474select pwms in $pwmactive "Change INTERVAL" "Just quit" "Save and quit" "Show configuration"; do
475        case $pwms in
476        "Change INTERVAL")
477                echo
478                echo "Current interval is $INTERVAL seconds."
479                echo -n "Enter the interval at which fancontrol should update PWM values (in s):"
480                read INTERVAL ;; #check user input here
481        "Just quit")
482                exit ;;
483        "Save and quit")
484                SaveConfig
485                exit ;;
486        "Show configuration")
487                echo
488                echo "Common Settings:"
489                echo "INTERVAL=$INTERVAL"
490                for pwmo in $pwmactive
491                do
492                        echo
493                        echo "Settings of ${pwmo}:"
494                        echo "  Depends on `echo $FCTEMPS |sed -e 's/ /\n/g' |egrep \"${pwmo}\" |sed -e 's/.*=//g'`"
495                        echo "  MINTEMP=`echo $MINTEMP |sed -e \"s/ /\n/g\" |egrep \"${pwmo}\" |sed -e \"s/.*=//g\"`"
496                        echo "  MAXTEMP=`echo $MAXTEMP |sed -e \"s/ /\n/g\" |egrep \"${pwmo}\" |sed -e \"s/.*=//g\"`"
497                        echo "  MINSTART=`echo $MINSTART |sed -e \"s/ /\n/g\" |egrep \"${pwmo}\" |sed -e \"s/.*=//g\"`"
498                        echo "  MINSTOP=`echo $MINSTOP |sed -e \"s/ /\n/g\" |egrep \"${pwmo}\" |sed -e \"s/.*=//g\"`"
499                done
500                echo ;;
501
502        "`echo ${pwmactive} |sed -e 's/ /\n/g' | egrep \"${pwms}\"`" )
503                pwmsed=`echo ${pwms} | sed -e 's/\//\\\\\//g'` #escape / for sed
504                echo
505                echo 'Current temperature readings are as follows:'
506                for j in $TEMPS
507                do
508                        # this will return the first field if there's only one (sysfs)
509                        S=`cat $j | cut -d' ' -f3`
510                        if [ "$SYSFS" = "1" ]
511                        then
512                                let S="$S / 1000"
513                        fi
514                        echo "$j        $S"
515                done
516                echo
517                echo "Select a temperature sensor as source for ${pwms}:"
518                select tempss in $TEMPS "None (Do not affect this PWM output)"; do
519                        if [ "$tempss" = "None (Do not affect this PWM output)" ]
520                        then
521                       
522                                break;
523                        else
524                                if [ "$FCTEMPS" = "" ]
525                                then
526                                        FCTEMPS="${pwms}=${tempss}"
527                                else
528                                        FCTEMPS="`echo $FCTEMPS | sed -e "s/${pwmsed}[^ ]* *//g\"` ${pwms}=${tempss}"
529                                fi
530                        fi
531                        echo
532                        echo 'Enter the low temperature (C)'
533                        echo -n "at which the fan should be switched off ($DEFMINTEMP): "
534                        read XMT
535                        if [ "$XMT" = "" ]
536                        then
537                                XMT=$DEFMINTEMP
538                        fi
539                        if [ "$MINTEMP" = "" ]
540                        then
541                                MINTEMP="${pwms}=${XMT}"
542                        else
543                                MINTEMP="`echo $MINTEMP | sed -e \"s/${pwmsed}[^ ]* *//g\"` ${pwms}=${XMT}"
544                        fi
545                        echo
546                        echo 'Enter the high temperature (C)'
547                        echo -n "at which the fan should be switched to full speed ($DEFMAXTEMP): "
548                        read XMT
549                        if [ "$XMT" = "" ]
550                        then
551                                XMT=$DEFMAXTEMP
552                        fi
553                        if [ "$MAXTEMP" = "" ]
554                        then
555                                MAXTEMP="${pwms}=${XMT}"
556                        else
557                                MAXTEMP="`echo $MAXTEMP | sed -e \"s/${pwmsed}[^ ]* *//g\"` ${pwms}=${XMT}"
558                        fi
559                        echo
560                        echo "Enter the minimum PWM value (0-$MAX)"
561                        echo -n "at which the fan STARTS spinning (press t to test) ($DEFMINSTART): "
562                        read XMV
563                        if [ "$XMV" = "" ]
564                        then
565                                XMV=$DEFMINSTART
566                        fi
567                        if [ "$XMV" = "t" -o "$XMV" = "T" ]
568                        then
569                                TestMinStart
570                                XMV=$fanval
571                        fi
572                        if [ "$MINSTART" = "" ]
573                        then
574                                MINSTART="${pwms}=${XMV}"
575                        else
576                                MINSTART="`echo $MINSTART | sed -e \"s/${pwmsed}[^ ]* *//g\"` ${pwms}=${XMV}"
577                        fi
578                        echo
579                        echo "Enter the minimum PWM value (0-$MAX)"
580                        echo -n "at which the fan STOPS spinning (press t to test) ($DEFMINSTOP): "
581                        read XMV
582                        if [ "$XMV" = "" ]
583                        then
584                                XMV=$DEFMINSTOP
585                        fi
586                        if [ "$XMV" = "t" -o "$XMV" = "T" ]
587                        then
588                                TestMinStop
589                                XMV=$fanval
590                        fi
591                        if [ "$MINSTOP" = "" ]
592                        then
593                                MINSTOP="${pwms}=${XMV}"
594                        else
595                                MINSTOP="`echo $MINSTOP | sed -e \"s/${pwmsed}[^ ]* *//g\"` ${pwms}=${XMV}"
596                        fi
597                        echo
598                        break;
599                done ;;
600       
601        *)
602                grep $pwm
603
604                echo "No such option. Enter a number." ;;
605        esac
606done
Note: See TracBrowser for help on using the browser.