Remove LiveTV menu.
[vuplus_xbmc] / xbmc / utils / AMLUtils.cpp
1 /*
2  *      Copyright (C) 2011-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <string>
27
28 #include "utils/CPUInfo.h"
29 #include "utils/log.h"
30 #include "utils/StringUtils.h"
31
32 int aml_set_sysfs_str(const char *path, const char *val)
33 {
34   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
35   if (fd >= 0)
36   {
37     write(fd, val, strlen(val));
38     close(fd);
39     return 0;
40   }
41   return -1;
42 }
43
44 int aml_get_sysfs_str(const char *path, char *valstr, const int size)
45 {
46   int fd = open(path, O_RDONLY);
47   if (fd >= 0)
48   {
49     read(fd, valstr, size - 1);
50     valstr[strlen(valstr)] = '\0';
51     close(fd);
52     return 0;
53   }
54
55   sprintf(valstr, "%s", "fail");
56   return -1;
57 }
58
59 int aml_set_sysfs_int(const char *path, const int val)
60 {
61   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
62   if (fd >= 0)
63   {
64     char bcmd[16];
65     sprintf(bcmd, "%d", val);
66     write(fd, bcmd, strlen(bcmd));
67     close(fd);
68     return 0;
69   }
70   return -1;
71 }
72
73 int aml_get_sysfs_int(const char *path)
74 {
75   int val = -1;
76   int fd = open(path, O_RDONLY);
77   if (fd >= 0)
78   {
79     char bcmd[16];
80     read(fd, bcmd, sizeof(bcmd));
81     val = strtol(bcmd, NULL, 16);
82     close(fd);
83   }
84   return val;
85 }
86
87 bool aml_present()
88 {
89   static int has_aml = -1;
90   if (has_aml == -1)
91   {
92     int rtn = aml_get_sysfs_int("/sys/class/audiodsp/digital_raw");
93     if (rtn != -1)
94       has_aml = 1;
95     else
96       has_aml = 0;
97     if (has_aml)
98       CLog::Log(LOGNOTICE, "aml_present, rtn(%d)", rtn);
99   }
100   return has_aml == 1;
101 }
102
103 bool aml_hw3d_present()
104 {
105   static int has_hw3d = -1;
106   if (has_hw3d == -1)
107   {
108     if (aml_get_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode") != -1)
109       has_hw3d = 1;
110     else
111       has_hw3d = 0;
112   }
113   return has_hw3d == 1;
114 }
115
116 bool aml_wired_present()
117 {
118   static int has_wired = -1;
119   if (has_wired == -1)
120   {
121     char test[64] = {0};
122     if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1)
123       has_wired = 1;
124     else
125       has_wired = 0;
126   }
127   return has_wired == 1;
128 }
129
130 void aml_permissions()
131 {
132   if (!aml_present())
133     return;
134   
135   // most all aml devices are already rooted.
136   int ret = system("ls /system/xbin/su");
137   if (ret != 0)
138   {
139     CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
140   }
141   else
142   {
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");
154   }
155 }
156
157 int aml_get_cputype()
158 {
159   static int aml_cputype = -1;
160   if (aml_cputype == -1)
161   {
162     std::string cpu_hardware = g_cpuInfo.getCPUHardware();
163
164     // default to AMLogic M1
165     aml_cputype = 1;
166     if (cpu_hardware.find("MESON-M3") != std::string::npos)
167       aml_cputype = 3;
168     else if (cpu_hardware.find("MESON3") != std::string::npos)
169       aml_cputype = 3;
170     else if (cpu_hardware.find("Meson6") != std::string::npos)
171       aml_cputype = 6;
172   }
173
174   return aml_cputype;
175 }
176
177 void aml_cpufreq_min(bool limit)
178 {
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)
183   {
184     int cpufreq = 300000;
185     if (limit)
186       cpufreq = 600000;
187
188     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
189   }
190 #endif
191 }
192
193 void aml_cpufreq_max(bool limit)
194 {
195   if (!aml_wired_present() && aml_get_cputype() > 3)
196   {
197     // this is a MX Stick, they cannot substain 1GHz
198     // operation without overheating so limit them to 800MHz.
199     int cpufreq = 1000000;
200     if (limit)
201       cpufreq = 800000;
202
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");
205   }
206 }
207
208 void aml_set_audio_passthrough(bool passthrough)
209 {
210   if (aml_present())
211   {
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);
215   }
216 }
217
218 void aml_probe_hdmi_audio()
219 {
220   std::vector<CStdString> audio_formats;
221   // Audio {format, channel, freq, cce}
222   // {1, 7, 7f, 7}
223   // {7, 5, 1e, 0}
224   // {2, 5, 7, 0}
225   // {11, 7, 7e, 1}
226   // {10, 7, 6, 0}
227   // {12, 7, 7e, 0}
228
229   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
230   if (fd >= 0)
231   {
232     char valstr[1024] = {0};
233
234     read(fd, valstr, sizeof(valstr) - 1);
235     valstr[strlen(valstr)] = '\0';
236     close(fd);
237
238     std::vector<CStdString> probe_str;
239     StringUtils::SplitString(valstr, "\n", probe_str);
240
241     for (size_t i = 0; i < probe_str.size(); i++)
242     {
243       if (probe_str[i].find("Audio") == std::string::npos)
244       {
245         for (size_t j = i+1; j < probe_str.size(); j++)
246         {
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");
275           else
276             break;
277         }
278         break;
279       }
280     }
281   }
282 }