blob: c2e4e66332767df6201cbf19f042baf7c6518f31 [file] [log] [blame]
/*
Copyright Statement:
This software/firmware and related documentation ("MediaTek Software") are
protected under relevant copyright laws. The information contained herein is
confidential and proprietary to MediaTek Inc. and/or its licensors. Without
the prior written permission of MediaTek inc. and/or its licensors, any
reproduction, modification, use or disclosure of MediaTek Software, and
information contained herein, in whole or in part, shall be strictly
prohibited.
MediaTek Inc. (C) 2016. All rights reserved.
BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
Auther: Garlic Tseng <garlic.tseng@mediatek.com>
*/
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#define STR_SIZE 128
#define DEFAULT_CARD_NAME "hw:0"
//mixer control structure for sound card
static snd_mixer_t *g_all_mixer_handler;
static char g_customize_card_name[STR_SIZE] = {'\0'};
static snd_mixer_elem_t *get_mixer_item_handler(const char *mixer_ctrl_name)
{
snd_mixer_selem_id_t *mixer_select = NULL;
snd_mixer_elem_t *mixer_item_handler = NULL;
int ret = 0;
ret = snd_mixer_selem_id_malloc(&mixer_select);
if (ret) {
printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
goto MIXER_ITEM_CREATE_ERROR;
}
snd_mixer_selem_id_set_index(mixer_select, 0);
if (ret) {
printf("%s, snd_mixer_selem_id_set_index failed: %d\n",
__func__, ret);
goto MIXER_ITEM_CREATE_ERROR;
}
snd_mixer_selem_id_set_name(mixer_select, mixer_ctrl_name);
if (ret) {
printf("%s, snd_mixer_selem_id_set_name failed: %d\n",
__func__, ret);
goto MIXER_ITEM_CREATE_ERROR;
}
mixer_item_handler = snd_mixer_find_selem(g_all_mixer_handler,
mixer_select);
if (!mixer_item_handler) {
printf("%s, snd_mixer_find_selem not found\n", __func__);
}
snd_mixer_selem_id_free(mixer_select);
return mixer_item_handler;
MIXER_ITEM_CREATE_ERROR:
snd_mixer_selem_id_free(mixer_select);
return NULL;
}
int set_card_name(const char *mixer_ctrl_name)
{
if (g_all_mixer_handler) {
snd_mixer_close(g_all_mixer_handler);
g_all_mixer_handler = 0;
}
strncpy(g_customize_card_name, mixer_ctrl_name, STR_SIZE);
return 0;
}
static int initial_all_mixer_handler()
{
int ret = 0;
ret = snd_mixer_open(&g_all_mixer_handler, 0);
if (ret) {
printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
goto ALL_MIXER_CREATE_ERROR;
}
if (g_customize_card_name[0] == '\0')
ret = snd_mixer_attach(g_all_mixer_handler, DEFAULT_CARD_NAME);
else
ret = snd_mixer_attach(g_all_mixer_handler, g_customize_card_name);
if (ret) {
printf("%s, snd_mixer_attach failed: %d\n", __func__, ret);
goto ALL_MIXER_CREATE_ERROR;
}
ret = snd_mixer_selem_register(g_all_mixer_handler, NULL, NULL);
if (ret) {
printf("%s, snd_mixer_selem_register failed: %d\n", __func__,
ret);
goto ALL_MIXER_CREATE_ERROR;
}
ret = snd_mixer_load(g_all_mixer_handler);
if (ret) {
printf("%s, snd_mixer_load failed: %d\n", __func__, ret);
/* goto ALL_MIXER_CREATE_ERROR; */
}
return 0;
ALL_MIXER_CREATE_ERROR:
snd_mixer_close(g_all_mixer_handler);
g_all_mixer_handler = 0;
return ret;
}
int set_mixer_ctrl_value_int(const char *mixer_ctrl_name,
const int option_int)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
int ret;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
/* mixer control item */
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, option_int);
if (ret) {
printf("%s, set_enum_item failed: %d, option_int: %d\n",
__func__, ret, option_int);
return ret;
}
return 0;
}
int set_mixer_ctrl_volume_value(const char *mixer_ctrl_name,
const long volume)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
int ret;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
/* mixer control item */
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret = snd_mixer_selem_set_playback_volume(mixer_item_handler, 0, volume);
if (ret) {
printf("%s, set_enum_item failed: %d, volume: %ld\n",
__func__, ret, volume);
return ret;
}
return 0;
}
long get_mixer_ctrl_volume_value(const char *mixer_ctrl_name)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
long mixer_item_value[1];
int ret;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret = snd_mixer_selem_get_playback_volume(mixer_item_handler, 0,
mixer_item_value);
if (ret) {
printf("%s, snd_mixer_selem_get_playback_volume failed: %d\n",
__func__, ret);
return ret;
}
return mixer_item_value[0];
}
int set_mixer_ctrl_interconn_value(const char *mixer_ctrl_name,
int is_on)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
int ret = 0;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
/*printf("%s, mixerctrl (%s) is_on (%d)!\n", __func__, mixer_ctrl_name, is_on); */
/* mixer control item */
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret =
snd_mixer_selem_set_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO , is_on);
/* printf("%s, snd_mixer_selem_set_playback_switch: %d\n", __func__, ret); */
/* if failed, get_enum_items return nagetive error num. */
if (ret < 0) {
printf("%s, snd_mixer_selem_set_playback_switch failed: %d\n",
__func__, ret);
}
return ret;
}
int get_mixer_ctrl_interconn_value(const char *mixer_ctrl_name)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
unsigned int mixer_item_value;
int ret;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
/* mixer control item */
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret =
snd_mixer_selem_get_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO, &mixer_item_value);
/* printf("%s, snd_mixer_selem_get_playback_switch: %d\n", __func__, ret); */
/* if failed, get_enum_items return nagetive error num. */
if (ret < 0) {
printf("%s, snd_mixer_selem_get_playback_switch failed: %d\n",
__func__, ret);
}
/* printf("%s, mixerctrl (%s) mixer_item_value (%d)!\n", __func__, mixer_ctrl_name, mixer_item_value[0]); */
return mixer_item_value;
}
int set_mixer_ctrl_value_string(const char *mixer_ctrl_name,
const char *option_name)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
int mixer_item_option_num = 0;
int i, ret;
char item_name[STR_SIZE];
if (!g_all_mixer_handler)
initial_all_mixer_handler();
/* mixer control item */
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
mixer_item_option_num =
snd_mixer_selem_get_enum_items(mixer_item_handler);
/* if failed, get_enum_items return nagetive error num. */
if (mixer_item_option_num < 0) {
printf("%s, snd_mixer_selem_get_enum_items failed: %d\n",
__func__, mixer_item_option_num);
return mixer_item_option_num;
}
/* find option_name index */
for (i = 0; i < mixer_item_option_num; i++) {
ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler, i,
STR_SIZE, item_name);
if (ret)
printf("%s, get_enum_item_name failed: %d, i: %d\n",
__func__, ret, i);
if (!strcmp(option_name, item_name))
break;
}
/* not found */
if (i == mixer_item_option_num) {
printf("%s, option_name (%s) not found in mixerctrl (%s)!\n",
__func__, option_name, mixer_ctrl_name);
return -EINVAL;
}
/* found: the index is 'i' */
ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, i);
if (ret) {
printf("%s, set_enum_item failed: %d, i: %d\n",
__func__, ret, i);
return ret;
}
return 0;
}
int get_mixer_ctrl_value_int(const char *mixer_ctrl_name)
{
snd_mixer_elem_t *mixer_item_handler = NULL;
unsigned int mixer_item_value[1];
int ret;
if (!g_all_mixer_handler)
initial_all_mixer_handler();
mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
if (!mixer_item_handler) {
printf("%s, get_mixer_item_handler failed!\n", __func__);
return -EINVAL;
}
ret = snd_mixer_selem_get_enum_item(mixer_item_handler, 0,
mixer_item_value);
if (ret) {
printf("%s, selem_get_enum_item failed: %d\n", __func__, ret);
return ret;
}
return mixer_item_value[0];
}
char *get_mixer_ctrl_value_string(const char *mixer_ctrl_name,
char *returned_value_name,
int value_name_size)
{
snd_mixer_elem_t *mixer_item_handler =
get_mixer_item_handler(mixer_ctrl_name);
int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
int ret;
char item_name[STR_SIZE];
ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler,
mixer_value_int,
STR_SIZE, item_name);
if (ret) {
printf("%s, get_enum_item_name failed: %d, mixer_value_int: %d\n",
__func__, ret, mixer_value_int);
return NULL;
}
return strncpy(returned_value_name, item_name, value_name_size);
}