void rtac_add_adm_device(u32 port_id, u32 popp_id) { u32 i = 0; pr_debug("%s\n", __func__); mutex_lock(&rtac_adm_mutex); if (rtac_adm_data.num_of_dev == RTAC_MAX_ACTIVE_DEVICES) { pr_err("%s, Can't add anymore RTAC devices!\n", __func__); goto done; } /* Check if device already added */ if (rtac_adm_data.num_of_dev != 0) { for (; i < rtac_adm_data.num_of_dev; i++) { if (rtac_adm_data.device[i].afe_port == port_id) add_popp(i, port_id, popp_id); goto done; } } if (rtac_adm_data.device[i].num_of_popp == RTAC_MAX_ACTIVE_POPP) { pr_err("%s, Max POPP!\n", __func__); goto done; } /* Add device */ rtac_adm_data.num_of_dev++; rtac_adm_data.device[i].afe_port = port_id; rtac_adm_data.device[i].copp = adm_get_copp_id(port_id); rtac_adm_data.device[i].popp[ rtac_adm_data.device[i].num_of_popp++] = popp_id; done: mutex_unlock(&rtac_adm_mutex); return; }
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_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; }