With the code from Ktoonsez to allow the control of the GPU voltage added to my Galaxy S4 kernel, one could now adjust the voltage of each stage of the GPU frequencies. However, until now, to the best of my knowledge, the only way to control it is to manually edit or echo the digits into the /sys/devices/system/cpu/cpufreq/vdd_table/gpu_vdd_levels file, which is a lot to type in the terminal app of the phone.
Since that was rather cumbersome, I felt that an app would be a more convenient method to control that function. while creating this app, I learned so much along the way, and I would like to take a few posts to break that down into groups. For now, here is the source on GitHub:
https://github.com/alaskalinuxuser/S4_GPU_voltage_control_app
And a download link for the app itself: http://www.mediafire.com/file/hk5vcce0s5r6kb7/GpuVoltageControl_1.0.apk
And here is a screenshot and the code, which is also available on GitHub, with some instructions.
AndroidManifest.xml
[CODE]
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.alaskalinuxuser.gvc” >
<uses-permission android:name=”android.permission.ACCESS_SUPERUSER” />
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />
<application
android:allowBackup=”true”
android:icon=”@drawable/gvcs4icon”
android:label=”@string/app_name” >
<activity
android:name=”.MainActivity”
android:label=”@string/app_name” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>
</manifest>
Contact GitHub API Training Shop Blog About
[/CODE]
main.xml
[CODE]
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:gravity=”top|center”
android:orientation=”vertical”
android:background=”#2D2D2D”>
<TextView
android:text=”GPU Voltage Control”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:gravity=”center”
android:background=”#04B1B3″
android:textSize=”20sp”
android:textColor=”#FFFFFF”/>
<TextView
android:layout_height=”wrap_content”
android:layout_width=”wrap_content”
android:text=”This is inhearently dangerous! Proceed with caution!”
android:gravity=”center”
android:textColor=”#FF0000″/>
<Button
android:layout_height=”wrap_content”
android:layout_width=”150dp”
android:text=”Undervolt GPU”
android:id=”@+id/uvButton”/>
<Button
android:layout_height=”wrap_content”
android:layout_width=”150dp”
android:text=”Set to Default”
android:id=”@+id/dfButton”
android:layout_margin=”5dp”/>
<Button
android:layout_height=”wrap_content”
android:layout_width=”150dp”
android:text=”Overvolt GPU”
android:id=”@+id/ovButton”/>
<Button
android:layout_height=”wrap_content”
android:layout_width=”150dp”
android:text=”Exit the App”
android:id=”@+id/exitButton”
android:layout_margin=”5dp”/>
<TextView
android:layout_height=”wrap_content”
android:layout_width=”wrap_content”
android:text=”This is inhearently dangerous! Proceed with caution!”
android:gravity=”center”
android:textColor=”#FF0000″
android:layout_gravity=”center”/>
<TextView
android:layout_height=”wrap_content”
android:layout_width=”wrap_content”
android:text=”This program is only for kernels that support Faux123’s GPU voltage control. This app is specifically written for the AKLU kernel on the JFLTE family of phones.”
android:textColor=”#FFFFFF”
android:gravity=”center”
android:layout_margin=”5dp”/>
</LinearLayout>
[/CODE]
And the MainActivity.java
[CODE]
package com.alaskalinuxuser.gvc;
// import our libraries
import android.app.*;
import java.util.*;
import java.*;
import java.lang.*;
import android.*;
import java.io.*;
import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
import android.os.*;
public class MainActivity extends Activity
{
// list the buttons
Button dFButton;
Button oVButton;
Button uVButton;
Button exiTButton;
// declare the gpu file
File gpu = new File(“/sys/devices/system/cpu/cpufreq/vdd_table/gpu_vdd_levels”);
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// check if the file exists
if(gpu.exists()){
System.out.println(“gpu exists”);
} else {
Toast.makeText(this, “This kernel does not support this action!”, Toast.LENGTH_SHORT).show();
finish();
}
// read the file for the current status
try {
FileInputStream fIn = new FileInputStream(gpu);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String aDataRow = “”;
String aBuffer = “”;
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + “\n”;
}
// get first 3 characters
String result = aBuffer.toString().substring(0, 3);
// if overvolted, tell the user
if (result.equals(“955”)) {
Toast.makeText(getBaseContext(),
“GPU is currently overvolted.”,
Toast.LENGTH_LONG).show();
} else {
// do nothing
}
// if undervolted, tell the user
if (result.equals(“935”)) {
Toast.makeText(getBaseContext(),
“GPU is currently undervolted.”,
Toast.LENGTH_LONG).show();
} else {
System.out.println(result);
}
// if default, tell the user
if (result.equals(“945”)) {
Toast.makeText(getBaseContext(),
“GPU is currently set to default.”,
Toast.LENGTH_LONG).show();
} else {
System.out.println(result);
}
myReader.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
// first up, the over volt button
oVButton = (Button) findViewById(R.id.ovButton);
oVButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
// the command to run
String[] pwrUp = { “su”, “-c”, “echo ‘955000\n1150000\n1250000’ > /sys/devices/system/cpu/cpufreq/vdd_table/gpu_vdd_levels” };
Runtime.getRuntime().exec(pwrUp);
// tell the user
Toast.makeText(getBaseContext(),
“GPU overvolted by 10 mV!”,
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// tell the user the problem
e.printStackTrace();
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
// next up, the under volt button
uVButton = (Button) findViewById(R.id.uvButton);
uVButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
// the command to run
String[] pwrDown = { “su”, “-c”, “echo ‘935000\n950000\n1050000’ > /sys/devices/system/cpu/cpufreq/vdd_table/gpu_vdd_levels” };
Runtime.getRuntime().exec(pwrDown);
// tell the user
Toast.makeText(getBaseContext(),
“GPU undervolted 10 mV!”,
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// tell the user the problem
e.printStackTrace();
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
// next up, the default volt button
dFButton = (Button) findViewById(R.id.dfButton);
dFButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
// the command to run
String[] pwrDef = { “su”, “-c”, “echo ‘945000\n1050000\n1150000’ > /sys/devices/system/cpu/cpufreq/vdd_table/gpu_vdd_levels” };
Runtime.getRuntime().exec(pwrDef);
// tell the user
Toast.makeText(getBaseContext(),
“GPU set to default voltage!”,
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// tell the user the problem
e.printStackTrace();
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
// now the exit button
exiTButton = (Button) findViewById(R.id.exitButton);
exiTButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// exit the app
finish();
}
});
}
}
[/CODE]
Remember, this app is only for the AKLU kernels for the S4. I am not responsible if you use this on some other phone or kernel which it was not designed for.
Linux – keep it simple.