[AML] Be rid of damned cpu type magic numbers
[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 #include "utils/AMLUtils.h"
32
33 int aml_set_sysfs_str(const char *path, const char *val)
34 {
35   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
36   if (fd >= 0)
37   {
38     write(fd, val, strlen(val));
39     close(fd);
40     return 0;
41   }
42   return -1;
43 }
44
45 int aml_get_sysfs_str(const char *path, char *valstr, const int size)
46 {
47   int fd = open(path, O_RDONLY);
48   if (fd >= 0)
49   {
50     read(fd, valstr, size - 1);
51     valstr[strlen(valstr)] = '\0';
52     close(fd);
53     return 0;
54   }
55
56   sprintf(valstr, "%s", "fail");
57   return -1;
58 }
59
60 int aml_set_sysfs_int(const char *path, const int val)
61 {
62   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
63   if (fd >= 0)
64   {
65     char bcmd[16];
66     sprintf(bcmd, "%d", val);
67     write(fd, bcmd, strlen(bcmd));
68     close(fd);
69     return 0;
70   }
71   return -1;
72 }
73
74 int aml_get_sysfs_int(const char *path)
75 {
76   int val = -1;
77   int fd = open(path, O_RDONLY);
78   if (fd >= 0)
79   {
80     char bcmd[16];
81     read(fd, bcmd, sizeof(bcmd));
82     val = strtol(bcmd, NULL, 16);
83     close(fd);
84   }
85   return val;
86 }
87
88 bool aml_present()
89 {
90   static int has_aml = -1;
91   if (has_aml == -1)
92   {
93     int rtn = aml_get_sysfs_int("/sys/class/audiodsp/digital_raw");
94     if (rtn != -1)
95       has_aml = 1;
96     else
97       has_aml = 0;
98     if (has_aml)
99       CLog::Log(LOGNOTICE, "aml_present, rtn(%d)", rtn);
100   }
101   return has_aml == 1;
102 }
103
104 bool aml_hw3d_present()
105 {
106   static int has_hw3d = -1;
107   if (has_hw3d == -1)
108   {
109     if (aml_get_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode") != -1)
110       has_hw3d = 1;
111     else
112       has_hw3d = 0;
113   }
114   return has_hw3d == 1;
115 }
116
117 bool aml_wired_present()
118 {
119   static int has_wired = -1;
120   if (has_wired == -1)
121   {
122     char test[64] = {0};
123     if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1)
124       has_wired = 1;
125     else
126       has_wired = 0;
127   }
128   return has_wired == 1;
129 }
130
131 void aml_permissions()
132 {
133   if (!aml_present())
134     return;
135   
136   // most all aml devices are already rooted.
137   int ret = system("ls /system/xbin/su");
138   if (ret != 0)
139   {
140     CLog::Log(LOGWARNING, "aml_permissions: missing su, playback might fail");
141   }
142   else
143   {
144     // certain aml devices have 664 permission, we need 666.
145     system("su -c chmod 666 /dev/amvideo");
146     system("su -c chmod 666 /dev/amstream*");
147     system("su -c chmod 666 /sys/class/video/axis");
148     system("su -c chmod 666 /sys/class/video/screen_mode");
149     system("su -c chmod 666 /sys/class/video/disable_video");
150     system("su -c chmod 666 /sys/class/tsync/pts_pcrscr");
151     system("su -c chmod 666 /sys/class/audiodsp/digital_raw");
152     system("su -c chmod 666 /sys/class/ppmgr/ppmgr_3d_mode");
153     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
154     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
155     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
156     CLog::Log(LOGINFO, "aml_permissions: permissions changed");
157   }
158 }
159
160 enum AML_DEVICE_TYPE aml_get_cputype()
161 {
162   static enum AML_DEVICE_TYPE aml_cputype = AML_DEVICE_TYPE_UNKNOWN;
163   if (aml_cputype == AML_DEVICE_TYPE_UNKNOWN)
164   {
165     std::string cpu_hardware = g_cpuInfo.getCPUHardware();
166
167     // default to AMLogic M1
168     aml_cputype = AML_DEVICE_TYPE_M1;
169     if (cpu_hardware.find("MESON-M3") != std::string::npos)
170       aml_cputype = AML_DEVICE_TYPE_M3;
171     else if (cpu_hardware.find("MESON3") != std::string::npos)
172       aml_cputype = AML_DEVICE_TYPE_M3;
173     else if (cpu_hardware.find("Meson6") != std::string::npos)
174       aml_cputype = AML_DEVICE_TYPE_M6;
175     else if (cpu_hardware.find("Meson8") != std::string::npos)
176       aml_cputype = AML_DEVICE_TYPE_M8;
177   }
178
179   return aml_cputype;
180 }
181
182 void aml_cpufreq_min(bool limit)
183 {
184 // do not touch scaling_min_freq on android
185 #if !defined(TARGET_ANDROID)
186   // only needed for m1/m3 SoCs
187   if (aml_get_cputype() <= AML_DEVICE_TYPE_M3)
188   {
189     int cpufreq = 300000;
190     if (limit)
191       cpufreq = 600000;
192
193     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
194   }
195 #endif
196 }
197
198 void aml_cpufreq_max(bool limit)
199 {
200   if (!aml_wired_present() && aml_get_cputype() > AML_DEVICE_TYPE_M3)
201   {
202     // this is a MX Stick, they cannot substain 1GHz
203     // operation without overheating so limit them to 800MHz.
204     int cpufreq = 1000000;
205     if (limit)
206       cpufreq = 800000;
207
208     aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq);
209     aml_set_sysfs_str("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand");
210   }
211 }
212
213 void aml_set_audio_passthrough(bool passthrough)
214 {
215   if (aml_present())
216   {
217     // m1 uses 1, m3 and above uses 2
218     int raw = aml_get_cputype() < AML_DEVICE_TYPE_M3 ? 1:2;
219     aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
220   }
221 }
222
223 void aml_probe_hdmi_audio()
224 {
225   // Audio {format, channel, freq, cce}
226   // {1, 7, 7f, 7}
227   // {7, 5, 1e, 0}
228   // {2, 5, 7, 0}
229   // {11, 7, 7e, 1}
230   // {10, 7, 6, 0}
231   // {12, 7, 7e, 0}
232
233   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
234   if (fd >= 0)
235   {
236     char valstr[1024] = {0};
237
238     read(fd, valstr, sizeof(valstr) - 1);
239     valstr[strlen(valstr)] = '\0';
240     close(fd);
241
242     std::vector<std::string> probe_str = StringUtils::Split(valstr, "\n");
243
244     for (std::vector<std::string>::const_iterator i = probe_str.begin(); i != probe_str.end(); ++i)
245     {
246       if (i->find("Audio") == std::string::npos)
247       {
248         for (std::vector<std::string>::const_iterator j = i + 1; j != probe_str.end(); ++j)
249         {
250           if      (j->find("{1,")  != std::string::npos)
251             printf(" PCM found {1,\n");
252           else if (j->find("{2,")  != std::string::npos)
253             printf(" AC3 found {2,\n");
254           else if (j->find("{3,")  != std::string::npos)
255             printf(" MPEG1 found {3,\n");
256           else if (j->find("{4,")  != std::string::npos)
257             printf(" MP3 found {4,\n");
258           else if (j->find("{5,")  != std::string::npos)
259             printf(" MPEG2 found {5,\n");
260           else if (j->find("{6,")  != std::string::npos)
261             printf(" AAC found {6,\n");
262           else if (j->find("{7,")  != std::string::npos)
263             printf(" DTS found {7,\n");
264           else if (j->find("{8,")  != std::string::npos)
265             printf(" ATRAC found {8,\n");
266           else if (j->find("{9,")  != std::string::npos)
267             printf(" One_Bit_Audio found {9,\n");
268           else if (j->find("{10,") != std::string::npos)
269             printf(" Dolby found {10,\n");
270           else if (j->find("{11,") != std::string::npos)
271             printf(" DTS_HD found {11,\n");
272           else if (j->find("{12,") != std::string::npos)
273             printf(" MAT found {12,\n");
274           else if (j->find("{13,") != std::string::npos)
275             printf(" ATRAC found {13,\n");
276           else if (j->find("{14,") != std::string::npos)
277             printf(" WMA found {14,\n");
278           else
279             break;
280         }
281         break;
282       }
283     }
284   }
285 }