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_wired_present()
105 static int has_wired = -1;
109 if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1)
114 return has_wired == 1;
117 void aml_permissions()
122 // most all aml devices are already rooted.
123 int ret = system("ls /system/xbin/su");
126 CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
130 // certain aml devices have 664 permission, we need 666.
131 system("su -c chmod 666 /sys/class/video/axis");
132 system("su -c chmod 666 /sys/class/video/screen_mode");
133 system("su -c chmod 666 /sys/class/video/disable_video");
134 system("su -c chmod 666 /sys/class/tsync/pts_pcrscr");
135 system("su -c chmod 666 /sys/class/audiodsp/digital_raw");
136 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
137 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
138 system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
139 CLog::Log(LOGINFO, "aml_permissions: permissions changed");
143 int aml_get_cputype()
145 static int aml_cputype = -1;
146 if (aml_cputype == -1)
148 std::string cpu_hardware = g_cpuInfo.getCPUHardware();
150 // default to AMLogic M1
152 if (cpu_hardware.find("MESON-M3") != std::string::npos)
154 else if (cpu_hardware.find("MESON3") != std::string::npos)
156 else if (cpu_hardware.find("Meson6") != std::string::npos)
163 void aml_cpufreq_min(bool limit)
165 // do not touch scaling_min_freq on android
166 #if !defined(TARGET_ANDROID)
167 // only needed for m1/m3 SoCs
168 if (aml_get_cputype() <= 3)
170 int cpufreq = 300000;
174 aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
179 void aml_cpufreq_max(bool limit)
181 if (!aml_wired_present() && aml_get_cputype() > 3)
183 // this is a MX Stick, they cannot substain 1GHz
184 // operation without overheating so limit them to 800MHz.
185 int cpufreq = 1000000;
189 aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq);
190 aml_set_sysfs_str("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand");
194 void aml_set_audio_passthrough(bool passthrough)
198 // m1 uses 1, m3 and above uses 2
199 int raw = aml_get_cputype() < 3 ? 1:2;
200 aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
204 void aml_probe_hdmi_audio()
206 std::vector<CStdString> audio_formats;
207 // Audio {format, channel, freq, cce}
215 int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
218 char valstr[1024] = {0};
220 read(fd, valstr, sizeof(valstr) - 1);
221 valstr[strlen(valstr)] = '\0';
224 std::vector<CStdString> probe_str;
225 StringUtils::SplitString(valstr, "\n", probe_str);
227 for (size_t i = 0; i < probe_str.size(); i++)
229 if (probe_str[i].find("Audio") == std::string::npos)
231 for (size_t j = i+1; j < probe_str.size(); j++)
233 if (probe_str[i].find("{1,") != std::string::npos)
234 printf(" PCM found {1,\n");
235 else if (probe_str[i].find("{2,") != std::string::npos)
236 printf(" AC3 found {2,\n");
237 else if (probe_str[i].find("{3,") != std::string::npos)
238 printf(" MPEG1 found {3,\n");
239 else if (probe_str[i].find("{4,") != std::string::npos)
240 printf(" MP3 found {4,\n");
241 else if (probe_str[i].find("{5,") != std::string::npos)
242 printf(" MPEG2 found {5,\n");
243 else if (probe_str[i].find("{6,") != std::string::npos)
244 printf(" AAC found {6,\n");
245 else if (probe_str[i].find("{7,") != std::string::npos)
246 printf(" DTS found {7,\n");
247 else if (probe_str[i].find("{8,") != std::string::npos)
248 printf(" ATRAC found {8,\n");
249 else if (probe_str[i].find("{9,") != std::string::npos)
250 printf(" One_Bit_Audio found {9,\n");
251 else if (probe_str[i].find("{10,") != std::string::npos)
252 printf(" Dolby found {10,\n");
253 else if (probe_str[i].find("{11,") != std::string::npos)
254 printf(" DTS_HD found {11,\n");
255 else if (probe_str[i].find("{12,") != std::string::npos)
256 printf(" MAT found {12,\n");
257 else if (probe_str[i].find("{13,") != std::string::npos)
258 printf(" ATRAC found {13,\n");
259 else if (probe_str[i].find("{14,") != std::string::npos)
260 printf(" WMA found {14,\n");