cpu voltage patch
authorBrenden Matthews <brenden1@rty.ca>
Wed, 24 May 2006 00:23:47 +0000 (00:23 +0000)
committerBrenden Matthews <brenden1@rty.ca>
Wed, 24 May 2006 00:23:47 +0000 (00:23 +0000)
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@657 7f574dfc-610e-0410-a909-a81674777703

AUTHORS
ChangeLog
README
doc/conky.1
doc/variables.xml
src/conky.c
src/conky.h
src/linux.c

diff --git a/AUTHORS b/AUTHORS
index 28a9655..8fb7486 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -138,6 +138,7 @@ Pascal Eberhard <pascal dor eberhard at gmail dot com>
 Peter Tarjan <ptarjan at citromail dot hu>
   IBM acpi support patch
   SMP support for freq stuff
+  CPU voltage patch
   
 Petr Holub <hopet@users.sourceforge.net>  
   fix autotools on FreeBSD in autogen.sh
index 8478719..62fc87a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 # $Id$
 
+2006-05-23
+       * CPU voltage support via $voltage_mv and $voltage_v (thanks to Peter
+       Tarjan for the patch)
+
 2006-05-21
        * SMP support for $freq and $freq_g (thanks to Peter Tarjan for the
        patch)
diff --git a/README b/README
index d66a21c..d117ade 100644 (file)
--- a/README
+++ b/README
@@ -561,6 +561,16 @@ VARIABLES
              omitted, the parameter defaults to 1.
 
 
+       voltage_mv (n)
+             Returns CPU #n's voltage in mV. CPUs  are  counted  from  1.  If
+             omitted, the parameter defaults to 1.
+
+
+       voltage_v (n)
+             Returns CPU #n's voltage in V. CPUs are counted from 1. If omit-
+             ted, the parameter defaults to 1.
+
+
        freq_dyn
              Returns CPU frequency in MHz, but is calculated by  counting  to
              clock  cycles  to  complete  an  instruction. Only available for
index 5b9a15e..b4a6f79 100644 (file)
@@ -513,6 +513,18 @@ counted from 1. If omitted, the parameter
 defaults to 1.
 
 .TP 
+\fBvoltage_mv\fR \fB(n)\fR 
+Returns CPU #n's voltage in mV. CPUs are
+counted from 1. If omitted, the parameter
+defaults to 1. 
+
+.TP 
+\fBvoltage_v\fR \fB(n)\fR 
+Returns CPU #n's voltage in V. CPUs are
+counted from 1. If omitted, the parameter
+defaults to 1.
+
+.TP 
 \fBfreq_dyn\fR 
 Returns CPU frequency in MHz, but is calculated by counting to clock cycles to complete an instruction. Only available for x86/amd64.
 
index d9abf2a..2a8122b 100644 (file)
        
        <varlistentry>
                <term>
+                       <command><option>voltage_mv</option></command>
+                       <option>(n)</option>
+               </term>
+               <listitem>
+                       Returns CPU #n's voltage in mV. CPUs are
+                       counted from 1. If omitted, the parameter
+                       defaults to 1. 
+                       <para></para></listitem>
+       </varlistentry>
+       <varlistentry>
+               <term>
+                       <command><option>voltage_v</option></command>
+                       <option>(n)</option>
+               </term>
+               <listitem>
+                       Returns CPU #n's voltage in V. CPUs are
+                       counted from 1. If omitted, the parameter
+                       defaults to 1.
+                       <para></para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+               <term>
                        <command><option>freq_dyn</option></command>
                </term>
                <listitem>
