dsp: Update ADM driver to support 32 ch
ADM supports now up to 32 channels. Extend the
ADM Channel map structures from 8 to 32
channels.
Change-Id: I87b3e4cce850af92467b139da9df67fcdafaf0b0
Signed-off-by: Dieter Luecking <dieterl@codeaurora.org>
Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
Signed-off-by: Dhanalakshmi Siddani <dsiddani@codeaurora.org>
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index c313fdc..3877b1b 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -23,6 +23,7 @@
#include <dsp/q6adm-v2.h>
#include <dsp/q6audio-v2.h>
#include <dsp/q6afe-v2.h>
+#include <dsp/q6core.h>
#include <dsp/audio_cal_utils.h>
#include <ipc/apr.h>
#include "adsp_err.h"
@@ -105,24 +106,32 @@
int num_ec_ref_rx_chans;
int ec_ref_rx_bit_width;
int ec_ref_rx_sampling_rate;
+
+ int native_mode;
};
static struct adm_ctl this_adm;
struct adm_multi_ch_map {
bool set_channel_map;
- char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
+ char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
};
#define ADM_MCH_MAP_IDX_PLAYBACK 0
#define ADM_MCH_MAP_IDX_REC 1
static struct adm_multi_ch_map multi_ch_maps[2] = {
- { false,
- {0, 0, 0, 0, 0, 0, 0, 0}
- },
- { false,
- {0, 0, 0, 0, 0, 0, 0, 0}
- }
+ { false,
+ {0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ { false,
+ {0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}
+ }
};
static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS];
@@ -1423,7 +1432,7 @@
}
memcpy(multi_ch_maps[idx].channel_mapping, channel_map,
- PCM_FORMAT_MAX_NUM_CHANNEL);
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
multi_ch_maps[idx].set_channel_map = true;
return 0;
@@ -1454,7 +1463,7 @@
if (multi_ch_maps[idx].set_channel_map) {
memcpy(channel_map, multi_ch_maps[idx].channel_mapping,
- PCM_FORMAT_MAX_NUM_CHANNEL);
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
}
return 0;
@@ -1622,6 +1631,7 @@
case ADM_CMD_DEVICE_OPEN_V5:
case ADM_CMD_DEVICE_CLOSE_V5:
case ADM_CMD_DEVICE_OPEN_V6:
+ case ADM_CMD_DEVICE_OPEN_V8:
pr_debug("%s: Basic callback received, wake up.\n",
__func__);
atomic_set(&this_adm.copp.stat[port_idx]
@@ -1718,8 +1728,10 @@
switch (data->opcode) {
case ADM_CMDRSP_DEVICE_OPEN_V5:
- case ADM_CMDRSP_DEVICE_OPEN_V6: {
- struct adm_cmd_rsp_device_open_v5 *open = NULL;
+ case ADM_CMDRSP_DEVICE_OPEN_V6:
+ case ADM_CMDRSP_DEVICE_OPEN_V8: {
+ struct adm_cmd_rsp_device_open_v5 *open =
+ (struct adm_cmd_rsp_device_open_v5 *)data->payload;
if (data->payload_size <
sizeof(struct adm_cmd_rsp_device_open_v5)) {
@@ -2643,6 +2655,225 @@
return rc;
}
+static int adm_arrange_mch_map_v8(
+ struct adm_device_endpoint_payload *ep_payload,
+ int path,
+ int channel_mode)
+{
+ int rc = 0, idx;
+
+ memset(ep_payload->dev_channel_mapping,
+ 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ switch (path) {
+ case ADM_PATH_PLAYBACK:
+ idx = ADM_MCH_MAP_IDX_PLAYBACK;
+ break;
+ case ADM_PATH_LIVE_REC:
+ case ADM_PATH_NONLIVE_REC:
+ idx = ADM_MCH_MAP_IDX_REC;
+ break;
+ default:
+ goto non_mch_path;
+ };
+
+ if ((ep_payload->dev_num_channel > 2) &&
+ multi_ch_maps[idx].set_channel_map) {
+ memcpy(ep_payload->dev_channel_mapping,
+ multi_ch_maps[idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ } else {
+ if (channel_mode == 1) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
+ } else if (channel_mode == 2) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ } else if (channel_mode == 3) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
+ } else if (channel_mode == 4) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 5) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 6) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 7) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_CS;
+ } else if (channel_mode == 8) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ } else if (channel_mode == 10) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
+ } else if (channel_mode == 12) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
+ } else if (channel_mode == 16) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
+ ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
+ ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
+ ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
+ ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ } else {
+ pr_err("%s: invalid num_chan %d\n", __func__,
+ channel_mode);
+ rc = -EINVAL;
+ goto inval_ch_mod;
+ }
+ }
+
+non_mch_path:
+inval_ch_mod:
+ return rc;
+}
+
+static int adm_arrange_mch_ep2_map_v8(
+ struct adm_device_endpoint_payload *ep_payload,
+ int channel_mode)
+{
+ int rc = 0;
+
+ memset(ep_payload->dev_channel_mapping, 0,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+
+ if (channel_mode == 1) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
+ } else if (channel_mode == 2) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ } else if (channel_mode == 3) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
+ } else if (channel_mode == 4) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 5) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 6) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ } else if (channel_mode == 8) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ } else if (channel_mode == 10) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
+ } else if (channel_mode == 12) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
+ } else if (channel_mode == 16) {
+ ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
+ ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
+ ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
+ ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
+ ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
+ ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
+ ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
+ ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
+ ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
+ ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH;
+ ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS;
+ ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
+ ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
+ ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
+ ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
+ } else {
+ pr_err("%s: invalid num_chan %d\n", __func__,
+ channel_mode);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
/**
* adm_open -
* command to send ADM open
@@ -2665,10 +2896,17 @@
{
struct adm_cmd_device_open_v5 open;
struct adm_cmd_device_open_v6 open_v6;
+ struct adm_cmd_device_open_v8 open_v8;
+ struct adm_device_endpoint_payload ep1_payload;
+ struct adm_device_endpoint_payload ep2_payload;
+ int ep1_payload_size = 0;
+ int ep2_payload_size = 0;
int ret = 0;
int port_idx, flags;
int copp_idx = -1;
int tmp_port = q6audio_get_port_id(port_id);
+ void *adm_params = NULL;
+ int param_size;
pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n",
__func__, port_id, path, rate, channel_mode, perf_mode,
@@ -2680,6 +2918,11 @@
pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
return -EINVAL;
}
+ if (channel_mode <= 0 || channel_mode > 32) {
+ pr_err("%s: Invalid channel number 0x%x\n",
+ __func__, channel_mode);
+ return -EINVAL;
+ }
if (this_adm.apr == NULL) {
this_adm.apr = apr_register("ADSP", "ADM", adm_callback,
@@ -2776,111 +3019,241 @@
if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) {
pr_debug("%s: open ADM: port_idx: %d, copp_idx: %d\n", __func__,
port_idx, copp_idx);
- if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) &&
- perf_mode == LEGACY_PCM_MODE) {
- int res;
+ if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) &&
+ perf_mode == LEGACY_PCM_MODE) {
+ int res;
- atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA);
- msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap);
- res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0,
- (uint32_t *)&this_adm.outband_memmap.size, 1);
- if (res < 0) {
- pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n",
- __func__, (void *)this_adm.outband_memmap.paddr,
- (uint32_t)this_adm.outband_memmap.size);
- }
- }
- open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- open.hdr.pkt_size = sizeof(open);
- open.hdr.src_svc = APR_SVC_ADM;
- open.hdr.src_domain = APR_DOMAIN_APPS;
- open.hdr.src_port = tmp_port;
- open.hdr.dest_svc = APR_SVC_ADM;
- open.hdr.dest_domain = APR_DOMAIN_ADSP;
- open.hdr.dest_port = tmp_port;
- open.hdr.token = port_idx << 16 | copp_idx;
- open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
- open.flags = flags;
- open.mode_of_operation = path;
- open.endpoint_id_1 = tmp_port;
- open.endpoint_id_2 = 0xFFFF;
-
- if (this_adm.ec_ref_rx && (path != 1) &&
- (afe_get_port_type(tmp_port) == MSM_AFE_PORT_TYPE_TX)) {
- open.endpoint_id_2 = this_adm.ec_ref_rx;
- this_adm.ec_ref_rx = -1;
+ atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA);
+ msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap);
+ res = adm_memory_map_regions(
+ &this_adm.outband_memmap.paddr, 0,
+ (uint32_t *)&this_adm.outband_memmap.size, 1);
+ if (res < 0) {
+ pr_err("%s: SRS adm_memory_map_regions failed! addr = 0x%pK, size = %d\n",
+ __func__,
+ (void *)this_adm.outband_memmap.paddr,
+ (uint32_t)this_adm.outband_memmap.size);
+ }
}
- open.topology_id = topology;
- open.dev_num_channel = channel_mode & 0x00FF;
- open.bit_width = bit_width;
- WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) &&
- (rate != ULL_SUPPORTED_SAMPLE_RATE));
- open.sample_rate = rate;
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_ADM_V) >=
+ ADSP_ADM_API_VERSION_V3) {
+ memset(&open_v8, 0, sizeof(open_v8));
+ memset(&ep1_payload, 0, sizeof(ep1_payload));
+ memset(&ep2_payload, 0, sizeof(ep2_payload));
- ret = adm_arrange_mch_map(&open, path, channel_mode,
- port_idx);
+ open_v8.hdr.hdr_field = APR_HDR_FIELD(
+ APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ open_v8.hdr.src_svc = APR_SVC_ADM;
+ open_v8.hdr.src_domain = APR_DOMAIN_APPS;
+ open_v8.hdr.src_port = tmp_port;
+ open_v8.hdr.dest_svc = APR_SVC_ADM;
+ open_v8.hdr.dest_domain = APR_DOMAIN_ADSP;
+ open_v8.hdr.dest_port = tmp_port;
+ open_v8.hdr.token = port_idx << 16 | copp_idx;
+ open_v8.hdr.opcode = ADM_CMD_DEVICE_OPEN_V8;
- if (ret)
- return ret;
-
- pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n",
- __func__, open.endpoint_id_1, open.sample_rate,
- open.topology_id);
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
-
- if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) &&
- (open.endpoint_id_2 != 0xFFFF)) {
- memset(&open_v6, 0,
- sizeof(struct adm_cmd_device_open_v6));
- memcpy(&open_v6, &open,
- sizeof(struct adm_cmd_device_open_v5));
- open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6;
- open_v6.hdr.pkt_size = sizeof(open_v6);
- open_v6.dev_num_channel_eid2 =
- this_adm.num_ec_ref_rx_chans;
- this_adm.num_ec_ref_rx_chans = 0;
-
- if (this_adm.ec_ref_rx_bit_width != 0) {
- open_v6.bit_width_eid2 =
- this_adm.ec_ref_rx_bit_width;
- this_adm.ec_ref_rx_bit_width = 0;
+ if (this_adm.native_mode != 0) {
+ open_v8.flags = flags |
+ (this_adm.native_mode << 11);
+ this_adm.native_mode = 0;
} else {
- open_v6.bit_width_eid2 = bit_width;
+ open_v8.flags = flags;
+ }
+ open_v8.mode_of_operation = path;
+ open_v8.endpoint_id_1 = tmp_port;
+ open_v8.endpoint_id_2 = 0xFFFF;
+ open_v8.endpoint_id_3 = 0xFFFF;
+
+ if (this_adm.ec_ref_rx && (path != 1)) {
+ open_v8.endpoint_id_2 = this_adm.ec_ref_rx;
+ this_adm.ec_ref_rx = -1;
}
- if (this_adm.ec_ref_rx_sampling_rate != 0) {
- open_v6.sample_rate_eid2 =
- this_adm.ec_ref_rx_sampling_rate;
- this_adm.ec_ref_rx_sampling_rate = 0;
- } else {
- open_v6.sample_rate_eid2 = rate;
- }
+ open_v8.topology_id = topology;
+ open_v8.reserved = 0;
- pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
- __func__, open_v6.dev_num_channel_eid2,
- open_v6.bit_width_eid2,
- open_v6.sample_rate_eid2);
-
- ret = adm_arrange_mch_ep2_map(&open_v6,
- open_v6.dev_num_channel_eid2);
-
+ /* variable endpoint payload */
+ ep1_payload.dev_num_channel = channel_mode & 0x00FF;
+ ep1_payload.bit_width = bit_width;
+ ep1_payload.sample_rate = rate;
+ ret = adm_arrange_mch_map_v8(&ep1_payload, path,
+ channel_mode);
if (ret)
return ret;
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open_v6);
+ pr_debug("%s: port_id=0x%x %x %x topology_id=0x%X flags %x ref_ch %x\n",
+ __func__, open_v8.endpoint_id_1,
+ open_v8.endpoint_id_2,
+ open_v8.endpoint_id_3,
+ open_v8.topology_id,
+ open_v8.flags,
+ this_adm.num_ec_ref_rx_chans);
+
+ ep1_payload_size = 8 +
+ roundup(ep1_payload.dev_num_channel, 4);
+ param_size = sizeof(struct adm_cmd_device_open_v8)
+ + ep1_payload_size;
+ atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
+
+ if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1)
+ && (open_v8.endpoint_id_2 != 0xFFFF)) {
+ ep2_payload.dev_num_channel =
+ this_adm.num_ec_ref_rx_chans;
+ this_adm.num_ec_ref_rx_chans = 0;
+
+ if (this_adm.ec_ref_rx_bit_width != 0) {
+ ep2_payload.bit_width =
+ this_adm.ec_ref_rx_bit_width;
+ this_adm.ec_ref_rx_bit_width = 0;
+ } else {
+ ep2_payload.bit_width = bit_width;
+ }
+
+ if (this_adm.ec_ref_rx_sampling_rate != 0) {
+ ep2_payload.sample_rate =
+ this_adm.ec_ref_rx_sampling_rate;
+ this_adm.ec_ref_rx_sampling_rate = 0;
+ } else {
+ ep2_payload.sample_rate = rate;
+ }
+
+ pr_debug("%s: adm open_v8 eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
+ __func__,
+ ep2_payload.dev_num_channel,
+ ep2_payload.bit_width,
+ ep2_payload.sample_rate);
+
+ ret = adm_arrange_mch_ep2_map_v8(&ep2_payload,
+ ep2_payload.dev_num_channel);
+
+ if (ret)
+ return ret;
+ ep2_payload_size = 8 +
+ roundup(ep2_payload.dev_num_channel, 4);
+ param_size += ep2_payload_size;
+ }
+
+ adm_params = kzalloc(param_size, GFP_KERNEL);
+ if (!adm_params)
+ return -ENOMEM;
+ open_v8.hdr.pkt_size = param_size;
+ memcpy(adm_params, &open_v8, sizeof(open_v8));
+ memcpy(adm_params + sizeof(open_v8),
+ (void *)&ep1_payload,
+ ep1_payload_size);
+ memcpy(adm_params + sizeof(open_v8)
+ + ep1_payload_size,
+ (void *)&ep2_payload,
+ ep2_payload_size);
+
+ ret = apr_send_pkt(this_adm.apr,
+ (uint32_t *)adm_params);
+ if (ret < 0) {
+ pr_err("%s: port_id: 0x%x for[0x%x] failed %d for open_v8\n",
+ __func__, tmp_port, port_id, ret);
+ return -EINVAL;
+ }
+ kfree(adm_params);
} else {
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open);
+
+ open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ open.hdr.pkt_size = sizeof(open);
+ open.hdr.src_svc = APR_SVC_ADM;
+ open.hdr.src_domain = APR_DOMAIN_APPS;
+ open.hdr.src_port = tmp_port;
+ open.hdr.dest_svc = APR_SVC_ADM;
+ open.hdr.dest_domain = APR_DOMAIN_ADSP;
+ open.hdr.dest_port = tmp_port;
+ open.hdr.token = port_idx << 16 | copp_idx;
+ open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
+ open.flags = flags;
+ open.mode_of_operation = path;
+ open.endpoint_id_1 = tmp_port;
+ open.endpoint_id_2 = 0xFFFF;
+
+ if (this_adm.ec_ref_rx && (path != 1)) {
+ open.endpoint_id_2 = this_adm.ec_ref_rx;
+ this_adm.ec_ref_rx = -1;
+ }
+
+ open.topology_id = topology;
+
+ open.dev_num_channel = channel_mode & 0x00FF;
+ open.bit_width = bit_width;
+ WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) &&
+ (rate != ULL_SUPPORTED_SAMPLE_RATE));
+ open.sample_rate = rate;
+
+ ret = adm_arrange_mch_map(&open, path, channel_mode,
+ port_idx);
+ if (ret)
+ return ret;
+
+ pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n",
+ __func__, open.endpoint_id_1, open.sample_rate,
+ open.topology_id);
+
+ atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
+
+ if ((this_adm.num_ec_ref_rx_chans != 0) &&
+ (path != 1) && (open.endpoint_id_2 != 0xFFFF)) {
+ memset(&open_v6, 0,
+ sizeof(struct adm_cmd_device_open_v6));
+ memcpy(&open_v6, &open,
+ sizeof(struct adm_cmd_device_open_v5));
+ open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6;
+ open_v6.hdr.pkt_size = sizeof(open_v6);
+ open_v6.dev_num_channel_eid2 =
+ this_adm.num_ec_ref_rx_chans;
+ this_adm.num_ec_ref_rx_chans = 0;
+
+ if (this_adm.ec_ref_rx_bit_width != 0) {
+ open_v6.bit_width_eid2 =
+ this_adm.ec_ref_rx_bit_width;
+ this_adm.ec_ref_rx_bit_width = 0;
+ } else {
+ open_v6.bit_width_eid2 = bit_width;
+ }
+
+ if (this_adm.ec_ref_rx_sampling_rate != 0) {
+ open_v6.sample_rate_eid2 =
+ this_adm.ec_ref_rx_sampling_rate;
+ this_adm.ec_ref_rx_sampling_rate = 0;
+ } else {
+ open_v6.sample_rate_eid2 = rate;
+ }
+
+ pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
+ __func__, open_v6.dev_num_channel_eid2,
+ open_v6.bit_width_eid2,
+ open_v6.sample_rate_eid2);
+
+ ret = adm_arrange_mch_ep2_map(&open_v6,
+ open_v6.dev_num_channel_eid2);
+
+ if (ret)
+ return ret;
+
+ ret = apr_send_pkt(this_adm.apr,
+ (uint32_t *)&open_v6);
+ } else {
+ ret = apr_send_pkt(this_adm.apr,
+ (uint32_t *)&open);
+ }
+ if (ret < 0) {
+ pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n",
+ __func__, tmp_port, port_id, ret);
+ return -EINVAL;
+ }
}
- if (ret < 0) {
- pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n",
- __func__, tmp_port, port_id, ret);
- return -EINVAL;
- }
+
/* Wait for the callback with copp id */
ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
atomic_read(&this_adm.copp.stat
@@ -3252,6 +3625,22 @@
EXPORT_SYMBOL(adm_ec_ref_rx_sampling_rate);
/**
+ * adm_set_native_mode -
+ * Set adm channel native mode.
+ * If enabled matrix mixer will be
+ * running in native mode for channel
+ * configuration for this device session.
+ *
+ */
+void adm_set_native_mode(int mode)
+{
+ this_adm.native_mode = mode;
+ pr_debug("%s: enable native_mode :%d\n",
+ __func__, this_adm.native_mode);
+}
+EXPORT_SYMBOL(adm_set_native_mode);
+
+/**
* adm_close -
* command to close ADM copp
*