int avcs_core_disable_power_collapse(int disable) { struct adsp_power_collapse pc; int rc = 0; if (core_handle) { pc.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); pc.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(uint32_t)); pc.hdr.src_port = 0; pc.hdr.dest_port = 0; pc.hdr.token = 0; pc.hdr.opcode = ADSP_CMD_SET_POWER_COLLAPSE_STATE; pc.power_collapse = disable; rc = apr_send_pkt(core_handle, (uint32_t *)&pc); if (rc < 0) { pr_debug("disable power collapse = %d failed\n", disable); return rc; } pr_debug("disable power collapse = %d\n", disable); } return 0; }
static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal) { s32 result = 0; struct adm_set_params_command adm_params; int index = afe_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: invalid port idx %d portid %d\n", __func__, index, port_id); return 0; } pr_debug("%s: Port id %d, index %d\n", __func__, port_id, index); if (!aud_cal || aud_cal->cal_size == 0) { pr_debug("%s: No ADM cal to send for port_id = %d!\n", __func__, port_id); result = -EINVAL; goto done; } adm_params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); adm_params.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(adm_params)); adm_params.hdr.src_svc = APR_SVC_ADM; adm_params.hdr.src_domain = APR_DOMAIN_APPS; adm_params.hdr.src_port = port_id; adm_params.hdr.dest_svc = APR_SVC_ADM; adm_params.hdr.dest_domain = APR_DOMAIN_ADSP; adm_params.hdr.dest_port = atomic_read(&this_adm.copp_id[index]); adm_params.hdr.token = port_id; adm_params.hdr.opcode = ADM_CMD_SET_PARAMS; adm_params.payload = aud_cal->cal_paddr; adm_params.payload_size = aud_cal->cal_size; atomic_set(&this_adm.copp_stat[index], 0); pr_debug("%s: Sending SET_PARAMS payload = 0x%x, size = %d\n", __func__, adm_params.payload, adm_params.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); if (result < 0) { pr_err("%s: Set params failed port = %d payload = 0x%x\n", __func__, port_id, aud_cal->cal_paddr); result = -EINVAL; goto done; } /* Wait for the callback */ result = wait_event_timeout(this_adm.wait, atomic_read(&this_adm.copp_stat[index]), msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: Set params timed out port = %d, payload = 0x%x\n", __func__, port_id, aud_cal->cal_paddr); result = -EINVAL; goto done; } result = 0; done: return result; }
int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) { struct afe_loopback_cfg_v1 lb_cmd; int ret = 0; int index = 0; ret = afe_q6_interface_prepare(); if (ret != 0) return ret; index = q6audio_get_port_index(rx_port); if (q6audio_validate_port(rx_port) < 0) return -EINVAL; lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); lb_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(lb_cmd) - APR_HDR_SIZE); lb_cmd.hdr.src_port = 0; lb_cmd.hdr.dest_port = 0; lb_cmd.hdr.token = index; lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; lb_cmd.param.port_id = tx_port; lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2)); lb_cmd.param.payload_address_lsw = 0x00; lb_cmd.param.payload_address_msw = 0x00; lb_cmd.param.mem_map_handle = 0x00; lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK; lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; lb_cmd.pdata.param_size = lb_cmd.param.payload_size - sizeof(struct afe_port_param_data_v2); lb_cmd.dst_port_id = rx_port; lb_cmd.routing_mode = LB_MODE_DEFAULT; lb_cmd.enable = (enable ? 1 : 0); lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; atomic_set(&this_afe.state, 1); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &lb_cmd); if (ret < 0) { pr_err("%s: AFE loopback failed\n", __func__); ret = -EINVAL; goto done; } pr_debug("%s: waiting for this_afe.wait[%d]\n", __func__, index); ret = wait_event_timeout(this_afe.wait[index], (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout\n", __func__); ret = -EINVAL; } done: return ret; }
int afe_loopback(u16 enable, u16 dst_port, u16 src_port) { struct afe_loopback_command lb_cmd; int ret = 0; ret = afe_q6_interface_prepare(); if (ret != 0) return ret; if ((afe_get_port_type(dst_port) == MSM_AFE_PORT_TYPE_RX) && (afe_get_port_type(src_port) == MSM_AFE_PORT_TYPE_RX)) return afe_loopback_cfg(enable, dst_port, src_port, LB_MODE_EC_REF_VOICE_AUDIO); lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); lb_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(lb_cmd) - APR_HDR_SIZE); lb_cmd.hdr.src_port = 0; lb_cmd.hdr.dest_port = 0; lb_cmd.hdr.token = 0; lb_cmd.hdr.opcode = AFE_PORT_CMD_LOOPBACK; lb_cmd.tx_port_id = src_port; lb_cmd.rx_port_id = dst_port; lb_cmd.mode = 0xFFFF; lb_cmd.enable = (enable ? 1 : 0); atomic_set(&this_afe.state, 1); pr_info("%s: AFE loopback enable %d from src 0x%x to dst 0x%x\n", __func__,enable,src_port,dst_port); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &lb_cmd); if (ret < 0) { pr_err("%s: AFE loopback failed\n", __func__); ret = -EINVAL; goto done; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout\n", __func__); #ifdef HTC_AUD_DEBUG BUG(); #endif ret = -EINVAL; } done: return ret; }
void send_cal(int port_id, struct acdb_cal_block *aud_cal) { s32 result; struct adm_set_params_command adm_params; pr_debug("%s: Port id %d\n", __func__, port_id); if (!aud_cal || aud_cal->cal_size == 0) { pr_debug("%s: No calibration data to send!\n", __func__); goto done; } adm_params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); adm_params.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(adm_params)); adm_params.hdr.src_svc = APR_SVC_ADM; adm_params.hdr.src_domain = APR_DOMAIN_APPS; adm_params.hdr.src_port = port_id; adm_params.hdr.dest_svc = APR_SVC_ADM; adm_params.hdr.dest_domain = APR_DOMAIN_ADSP; adm_params.hdr.dest_port = atomic_read(&this_adm.copp_id[port_id]); adm_params.hdr.token = port_id; adm_params.hdr.opcode = ADM_CMD_SET_PARAMS; adm_params.payload = aud_cal->cal_paddr; adm_params.payload_size = aud_cal->cal_size; atomic_set(&this_adm.copp_stat[port_id], 0); pr_debug("%s: Sending SET_PARAMS payload = 0x%x, size = %d\n", __func__, adm_params.payload, adm_params.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); if (result < 0) { pr_err("%s: Set params failed port = %d payload = 0x%x\n", __func__, port_id, aud_cal->cal_paddr); goto done; } /* Wait for the callback */ result = wait_event_timeout(this_adm.wait, atomic_read(&this_adm.copp_stat[port_id]), msecs_to_jiffies(TIMEOUT_MS)); if (!result) pr_err("%s: Set params timed out port = %d, payload = 0x%x\n", __func__, port_id, aud_cal->cal_paddr); done: return; }
static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr, uint32_t pkt_size, bool cmd_flg) { mutex_lock(&usc->cmd_lock); hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \ APR_HDR_LEN(sizeof(struct apr_hdr)),\ APR_PKT_VER); hdr->src_svc = ((struct apr_svc *)usc->apr)->id; hdr->src_domain = APR_DOMAIN_APPS; hdr->dest_svc = APR_SVC_USM; hdr->dest_domain = APR_DOMAIN_ADSP; hdr->src_port = (usc->session << 8) | 0x0001; hdr->dest_port = (usc->session << 8) | 0x0001; if (cmd_flg) { hdr->token = usc->session; atomic_set(&usc->cmd_state, 1); } hdr->pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, pkt_size); mutex_unlock(&usc->cmd_lock); return; }
int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) { struct afe_loopback_command lb_cmd; int ret = 0; if (this_afe.apr == NULL) { pr_err("%s:AFE is not opened\n", __func__); ret = -1; goto done; } lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); lb_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(lb_cmd) - APR_HDR_SIZE); lb_cmd.hdr.src_port = 0; lb_cmd.hdr.dest_port = 0; lb_cmd.hdr.token = 0; lb_cmd.hdr.opcode = AFE_PORT_CMD_LOOPBACK; lb_cmd.tx_port_id = tx_port; lb_cmd.rx_port_id = rx_port; lb_cmd.mode = 0xFFFF; lb_cmd.enable = (enable ? 1 : 0); atomic_set(&this_afe.state, 1); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &lb_cmd); if (ret < 0) { pr_err("%s: AFE loopback failed\n", __func__); ret = -EINVAL; goto done; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout\n", __func__); ret = -EINVAL; } done: return ret; }
int avcs_core_disable_power_collapse(int disable) { struct adsp_power_collapse pc; int rc = 0; if (core_handle) { pc.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); pc.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(uint32_t)); pc.hdr.src_port = 0; pc.hdr.dest_port = 0; pc.hdr.token = 0; pc.hdr.opcode = ADSP_CMD_SET_POWER_COLLAPSE_STATE; /* * When power_collapse set to 1 -- If the aDSP is in the power * collapsed state when this command is received, it is awakened * from this state. The aDSP does not power collapse again until * the client revokes this command * When power_collapse set to 0 -- This indicates to the aDSP * that the remote client does not need it to be out of power * collapse any longer. This may not always put the aDSP into * power collapse; the aDSP must honor an internal client's * power requirements as well. */ pc.power_collapse = disable; rc = apr_send_pkt(core_handle, (uint32_t *)&pc); if (rc < 0) { pr_debug("disable power collapse = %d failed\n", disable); return rc; } pr_debug("disable power collapse = %d\n", disable); } return 0; }
u32 send_adm_apr(void *buf, u32 opcode) { s32 result; u32 user_buf_size = 0; u32 bytes_returned = 0; u32 port_index = 0; u32 copp_id; int port_id; u32 payload_size; u32 data_size = 0; struct apr_hdr adm_params; pr_debug("%s\n", __func__); if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) { result = rtac_allocate_cal_buffer(ADM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", __func__); goto done; } } if (rtac_cal[ADM_RTAC_CAL].map_data.map_handle == 0) { result = rtac_map_cal_buffer(ADM_RTAC_CAL); if (result < 0) { pr_err("%s: map buffer failed!", __func__); goto done; } } if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { pr_err("%s: Copy from user failed! buf = 0x%x\n", __func__, (unsigned int)buf); goto done; } if (user_buf_size <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, user_buf_size); goto done; } if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy port id from user buffer\n", __func__); goto done; } for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) { if (adm_get_copp_id(port_index) == copp_id) break; if (adm_get_lowlatency_copp_id(port_index) == copp_id) break; } if (port_index >= AFE_MAX_PORTS) { pr_err("%s: Could not find port index for copp = %d\n", __func__, copp_id); goto done; } port_id = q6audio_get_port_id_from_index(port_index); if (port_id < 0) { pr_err("%s: Could not find port id mapped for port_idx %d\n", __func__, port_index); goto done; } mutex_lock(&rtac_adm_apr_mutex); if (rtac_adm_apr_data.apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } if (opcode == ADM_CMD_SET_PP_PARAMS_V5) { data_size = payload_size - 4 * sizeof(u32); if (data_size > rtac_cal[ADM_RTAC_CAL].map_data.map_size) { pr_err("%s: Invalid data size = %d\n", __func__, data_size); goto done; } payload_size = 4 * sizeof(u32); if (copy_from_user((void *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } rtac_adm_buffer[8] = data_size; } else { if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto done; } if (copy_from_user(rtac_adm_buffer + sizeof(adm_params)/sizeof(u32), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } } adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); adm_params.src_svc = APR_SVC_ADM; adm_params.src_domain = APR_DOMAIN_APPS; adm_params.src_port = copp_id; adm_params.dest_svc = APR_SVC_ADM; adm_params.dest_domain = APR_DOMAIN_ADSP; adm_params.dest_port = copp_id; adm_params.token = port_id; adm_params.opcode = opcode; rtac_adm_buffer[5] = rtac_cal[ADM_RTAC_CAL].cal_data.paddr; rtac_adm_buffer[6] = 0; rtac_adm_buffer[7] = rtac_cal[ADM_RTAC_CAL].map_data.map_handle; memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params)); atomic_set(&rtac_adm_apr_data.cmd_state, 1); pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%x\n", __func__, opcode, rtac_cal[ADM_RTAC_CAL].cal_data.paddr); result = apr_send_pkt(rtac_adm_apr_data.apr_handle, (uint32_t *)rtac_adm_buffer); if (result < 0) { pr_err("%s: Set params failed port = %d, copp = %d\n", __func__, port_index, copp_id); goto err; } result = wait_event_timeout(rtac_adm_apr_data.cmd_wait, (atomic_read(&rtac_adm_apr_data.cmd_state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: Set params timed out port = %d, copp = %d\n", __func__, port_index, copp_id); goto err; } if (atomic_read(&rtac_common.apr_err_code)) { pr_err("%s: DSP returned error code = %d, opcode = 0x%x\n", __func__, atomic_read(&rtac_common.apr_err_code), opcode); goto err; } if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); goto err; } if (copy_to_user(buf, (void *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, bytes_returned)) { pr_err("%s: Could not copy buffer to user,size = %d\n", __func__, bytes_returned); goto err; } } else { bytes_returned = data_size; } err: mutex_unlock(&rtac_adm_apr_mutex); done: return bytes_returned; }
u32 send_voice_apr(u32 mode, void *buf, u32 opcode) { s32 result; u32 user_buf_size = 0; u32 bytes_returned = 0; u32 payload_size; u32 dest_port; u32 data_size = 0; struct apr_hdr voice_params; pr_debug("%s\n", __func__); if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) { result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", __func__); goto done; } } if (rtac_cal[VOICE_RTAC_CAL].map_data.map_handle == 0) { result = rtac_map_cal_buffer(VOICE_RTAC_CAL); if (result < 0) { pr_err("%s: map buffer failed!", __func__); goto done; } } if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { pr_err("%s: Copy from user failed! buf = 0x%x\n", __func__, (unsigned int)buf); goto done; } if (user_buf_size <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, user_buf_size); goto done; } if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy port id from user buffer\n", __func__); goto done; } if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) { pr_err("%s: Invalid Mode for APR, mode = %d\n", __func__, mode); goto done; } mutex_lock(&rtac_voice_apr_mutex); if (rtac_voice_apr_data[mode].apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } if (opcode == VOICE_CMD_SET_PARAM) { data_size = payload_size - 4 * sizeof(u32); if (data_size > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) { pr_err("%s: Invalid data size = %d\n", __func__, data_size); goto done; } payload_size = 4 * sizeof(u32); if (copy_from_user((void *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } rtac_voice_buffer[8] = data_size; } else { if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto done; } if (copy_from_user(rtac_voice_buffer + sizeof(voice_params)/sizeof(u32), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } } voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); voice_params.src_svc = 0; voice_params.src_domain = APR_DOMAIN_APPS; voice_params.src_port = get_voice_index(mode, dest_port); voice_params.dest_svc = 0; voice_params.dest_domain = APR_DOMAIN_MODEM; voice_params.dest_port = (u16)dest_port; voice_params.token = 0; voice_params.opcode = opcode; rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle; rtac_voice_buffer[6] = rtac_cal[VOICE_RTAC_CAL].cal_data.paddr; rtac_voice_buffer[7] = 0; memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%x\n", __func__, opcode, rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle, (uint32_t *)rtac_voice_buffer); if (result < 0) { pr_err("%s: apr_send_pkt failed opcode = %x\n", __func__, opcode); goto err; } result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait, (atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: apr_send_pkt timed out opcode = %x\n", __func__, opcode); goto err; } if (atomic_read(&rtac_common.apr_err_code)) { pr_err("%s: DSP returned error code = %d, opcode = 0x%x\n", __func__, atomic_read(&rtac_common.apr_err_code), opcode); goto err; } if (opcode == VOICE_CMD_GET_PARAM) { bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); goto err; } if (copy_to_user(buf, (void *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, bytes_returned)) { pr_err("%s: Could not copy buffer to user, size = %d\n", __func__, bytes_returned); goto err; } } else { bytes_returned = data_size; } err: mutex_unlock(&rtac_voice_apr_mutex); done: return bytes_returned; }
u32 send_rtac_asm_apr(void *buf, u32 opcode) { s32 result; u32 user_buf_size = 0; u32 bytes_returned = 0; u32 session_id = 0; u32 payload_size; u32 data_size = 0; struct apr_hdr asm_params; pr_debug("%s\n", __func__); if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) { result = rtac_allocate_cal_buffer(ASM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", __func__); goto done; } } if (rtac_cal[ASM_RTAC_CAL].map_data.map_handle == 0) { result = rtac_map_cal_buffer(ASM_RTAC_CAL); if (result < 0) { pr_err("%s: map buffer failed!", __func__); goto done; } } if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { pr_err("%s: Copy from user failed! buf = 0x%x\n", __func__, (unsigned int)buf); goto done; } if (user_buf_size <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, user_buf_size); goto done; } if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy session id from user buffer\n", __func__); goto done; } if (session_id >= (SESSION_MAX + 1)) { pr_err("%s: Invalid Session = %d\n", __func__, session_id); goto done; } mutex_lock(&rtac_asm_apr_mutex); if (rtac_asm_apr_data[session_id].apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) { data_size = payload_size - 4 * sizeof(u32); if (data_size > rtac_cal[ASM_RTAC_CAL].map_data.map_size) { pr_err("%s: Invalid data size = %d\n", __func__, data_size); goto err; } payload_size = 4 * sizeof(u32); if (copy_from_user((void *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } rtac_asm_buffer[8] = data_size; } else { if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto err; } if (copy_from_user(rtac_asm_buffer + sizeof(asm_params)/sizeof(u32), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } } asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); asm_params.src_svc = q6asm_get_apr_service_id(session_id); if (asm_params.src_svc == -EINVAL) { pr_err("%s: Could not get service id form session %d", __func__, session_id); goto err; } asm_params.src_domain = APR_DOMAIN_APPS; asm_params.src_port = (session_id << 8) | 0x0001; asm_params.dest_svc = APR_SVC_ASM; asm_params.dest_domain = APR_DOMAIN_ADSP; asm_params.dest_port = (session_id << 8) | 0x0001; asm_params.token = session_id; asm_params.opcode = opcode; rtac_asm_buffer[5] = rtac_cal[ASM_RTAC_CAL].cal_data.paddr; rtac_asm_buffer[6] = 0; rtac_asm_buffer[7] = rtac_cal[ASM_RTAC_CAL].map_data.map_handle; memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params)); atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1); pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%x\n", __func__, opcode, rtac_cal[ASM_RTAC_CAL].cal_data.paddr); result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle, (uint32_t *)rtac_asm_buffer); if (result < 0) { pr_err("%s: Set params failed session = %d\n", __func__, session_id); goto err; } result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait, (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0), 5 * HZ); if (!result) { pr_err("%s: Set params timed out session = %d\n", __func__, session_id); goto err; } if (atomic_read(&rtac_common.apr_err_code)) { pr_err("%s: DSP returned error code = %d, opcode = 0x%x\n", __func__, atomic_read(&rtac_common.apr_err_code), opcode); goto err; } if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) { bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); goto err; } if (copy_to_user(buf, (void *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, bytes_returned)) { pr_err("%s: Could not copy buffer to user,size = %d\n", __func__, bytes_returned); goto err; } } else { bytes_returned = data_size; } err: mutex_unlock(&rtac_asm_apr_mutex); done: return bytes_returned; }
u32 send_voice_apr(u32 mode, void *buf, u32 opcode) { s32 result; u32 count = 0; u32 bytes_returned = 0; u32 payload_size; u32 dest_port; struct apr_hdr voice_params; pr_debug("%s\n", __func__); if (copy_from_user(&count, (void *)buf, sizeof(count))) { pr_err("%s: Copy to user failed! buf = 0x%x\n", __func__, (unsigned int)buf); result = -EFAULT; goto done; } if (count <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, count); goto done; } if (copy_from_user(&payload_size, buf + sizeof(payload_size), sizeof(payload_size))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto done; } if (copy_from_user(&dest_port, buf + 2 * sizeof(dest_port), sizeof(dest_port))) { pr_err("%s: Could not copy port id from user buffer\n", __func__); goto done; } if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) { pr_err("%s: Invalid Mode for APR, mode = %d\n", __func__, mode); goto done; } mutex_lock(&rtac_voice_apr_mutex); if (rtac_voice_apr_data[mode].apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } rtac_voice_user_buf_size = count; if (copy_from_user(rtac_voice_buffer + sizeof(voice_params), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); voice_params.src_svc = 0; voice_params.src_domain = APR_DOMAIN_APPS; voice_params.src_port = voice_session_id[ get_voice_index(mode, dest_port)]; voice_params.dest_svc = 0; voice_params.dest_domain = APR_DOMAIN_MODEM; voice_params.dest_port = (u16)dest_port; voice_params.token = 0; voice_params.opcode = opcode; memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); pr_debug("%s: Sending RTAC command size = %d, opcode = %x\n", __func__, voice_params.pkt_size, opcode); result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle, (uint32_t *)rtac_voice_buffer); if (result < 0) { pr_err("%s: apr_send_pkt failed opcode = %x\n", __func__, opcode); goto err; } result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait, (atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0), msecs_to_jiffies(TIMEOUT_MS)); mutex_unlock(&rtac_voice_apr_mutex); if (!result) { pr_err("%s: apr_send_pkt timed out opcode = %x\n", __func__, opcode); goto done; } if (rtac_voice_payload_size != 0) { if (copy_to_user(buf, rtac_voice_buffer, rtac_voice_payload_size + sizeof(u32))) { pr_err("%s: Could not copy buffer to user,size = %d\n", __func__, payload_size); goto done; } } if (opcode == VOICE_CMD_GET_PARAM) bytes_returned = rtac_voice_payload_size; else bytes_returned = payload_size; done: return bytes_returned; err: mutex_unlock(&rtac_voice_apr_mutex); return bytes_returned; }
u32 send_rtac_asm_apr(void *buf, u32 opcode) { s32 result; u32 count = 0; u32 bytes_returned = 0; u32 session_id = 0; u32 payload_size; struct apr_hdr asm_params; pr_debug("%s\n", __func__); if (copy_from_user(&count, (void *)buf, sizeof(count))) { pr_err("%s: Copy to user failed! buf = 0x%x\n", __func__, (unsigned int)buf); result = -EFAULT; goto done; } if (count <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, count); goto done; } if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto done; } if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy session id from user buffer\n", __func__); goto done; } if (session_id > (SESSION_MAX + 1)) { pr_err("%s: Invalid Session = %d\n", __func__, session_id); goto done; } mutex_lock(&rtac_asm_apr_mutex); if (session_id < SESSION_MAX+1) { if (rtac_asm_apr_data[session_id].apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } } rtac_asm_user_buf_size = count; if (copy_from_user(rtac_asm_buffer + sizeof(asm_params), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); asm_params.src_svc = q6asm_get_apr_service_id(session_id); asm_params.src_domain = APR_DOMAIN_APPS; asm_params.src_port = (session_id << 8) | 0x0001; asm_params.dest_svc = APR_SVC_ASM; asm_params.dest_domain = APR_DOMAIN_ADSP; asm_params.dest_port = (session_id << 8) | 0x0001; asm_params.token = session_id; asm_params.opcode = opcode; memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params)); if (session_id < SESSION_MAX+1) atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1); pr_debug("%s: Sending RTAC command size = %d, session_id=%d\n", __func__, asm_params.pkt_size, session_id); result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle, (uint32_t *)rtac_asm_buffer); if (result < 0) { pr_err("%s: Set params failed session = %d\n", __func__, session_id); goto err; } result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait, (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0), 5 * HZ); mutex_unlock(&rtac_asm_apr_mutex); if (!result) { pr_err("%s: Set params timed out session = %d\n", __func__, session_id); goto done; } if (rtac_asm_payload_size != 0) { if (copy_to_user(buf, rtac_asm_buffer, rtac_asm_payload_size + sizeof(u32))) { pr_err("%s: Could not copy buffer to user,size = %d\n", __func__, payload_size); goto done; } } if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS) bytes_returned = rtac_asm_payload_size; else bytes_returned = payload_size; done: return bytes_returned; err: mutex_unlock(&rtac_asm_apr_mutex); return bytes_returned; }
u32 send_adm_apr(void *buf, u32 opcode) { s32 result; u32 count = 0; u32 bytes_returned = 0; u32 port_index = 0; u32 copp_id; u32 payload_size; struct apr_hdr adm_params; pr_debug("%s\n", __func__); if (copy_from_user(&count, (void *)buf, sizeof(count))) { pr_err("%s: Copy to user failed! buf = 0x%x\n", __func__, (unsigned int)buf); result = -EFAULT; goto done; } if (count <= 0) { pr_err("%s: Invalid buffer size = %d\n", __func__, count); goto done; } if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy payload size from user buffer\n", __func__); goto done; } if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); goto done; } if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) { pr_err("%s: Could not copy port id from user buffer\n", __func__); goto done; } for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) { if (adm_get_copp_id(port_index) == copp_id) break; } if (port_index >= AFE_MAX_PORTS) { pr_err("%s: Could not find port index for copp = %d\n", __func__, copp_id); goto done; } mutex_lock(&rtac_adm_apr_mutex); if (rtac_adm_apr_data.apr_handle == NULL) { pr_err("%s: APR not initialized\n", __func__); goto err; } rtac_adm_user_buf_size = count; if (copy_from_user(rtac_adm_buffer + sizeof(adm_params), buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); goto err; } adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, payload_size); adm_params.src_svc = APR_SVC_ADM; adm_params.src_domain = APR_DOMAIN_APPS; adm_params.src_port = copp_id; adm_params.dest_svc = APR_SVC_ADM; adm_params.dest_domain = APR_DOMAIN_ADSP; adm_params.dest_port = copp_id; adm_params.token = copp_id; adm_params.opcode = opcode; memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params)); atomic_set(&rtac_adm_apr_data.cmd_state, 1); pr_debug("%s: Sending RTAC command size = %d\n", __func__, adm_params.pkt_size); result = apr_send_pkt(rtac_adm_apr_data.apr_handle, (uint32_t *)rtac_adm_buffer); if (result < 0) { pr_err("%s: Set params failed port = %d, copp = %d\n", __func__, port_index, copp_id); goto err; } result = wait_event_timeout(rtac_adm_apr_data.cmd_wait, (atomic_read(&rtac_adm_apr_data.cmd_state) == 0), msecs_to_jiffies(TIMEOUT_MS)); mutex_unlock(&rtac_adm_apr_mutex); if (!result) { pr_err("%s: Set params timed out port = %d, copp = %d\n", __func__, port_index, copp_id); goto done; } if (rtac_adm_payload_size != 0) { if (copy_to_user(buf, rtac_adm_buffer, rtac_adm_payload_size + sizeof(u32))) { pr_err("%s: Could not copy buffer to user, size = %d\n", __func__, payload_size); goto done; } } if (opcode == ADM_CMD_GET_PARAMS) bytes_returned = rtac_adm_payload_size; else bytes_returned = payload_size; done: return bytes_returned; err: mutex_unlock(&rtac_adm_apr_mutex); return bytes_returned; }
void send_adm_custom_topology(int port_id) { struct acdb_cal_block cal_block; struct cmd_set_topologies adm_top; int index; int result; int size = 4096; get_adm_custom_topology(&cal_block); if (cal_block.cal_size == 0) { pr_debug("%s: no cal to send addr= 0x%x\n", __func__, cal_block.cal_paddr); goto done; } index = afe_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: invalid port idx %d portid %#x\n", __func__, index, port_id); goto done; } if (this_adm.set_custom_topology) { /* specific index 4 for adm topology memory */ atomic_set(&this_adm.mem_map_cal_index, ADM_CUSTOM_TOP_CAL); /* Only call this once */ this_adm.set_custom_topology = 0; result = adm_memory_map_regions(GLOBAL_CFG, &cal_block.cal_paddr, 0, &size, 1); if (result < 0) { pr_err("%s: mmap did not work! addr = 0x%x, size = %d\n", __func__, cal_block.cal_paddr, cal_block.cal_size); goto done; } } adm_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(20), APR_PKT_VER); adm_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(adm_top)); adm_top.hdr.src_svc = APR_SVC_ADM; adm_top.hdr.src_domain = APR_DOMAIN_APPS; adm_top.hdr.src_port = port_id; adm_top.hdr.dest_svc = APR_SVC_ADM; adm_top.hdr.dest_domain = APR_DOMAIN_ADSP; adm_top.hdr.dest_port = atomic_read(&this_adm.copp_id[index]); adm_top.hdr.token = port_id; adm_top.hdr.opcode = ADM_CMD_ADD_TOPOLOGIES; adm_top.payload_addr_lsw = cal_block.cal_paddr; adm_top.payload_addr_msw = 0; adm_top.mem_map_handle = atomic_read(&this_adm.mem_map_cal_handles[ADM_CUSTOM_TOP_CAL]); adm_top.payload_size = cal_block.cal_size; atomic_set(&this_adm.copp_stat[index], 0); pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%x, size = %d\n", __func__, adm_top.payload_addr_lsw, adm_top.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_top); if (result < 0) { pr_err("%s: Set topologies failed port = 0x%x payload = 0x%x\n", __func__, port_id, cal_block.cal_paddr); goto done; } /* Wait for the callback */ result = wait_event_timeout(this_adm.wait[index], atomic_read(&this_adm.copp_stat[index]), msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: Set topologies timed out port = 0x%x, payload = 0x%x\n", __func__, port_id, cal_block.cal_paddr); goto done; } done: return; }