index 15767b9..006334b 100644 (file)
@@ -873,6 +873,8 @@ enum text_object_type {
        OBJ_ibm_volume,
        OBJ_ibm_brightness,
         OBJ_pb_battery,
+       OBJ_voltage_mv,
+       OBJ_voltage_v,
 #endif /* __linux__ */
        OBJ_if_existing,
        OBJ_if_mounted,
@@ -2009,6 +2011,36 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        {
            obj->data.cpu_index=atoi(&arg[0]);
        }
+       END OBJ(voltage_mv, 0)
+           get_cpu_count();
+       if (!arg
+           || !isdigit(arg[0])
+           || strlen(arg) >=2
+           || atoi(&arg[0])==0
+           || (unsigned int)atoi(&arg[0])>info.cpu_count)
+       {
+           obj->data.cpu_index=1;
+           ERR("voltage_mv: Invalid CPU number or you don't have that many CPUs! Displaying voltage for CPU 1.");
+       }
+       else 
+       {
+           obj->data.cpu_index=atoi(&arg[0]);
+       }
+       END OBJ(voltage_v, 0)
+           get_cpu_count();
+       if (!arg
+           || !isdigit(arg[0])
+           || strlen(arg) >=2
+           || atoi(&arg[0])==0
+           || (unsigned int)atoi(&arg[0])>info.cpu_count)
+       {
+           obj->data.cpu_index=1;
+           ERR("voltage_v: Invalid CPU number or you don't have that many CPUs! Displaying voltage for CPU 1.");
+       }
+       else 
+       {
+           obj->data.cpu_index=atoi(&arg[0]);
+       }
 #else 
        END OBJ(freq, 0);
        END OBJ(freq_g, 0);
@@ -3128,6 +3160,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                OBJ(freq_g) {
                                        get_freq(p, p_max_size, "%'.2f", 1000, obj->data.cpu_index); /* pk */
                                }
+                               OBJ(voltage_mv) {
+                                       get_voltage(p, p_max_size, "%.0f", 1, obj->data.cpu_index); /* ptarjan */
+                               }
+                               OBJ(voltage_v) {
+                                       get_voltage(p, p_max_size, "%'.3f", 1000, obj->data.cpu_index); /* ptarjan */
+                               }
+
                                OBJ(freq_dyn) {
                                        if (use_spacer) {
                                                get_freq_dynamic(p, 6, "%.0f     ", 1 ); /* pk */
index a228bec..64959f7 100644 (file)
@@ -463,6 +463,7 @@ void update_running_processes(void);
 void update_i8k(void);
 void get_freq( char *, size_t, char *, int, unsigned int ); /* pk */
 void get_freq_dynamic( char *, size_t, char *, int ); /* pk */
+void get_voltage(char *, size_t, char *, int, unsigned int ); /* ptarjan */
 void update_load_average();
 int open_i2c_sensor(const char *dev, const char *type, int n, int *div,
                    char *devtype);
index 9eeb657..53c93c6 100644 (file)
@@ -918,6 +918,84 @@ void get_freq( char * p_client_buffer, size_t client_buffer_size, char * p_forma
        return;
 }
 
+#define CPUFREQ_VOLTAGE "cpufreq/scaling_voltages"
+
+/* return cpu voltage in mV (use divisor=1) or V (use divisor=1000) */
+void get_voltage( char * p_client_buffer, size_t client_buffer_size, char * p_format, int divisor, unsigned int cpu )
+{
+/* /sys/devices/system/cpu/cpu0/cpufreq/scaling_voltages looks 
+   something like this:
+# frequency voltage
+1800000 1340
+1600000 1292
+1400000 1100
+1200000 988
+1000000 1116
+800000 1004
+600000 988
+*/
+
+/* Peter Tarjan (ptarjan@citromail.hu) */
+       FILE *f;
+       char s[256];
+       int freq = 0;
+       int voltage = 0;
+       char current_freq_file[128];
+       int freq_comp = 0;
+       
+
+/* build the voltage file name */
+       cpu--;
+       snprintf(current_freq_file, 127, "%s/cpu%d/%s",
+                CPUFREQ_PREFIX, cpu, CPUFREQ_POSTFIX);
+
+       if ( !p_client_buffer || client_buffer_size <= 0 || !p_format || divisor <= 0 )
+               return;
+
+       /* read the current cpu frequency from the /sys node */
+       f = fopen(current_freq_file, "r");
+       if (f) {
+           if (fgets(s, sizeof(s), f)) {
+               s[strlen(s)-1] = '\0';
+               freq = strtod(s, NULL);
+           }
+           fclose(f);
+       }
+       else 
+           {
+               ERR("voltage: No %s.", current_freq_file);
+               fclose(f);
+               return;
+           }
+
+       snprintf(current_freq_file, 127, "%s/cpu%d/%s",
+                CPUFREQ_PREFIX, cpu, CPUFREQ_VOLTAGE);
+
+/* use the current cpu frequency to find the corresponding voltage */
+       f = fopen(current_freq_file, "r");
+
+       if (f)
+       {
+           while (!feof(f))
+           {
+               char line[256];
+               if (fgets(line, 255, f) == NULL) break;
+               sscanf(line, "%d %d", &freq_comp, &voltage);
+               if(freq_comp == freq) break;
+           }
+           fclose(f);
+       }
+       else
+       {
+           ERR("voltage: No %s.", current_freq_file);
+           fclose(f);
+           return;
+       }
+
+       snprintf( p_client_buffer, client_buffer_size, p_format, (float)voltage/divisor );
+       return;
+
+}
 
 #define ACPI_FAN_DIR "/proc/acpi/fan/"