Merge "ASoC: msm: update QUAT/QUIN TDM slot mappings for A2B"

这个提交包含在:
qctecmdr
2020-03-30 01:20:38 -07:00
提交者 Gerrit - the friendly Code Review server
当前提交 b8e5bd2fc8
修改 8 个文件,包含 432 行新增195 行删除

查看文件

@@ -23,6 +23,7 @@
#include "q6afecal-hwdep.h"
#define WAKELOCK_TIMEOUT 5000
#define AFE_CLK_TOKEN 1024
enum {
AFE_COMMON_RX_CAL = 0,
AFE_COMMON_TX_CAL,
@@ -106,8 +107,11 @@ struct afe_ctl {
void *apr;
atomic_t state;
atomic_t status;
atomic_t clk_state;
atomic_t clk_status;
wait_queue_head_t wait[AFE_MAX_PORTS];
wait_queue_head_t wait_wakeup;
wait_queue_head_t clk_wait;
struct task_struct *task;
wait_queue_head_t lpass_core_hw_wait;
uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX];
@@ -154,6 +158,7 @@ struct afe_ctl {
struct aanc_data aanc_info;
struct mutex afe_cmd_lock;
struct mutex afe_apr_lock;
struct mutex afe_clk_lock;
int set_custom_topology;
int dev_acdb_id[AFE_MAX_PORTS];
routing_cb rt_cb;
@@ -680,8 +685,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX)
this_afe.lpass_hw_core_client_hdl[data->token] =
payload[0];
atomic_set(&this_afe.state, 0);
atomic_set(&this_afe.status, 0);
atomic_set(&this_afe.clk_state, 0);
atomic_set(&this_afe.clk_status, 0);
wake_up(&this_afe.lpass_core_hw_wait);
} else if (data->payload_size) {
uint32_t *payload;
@@ -699,7 +704,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
payload[0], payload[1], data->token);
/* payload[1] contains the error status for response */
if (payload[1] != 0) {
atomic_set(&this_afe.status, payload[1]);
if(data->token == AFE_CLK_TOKEN)
atomic_set(&this_afe.clk_status, payload[1]);
else
atomic_set(&this_afe.status, payload[1]);
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
}
@@ -720,11 +728,16 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
case AFE_SVC_CMD_SET_PARAM:
case AFE_SVC_CMD_SET_PARAM_V2:
case AFE_PORT_CMD_MOD_EVENT_CFG:
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
if(data->token == AFE_CLK_TOKEN) {
atomic_set(&this_afe.clk_state, 0);
wake_up(&this_afe.clk_wait);
} else {
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
}
break;
case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
break;
@@ -770,7 +783,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
break;
case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST:
atomic_set(&this_afe.state, 0);
if (payload[1] != 0)
atomic_set(&this_afe.clk_state,
payload[1]);
wake_up(&this_afe.lpass_core_hw_wait);
break;
case AFE_SVC_CMD_EVENT_CFG:
@@ -1090,6 +1105,46 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait)
mutex_unlock(&this_afe.afe_apr_lock);
return ret;
}
/*
* afe_apr_send_clk_pkt : returns 0 on success, negative otherwise.
*/
static int afe_apr_send_clk_pkt(void *data, wait_queue_head_t *wait)
{
int ret;
if (wait)
atomic_set(&this_afe.clk_state, 1);
atomic_set(&this_afe.clk_status, 0);
ret = apr_send_pkt(this_afe.apr, data);
if (ret > 0) {
if (wait) {
ret = wait_event_timeout(*wait,
(atomic_read(&this_afe.clk_state) == 0),
msecs_to_jiffies(2 * TIMEOUT_MS));
if (!ret) {
pr_err("%s: timeout\n", __func__);
ret = -ETIMEDOUT;
} else if (atomic_read(&this_afe.clk_status) > 0) {
pr_err("%s: DSP returned error[%s]\n", __func__,
adsp_err_get_err_str(atomic_read(
&this_afe.clk_status)));
ret = adsp_err_get_lnx_err_code(
atomic_read(&this_afe.clk_status));
} else {
ret = 0;
}
} else {
ret = 0;
}
} else if (ret == 0) {
pr_err("%s: packet not transmitted\n", __func__);
/* apr_send_pkt can return 0 when nothing is transmitted */
ret = -EINVAL;
}
pr_debug("%s: leave %d\n", __func__, ret);
return ret;
}
/* This function shouldn't be called directly. Instead call q6afe_set_params. */
static int q6afe_set_params_v2(u16 port_id, int index,
@@ -1486,6 +1541,122 @@ done:
return rc;
}
/*
* This function shouldn't be called directly. Instead call
* q6afe_clk_set_params.
*/
static int q6afe_clk_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
u8 *packed_param_data, u32 packed_data_size)
{
struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
int rc = 0;
if (packed_param_data != NULL)
size += packed_data_size;
svc_set_param = kzalloc(size, GFP_KERNEL);
if (svc_set_param == NULL)
return -ENOMEM;
svc_set_param->apr_hdr.hdr_field =
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
APR_PKT_VER);
svc_set_param->apr_hdr.pkt_size = size;
svc_set_param->apr_hdr.src_port = 0;
svc_set_param->apr_hdr.dest_port = 0;
svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
svc_set_param->payload_size = packed_data_size;
if (mem_hdr != NULL) {
/* Out of band case. */
svc_set_param->mem_hdr = *mem_hdr;
} else if (packed_param_data != NULL) {
/* In band case. */
memcpy(&svc_set_param->param_data, packed_param_data,
packed_data_size);
} else {
pr_err("%s: Both memory header and param data are NULL\n",
__func__);
rc = -EINVAL;
goto done;
}
rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
done:
kfree(svc_set_param);
return rc;
}
/*
* This function shouldn't be called directly. Instead call
* q6afe_clk_set_params.
*/
static int q6afe_clk_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
u8 *packed_param_data, u32 packed_data_size)
{
struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
int rc = 0;
if (packed_param_data != NULL)
size += packed_data_size;
svc_set_param = kzalloc(size, GFP_KERNEL);
if (svc_set_param == NULL)
return -ENOMEM;
svc_set_param->apr_hdr.hdr_field =
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
APR_PKT_VER);
svc_set_param->apr_hdr.pkt_size = size;
svc_set_param->apr_hdr.src_port = 0;
svc_set_param->apr_hdr.dest_port = 0;
svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
svc_set_param->payload_size = packed_data_size;
if (mem_hdr != NULL) {
/* Out of band case. */
svc_set_param->mem_hdr = *mem_hdr;
} else if (packed_param_data != NULL) {
/* In band case. */
memcpy(&svc_set_param->param_data, packed_param_data,
packed_data_size);
} else {
pr_err("%s: Both memory header and param data are NULL\n",
__func__);
rc = -EINVAL;
goto done;
}
rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
done:
kfree(svc_set_param);
return rc;
}
static int q6afe_clk_set_params(int index, struct mem_mapping_hdr *mem_hdr,
u8 *packed_param_data, u32 packed_data_size,
bool is_iid_supported)
{
int ret;
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
return ret;
}
if (is_iid_supported)
return q6afe_clk_set_params_v2(index, mem_hdr,
packed_param_data,
packed_data_size);
else
return q6afe_clk_set_params_v1(index, mem_hdr,
packed_param_data,
packed_data_size);
}
static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
u8 *packed_param_data, u32 packed_data_size,
bool is_iid_supported)
@@ -1530,9 +1701,12 @@ static int q6afe_svc_pack_and_set_param_in_band(int index,
__func__, ret);
goto done;
}
ret = q6afe_svc_set_params(index, NULL, packed_param_data,
packed_data_size, is_iid_supported);
if (param_hdr.module_id == AFE_MODULE_CLOCK_SET)
ret = q6afe_clk_set_params(index, NULL, packed_param_data,
packed_data_size, is_iid_supported);
else
ret = q6afe_svc_set_params(index, NULL, packed_param_data,
packed_data_size, is_iid_supported);
done:
kfree(packed_param_data);
@@ -7655,13 +7829,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
memset(&param_hdr, 0, sizeof(param_hdr));
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret);
return ret;
}
mutex_lock(&this_afe.afe_cmd_lock);
mutex_lock(&this_afe.afe_clk_lock);
param_hdr.module_id = AFE_MODULE_CLOCK_SET;
param_hdr.instance_id = INSTANCE_ID_0;
param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET;
@@ -7681,7 +7849,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
__func__, ret);
mutex_unlock(&this_afe.afe_cmd_lock);
mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_set_lpass_clk_cfg);
@@ -9028,6 +9196,8 @@ int __init afe_init(void)
atomic_set(&this_afe.state, 0);
atomic_set(&this_afe.status, 0);
atomic_set(&this_afe.clk_state, 0);
atomic_set(&this_afe.clk_status, 0);
atomic_set(&this_afe.mem_map_cal_index, -1);
this_afe.apr = NULL;
this_afe.dtmf_gen_rx_portid = -1;
@@ -9041,6 +9211,7 @@ int __init afe_init(void)
this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
mutex_init(&this_afe.afe_cmd_lock);
mutex_init(&this_afe.afe_apr_lock);
mutex_init(&this_afe.afe_clk_lock);
for (i = 0; i < AFE_MAX_PORTS; i++) {
this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
this_afe.afe_sample_rates[i] = 0;
@@ -9052,6 +9223,7 @@ int __init afe_init(void)
}
init_waitqueue_head(&this_afe.wait_wakeup);
init_waitqueue_head(&this_afe.lpass_core_hw_wait);
init_waitqueue_head(&this_afe.clk_wait);
wl.ws = wakeup_source_register(NULL, "spkr-prot");
if (!wl.ws)
return -ENOMEM;
@@ -9101,6 +9273,7 @@ void afe_exit(void)
config_debug_fs_exit();
mutex_destroy(&this_afe.afe_cmd_lock);
mutex_destroy(&this_afe.afe_apr_lock);
mutex_destroy(&this_afe.afe_clk_lock);
wakeup_source_unregister(wl.ws);
}
@@ -9164,7 +9337,7 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
return ret;
}
mutex_lock(&this_afe.afe_cmd_lock);
mutex_lock(&this_afe.afe_clk_lock);
memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
@@ -9184,15 +9357,15 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
__func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
*client_handle = 0;
ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
&this_afe.lpass_core_hw_wait);
ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
&this_afe.lpass_core_hw_wait);
if (ret == 0) {
*client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id];
pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__,
this_afe.lpass_hw_core_client_hdl[hw_block_id]);
}
mutex_unlock(&this_afe.afe_cmd_lock);
mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_vote_lpass_core_hw);
@@ -9218,7 +9391,7 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
return ret;
}
mutex_lock(&this_afe.afe_cmd_lock);
mutex_lock(&this_afe.afe_clk_lock);
if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) {
pr_debug("%s: SSR in progress, return\n", __func__);
@@ -9247,10 +9420,10 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
goto done;
}
ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
&this_afe.lpass_core_hw_wait);
ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
&this_afe.lpass_core_hw_wait);
done:
mutex_unlock(&this_afe.afe_cmd_lock);
mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_unvote_lpass_core_hw);