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
# $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)
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
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.
<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>
OBJ_ibm_volume,
OBJ_ibm_brightness,
OBJ_pb_battery,
+ OBJ_voltage_mv,
+ OBJ_voltage_v,
#endif /* __linux__ */
OBJ_if_existing,
OBJ_if_mounted,
{
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);
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 */
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);
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/"