Merge pull request #3195 from afedchin/win_vsync_def
[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   // most all aml devices are already rooted.
120   int ret = system("ls /system/xbin/su");
121   if (ret != 0)
122   {
123     CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
124   }
125   else
126   {
127     // certain aml devices have 664 permission, we need 666.
128     system("su -c chmod 666 /sys/class/video/axis");
129     system("su -c chmod 666 /sys/class/video/screen_mode");
130     system("su -c chmod 666 /sys/class/video/disable_video");
131     system("su -c chmod 666 /sys/class/tsync/pts_pcrscr");
132     system("su -c chmod 666 /sys/class/audiodsp/digital_raw");
133     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
134     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
135     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
136     CLog::Log(LOGINFO, "aml_permissions: permissions changed");
137   }
138 }
139
140 int aml_get_cputype()
141 {
142   static int aml_cputype = -1;
143   if (aml_cputype == -1)
144   {
145     std::string cpu_hardware = g_cpuInfo.getCPUHardware();
146
147     // default to AMLogic M1
148     aml_cputype = 1;
149     if (cpu_hardware.find("MESON-M3") != std::string::npos)
150       aml_cputype = 3;
151     else if (cpu_hardware.find("MESON3") != std::string::npos)
152       aml_cputype = 3;
153     else if (cpu_hardware.find("Meson6") != std::string::npos)
154       aml_cputype = 6;
155   }
156
157   return aml_cputype;
158 }
159
160 void aml_cpufreq_min(bool limit)
161 {
162 // do not touch scaling_min_freq on android
163 #if !defined(TARGET_ANDROID)
164   // only needed for m1/m3 SoCs
165   if (aml_get_cputype() <= 3)
166   {
167     int cpufreq = 300000;
168     if (limit)
169       cpufreq = 600000;
170
171     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
172   }
173 #endif
174 }
175
176 void aml_cpufreq_max(bool limit)
177 {
178   if (!aml_wired_present() && aml_get_cputype() > 3)
179   {
180     // this is a MX Stick, they cannot substain 1GHz
181     // operation without overheating so limit them to 800MHz.
182     int cpufreq = 1000000;
183     if (limit)
184       cpufreq = 800000;
185
186     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq);
187     aml_set_sysfs_str("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand");
188   }
189 }
190
191 void aml_set_audio_passthrough(bool passthrough)
192 {
193   if (aml_present())
194   {
195     // m1 uses 1, m3 and above uses 2
196     int raw = aml_get_cputype() < 3 ? 1:2;
197     aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
198   }
199 }
200
201 void aml_probe_hdmi_audio()
202 {
203   std::vector<CStdString> audio_formats;
204   // Audio {format, channel, freq, cce}
205   // {1, 7, 7f, 7}
206   // {7, 5, 1e, 0}
207   // {2, 5, 7, 0}
208   // {11, 7, 7e, 1}
209   // {10, 7, 6, 0}
210   // {12, 7, 7e, 0}
211
212   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
213   if (fd >= 0)
214   {
215     char valstr[1024] = {0};
216
217     read(fd, valstr, sizeof(valstr) - 1);
218     valstr[strlen(valstr)] = '\0';
219     close(fd);
220
221     std::vector<CStdString> probe_str;
222     StringUtils::SplitString(valstr, "\n", probe_str);
223
224     for (size_t i = 0; i < probe_str.size(); i++)
225     {
226       if (probe_str[i].find("Audio") == std::string::npos)
227       {
228         for (size_t j = i+1; j < probe_str.size(); j++)
229         {
230           if      (probe_str[i].find("{1,")  != std::string::npos)
231             printf(" PCM found {1,\n");
232           else if (probe_str[i].find("{2,")  != std::string::npos)
233             printf(" AC3 found {2,\n");
234           else if (probe_str[i].find("{3,")  != std::string::npos)
235             printf(" MPEG1 found {3,\n");
236           else if (probe_str[i].find("{4,")  != std::string::npos)
237             printf(" MP3 found {4,\n");
238           else if (probe_str[i].find("{5,")  != std::string::npos)
239             printf(" MPEG2 found {5,\n");
240           else if (probe_str[i].find("{6,")  != std::string::npos)
241             printf(" AAC found {6,\n");
242           else if (probe_str[i].find("{7,")  != std::string::npos)
243             printf(" DTS found {7,\n");
244           else if (probe_str[i].find("{8,")  != std::string::npos)
245             printf(" ATRAC found {8,\n");
246           else if (probe_str[i].find("{9,")  != std::string::npos)
247             printf(" One_Bit_Audio found {9,\n");
248           else if (probe_str[i].find("{10,") != std::string::npos)
249             printf(" Dolby found {10,\n");
250           else if (probe_str[i].find("{11,") != std::string::npos)
251             printf(" DTS_HD found {11,\n");
252           else if (probe_str[i].find("{12,") != std::string::npos)
253             printf(" MAT found {12,\n");
254           else if (probe_str[i].find("{13,") != std::string::npos)
255             printf(" ATRAC found {13,\n");
256           else if (probe_str[i].find("{14,") != std::string::npos)
257             printf(" WMA found {14,\n");
258           else
259             break;
260         }
261         break;
262       }
263     }
264   }
265 }