1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <iniparser.h> 7 #include <syslog.h> 8 9 #include "cras_util.h" 10 #include "cras_volume_curve.h" 11 #include "utlist.h" 12 13 /* Allocate 63 chars + 1 for null where declared. */ 14 static const unsigned int MAX_INI_NAME_LEN = 63; 15 static const unsigned int MAX_KEY_LEN = 63; 16 17 struct cras_card_config { 18 dictionary *ini; 19 }; 20 21 static struct cras_volume_curve *create_simple_step_curve( 22 const struct cras_card_config *card_config, 23 const char *control_name) 24 { 25 char ini_key[MAX_KEY_LEN + 1]; 26 int max_volume; 27 int volume_step; 28 29 snprintf(ini_key, MAX_KEY_LEN, "%s:max_volume", control_name); 30 ini_key[MAX_KEY_LEN] = 0; 31 max_volume = iniparser_getint(card_config->ini, ini_key, 0); 32 snprintf(ini_key, MAX_KEY_LEN, "%s:volume_step", control_name); 33 ini_key[MAX_KEY_LEN] = 0; 34 volume_step = iniparser_getint(card_config->ini, ini_key, 300); 35 syslog(LOG_INFO, "Configure curve found for %s.", control_name); 36 return cras_volume_curve_create_simple_step(max_volume, volume_step); 37 } 38 39 static struct cras_volume_curve *create_explicit_curve( 40 const struct cras_card_config *card_config, 41 const char *control_name) 42 { 43 unsigned int i; 44 char ini_key[MAX_KEY_LEN + 1]; 45 long dB_values[101]; 46 47 for (i = 0; i < 101; i++) { 48 snprintf(ini_key, MAX_KEY_LEN, "%s:dB_at_%u", control_name, i); 49 ini_key[MAX_KEY_LEN] = 0; 50 dB_values[i] = iniparser_getint(card_config->ini, ini_key, 0); 51 } 52 syslog(LOG_INFO, "Explicit volume curve found for %s.", control_name); 53 return cras_volume_curve_create_explicit(dB_values); 54 } 55 56 /* 57 * Exported interface. 58 */ 59 60 struct cras_card_config *cras_card_config_create(const char *config_path, 61 const char *card_name) 62 { 63 struct cras_card_config *card_config = NULL; 64 char ini_name[MAX_INI_NAME_LEN + 1]; 65 dictionary *ini; 66 67 snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_path, card_name); 68 ini_name[MAX_INI_NAME_LEN] = '\0'; 69 ini = iniparser_load(ini_name); 70 if (ini == NULL) { 71 syslog(LOG_DEBUG, "No ini file %s", ini_name); 72 return NULL; 73 } 74 75 card_config = calloc(1, sizeof(*card_config)); 76 if (card_config == NULL) { 77 iniparser_freedict(ini); 78 return NULL; 79 } 80 81 card_config->ini = ini; 82 syslog(LOG_DEBUG, "Loaded ini file %s", ini_name); 83 return card_config; 84 } 85 86 void cras_card_config_destroy(struct cras_card_config *card_config) 87 { 88 assert(card_config); 89 iniparser_freedict(card_config->ini); 90 free(card_config); 91 } 92 93 struct cras_volume_curve *cras_card_config_get_volume_curve_for_control( 94 const struct cras_card_config *card_config, 95 const char *control_name) 96 { 97 char ini_key[MAX_KEY_LEN + 1]; 98 const char *curve_type; 99 100 if (card_config == NULL || control_name == NULL) 101 return NULL; 102 103 snprintf(ini_key, MAX_KEY_LEN, "%s:volume_curve", control_name); 104 ini_key[MAX_KEY_LEN] = 0; 105 curve_type = iniparser_getstring(card_config->ini, ini_key, NULL); 106 107 if (curve_type && strcmp(curve_type, "simple_step") == 0) 108 return create_simple_step_curve(card_config, control_name); 109 if (curve_type && strcmp(curve_type, "explicit") == 0) 110 return create_explicit_curve(card_config, control_name); 111 syslog(LOG_DEBUG, "No configure curve found for %s.", control_name); 112 return NULL; 113 } 114