[release] version bump to 13.0 beta1
[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_wired_present()
104 {
105   static int has_wired = -1;
106   if (has_wired == -1)
107   {
108     char test[64] = {0};
109     if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1)
110       has_wired = 1;
111     else
112       has_wired = 0;
113   }
114   return has_wired == 1;
115 }
116
117 void aml_permissions()
118 {
119   if (!aml_present())
120     return;
121   
122   // most all aml devices are already rooted.
123   int ret = system("ls /system/xbin/su");
124   if (ret != 0)
125   {
126     CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
127   }
128   else
129   {
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");
140   }
141 }
142
143 int aml_get_cputype()
144 {
145   static int aml_cputype = -1;
146   if (aml_cputype == -1)
147   {
148     std::string cpu_hardware = g_cpuInfo.getCPUHardware();
149
150     // default to AMLogic M1
151     aml_cputype = 1;
152     if (cpu_hardware.find("MESON-M3") != std::string::npos)
153       aml_cputype = 3;
154     else if (cpu_hardware.find("MESON3") != std::string::npos)
155       aml_cputype = 3;
156     else if (cpu_hardware.find("Meson6") != std::string::npos)
157       aml_cputype = 6;
158   }
159
160   return aml_cputype;
161 }
162
163 void aml_cpufreq_min(bool limit)
164 {
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)
169   {
170     int cpufreq = 300000;
171     if (limit)
172       cpufreq = 600000;
173
174     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
175   }
176 #endif
177 }
178
179 void aml_cpufreq_max(bool limit)
180 {
181   if (!aml_wired_present() && aml_get_cputype() > 3)
182   {
183     // this is a MX Stick, they cannot substain 1GHz
184     // operation without overheating so limit them to 800MHz.
185     int cpufreq = 1000000;
186     if (limit)
187       cpufreq = 800000;
188
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");
191   }
192 }
193
194 void aml_set_audio_passthrough(bool passthrough)
195 {
196   if (aml_present())
197   {
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);
201   }
202 }
203
204 void aml_probe_hdmi_audio()
205 {
206   std::vector<CStdString> audio_formats;
207   // Audio {format, channel, freq, cce}
208   // {1, 7, 7f, 7}
209   // {7, 5, 1e, 0}
210   // {2, 5, 7, 0}
211   // {11, 7, 7e, 1}
212   // {10, 7, 6, 0}
213   // {12, 7, 7e, 0}
214
215   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
216   if (fd >= 0)
217   {
218     char valstr[1024] = {0};
219
220     read(fd, valstr, sizeof(valstr) - 1);
221     valstr[strlen(valstr)] = '\0';
222     close(fd);
223
224     std::vector<CStdString> probe_str;
225     StringUtils::SplitString(valstr, "\n", probe_str);
226
227     for (size_t i = 0; i < probe_str.size(); i++)
228     {
229       if (probe_str[i].find("Audio") == std::string::npos)
230       {
231         for (size_t j = i+1; j < probe_str.size(); j++)
232         {
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");
261           else
262             break;
263         }
264         break;
265       }
266     }
267   }
268 }