Files
android_kernel_motorola_sm6225/sound/soc/codecs/tas25xx-algo.c
T
Hujun Liao 8f491c1f46 Revert "(CR): ASoC: add APIs to access digital volume in tas25xx algo"
we use dcv_pcm as ramping function 
instead of digital volume gain.
when adev_open ,init all control , digital volume gain control will cost about 2s.
delete nouseful digital volume gain control to optimze the init time.

This reverts commit 7e3f682085432db213d8f35d649fef11b8951ff0.

Change-Id: I137fc78b8f934a6f008d30fbed92b2bb3572387d
Reviewed-on: https://gerrit.mot.com/1468340
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Wanlong Zhou <zhouwl@motorola.com>
Reviewed-by: Hujun Liao <liaohj@motorola.com>
Submit-Approved: Jira Key
2019-12-09 00:36:03 -06:00

825 lines
23 KiB
C

#ifdef CONFIG_TAS25XX_ALGO
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/device.h>
#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/fs.h>
#include <dsp/q6afe-v2.h>
#include <dsp/tas_smart_amp_v2.h>
#include "tas25xx-calib.h"
#define USE_VFS 1
#define CODEC_CONTROL 1
#define CONFIG_SET_RE_IN_KERNEL
#define POISON_VAL 0xDEADDEAD
#define MAX_STRING (300)
#define SMARTAMP_SPEAKER_CALIBDATA_FILE "/mnt/vendor/persist/factory/audio/tas25xx_calib.bin"
/*Master Control to Bypass the Smartamp TI CAPIv2 module*/
static int s_tas_smartamp_bypass = 0;
static int s_tas_smartamp_enable = 0;
static struct mutex routing_lock;
#ifdef CONFIG_SET_RE_IN_KERNEL
static int get_calibrated_re_tcalib (uint32_t *rdc_fix, uint32_t *tv_fix, int channel_count)
{
struct file *file = NULL;
char calib_data[MAX_STRING] = {0};
char filepath[128] = SMARTAMP_SPEAKER_CALIBDATA_FILE;
mm_segment_t fs;
int ret = 0;
static int s_rdc_fix[2] = {POISON_VAL, POISON_VAL};
static int s_tv_fix = POISON_VAL;
#if USE_VFS
loff_t pos = 0;
#else
int size;
int fd;
#endif
if ((s_rdc_fix[0] == POISON_VAL) &&
(s_rdc_fix[1] == POISON_VAL)
)
{
fs = get_fs();
set_fs(get_ds());
#if USE_VFS
file = filp_open(filepath, O_RDONLY, 0);
if(!IS_ERR(file))
{
vfs_read(file, calib_data, MAX_STRING-1, &pos);
if (channel_count == 1) {
if(sscanf(calib_data, "%d;%d;", s_rdc_fix, &s_tv_fix) != 2) {
pr_err("[Smartamp:%s] file %s read error\n", __func__, filepath);
ret = -EIO;
}
} else if (channel_count == 2) {
if(sscanf(calib_data, "%d;%d;%d;", &s_rdc_fix[0], &s_rdc_fix[1], &s_tv_fix) != 3) {
pr_err("[Smartamp:%s] file %s read error\n", __func__, filepath);
ret = -EIO;
}
}
filp_close(file, NULL);
} else {
pr_err("[Smartamp:%s] file %s open failed %p \n ", __func__, filepath, file);
ret = -EIO;
}
#else
fd = sys_open (filepath, O_RDONLY, 0);
if (fd > 0) {
memset (calib_data, 0, sizeof(calib_data));
size = sys_read (fd, calib_data, MAX_STRING-1);
sys_close (fd);
pr_info ("TI-SmartPA: *** sys_read size = %d", size);
if (channel_count == 1) {
if(sscanf(calib_data, "%d;%d;", &rdc_fix[0], tv_fix) != 2) {
pr_err("[TI-SmartPA:%s] file %s read error\n", __func__, filepath);
ret = -EIO;
}
} else if (channel_count == 2) {
if(sscanf(calib_data, "%d;%d;%d;", &rdc_fix[0], &rdc_fix[1], tv_fix) != 3) {
pr_err("[TI-SmartPA:%s] file %s read error\n", __func__, filepath);
ret = -EIO;
}
}
} else {
pr_err("[TI-SmartPA:%s] file %s open failed %p \n ", __func__, filepath, file);
ret = -EIO;
}
#endif
set_fs(fs);
}
if (ret == 0) {
if (rdc_fix) {
rdc_fix[0] = (uint32_t)s_rdc_fix[0];
if (channel_count == 2) {
rdc_fix[1] = (uint32_t)s_rdc_fix[1];
}
}
if (tv_fix)
*tv_fix = (uint32_t)s_tv_fix;
}
return ret;
}
#endif //CONFIG_SET_RE_IN_KERNEL
static int tas25xx_smartamp_get_set(u8 *user_data, uint32_t param_id,
uint8_t get_set, uint32_t length, uint32_t module_id)
{
int ret = 0;
switch (get_set) {
case TAS_SET_PARAM:
if (s_tas_smartamp_bypass) {
pr_err("TI-SmartPA: %s: SmartAmp is bypassed no control set", __func__);
goto fail_cmd;
}
ret = afe_tas_smartamp_set_calib_data(module_id, param_id, length, user_data);
break;
case TAS_GET_PARAM:
memset(user_data, 0, length);
ret = afe_tas_smartamp_get_calib_data(module_id, param_id, length, user_data);
break;
default:
goto fail_cmd;
}
fail_cmd:
return ret;
}
/*Wrapper arround set/get parameter, all set/get commands pass through this wrapper*/
int tas25xx_smartamp_algo_ctrl(u8 *user_data, uint32_t param_id,
uint8_t get_set, uint32_t length, uint32_t module_id)
{
int ret = 0;
mutex_lock(&routing_lock);
ret = tas25xx_smartamp_get_set(user_data, param_id, get_set, length, module_id);
mutex_unlock(&routing_lock);
return ret;
}
EXPORT_SYMBOL(tas25xx_smartamp_algo_ctrl);
/*Control-1: Set Profile*/
static const char *profile_index_text[] = { "NONE", TAS_ALGO_PROFILE_LIST, "CALIB"};
static const struct soc_enum profile_index_enum[] = {
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(profile_index_text), profile_index_text),
};
static int tas25xx_set_profile(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret;
int profile_id = pUcontrol->value.integer.value[0];
int param_id = 0;
int max_number_of_profiles = sizeof(profile_index_text)/sizeof(profile_index_text[0]);
if ((profile_id >= max_number_of_profiles) || (profile_id < 0))
return -EINVAL;
pr_info("TI-SmartPA: %s: Setting profile %s", __func__, profile_index_text[profile_id]);
if(profile_id)
profile_id -= 1;
else
return 0;
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_PROFILE, 1, CHANNEL0);
pr_info("TI-SmartPA: %s: Sending set profile", __func__);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&profile_id, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0)
pr_err("TI-SmartPA: %s: Failed to set config", __func__);
return ret;
}
static int tas25xx_get_profile(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret;
int profile_id = 0;
int param_id = 0;
int max_number_of_profiles = sizeof(profile_index_text)/sizeof(profile_index_text[0]);
if(s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_PROFILE, 1, CHANNEL0);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&profile_id, param_id,
TAS_GET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to get profile", __func__);
profile_id = 0;
} else {
profile_id += 1;
}
}
pUcontrol->value.integer.value[0] = profile_id;
if (profile_id < max_number_of_profiles) {
pr_info("TI-SmartPA: %s: getting profile %s", __func__, profile_index_text[profile_id]);
}
return 0;
}
/*Control-2: Set Calibrated Rdc*/
static int tas25xx_set_Re_common (int re_value_in, int channel)
{
int ret;
int param_id = 0;
int re_value = re_value_in;
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, channel);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&re_value, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
return ret;
}
static int tas25xx_set_Re_left(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int re_value = pUcontrol->value.integer.value[0];
pr_info("TI-SmartPA: %s: Setting Re %d", __func__, re_value);
return tas25xx_set_Re_common(re_value, CHANNEL0);
}
static int tas25xx_dummy_get(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
pUcontrol->value.integer.value[0] = 0;
return ret;
}
static int tas25xx_dummy_set(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
return 0;
}
/*Control-3: Calibration and Test(F0,Q,Tv) Controls*/
static const char *tas25xx_calib_test_text[] = {
"NONE",
"CALIB_START",
"CALIB_STOP",
"TEST_START",
"TEST_STOP"
};
static const struct soc_enum tas25xx_calib_test_enum[] = {
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_calib_test_text), tas25xx_calib_test_text),
};
static int tas25xx_calib_test_set_common (int calib_command, int channel)
{
int ret = 0;
int param_id = 0;
int data = 1;
switch(calib_command) {
case CALIB_START:
pr_info ("TI-SmartPA: %s: CALIB_START", __func__);
param_id = TAS_CALC_PARAM_IDX (TAS_SA_CALIB_INIT, 1, channel);
break;
case CALIB_STOP:
pr_info ("TI-SmartPA: %s: CALIB_STOP", __func__);
param_id = TAS_CALC_PARAM_IDX (TAS_SA_CALIB_DEINIT, 1, channel);
break;
case TEST_START:
case TEST_STOP:
default:
pr_info ("TI-SmartPA: %s: no impl", __func__);
ret = -EINVAL;
break;
}
if (param_id) {
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&data, param_id,
TAS_SET_PARAM, sizeof (uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to set calib/test, ret=%d", __func__, ret);
}
}
return ret;
}
static int tas25xx_calib_test_set(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int user_data = pUcontrol->value.integer.value[0];
if ((0 == (ret = tas25xx_calib_test_set_common (user_data, CHANNEL0)))) {
#ifdef CONFIG_TAS25XX_ALGO_STEREO
ret = tas25xx_calib_test_set_common (user_data, CHANNEL1);
#endif
}
return ret;
}
/*Control-4: Get Re*/
//returns -ve error or +ve re value, 0 if not called
static int tas25xx_get_re_common (int channel)
{
int ret = 0;
int re_value = 0;
int param_id = 0;
pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
if(s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX (TAS_SA_GET_RE, 1, channel);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&re_value, param_id,
TAS_GET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to get Re", __func__);
} else {
ret = re_value;
}
}
return ret;
}
static int tas25xx_get_re_left(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_re_common (CHANNEL0);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
ret = 0;
pr_info("TI-SmartPA: %s: Getting Re %d", __func__, ret);
}
return ret;
}
/*Control-5: Get F0*/
static int tas25xx_get_f0_common(int channel)
{
int f0_value = 0;
int param_id = 0;
int ret = 0;
pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
if(s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_F0, 1, channel);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&f0_value, param_id,
TAS_GET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err ("TI-SmartPA: %s: Failed to get F0", __func__);
} else {
ret = f0_value;
}
}
return ret;
}
static int tas25xx_get_f0_left(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_f0_common (CHANNEL0);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting F0 val=%d", __func__, ret);
ret = 0;
}
return ret;
}
/*Control-6: Get Q*/
static int tas25xx_get_q_common (int channel)
{
int ret = 0;
int q_value = 0;
int param_id = 0;
pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
if (s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX (TAS_SA_GET_Q, 1, channel);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&q_value, param_id,
TAS_GET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err ("TI-SmartPA: %s: Failed to get F0", __func__);
} else {
ret = q_value;
}
}
return ret;
}
static int tas25xx_get_q_left(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_q_common (CHANNEL0);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting Q %d", __func__, ret);
ret = 0;
}
return ret;
}
/*Control-7: Get Tv*/
static int tas25xx_get_tv_common(int channel)
{
int ret = 0;
int tv_value = 0;
int param_id = 0;
pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
if (s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_TV, 1, channel);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&tv_value, param_id,
TAS_GET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err ("TI-SmartPA: %s: Failed to get Tv", __func__);
} else {
ret = tv_value;
}
}
return ret;
}
static int tas25xx_get_tv_left(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_tv_common (CHANNEL0);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting Tv %d", __func__, ret);
ret = 0;
}
return ret;
}
/*Control-8: Smartamp Enable*/
static const char *tas25xx_smartamp_enable_text[] = {
"DISABLE",
"ENABLE"
};
static const struct soc_enum tas25xx_smartamp_enable_enum[] = {
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_enable_text), tas25xx_smartamp_enable_text),
};
static int tas25xx_smartamp_enable_set(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int param_id = 0;
int user_data = pUcontrol->value.integer.value[0];
#ifdef CONFIG_SET_RE_IN_KERNEL
uint32_t calibration_data[3];
#endif
#ifdef CONFIG_TAS25XX_ALGO_STEREO
int number_of_ch = 2;
#else
int number_of_ch = 1;
#endif
pr_info("TI-SmartPA: %s: case %d, number_of_ch=%d", __func__, user_data, number_of_ch);
s_tas_smartamp_enable = user_data;
if (s_tas_smartamp_enable == 0) {
pr_info("TI-SmartPA: %s: Disable called", __func__);
return 0;
}
pr_info ("TI-SmartPA: %s: Setting the feedback module info for TAS", __func__);
ret = afe_spk_prot_feed_back_cfg (TAS_TX_PORT,TAS_RX_PORT, 1, 0, 1);
if (ret) {
pr_err("TI-SmartPA: %s: FB Path Info failed ignoring ret = 0x%x", __func__, ret);
}
pr_info ("TI-SmartPA: %s: Sending TX Enable", __func__);
param_id = CAPI_V2_TAS_TX_ENABLE;
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&user_data, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_TX);
if (ret) {
pr_err("TI-SmartPA: %s: TX Enable Failed ret = 0x%x", __func__, ret);
goto fail_cmd;
}
//Special configuration indicating bin file
user_data = 0xB1B1B1B1;
pr_info("TI-SmartPA: %s: Sending TX Config", __func__);
param_id = CAPI_V2_TAS_TX_CFG;
ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_TX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to set config", __func__);
}
user_data = 1;
pr_info ("TI-SmartPA: %s: Sending RX Enable", __func__);
param_id = CAPI_V2_TAS_RX_ENABLE;
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&user_data, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret) {
pr_err("TI-SmartPA: %s: RX Enable Failed ret = 0x%x", __func__, ret);
goto fail_cmd;
}
//Special configuration indicating bin file
user_data = 0xB1B1B1B1;
pr_info("TI-SmartPA: %s: Sending RX Config", __func__);
param_id = CAPI_V2_TAS_RX_CFG;
ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to set config", __func__);
}
s_tas_smartamp_enable = true;
#ifdef CONFIG_SET_RE_IN_KERNEL
if (number_of_ch == 2) {
ret = get_calibrated_re_tcalib (calibration_data, &calibration_data[2], number_of_ch);
} else {
ret = get_calibrated_re_tcalib (calibration_data, &calibration_data[1], number_of_ch);
}
if(ret) {
pr_err("[Smartamp:%s] unable to get the calibration data = 0x%x", __func__, ret);
} else {
int32_t t_cal;
if (number_of_ch == 2) {
t_cal = calibration_data[2];
pr_info("[Smartamp:%s] setting re %d,%d and tcal %d", __func__
, calibration_data[0], calibration_data[1], calibration_data[2]);
} else {
t_cal = calibration_data[1];
pr_info("[Smartamp:%s] setting re %d and tcal %d", __func__
, calibration_data[0], calibration_data[1]);
}
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&t_cal,
param_id, TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("[Smartamp:%s] Failed to set Tcal", __func__);
goto fail_cmd;
}
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL0);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)(&(calibration_data[0])),
param_id, TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err("TI-SmartPA: %s: Failed to set Re", __func__);
goto fail_cmd;
}
if (number_of_ch == 2) {
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL1);
ret = tas25xx_smartamp_algo_ctrl ((u8 *)&(calibration_data[1]),
param_id, TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if(ret < 0) {
pr_err("TI-SmartPA: %s: Failed to set Re", __func__);
goto fail_cmd;
}
}
}
#endif //CONFIG_SET_RE_IN_KERNEL
fail_cmd:
return ret;
}
static int tas25xx_smartamp_enable_get(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int user_data = s_tas_smartamp_enable;
pUcontrol->value.integer.value[0] = user_data;
pr_info("TI-SmartPA: %s: case %d(0=DISABLE, 1=ENABLE)", __func__, user_data);
return ret;
}
/*Control-9: Smartamp Bypass */
static const char *tas25xx_smartamp_bypass_text[] = {
"FALSE",
"TRUE"
};
static const struct soc_enum tas25xx_smartamp_bypass_enum[] = {
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_bypass_text), tas25xx_smartamp_bypass_text),
};
static int tas25xx_smartamp_bypass_set(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int user_data = pUcontrol->value.integer.value[0];
if (s_tas_smartamp_enable) {
pr_debug("TI-SmartPA: %s: cannot update while smartamp enabled", __func__);
return -EINVAL;
}
s_tas_smartamp_bypass = user_data;
pr_info("TI-SmartPA: %s: case %d(FALSE=0,TRUE=1)", __func__, user_data);
return ret;
}
static int tas25xx_smartamp_bypass_get(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
pUcontrol->value.integer.value[0] = s_tas_smartamp_bypass;
pr_info("TI-SmartPA: %s: case %d", __func__, s_tas_smartamp_bypass);
return ret;
}
static int tas25xx_set_spk_id(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int speaker_id = pUcontrol->value.integer.value[0];
int param_id = 0;
pr_info("TI-SmartPA: %s: spk-id set %d", __func__, speaker_id);
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_SPKID, 1, CHANNEL0);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&speaker_id, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err ("TI-SmartPA: %s: Failed to set spk id", __func__);
}
return ret;
}
static int tas25xx_set_t_calib(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = 0;
int calib_temp = pUcontrol->value.integer.value[0];
int param_id = 0;
pr_info("TI-SmartPA: %s: tcalib set %d", __func__, calib_temp);
if (s_tas_smartamp_enable) {
param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0);
ret = tas25xx_smartamp_algo_ctrl((u8 *)&calib_temp, param_id,
TAS_SET_PARAM, sizeof(uint32_t), AFE_SMARTAMP_MODULE_RX);
if (ret < 0) {
pr_err ("TI-SmartPA: %s: Failed to set spk id", __func__);
}
}
return ret;
}
#ifdef CONFIG_TAS25XX_ALGO_STEREO
static int tas25xx_set_Re_right(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int re_value = pUcontrol->value.integer.value[0];
pr_info("TI-SmartPA: %s: Setting Re %d", __func__, re_value);
return tas25xx_set_Re_common(re_value, CHANNEL1);
}
static int tas25xx_get_re_right(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret;
ret = tas25xx_get_re_common (CHANNEL1);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
ret = 0;
pr_info("TI-SmartPA: %s: Getting Re value=%d", __func__, ret);
}
return ret;
}
static int tas25xx_get_f0_right(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_f0_common (CHANNEL1);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting F0 valu=%d", __func__, ret);
ret = 0;
}
return ret;
}
static int tas25xx_get_q_right(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_q_common (CHANNEL1);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting Q val=%d", __func__, ret);
ret = 0;
}
return ret;
}
static int tas25xx_get_tv_right(struct snd_kcontrol *pKcontrol,
struct snd_ctl_elem_value *pUcontrol)
{
int ret = tas25xx_get_tv_common (CHANNEL1);
if (ret >= 0) {
pUcontrol->value.integer.value[0] = ret;
pr_info("TI-SmartPA: %s: Getting Tv %d", __func__, ret);
ret = 0;
}
return ret;
}
#endif
static const struct snd_kcontrol_new smartamp_tas25xx_mixer_controls[] = {
SOC_ENUM_EXT("TAS25XX_ALGO_PROFILE", profile_index_enum[0],
tas25xx_get_profile, tas25xx_set_profile),
SOC_ENUM_EXT("TAS25XX_ALGO_CALIB_TEST", tas25xx_calib_test_enum[0],
tas25xx_dummy_get, tas25xx_calib_test_set),
SOC_SINGLE_EXT("TAS25XX_SET_SPK_ID", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_dummy_get, tas25xx_set_spk_id),
SOC_SINGLE_EXT("TAS25XX_SET_T_CALIB", SND_SOC_NOPM, 0, 100, 0,
tas25xx_dummy_get, tas25xx_set_t_calib),
//left
SOC_SINGLE_EXT("TAS25XX_SET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_dummy_get, tas25xx_set_Re_left),
SOC_SINGLE_EXT("TAS25XX_GET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_re_left, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_F0_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_f0_left, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_Q_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_q_left, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_TV_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_tv_left, tas25xx_dummy_set),
//Right
#ifdef CONFIG_TAS25XX_ALGO_STEREO
SOC_SINGLE_EXT("TAS25XX_SET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_dummy_get, tas25xx_set_Re_right),
SOC_SINGLE_EXT("TAS25XX_GET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_re_right, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_F0_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_f0_right, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_Q_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_q_right, tas25xx_dummy_set),
SOC_SINGLE_EXT("TAS25XX_GET_TV_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
tas25xx_get_tv_right, tas25xx_dummy_set),
#endif
SOC_ENUM_EXT("TAS25XX_SMARTPA_ENABLE", tas25xx_smartamp_enable_enum[0],
tas25xx_smartamp_enable_get, tas25xx_smartamp_enable_set),
SOC_ENUM_EXT("TAS25XX_ALGO_BYPASS", tas25xx_smartamp_bypass_enum[0],
tas25xx_smartamp_bypass_get, tas25xx_smartamp_bypass_set),
};
#if CODEC_CONTROL
void tas_smartamp_add_algo_controls(struct snd_soc_codec *codec)
{
pr_err("TI-SmartPA: %s: Adding smartamp controls", __func__);
mutex_init(&routing_lock);
snd_soc_add_codec_controls(codec, smartamp_tas25xx_mixer_controls,
ARRAY_SIZE(smartamp_tas25xx_mixer_controls));
tas_calib_init();
}
EXPORT_SYMBOL(tas_smartamp_add_algo_controls);
#else
void tas_smartamp_add_algo_controls_for_platform (struct snd_soc_platform *platform)
{
pr_err("TI-SmartPA: %s: Adding smartamp controls", __func__);
mutex_init(&routing_lock);
snd_soc_add_platform_controls (platform, smartamp_tas25xx_mixer_controls, ARRAY_SIZE(smartamp_tas25xx_mixer_controls));
tas_calib_init();
}
EXPORT_SYMBOL(tas_smartamp_add_algo_controls_for_platform);
#endif
void tas_smartamp_remove_algo_controls(struct snd_soc_codec *codec)
{
(void)codec;
tas_calib_exit();
}
EXPORT_SYMBOL(tas_smartamp_remove_algo_controls);
MODULE_AUTHOR("Texas Instrumnets Inc.");
MODULE_DESCRIPTION("TAS25xx ALSA SOC Smart Amplifier algo driver");
MODULE_LICENSE("GPL v2");
#endif /* CONFIG_TAS25XX_ALGO */