2 * Copyright (C) 2011-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
28 #include "utils/CPUInfo.h"
29 #include "utils/log.h"
30 #include "utils/StringUtils.h"
32 int aml_set_sysfs_str(const char *path, const char *val)
34 int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
37 write(fd, val, strlen(val));
44 int aml_get_sysfs_str(const char *path, char *valstr, const int size)
46 int fd = open(path, O_RDONLY);
49 read(fd, valstr, size - 1);
50 valstr[strlen(valstr)] = '\0';
55 sprintf(valstr, "%s", "fail");
59 int aml_set_sysfs_int(const char *path, const int val)
61 int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
65 sprintf(bcmd, "%d", val);
66 write(fd, bcmd, strlen(bcmd));
73 int aml_get_sysfs_int(const char *path)
76 int fd = open(path, O_RDONLY);
80 read(fd, bcmd, sizeof(bcmd));
81 val = strtol(bcmd, NULL, 16);
89 static int has_aml = -1;
92 int rtn = aml_get_sysfs_int("/sys/class/audiodsp/digital_raw");
98 CLog::Log(LOGNOTICE, "aml_present, rtn(%d)", rtn);
103 bool aml_hw3d_present()
105 static int has_hw3d = -1;
108 if (aml_get_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode") != -1)
113 return has_hw3d == 1;
116 bool aml_wired_present()
118 static int has_wired = -1;
122 if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1)
127 return has_wired == 1;
130 void aml_permissions()
135 // most all aml devices are already rooted.
136 int ret = system("ls /system/xbin/su");
139 CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
143 // certain aml devices have 664 permission, we need 666.
144 system("su -c chmod 666 /sys/class/video/axis");
145 system("su -c chmod 666 /sys/class/video/screen_mode");
146 system("su -c chmod 666 /sys/class/video/disable_video");
147 system("su -c chmod 666 /sys/class/tsync/pts_pcrscr");
148 system("su -c chmod 666 /sys/class/audiodsp/digital_raw");
149 system("su -c chmod 666 /sys/class/ppmgr/ppmgr_3d_mode");
150 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
151 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
152 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
153 CLog::Log(LOGINFO, "aml_permissions: permissions changed");
157 int aml_get_cputype()
159 static int aml_cputype = -1;
160 if (aml_cputype == -1)
162 std::string cpu_hardware = g_cpuInfo.getCPUHardware();
164 // default to AMLogic M1
166 if (cpu_hardware.find("MESON-M3") != std::string::npos)
168 else if (cpu_hardware.find("MESON3") != std::string::npos)
170 else if (cpu_hardware.find("Meson6") != std::string::npos)
177 void aml_cpufreq_min(bool limit)
179 // do not touch scaling_min_freq on android
180 #if !defined(TARGET_ANDROID)
181 // only needed for m1/m3 SoCs
182 if (aml_get_cputype() <= 3)
184 int cpufreq = 300000;
188 aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
193 void aml_cpufreq_max(bool limit)
195 if (!aml_wired_present() && aml_get_cputype() > 3)
197 // this is a MX Stick, they cannot substain 1GHz
198 // operation without overheating so limit them to 800MHz.
199 int cpufreq = 1000000;
203 aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq);
204 aml_set_sysfs_str("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand");
208 void aml_set_audio_passthrough(bool passthrough)
212 // m1 uses 1, m3 and above uses 2
213 int raw = aml_get_cputype() < 3 ? 1:2;
214 aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
218 void aml_probe_hdmi_audio()
220 std::vector<CStdString> audio_formats;
221 // Audio {format, channel, freq, cce}
229 int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
232 char valstr[1024] = {0};
234 read(fd, valstr, sizeof(valstr) - 1);
235 valstr[strlen(valstr)] = '\0';
238 std::vector<CStdString> probe_str;
239 StringUtils::SplitString(valstr, "\n", probe_str);
241 for (size_t i = 0; i < probe_str.size(); i++)
243 if (probe_str[i].find("Audio") == std::string::npos)
245 for (size_t j = i+1; j < probe_str.size(); j++)
247 if (probe_str[i].find("{1,") != std::string::npos)
248 printf(" PCM found {1,\n");
249 else if (probe_str[i].find("{2,") != std::string::npos)
250 printf(" AC3 found {2,\n");
251 else if (probe_str[i].find("{3,") != std::string::npos)
252 printf(" MPEG1 found {3,\n");
253 else if (probe_str[i].find("{4,") != std::string::npos)
254 printf(" MP3 found {4,\n");
255 else if (probe_str[i].find("{5,") != std::string::npos)
256 printf(" MPEG2 found {5,\n");
257 else if (probe_str[i].find("{6,") != std::string::npos)
258 printf(" AAC found {6,\n");
259 else if (probe_str[i].find("{7,") != std::string::npos)
260 printf(" DTS found {7,\n");
261 else if (probe_str[i].find("{8,") != std::string::npos)
262 printf(" ATRAC found {8,\n");
263 else if (probe_str[i].find("{9,") != std::string::npos)
264 printf(" One_Bit_Audio found {9,\n");
265 else if (probe_str[i].find("{10,") != std::string::npos)
266 printf(" Dolby found {10,\n");
267 else if (probe_str[i].find("{11,") != std::string::npos)
268 printf(" DTS_HD found {11,\n");
269 else if (probe_str[i].find("{12,") != std::string::npos)
270 printf(" MAT found {12,\n");
271 else if (probe_str[i].find("{13,") != std::string::npos)
272 printf(" ATRAC found {13,\n");
273 else if (probe_str[i].find("{14,") != std::string::npos)
274 printf(" WMA found {14,\n");