Merge pull request #3310 from MartijnKaijser/addon_dependencies
[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;
101 }
102
103 int aml_get_cputype()
104 {
105   static int aml_cputype = -1;
106   if (aml_cputype == -1)
107   {
108     std::string cpu_hardware = g_cpuInfo.getCPUHardware();
109
110     // default to AMLogic M1
111     aml_cputype = 1;
112     if (cpu_hardware.find("MESON-M3") != std::string::npos)
113       aml_cputype = 3;
114     else if (cpu_hardware.find("MESON3") != std::string::npos)
115       aml_cputype = 3;
116     else if (cpu_hardware.find("Meson6") != std::string::npos)
117       aml_cputype = 6;
118   }
119
120   return aml_cputype;
121 }
122
123 void aml_cpufreq_limit(bool limit)
124 {
125   int cpufreq = 300000;
126   if (limit)
127     cpufreq = 600000;
128
129   aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
130 }
131
132 void aml_set_audio_passthrough(bool passthrough)
133 {
134   if (aml_present())
135   {
136     int raw = aml_get_cputype() < 3 ? 1:2;
137     aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
138   }
139 }
140
141 void aml_probe_hdmi_audio()
142 {
143   std::vector<CStdString> audio_formats;
144   // Audio {format, channel, freq, cce}
145   // {1, 7, 7f, 7}
146   // {7, 5, 1e, 0}
147   // {2, 5, 7, 0}
148   // {11, 7, 7e, 1}
149   // {10, 7, 6, 0}
150   // {12, 7, 7e, 0}
151
152   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
153   if (fd >= 0)
154   {
155     char valstr[1024] = {0};
156
157     read(fd, valstr, sizeof(valstr) - 1);
158     valstr[strlen(valstr)] = '\0';
159     close(fd);
160
161     std::vector<CStdString> probe_str;
162     StringUtils::SplitString(valstr, "\n", probe_str);
163
164     for (size_t i = 0; i < probe_str.size(); i++)
165     {
166       if (probe_str[i].find("Audio") == std::string::npos)
167       {
168         for (size_t j = i+1; j < probe_str.size(); j++)
169         {
170           if      (probe_str[i].find("{1,")  != std::string::npos)
171             printf(" PCM found {1,\n");
172           else if (probe_str[i].find("{2,")  != std::string::npos)
173             printf(" AC3 found {2,\n");
174           else if (probe_str[i].find("{3,")  != std::string::npos)
175             printf(" MPEG1 found {3,\n");
176           else if (probe_str[i].find("{4,")  != std::string::npos)
177             printf(" MP3 found {4,\n");
178           else if (probe_str[i].find("{5,")  != std::string::npos)
179             printf(" MPEG2 found {5,\n");
180           else if (probe_str[i].find("{6,")  != std::string::npos)
181             printf(" AAC found {6,\n");
182           else if (probe_str[i].find("{7,")  != std::string::npos)
183             printf(" DTS found {7,\n");
184           else if (probe_str[i].find("{8,")  != std::string::npos)
185             printf(" ATRAC found {8,\n");
186           else if (probe_str[i].find("{9,")  != std::string::npos)
187             printf(" One_Bit_Audio found {9,\n");
188           else if (probe_str[i].find("{10,") != std::string::npos)
189             printf(" Dolby found {10,\n");
190           else if (probe_str[i].find("{11,") != std::string::npos)
191             printf(" DTS_HD found {11,\n");
192           else if (probe_str[i].find("{12,") != std::string::npos)
193             printf(" MAT found {12,\n");
194           else if (probe_str[i].find("{13,") != std::string::npos)
195             printf(" ATRAC found {13,\n");
196           else if (probe_str[i].find("{14,") != std::string::npos)
197             printf(" WMA found {14,\n");
198           else
199             break;
200         }
201         break;
202       }
203     }
204   }
205 }