1 /*
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 "hardware_info"
18 /*#define LOG_NDEBUG 0*/
19 #define LOG_NDDEBUG 0
20
21 #include <stdlib.h>
22 #include <log/log.h>
23 #include "audio_hw.h"
24 #include "platform.h"
25 #include "audio_extn.h"
26
27 struct hardware_info {
28 char name[HW_INFO_ARRAY_MAX_SIZE];
29 char type[HW_INFO_ARRAY_MAX_SIZE];
30 /* variables for handling target variants */
31 uint32_t num_snd_devices;
32 char dev_extn[HW_INFO_ARRAY_MAX_SIZE];
33 snd_device_t *snd_devices;
34 };
35
36 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
37
38
39 static const snd_device_t tasha_db_variant_devices[] = {
40 SND_DEVICE_OUT_SPEAKER
41 };
42
43 static const snd_device_t tasha_fluid_variant_devices[] = {
44 SND_DEVICE_OUT_SPEAKER,
45 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
46 SND_DEVICE_OUT_VOICE_SPEAKER,
47 SND_DEVICE_OUT_SPEAKER_AND_HDMI,
48 SND_DEVICE_OUT_SPEAKER_PROTECTED,
49 SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
50 };
51
52 static const snd_device_t tasha_liquid_variant_devices[] = {
53 SND_DEVICE_OUT_SPEAKER,
54 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
55 SND_DEVICE_IN_SPEAKER_MIC,
56 SND_DEVICE_IN_HEADSET_MIC,
57 SND_DEVICE_IN_VOICE_DMIC,
58 SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
59 SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
60 SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
61 SND_DEVICE_IN_QUAD_MIC,
62 };
63
update_hardware_info_8996(struct hardware_info * hw_info)64 static void update_hardware_info_8996(struct hardware_info *hw_info)
65 {
66 struct snd_card_split *tmp_handle = audio_extn_get_snd_card_split();
67 ALOGV("%s: device %s snd_card %s form_factor %s",
68 __func__, tmp_handle->device, tmp_handle->snd_card, tmp_handle->form_factor);
69
70 strlcpy(hw_info->name, tmp_handle->device, sizeof(hw_info->name));
71 snprintf(hw_info->type, sizeof(hw_info->type), " %s", tmp_handle->form_factor);
72 snprintf(hw_info->dev_extn, sizeof(hw_info->dev_extn), "-%s", tmp_handle->form_factor);
73
74 if (!strncmp(tmp_handle->form_factor, "fluid", sizeof("fluid"))) {
75 hw_info->snd_devices = (snd_device_t *)tasha_fluid_variant_devices;
76 hw_info->num_snd_devices = ARRAY_SIZE(tasha_fluid_variant_devices);
77 } else if (!strncmp(tmp_handle->form_factor, "liquid", sizeof("liquid"))) {
78 hw_info->snd_devices = (snd_device_t *)tasha_liquid_variant_devices;
79 hw_info->num_snd_devices = ARRAY_SIZE(tasha_liquid_variant_devices);
80 } else if (!strncmp(tmp_handle->form_factor, "db", sizeof("db"))) {
81 hw_info->snd_devices = (snd_device_t *)tasha_db_variant_devices;
82 hw_info->num_snd_devices = ARRAY_SIZE(tasha_db_variant_devices);
83 } else {
84 ALOGW("%s: %s form factor doesnt need mixer path over ride", __func__, tmp_handle->form_factor);
85 }
86
87 ALOGV("name %s type %s dev_extn %s", hw_info->name, hw_info->type, hw_info->dev_extn);
88 }
89
90
hw_info_init(const char * snd_card_name)91 void *hw_info_init(const char *snd_card_name)
92 {
93 struct hardware_info *hw_info = NULL;
94 bool hw_supported = false;
95
96 if (strstr(snd_card_name, "msm8996")) {
97 ALOGD("8996 - variant soundcard");
98 hw_supported = true;
99 } else {
100 ALOGE("%s: Unsupported target %s:",__func__, snd_card_name);
101 }
102
103 if (hw_supported) {
104 hw_info = malloc(sizeof(struct hardware_info));
105 if (!hw_info) {
106 ALOGE("failed to allocate mem for hardware info");
107 goto on_finish;
108 }
109
110 hw_info->snd_devices = NULL;
111 hw_info->num_snd_devices = 0;
112 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
113 strlcpy(hw_info->type, "", sizeof(hw_info->type));
114 strlcpy(hw_info->name, "", sizeof(hw_info->name));
115 update_hardware_info_8996(hw_info);
116 }
117
118 on_finish:
119 return hw_info;
120 }
121
hw_info_deinit(void * hw_info)122 void hw_info_deinit(void *hw_info)
123 {
124 free(hw_info);
125 }
126
hw_info_append_hw_type(void * hw_info,snd_device_t snd_device,char * device_name)127 void hw_info_append_hw_type(void *hw_info, snd_device_t snd_device,
128 char *device_name)
129 {
130 struct hardware_info *my_data = (struct hardware_info*) hw_info;
131 uint32_t i = 0;
132
133 if (my_data == NULL)
134 return;
135
136 snd_device_t *snd_devices =
137 (snd_device_t *) my_data->snd_devices;
138
139 if (snd_devices != NULL) {
140 for (i = 0; i < my_data->num_snd_devices; i++) {
141 if (snd_device == (snd_device_t)snd_devices[i]) {
142 ALOGV("extract dev_extn device %d, device_name %s extn = %s ",
143 (snd_device_t)snd_devices[i], device_name, my_data->dev_extn);
144 CHECK(strlcat(device_name, my_data->dev_extn,
145 DEVICE_NAME_MAX_SIZE) < DEVICE_NAME_MAX_SIZE);
146 break;
147 }
148 }
149 }
150 ALOGD("%s : device_name = %s", __func__,device_name);
151 }
152