/* This computes linear mapping device volume. */ s32 qdsp6_volume_mapping(u32 device_id, s32 percentage) { s32 max_gain = 0; s32 min_gain = 0; u32 tmp_device_id = qdsp6_volume_device_id_mapping(device_id); if (tmp_device_id == INT_CAD_HW_DEVICE_ID_INVALID) { pr_err("%s: invalid device\n", __func__); return 0xFFFFFFFF; } if (percentage < 0 || percentage > 100) { pr_err("%s: invalid percentage\n", __func__); return 0xFFFFFFFF; } max_gain = qdsp6_volume_cache_tbl[device_id].max_gain; min_gain = qdsp6_volume_cache_tbl[device_id].min_gain; return min_gain + (((max_gain - min_gain) * percentage) / 100); }
s32 qdsp6_volume_ioctl(s32 session_id, u32 cmd_code, void *cmd_buf, u32 cmd_len) { enum cad_int_device_id device_id = INT_CAD_HW_DEVICE_ID_INVALID; struct cad_filter_struct *vol_flt = NULL; struct cad_flt_cfg_dev_vol *dev_vol_buf = NULL; struct cad_flt_cfg_strm_vol *stream_vol_buf = NULL; struct cad_flt_cfg_dev_mute *dev_mute_buf = NULL; struct cad_flt_cfg_strm_mute *stream_mute_buf = NULL; struct adsp_audio_set_device_volume *q6_set_dev_vol = NULL; struct adsp_audio_set_stream_volume *q6_set_strm_vol = NULL; struct adsp_audio_set_device_mute *q6_set_dev_mute = NULL; struct adsp_audio_set_stream_mute *q6_set_strm_mute = NULL; int rc = CAD_RES_SUCCESS; s32 device_volume = 0; s32 rpc_cmd_code = 0; u8 *rpc_cmd_buf = NULL; u32 rpc_cmd_buf_len = 0; struct adsp_audio_event event_payload; struct adsp_audio_set_device_volume *q6_set_dev_vol1 = NULL; struct adsp_audio_set_stream_volume *q6_set_strm_vol1 = NULL; struct adsp_audio_set_device_mute *q6_set_dev_mute1 = NULL; struct adsp_audio_set_stream_mute *q6_set_strm_mute1 = NULL; s32 rpc_cmd_code1 = 0; u8 *rpc_cmd_buf1 = NULL; u32 rpc_cmd_buf_len1 = 0; struct adsp_audio_event event_payload1; memset(&event_payload, 0, sizeof(struct adsp_audio_event)); memset(&event_payload1, 0, sizeof(struct adsp_audio_event)); /* Ensure session_id is valid. */ if (session_id < 1 || session_id >= CAD_MAX_SESSION) return CAD_RES_FAILURE; /* Not handle request other than the following two. */ /* Just silently succeed unrecognized IOCTLs. */ if (cmd_code != CAD_IOCTL_CMD_SET_STREAM_FILTER_CONFIG && cmd_code != CAD_IOCTL_CMD_SET_DEVICE_FILTER_CONFIG && cmd_code != CAD_IOCTL_CMD_STREAM_START) return CAD_RES_SUCCESS; /* Defensive programming. */ if ((cmd_buf == NULL || cmd_len != sizeof(struct cad_filter_struct)) && cmd_code != CAD_IOCTL_CMD_STREAM_START) { D("%s: invalid params\n", __func__); return CAD_RES_FAILURE; } /* Do not handle stream_start for device control session. */ if (cmd_code == CAD_IOCTL_CMD_STREAM_START && ardsession[session_id]->session_type == DEVICE_CTRL_TYPE) { D("%s: not handling for device control type\n", __func__); return CAD_RES_SUCCESS; } /* Handle stream start. */ if (cmd_code == CAD_IOCTL_CMD_STREAM_START) { if (ardsession[session_id]->sess_open_info->cad_stream.app_type == CAD_STREAM_APP_VOICE) { D("%s: Do not handle voice session.\n", __func__); return CAD_RES_SUCCESS; } q6_set_strm_mute1 = kmalloc( sizeof(struct adsp_audio_set_stream_mute), GFP_KERNEL); if (!q6_set_strm_mute1) return CAD_RES_FAILURE; memset(q6_set_strm_mute1, 0, sizeof(struct adsp_audio_set_stream_mute)); /* 2. Assign values to command buffer. */ if (stream_volume_cache == CAD_STREAM_MIN_GAIN) q6_set_strm_mute1->mute = 1; else q6_set_strm_mute1->mute = 0; rpc_cmd_buf1 = (u8 *)q6_set_strm_mute1; rpc_cmd_buf_len1 = sizeof(struct adsp_audio_set_stream_mute); rpc_cmd_code1 = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE; /* 3. Send command to Q6. */ if (ardsession[session_id]->sess_open_info->cad_open.op_code == CAD_OPEN_OP_WRITE) { /* Only issue stream commands for Rx path. */ rc = cad_rpc_ioctl( session_id, 1, rpc_cmd_code1, rpc_cmd_buf1, rpc_cmd_buf_len1, &event_payload1); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } } if (stream_volume_cache != CAD_STREAM_MIN_GAIN) { q6_set_strm_vol1 = kmalloc( sizeof(struct adsp_audio_set_stream_volume), GFP_KERNEL); if (!q6_set_strm_vol1) return CAD_RES_FAILURE; /* 2. Assign values to command buffer. */ q6_set_strm_vol1->volume = stream_volume_cache; rpc_cmd_buf1 = (u8 *)q6_set_strm_vol1; rpc_cmd_buf_len1 = sizeof(struct adsp_audio_set_stream_volume); rpc_cmd_code1 = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL; if (ardsession[session_id]->sess_open_info-> cad_open.op_code == CAD_OPEN_OP_WRITE) { /* Only issue stream commands for Rx path. */ rc = cad_rpc_ioctl( session_id, 1, rpc_cmd_code1, rpc_cmd_buf1, rpc_cmd_buf_len1, &event_payload1); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } } } q6_set_dev_mute1 = kmalloc( sizeof(struct adsp_audio_set_device_mute), GFP_KERNEL); if (!q6_set_dev_mute1) { rc = CAD_RES_FAILURE; goto done; } memset(q6_set_dev_mute1, 0, sizeof(struct adsp_audio_set_device_mute)); /* Send Device Volume during stream start. */ if (ardsession[session_id]->sess_open_info->cad_open.op_code == CAD_OPEN_OP_READ) { device_id = ard_state.def_tx_device; if (device_id == INT_CAD_HW_DEVICE_ID_INVALID) { rc = CAD_RES_FAILURE; pr_err("%s: invalid device id %d\n", __func__, ard_state.def_tx_device); goto done; } q6_set_dev_mute1->path = CAD_TX_DEVICE; } else if (ardsession[session_id]->sess_open_info-> cad_open.op_code == CAD_OPEN_OP_WRITE) { device_id = ard_state.def_rx_device; if (device_id == INT_CAD_HW_DEVICE_ID_INVALID) { rc = CAD_RES_FAILURE; pr_err("%s: invalid device id %d\n", __func__, ard_state.def_rx_device); goto done; } q6_set_dev_mute1->path = CAD_RX_DEVICE; } /* 2. Assign values to command buffer. */ q6_set_dev_mute1->device = q6_device_id_mapping(device_id); device_id = qdsp6_volume_device_id_mapping(device_id); if (qdsp6_volume_cache_tbl[device_id].mute == 1) q6_set_dev_mute1->mute = 1; else q6_set_dev_mute1->mute = 0; rpc_cmd_buf1 = (u8 *)q6_set_dev_mute1; rpc_cmd_buf_len1 = sizeof(struct adsp_audio_set_device_mute); rpc_cmd_code1 = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; rc = cad_rpc_ioctl( audio_ctrl_handle, 1, rpc_cmd_code1, rpc_cmd_buf1, rpc_cmd_buf_len1, &event_payload1); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } if (qdsp6_volume_cache_tbl[device_id].mute == 0) { q6_set_dev_vol1 = kmalloc( sizeof(struct adsp_audio_set_device_volume), GFP_KERNEL); if (!q6_set_dev_vol1) return CAD_RES_FAILURE; memset(q6_set_dev_vol1, 0, sizeof(struct adsp_audio_set_device_volume)); if (qdsp6_volume_cache_tbl[device_id]. valid_current_volume == 1) { q6_set_dev_vol1->volume = qdsp6_volume_cache_tbl[device_id]. current_volume; D("%s: current_volume is %d\n", __func__, q6_set_dev_vol1->volume); } else { q6_set_dev_vol1->volume = qdsp6_volume_cache_tbl[device_id]. default_volume; D("%s: current_volume is %d (default)\n", __func__, q6_set_dev_vol1->volume); } q6_set_dev_vol1->path = q6_set_dev_mute1->path; q6_set_dev_vol1->device = q6_set_dev_mute1->device; rpc_cmd_buf1 = (u8 *)q6_set_dev_vol1; rpc_cmd_buf_len1 = sizeof(struct adsp_audio_set_device_volume); rpc_cmd_code1 = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; rc = cad_rpc_ioctl( audio_ctrl_handle, 1, rpc_cmd_code1, rpc_cmd_buf1, rpc_cmd_buf_len1, &event_payload1); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } } rc = CAD_RES_SUCCESS; goto done; } if ((cmd_buf == NULL) || (cmd_len != sizeof(struct cad_filter_struct))) { pr_err("%s: invalid ioctl params\n", __func__); rc = CAD_RES_FAILURE; goto done; } vol_flt = (struct cad_filter_struct *)cmd_buf; if (vol_flt->filter_type != CAD_DEVICE_FILTER_TYPE_VOL) { D("%s: not volume filter type\n", __func__); rc = CAD_RES_SUCCESS; goto done; } /* Find the appropriate command type. */ if (cmd_code == CAD_IOCTL_CMD_SET_DEVICE_FILTER_CONFIG && vol_flt->cmd == CAD_FILTER_CONFIG_DEVICE_VOLUME && vol_flt->format_block_len == sizeof(struct cad_flt_cfg_dev_vol)) dev_vol_buf = (struct cad_flt_cfg_dev_vol *) vol_flt->format_block; else if (CAD_IOCTL_CMD_SET_DEVICE_FILTER_CONFIG == cmd_code && vol_flt->cmd == CAD_FILTER_CONFIG_DEVICE_MUTE && vol_flt->format_block_len == sizeof(struct cad_flt_cfg_dev_mute)) dev_mute_buf = (struct cad_flt_cfg_dev_mute *) vol_flt->format_block; /* stream session */ else if (cmd_code == CAD_IOCTL_CMD_SET_STREAM_FILTER_CONFIG && vol_flt->cmd == CAD_FILTER_CONFIG_STREAM_VOLUME && vol_flt->format_block_len == sizeof(struct cad_flt_cfg_strm_vol)) stream_vol_buf = (struct cad_flt_cfg_strm_vol *)( vol_flt->format_block); else if (cmd_code == CAD_IOCTL_CMD_SET_STREAM_FILTER_CONFIG && vol_flt->cmd == CAD_FILTER_CONFIG_STREAM_MUTE && vol_flt->format_block_len == sizeof(struct cad_flt_cfg_strm_mute)) stream_mute_buf = (struct cad_flt_cfg_strm_mute *) (vol_flt->format_block); else { pr_err("CAD:VOL: Error: wrong type id.\n"); return CAD_RES_FAILURE; } /* Handle volume control command. */ switch (vol_flt->cmd) { case CAD_FILTER_CONFIG_DEVICE_VOLUME: D("CAD:VOL: Device Volume\n"); if (dev_vol_buf->device_id == 0 || dev_vol_buf->device_id > CAD_HW_DEVICE_ID_MAX_NUM) { pr_err("%s: invalid device id %d.\n", __func__, dev_vol_buf->device_id); rc = CAD_RES_FAILURE; goto done; } if (dev_vol_buf->device_id == CAD_HW_DEVICE_ID_DEFAULT_TX) dev_vol_buf->device_id = ard_state.def_tx_device; else if (dev_vol_buf->device_id == CAD_HW_DEVICE_ID_DEFAULT_RX) dev_vol_buf->device_id = ard_state.def_rx_device; else ; /* Do nothing. */ if (ardsession[session_id]->sess_open_info->cad_open.op_code == CAD_OPEN_OP_READ) { if (dev_vol_buf->device_id != ard_state.def_tx_device) { pr_err("%s: %d is not current device id.\n", __func__, dev_vol_buf->device_id); rc = CAD_RES_FAILURE; goto done; } } else if (ardsession[session_id]->sess_open_info-> cad_open.op_code == CAD_OPEN_OP_WRITE) { if (dev_vol_buf->device_id != ard_state.def_rx_device) { pr_err("%s: %d is not current device id.\n", __func__, dev_vol_buf->device_id); rc = CAD_RES_FAILURE; goto done; } } /* For volume != 0%: send unmute command. */ if (dev_vol_buf->volume != 0) { /* Construct QDSP6 device mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_dev_mute = kmalloc( sizeof(struct adsp_audio_set_device_mute), GFP_KERNEL); if (!q6_set_dev_mute) return CAD_RES_FAILURE; memset(q6_set_dev_mute, 0, sizeof(struct adsp_audio_set_device_mute)); /* 2. Assign values to command buffer. */ q6_set_dev_mute->device = q6_device_id_mapping(dev_vol_buf->device_id); q6_set_dev_mute->path = dev_vol_buf->path; q6_set_dev_mute->mute = 0; rpc_cmd_buf = (u8 *)q6_set_dev_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_device_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; /* 3. Send command to Q6. */ rc = cad_rpc_ioctl( session_id, 1, rpc_cmd_code, rpc_cmd_buf, rpc_cmd_buf_len, &event_payload); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } } /* Map the device volume to QDSP6. */ device_volume = qdsp6_volume_mapping( dev_vol_buf->device_id, dev_vol_buf->volume); /* Cache the device volume. */ device_id = qdsp6_volume_device_id_mapping( dev_vol_buf->device_id); qdsp6_volume_cache_tbl[device_id] .current_volume = device_volume; qdsp6_volume_cache_tbl[device_id] .valid_current_volume = 1; qdsp6_volume_cache_tbl[device_id] .mute = 0; /* Construct QDSP6 device volume command: */ /* 1. Allocate memory for command buffer. */ q6_set_dev_vol = kmalloc( sizeof(struct cad_flt_cfg_dev_vol), GFP_KERNEL); if (!q6_set_dev_vol) return CAD_RES_FAILURE; memset(q6_set_dev_vol, 0, sizeof(struct adsp_audio_set_device_volume)); /* 2. Assign values to command buffer. */ q6_set_dev_vol->device = q6_device_id_mapping(dev_vol_buf->device_id); q6_set_dev_vol->path = dev_vol_buf->path; q6_set_dev_vol->volume = device_volume; rpc_cmd_buf = (u8 *)q6_set_dev_vol; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_device_volume); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; /* HACK: for volume = 0%: send mute command instead. */ if (dev_vol_buf->volume == 0) { /* Construct QDSP6 device mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_dev_mute = kmalloc( sizeof(struct adsp_audio_set_device_mute), GFP_KERNEL); if (!q6_set_dev_mute) return CAD_RES_FAILURE; memset(q6_set_dev_mute, 0, sizeof(struct adsp_audio_set_device_mute)); /* 2. Assign values to command buffer. */ q6_set_dev_mute->device = q6_set_dev_vol->device; q6_set_dev_mute->path = q6_set_dev_vol->path; q6_set_dev_mute->mute = 1; /* mute */ rpc_cmd_buf = (u8 *)q6_set_dev_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_device_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; } break; case CAD_FILTER_CONFIG_DEVICE_MUTE: D("CAD:VOL: Device Mute\n"); device_id = qdsp6_volume_device_id_mapping( dev_mute_buf->device_id); qdsp6_volume_cache_tbl[device_id].mute = dev_mute_buf->mute; /* Construct QDSP6 device mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_dev_mute = kmalloc( sizeof(struct adsp_audio_set_device_mute), GFP_KERNEL); if (!q6_set_dev_mute) return CAD_RES_FAILURE; memset(q6_set_dev_mute, 0, sizeof(struct adsp_audio_set_device_mute)); /* 2. Assign values to command buffer. */ q6_set_dev_mute->device = q6_device_id_mapping(dev_mute_buf->device_id); q6_set_dev_mute->path = dev_mute_buf->path; q6_set_dev_mute->mute = dev_mute_buf->mute; rpc_cmd_buf = (u8 *)q6_set_dev_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_device_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; break; case CAD_FILTER_CONFIG_STREAM_VOLUME: D("CAD:VOL: Stream Volume\n"); stream_volume_cache = stream_vol_buf->volume; if (ardsession[session_id]->active != ARD_TRUE) { rc = CAD_RES_SUCCESS; D("not active session, cached stream volume.\n"); goto done; } /* For volume != min: send unmute command. */ if (stream_vol_buf->volume != CAD_STREAM_MIN_GAIN) { /* Construct QDSP6 stream mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_strm_mute = kmalloc( sizeof(struct adsp_audio_set_stream_mute), GFP_KERNEL); if (!q6_set_strm_mute) return CAD_RES_FAILURE; /* 2. Assign values to command buffer. */ q6_set_strm_mute->mute = 0; rpc_cmd_buf = (u8 *)q6_set_strm_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_stream_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE; /* 3. Send command to Q6. */ rc = cad_rpc_ioctl(session_id, 1, rpc_cmd_code, rpc_cmd_buf, rpc_cmd_buf_len, &event_payload); if (rc != CAD_RES_SUCCESS) { pr_err("%s: cad_rpc_ioctl() failure\n", __func__); return rc; } } /* Construct QDSP6 stream volume command. */ /* 1. Allocate memory for command buffer. */ q6_set_strm_vol = kmalloc( sizeof(struct adsp_audio_set_stream_volume), GFP_KERNEL); if (!q6_set_strm_vol) return CAD_RES_FAILURE; /* 2. Assign values to command buffer. */ q6_set_strm_vol->volume = stream_vol_buf->volume; rpc_cmd_buf = (u8 *)q6_set_strm_vol; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_stream_volume); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL; /* For volume = min: send mute command instead. */ if (stream_vol_buf->volume == CAD_STREAM_MIN_GAIN) { /* Construct QDSP6 stream mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_strm_mute = kmalloc( sizeof( struct adsp_audio_set_stream_mute), GFP_KERNEL); if (!q6_set_strm_mute) return CAD_RES_FAILURE; /* 2. Assign values to command buffer. */ q6_set_strm_mute->mute = 1; rpc_cmd_buf = (u8 *)q6_set_strm_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_stream_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE; } break; case CAD_FILTER_CONFIG_STREAM_MUTE: D("CAD:VOL: Stream Mute\n"); /* Construct QDSP6 stream mute command. */ /* 1. Allocate memory for command buffer. */ q6_set_strm_mute = kmalloc( sizeof( struct adsp_audio_set_stream_mute), GFP_KERNEL); if (!q6_set_strm_mute) return CAD_RES_FAILURE; /* 2. Assign values to command buffer. */ q6_set_strm_mute->mute = stream_mute_buf->mute; rpc_cmd_buf = (u8 *)q6_set_strm_mute; rpc_cmd_buf_len = sizeof(struct adsp_audio_set_stream_mute); rpc_cmd_code = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE; break; default: /* Just return without error. */ return CAD_RES_SUCCESS; } /* Always send device/stream volume command to Q6 for now. */ rc = cad_rpc_ioctl( session_id, 1, rpc_cmd_code, rpc_cmd_buf, rpc_cmd_buf_len, &event_payload); if (rc != CAD_RES_SUCCESS) pr_err("%s: cad_rpc_ioctl() failure\n", __func__); done: D("%s: ioctl() processed.\n", __func__); kfree(q6_set_dev_vol); kfree(q6_set_strm_vol); kfree(q6_set_dev_mute); kfree(q6_set_strm_mute); kfree(q6_set_dev_vol1); kfree(q6_set_strm_vol1); kfree(q6_set_dev_mute1); kfree(q6_set_strm_mute1); return rc; }
int cad_apply_cached_vol_on_dev(u32 device_id) { struct adsp_audio_set_dev_volume_command *q6_set_dev_vol; struct adsp_audio_set_dev_mute_command *q6_set_dev_mute; union adsp_audio_event event_payload; u32 path = CAD_RX_DEVICE; u8 *rpc_cmd_buf = NULL; u32 rpc_cmd_buf_len = 0; int int_dev_id = qdsp6_volume_device_id_mapping(device_id); s32 rc = CAD_RES_SUCCESS; D("%s: device_id = %d\n", __func__, device_id); if (int_dev_id == INT_CAD_HW_DEVICE_ID_INVALID) { pr_err("%s: bad device_id (%d)\n", __func__, device_id); return CAD_RES_FAILURE; } if (qdsp6_volume_cache_tbl[int_dev_id].valid_current_volume == 1) { q6_set_dev_vol = kmalloc(sizeof(*q6_set_dev_vol), GFP_KERNEL); if (!q6_set_dev_vol) return CAD_RES_FAILURE; memset(q6_set_dev_vol, 0, sizeof(*q6_set_dev_vol)); q6_set_dev_mute = kmalloc( sizeof(*q6_set_dev_mute), GFP_KERNEL); if (!q6_set_dev_mute) { kfree(q6_set_dev_vol); return CAD_RES_FAILURE; } memset(q6_set_dev_mute, 0, sizeof(*q6_set_dev_mute)); if (ardsession[audio_ctrl_handle]->sess_open_info-> cad_open.op_code == CAD_OPEN_OP_READ) path = CAD_TX_DEVICE; else if (ardsession[audio_ctrl_handle]->sess_open_info-> cad_open.op_code == CAD_OPEN_OP_WRITE) path = CAD_RX_DEVICE; q6_set_dev_vol->volume = qdsp6_volume_cache_tbl[int_dev_id].current_volume; q6_set_dev_vol->device_id = q6_device_id_mapping(device_id); q6_set_dev_vol->path = path; q6_set_dev_vol->cmd.op_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; q6_set_dev_vol->cmd.response_type = ADSP_AUDIO_RESPONSE_COMMAND; rpc_cmd_buf = (u8 *)q6_set_dev_vol; rpc_cmd_buf_len = sizeof(*q6_set_dev_vol); rc = cad_rpc_control(audio_ctrl_handle, ardsession[audio_ctrl_handle]->group_id, (void *)rpc_cmd_buf, rpc_cmd_buf_len, &event_payload); if (rc != CAD_RES_SUCCESS) pr_err("%s: cad_rpc_control() failure\n", __func__); if ((qdsp6_volume_cache_tbl[int_dev_id].mute == 1) || (qdsp6_volume_cache_tbl[int_dev_id].current_volume == qdsp6_volume_cache_tbl[int_dev_id].min_gain)) q6_set_dev_mute->mute = 1; else q6_set_dev_mute->mute = 0; q6_set_dev_mute->device_id = q6_device_id_mapping(device_id); q6_set_dev_mute->path = path; rpc_cmd_buf = (u8 *)q6_set_dev_mute; rpc_cmd_buf_len = sizeof(*q6_set_dev_mute); q6_set_dev_mute->cmd.op_code = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; q6_set_dev_mute->cmd.response_type = ADSP_AUDIO_RESPONSE_COMMAND; rc = cad_rpc_control(audio_ctrl_handle, ardsession[audio_ctrl_handle]->group_id, (void *)rpc_cmd_buf, rpc_cmd_buf_len, &event_payload); kfree(q6_set_dev_vol); kfree(q6_set_dev_mute); } return rc; }