1468 lines
37 KiB
C
1468 lines
37 KiB
C
|
// SPDX-License-Identifier: GPL-2.0-only
|
||
|
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||
|
*/
|
||
|
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/err.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/moduleparam.h>
|
||
|
#include <linux/time.h>
|
||
|
#include <linux/wait.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/delay.h>
|
||
|
#include <sound/core.h>
|
||
|
#include <sound/soc.h>
|
||
|
#include <sound/soc-dapm.h>
|
||
|
#include <sound/pcm.h>
|
||
|
#include <ipc/apr_tal.h>
|
||
|
#include <dsp/apr_audio-v2.h>
|
||
|
#include <dsp/q6audio-v2.h>
|
||
|
#include <dsp/audio_cal_utils.h>
|
||
|
#include <dsp/q6voice.h>
|
||
|
#include <dsp/q6asm-v2.h>
|
||
|
#include <dsp/q6common.h>
|
||
|
#include <asoc/sec_audio_adaptation.h>
|
||
|
#include "msm-pcm-routing-v2.h"
|
||
|
|
||
|
struct afe_ctl {
|
||
|
void *apr;
|
||
|
atomic_t state;
|
||
|
atomic_t status;
|
||
|
wait_queue_head_t wait;
|
||
|
};
|
||
|
|
||
|
struct afe_port {
|
||
|
unsigned int device_tx_port;
|
||
|
unsigned int spk_rx_port;
|
||
|
unsigned int usb_rx_port;
|
||
|
unsigned int bt_rx_port;
|
||
|
unsigned int headset_rx_port;
|
||
|
unsigned int volume_monitor_port;
|
||
|
};
|
||
|
|
||
|
static struct afe_ctl this_afe;
|
||
|
static struct audio_session *session;
|
||
|
static struct afe_port afe_port;
|
||
|
static struct mutex asm_lock;
|
||
|
static uint32_t upscaler_val;
|
||
|
|
||
|
int q6asm_set_sound_alive(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_sa cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_SA;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_SA_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* SA paramerters */
|
||
|
cmd.OutDevice = param[0];
|
||
|
cmd.Preset = param[1];
|
||
|
for (i = 0; i < 9; i++)
|
||
|
cmd.EqLev[i] = param[i+2];
|
||
|
cmd.m3Dlevel = param[11];
|
||
|
cmd.BElevel = param[12];
|
||
|
cmd.CHlevel = param[13];
|
||
|
cmd.CHRoomSize = param[14];
|
||
|
cmd.Clalevel = param[15];
|
||
|
cmd.volume = param[16];
|
||
|
cmd.Sqrow = param[17];
|
||
|
cmd.Sqcol = param[18];
|
||
|
cmd.TabInfo = param[19];
|
||
|
cmd.NewUI = param[20];
|
||
|
cmd.m3DPositionOn = param[21];
|
||
|
cmd.m3DPositionAngle[0] = param[22];
|
||
|
cmd.m3DPositionAngle[1] = param[23];
|
||
|
cmd.m3DPositionGain[0] = param[24];
|
||
|
cmd.m3DPositionGain[1] = param[25];
|
||
|
cmd.AHDRonoff = param[26];
|
||
|
pr_info("%s: %d %d %d%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
|
||
|
__func__,
|
||
|
cmd.OutDevice, cmd.Preset, cmd.EqLev[0],
|
||
|
cmd.EqLev[1], cmd.EqLev[2], cmd.EqLev[3],
|
||
|
cmd.EqLev[4], cmd.EqLev[5], cmd.EqLev[6],
|
||
|
cmd.EqLev[7], cmd.EqLev[8],
|
||
|
cmd.m3Dlevel, cmd.BElevel, cmd.CHlevel,
|
||
|
cmd.CHRoomSize, cmd.Clalevel, cmd.volume,
|
||
|
cmd.Sqrow, cmd.Sqcol, cmd.TabInfo,
|
||
|
cmd.NewUI, cmd.m3DPositionOn,
|
||
|
cmd.m3DPositionAngle[0], cmd.m3DPositionAngle[1],
|
||
|
cmd.m3DPositionGain[0], cmd.m3DPositionGain[1],
|
||
|
cmd.AHDRonoff);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_sa_listenback(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_sa cmd = {0, };
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_SA;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_SA_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* SA paramerters */
|
||
|
cmd.OutDevice = 1; /* EAR */
|
||
|
cmd.Preset = param[0];
|
||
|
cmd.BElevel = param[1];
|
||
|
cmd.Clalevel = param[2];
|
||
|
cmd.TabInfo = 1;
|
||
|
cmd.NewUI = 1;
|
||
|
pr_info("%s: %d %d %d\n", __func__, cmd.Preset, cmd.BElevel, cmd.Clalevel);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_play_speed(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_vsp cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_SA_VSP;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_SA_VSP_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* play speed paramerters */
|
||
|
cmd.speed_int = (uint16_t)param[0];
|
||
|
pr_info("%s: %d\n", __func__, cmd.speed_int);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_adaptation_sound(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_adaptation_sound cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_ADAPTATION_SOUND;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_ADAPTATION_SOUND_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* adapt sound paramerters */
|
||
|
cmd.enable = param[0];
|
||
|
for (i = 0; i < 12; i++)
|
||
|
cmd.gain[i/6][i%6] = param[i+1];
|
||
|
cmd.device = param[13];
|
||
|
pr_info("%s: %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
|
||
|
__func__,
|
||
|
cmd.enable, cmd.gain[0][0], cmd.gain[0][1], cmd.gain[0][2],
|
||
|
cmd.gain[0][3], cmd.gain[0][4], cmd.gain[0][5], cmd.gain[1][0],
|
||
|
cmd.gain[1][1], cmd.gain[1][2], cmd.gain[1][3], cmd.gain[1][4],
|
||
|
cmd.gain[1][5], cmd.device);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_sound_balance(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_lrsm cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_LRSM;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_LRSM_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* sound balance paramerters */
|
||
|
cmd.sm = param[0];
|
||
|
cmd.lr = param[1];
|
||
|
pr_info("%s: %d %d\n", __func__, cmd.sm, cmd.lr);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_myspace(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_msp cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_SA_MSP;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = MODULE_ID_PP_SA_MSP_PARAM;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* myspace paramerters */
|
||
|
cmd.msp_int = (uint16_t)param[0];
|
||
|
pr_info("%s: %d\n", __func__, cmd.msp_int);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_upscaler(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_upscaler cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_SA_UPSCALER_COLOR;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_SA_UPSCALER_COLOR_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* upscaler paramerters */
|
||
|
cmd.upscaler_enable = (uint16_t)param[0];
|
||
|
pr_info("%s: %d\n", __func__, cmd.upscaler_enable);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
|
||
|
upscaler_val = cmd.upscaler_enable;
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int q6asm_set_dolby_atmos(struct audio_client *ac, long *param)
|
||
|
{
|
||
|
struct asm_stream_cmd_set_pp_params_dolby_atmos cmd;
|
||
|
struct param_hdr_v3 param_info;
|
||
|
int rc = 0;
|
||
|
|
||
|
if (ac == NULL) {
|
||
|
pr_err("%s: Audio client is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_info, 0, sizeof(param_info));
|
||
|
memset(&cmd, 0, sizeof(cmd));
|
||
|
param_info.module_id = MODULE_ID_PP_DOLBY_DAP;
|
||
|
param_info.instance_id = INSTANCE_ID_0;
|
||
|
param_info.param_id = PARAM_ID_PP_DOLBY_DAP_PARAMS;
|
||
|
param_info.param_size = sizeof(cmd);
|
||
|
|
||
|
/* rotation paramerters */
|
||
|
cmd.enable = (uint32_t)param[0];
|
||
|
cmd.device = (uint16_t)param[1];
|
||
|
cmd.dolby_profile = (uint16_t)param[2];
|
||
|
pr_info("%s: %d %d %d\n", __func__,
|
||
|
cmd.enable, cmd.device, cmd.dolby_profile);
|
||
|
|
||
|
rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
|
||
|
(u8 *) &cmd);
|
||
|
if (rc)
|
||
|
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
|
||
|
__func__, param_info.param_id, rc);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
int adm_set_sound_booster(int port_id, int copp_idx,
|
||
|
long *param)
|
||
|
{
|
||
|
struct adm_param_soundbooster_t sb_param;
|
||
|
struct param_hdr_v3 param_hdr;
|
||
|
int ret = 0;
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
pr_debug("%s: Enter\n", __func__);
|
||
|
|
||
|
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||
|
param_hdr.module_id = MODULE_ID_PP_SB;
|
||
|
param_hdr.instance_id = INSTANCE_ID_0;
|
||
|
param_hdr.param_id = PARAM_ID_PP_SB_PARAM;
|
||
|
param_hdr.param_size = sizeof(sb_param);
|
||
|
/* soundbooster paramerters */
|
||
|
sb_param.sb_enable = (uint32_t)param[0];
|
||
|
|
||
|
pr_info("%s: Enter, port_id(0x%x), copp_idx(%d), enable(%d)\n",
|
||
|
__func__, port_id, copp_idx, sb_param.sb_enable);
|
||
|
|
||
|
ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||
|
(uint8_t *) &sb_param);
|
||
|
if (ret)
|
||
|
pr_err("%s: Failed to set sound booster params, err %d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int adm_set_sb_rotation(int port_id, int copp_idx,
|
||
|
uint32_t rotation)
|
||
|
{
|
||
|
struct adm_param_sb_rotation cmd;
|
||
|
struct param_hdr_v3 param_hdr;
|
||
|
int ret = 0;
|
||
|
|
||
|
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||
|
param_hdr.module_id = MODULE_ID_PP_SB;
|
||
|
param_hdr.instance_id = INSTANCE_ID_0;
|
||
|
param_hdr.param_id = PARAM_ID_PP_SB_ROTATION_PARAM;
|
||
|
param_hdr.param_size = sizeof(cmd);
|
||
|
/* rotation paramerters */
|
||
|
cmd.sb_rotation = rotation;
|
||
|
|
||
|
pr_info("%s: Enter, port_id(0x%x), copp_idx(%d), enable(%d)\n",
|
||
|
__func__, port_id, copp_idx, cmd.sb_rotation);
|
||
|
|
||
|
ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||
|
(uint8_t *) &cmd);
|
||
|
if (ret)
|
||
|
pr_err("%s: Failed to set sb rotation params, err %d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int adm_set_sb_flatmotion(int port_id, int copp_idx,
|
||
|
long *param)
|
||
|
{
|
||
|
struct adm_param_sb_flatmotion cmd;
|
||
|
struct param_hdr_v3 param_hdr;
|
||
|
int ret = 0;
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||
|
param_hdr.module_id = MODULE_ID_PP_SB;
|
||
|
param_hdr.instance_id = INSTANCE_ID_0;
|
||
|
param_hdr.param_id = PARAM_ID_PP_SB_FLATMOTION_PARAM;
|
||
|
param_hdr.param_size = sizeof(cmd);
|
||
|
/* flatmotion paramerters */
|
||
|
cmd.sb_flatmotion = (unsigned int)param[0];
|
||
|
|
||
|
pr_info("%s: Enter, port_id(0x%x), copp_idx(%d), enable(%d)\n",
|
||
|
__func__, port_id, copp_idx, cmd.sb_flatmotion);
|
||
|
|
||
|
ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||
|
(uint8_t *) &cmd);
|
||
|
if (ret)
|
||
|
pr_err("%s: Failed to set sb flatmotion params, err %d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int adm_set_sb_volume(int port_id, int copp_idx,
|
||
|
long *param)
|
||
|
{
|
||
|
struct adm_param_sb_volume cmd;
|
||
|
struct param_hdr_v3 param_hdr;
|
||
|
int ret = 0;
|
||
|
|
||
|
if (param == NULL) {
|
||
|
pr_err("%s: param is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
pr_debug("%s: Enter\n", __func__);
|
||
|
|
||
|
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||
|
param_hdr.module_id = MODULE_ID_PP_SB;
|
||
|
param_hdr.instance_id = INSTANCE_ID_0;
|
||
|
param_hdr.param_id = PARAM_ID_PP_SB_PARAMS_VOLUME;
|
||
|
param_hdr.param_size = sizeof(cmd);
|
||
|
/* soundbooster paramerters */
|
||
|
cmd.sb_volume = (uint32_t)param[0];
|
||
|
|
||
|
pr_info("%s: Enter, port_id(0x%x), copp_idx(%d), volume(%d)\n",
|
||
|
__func__, port_id, copp_idx, cmd.sb_volume);
|
||
|
|
||
|
ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||
|
(uint8_t *) &cmd);
|
||
|
if (ret)
|
||
|
pr_err("%s: Failed to set sound booster volume, err %d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_alive_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_rx_vol_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_rx_vol_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_fm_rx_vol_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_rx_data_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_play_speed_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_adaptation_sound_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_balance_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_voice_tracking_info_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
int be_idx = 0;
|
||
|
char *param_value;
|
||
|
int *update_param_value;
|
||
|
uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t);
|
||
|
struct msm_pcm_routing_bdai_data msm_bedai;
|
||
|
struct param_hdr_v3 param_hdr;
|
||
|
|
||
|
param_value = kzalloc(param_size, GFP_KERNEL);
|
||
|
if (!param_value)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
|
||
|
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
|
||
|
if (msm_bedai.port_id == afe_port.device_tx_port)
|
||
|
break;
|
||
|
}
|
||
|
if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedai.active) {
|
||
|
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||
|
param_hdr.module_id = MODULE_ID_PP_SS_REC;
|
||
|
param_hdr.instance_id = 0x8000;
|
||
|
param_hdr.param_id = PARAM_ID_PP_SS_REC_GETPARAMS;
|
||
|
param_hdr.param_size = param_size;
|
||
|
rc = adm_get_pp_params(afe_port.device_tx_port, 0,
|
||
|
ADM_CLIENT_ID_DEFAULT, NULL, ¶m_hdr, param_value);
|
||
|
if (rc) {
|
||
|
pr_err("%s: get parameters failed:%d\n", __func__, rc);
|
||
|
kfree(param_value);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (param_value == NULL) {
|
||
|
pr_err("%s: param_value is NULL\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
update_param_value = (int *)param_value;
|
||
|
ucontrol->value.integer.value[0] = update_param_value[0];
|
||
|
|
||
|
pr_debug("%s: FROM DSP value[0] 0x%x\n",
|
||
|
__func__, update_param_value[0]);
|
||
|
}
|
||
|
kfree(param_value);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_myspace_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_boost_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_upscaler_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
ucontrol->value.integer.value[0] = upscaler_val;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_rotation_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_flatmotion_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_dolby_atmos_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t volume_monitor_value[VOLUME_MONITOR_GET_PAYLOAD_SIZE] = {0};
|
||
|
|
||
|
static int sec_audio_volume_monitor_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int be_idx = 0;
|
||
|
int i;
|
||
|
|
||
|
struct msm_pcm_routing_bdai_data msm_bedai;
|
||
|
|
||
|
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
|
||
|
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
|
||
|
|
||
|
if (msm_bedai.active) {
|
||
|
if (msm_bedai.port_id == afe_port.headset_rx_port)
|
||
|
break;
|
||
|
if (msm_bedai.port_id == afe_port.bt_rx_port)
|
||
|
break;
|
||
|
if (msm_bedai.port_id == afe_port.usb_rx_port)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (be_idx == MSM_BACKEND_DAI_MAX) {
|
||
|
pr_info("%s: no active backend port\n", __func__);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
afe_port.volume_monitor_port = msm_bedai.port_id;
|
||
|
|
||
|
ret = afe_get_volume_monitor(afe_port.volume_monitor_port, volume_monitor_value);
|
||
|
|
||
|
if (ret) {
|
||
|
pr_err("%s: fail afe_get_volume_monitor error = %d\n", __func__, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < VOLUME_MONITOR_GET_PAYLOAD_SIZE; i++)
|
||
|
ucontrol->value.integer.value[i] = volume_monitor_value[i];
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_volume_monitor_data_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_enable_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_alive_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_sound_alive(ac,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: sound alive cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_rx_vol_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
uint32_t gain_list[8];
|
||
|
int ret = 0;
|
||
|
struct audio_client *ac;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
|
||
|
gain_list[0] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
gain_list[1] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
gain_list[2] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA6,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED)) {
|
||
|
pr_info("%s: audio session is not active : %d\n",
|
||
|
__func__, fe_dai_map.strm_id);
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
pr_info("%s: stream id %d, vol = %d\n",
|
||
|
__func__, fe_dai_map.strm_id, gain_list[0]);
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_multich_gain(ac, 3/*num_channels*/, gain_list, NULL, true);
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: listenback rx vol cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_rx_vol_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id, copp_idx;
|
||
|
|
||
|
port_id = afe_port.spk_rx_port;
|
||
|
ret = q6audio_get_copp_idx_from_port_id(port_id, SB_VOLUME, &copp_idx);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Could not get copp idx for port_id=%d\n",
|
||
|
__func__, port_id);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
ret = adm_set_sb_volume(port_id, copp_idx,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting sound booster volume, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_fm_rx_vol_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
uint32_t gain_list[8];
|
||
|
int ret = 0;
|
||
|
struct audio_client *ac;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
|
||
|
gain_list[0] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
gain_list[1] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
gain_list[2] = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA6,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED)) {
|
||
|
pr_info("%s: audio session is not active : %d\n",
|
||
|
__func__, fe_dai_map.strm_id);
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
pr_info("%s: stream id %d, vol = %d\n",
|
||
|
__func__, fe_dai_map.strm_id, gain_list[0]);
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_multich_gain(ac, 3/*num_channels*/, gain_list, NULL, true);
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: fm rx vol cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_rx_data_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA6,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
pr_info("%s: stream id %d\n", __func__, fe_dai_map.strm_id);
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_sa_listenback(ac, (long *)ucontrol->value.integer.value);
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: listenback rx data cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_play_speed_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_play_speed(ac,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: play speed cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_adaptation_sound_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_adaptation_sound(ac,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: adaptation sound cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_balance_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_sound_balance(ac,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: sound balance cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_voice_tracking_info_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_myspace_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_myspace(ac, (long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: sound myspace cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sound_boost_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id, copp_idx;
|
||
|
enum sb_type func_type = (uint16_t)ucontrol->value.integer.value[0];
|
||
|
|
||
|
port_id = afe_port.spk_rx_port;
|
||
|
ret = q6audio_get_copp_idx_from_port_id(port_id, func_type, &copp_idx);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Could not get copp idx for port_id=%d\n",
|
||
|
__func__, port_id);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
ret = adm_set_sound_booster(port_id, copp_idx,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting Sound Focus Params, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_upscaler_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_upscaler(ac, (long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: upscaler cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Stream Information
|
||
|
* 0 : Deep/Offload
|
||
|
* 1 : Low Latency
|
||
|
*
|
||
|
* Rotation Information
|
||
|
* 0 : Top up
|
||
|
* 1 : Left up
|
||
|
* 2 : Bottom up
|
||
|
* 3 : Right up
|
||
|
*/
|
||
|
static int sec_audio_sb_rotation_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id, copp_idx;
|
||
|
uint32_t stream = 0;
|
||
|
uint32_t rotation = 0;
|
||
|
enum sb_type func_type = SB_MAX;
|
||
|
|
||
|
stream = (uint32_t)ucontrol->value.integer.value[0];
|
||
|
rotation = (uint32_t)ucontrol->value.integer.value[1];
|
||
|
|
||
|
switch (stream) {
|
||
|
case DEEP_OFFLOAD_MODE:
|
||
|
func_type = SB_ROTATION;
|
||
|
break;
|
||
|
case LOW_LATENCY_MODE:
|
||
|
func_type = SB_ROTATION_LL;
|
||
|
break;
|
||
|
case RINGTONE_MODE:
|
||
|
func_type = SB_ROTATION_RINGTONE;
|
||
|
break;
|
||
|
default:
|
||
|
pr_info("%s: unknown stream type\n", __func__);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
port_id = afe_port.spk_rx_port;
|
||
|
ret = q6audio_get_copp_idx_from_port_id(port_id, func_type, &copp_idx);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Could not get copp idx for port_id=%d\n",
|
||
|
__func__, port_id);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
ret = adm_set_sb_rotation(port_id, copp_idx, rotation);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting Sound boost rotation, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sb_flatmotion_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id, copp_idx;
|
||
|
|
||
|
port_id = afe_port.spk_rx_port;
|
||
|
ret = q6audio_get_copp_idx_from_port_id(port_id, SB_FLATMOTION, &copp_idx);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Could not get copp idx for port_id=%d\n",
|
||
|
__func__, port_id);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
ret = adm_set_sb_flatmotion(port_id, copp_idx,
|
||
|
(long *)ucontrol->value.integer.value);
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting Sound boost flatmotion, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_dolby_atmos_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct msm_pcm_routing_fdai_data fe_dai_map;
|
||
|
struct audio_client *ac;
|
||
|
|
||
|
mutex_lock(&asm_lock);
|
||
|
msm_pcm_routing_get_fedai_info(MSM_FRONTEND_DAI_MULTIMEDIA4,
|
||
|
SESSION_TYPE_RX, &fe_dai_map);
|
||
|
|
||
|
if ((fe_dai_map.strm_id <= 0) ||
|
||
|
(fe_dai_map.strm_id > ASM_ACTIVE_STREAMS_ALLOWED))
|
||
|
goto done;
|
||
|
|
||
|
ac = q6asm_get_audio_client(fe_dai_map.strm_id);
|
||
|
ret = q6asm_set_dolby_atmos(ac, (long *)ucontrol->value.integer.value);
|
||
|
|
||
|
if (ret < 0)
|
||
|
pr_err("%s: dolby atmos cmd failed ret=%d\n", __func__, ret);
|
||
|
|
||
|
done:
|
||
|
mutex_unlock(&asm_lock);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_volume_monitor_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_volume_monitor_data_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id;
|
||
|
int be_idx = 0;
|
||
|
int enable = ucontrol->value.integer.value[0];
|
||
|
int volume_level = ucontrol->value.integer.value[1];
|
||
|
int avc_support = ucontrol->value.integer.value[2];
|
||
|
int db_atten = ucontrol->value.integer.value[3];
|
||
|
|
||
|
struct msm_pcm_routing_bdai_data msm_bedai;
|
||
|
|
||
|
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
|
||
|
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
|
||
|
|
||
|
if (msm_bedai.active) {
|
||
|
if (msm_bedai.port_id == afe_port.headset_rx_port)
|
||
|
break;
|
||
|
if (msm_bedai.port_id == afe_port.bt_rx_port)
|
||
|
break;
|
||
|
if (msm_bedai.port_id == afe_port.usb_rx_port)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (be_idx == MSM_BACKEND_DAI_MAX) {
|
||
|
pr_info("%s: no active backend port\n", __func__);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
port_id = msm_bedai.port_id;
|
||
|
|
||
|
pr_info("%s: port_id : %x , enable : %d volume_level : %d avc_support : %d db_atten : %d\n",
|
||
|
__func__, port_id, enable, volume_level, avc_support, db_atten);
|
||
|
|
||
|
ret = afe_set_volume_monitor(port_id, enable, volume_level, avc_support, db_atten);
|
||
|
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting volume monitor, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_audio_sa_listenback_enable_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id;
|
||
|
int be_idx = 0;
|
||
|
int enable = ucontrol->value.integer.value[0];
|
||
|
|
||
|
struct msm_pcm_routing_bdai_data msm_bedai;
|
||
|
|
||
|
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
|
||
|
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
|
||
|
if (msm_bedai.active) {
|
||
|
if (msm_bedai.port_id == afe_port.usb_rx_port)
|
||
|
break;
|
||
|
if (msm_bedai.port_id == afe_port.headset_rx_port)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (be_idx == MSM_BACKEND_DAI_MAX) {
|
||
|
pr_info("%s: no active backend port\n", __func__);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
port_id = msm_bedai.port_id;
|
||
|
|
||
|
pr_info("%s: port_id : %x , enable : %d\n",
|
||
|
__func__, port_id, enable);
|
||
|
|
||
|
ret = afe_set_sa_listenback(port_id, enable);
|
||
|
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting set listenback, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_afe_remote_mic_vol(int index)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
int port_id;
|
||
|
int be_idx = 0;
|
||
|
struct msm_pcm_routing_bdai_data msm_bedai;
|
||
|
|
||
|
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
|
||
|
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
|
||
|
if (msm_bedai.active) {
|
||
|
if (msm_bedai.port_id == afe_port.device_tx_port)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (be_idx == MSM_BACKEND_DAI_MAX) {
|
||
|
pr_info("%s: no active backend port\n", __func__);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
port_id = msm_bedai.port_id;
|
||
|
|
||
|
pr_info("%s: port_id : %x , index : %d\n",
|
||
|
__func__, port_id, index);
|
||
|
|
||
|
ret = afe_set_remote_mic_vol(port_id, index);
|
||
|
|
||
|
if (ret) {
|
||
|
pr_err("%s: Error setting set listenback, err=%d\n",
|
||
|
__func__, ret);
|
||
|
|
||
|
ret = -EINVAL;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int sec_remote_mic_vol_get(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sec_remote_mic_vol_put(struct snd_kcontrol *kcontrol,
|
||
|
struct snd_ctl_elem_value *ucontrol)
|
||
|
{
|
||
|
int volumeindex = ucontrol->value.integer.value[0];
|
||
|
|
||
|
if ((volumeindex < 0) || (volumeindex > 15)) {
|
||
|
pr_err("%s: volumeindex=%d is wrong value\n", __func__, volumeindex);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
pr_debug("%s: volumeindex=%d\n", __func__, volumeindex);
|
||
|
|
||
|
return sec_afe_remote_mic_vol(volumeindex);
|
||
|
}
|
||
|
|
||
|
static const struct snd_kcontrol_new samsung_solution_mixer_controls[] = {
|
||
|
SOC_SINGLE_MULTI_EXT("SA data", SND_SOC_NOPM, 0, 65535, 0, 27,
|
||
|
sec_audio_sound_alive_get,
|
||
|
sec_audio_sound_alive_put),
|
||
|
SOC_SINGLE_EXT("SA LISTENBACK RX volume", SND_SOC_NOPM, 0, 65535, 0,
|
||
|
sec_audio_sa_listenback_rx_vol_get,
|
||
|
sec_audio_sa_listenback_rx_vol_put),
|
||
|
SOC_SINGLE_MULTI_EXT("SA LISTENBACK RX data", SND_SOC_NOPM, 0, 65535, 0, 27,
|
||
|
sec_audio_sa_listenback_rx_data_get,
|
||
|
sec_audio_sa_listenback_rx_data_put),
|
||
|
SOC_SINGLE_MULTI_EXT("VSP data", SND_SOC_NOPM, 0, 65535, 0, 1,
|
||
|
sec_audio_play_speed_get,
|
||
|
sec_audio_play_speed_put),
|
||
|
SOC_SINGLE_MULTI_EXT("Audio DHA data", SND_SOC_NOPM, 0, 65535, 0, 14,
|
||
|
sec_audio_adaptation_sound_get,
|
||
|
sec_audio_adaptation_sound_put),
|
||
|
SOC_SINGLE_MULTI_EXT("LRSM data", SND_SOC_NOPM, 0, 65535, 0, 2,
|
||
|
sec_audio_sound_balance_get,
|
||
|
sec_audio_sound_balance_put),
|
||
|
SOC_SINGLE_EXT("VoiceTrackInfo", SND_SOC_NOPM, 0, 2147483647, 0,
|
||
|
sec_audio_voice_tracking_info_get,
|
||
|
sec_audio_voice_tracking_info_put),
|
||
|
SOC_SINGLE_MULTI_EXT("MSP data", SND_SOC_NOPM, 0, 65535, 0, 1,
|
||
|
sec_audio_myspace_get, sec_audio_myspace_put),
|
||
|
SOC_SINGLE_MULTI_EXT("SB enable", SND_SOC_NOPM, 0, 65535, 0, 1,
|
||
|
sec_audio_sound_boost_get,
|
||
|
sec_audio_sound_boost_put),
|
||
|
SOC_SINGLE_MULTI_EXT("UPSCALER", SND_SOC_NOPM, 0, 65535, 0, 1,
|
||
|
sec_audio_upscaler_get, sec_audio_upscaler_put),
|
||
|
SOC_SINGLE_MULTI_EXT("SB rotation", SND_SOC_NOPM, 0, 65535, 0, 2,
|
||
|
sec_audio_sb_rotation_get, sec_audio_sb_rotation_put),
|
||
|
SOC_SINGLE_MULTI_EXT("SB flatmotion", SND_SOC_NOPM, 0, 65535, 0, 1,
|
||
|
sec_audio_sb_flatmotion_get, sec_audio_sb_flatmotion_put),
|
||
|
SOC_SINGLE_MULTI_EXT("DA data", SND_SOC_NOPM, 0, 65535, 0, 3,
|
||
|
sec_audio_dolby_atmos_get, sec_audio_dolby_atmos_put),
|
||
|
SOC_SINGLE_EXT("SB RX Volume", SND_SOC_NOPM, 0, 65535, 0,
|
||
|
sec_audio_sb_rx_vol_get,
|
||
|
sec_audio_sb_rx_vol_put),
|
||
|
SOC_SINGLE_EXT("SB FM RX Volume", SND_SOC_NOPM, 0, 65535, 0,
|
||
|
sec_audio_sb_fm_rx_vol_get,
|
||
|
sec_audio_sb_fm_rx_vol_put),
|
||
|
SOC_SINGLE_EXT("Remote Mic Vol Index", SND_SOC_NOPM, 0, 65535, 0,
|
||
|
sec_remote_mic_vol_get,
|
||
|
sec_remote_mic_vol_put),
|
||
|
SOC_SINGLE_MULTI_EXT("VM Energy", SND_SOC_NOPM, 0, 65535, 0, 61,
|
||
|
sec_audio_volume_monitor_get, sec_audio_volume_monitor_put),
|
||
|
SOC_SINGLE_MULTI_EXT("VM data", SND_SOC_NOPM, 0, 65535, 0, 4,
|
||
|
sec_audio_volume_monitor_data_get, sec_audio_volume_monitor_data_put),
|
||
|
SOC_SINGLE_EXT("Listenback Enable", SND_SOC_NOPM, 0, 65535, 0,
|
||
|
sec_audio_sa_listenback_enable_get,
|
||
|
sec_audio_sa_listenback_enable_put),
|
||
|
};
|
||
|
|
||
|
static int q6audio_adaptation_platform_probe(struct snd_soc_component *component)
|
||
|
{
|
||
|
pr_info("%s: platform\n", __func__);
|
||
|
|
||
|
session = q6asm_get_audio_session();
|
||
|
|
||
|
snd_soc_add_component_controls(component,
|
||
|
samsung_solution_mixer_controls,
|
||
|
ARRAY_SIZE(samsung_solution_mixer_controls));
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static const struct snd_soc_component_driver q6audio_adaptation = {
|
||
|
.probe = q6audio_adaptation_platform_probe,
|
||
|
};
|
||
|
|
||
|
static int samsung_q6audio_adaptation_probe(struct platform_device *pdev)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
|
||
|
|
||
|
atomic_set(&this_afe.state, 0);
|
||
|
atomic_set(&this_afe.status, 0);
|
||
|
this_afe.apr = NULL;
|
||
|
init_waitqueue_head(&this_afe.wait);
|
||
|
mutex_init(&asm_lock);
|
||
|
|
||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||
|
"adaptation,device-tx-port-id",
|
||
|
&afe_port.device_tx_port);
|
||
|
if (ret)
|
||
|
pr_err("%s : Unable to read Tx BE\n", __func__);
|
||
|
|
||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||
|
"adaptation,spk-rx-port-id",
|
||
|
&afe_port.spk_rx_port);
|
||
|
if (ret)
|
||
|
pr_debug("%s : Unable to find amp-rx-port\n", __func__);
|
||
|
|
||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||
|
"adaptation,usb-rx-port-id",
|
||
|
&afe_port.usb_rx_port);
|
||
|
if (ret)
|
||
|
pr_debug("%s : Unable to find usb-rx-port\n", __func__);
|
||
|
|
||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||
|
"adaptation,bt-rx-port-id",
|
||
|
&afe_port.bt_rx_port);
|
||
|
if (ret)
|
||
|
pr_debug("%s : Unable to find bt-rx-port\n", __func__);
|
||
|
|
||
|
ret = of_property_read_u32(pdev->dev.of_node,
|
||
|
"adaptation,headset-rx-port-id",
|
||
|
&afe_port.headset_rx_port);
|
||
|
if (ret)
|
||
|
pr_debug("%s : Unable to find headset-rx-port\n", __func__);
|
||
|
|
||
|
return snd_soc_register_component(&pdev->dev,
|
||
|
&q6audio_adaptation, NULL, 0);
|
||
|
}
|
||
|
|
||
|
static int samsung_q6audio_adaptation_remove(struct platform_device *pdev)
|
||
|
{
|
||
|
pr_debug("%s\n", __func__);
|
||
|
snd_soc_unregister_component(&pdev->dev);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static const struct of_device_id samsung_q6audio_adaptation_dt_match[] = {
|
||
|
{.compatible = "samsung,q6audio-adaptation"},
|
||
|
{}
|
||
|
};
|
||
|
MODULE_DEVICE_TABLE(of, samsung_q6audio_adaptation_dt_match);
|
||
|
|
||
|
static struct platform_driver samsung_q6audio_adaptation_driver = {
|
||
|
.driver = {
|
||
|
.name = "samsung-q6audio-adaptation",
|
||
|
.owner = THIS_MODULE,
|
||
|
.of_match_table = samsung_q6audio_adaptation_dt_match,
|
||
|
},
|
||
|
.probe = samsung_q6audio_adaptation_probe,
|
||
|
.remove = samsung_q6audio_adaptation_remove,
|
||
|
};
|
||
|
|
||
|
int __init sec_soc_audio_platform_init(void)
|
||
|
{
|
||
|
pr_debug("%s\n", __func__);
|
||
|
return platform_driver_register(&samsung_q6audio_adaptation_driver);
|
||
|
}
|
||
|
|
||
|
void sec_soc_audio_platform_exit(void)
|
||
|
{
|
||
|
pr_debug("%s\n", __func__);
|
||
|
platform_driver_unregister(&samsung_q6audio_adaptation_driver);
|
||
|
}
|
||
|
|
||
|
MODULE_DESCRIPTION("Samsung Audio Adaptation platform driver");
|
||
|
MODULE_LICENSE("GPL v2");
|