blob: 2fc424c161a5c2ea17819cc9db488aef05552630 [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{
vivek mehtaa68fea62017-06-08 19:04:02 -0700217 struct stream_in *in = usecase->stream.in;
218 struct stream_app_type_cfg *app_type_cfg = &in->app_type_cfg;
219
220 *sample_rate = DEFAULT_INPUT_SAMPLING_RATE;
221 if (in->device & AUDIO_DEVICE_IN_USB_DEVICE) {
222 platform_check_and_update_copp_sample_rate(adev->platform,
223 usecase->in_snd_device,
224 in->sample_rate,
225 sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800226 }
227
vivek mehtaa68fea62017-06-08 19:04:02 -0700228 app_type_cfg->mode = flags_to_mode(1 /*capture*/, in->flags);
229 ALOGV("%s mode %s", __func__, app_type_cfg->mode);
230 if (in->format == AUDIO_FORMAT_PCM_16_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800231 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700232 PCM_CAPTURE,
233 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800234 16,
vivek mehtaa68fea62017-06-08 19:04:02 -0700235 app_type_cfg->sample_rate,
236 app_type);
237 } else if (in->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
238 in->format == AUDIO_FORMAT_PCM_8_24_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800239 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700240 PCM_CAPTURE,
241 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800242 24,
vivek mehtaa68fea62017-06-08 19:04:02 -0700243 app_type_cfg->sample_rate,
244 app_type);
245 } else if (in->format == AUDIO_FORMAT_PCM_32_BIT) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800246 platform_get_app_type_v2(adev->platform,
vivek mehtaa68fea62017-06-08 19:04:02 -0700247 PCM_CAPTURE,
248 app_type_cfg->mode,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800249 32,
vivek mehtaa68fea62017-06-08 19:04:02 -0700250 app_type_cfg->sample_rate,
251 app_type);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800252 } else {
253 ALOGE("%s bad format\n", __func__);
254 return -1;
255 }
256
vivek mehtaa68fea62017-06-08 19:04:02 -0700257 app_type_cfg->app_type = *app_type;
258 app_type_cfg->sample_rate = *sample_rate;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800259 return 0;
260}
261
vivek mehtaa68fea62017-06-08 19:04:02 -0700262static int derive_playback_app_type_cfg(struct audio_device *adev,
263 struct audio_usecase *usecase,
264 int *app_type,
265 int *sample_rate)
266{
267 struct stream_out *out = usecase->stream.out;
268 struct stream_app_type_cfg *app_type_cfg = &out->app_type_cfg;
269
270 *sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
271
272 // add speaker prot changes if needed
273 // and use that to check for device
274 if (out->devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
275 platform_check_and_update_copp_sample_rate(adev->platform,
276 usecase->out_snd_device,
277 out->sample_rate,
278 sample_rate);
279 }
280
281 app_type_cfg->mode = flags_to_mode(0 /*playback*/, out->flags);
282 if (!audio_is_linear_pcm(out->format)) {
283 platform_get_default_app_type_v2(adev->platform,
284 PCM_PLAYBACK,
285 app_type);
286 } else if (out->format == AUDIO_FORMAT_PCM_16_BIT) {
287 platform_get_app_type_v2(adev->platform,
288 PCM_PLAYBACK,
289 app_type_cfg->mode,
290 16,
291 *sample_rate,
292 app_type);
293 } else if (out->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
294 out->format == AUDIO_FORMAT_PCM_8_24_BIT) {
295 platform_get_app_type_v2(adev->platform,
296 PCM_PLAYBACK,
297 app_type_cfg->mode,
298 24,
299 *sample_rate,
300 app_type);
301 } else if (out->format == AUDIO_FORMAT_PCM_32_BIT) {
302 platform_get_app_type_v2(adev->platform,
303 PCM_PLAYBACK,
304 app_type_cfg->mode,
305 32,
306 *sample_rate,
307 app_type);
308 } else {
309 ALOGE("%s bad format\n", __func__);
310 return -1;
311 }
312
313 app_type_cfg->app_type = *app_type;
314 app_type_cfg->sample_rate = *sample_rate;
315 return 0;
316}
317
318static int derive_acdb_dev_id(struct audio_device *adev __unused,
319 struct audio_usecase *usecase)
320{
321 struct stream_out *out;
322 struct stream_in *in;
323
324 if (usecase->type == PCM_PLAYBACK) {
325 return platform_get_snd_device_acdb_id(usecase->out_snd_device);
326 } else if(usecase->type == PCM_CAPTURE) {
327 return platform_get_snd_device_acdb_id(usecase->in_snd_device);
328 }
329 return -1;
330}
331
332int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
333 struct audio_usecase *usecase)
334{
335 int len = 0;
336 int sample_rate;
337 int app_type;
338 int acdb_dev_id;
339 size_t app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
340 char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
341 int pcm_device_id;
342 struct mixer_ctl *ctl;
343 int ret;
344
345 if (usecase->type == PCM_HFP_CALL) {
346 return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
347 }
348
349 if (!platform_supports_app_type_cfg())
350 return -1;
351
352 if (usecase->type == PCM_PLAYBACK) {
353 ret = derive_playback_app_type_cfg(adev,
354 usecase,
355 &app_type,
356 &sample_rate);
357 } else if (usecase->type == PCM_CAPTURE) {
358 ret = derive_capture_app_type_cfg(adev,
359 usecase,
360 &app_type,
361 &sample_rate);
362 } else {
363 ALOGE("%s: Invalid uc type : 0x%x", __func__, usecase->type);
364 return -1;
365 }
366
367 if (ret < 0) {
368 ALOGE("%s: Failed to derive app_type for uc type : 0x%x", __func__,
369 usecase->type);
370 return -1;
371 }
372
373 acdb_dev_id = derive_acdb_dev_id(adev, usecase);
374 if (acdb_dev_id <= 0) {
375 ALOGE("%s: Couldn't get the acdb dev id", __func__);
376 return -1;
377 }
378
379 pcm_device_id = platform_get_pcm_device_id(usecase->id, usecase->type);
380 set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id,
381 sample_rate,
382 usecase->type,
383 usecase->type == PCM_PLAYBACK ? usecase->out_snd_device :
384 usecase->in_snd_device);
385 return 0;
386}
387
388// this assumes correct app_type and sample_rate fields
389// have been set for the stream using audio_extn_utils_send_app_type_cfg
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800390void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
391 struct audio_usecase *usecase)
392{
393 int type = usecase->type;
394 int app_type = 0;
395
396 if (type == PCM_PLAYBACK && usecase->stream.out != NULL) {
397 struct stream_out *out = usecase->stream.out;
vivek mehtaa68fea62017-06-08 19:04:02 -0700398 ALOGV("%s send cal for app_type %d, rate %d", __func__,
399 out->app_type_cfg.app_type,
400 out->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800401 platform_send_audio_calibration_v2(adev->platform, usecase,
vivek mehtaa68fea62017-06-08 19:04:02 -0700402 out->app_type_cfg.app_type,
403 out->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800404 } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) {
vivek mehtaa68fea62017-06-08 19:04:02 -0700405 struct stream_in *in = usecase->stream.in;
406 ALOGV("%s send cal for capture app_type %d, rate %d", __func__,
407 in->app_type_cfg.app_type,
408 in->app_type_cfg.sample_rate);
409 platform_send_audio_calibration_v2(adev->platform, usecase,
410 in->app_type_cfg.app_type,
411 in->app_type_cfg.sample_rate);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800412 } else {
413 /* when app type is default. the sample rate is not used to send cal */
414 platform_get_default_app_type_v2(adev->platform, type, &app_type);
vivek mehtaa68fea62017-06-08 19:04:02 -0700415 platform_send_audio_calibration_v2(adev->platform, usecase, app_type,
416 48000);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800417 }
418}
vivek mehta0fb11312017-05-15 19:35:32 -0700419
420#define MAX_SND_CARD 8
421#define RETRY_US 500000
422#define RETRY_NUMBER 10
423
424#define min(a, b) ((a) < (b) ? (a) : (b))
425
426static const char *kConfigLocationList[] =
427 {"/odm/etc", "/vendor/etc", "/system/etc"};
428static const int kConfigLocationListSize =
429 (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
430
431bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
432{
433 char full_config_path[MIXER_PATH_MAX_LENGTH];
434 for (int i = 0; i < kConfigLocationListSize; i++) {
435 snprintf(full_config_path,
436 MIXER_PATH_MAX_LENGTH,
437 "%s/%s",
438 kConfigLocationList[i],
439 file_name);
440 if (F_OK == access(full_config_path, 0)) {
441 strcpy(file_name, full_config_path);
442 return true;
443 }
444 }
445 return false;
446}
447
448/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700449int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
vivek mehta0fb11312017-05-15 19:35:32 -0700450{
451 if (NULL == snd_card_name) {
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700452 return -1;
vivek mehta0fb11312017-05-15 19:35:32 -0700453 }
454
455 struct snd_card_split *snd_split_handle = NULL;
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700456 int ret = 0;
vivek mehta0fb11312017-05-15 19:35:32 -0700457 audio_extn_set_snd_card_split(snd_card_name);
458 snd_split_handle = audio_extn_get_snd_card_split();
459
460 snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
461 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
462 snd_split_handle->form_factor);
463
464 if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
465 memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
466 snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
467 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
468
469 if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
470 memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
471 strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700472 ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
vivek mehta0fb11312017-05-15 19:35:32 -0700473 }
474 }
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700475
476 return ret;
vivek mehta0fb11312017-05-15 19:35:32 -0700477}
478
479int audio_extn_utils_get_snd_card_num()
480{
481
482 void *hw_info = NULL;
483 struct mixer *mixer = NULL;
484 int retry_num = 0;
485 int snd_card_num = 0;
486 const char* snd_card_name = NULL;
487 char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
488
489 struct acdb_platform_data *my_data = calloc(1, sizeof(struct acdb_platform_data));
490
491 bool card_verifed[MAX_SND_CARD] = {0};
492 const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);
493
494 for (;;) {
495 if (snd_card_num >= MAX_SND_CARD) {
496 if (retry_num++ >= retry_limit) {
497 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
498 snd_card_num = -1;
499 goto done;
500 }
501
502 snd_card_num = 0;
503 usleep(RETRY_US);
504 continue;
505 }
506
507 if (card_verifed[snd_card_num]) {
508 ++snd_card_num;
509 continue;
510 }
511
512 mixer = mixer_open(snd_card_num);
513
514 if (!mixer) {
515 ALOGE("%s: Unable to open the mixer card: %d", __func__,
516 snd_card_num);
517 ++snd_card_num;
518 continue;
519 }
520
521 card_verifed[snd_card_num] = true;
522
523 snd_card_name = mixer_get_name(mixer);
524 hw_info = hw_info_init(snd_card_name);
525
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700526 if (audio_extn_utils_get_platform_info(snd_card_name, platform_info_file) < 0) {
527 ALOGE("Failed to find platform_info_file");
528 goto cleanup;
529 }
vivek mehta0fb11312017-05-15 19:35:32 -0700530
531 /* Initialize snd card name specific ids and/or backends*/
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700532 if (snd_card_info_init(platform_info_file, my_data,
533 &acdb_set_parameters) < 0) {
534 ALOGE("Failed to find platform_info_file");
535 goto cleanup;
536 }
vivek mehta0fb11312017-05-15 19:35:32 -0700537
538 /* validate the sound card name
539 * my_data->snd_card_name can contain
540 * <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card
541 * example: msm8994-tomtom-mtp-snd-card
542 * <b> or sub string of the card name, i.e. <device>-<codec>
543 * example: msm8994-tomtom
544 * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation
545 * so use min of my_data->snd_card_name and snd_card_name length for comparison
546 */
547
548 if (my_data->snd_card_name != NULL &&
549 strncmp(snd_card_name, my_data->snd_card_name,
550 min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) {
551 ALOGI("%s: found valid sound card %s, but not primary sound card %s",
552 __func__, snd_card_name, my_data->snd_card_name);
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700553 goto cleanup;
vivek mehta0fb11312017-05-15 19:35:32 -0700554 }
555
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700556 ALOGI("%s: found sound card %s, primary sound card expected is %s",
vivek mehta0fb11312017-05-15 19:35:32 -0700557 __func__, snd_card_name, my_data->snd_card_name);
558 break;
Haynes Mathew George66ff30c2017-06-01 20:24:42 -0700559 cleanup:
560 ++snd_card_num;
561 mixer_close(mixer);
562 mixer = NULL;
563 hw_info_deinit(hw_info);
564 hw_info = NULL;
vivek mehta0fb11312017-05-15 19:35:32 -0700565 }
566
567done:
568 mixer_close(mixer);
569 hw_info_deinit(hw_info);
570
571 if (my_data)
572 free(my_data);
573
574 return snd_card_num;
575}