blob: 4ee4c232da07c946e75338af10982324d79716c1 [file] [log] [blame]
Yamit Mehtae3b99562016-09-16 22:44:00 +05301/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_utils"
18//#define LOG_NDEBUG 0
19
20#include <errno.h>
21#include <cutils/properties.h>
22#include <cutils/config_utils.h>
23#include <stdlib.h>
24#include <dlfcn.h>
25#include <cutils/str_parms.h>
26#include <cutils/log.h>
27#include <cutils/misc.h>
28
vivek mehta0fb11312017-05-15 19:35:32 -070029#include "acdb.h"
Yamit Mehtae3b99562016-09-16 22:44:00 +053030#include "audio_hw.h"
31#include "platform.h"
32#include "platform_api.h"
33#include "audio_extn.h"
34
35#define MAX_LENGTH_MIXER_CONTROL_IN_INT 128
36
vivek mehtaa68fea62017-06-08 19:04:02 -070037static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
38 int pcm_device_id, int app_type,
39 int acdb_dev_id, int sample_rate,
40 int stream_type,
41 snd_device_t snd_device)
Yamit Mehtae3b99562016-09-16 22:44:00 +053042{
43
44 char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
45 struct mixer_ctl *ctl;
46 int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
vivek mehtaa68fea62017-06-08 19:04:02 -070047 int snd_device_be_idx = -1;
Yamit Mehtae3b99562016-09-16 22:44:00 +053048
49 if (stream_type == PCM_PLAYBACK) {
50 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
51 "Audio Stream %d App Type Cfg", pcm_device_id);
52 } else if (stream_type == PCM_CAPTURE) {
53 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
54 "Audio Stream Capture %d App Type Cfg", pcm_device_id);
55 }
56
57 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
58 if (!ctl) {
59 ALOGE("%s: Could not get ctl for mixer cmd - %s",
60 __func__, mixer_ctl_name);
61 rc = -EINVAL;
62 goto exit;
63 }
64 app_type_cfg[len++] = app_type;
65 app_type_cfg[len++] = acdb_dev_id;
66 app_type_cfg[len++] = sample_rate;
vivek mehtaa68fea62017-06-08 19:04:02 -070067
68 snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
69 if (snd_device_be_idx > 0)
70 app_type_cfg[len++] = snd_device_be_idx;
71 ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
72 "sample rate %d, snd_device_be_idx %d",
73 __func__, stream_type, app_type, acdb_dev_id, sample_rate,
74 snd_device_be_idx);
Yamit Mehtae3b99562016-09-16 22:44:00 +053075 mixer_ctl_set_array(ctl, app_type_cfg, len);
76
77exit:
78 return rc;
79}
80
81void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer)
82{
83 int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1};
84 int length = 0, app_type = 0,rc = 0;
85 struct mixer_ctl *ctl = NULL;
86 const char *mixer_ctl_name = "App Type Config";
87
88 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
89 if (!ctl) {
90 ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
91 return;
92 }
93 rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type);
94 if (rc == 0) {
95 app_type_cfg[length++] = 1;
96 app_type_cfg[length++] = app_type;
97 app_type_cfg[length++] = 48000;
98 app_type_cfg[length++] = 16;
99 mixer_ctl_set_array(ctl, app_type_cfg, length);
100 }
101 return;
102}
103
vivek mehtaa68fea62017-06-08 19:04:02 -0700104static const char *flags_to_mode(int dir, uint32_t flags)
105{
106 if (dir == 0) {
107 if (flags & AUDIO_OUTPUT_FLAG_VOIP_RX) {
108 return "voip";
109 }
110 } else if (dir == 1) {
111 if (flags & AUDIO_INPUT_FLAG_VOIP_TX) {
112 return "voip";
113 }
114 }
115 return "default";
116}
117
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800118static int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev,
Yamit Mehtae3b99562016-09-16 22:44:00 +0530119 struct audio_usecase *usecase)
120{
121 struct mixer_ctl *ctl;
122 int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
123 int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
124 int app_type = 0, rc = 0;
125
126 ALOGV("%s", __func__);
127
128 if (usecase->type != PCM_HFP_CALL) {
129 ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
130 rc = 0;
131 goto exit_send_app_type_cfg;
132 }
133 if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
134 (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
135 ALOGV("%s: a playback path where app type cfg is not required", __func__);
136 rc = 0;
137 goto exit_send_app_type_cfg;
138 }
139
140 snd_device = usecase->out_snd_device;
141 pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
142
143 snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
144 audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
145 acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
146 if (acdb_dev_id < 0) {
147 ALOGE("%s: Couldn't get the acdb dev id", __func__);
148 rc = -EINVAL;
149 goto exit_send_app_type_cfg;
150 }
151
152 if (usecase->type == PCM_HFP_CALL) {
153
154 /* config HFP session:1 playback path */
155 rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
156 if (rc < 0)
157 goto exit_send_app_type_cfg;
158
159 sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
vivek mehtaa68fea62017-06-08 19:04:02 -0700160 rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
161 acdb_dev_id, sample_rate,
162 PCM_PLAYBACK,
163 SND_DEVICE_NONE); // use legacy behavior
Yamit Mehtae3b99562016-09-16 22:44:00 +0530164 if (rc < 0)
165 goto exit_send_app_type_cfg;
166 /* config HFP session:1 capture path */
167 rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);
168
169 if (rc == 0) {
vivek mehtaa68fea62017-06-08 19:04:02 -0700170 rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
171 acdb_dev_id, sample_rate,
172 PCM_CAPTURE,
173 SND_DEVICE_NONE);
Yamit Mehtae3b99562016-09-16 22:44:00 +0530174 if (rc < 0)
175 goto exit_send_app_type_cfg;
176 }
177 /* config HFP session:2 capture path */
178 pcm_device_id = HFP_ASM_RX_TX;
179 snd_device = usecase->in_snd_device;
180 acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
181 if (acdb_dev_id <= 0) {
182 ALOGE("%s: Couldn't get the acdb dev id", __func__);
183 rc = -EINVAL;
184 goto exit_send_app_type_cfg;
185 }
186 rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);
187 if (rc == 0) {
vivek mehtaa68fea62017-06-08 19:04:02 -0700188 rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
189 acdb_dev_id, sample_rate, PCM_CAPTURE,
190 SND_DEVICE_NONE);
Yamit Mehtae3b99562016-09-16 22:44:00 +0530191 if (rc < 0)
192 goto exit_send_app_type_cfg;
193 }
194
195 /* config HFP session:2 playback path */
196 rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
197 if (rc == 0) {
vivek mehtaa68fea62017-06-08 19:04:02 -0700198 rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
199 acdb_dev_id, sample_rate,
200 PCM_PLAYBACK, SND_DEVICE_NONE);
Yamit Mehtae3b99562016-09-16 22:44:00 +0530201 if (rc < 0)
202 goto exit_send_app_type_cfg;
203 }
204 }
205
206 rc = 0;
207exit_send_app_type_cfg:
208 return rc;
209}
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800210
vivek mehtaa68fea62017-06-08 19:04:02 -0700211
212static int derive_capture_app_type_cfg(struct audio_device *adev,
213 struct audio_usecase *usecase,
214 int *app_type,
215 int *sample_rate)
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800216{
Mark Urbanus2e259972017-06-15 16:50:53 -0700217 if (usecase->stream.in == NULL) {
218 return -1;
219 }
vivek mehtaa68fea62017-06-08 19:04:02 -0700220 struct stream_in *in = usecase->stream.in;
221 struct stream_app_type_cfg *app_type_cfg = &in->app_type_cfg;
222
223 *sample_rate = DEFAULT_INPUT_SAMPLING_RATE;
224 if (in->device & AUDIO_DEVICE_IN_USB_DEVICE) {
225 platform_check_and_update_copp_sample_rate(adev->platform,
226 usecase->in_snd_device,
227 in->sample_rate,
228 sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800229 }
230
vivek mehtaa68fea62017-06-08 19:04:02 -0700231 app_type_cfg->mode = flags_to_mode(1 /*capture*/, in->flags);
232 ALOGV("%s mode %s", __func__, app_type_cfg->mode);
233 if (in->format == AUDIO_FORMAT_PCM_16_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800234 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700235 PCM_CAPTURE,
236 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800237 16,
vivek mehtaa68fea62017-06-08 19:04:02 -0700238 app_type_cfg->sample_rate,
239 app_type);
240 } else if (in->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
241 in->format == AUDIO_FORMAT_PCM_8_24_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800242 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700243 PCM_CAPTURE,
244 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800245 24,
vivek mehtaa68fea62017-06-08 19:04:02 -0700246 app_type_cfg->sample_rate,
247 app_type);
248 } else if (in->format == AUDIO_FORMAT_PCM_32_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800249 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700250 PCM_CAPTURE,
251 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800252 32,
vivek mehtaa68fea62017-06-08 19:04:02 -0700253 app_type_cfg->sample_rate,
254 app_type);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800255 } else {
256 ALOGE("%s bad format\n", __func__);
257 return -1;
258 }
259
vivek mehtaa68fea62017-06-08 19:04:02 -0700260 app_type_cfg->app_type = *app_type;
261 app_type_cfg->sample_rate = *sample_rate;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800262 return 0;
263}
264
vivek mehtaa68fea62017-06-08 19:04:02 -0700265static int derive_playback_app_type_cfg(struct audio_device *adev,
266 struct audio_usecase *usecase,
267 int *app_type,
268 int *sample_rate)
269{
Mark Urbanus2e259972017-06-15 16:50:53 -0700270 if (usecase->stream.out == NULL) {
271 return -1;
272 }
vivek mehtaa68fea62017-06-08 19:04:02 -0700273 struct stream_out *out = usecase->stream.out;
274 struct stream_app_type_cfg *app_type_cfg = &out->app_type_cfg;
275
276 *sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
277
278 // add speaker prot changes if needed
279 // and use that to check for device
280 if (out->devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
281 platform_check_and_update_copp_sample_rate(adev->platform,
282 usecase->out_snd_device,
283 out->sample_rate,
284 sample_rate);
285 }
286
287 app_type_cfg->mode = flags_to_mode(0 /*playback*/, out->flags);
288 if (!audio_is_linear_pcm(out->format)) {
289 platform_get_default_app_type_v2(adev->platform,
290 PCM_PLAYBACK,
291 app_type);
292 } else if (out->format == AUDIO_FORMAT_PCM_16_BIT) {
293 platform_get_app_type_v2(adev->platform,
294 PCM_PLAYBACK,
295 app_type_cfg->mode,
296 16,
297 *sample_rate,
298 app_type);
299 } else if (out->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
300 out->format == AUDIO_FORMAT_PCM_8_24_BIT) {
301 platform_get_app_type_v2(adev->platform,
302 PCM_PLAYBACK,
303 app_type_cfg->mode,
304 24,
305 *sample_rate,
306 app_type);
307 } else if (out->format == AUDIO_FORMAT_PCM_32_BIT) {
308 platform_get_app_type_v2(adev->platform,
309 PCM_PLAYBACK,
310 app_type_cfg->mode,
311 32,
312 *sample_rate,
313 app_type);
314 } else {
315 ALOGE("%s bad format\n", __func__);
316 return -1;
317 }
318
319 app_type_cfg->app_type = *app_type;
320 app_type_cfg->sample_rate = *sample_rate;
321 return 0;
322}
323
324static int derive_acdb_dev_id(struct audio_device *adev __unused,
325 struct audio_usecase *usecase)
326{
327 struct stream_out *out;
328 struct stream_in *in;
329
330 if (usecase->type == PCM_PLAYBACK) {
331 return platform_get_snd_device_acdb_id(usecase->out_snd_device);
332 } else if(usecase->type == PCM_CAPTURE) {
333 return platform_get_snd_device_acdb_id(usecase->in_snd_device);
334 }
335 return -1;
336}
337
338int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
339 struct audio_usecase *usecase)
340{
341 int len = 0;
342 int sample_rate;
343 int app_type;
344 int acdb_dev_id;
345 size_t app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
346 char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
347 int pcm_device_id;
348 struct mixer_ctl *ctl;
349 int ret;
350
351 if (usecase->type == PCM_HFP_CALL) {
352 return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
353 }
354
355 if (!platform_supports_app_type_cfg())
356 return -1;
357
358 if (usecase->type == PCM_PLAYBACK) {
359 ret = derive_playback_app_type_cfg(adev,
360 usecase,
361 &app_type,
362 &sample_rate);
363 } else if (usecase->type == PCM_CAPTURE) {
364 ret = derive_capture_app_type_cfg(adev,
365 usecase,
366 &app_type,
367 &sample_rate);
368 } else {
369 ALOGE("%s: Invalid uc type : 0x%x", __func__, usecase->type);
370 return -1;
371 }
372
373 if (ret < 0) {
374 ALOGE("%s: Failed to derive app_type for uc type : 0x%x", __func__,
375 usecase->type);
376 return -1;
377 }
378
379 acdb_dev_id = derive_acdb_dev_id(adev, usecase);
380 if (acdb_dev_id <= 0) {
381 ALOGE("%s: Couldn't get the acdb dev id", __func__);
382 return -1;
383 }
384
385 pcm_device_id = platform_get_pcm_device_id(usecase->id, usecase->type);
386 set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id,
387 sample_rate,
388 usecase->type,
389 usecase->type == PCM_PLAYBACK ? usecase->out_snd_device :
390 usecase->in_snd_device);
391 return 0;
392}
393
394// this assumes correct app_type and sample_rate fields
395// have been set for the stream using audio_extn_utils_send_app_type_cfg
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800396void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
397 struct audio_usecase *usecase)
398{
399 int type = usecase->type;
400 int app_type = 0;
401
402 if (type == PCM_PLAYBACK && usecase->stream.out != NULL) {
403 struct stream_out *out = usecase->stream.out;
vivek mehtaa68fea62017-06-08 19:04:02 -0700404 ALOGV("%s send cal for app_type %d, rate %d", __func__,
405 out->app_type_cfg.app_type,
406 out->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800407 platform_send_audio_calibration_v2(adev->platform, usecase,
vivek mehtaa68fea62017-06-08 19:04:02 -0700408 out->app_type_cfg.app_type,
409 out->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800410 } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) {
vivek mehtaa68fea62017-06-08 19:04:02 -0700411 struct stream_in *in = usecase->stream.in;
412 ALOGV("%s send cal for capture app_type %d, rate %d", __func__,
413 in->app_type_cfg.app_type,
414 in->app_type_cfg.sample_rate);
415 platform_send_audio_calibration_v2(adev->platform, usecase,
416 in->app_type_cfg.app_type,
417 in->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800418 } else {
419 /* when app type is default. the sample rate is not used to send cal */
420 platform_get_default_app_type_v2(adev->platform, type, &app_type);
vivek mehtaa68fea62017-06-08 19:04:02 -0700421 platform_send_audio_calibration_v2(adev->platform, usecase, app_type,
422 48000);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800423 }
424}
vivek mehta0fb11312017-05-15 19:35:32 -0700425
426#define MAX_SND_CARD 8
427#define RETRY_US 500000
428#define RETRY_NUMBER 10
429
430#define min(a, b) ((a) < (b) ? (a) : (b))
431
432static const char *kConfigLocationList[] =
433 {"/odm/etc", "/vendor/etc", "/system/etc"};
434static const int kConfigLocationListSize =
435 (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
436
437bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
438{
439 char full_config_path[MIXER_PATH_MAX_LENGTH];
440 for (int i = 0; i < kConfigLocationListSize; i++) {
441 snprintf(full_config_path,
442 MIXER_PATH_MAX_LENGTH,
443 "%s/%s",
444 kConfigLocationList[i],
445 file_name);
446 if (F_OK == access(full_config_path, 0)) {
447 strcpy(file_name, full_config_path);
448 return true;
449 }
450 }
451 return false;
452}
453
454/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700455int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
vivek mehta0fb11312017-05-15 19:35:32 -0700456{
457 if (NULL == snd_card_name) {
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700458 return -1;
vivek mehta0fb11312017-05-15 19:35:32 -0700459 }
460
461 struct snd_card_split *snd_split_handle = NULL;
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700462 int ret = 0;
vivek mehta0fb11312017-05-15 19:35:32 -0700463 audio_extn_set_snd_card_split(snd_card_name);
464 snd_split_handle = audio_extn_get_snd_card_split();
465
466 snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
467 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
468 snd_split_handle->form_factor);
469
470 if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
471 memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
472 snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
473 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
474
475 if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
476 memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
477 strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700478 ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
vivek mehta0fb11312017-05-15 19:35:32 -0700479 }
480 }
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700481
482 return ret;
vivek mehta0fb11312017-05-15 19:35:32 -0700483}
484
485int audio_extn_utils_get_snd_card_num()
486{
487
488 void *hw_info = NULL;
489 struct mixer *mixer = NULL;
490 int retry_num = 0;
491 int snd_card_num = 0;
492 const char* snd_card_name = NULL;
493 char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
494
495 struct acdb_platform_data *my_data = calloc(1, sizeof(struct acdb_platform_data));
496
497 bool card_verifed[MAX_SND_CARD] = {0};
498 const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);
499
500 for (;;) {
501 if (snd_card_num >= MAX_SND_CARD) {
502 if (retry_num++ >= retry_limit) {
503 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
504 snd_card_num = -1;
505 goto done;
506 }
507
508 snd_card_num = 0;
509 usleep(RETRY_US);
510 continue;
511 }
512
513 if (card_verifed[snd_card_num]) {
514 ++snd_card_num;
515 continue;
516 }
517
518 mixer = mixer_open(snd_card_num);
519
520 if (!mixer) {
521 ALOGE("%s: Unable to open the mixer card: %d", __func__,
522 snd_card_num);
523 ++snd_card_num;
524 continue;
525 }
526
527 card_verifed[snd_card_num] = true;
528
529 snd_card_name = mixer_get_name(mixer);
530 hw_info = hw_info_init(snd_card_name);
531
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700532 if (audio_extn_utils_get_platform_info(snd_card_name, platform_info_file) < 0) {
533 ALOGE("Failed to find platform_info_file");
534 goto cleanup;
535 }
vivek mehta0fb11312017-05-15 19:35:32 -0700536
537 /* Initialize snd card name specific ids and/or backends*/
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700538 if (snd_card_info_init(platform_info_file, my_data,
539 &acdb_set_parameters) < 0) {
540 ALOGE("Failed to find platform_info_file");
541 goto cleanup;
542 }
vivek mehta0fb11312017-05-15 19:35:32 -0700543
544 /* validate the sound card name
545 * my_data->snd_card_name can contain
546 * <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card
547 * example: msm8994-tomtom-mtp-snd-card
548 * <b> or sub string of the card name, i.e. <device>-<codec>
549 * example: msm8994-tomtom
550 * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation
551 * so use min of my_data->snd_card_name and snd_card_name length for comparison
552 */
553
554 if (my_data->snd_card_name != NULL &&
555 strncmp(snd_card_name, my_data->snd_card_name,
556 min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) {
557 ALOGI("%s: found valid sound card %s, but not primary sound card %s",
558 __func__, snd_card_name, my_data->snd_card_name);
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700559 goto cleanup;
vivek mehta0fb11312017-05-15 19:35:32 -0700560 }
561
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700562 ALOGI("%s: found sound card %s, primary sound card expected is %s",
vivek mehta0fb11312017-05-15 19:35:32 -0700563 __func__, snd_card_name, my_data->snd_card_name);
564 break;
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700565 cleanup:
566 ++snd_card_num;
567 mixer_close(mixer);
568 mixer = NULL;
569 hw_info_deinit(hw_info);
570 hw_info = NULL;
vivek mehta0fb11312017-05-15 19:35:32 -0700571 }
572
573done:
574 mixer_close(mixer);
575 hw_info_deinit(hw_info);
576
577 if (my_data)
578 free(my_data);
579
580 return snd_card_num;
581}