628 lines
20 KiB
C
628 lines
20 KiB
C
/*
|
|
* Copyright (C) 2017 Amlogic Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
** aml_alsa_mixer.c
|
|
**
|
|
** This program is APIs for read/write mixers of alsa.
|
|
** author: shen pengru
|
|
**
|
|
*/
|
|
#define LOG_TAG "audio_hw_utils_alsamixer"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include "aml_audio_log.h"
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <tinyalsa/asoundlib.h>
|
|
#include <aml_alsa_mixer.h>
|
|
#include "audio_hw_utils.h"
|
|
#include "alsa_device_parser.h"
|
|
#include "aml_malloc_debug.h"
|
|
|
|
static struct aml_mixer_list gAmlMixerList[] = {
|
|
/* for i2s out status */
|
|
{AML_MIXER_ID_I2S_MUTE, "Audio i2s mute"},
|
|
/* for spdif out status */
|
|
{AML_MIXER_ID_SPDIF_MUTE, "Audio spdif mute"},
|
|
{AML_MIXER_ID_SPDIF_B_MUTE, "Audio spdif_b mute"},
|
|
/* for HDMI TX status */
|
|
{AML_MIXER_ID_HDMI_OUT_AUDIO_MUTE, "Audio hdmi-out mute"},
|
|
/* for HDMI ARC status */
|
|
{AML_MIXER_ID_HDMI_ARC_AUDIO_ENABLE, "HDMI ARC Switch"},
|
|
{AML_MIXER_ID_EARCRX_ATTENDED_TYPE, "eARC_RX attended type"},
|
|
{AML_MIXER_ID_AUDIO_IN_SRC, "Audio In Source"},
|
|
{AML_MIXER_ID_I2SIN_AUDIO_TYPE, "I2SIN Audio Type"},
|
|
{AML_MIXER_ID_SPDIFIN_AUDIO_TYPE, "SPDIFIN Audio Type"},
|
|
{AML_MIXER_ID_HW_RESAMPLE_ENABLE, "Hardware resample enable"},
|
|
{AML_MIXER_ID_OUTPUT_SWAP, "Output Swap"},
|
|
/* for HDMI RX status */
|
|
{AML_MIXER_ID_HDMI_IN_AUDIO_STABLE, "HDMIIN audio stable"},
|
|
{AML_MIXER_ID_HDMI_IN_SAMPLERATE, "HDMIIN audio samplerate"},
|
|
{AML_MIXER_ID_HDMI_IN_CHANNELS, "HDMIIN audio channels"},
|
|
{AML_MIXER_ID_HDMI_IN_FORMATS, "HDMIIN audio format"},
|
|
{AML_MIXER_ID_HDMI_IN_EDID, "HDMIIN AUDIO EDID"},
|
|
/* for ATV status */
|
|
{AML_MIXER_ID_ATV_IN_AUDIO_STABLE, "ATV audio stable"},
|
|
{AML_MIXER_ID_SPDIF_FORMAT, "Audio spdif format"},
|
|
{AML_MIXER_ID_SPDIF_B_FORMAT, "Audio spdif_b format"},
|
|
{AML_MIXER_ID_AUDIO_SRC_TO_HDMI, "HDMITX Audio Source Select"},
|
|
|
|
/* for AV status */
|
|
{AML_MIXER_ID_AV_IN_AUDIO_STABLE, "AV audio stable"},
|
|
/* for Speaker master volume */
|
|
{AML_MIXER_ID_EQ_LCH_VOLUME, "AED Lch volume"},
|
|
{AML_MIXER_ID_EQ_RCH_VOLUME, "AED Rch volume"},
|
|
{AML_MIXER_ID_EQ_MASTER_VOLUME, "AED master volume"},
|
|
{AML_MIXER_ID_AED_EQ_ENABLE, "AED EQ enable"},
|
|
/* ARCIN and SPDIFIN switch*/
|
|
{AML_MIXER_ID_SPDIFIN_ARCIN_SWITCH, "AudioIn Switch"},
|
|
{AML_MIXER_ID_SPDIFIN_PAO, "SPDIFIN PAO"},
|
|
/* HDMI IN audio format */
|
|
{AML_MIXER_ID_HDMIIN_AUDIO_TYPE, "HDMIIN Audio Type"},
|
|
/* SPDIF IN audio SRC select */
|
|
{AML_MIXER_ID_SPDIFIN_SRC, "Audio spdifin source"},
|
|
{AML_MIXER_ID_HDMIIN_AUDIO_PACKET, "HDMIIN Audio Packet"},
|
|
{AML_MIXER_ID_CHANGE_SPDIF_PLL, "SPDIF CLK Fine Setting"},
|
|
{AML_MIXER_ID_CHANGE_SPDIF_PLL_PPM, "SPDIF CLK Fine PPM Tuning"},
|
|
{AML_MIXER_ID_CHANGE_SPDIFB_PLL, "SPDIF_B CLK Fine Setting"},
|
|
{AML_MIXER_ID_CHANGE_SPDIFB_PLL_PPM, "SPDIF_B CLK Fine PPM Tuning"},
|
|
{AML_MIXER_ID_CHANGE_I2S_PLL, "TDM MCLK Fine Setting"},
|
|
{AML_MIXER_ID_CHANGE_I2S_PLL_PPM, "TDM MCLK Fine PPM Tuning"},
|
|
{AML_MIXER_ID_CHANGE_EARC_PLL, "eARC_TX CLK Fine Setting"},
|
|
{AML_MIXER_ID_CHANGE_EARC_PLL_PPM, "eARC_TX CLK Fine PPM Tuning"},
|
|
{AML_MIXER_ID_SPDIF_IN_SAMPLERATE, "SPDIFIN audio samplerate"},
|
|
{AML_MIXER_ID_HW_RESAMPLE_SOURCE, "Hw resample module"},
|
|
{AML_MIXER_ID_EARCRX_AUDIO_CODING_TYPE, "eARC_RX Audio Coding Type"},
|
|
{AML_MIXER_ID_EARCRX_CS_MUTE, "eARC_RX CS Mute"},
|
|
{AML_MIXER_ID_EARCRX_STABLE, "eARC RX stable"},
|
|
{AML_MIXER_ID_EARCRX_AUDIO_SAMPLERATE, "eARC_RX Audio Sample Frequency"},
|
|
{AML_MIXER_ID_EARCRX_AUDIO_BIT_DEPTH, "eARC_RX Audio Word Length"},
|
|
{AML_MIXER_ID_EARCRX_CHANNEL_MAP, "eARC_RX Channel Map"},
|
|
{AML_MIXER_ID_EARCRX_CA, "eARC_RX Channel Allocation"},
|
|
{AML_MIXER_ID_AUDIO_HAL_FORMAT, "Audio HAL Format"},
|
|
{AML_MIXER_ID_HDMIIN_AUDIO_EDID, "HDMIIN AUDIO EDID"},
|
|
{AML_MIXER_ID_EARC_TX_ATTENDED_TYPE, "eARC_TX attended type"},
|
|
{AML_MIXER_ID_EARC_TX_AUDIO_TYPE, "eARC_TX Audio Coding Type"},
|
|
{AML_MIXER_ID_EARC_TX_EARC_MODE, "eARC_TX eARC Mode"},
|
|
{AML_MIXER_ID_ARC_EARC_TX_ENABLE, "ARC eARC TX enable"},
|
|
{AML_MIXER_ID_EARCTX_CDS, "eARC_TX CDS"},
|
|
{AML_MIXER_ID_EARC_TX_LATENCY, "eARC_TX Latency"},
|
|
{AML_MIXER_ID_ARC_EARC_SPDIFOUT_REG_MUTE, "ARC eARC Spdifout Reg Mute"},
|
|
{AML_MIXER_ID_EARC_TX_CA, "eARC_TX Channel Allocation"},
|
|
{AML_MIXER_ID_DIGITAL_MODE, "Audio Digital Mode"},
|
|
{AML_MIXER_ID_DRC_CONTROL, "Audio DRC Control"},
|
|
{AML_MIXER_ID_OUTPUT_SELECT, "Audio Output Select"},
|
|
{AML_MIXER_ID_AML_CHIP_ID, "AML chip id"},
|
|
{AML_MIXER_ID_TVIN_VIDEO_DELAY, "TVIN VIDEO DELAY"},
|
|
{AML_MIXER_ID_TVIN_VIDEO_MIN_DELAY, "TVIN VIDEO MIN DELAY"},
|
|
{AML_MIXER_ID_TVIN_VIDEO_MAX_DELAY, "TVIN VIDEO MAX DELAY"},
|
|
{AML_MIXER_ID_SPDIF_OUT_CHANNEL_STATUS, "spdif out channel status"},
|
|
{AML_MIXER_ID_SPDIF_B_OUT_CHANNEL_STATUS, "spdif_b out channel status"},
|
|
{AML_MIXER_ID_MEDIA_VIDEO_DELAY, "Media Video Delay"},
|
|
{AML_MIXER_ID_HDMIIN_AUDIO_MODE, "HDMIIN Audio output mode"},
|
|
{AML_MIXER_ID_VAD_ENABLE, "VAD enable"},
|
|
{AML_MIXER_ID_VAD_SOURCE_SEL, "VAD Source sel"},
|
|
{AML_MIXER_ID_VAD_SWITCH, "VAD Switch"},
|
|
{AML_MIXER_ID_DTV_CLK_TUNING, "DTV clk force MPLL"},
|
|
{AML_MIXER_ID_I2S2HDMI_FORMAT, "Audio I2S to HDMITX Format"},
|
|
{AML_MIXER_ID_SPDIF_OUT_CHANNEL_STATUS, "spdif out channel status"},
|
|
{AML_MIXER_ID_AUDIO_PCPD_MONITOR_ENABLE, "Pc_Pd_Monitor_A Detect enable"},
|
|
{AML_MIXER_ID_AUDIO_PCPD_MONITOR_DATA_TYPE, "Pc_Pd_Monitor_A Audio Type"},
|
|
{AML_MIXER_ID_DAC_DIGITAL_VOLUME, "DAC Digital Playback Volume"},
|
|
{AML_MIXER_ID_AMP_MASTER_VOLUME, "AMP Master Volume"},
|
|
{AML_MIXER_ID_AED_FULL_DRC_ENABLE, "AED Full-band DRC enable"},
|
|
{AML_MIXER_ID_DAC_DIGITAL_VOLUME, "AMP DAC Digital Playback Volume"},
|
|
{AML_MIXER_ID_HDMI_IN1_AUDIO_STABLE, "HDMIIN_1 audio stable"},
|
|
{AML_MIXER_ID_HDMI_IN1_SAMPLERATE, "HDMIIN_1 audio samplerate"},
|
|
{AML_MIXER_ID_HDMI_IN1_CHANNELS, "HDMIIN_1 audio channels"},
|
|
{AML_MIXER_ID_HDMIIN1_ALLOCATION, "HDMIIN_1 audio allocation"},
|
|
{AML_MIXER_ID_HDMI_IN1_FORMATS, "HDMIIN_1 audio format"},
|
|
{AML_MIXER_ID_HDMIIN1_AUDIO_PACKET, "HDMIIN_1 Audio Packet"},
|
|
{AML_MIXER_ID_HDMI_IN1_NONAUDIO, "HDMIIN_1 NONAUDIO"},
|
|
{AML_MIXER_ID_HW_RESAMPLE_C_SOURCE, "Hw resample c module"},
|
|
{AML_MIXER_ID_HW_RESAMPLE_C_ENABLE, "Hardware resample c enable"},
|
|
{AML_MIXER_ID_AUDIO_PCPD_MONITOR_B_DATA_TYPE, "Pc_Pd_Monitor_B Audio Type"},
|
|
{AML_MIXER_ID_AUDIO_PCPD_MONITOR_B_ENABLE, "Pc_Pd_Monitor_B Detect enable"},
|
|
{AML_MIXER_ID_HW_MIXER_VOLUME, "mixer vol"},
|
|
{AML_MIXER_ID_HW_MIXER_LANE_SOURCE, "MIXER LANE SOURCE SELECT"},
|
|
{AML_MIXER_ID_HW_MIXER_XRUN, "Mixer Xrun"},
|
|
{AML_MIXER_ID_AD82128_C30_MASTER_VOLUME,"ad82128_c_30 Master Volume"},
|
|
{AML_MIXER_ID_AD82128_C31_MASTER_VOLUME,"ad82128_c_31 Master Volume"},
|
|
{AML_MIXER_ID_AI_SOUND_MODE, "AI Sort Result"},
|
|
};
|
|
|
|
static char *get_mixer_name_by_id(int mixer_id)
|
|
{
|
|
int i;
|
|
int cnt_mixer = sizeof(gAmlMixerList) / sizeof(struct aml_mixer_list);
|
|
|
|
for (i = 0; i < cnt_mixer; i++) {
|
|
if (gAmlMixerList[i].id == mixer_id) {
|
|
return gAmlMixerList[i].mixer_name;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int open_mixer_handle(struct aml_mixer_handle *mixer_handle)
|
|
{
|
|
int card = 0;
|
|
struct mixer *pmixer = NULL;
|
|
|
|
card = alsa_device_get_card_index();
|
|
if (card < 0) {
|
|
AM_LOGE("Failed to get sound card");
|
|
return -1;
|
|
}
|
|
|
|
pmixer = mixer_open(card);
|
|
if (NULL == pmixer) {
|
|
AM_LOGE("Failed to open mixer");
|
|
return -1;
|
|
}
|
|
mixer_handle->pMixer = pmixer;
|
|
pthread_mutex_init(&mixer_handle->lock, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int close_mixer_handle(struct aml_mixer_handle *mixer_handle)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
|
|
if (NULL != pMixer) {
|
|
mixer_close(pMixer);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct mixer_ctl *get_mixer_ctl_handle(struct mixer *pmixer, int mixer_id)
|
|
{
|
|
struct mixer_ctl *pCtrl = NULL;
|
|
|
|
if (get_mixer_name_by_id(mixer_id) != NULL) {
|
|
pCtrl = mixer_get_ctl_by_name(pmixer,
|
|
get_mixer_name_by_id(mixer_id));
|
|
}
|
|
|
|
return pCtrl;
|
|
}
|
|
|
|
int aml_mixer_ctrl_get_array(struct aml_mixer_handle *mixer_handle, int mixer_id, void *array, int count)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
mixer_ctl_get_array(pCtrl, array, count);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int aml_mixer_ctrl_get_int(struct aml_mixer_handle *mixer_handle, int mixer_id)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl;
|
|
int value = -1;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
|
|
value = mixer_ctl_get_value(pCtrl, 0);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
return value;
|
|
}
|
|
|
|
int aml_mixer_ctrl_get_enum_str_to_int(struct aml_mixer_handle *mixer_handle, int mixer_id, int *ret)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl;
|
|
const char *string = NULL;
|
|
int value = -1;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
value = mixer_ctl_get_value(pCtrl, 0);
|
|
string = mixer_ctl_get_enum_string(pCtrl, value);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
if (string) {
|
|
*ret = atoi(string);
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int aml_mixer_ctrl_set_array(struct aml_mixer_handle *mixer_handle, int mixer_id, void *array, int count)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl = NULL;
|
|
int i = 0;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
AM_LOGI("audiohal set kctrl: %s, array length: %d", get_mixer_name_by_id(mixer_id), count);
|
|
for (i = 0; i < count; i ++) {
|
|
AM_LOGI("array[%d]: %#x", i, ((char *)array)[i]);
|
|
}
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
mixer_ctl_set_array(pCtrl, array, count);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int aml_mixer_ctrl_set_int(struct aml_mixer_handle *mixer_handle, int mixer_id, int value)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl = NULL;
|
|
int ret = -1;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
AM_LOGI("audiohal set kctrl: %s, value: %d", get_mixer_name_by_id(mixer_id), value);
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
ret = mixer_ctl_set_value(pCtrl, 0, value);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int aml_mixer_ctrl_set_str(struct aml_mixer_handle *mixer_handle, int mixer_id, char *value)
|
|
{
|
|
struct mixer *pMixer = mixer_handle->pMixer;
|
|
struct mixer_ctl *pCtrl = NULL;
|
|
|
|
if (pMixer == NULL) {
|
|
AM_LOGE("pMixer is invalid!");
|
|
return -1;
|
|
}
|
|
AM_LOGI("audiohal set kctrl: %s, value: %s", get_mixer_name_by_id(mixer_id), value);
|
|
|
|
pthread_mutex_lock(&mixer_handle->lock);
|
|
pCtrl = get_mixer_ctl_handle(pMixer, mixer_id);
|
|
if (pCtrl == NULL) {
|
|
AM_LOGE("Failed to open mixer %s", get_mixer_name_by_id(mixer_id));
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
return -1;
|
|
}
|
|
mixer_ctl_set_enum_by_string(pCtrl, value);
|
|
pthread_mutex_unlock(&mixer_handle->lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void print_enum(struct mixer_ctl *ctl, int fd)
|
|
{
|
|
unsigned int num_enums;
|
|
unsigned int i;
|
|
unsigned int value;
|
|
const char *string;
|
|
|
|
num_enums = mixer_ctl_get_num_enums(ctl);
|
|
value = mixer_ctl_get_value(ctl, 0);
|
|
|
|
for (i = 0; i < num_enums; i++) {
|
|
string = mixer_ctl_get_enum_string(ctl, i);
|
|
dprintf(fd, "%s%s, ", value == i ? "> " : "", string);
|
|
}
|
|
}
|
|
|
|
static void print_control_values(struct mixer_ctl *control, int fd)
|
|
{
|
|
enum mixer_ctl_type type;
|
|
unsigned int num_values;
|
|
unsigned int i;
|
|
int min, max;
|
|
int ret;
|
|
char *buf = NULL;
|
|
unsigned int tlv_header_size = 0;
|
|
|
|
type = mixer_ctl_get_type(control);
|
|
num_values = mixer_ctl_get_num_values(control);
|
|
if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
|
|
if (mixer_ctl_is_access_tlv_rw(control) != 0) {
|
|
tlv_header_size = TLV_HEADER_SIZE;
|
|
}
|
|
buf = aml_audio_calloc(1, num_values + tlv_header_size);
|
|
if (buf == NULL) {
|
|
AM_LOGE("Failed to alloc mem for bytes %u", num_values);
|
|
return;
|
|
}
|
|
ret = mixer_ctl_get_array(control, buf, num_values + tlv_header_size);
|
|
if (ret < 0) {
|
|
AM_LOGE("Failed to mixer_ctl_get_array");
|
|
aml_audio_free(buf);
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < num_values; i++) {
|
|
switch (type)
|
|
{
|
|
case MIXER_CTL_TYPE_INT:
|
|
dprintf(fd,"%d", mixer_ctl_get_value(control, i));
|
|
break;
|
|
case MIXER_CTL_TYPE_BOOL:
|
|
dprintf(fd,"%s", mixer_ctl_get_value(control, i) ? "On" : "Off");
|
|
break;
|
|
case MIXER_CTL_TYPE_ENUM:
|
|
print_enum(control, fd);
|
|
break;
|
|
case MIXER_CTL_TYPE_BYTE:
|
|
dprintf(fd,"%02hhx", buf[i]);
|
|
break;
|
|
default:
|
|
dprintf(fd,"unknown");
|
|
break;
|
|
};
|
|
if ((i + 1) < num_values) {
|
|
dprintf(fd, ", ");
|
|
}
|
|
}
|
|
|
|
if (type == MIXER_CTL_TYPE_INT) {
|
|
min = mixer_ctl_get_range_min(control);
|
|
max = mixer_ctl_get_range_max(control);
|
|
dprintf(fd, " (range %d->%d)", min, max);
|
|
}
|
|
|
|
aml_audio_free(buf);
|
|
}
|
|
|
|
int set_spdifin_pao(struct aml_mixer_handle *mixer_handle,int enable)
|
|
{
|
|
return aml_mixer_ctrl_set_int(mixer_handle, AML_MIXER_ID_SPDIFIN_PAO, enable);
|
|
}
|
|
|
|
int get_spdifin_samplerate(struct aml_mixer_handle *mixer_handle)
|
|
{
|
|
int index = aml_mixer_ctrl_get_int(mixer_handle, AML_MIXER_ID_SPDIF_IN_SAMPLERATE);
|
|
|
|
return index;
|
|
}
|
|
|
|
int get_hdmiin_sample_rate_index(struct aml_mixer_handle *mixer_handle, int is_hdmi1)
|
|
{
|
|
int stable = 0;
|
|
int mixer_id = AML_MIXER_ID_HDMI_IN_AUDIO_STABLE;
|
|
if (is_hdmi1) {
|
|
mixer_id = AML_MIXER_ID_HDMI_IN1_AUDIO_STABLE;
|
|
}
|
|
stable = aml_mixer_ctrl_get_int(mixer_handle, mixer_id);
|
|
if (!stable) {
|
|
return -1;
|
|
}
|
|
|
|
if (is_hdmi1) {
|
|
mixer_id = AML_MIXER_ID_HDMI_IN1_SAMPLERATE;
|
|
} else {
|
|
mixer_id = AML_MIXER_ID_HDMI_IN_SAMPLERATE;
|
|
}
|
|
return aml_mixer_ctrl_get_int(mixer_handle, mixer_id);
|
|
}
|
|
|
|
int get_hdmiin_samplerate(int resample_index)
|
|
{
|
|
int sample_rate;
|
|
|
|
switch (resample_index) {
|
|
case HW_RESAMPLE_32K:
|
|
sample_rate = 32000;
|
|
break;
|
|
case HW_RESAMPLE_44K:
|
|
sample_rate = 44100;
|
|
break;
|
|
case HW_RESAMPLE_48K:
|
|
sample_rate = 48000;
|
|
break;
|
|
case HW_RESAMPLE_88K:
|
|
sample_rate = 88200;
|
|
break;
|
|
case HW_RESAMPLE_96K:
|
|
sample_rate = 96000;
|
|
break;
|
|
case HW_RESAMPLE_176K:
|
|
sample_rate = 176400;
|
|
break;
|
|
case HW_RESAMPLE_192K:
|
|
sample_rate = 192000;
|
|
break;
|
|
default:
|
|
sample_rate = 0;
|
|
break;
|
|
}
|
|
|
|
return sample_rate;
|
|
}
|
|
|
|
int get_hdmiin_channel(struct aml_mixer_handle *mixer_handle, int is_hdmi1)
|
|
{
|
|
int channel_index = 0;
|
|
int mixer_id = AML_MIXER_ID_HDMI_IN_CHANNELS;
|
|
/*hmdirx audio support: N/A, 2, 3, 4, 5, 6, 7, 8*/
|
|
if (is_hdmi1) {
|
|
mixer_id = AML_MIXER_ID_HDMI_IN1_CHANNELS;
|
|
} else {
|
|
mixer_id = AML_MIXER_ID_HDMI_IN_CHANNELS;
|
|
}
|
|
channel_index = aml_mixer_ctrl_get_int(mixer_handle, mixer_id);
|
|
if (channel_index == 0) {
|
|
return 0;
|
|
}
|
|
else if (1 == channel_index) {
|
|
return 2;
|
|
}
|
|
else {
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
hdmiin_audio_packet_t get_hdmiin_audio_packet(struct aml_mixer_handle *mixer_handle, int is_hdmi1)
|
|
{
|
|
int audio_packet = 0;
|
|
if (is_hdmi1) {
|
|
audio_packet = aml_mixer_ctrl_get_int(mixer_handle,AML_MIXER_ID_HDMIIN1_AUDIO_PACKET);
|
|
} else {
|
|
audio_packet = aml_mixer_ctrl_get_int(mixer_handle,AML_MIXER_ID_HDMIIN_AUDIO_PACKET);
|
|
}
|
|
if (audio_packet < 0) {
|
|
return AUDIO_PACKET_NONE;
|
|
}
|
|
return (hdmiin_audio_packet_t)audio_packet;
|
|
}
|
|
|
|
int set_hdmiin_audio_mode(struct aml_mixer_handle *mixer_handle, char *mode)
|
|
{
|
|
if (mode == NULL || strlen(mode) > 5)
|
|
return -EINVAL;
|
|
|
|
return aml_mixer_ctrl_set_str(mixer_handle,
|
|
AML_MIXER_ID_HDMIIN_AUDIO_MODE, mode);
|
|
}
|
|
|
|
enum hdmiin_audio_mode get_hdmiin_audio_mode(struct aml_mixer_handle *mixer_handle)
|
|
{
|
|
return (enum hdmiin_audio_mode)aml_mixer_ctrl_get_int(mixer_handle, AML_MIXER_ID_HDMIIN_AUDIO_MODE);
|
|
}
|
|
|
|
static inline eMixerHwResample _sr_enum(int sr)
|
|
{
|
|
switch (sr) {
|
|
case 32000:
|
|
return HW_RESAMPLE_32K;
|
|
case 44100:
|
|
return HW_RESAMPLE_44K;
|
|
case 48000:
|
|
return HW_RESAMPLE_48K;
|
|
case 88200:
|
|
return HW_RESAMPLE_88K;
|
|
case 96000:
|
|
return HW_RESAMPLE_96K;
|
|
case 176400:
|
|
return HW_RESAMPLE_176K;
|
|
case 192000:
|
|
return HW_RESAMPLE_192K;
|
|
default:
|
|
return HW_RESAMPLE_DISABLE;
|
|
}
|
|
}
|
|
|
|
eMixerHwResample get_eArcIn_samplerate(struct aml_mixer_handle *mixer_handle)
|
|
{
|
|
int sr = aml_mixer_ctrl_get_int(mixer_handle, AML_MIXER_ID_EARCRX_AUDIO_SAMPLERATE);
|
|
|
|
/* eARC mix control does not return sample rate as enum type as HDMIIN and SPDIF */
|
|
return _sr_enum(sr);
|
|
}
|
|
|
|
void aml_alsa_mixer_status_dump(struct aml_mixer_handle *mixer_handle, int fd)
|
|
{
|
|
dprintf(fd, "\n-------------[AML_HAL] ALSA mxier ctrl ------------------------\n");
|
|
|
|
struct mixer_ctl *ctl;
|
|
const char *name, *type;
|
|
unsigned int num_ctls, num_values;
|
|
unsigned int i;
|
|
//struct aml_mixer_handle *aml_mixer = &adev->alsa_mixer;
|
|
struct aml_mixer_handle *aml_mixer = mixer_handle;
|
|
|
|
if (!aml_mixer->pMixer) {
|
|
ALOGW("%s() Warning! mixer = NULL!, return!", __func__);
|
|
return;
|
|
}
|
|
|
|
num_ctls = mixer_get_num_ctls(aml_mixer->pMixer);
|
|
|
|
dprintf(fd,"Number of controls: %u\n", num_ctls);
|
|
|
|
dprintf(fd,"ctl\ttype\tnum\t%-40svalue\n", "name");
|
|
|
|
for (i = 0; i < num_ctls; i++) {
|
|
ctl = mixer_get_ctl(aml_mixer->pMixer, i); //ask one mixer_ctrl
|
|
|
|
name = mixer_ctl_get_name(ctl);
|
|
type = mixer_ctl_get_type_string(ctl);
|
|
num_values = mixer_ctl_get_num_values(ctl);
|
|
dprintf(fd, "%u\t%s\t%u\t%-40s", i, type, num_values, name);
|
|
|
|
pthread_mutex_lock(&aml_mixer->lock);
|
|
print_control_values(ctl, fd);
|
|
pthread_mutex_unlock(&aml_mixer->lock);
|
|
dprintf(fd, "\n");
|
|
}
|
|
}
|