6a3100d23f0fdeb7a091e568a6537f4d80a0084c
[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/log.h"
29 #include "utils/StringUtils.h"
30
31 int aml_set_sysfs_str(const char *path, const char *val)
32 {
33   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
34   if (fd >= 0)
35   {
36     write(fd, val, strlen(val));
37     close(fd);
38     return 0;
39   }
40   return -1;
41 }
42
43 int aml_get_sysfs_str(const char *path, char *valstr, const int size)
44 {
45   int fd = open(path, O_RDONLY);
46   if (fd >= 0)
47   {
48     read(fd, valstr, size - 1);
49     valstr[strlen(valstr)] = '\0';
50     close(fd);
51     return 0;
52   }
53
54   sprintf(valstr, "%s", "fail");
55   return -1;
56 }
57
58 int aml_set_sysfs_int(const char *path, const int val)
59 {
60   int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
61   if (fd >= 0)
62   {
63     char bcmd[16];
64     sprintf(bcmd, "%d", val);
65     write(fd, bcmd, strlen(bcmd));
66     close(fd);
67     return 0;
68   }
69   return -1;
70 }
71
72 int aml_get_sysfs_int(const char *path)
73 {
74   int val = -1;
75   int fd = open(path, O_RDONLY);
76   if (fd >= 0)
77   {
78     char bcmd[16];
79     read(fd, bcmd, sizeof(bcmd));
80     val = strtol(bcmd, NULL, 16);
81     close(fd);
82   }
83   return val;
84 }
85
86 bool aml_present()
87 {
88   static int has_aml = -1;
89   if (has_aml == -1)
90   {
91     int rtn = aml_get_sysfs_int("/sys/class/audiodsp/digital_raw");
92     if (rtn != -1)
93       has_aml = 1;
94     else
95       has_aml = 0;
96     if (has_aml)
97       CLog::Log(LOGNOTICE, "aml_present, rtn(%d)", rtn);
98   }
99   return has_aml;
100 }
101
102 int aml_get_cputype()
103 {
104   static int aml_cputype = -1;
105   if (aml_cputype == -1)
106   {
107     // defualt to m1 SoC
108     aml_cputype = 1;
109
110     FILE *cpuinfo_fd = fopen("/proc/cpuinfo", "r");
111     if (cpuinfo_fd)
112     {
113       char buffer[512];
114       while (fgets(buffer, sizeof(buffer), cpuinfo_fd))
115       {
116         std::string stdbuffer(buffer);
117         if (stdbuffer.find("MESON-M3") != std::string::npos)
118         {
119           aml_cputype = 3;
120           break;
121         }
122         else if (stdbuffer.find("MESON3") != std::string::npos)
123         {
124           aml_cputype = 3;
125           break;
126         }
127         else if (stdbuffer.find("Meson6") != std::string::npos)
128         {
129           aml_cputype = 6;
130           break;
131         }
132       }
133       fclose(cpuinfo_fd);
134     }
135   }
136
137   return aml_cputype;
138 }
139
140 void aml_cpufreq_limit(bool limit)
141 {
142   int cpufreq = 300000;
143   if (limit)
144     cpufreq = 600000;
145
146   aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq);
147 }
148
149 void aml_set_audio_passthrough(bool passthrough)
150 {
151   if (aml_present())
152   {
153     int raw = aml_get_cputype() < 3 ? 1:2;
154     aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0);
155   }
156 }
157
158 void aml_probe_hdmi_audio()
159 {
160   std::vector<CStdString> audio_formats;
161   // Audio {format, channel, freq, cce}
162   // {1, 7, 7f, 7}
163   // {7, 5, 1e, 0}
164   // {2, 5, 7, 0}
165   // {11, 7, 7e, 1}
166   // {10, 7, 6, 0}
167   // {12, 7, 7e, 0}
168
169   int fd = open("/sys/class/amhdmitx/amhdmitx0/edid", O_RDONLY);
170   if (fd >= 0)
171   {
172     char valstr[1024] = {0};
173
174     read(fd, valstr, sizeof(valstr) - 1);
175     valstr[strlen(valstr)] = '\0';
176     close(fd);
177
178     std::vector<CStdString> probe_str;
179     StringUtils::SplitString(valstr, "\n", probe_str);
180
181     for (size_t i = 0; i < probe_str.size(); i++)
182     {
183       if (probe_str[i].find("Audio") == std::string::npos)
184       {
185         for (size_t j = i+1; j < probe_str.size(); j++)
186         {
187           if      (probe_str[i].find("{1,")  != std::string::npos)
188             printf(" PCM found {1,\n");
189           else if (probe_str[i].find("{2,")  != std::string::npos)
190             printf(" AC3 found {2,\n");
191           else if (probe_str[i].find("{3,")  != std::string::npos)
192             printf(" MPEG1 found {3,\n");
193           else if (probe_str[i].find("{4,")  != std::string::npos)
194             printf(" MP3 found {4,\n");
195           else if (probe_str[i].find("{5,")  != std::string::npos)
196             printf(" MPEG2 found {5,\n");
197           else if (probe_str[i].find("{6,")  != std::string::npos)
198             printf(" AAC found {6,\n");
199           else if (probe_str[i].find("{7,")  != std::string::npos)
200             printf(" DTS found {7,\n");
201           else if (probe_str[i].find("{8,")  != std::string::npos)
202             printf(" ATRAC found {8,\n");
203           else if (probe_str[i].find("{9,")  != std::string::npos)
204             printf(" One_Bit_Audio found {9,\n");
205           else if (probe_str[i].find("{10,") != std::string::npos)
206             printf(" Dolby found {10,\n");
207           else if (probe_str[i].find("{11,") != std::string::npos)
208             printf(" DTS_HD found {11,\n");
209           else if (probe_str[i].find("{12,") != std::string::npos)
210             printf(" MAT found {12,\n");
211           else if (probe_str[i].find("{13,") != std::string::npos)
212             printf(" ATRAC found {13,\n");
213           else if (probe_str[i].find("{14,") != std::string::npos)
214             printf(" WMA found {14,\n");
215           else
216             break;
217         }
218         break;
219       }
220     }
221   }
222 }