1/* 2 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#define LOG_TAG "hardware_info" 31/*#define LOG_NDEBUG 0*/ 32#define LOG_NDDEBUG 0 33 34#include <stdlib.h> 35#include <dlfcn.h> 36#include <cutils/log.h> 37#include <cutils/str_parms.h> 38#include "audio_hw.h" 39#include "platform.h" 40#include "platform_api.h" 41 42 43struct hardware_info { 44 char name[HW_INFO_ARRAY_MAX_SIZE]; 45 char type[HW_INFO_ARRAY_MAX_SIZE]; 46 /* variables for handling target variants */ 47 uint32_t num_snd_devices; 48 char dev_extn[HW_INFO_ARRAY_MAX_SIZE]; 49 snd_device_t *snd_devices; 50}; 51 52#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 53 54static const snd_device_t taiko_fluid_variant_devices[] = { 55 SND_DEVICE_OUT_SPEAKER, 56 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 57 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 58}; 59 60static const snd_device_t taiko_CDP_variant_devices[] = { 61 SND_DEVICE_OUT_SPEAKER, 62 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 63 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 64 SND_DEVICE_IN_QUAD_MIC, 65}; 66 67static const snd_device_t taiko_apq8084_CDP_variant_devices[] = { 68 SND_DEVICE_IN_HANDSET_MIC, 69}; 70 71static const snd_device_t taiko_liquid_variant_devices[] = { 72 SND_DEVICE_OUT_SPEAKER, 73 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 74 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 75 SND_DEVICE_IN_SPEAKER_MIC, 76 SND_DEVICE_IN_HEADSET_MIC, 77 SND_DEVICE_IN_VOICE_DMIC, 78 SND_DEVICE_IN_VOICE_SPEAKER_DMIC, 79 SND_DEVICE_IN_VOICE_REC_DMIC_STEREO, 80 SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE, 81 SND_DEVICE_IN_QUAD_MIC, 82 SND_DEVICE_IN_HANDSET_STEREO_DMIC, 83 SND_DEVICE_IN_SPEAKER_STEREO_DMIC, 84}; 85 86static const snd_device_t taiko_DB_variant_devices[] = { 87 SND_DEVICE_OUT_SPEAKER, 88 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 89 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 90 SND_DEVICE_IN_SPEAKER_MIC, 91 SND_DEVICE_IN_HEADSET_MIC, 92 SND_DEVICE_IN_QUAD_MIC, 93}; 94 95static const snd_device_t tapan_lite_variant_devices[] = { 96 SND_DEVICE_OUT_SPEAKER, 97 SND_DEVICE_OUT_HEADPHONES, 98 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 99 SND_DEVICE_OUT_VOICE_HEADPHONES, 100 SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES, 101 SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES, 102}; 103 104static const snd_device_t tapan_skuf_variant_devices[] = { 105 SND_DEVICE_OUT_SPEAKER, 106 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 107 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 108 /*SND_DEVICE_OUT_SPEAKER_AND_ANC_FB_HEADSET,*/ 109}; 110 111static const snd_device_t tapan_lite_skuf_variant_devices[] = { 112 SND_DEVICE_OUT_SPEAKER, 113 SND_DEVICE_OUT_HEADPHONES, 114 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 115 SND_DEVICE_OUT_VOICE_HEADPHONES, 116 SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES, 117 SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES, 118}; 119 120static const snd_device_t helicon_skuab_variant_devices[] = { 121 SND_DEVICE_OUT_SPEAKER, 122 SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES, 123 SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET, 124}; 125 126static void update_hardware_info_8x16(struct hardware_info *hw_info, const char *snd_card_name) 127{ 128 if (!strcmp(snd_card_name, "msm8x16-snd-card")) { 129 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 130 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 131 hw_info->snd_devices = NULL; 132 hw_info->num_snd_devices = 0; 133 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 134 } else if (!strcmp(snd_card_name, "msm8x16-snd-card-mtp")) { 135 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 136 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 137 hw_info->snd_devices = NULL; 138 hw_info->num_snd_devices = 0; 139 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 140 } else if (!strcmp(snd_card_name, "msm8x16-snd-card-sbc")) { 141 strlcpy(hw_info->type, "sbc", sizeof(hw_info->type)); 142 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 143 hw_info->snd_devices = NULL; 144 hw_info->num_snd_devices = 0; 145 } else if (!strcmp(snd_card_name, "msm8x16-skuh-snd-card")) { 146 strlcpy(hw_info->type, "skuh", sizeof(hw_info->type)); 147 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 148 hw_info->snd_devices = NULL; 149 hw_info->num_snd_devices = 0; 150 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 151 } else if (!strcmp(snd_card_name, "msm8x16-skui-snd-card")) { 152 strlcpy(hw_info->type, "skui", sizeof(hw_info->type)); 153 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 154 hw_info->snd_devices = NULL; 155 hw_info->num_snd_devices = 0; 156 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 157 } else if (!strcmp(snd_card_name, "msm8x16-skuhf-snd-card")) { 158 strlcpy(hw_info->type, "skuhf", sizeof(hw_info->type)); 159 strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name)); 160 hw_info->snd_devices = NULL; 161 hw_info->num_snd_devices = 0; 162 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 163 } else if (!strcmp(snd_card_name, "msm8939-snd-card")) { 164 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 165 strlcpy(hw_info->name, "msm8939", sizeof(hw_info->name)); 166 hw_info->snd_devices = NULL; 167 hw_info->num_snd_devices = 0; 168 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 169 } else if (!strcmp(snd_card_name, "msm8939-snd-card-mtp")) { 170 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 171 strlcpy(hw_info->name, "msm8939", sizeof(hw_info->name)); 172 hw_info->snd_devices = NULL; 173 hw_info->num_snd_devices = 0; 174 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 175 } else if (!strcmp(snd_card_name, "msm8939-snd-card-skuk")) { 176 strlcpy(hw_info->type, "skuk", sizeof(hw_info->type)); 177 strlcpy(hw_info->name, "msm8939", sizeof(hw_info->name)); 178 hw_info->snd_devices = NULL; 179 hw_info->num_snd_devices = 0; 180 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 181 } else if (!strcmp(snd_card_name, "msm8939-tapan-snd-card") || 182 !strcmp(snd_card_name, "msm8939-tapan9302-snd-card")) { 183 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 184 strlcpy(hw_info->name, "msm8939", sizeof(hw_info->name)); 185 hw_info->snd_devices = NULL; 186 hw_info->num_snd_devices = 0; 187 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 188 } else if (!strcmp(snd_card_name, "msm8909-snd-card")) { 189 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 190 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 191 hw_info->snd_devices = NULL; 192 hw_info->num_snd_devices = 0; 193 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 194 } else if (!strcmp(snd_card_name, "msm8909-skua-snd-card")) { 195 strlcpy(hw_info->type, "skua", sizeof(hw_info->type)); 196 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 197 hw_info->snd_devices = NULL; 198 hw_info->num_snd_devices = 0; 199 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 200 } else if (!strcmp(snd_card_name, "msm8909-skuc-snd-card")) { 201 strlcpy(hw_info->type, "skuc", sizeof(hw_info->type)); 202 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 203 hw_info->snd_devices = NULL; 204 hw_info->num_snd_devices = 0; 205 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 206 } else if (!strcmp(snd_card_name, "msm8909-pm8916-snd-card")) { 207 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 208 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 209 hw_info->snd_devices = NULL; 210 hw_info->num_snd_devices = 0; 211 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 212 } else if (!strcmp(snd_card_name, "msm8909-skue-snd-card")) { 213 strlcpy(hw_info->type, "skue", sizeof(hw_info->type)); 214 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 215 hw_info->snd_devices = NULL; 216 hw_info->num_snd_devices = 0; 217 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 218 } else if (!strcmp(snd_card_name, "msm8939-snd-card-skul")) { 219 strlcpy(hw_info->type, "skul", sizeof(hw_info->type)); 220 strlcpy(hw_info->name, "msm8939", sizeof(hw_info->name)); 221 hw_info->snd_devices = NULL; 222 hw_info->num_snd_devices = 0; 223 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 224 } else if (!strcmp(snd_card_name, "msm8909-skut-snd-card")) { 225 strlcpy(hw_info->type, "skut", sizeof(hw_info->type)); 226 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 227 hw_info->snd_devices = NULL; 228 hw_info->num_snd_devices = 0; 229 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 230 } else if (!strcmp(snd_card_name, "msm8x09-tasha9326-snd-card")) { 231 strlcpy(hw_info->type, "", sizeof(hw_info->type)); 232 strlcpy(hw_info->name, "msm8909", sizeof(hw_info->name)); 233 hw_info->snd_devices = NULL; 234 hw_info->num_snd_devices = 0; 235 strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); 236 } else { 237 ALOGW("%s: Not an 8x16/8939/8909 device", __func__); 238 } 239} 240 241void *hw_info_init(const char *snd_card_name) 242{ 243 struct hardware_info *hw_info; 244 245 hw_info = malloc(sizeof(struct hardware_info)); 246 if (!hw_info) { 247 ALOGE("failed to allocate mem for hardware info"); 248 return NULL; 249 } 250 251 if (strstr(snd_card_name, "msm8x16") || strstr(snd_card_name, "msm8939") || 252 strstr(snd_card_name, "msm8909") || strstr(snd_card_name, "msm8x09")) { 253 ALOGV("8x16 - variant soundcard"); 254 update_hardware_info_8x16(hw_info, snd_card_name); 255 } else { 256 ALOGE("%s: Unsupported target %s:",__func__, snd_card_name); 257 free(hw_info); 258 hw_info = NULL; 259 } 260 261 return hw_info; 262} 263 264void hw_info_deinit(void *hw_info) 265{ 266 struct hardware_info *my_data = (struct hardware_info*) hw_info; 267 268 if(!my_data) 269 free(my_data); 270} 271 272void hw_info_append_hw_type(void *hw_info, snd_device_t snd_device, 273 char *device_name) 274{ 275 struct hardware_info *my_data = (struct hardware_info*) hw_info; 276 uint32_t i = 0; 277 278 snd_device_t *snd_devices = 279 (snd_device_t *) my_data->snd_devices; 280 281 if(snd_devices != NULL) { 282 for (i = 0; i < my_data->num_snd_devices; i++) { 283 if (snd_device == (snd_device_t)snd_devices[i]) { 284 ALOGV("extract dev_extn device %d, extn = %s", 285 (snd_device_t)snd_devices[i], my_data->dev_extn); 286 CHECK(strlcat(device_name, my_data->dev_extn, 287 DEVICE_NAME_MAX_SIZE) < DEVICE_NAME_MAX_SIZE); 288 break; 289 } 290 } 291 } 292 ALOGD("%s : device_name = %s", __func__,device_name); 293} 294