summaryrefslogtreecommitdiff
path: root/audio_hw_profile.c (plain)
blob: 0b30d3cdee3d90eba30605ad4853622b6838a5c8
1#include <errno.h>
2#include <pthread.h>
3#include <stdint.h>
4#include <sys/time.h>
5#include <stdlib.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <math.h>
9#include <cutils/log.h>
10#include <cutils/str_parms.h>
11#include <cutils/properties.h>
12#include <hardware/hardware.h>
13#include <system/audio.h>
14#include <hardware/audio.h>
15
16#include "audio_hw_utils.h"
17
18#define LOG_TAG "audio_hw_hdmi"
19
20/*
21 type : 0 -> playback, 1 -> capture
22*/
23#define MAX_CARD_NUM 2
24int get_external_card(int type)
25{
26 int card_num = 1; // start num, 0 is defualt sound card.
27 struct stat card_stat;
28 char fpath[256];
29 int ret;
30 while (card_num <= MAX_CARD_NUM) {
31 snprintf(fpath, sizeof(fpath), "/proc/asound/card%d", card_num);
32 ret = stat(fpath, &card_stat);
33 if (ret < 0) {
34 ret = -1;
35 } else {
36 snprintf(fpath, sizeof(fpath), "/dev/snd/pcmC%uD0%c", card_num,
37 type ? 'c' : 'p');
38 ret = stat(fpath, &card_stat);
39 if (ret == 0) {
40 return card_num;
41 }
42 }
43 card_num++;
44 }
45 return ret;
46}
47
48int
49get_aml_card()
50{
51 int card = -1, err = 0;
52 int fd = -1;
53 unsigned fileSize = 512;
54 char *read_buf = NULL, *pd = NULL;
55 static const char *const SOUND_CARDS_PATH = "/proc/asound/cards";
56 fd = open(SOUND_CARDS_PATH, O_RDONLY);
57 if (fd < 0) {
58 ALOGE("ERROR: failed to open config file %s error: %d\n",
59 SOUND_CARDS_PATH, errno);
60 close(fd);
61 return -EINVAL;
62 }
63
64 read_buf = (char *) malloc(fileSize);
65 if (!read_buf) {
66 ALOGE("Failed to malloc read_buf");
67 close(fd);
68 return -ENOMEM;
69 }
70 memset(read_buf, 0x0, fileSize);
71 err = read(fd, read_buf, fileSize);
72 if (fd < 0) {
73 ALOGE("ERROR: failed to read config file %s error: %d\n",
74 SOUND_CARDS_PATH, errno);
75 close(fd);
76 return -EINVAL;
77 }
78 pd = strstr(read_buf, "AML");
79 card = *(pd - 3) - '0';
80OUT:
81 free(read_buf);
82 close(fd);
83 return card;
84}
85
86int
87get_spdif_port()
88{
89 int port = -1, err = 0;
90 int fd = -1;
91 unsigned fileSize = 512;
92 char *read_buf = NULL, *pd = NULL;
93 static const char *const SOUND_PCM_PATH = "/proc/asound/pcm";
94 fd = open(SOUND_PCM_PATH, O_RDONLY);
95 if (fd < 0) {
96 ALOGE("ERROR: failed to open config file %s error: %d\n",
97 SOUND_PCM_PATH, errno);
98 close(fd);
99 return -EINVAL;
100 }
101 read_buf = (char *) malloc(fileSize);
102 if (!read_buf) {
103 ALOGE("Failed to malloc read_buf");
104 close(fd);
105 return -ENOMEM;
106 }
107 memset(read_buf, 0x0, fileSize);
108 err = read(fd, read_buf, fileSize);
109 if (fd < 0) {
110 ALOGE("ERROR: failed to read config file %s error: %d\n",
111 SOUND_PCM_PATH, errno);
112 close(fd);
113 return -EINVAL;
114 }
115 pd = strstr(read_buf, "SPDIF");
116 port = *(pd - 3) - '0';
117OUT:
118 free(read_buf);
119 close(fd);
120 return port;
121}
122
123
124/*
125CodingType MaxChannels SamplingFreq SampleSize
126PCM, 2 ch, 32/44.1/48/88.2/96/176.4/192 kHz, 16/20/24 bit
127PCM, 8 ch, 32/44.1/48/88.2/96/176.4/192 kHz, 16/20/24 bit
128AC-3, 8 ch, 32/44.1/48 kHz, bit
129DTS, 8 ch, 44.1/48 kHz, bit
130OneBitAudio, 2 ch, 44.1 kHz, bit
131Dobly_Digital+, 8 ch, 44.1/48 kHz, 16 bit
132DTS-HD, 8 ch, 44.1/48/88.2/96/176.4/192 kHz, 16 bit
133MAT, 8 ch, 32/44.1/48/88.2/96/176.4/192 kHz, 16 bit
134*/
135char* get_hdmi_sink_cap(const char *keys)
136{
137 int i = 0;
138 char * infobuf = NULL;
139 int channel = 0;
140 int dgraw = 0;
141 int fd = -1;
142 int size = 0;
143 char *aud_cap = NULL;
144 infobuf = (char *)malloc(1024 * sizeof(char));
145 if (infobuf == NULL) {
146 ALOGE("malloc buffer failed\n");
147 goto fail;
148 }
149 aud_cap = (char*)malloc(1024);
150 if (aud_cap == NULL) {
151 ALOGE("malloc buffer failed\n");
152 goto fail;
153 }
154 memset(aud_cap, 0, 1024);
155 memset(infobuf, 0, 1024);
156 fd = open("/sys/class/amhdmitx/amhdmitx0/aud_cap", O_RDONLY);
157 if (fd >= 0) {
158 int nread = read(fd, infobuf, 1024);
159 /* check the format cap */
160 if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
161 size += sprintf(aud_cap, "=%s|", "AUDIO_FORMAT_PCM_16_BIT");
162 if (mystrstr(infobuf, "Dobly_Digital+")) {
163 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_E_AC3");
164 }
165 if (mystrstr(infobuf, "AC-3")) {
166 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_AC3");
167 }
168 if (mystrstr(infobuf, "DTS-HD")) {
169 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTSHD");
170 } else if (mystrstr(infobuf, "DTS")) {
171 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS");
172 }
173 if (mystrstr(infobuf, "MAT")) {
174 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_TRUEHD");
175 }
176 }
177 /*check the channel cap */
178 else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
179 /* take the 2ch suppported as default */
180 size += sprintf(aud_cap, "=%s|", "AUDIO_CHANNEL_OUT_STEREO");
181 if (mystrstr(infobuf, "PCM, 8 ch")) {
182 size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_7POINT1");
183 } else if (mystrstr(infobuf, "PCM, 6 ch")) {
184 size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1");
185 }
186 } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
187 /* take the 32/44.1/48 khz suppported as default */
188 size += sprintf(aud_cap, "=%s|", "32000|44100|48000");
189 if (mystrstr(infobuf, "88.2")) {
190 size += sprintf(aud_cap + size, "%s|", "88200");
191 }
192 if (mystrstr(infobuf, "96")) {
193 size += sprintf(aud_cap + size, "%s|", "96000");
194 }
195 if (mystrstr(infobuf, "176.4")) {
196 size += sprintf(aud_cap + size, "%s|", "176400");
197 }
198 if (mystrstr(infobuf, "192")) {
199 size += sprintf(aud_cap + size, "%s|", "192000");
200 }
201 }
202 }
203 if (infobuf) {
204 free(infobuf);
205 }
206 if (fd >= 0) {
207 close(fd);
208 }
209 return aud_cap;
210fail:
211 if (aud_cap) {
212 free(aud_cap);
213 }
214 if (infobuf) {
215 free(infobuf);
216 }
217 return NULL;
218}
219char* get_hdmi_arc_cap(unsigned *ad, int maxsize, const char *keys)
220{
221 int i = 0;
222 int channel = 0;
223 int dgraw = 0;
224 int fd = -1;
225 int size = 0;
226 char *aud_cap = NULL;
227 unsigned char format, ch, sr;
228 aud_cap = (char*)malloc(1024);
229 if (aud_cap == NULL) {
230 ALOGE("malloc buffer failed\n");
231 goto fail;
232 }
233 memset(aud_cap, 0, 1024);
234 ALOGI("get_hdmi_arc_cap\n");
235 /* check the format cap */
236 if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
237 size += sprintf(aud_cap, "=%s|", "AUDIO_FORMAT_PCM_16_BIT");
238 }
239 /*check the channel cap */
240 else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
241 //ALOGI("check channels\n");
242 /* take the 2ch suppported as default */
243 size += sprintf(aud_cap, "=%s|", "AUDIO_CHANNEL_OUT_STEREO");
244 } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
245 /* take the 32/44.1/48 khz suppported as default */
246 size += sprintf(aud_cap, "=%s|", "32000|44100|48000");
247 //ALOGI("check sample rate\n");
248 }
249 for (i = 0; i < maxsize; i++) {
250 if (ad[i] != 0) {
251 format = (ad[i] >> 19) & 0xf;
252 ch = (ad[i] >> 16) & 0x7;
253 sr = (ad[i] > 8) & 0xf;
254 ALOGI("ad %x,format %d,ch %d,sr %d\n", ad[i], format, ch, sr);
255 /* check the format cap */
256 if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
257 //ALOGI("check format\n");
258 if (format == 10) {
259 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_E_AC3");
260 }
261 if (format == 2) {
262 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_AC3");
263 }
264 if (format == 11) {
265 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTSHD");
266 } else if (format == 7) {
267 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_DTS");
268 }
269 if (format == 12) {
270 size += sprintf(aud_cap + size, "%s|", "AUDIO_FORMAT_TRUEHD");
271 }
272 }
273 /*check the channel cap */
274 else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
275 //ALOGI("check channels\n");
276 if (/*format == 1 && */ch == 7) {
277 size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_7POINT1");
278 } else if (/*format == 1 && */ch == 5) {
279 size += sprintf(aud_cap + size, "%s|", "AUDIO_CHANNEL_OUT_5POINT1");
280 }
281 } else if (strstr(keys, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
282 ALOGI("check sample rate\n");
283 if (format == 1 && sr == 4) {
284 size += sprintf(aud_cap + size, "%s|", "88200");
285 }
286 if (format == 1 && sr == 5) {
287 size += sprintf(aud_cap + size, "%s|", "96000");
288 }
289 if (format == 1 && sr == 6) {
290 size += sprintf(aud_cap + size, "%s|", "176400");
291 }
292 if (format == 1 && sr == 7) {
293 size += sprintf(aud_cap + size, "%s|", "192000");
294 }
295 }
296
297 } else {
298 format = 0;
299 ch = 0;
300 sr = 0;
301 }
302 }
303 return aud_cap;
304fail:
305 if (aud_cap) {
306 free(aud_cap);
307 }
308 return NULL;
309}
310
311